@dwelle/excalidraw 0.6.0-rc.1 → 0.6.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (227) hide show
  1. package/README.md +3 -2
  2. package/dist/dev/{chunk-EFVS2MI5.js → chunk-LCPOPWNR.js} +2 -2
  3. package/dist/dev/{chunk-EFVS2MI5.js.map → chunk-LCPOPWNR.js.map} +1 -1
  4. package/dist/dev/chunk-NGUTX5QY.js +25914 -0
  5. package/dist/dev/chunk-NGUTX5QY.js.map +7 -0
  6. package/dist/dev/data/image-2IPPJHZ4.js +13 -0
  7. package/dist/dev/index.css.map +1 -1
  8. package/dist/dev/index.js +33216 -35
  9. package/dist/dev/index.js.map +4 -4
  10. package/dist/dev/subset-shared.chunk.js +1 -1
  11. package/dist/dev/subset-worker.chunk.js +1 -1
  12. package/dist/prod/{chunk-P7457GAF.js → chunk-BE2LY6VO.js} +1 -1
  13. package/dist/prod/chunk-R7OERAXD.js +46 -0
  14. package/dist/prod/data/image-DXJVNPGL.js +1 -0
  15. package/dist/prod/index.js +108 -1
  16. package/dist/prod/subset-shared.chunk.js +1 -1
  17. package/dist/prod/subset-worker.chunk.js +1 -1
  18. package/dist/types/excalidraw/actions/actionAlign.d.ts +12 -12
  19. package/dist/types/excalidraw/actions/actionCanvas.d.ts +18 -18
  20. package/dist/types/excalidraw/actions/actionClipboard.d.ts +4 -4
  21. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +2 -2
  22. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +2 -2
  23. package/dist/types/excalidraw/actions/actionDistribute.d.ts +2 -2
  24. package/dist/types/excalidraw/actions/actionDuplicateSelection.d.ts +2 -2
  25. package/dist/types/excalidraw/actions/actionElementLink.d.ts +2 -2
  26. package/dist/types/excalidraw/actions/actionElementLock.d.ts +2 -2
  27. package/dist/types/excalidraw/actions/actionExport.d.ts +19 -19
  28. package/dist/types/excalidraw/actions/actionFinalize.d.ts +1 -1
  29. package/dist/types/excalidraw/actions/actionFlip.d.ts +2 -2
  30. package/dist/types/excalidraw/actions/actionFrame.d.ts +2 -2
  31. package/dist/types/excalidraw/actions/actionGroup.d.ts +4 -4
  32. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +1 -1
  33. package/dist/types/excalidraw/actions/actionLink.d.ts +2 -2
  34. package/dist/types/excalidraw/actions/actionMenu.d.ts +3 -3
  35. package/dist/types/excalidraw/actions/actionNavigate.d.ts +1 -1
  36. package/dist/types/excalidraw/actions/actionProperties.d.ts +16 -16
  37. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +1 -1
  38. package/dist/types/excalidraw/actions/actionStyles.d.ts +2 -2
  39. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +1 -1
  40. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +1 -1
  41. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +1 -1
  42. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +1 -1
  43. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +1 -1
  44. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +1 -1
  45. package/dist/types/excalidraw/actions/actionZindex.d.ts +10 -10
  46. package/dist/types/excalidraw/actions/manager.d.ts +1 -1
  47. package/dist/types/excalidraw/appState.d.ts +9 -9
  48. package/dist/types/excalidraw/clipboard.d.ts +4 -4
  49. package/dist/types/excalidraw/components/Actions.d.ts +6 -7
  50. package/dist/types/excalidraw/components/ActiveConfirmDialog.d.ts +1 -2
  51. package/dist/types/excalidraw/components/App.d.ts +1 -1
  52. package/dist/types/excalidraw/components/Avatar.d.ts +1 -1
  53. package/dist/types/excalidraw/components/BraveMeasureTextError.d.ts +1 -2
  54. package/dist/types/excalidraw/components/Button.d.ts +1 -1
  55. package/dist/types/excalidraw/components/ButtonIcon.d.ts +1 -1
  56. package/dist/types/excalidraw/components/ButtonIconCycle.d.ts +2 -2
  57. package/dist/types/excalidraw/components/ButtonIconSelect.d.ts +2 -2
  58. package/dist/types/excalidraw/components/ButtonSelect.d.ts +1 -2
  59. package/dist/types/excalidraw/components/ButtonSeparator.d.ts +1 -2
  60. package/dist/types/excalidraw/components/ColorPicker/ColorInput.d.ts +1 -2
  61. package/dist/types/excalidraw/components/ColorPicker/ColorPicker.d.ts +1 -2
  62. package/dist/types/excalidraw/components/ColorPicker/CustomColorList.d.ts +1 -2
  63. package/dist/types/excalidraw/components/ColorPicker/HotkeyLabel.d.ts +1 -2
  64. package/dist/types/excalidraw/components/ColorPicker/Picker.d.ts +1 -1
  65. package/dist/types/excalidraw/components/ColorPicker/PickerColorList.d.ts +1 -2
  66. package/dist/types/excalidraw/components/ColorPicker/PickerHeading.d.ts +1 -1
  67. package/dist/types/excalidraw/components/ColorPicker/ShadeList.d.ts +1 -2
  68. package/dist/types/excalidraw/components/ColorPicker/TopPicks.d.ts +1 -2
  69. package/dist/types/excalidraw/components/CommandPalette/CommandPalette.d.ts +1 -2
  70. package/dist/types/excalidraw/components/ConfirmDialog.d.ts +1 -2
  71. package/dist/types/excalidraw/components/ContextMenu.d.ts +1 -1
  72. package/dist/types/excalidraw/components/DarkModeToggle.d.ts +1 -2
  73. package/dist/types/excalidraw/components/DefaultSidebar.d.ts +1 -1
  74. package/dist/types/excalidraw/components/Dialog.d.ts +1 -1
  75. package/dist/types/excalidraw/components/DialogActionButton.d.ts +1 -1
  76. package/dist/types/excalidraw/components/ElementLinkDialog.d.ts +1 -2
  77. package/dist/types/excalidraw/components/ErrorDialog.d.ts +1 -1
  78. package/dist/types/excalidraw/components/ExcalidrawLogo.d.ts +1 -1
  79. package/dist/types/excalidraw/components/FixedSideContainer.d.ts +1 -1
  80. package/dist/types/excalidraw/components/FollowMode/FollowMode.d.ts +1 -2
  81. package/dist/types/excalidraw/components/FontPicker/FontPicker.d.ts +2 -2
  82. package/dist/types/excalidraw/components/FontPicker/FontPickerList.d.ts +2 -1
  83. package/dist/types/excalidraw/components/FontPicker/FontPickerTrigger.d.ts +1 -2
  84. package/dist/types/excalidraw/components/FontPicker/keyboardNavHandlers.d.ts +1 -1
  85. package/dist/types/excalidraw/components/HandButton.d.ts +1 -2
  86. package/dist/types/excalidraw/components/HelpButton.d.ts +1 -2
  87. package/dist/types/excalidraw/components/HelpDialog.d.ts +1 -2
  88. package/dist/types/excalidraw/components/HintViewer.d.ts +1 -2
  89. package/dist/types/excalidraw/components/IconPicker.d.ts +2 -2
  90. package/dist/types/excalidraw/components/ImageExportDialog.d.ts +2 -3
  91. package/dist/types/excalidraw/components/InitializeApp.d.ts +1 -1
  92. package/dist/types/excalidraw/components/InlineIcon.d.ts +1 -2
  93. package/dist/types/excalidraw/components/JSONExportDialog.d.ts +1 -1
  94. package/dist/types/excalidraw/components/LaserPointerButton.d.ts +1 -2
  95. package/dist/types/excalidraw/components/LayerUI.d.ts +1 -1
  96. package/dist/types/excalidraw/components/LibraryMenu.d.ts +1 -1
  97. package/dist/types/excalidraw/components/LibraryMenuBrowseButton.d.ts +1 -2
  98. package/dist/types/excalidraw/components/LibraryMenuControlButtons.d.ts +1 -2
  99. package/dist/types/excalidraw/components/LibraryMenuHeaderContent.d.ts +1 -1
  100. package/dist/types/excalidraw/components/LibraryMenuItems.d.ts +1 -2
  101. package/dist/types/excalidraw/components/LibraryMenuSection.d.ts +2 -2
  102. package/dist/types/excalidraw/components/LibraryUnit.d.ts +2 -2
  103. package/dist/types/excalidraw/components/LockButton.d.ts +1 -2
  104. package/dist/types/excalidraw/components/MagicButton.d.ts +2 -2
  105. package/dist/types/excalidraw/components/MobileMenu.d.ts +2 -1
  106. package/dist/types/excalidraw/components/OverwriteConfirm/OverwriteConfirm.d.ts +4 -4
  107. package/dist/types/excalidraw/components/OverwriteConfirm/OverwriteConfirmActions.d.ts +6 -6
  108. package/dist/types/excalidraw/components/Paragraph.d.ts +1 -2
  109. package/dist/types/excalidraw/components/PasteChartDialog.d.ts +1 -1
  110. package/dist/types/excalidraw/components/PenModeButton.d.ts +1 -2
  111. package/dist/types/excalidraw/components/Popover.d.ts +1 -1
  112. package/dist/types/excalidraw/components/ProjectName.d.ts +1 -2
  113. package/dist/types/excalidraw/components/PublishLibrary.d.ts +1 -2
  114. package/dist/types/excalidraw/components/RadioGroup.d.ts +1 -1
  115. package/dist/types/excalidraw/components/Range.d.ts +1 -2
  116. package/dist/types/excalidraw/components/SVGLayer.d.ts +1 -2
  117. package/dist/types/excalidraw/components/ScrollableList.d.ts +1 -1
  118. package/dist/types/excalidraw/components/SearchMenu.d.ts +1 -2
  119. package/dist/types/excalidraw/components/ShareableLinkDialog.d.ts +1 -2
  120. package/dist/types/excalidraw/components/Sidebar/Sidebar.d.ts +6 -6
  121. package/dist/types/excalidraw/components/Sidebar/SidebarHeader.d.ts +1 -2
  122. package/dist/types/excalidraw/components/Sidebar/SidebarTab.d.ts +1 -1
  123. package/dist/types/excalidraw/components/Sidebar/SidebarTabTrigger.d.ts +1 -1
  124. package/dist/types/excalidraw/components/Sidebar/SidebarTabTriggers.d.ts +1 -1
  125. package/dist/types/excalidraw/components/Sidebar/SidebarTabs.d.ts +1 -1
  126. package/dist/types/excalidraw/components/Sidebar/SidebarTrigger.d.ts +1 -2
  127. package/dist/types/excalidraw/components/Sidebar/common.d.ts +1 -0
  128. package/dist/types/excalidraw/components/Spinner.d.ts +1 -2
  129. package/dist/types/excalidraw/components/Stack.d.ts +2 -3
  130. package/dist/types/excalidraw/components/Stats/Angle.d.ts +1 -2
  131. package/dist/types/excalidraw/components/Stats/CanvasGrid.d.ts +1 -1
  132. package/dist/types/excalidraw/components/Stats/Collapsible.d.ts +1 -1
  133. package/dist/types/excalidraw/components/Stats/Dimension.d.ts +1 -2
  134. package/dist/types/excalidraw/components/Stats/DragInput.d.ts +1 -1
  135. package/dist/types/excalidraw/components/Stats/FontSize.d.ts +1 -2
  136. package/dist/types/excalidraw/components/Stats/MultiAngle.d.ts +1 -2
  137. package/dist/types/excalidraw/components/Stats/MultiDimension.d.ts +1 -2
  138. package/dist/types/excalidraw/components/Stats/MultiFontSize.d.ts +1 -2
  139. package/dist/types/excalidraw/components/Stats/MultiPosition.d.ts +1 -2
  140. package/dist/types/excalidraw/components/Stats/Position.d.ts +1 -2
  141. package/dist/types/excalidraw/components/Stats/index.d.ts +4 -4
  142. package/dist/types/excalidraw/components/Switch.d.ts +1 -2
  143. package/dist/types/excalidraw/components/TTDDialog/MermaidToExcalidraw.d.ts +1 -2
  144. package/dist/types/excalidraw/components/TTDDialog/TTDDialog.d.ts +1 -1
  145. package/dist/types/excalidraw/components/TTDDialog/TTDDialogInput.d.ts +1 -1
  146. package/dist/types/excalidraw/components/TTDDialog/TTDDialogOutput.d.ts +2 -2
  147. package/dist/types/excalidraw/components/TTDDialog/TTDDialogPanel.d.ts +1 -1
  148. package/dist/types/excalidraw/components/TTDDialog/TTDDialogPanels.d.ts +1 -1
  149. package/dist/types/excalidraw/components/TTDDialog/TTDDialogSubmitShortcut.d.ts +1 -2
  150. package/dist/types/excalidraw/components/TTDDialog/TTDDialogTab.d.ts +1 -1
  151. package/dist/types/excalidraw/components/TTDDialog/TTDDialogTabTrigger.d.ts +1 -1
  152. package/dist/types/excalidraw/components/TTDDialog/TTDDialogTabTriggers.d.ts +1 -1
  153. package/dist/types/excalidraw/components/TTDDialog/TTDDialogTabs.d.ts +1 -1
  154. package/dist/types/excalidraw/components/TTDDialog/TTDDialogTrigger.d.ts +2 -1
  155. package/dist/types/excalidraw/components/TTDDialog/common.d.ts +1 -1
  156. package/dist/types/excalidraw/components/Toast.d.ts +1 -1
  157. package/dist/types/excalidraw/components/Tooltip.d.ts +1 -1
  158. package/dist/types/excalidraw/components/UserList.d.ts +1 -1
  159. package/dist/types/excalidraw/components/canvases/InteractiveCanvas.d.ts +2 -2
  160. package/dist/types/excalidraw/components/canvases/NewElementCanvas.d.ts +1 -2
  161. package/dist/types/excalidraw/components/canvases/StaticCanvas.d.ts +1 -1
  162. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenu.d.ts +11 -11
  163. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuContent.d.ts +1 -1
  164. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuGroup.d.ts +1 -1
  165. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItem.d.ts +4 -3
  166. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItemContent.d.ts +2 -2
  167. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItemContentRadio.d.ts +1 -1
  168. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItemCustom.d.ts +1 -1
  169. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItemLink.d.ts +2 -1
  170. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuSeparator.d.ts +1 -2
  171. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuTrigger.d.ts +1 -1
  172. package/dist/types/excalidraw/components/dropdownMenu/dropdownMenuUtils.d.ts +2 -2
  173. package/dist/types/excalidraw/components/footer/Footer.d.ts +1 -2
  174. package/dist/types/excalidraw/components/footer/FooterCenter.d.ts +1 -2
  175. package/dist/types/excalidraw/components/hyperlink/Hyperlink.d.ts +1 -2
  176. package/dist/types/excalidraw/components/icons.d.ts +178 -178
  177. package/dist/types/excalidraw/components/live-collaboration/LiveCollaborationTrigger.d.ts +1 -1
  178. package/dist/types/excalidraw/components/main-menu/DefaultItems.d.ts +12 -13
  179. package/dist/types/excalidraw/components/main-menu/MainMenu.d.ts +9 -9
  180. package/dist/types/excalidraw/components/welcome-screen/WelcomeScreen.Center.d.ts +10 -10
  181. package/dist/types/excalidraw/components/welcome-screen/WelcomeScreen.Hints.d.ts +3 -4
  182. package/dist/types/excalidraw/components/welcome-screen/WelcomeScreen.d.ts +15 -15
  183. package/dist/types/excalidraw/constants.d.ts +1 -0
  184. package/dist/types/excalidraw/data/blob.d.ts +1 -1
  185. package/dist/types/excalidraw/element/ElementCanvasButtons.d.ts +1 -2
  186. package/dist/types/excalidraw/element/binding.d.ts +1 -2
  187. package/dist/types/excalidraw/element/collision.d.ts +10 -1
  188. package/dist/types/excalidraw/element/distance.d.ts +3 -0
  189. package/dist/types/excalidraw/element/newElement.d.ts +1 -1
  190. package/dist/types/excalidraw/element/transformHandles.d.ts +2 -2
  191. package/dist/types/excalidraw/element/types.d.ts +1 -1
  192. package/dist/types/excalidraw/element/utils.d.ts +21 -0
  193. package/dist/types/excalidraw/fonts/FontMetadata.d.ts +1 -1
  194. package/dist/types/excalidraw/hooks/useOutsideClick.d.ts +1 -1
  195. package/dist/types/excalidraw/hooks/useScrollPosition.d.ts +1 -1
  196. package/dist/types/excalidraw/index.d.ts +1 -3
  197. package/dist/types/excalidraw/shapes.d.ts +11 -12
  198. package/dist/types/excalidraw/types.d.ts +1 -0
  199. package/dist/types/excalidraw/utils.d.ts +3 -3
  200. package/dist/types/excalidraw/visualdebug.d.ts +7 -8
  201. package/dist/types/excalidraw/zindex.d.ts +2 -2
  202. package/dist/types/math/curve.d.ts +22 -14
  203. package/dist/types/math/ellipse.d.ts +44 -0
  204. package/dist/types/math/index.d.ts +1 -1
  205. package/dist/types/math/line.d.ts +2 -30
  206. package/dist/types/math/point.d.ts +1 -29
  207. package/dist/types/math/rectangle.d.ts +3 -0
  208. package/dist/types/math/segment.d.ts +8 -1
  209. package/dist/types/math/types.d.ts +15 -6
  210. package/dist/types/math/vector.d.ts +0 -4
  211. package/dist/types/utils/export.d.ts +1 -1
  212. package/package.json +5 -5
  213. package/dist/dev/chunk-637CAVTS.js +0 -57639
  214. package/dist/dev/chunk-637CAVTS.js.map +0 -7
  215. package/dist/dev/data/image-N6Y7BWW6.css +0 -6753
  216. package/dist/dev/data/image-N6Y7BWW6.css.map +0 -7
  217. package/dist/dev/data/image-QMQX6YR5.js +0 -15
  218. package/dist/prod/chunk-PEDHHNBJ.js +0 -153
  219. package/dist/prod/data/image-IP6M4LZC.js +0 -1
  220. package/dist/prod/data/image-KGQIL6Y4.css +0 -1
  221. package/dist/types/math/arc.d.ts +0 -6
  222. package/dist/types/math/ga/ga.d.ts +0 -63
  223. package/dist/types/math/ga/gadirections.d.ts +0 -8
  224. package/dist/types/math/ga/galines.d.ts +0 -22
  225. package/dist/types/math/ga/gapoints.d.ts +0 -7
  226. package/dist/types/math/ga/gatransforms.d.ts +0 -10
  227. /package/dist/dev/data/{image-QMQX6YR5.js.map → image-2IPPJHZ4.js.map} +0 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../data/image.ts", "../../data/encode.ts", "../../constants.ts", "../../data/blob.ts", "../../appState.ts", "../../scene/Scene.ts", "../../utils.ts", "../../../math/utils.ts", "../../../math/angle.ts", "../../../math/vector.ts", "../../../math/point.ts", "../../../math/line.ts", "../../../math/segment.ts", "../../../math/rectangle.ts", "../../../math/curve.ts", "../../../math/polygon.ts", "../../../math/range.ts", "../../../math/triangle.ts", "../../element/typeChecks.ts", "../../element/textMeasurements.ts", "../../element/textWrapping.ts", "../../element/bounds.ts", "../../renderer/renderElement.ts", "../../scene/ShapeCache.ts", "../../colors.ts", "../../components/icons.tsx", "../../fonts/FontMetadata.ts", "../../errors.ts", "../../workers.ts", "../../subset/subset-main.ts", "../../fonts/ExcalidrawFontFace.ts", "../../fonts/Cascadia/index.ts", "../../fonts/ComicShanns/index.ts", "../../fonts/Emoji/index.ts", "../../fonts/Excalifont/index.ts", "../../fonts/Helvetica/index.ts", "../../fonts/Liberation/index.ts", "../../fonts/Lilita/index.ts", "../../fonts/Nunito/index.ts", "../../fonts/Virgil/index.ts", "../../fonts/Xiaolai/index.ts", "../../fonts/Fonts.ts", "../../../utils/geometry/shape.ts", "../../../utils/collision.ts", "../../../math/ellipse.ts", "../../element/utils.ts", "../../element/collision.ts", "../../keys.ts", "../../shapes.tsx", "../../element/cropElement.ts", "../../scene/Shape.ts", "../../scene/comparisons.ts", "../../element/heading.ts", "../../points.ts", "../../element/distance.ts", "../../element/binding.ts", "../../scene/scroll.ts", "../../scene/normalize.ts", "../../groups.ts", "../../snapping.ts", "../../element/linearElementEditor.ts", "../../element/containerCache.ts", "../../element/textElement.ts", "../../scene/export.ts", "../../data/url.ts", "../../actions/register.ts", "../../cursor.ts", "../../random.ts", "../../element/newElement.ts", "../../fractionalIndex.ts", "../../change.ts", "../../emitter.ts", "../../store.ts", "../../element/embeddable.ts", "../../renderer/staticSvgScene.ts", "../../data/filesystem.ts", "../../data/json.ts", "../../element/image.ts", "../../data/restore.ts", "../../components/hyperlink/helpers.ts", "../../renderer/helpers.ts", "../../element/elementLink.ts", "../../renderer/staticScene.ts", "../../charts.ts", "../../clipboard.ts", "../../../utils/export.ts", "../../../utils/withinBounds.ts", "../../../utils/bbox.ts", "../../frame.ts", "../../scene/selection.ts", "../../binaryheap.ts", "../../element/elbowArrow.ts", "../../element/mutateElement.ts", "../../element/sizeHelpers.ts", "../../element/transformHandles.ts", "../../element/resizeTest.ts", "../../element/resizeElements.ts", "../../element/dragElements.ts", "../../element/showSelectedShapeActions.ts", "../../element/index.ts"],
4
+ "sourcesContent": ["import decodePng from \"png-chunks-extract\";\nimport tEXt from \"png-chunk-text\";\nimport encodePng from \"png-chunks-encode\";\nimport { encode, decode } from \"./encode\";\nimport { EXPORT_DATA_TYPES, MIME_TYPES } from \"../constants\";\nimport { blobToArrayBuffer } from \"./blob\";\n\n// -----------------------------------------------------------------------------\n// PNG\n// -----------------------------------------------------------------------------\n\nexport const getTEXtChunk = async (\n blob: Blob,\n): Promise<{ keyword: string; text: string } | null> => {\n const chunks = decodePng(new Uint8Array(await blobToArrayBuffer(blob)));\n const metadataChunk = chunks.find((chunk) => chunk.name === \"tEXt\");\n if (metadataChunk) {\n return tEXt.decode(metadataChunk.data);\n }\n return null;\n};\n\nexport const encodePngMetadata = async ({\n blob,\n metadata,\n}: {\n blob: Blob;\n metadata: string;\n}) => {\n const chunks = decodePng(new Uint8Array(await blobToArrayBuffer(blob)));\n\n const metadataChunk = tEXt.encode(\n MIME_TYPES.excalidraw,\n JSON.stringify(\n encode({\n text: metadata,\n compress: true,\n }),\n ),\n );\n // insert metadata before last chunk (iEND)\n chunks.splice(-1, 0, metadataChunk);\n\n return new Blob([encodePng(chunks)], { type: MIME_TYPES.png });\n};\n\nexport const decodePngMetadata = async (blob: Blob) => {\n const metadata = await getTEXtChunk(blob);\n if (metadata?.keyword === MIME_TYPES.excalidraw) {\n try {\n const encodedData = JSON.parse(metadata.text);\n if (!(\"encoded\" in encodedData)) {\n // legacy, un-encoded scene JSON\n if (\n \"type\" in encodedData &&\n encodedData.type === EXPORT_DATA_TYPES.excalidraw\n ) {\n return metadata.text;\n }\n throw new Error(\"FAILED\");\n }\n return decode(encodedData);\n } catch (error: any) {\n console.error(error);\n throw new Error(\"FAILED\");\n }\n }\n throw new Error(\"INVALID\");\n};\n", "import { deflate, inflate } from \"pako\";\nimport { encryptData, decryptData } from \"./encryption\";\n\n// -----------------------------------------------------------------------------\n// byte (binary) strings\n// -----------------------------------------------------------------------------\n\n// Buffer-compatible implem.\n//\n// Note that in V8, spreading the uint8array (by chunks) into\n// `String.fromCharCode(...uint8array)` tends to be faster for large\n// strings/buffers, in case perf is needed in the future.\nexport const toByteString = (data: string | Uint8Array | ArrayBuffer) => {\n const bytes =\n typeof data === \"string\"\n ? new TextEncoder().encode(data)\n : data instanceof Uint8Array\n ? data\n : new Uint8Array(data);\n let bstring = \"\";\n for (const byte of bytes) {\n bstring += String.fromCharCode(byte);\n }\n return bstring;\n};\n\nconst byteStringToArrayBuffer = (byteString: string) => {\n const buffer = new ArrayBuffer(byteString.length);\n const bufferView = new Uint8Array(buffer);\n for (let i = 0, len = byteString.length; i < len; i++) {\n bufferView[i] = byteString.charCodeAt(i);\n }\n return buffer;\n};\n\nconst byteStringToString = (byteString: string) => {\n return new TextDecoder(\"utf-8\").decode(byteStringToArrayBuffer(byteString));\n};\n\n// -----------------------------------------------------------------------------\n// base64\n// -----------------------------------------------------------------------------\n\n/**\n * @param isByteString set to true if already byte string to prevent bloat\n * due to reencoding\n */\nexport const stringToBase64 = (str: string, isByteString = false) => {\n return isByteString ? window.btoa(str) : window.btoa(toByteString(str));\n};\n\n// async to align with stringToBase64\nexport const base64ToString = (base64: string, isByteString = false) => {\n return isByteString\n ? window.atob(base64)\n : byteStringToString(window.atob(base64));\n};\n\nexport const base64ToArrayBuffer = (base64: string): ArrayBuffer => {\n if (typeof Buffer !== \"undefined\") {\n // Node.js environment\n return Buffer.from(base64, \"base64\").buffer;\n }\n // Browser environment\n return byteStringToArrayBuffer(atob(base64));\n};\n\n// -----------------------------------------------------------------------------\n// base64url\n// -----------------------------------------------------------------------------\n\nexport const base64urlToString = (str: string) => {\n return window.atob(\n // normalize base64URL to base64\n str\n .replace(/-/g, \"+\")\n .replace(/_/g, \"/\")\n .padEnd(str.length + ((4 - (str.length % 4)) % 4), \"=\"),\n );\n};\n\n// -----------------------------------------------------------------------------\n// text encoding\n// -----------------------------------------------------------------------------\n\ntype EncodedData = {\n encoded: string;\n encoding: \"bstring\";\n /** whether text is compressed (zlib) */\n compressed: boolean;\n /** version for potential migration purposes */\n version?: string;\n};\n\n/**\n * Encodes (and potentially compresses via zlib) text to byte string\n */\nexport const encode = ({\n text,\n compress,\n}: {\n text: string;\n /** defaults to `true`. If compression fails, falls back to bstring alone. */\n compress?: boolean;\n}): EncodedData => {\n let deflated!: string;\n if (compress !== false) {\n try {\n deflated = toByteString(deflate(text));\n } catch (error: any) {\n console.error(\"encode: cannot deflate\", error);\n }\n }\n return {\n version: \"1\",\n encoding: \"bstring\",\n compressed: !!deflated,\n encoded: deflated || toByteString(text),\n };\n};\n\nexport const decode = (data: EncodedData): string => {\n let decoded: string;\n\n switch (data.encoding) {\n case \"bstring\":\n // if compressed, do not double decode the bstring\n decoded = data.compressed\n ? data.encoded\n : byteStringToString(data.encoded);\n break;\n default:\n throw new Error(`decode: unknown encoding \"${data.encoding}\"`);\n }\n\n if (data.compressed) {\n return inflate(new Uint8Array(byteStringToArrayBuffer(decoded)), {\n to: \"string\",\n });\n }\n\n return decoded;\n};\n\n// -----------------------------------------------------------------------------\n// binary encoding\n// -----------------------------------------------------------------------------\n\ntype FileEncodingInfo = {\n /* version 2 is the version we're shipping the initial image support with.\n version 1 was a PR version that a lot of people were using anyway.\n Thus, if there are issues we can check whether they're not using the\n unoffic version */\n version: 1 | 2;\n compression: \"pako@1\" | null;\n encryption: \"AES-GCM\" | null;\n};\n\n// -----------------------------------------------------------------------------\nconst CONCAT_BUFFERS_VERSION = 1;\n/** how many bytes we use to encode how many bytes the next chunk has.\n * Corresponds to DataView setter methods (setUint32, setUint16, etc).\n *\n * NOTE ! values must not be changed, which would be backwards incompatible !\n */\nconst VERSION_DATAVIEW_BYTES = 4;\nconst NEXT_CHUNK_SIZE_DATAVIEW_BYTES = 4;\n// -----------------------------------------------------------------------------\n\nconst DATA_VIEW_BITS_MAP = { 1: 8, 2: 16, 4: 32 } as const;\n\n// getter\nfunction dataView(buffer: Uint8Array, bytes: 1 | 2 | 4, offset: number): number;\n// setter\nfunction dataView(\n buffer: Uint8Array,\n bytes: 1 | 2 | 4,\n offset: number,\n value: number,\n): Uint8Array;\n/**\n * abstraction over DataView that serves as a typed getter/setter in case\n * you're using constants for the byte size and want to ensure there's no\n * discrepenancy in the encoding across refactors.\n *\n * DataView serves for an endian-agnostic handling of numbers in ArrayBuffers.\n */\nfunction dataView(\n buffer: Uint8Array,\n bytes: 1 | 2 | 4,\n offset: number,\n value?: number,\n): Uint8Array | number {\n if (value != null) {\n if (value > Math.pow(2, DATA_VIEW_BITS_MAP[bytes]) - 1) {\n throw new Error(\n `attempting to set value higher than the allocated bytes (value: ${value}, bytes: ${bytes})`,\n );\n }\n const method = `setUint${DATA_VIEW_BITS_MAP[bytes]}` as const;\n new DataView(buffer.buffer)[method](offset, value);\n return buffer;\n }\n const method = `getUint${DATA_VIEW_BITS_MAP[bytes]}` as const;\n return new DataView(buffer.buffer)[method](offset);\n}\n\n// -----------------------------------------------------------------------------\n\n/**\n * Resulting concatenated buffer has this format:\n *\n * [\n * VERSION chunk (4 bytes)\n * LENGTH chunk 1 (4 bytes)\n * DATA chunk 1 (up to 2^32 bits)\n * LENGTH chunk 2 (4 bytes)\n * DATA chunk 2 (up to 2^32 bits)\n * ...\n * ]\n *\n * @param buffers each buffer (chunk) must be at most 2^32 bits large (~4GB)\n */\nconst concatBuffers = (...buffers: Uint8Array[]) => {\n const bufferView = new Uint8Array(\n VERSION_DATAVIEW_BYTES +\n NEXT_CHUNK_SIZE_DATAVIEW_BYTES * buffers.length +\n buffers.reduce((acc, buffer) => acc + buffer.byteLength, 0),\n );\n\n let cursor = 0;\n\n // as the first chunk we'll encode the version for backwards compatibility\n dataView(bufferView, VERSION_DATAVIEW_BYTES, cursor, CONCAT_BUFFERS_VERSION);\n cursor += VERSION_DATAVIEW_BYTES;\n\n for (const buffer of buffers) {\n dataView(\n bufferView,\n NEXT_CHUNK_SIZE_DATAVIEW_BYTES,\n cursor,\n buffer.byteLength,\n );\n cursor += NEXT_CHUNK_SIZE_DATAVIEW_BYTES;\n\n bufferView.set(buffer, cursor);\n cursor += buffer.byteLength;\n }\n\n return bufferView;\n};\n\n/** can only be used on buffers created via `concatBuffers()` */\nconst splitBuffers = (concatenatedBuffer: Uint8Array) => {\n const buffers = [];\n\n let cursor = 0;\n\n // first chunk is the version\n const version = dataView(\n concatenatedBuffer,\n NEXT_CHUNK_SIZE_DATAVIEW_BYTES,\n cursor,\n );\n // If version is outside of the supported versions, throw an error.\n // This usually means the buffer wasn't encoded using this API, so we'd only\n // waste compute.\n if (version > CONCAT_BUFFERS_VERSION) {\n throw new Error(`invalid version ${version}`);\n }\n\n cursor += VERSION_DATAVIEW_BYTES;\n\n while (true) {\n const chunkSize = dataView(\n concatenatedBuffer,\n NEXT_CHUNK_SIZE_DATAVIEW_BYTES,\n cursor,\n );\n cursor += NEXT_CHUNK_SIZE_DATAVIEW_BYTES;\n\n buffers.push(concatenatedBuffer.slice(cursor, cursor + chunkSize));\n cursor += chunkSize;\n if (cursor >= concatenatedBuffer.byteLength) {\n break;\n }\n }\n\n return buffers;\n};\n\n// helpers for (de)compressing data with JSON metadata including encryption\n// -----------------------------------------------------------------------------\n\n/** @private */\nconst _encryptAndCompress = async (\n data: Uint8Array | string,\n encryptionKey: string,\n) => {\n const { encryptedBuffer, iv } = await encryptData(\n encryptionKey,\n deflate(data),\n );\n\n return { iv, buffer: new Uint8Array(encryptedBuffer) };\n};\n\n/**\n * The returned buffer has following format:\n * `[]` refers to a buffers wrapper (see `concatBuffers`)\n *\n * [\n * encodingMetadataBuffer,\n * iv,\n * [\n * contentsMetadataBuffer\n * contentsBuffer\n * ]\n * ]\n */\nexport const compressData = async <T extends Record<string, any> = never>(\n dataBuffer: Uint8Array,\n options: {\n encryptionKey: string;\n } & ([T] extends [never]\n ? {\n metadata?: T;\n }\n : {\n metadata: T;\n }),\n): Promise<Uint8Array> => {\n const fileInfo: FileEncodingInfo = {\n version: 2,\n compression: \"pako@1\",\n encryption: \"AES-GCM\",\n };\n\n const encodingMetadataBuffer = new TextEncoder().encode(\n JSON.stringify(fileInfo),\n );\n\n const contentsMetadataBuffer = new TextEncoder().encode(\n JSON.stringify(options.metadata || null),\n );\n\n const { iv, buffer } = await _encryptAndCompress(\n concatBuffers(contentsMetadataBuffer, dataBuffer),\n options.encryptionKey,\n );\n\n return concatBuffers(encodingMetadataBuffer, iv, buffer);\n};\n\n/** @private */\nconst _decryptAndDecompress = async (\n iv: Uint8Array,\n decryptedBuffer: Uint8Array,\n decryptionKey: string,\n isCompressed: boolean,\n) => {\n decryptedBuffer = new Uint8Array(\n await decryptData(iv, decryptedBuffer, decryptionKey),\n );\n\n if (isCompressed) {\n return inflate(decryptedBuffer);\n }\n\n return decryptedBuffer;\n};\n\nexport const decompressData = async <T extends Record<string, any>>(\n bufferView: Uint8Array,\n options: { decryptionKey: string },\n) => {\n // first chunk is encoding metadata (ignored for now)\n const [encodingMetadataBuffer, iv, buffer] = splitBuffers(bufferView);\n\n const encodingMetadata: FileEncodingInfo = JSON.parse(\n new TextDecoder().decode(encodingMetadataBuffer),\n );\n\n try {\n const [contentsMetadataBuffer, contentsBuffer] = splitBuffers(\n await _decryptAndDecompress(\n iv,\n buffer,\n options.decryptionKey,\n !!encodingMetadata.compression,\n ),\n );\n\n const metadata = JSON.parse(\n new TextDecoder().decode(contentsMetadataBuffer),\n ) as T;\n\n return {\n /** metadata source is always JSON so we can decode it here */\n metadata,\n /** data can be anything so the caller must decode it */\n data: contentsBuffer,\n };\n } catch (error: any) {\n console.error(\n `Error during decompressing and decrypting the file.`,\n encodingMetadata,\n );\n throw error;\n }\n};\n\n// -----------------------------------------------------------------------------\n", "import type { AppProps, AppState, NormalizedZoomValue } from \"./types\";\nimport type { ExcalidrawElement, FontFamilyValues } from \"./element/types\";\n\nexport const isDarwin = /Mac|iPod|iPhone|iPad/.test(navigator.platform);\nexport const isWindows = /^Win/.test(navigator.platform);\nexport const isAndroid = /\\b(android)\\b/i.test(navigator.userAgent);\nexport const isFirefox =\n \"netscape\" in window &&\n navigator.userAgent.indexOf(\"rv:\") > 1 &&\n navigator.userAgent.indexOf(\"Gecko\") > 1;\nexport const isChrome = navigator.userAgent.indexOf(\"Chrome\") !== -1;\nexport const isSafari =\n !isChrome && navigator.userAgent.indexOf(\"Safari\") !== -1;\nexport const isIOS =\n /iPad|iPhone/.test(navigator.platform) ||\n // iPadOS 13+\n (navigator.userAgent.includes(\"Mac\") && \"ontouchend\" in document);\n// keeping function so it can be mocked in test\nexport const isBrave = () =>\n (navigator as any).brave?.isBrave?.name === \"isBrave\";\n\nexport const supportsResizeObserver =\n typeof window !== \"undefined\" && \"ResizeObserver\" in window;\n\nexport const APP_NAME = \"Excalidraw\";\n\n// distance when creating text before it's considered `autoResize: false`\n// we're using higher threshold so that clicks that end up being drags\n// don't unintentionally create text elements that are wrapped to a few chars\n// (happens a lot with fast clicks with the text tool)\nexport const TEXT_AUTOWRAP_THRESHOLD = 36; // px\nexport const DRAGGING_THRESHOLD = 10; // px\nexport const LINE_CONFIRM_THRESHOLD = 8; // px\nexport const ELEMENT_SHIFT_TRANSLATE_AMOUNT = 5;\nexport const ELEMENT_TRANSLATE_AMOUNT = 1;\nexport const TEXT_TO_CENTER_SNAP_THRESHOLD = 30;\nexport const SHIFT_LOCKING_ANGLE = Math.PI / 12;\nexport const DEFAULT_LASER_COLOR = \"red\";\nexport const CURSOR_TYPE = {\n TEXT: \"text\",\n CROSSHAIR: \"crosshair\",\n GRABBING: \"grabbing\",\n GRAB: \"grab\",\n POINTER: \"pointer\",\n MOVE: \"move\",\n AUTO: \"\",\n};\nexport const POINTER_BUTTON = {\n MAIN: 0,\n WHEEL: 1,\n SECONDARY: 2,\n TOUCH: -1,\n ERASER: 5,\n} as const;\n\nexport const POINTER_EVENTS = {\n enabled: \"all\",\n disabled: \"none\",\n // asserted as any so it can be freely assigned to React Element\n // \"pointerEnvets\" CSS prop\n inheritFromUI: \"var(--ui-pointerEvents)\" as any,\n} as const;\n\nexport enum EVENT {\n COPY = \"copy\",\n PASTE = \"paste\",\n CUT = \"cut\",\n KEYDOWN = \"keydown\",\n KEYUP = \"keyup\",\n MOUSE_MOVE = \"mousemove\",\n RESIZE = \"resize\",\n UNLOAD = \"unload\",\n FOCUS = \"focus\",\n BLUR = \"blur\",\n DRAG_OVER = \"dragover\",\n DROP = \"drop\",\n GESTURE_END = \"gestureend\",\n BEFORE_UNLOAD = \"beforeunload\",\n GESTURE_START = \"gesturestart\",\n GESTURE_CHANGE = \"gesturechange\",\n POINTER_MOVE = \"pointermove\",\n POINTER_DOWN = \"pointerdown\",\n POINTER_UP = \"pointerup\",\n STATE_CHANGE = \"statechange\",\n WHEEL = \"wheel\",\n TOUCH_START = \"touchstart\",\n TOUCH_END = \"touchend\",\n HASHCHANGE = \"hashchange\",\n VISIBILITY_CHANGE = \"visibilitychange\",\n SCROLL = \"scroll\",\n // custom events\n EXCALIDRAW_LINK = \"excalidraw-link\",\n MENU_ITEM_SELECT = \"menu.itemSelect\",\n MESSAGE = \"message\",\n FULLSCREENCHANGE = \"fullscreenchange\",\n}\n\nexport const YOUTUBE_STATES = {\n UNSTARTED: -1,\n ENDED: 0,\n PLAYING: 1,\n PAUSED: 2,\n BUFFERING: 3,\n CUED: 5,\n} as const;\n\nexport const ENV = {\n TEST: \"test\",\n};\n\nexport const CLASSES = {\n SHAPE_ACTIONS_MENU: \"App-menu__left\",\n ZOOM_ACTIONS: \"zoom-actions\",\n SEARCH_MENU_INPUT_WRAPPER: \"layer-ui__search-inputWrapper\",\n};\n\nexport const CJK_HAND_DRAWN_FALLBACK_FONT = \"Xiaolai\";\nexport const WINDOWS_EMOJI_FALLBACK_FONT = \"Segoe UI Emoji\";\n\n/**\n * // TODO: shouldn't be really `const`, likely neither have integers as values, due to value for the custom fonts, which should likely be some hash.\n *\n * Let's think this through and consider:\n * - https://developer.mozilla.org/en-US/docs/Web/CSS/generic-family\n * - https://drafts.csswg.org/css-fonts-4/#font-family-prop\n * - https://learn.microsoft.com/en-us/typography/opentype/spec/ibmfc\n */\nexport const FONT_FAMILY = {\n Virgil: 1,\n Helvetica: 2,\n Cascadia: 3,\n // leave 4 unused as it was historically used for Assistant (which we don't use anymore) or custom font (Obsidian)\n Excalifont: 5,\n Nunito: 6,\n \"Lilita One\": 7,\n \"Comic Shanns\": 8,\n \"Liberation Sans\": 9,\n};\n\nexport const FONT_FAMILY_FALLBACKS = {\n [CJK_HAND_DRAWN_FALLBACK_FONT]: 100,\n [WINDOWS_EMOJI_FALLBACK_FONT]: 1000,\n};\n\nexport const getFontFamilyFallbacks = (\n fontFamily: number,\n): Array<keyof typeof FONT_FAMILY_FALLBACKS> => {\n switch (fontFamily) {\n case FONT_FAMILY.Excalifont:\n return [CJK_HAND_DRAWN_FALLBACK_FONT, WINDOWS_EMOJI_FALLBACK_FONT];\n default:\n return [WINDOWS_EMOJI_FALLBACK_FONT];\n }\n};\n\nexport const THEME = {\n LIGHT: \"light\",\n DARK: \"dark\",\n} as const;\n\nexport const FRAME_STYLE = {\n strokeColor: \"#bbb\" as ExcalidrawElement[\"strokeColor\"],\n strokeWidth: 2 as ExcalidrawElement[\"strokeWidth\"],\n strokeStyle: \"solid\" as ExcalidrawElement[\"strokeStyle\"],\n fillStyle: \"solid\" as ExcalidrawElement[\"fillStyle\"],\n roughness: 0 as ExcalidrawElement[\"roughness\"],\n roundness: null as ExcalidrawElement[\"roundness\"],\n backgroundColor: \"transparent\" as ExcalidrawElement[\"backgroundColor\"],\n radius: 8,\n nameOffsetY: 3,\n nameColorLightTheme: \"#999999\",\n nameColorDarkTheme: \"#7a7a7a\",\n nameFontSize: 14,\n nameLineHeight: 1.25,\n};\n\nexport const MIN_FONT_SIZE = 1;\nexport const DEFAULT_FONT_SIZE = 20;\nexport const DEFAULT_FONT_FAMILY: FontFamilyValues = FONT_FAMILY.Excalifont;\nexport const DEFAULT_TEXT_ALIGN = \"left\";\nexport const DEFAULT_VERTICAL_ALIGN = \"top\";\nexport const DEFAULT_VERSION = \"{version}\";\nexport const DEFAULT_TRANSFORM_HANDLE_SPACING = 2;\nexport const DEFAULT_ZOOM_VALUE = 1 as NormalizedZoomValue;\n\n// -----------------------------------------------\n// !!! these colors are tied to color picker !!!\nexport const COLOR_WHITE = \"#ffffff\";\nexport const COLOR_CHARCOAL_BLACK = \"#1e1e1e\";\nexport const COLOR_TRANSPARENT = \"transparent\";\n// -----------------------------------------------\n\nexport const SIDE_RESIZING_THRESHOLD = 2 * DEFAULT_TRANSFORM_HANDLE_SPACING;\n// a small epsilon to make side resizing always take precedence\n// (avoids an increase in renders and changes to tests)\nexport const EPSILON = 0.00001;\nexport const DEFAULT_COLLISION_THRESHOLD =\n 2 * SIDE_RESIZING_THRESHOLD - EPSILON;\n\n// keep this in sync with CSS\nexport const COLOR_VOICE_CALL = \"#a2f1a6\";\n\nexport const CANVAS_ONLY_ACTIONS = [\"selectAll\"];\n\nexport const DEFAULT_GRID_SIZE = 20;\nexport const DEFAULT_GRID_STEP = 5;\n\nexport const IMAGE_MIME_TYPES = {\n svg: \"image/svg+xml\",\n png: \"image/png\",\n jpg: \"image/jpeg\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n bmp: \"image/bmp\",\n ico: \"image/x-icon\",\n avif: \"image/avif\",\n jfif: \"image/jfif\",\n} as const;\n\nexport const MIME_TYPES = {\n text: \"text/plain\",\n html: \"text/html\",\n json: \"application/json\",\n // excalidraw data\n excalidraw: \"application/vnd.excalidraw+json\",\n excalidrawlib: \"application/vnd.excalidrawlib+json\",\n // image-encoded excalidraw data\n \"excalidraw.svg\": \"image/svg+xml\",\n \"excalidraw.png\": \"image/png\",\n // binary\n binary: \"application/octet-stream\",\n // image\n ...IMAGE_MIME_TYPES,\n} as const;\n\nexport const ALLOWED_PASTE_MIME_TYPES = [\n MIME_TYPES.text,\n MIME_TYPES.html,\n ...Object.values(IMAGE_MIME_TYPES),\n] as const;\n\nexport const EXPORT_IMAGE_TYPES = {\n png: \"png\",\n svg: \"svg\",\n clipboard: \"clipboard\",\n} as const;\n\nexport const EXPORT_DATA_TYPES = {\n excalidraw: \"excalidraw\",\n excalidrawClipboard: \"excalidraw/clipboard\",\n excalidrawLibrary: \"excalidrawlib\",\n excalidrawClipboardWithAPI: \"excalidraw-api/clipboard\",\n} as const;\n\nexport const EXPORT_SOURCE =\n window.EXCALIDRAW_EXPORT_SOURCE || window.location.origin;\n\n// time in milliseconds\nexport const IMAGE_RENDER_TIMEOUT = 500;\nexport const TAP_TWICE_TIMEOUT = 300;\nexport const TOUCH_CTX_MENU_TIMEOUT = 500;\nexport const TITLE_TIMEOUT = 10000;\nexport const VERSION_TIMEOUT = 30000;\nexport const SCROLL_TIMEOUT = 100;\nexport const ZOOM_STEP = 0.1;\nexport const MIN_ZOOM = 0.1;\nexport const MAX_ZOOM = 30;\nexport const HYPERLINK_TOOLTIP_DELAY = 300;\n\n// Report a user inactive after IDLE_THRESHOLD milliseconds\nexport const IDLE_THRESHOLD = 60_000;\n// Report a user active each ACTIVE_THRESHOLD milliseconds\nexport const ACTIVE_THRESHOLD = 3_000;\n\n// duplicates --theme-filter, should be removed soon\nexport const THEME_FILTER = \"invert(93%) hue-rotate(180deg)\";\n\nexport const URL_QUERY_KEYS = {\n addLibrary: \"addLibrary\",\n} as const;\n\nexport const URL_HASH_KEYS = {\n addLibrary: \"addLibrary\",\n} as const;\n\nexport const DEFAULT_UI_OPTIONS: AppProps[\"UIOptions\"] = {\n canvasActions: {\n changeViewBackgroundColor: true,\n clearCanvas: true,\n export: { saveFileToDisk: true },\n loadScene: true,\n saveToActiveFile: true,\n toggleTheme: null,\n saveAsImage: true,\n },\n tools: {\n image: true,\n },\n};\n\n// breakpoints\n// -----------------------------------------------------------------------------\n// md screen\nexport const MQ_MAX_WIDTH_PORTRAIT = 800;\nexport const MQ_MAX_WIDTH_LANDSCAPE = 1000;\nexport const MQ_MAX_HEIGHT_LANDSCAPE = 500;\n// sidebar\nexport const MQ_RIGHT_SIDEBAR_MIN_WIDTH = 1229;\n// -----------------------------------------------------------------------------\n\nexport const LIBRARY_SIDEBAR_WIDTH = 302;\n\nexport const MAX_DECIMALS_FOR_SVG_EXPORT = 2;\n\nexport const EXPORT_SCALES = [1, 2, 3];\nexport const DEFAULT_EXPORT_PADDING = 10; // px\n\nexport const DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT = 1440;\n\nexport const MAX_ALLOWED_FILE_BYTES = 4 * 1024 * 1024;\n\nexport const SVG_NS = \"http://www.w3.org/2000/svg\";\n\nexport const ENCRYPTION_KEY_BITS = 128;\n\nexport const VERSIONS = {\n excalidraw: 2,\n excalidrawLibrary: 2,\n} as const;\n\nexport const BOUND_TEXT_PADDING = 5;\nexport const ARROW_LABEL_WIDTH_FRACTION = 0.7;\nexport const ARROW_LABEL_FONT_SIZE_TO_MIN_WIDTH_RATIO = 11;\n\nexport const VERTICAL_ALIGN = {\n TOP: \"top\",\n MIDDLE: \"middle\",\n BOTTOM: \"bottom\",\n};\n\nexport const TEXT_ALIGN = {\n LEFT: \"left\",\n CENTER: \"center\",\n RIGHT: \"right\",\n};\n\nexport const ELEMENT_READY_TO_ERASE_OPACITY = 20;\n\n// Radius represented as 25% of element's largest side (width/height).\n// Used for LEGACY and PROPORTIONAL_RADIUS algorithms, or when the element is\n// below the cutoff size.\nexport const DEFAULT_PROPORTIONAL_RADIUS = 0.25;\n// Fixed radius for the ADAPTIVE_RADIUS algorithm. In pixels.\nexport const DEFAULT_ADAPTIVE_RADIUS = 32;\n// roundness type (algorithm)\nexport const ROUNDNESS = {\n // Used for legacy rounding (rectangles), which currently works the same\n // as PROPORTIONAL_RADIUS, but we need to differentiate for UI purposes and\n // forwards-compat.\n LEGACY: 1,\n\n // Used for linear elements & diamonds\n PROPORTIONAL_RADIUS: 2,\n\n // Current default algorithm for rectangles, using fixed pixel radius.\n // It's working similarly to a regular border-radius, but attemps to make\n // radius visually similar across differnt element sizes, especially\n // very large and very small elements.\n //\n // NOTE right now we don't allow configuration and use a constant radius\n // (see DEFAULT_ADAPTIVE_RADIUS constant)\n ADAPTIVE_RADIUS: 3,\n} as const;\n\nexport const ROUGHNESS = {\n architect: 0,\n artist: 1,\n cartoonist: 2,\n} as const;\n\nexport const STROKE_WIDTH = {\n thin: 1,\n bold: 2,\n extraBold: 4,\n} as const;\n\nexport const DEFAULT_ELEMENT_PROPS: {\n strokeColor: ExcalidrawElement[\"strokeColor\"];\n backgroundColor: ExcalidrawElement[\"backgroundColor\"];\n fillStyle: ExcalidrawElement[\"fillStyle\"];\n strokeWidth: ExcalidrawElement[\"strokeWidth\"];\n strokeStyle: ExcalidrawElement[\"strokeStyle\"];\n roughness: ExcalidrawElement[\"roughness\"];\n opacity: ExcalidrawElement[\"opacity\"];\n locked: ExcalidrawElement[\"locked\"];\n} = {\n strokeColor: COLOR_CHARCOAL_BLACK,\n backgroundColor: COLOR_TRANSPARENT,\n fillStyle: \"solid\",\n strokeWidth: 2,\n strokeStyle: \"solid\",\n roughness: ROUGHNESS.artist,\n opacity: 100,\n locked: false,\n};\n\nexport const LIBRARY_SIDEBAR_TAB = \"library\";\nexport const CANVAS_SEARCH_TAB = \"search\";\n\nexport const DEFAULT_SIDEBAR = {\n name: \"default\",\n defaultTab: LIBRARY_SIDEBAR_TAB,\n} as const;\n\nexport const LIBRARY_DISABLED_TYPES = new Set([\n \"iframe\",\n \"embeddable\",\n \"image\",\n] as const);\n\n// use these constants to easily identify reference sites\nexport const TOOL_TYPE = {\n selection: \"selection\",\n rectangle: \"rectangle\",\n diamond: \"diamond\",\n ellipse: \"ellipse\",\n arrow: \"arrow\",\n line: \"line\",\n freedraw: \"freedraw\",\n text: \"text\",\n image: \"image\",\n eraser: \"eraser\",\n hand: \"hand\",\n frame: \"frame\",\n magicframe: \"magicframe\",\n embeddable: \"embeddable\",\n laser: \"laser\",\n} as const;\n\nexport const EDITOR_LS_KEYS = {\n OAI_API_KEY: \"excalidraw-oai-api-key\",\n // legacy naming (non)scheme\n MERMAID_TO_EXCALIDRAW: \"mermaid-to-excalidraw\",\n PUBLISH_LIBRARY: \"publish-library-data\",\n} as const;\n\n/**\n * not translated as this is used only in public, stateless API as default value\n * where filename is optional and we can't retrieve name from app state\n */\nexport const DEFAULT_FILENAME = \"Untitled\";\n\nexport const STATS_PANELS = { generalStats: 1, elementProperties: 2 } as const;\n\nexport const MIN_WIDTH_OR_HEIGHT = 1;\n\nexport const ARROW_TYPE: { [T in AppState[\"currentItemArrowType\"]]: T } = {\n sharp: \"sharp\",\n round: \"round\",\n elbow: \"elbow\",\n};\n\nexport const DEFAULT_REDUCED_GLOBAL_ALPHA = 0.3;\nexport const ELEMENT_LINK_KEY = \"element\";\n\n/** used in tests */\nexport const ORIG_ID = Symbol.for(\"__test__originalId__\");\n\nexport enum UserIdleState {\n ACTIVE = \"active\",\n AWAY = \"away\",\n IDLE = \"idle\",\n}\n", "import { nanoid } from \"nanoid\";\nimport { cleanAppStateForExport } from \"../appState\";\nimport { IMAGE_MIME_TYPES, MIME_TYPES } from \"../constants\";\nimport { clearElementsForExport } from \"../element\";\nimport type { ExcalidrawElement, FileId } from \"../element/types\";\nimport { CanvasError, ImageSceneDataError } from \"../errors\";\nimport { calculateScrollCenter } from \"../scene\";\nimport { decodeSvgBase64Payload } from \"../scene/export\";\nimport type { AppState, DataURL, LibraryItem } from \"../types\";\nimport type { ValueOf } from \"../utility-types\";\nimport { bytesToHexString, isPromiseLike } from \"../utils\";\nimport { base64ToString, stringToBase64, toByteString } from \"./encode\";\nimport type { FileSystemHandle } from \"./filesystem\";\nimport { nativeFileSystemSupported } from \"./filesystem\";\nimport { isValidExcalidrawData, isValidLibrary } from \"./json\";\nimport { restore, restoreLibraryItems } from \"./restore\";\nimport type { ImportedLibraryData } from \"./types\";\n\nconst parseFileContents = async (blob: Blob | File): Promise<string> => {\n let contents: string;\n\n if (blob.type === MIME_TYPES.png) {\n try {\n return await (await import(\"./image\")).decodePngMetadata(blob);\n } catch (error: any) {\n if (error.message === \"INVALID\") {\n throw new ImageSceneDataError(\n \"Image doesn't contain scene\",\n \"IMAGE_NOT_CONTAINS_SCENE_DATA\",\n );\n } else {\n throw new ImageSceneDataError(\"Error: cannot restore image\");\n }\n }\n } else {\n if (\"text\" in Blob) {\n contents = await blob.text();\n } else {\n contents = await new Promise((resolve) => {\n const reader = new FileReader();\n reader.readAsText(blob, \"utf8\");\n reader.onloadend = () => {\n if (reader.readyState === FileReader.DONE) {\n resolve(reader.result as string);\n }\n };\n });\n }\n if (blob.type === MIME_TYPES.svg) {\n try {\n return decodeSvgBase64Payload({\n svg: contents,\n });\n } catch (error: any) {\n if (error.message === \"INVALID\") {\n throw new ImageSceneDataError(\n \"Image doesn't contain scene\",\n \"IMAGE_NOT_CONTAINS_SCENE_DATA\",\n );\n } else {\n throw new ImageSceneDataError(\"Error: cannot restore image\");\n }\n }\n }\n }\n return contents;\n};\n\nexport const getMimeType = (blob: Blob | string): string => {\n let name: string;\n if (typeof blob === \"string\") {\n name = blob;\n } else {\n if (blob.type) {\n return blob.type;\n }\n name = blob.name || \"\";\n }\n if (/\\.(excalidraw|json)$/.test(name)) {\n return MIME_TYPES.json;\n } else if (/\\.png$/.test(name)) {\n return MIME_TYPES.png;\n } else if (/\\.jpe?g$/.test(name)) {\n return MIME_TYPES.jpg;\n } else if (/\\.svg$/.test(name)) {\n return MIME_TYPES.svg;\n }\n return \"\";\n};\n\nexport const getFileHandleType = (handle: FileSystemHandle | null) => {\n if (!handle) {\n return null;\n }\n\n return handle.name.match(/\\.(json|excalidraw|png|svg)$/)?.[1] || null;\n};\n\nexport const isImageFileHandleType = (\n type: string | null,\n): type is \"png\" | \"svg\" => {\n return type === \"png\" || type === \"svg\";\n};\n\nexport const isImageFileHandle = (handle: FileSystemHandle | null) => {\n const type = getFileHandleType(handle);\n return type === \"png\" || type === \"svg\";\n};\n\nexport const isSupportedImageFileType = (type: string | null | undefined) => {\n return !!type && (Object.values(IMAGE_MIME_TYPES) as string[]).includes(type);\n};\n\nexport const isSupportedImageFile = (\n blob: Blob | null | undefined,\n): blob is Blob & { type: ValueOf<typeof IMAGE_MIME_TYPES> } => {\n const { type } = blob || {};\n return isSupportedImageFileType(type);\n};\n\nexport const loadSceneOrLibraryFromBlob = async (\n blob: Blob | File,\n /** @see restore.localAppState */\n localAppState: AppState | null,\n localElements: readonly ExcalidrawElement[] | null,\n /** FileSystemHandle. Defaults to `blob.handle` if defined, otherwise null. */\n fileHandle?: FileSystemHandle | null,\n) => {\n const contents = await parseFileContents(blob);\n let data;\n try {\n try {\n data = JSON.parse(contents);\n } catch (error: any) {\n if (isSupportedImageFile(blob)) {\n throw new ImageSceneDataError(\n \"Image doesn't contain scene\",\n \"IMAGE_NOT_CONTAINS_SCENE_DATA\",\n );\n }\n throw error;\n }\n if (isValidExcalidrawData(data)) {\n return {\n type: MIME_TYPES.excalidraw,\n data: restore(\n {\n elements: clearElementsForExport(data.elements || []),\n appState: {\n theme: localAppState?.theme,\n fileHandle: fileHandle || blob.handle || null,\n ...cleanAppStateForExport(data.appState || {}),\n ...(localAppState\n ? calculateScrollCenter(data.elements || [], localAppState)\n : {}),\n },\n files: data.files,\n },\n localAppState,\n localElements,\n { repairBindings: true, refreshDimensions: false },\n ),\n };\n } else if (isValidLibrary(data)) {\n return {\n type: MIME_TYPES.excalidrawlib,\n data,\n };\n }\n throw new Error(\"Error: invalid file\");\n } catch (error: any) {\n if (error instanceof ImageSceneDataError) {\n throw error;\n }\n throw new Error(\"Error: invalid file\");\n }\n};\n\nexport const loadFromBlob = async (\n blob: Blob,\n /** @see restore.localAppState */\n localAppState: AppState | null,\n localElements: readonly ExcalidrawElement[] | null,\n /** FileSystemHandle. Defaults to `blob.handle` if defined, otherwise null. */\n fileHandle?: FileSystemHandle | null,\n) => {\n const ret = await loadSceneOrLibraryFromBlob(\n blob,\n localAppState,\n localElements,\n fileHandle,\n );\n if (ret.type !== MIME_TYPES.excalidraw) {\n throw new Error(\"Error: invalid file\");\n }\n return ret.data;\n};\n\nexport const parseLibraryJSON = (\n json: string,\n defaultStatus: LibraryItem[\"status\"] = \"unpublished\",\n) => {\n const data: ImportedLibraryData | undefined = JSON.parse(json);\n if (!isValidLibrary(data)) {\n throw new Error(\"Invalid library\");\n }\n const libraryItems = data.libraryItems || data.library;\n return restoreLibraryItems(libraryItems, defaultStatus);\n};\n\nexport const loadLibraryFromBlob = async (\n blob: Blob,\n defaultStatus: LibraryItem[\"status\"] = \"unpublished\",\n) => {\n return parseLibraryJSON(await parseFileContents(blob), defaultStatus);\n};\n\nexport const canvasToBlob = async (\n canvas: HTMLCanvasElement | Promise<HTMLCanvasElement>,\n): Promise<Blob> => {\n return new Promise(async (resolve, reject) => {\n try {\n if (isPromiseLike(canvas)) {\n canvas = await canvas;\n }\n canvas.toBlob((blob) => {\n if (!blob) {\n return reject(\n new CanvasError(\"Error: Canvas too big\", \"CANVAS_POSSIBLY_TOO_BIG\"),\n );\n }\n resolve(blob);\n });\n } catch (error: any) {\n reject(error);\n }\n });\n};\n\n/** generates SHA-1 digest from supplied file (if not supported, falls back\n to a 40-char base64 random id) */\nexport const generateIdFromFile = async (file: File): Promise<FileId> => {\n try {\n const hashBuffer = await window.crypto.subtle.digest(\n \"SHA-1\",\n await blobToArrayBuffer(file),\n );\n return bytesToHexString(new Uint8Array(hashBuffer)) as FileId;\n } catch (error: any) {\n console.error(error);\n // length 40 to align with the HEX length of SHA-1 (which is 160 bit)\n return nanoid(40) as FileId;\n }\n};\n\n/** async. For sync variant, use getDataURL_sync */\nexport const getDataURL = async (file: Blob | File): Promise<DataURL> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n const dataURL = reader.result as DataURL;\n resolve(dataURL);\n };\n reader.onerror = (error) => reject(error);\n reader.readAsDataURL(file);\n });\n};\n\nexport const getDataURL_sync = (\n data: string | Uint8Array | ArrayBuffer,\n mimeType: ValueOf<typeof MIME_TYPES>,\n): DataURL => {\n return `data:${mimeType};base64,${stringToBase64(\n toByteString(data),\n true,\n )}` as DataURL;\n};\n\nexport const dataURLToFile = (dataURL: DataURL, filename = \"\") => {\n const dataIndexStart = dataURL.indexOf(\",\");\n const byteString = atob(dataURL.slice(dataIndexStart + 1));\n const mimeType = dataURL.slice(0, dataIndexStart).split(\":\")[1].split(\";\")[0];\n\n const ab = new ArrayBuffer(byteString.length);\n const ia = new Uint8Array(ab);\n for (let i = 0; i < byteString.length; i++) {\n ia[i] = byteString.charCodeAt(i);\n }\n return new File([ab], filename, { type: mimeType });\n};\n\nexport const dataURLToString = (dataURL: DataURL) => {\n return base64ToString(dataURL.slice(dataURL.indexOf(\",\") + 1));\n};\n\nexport const resizeImageFile = async (\n file: File,\n opts: {\n /** undefined indicates auto */\n outputType?: typeof MIME_TYPES[\"jpg\"];\n maxWidthOrHeight: number;\n },\n): Promise<File> => {\n // SVG files shouldn't a can't be resized\n if (file.type === MIME_TYPES.svg) {\n return file;\n }\n\n const [pica, imageBlobReduce] = await Promise.all([\n import(\"pica\").then((res) => res.default),\n // a wrapper for pica for better API\n import(\"image-blob-reduce\").then((res) => res.default),\n ]);\n\n // CRA's minification settings break pica in WebWorkers, so let's disable\n // them for now\n // https://github.com/nodeca/image-blob-reduce/issues/21#issuecomment-757365513\n const reduce = imageBlobReduce({\n pica: pica({ features: [\"js\", \"wasm\"] }),\n });\n\n if (opts.outputType) {\n const { outputType } = opts;\n reduce._create_blob = function (env) {\n return this.pica.toBlob(env.out_canvas, outputType, 0.8).then((blob) => {\n env.out_blob = blob;\n return env;\n });\n };\n }\n\n if (!isSupportedImageFile(file)) {\n throw new Error(\"Error: unsupported file type\", { cause: \"UNSUPPORTED\" });\n }\n\n return new File(\n [await reduce.toBlob(file, { max: opts.maxWidthOrHeight, alpha: true })],\n file.name,\n {\n type: opts.outputType || file.type,\n },\n );\n};\n\nexport const SVGStringToFile = (SVGString: string, filename: string = \"\") => {\n return new File([new TextEncoder().encode(SVGString)], filename, {\n type: MIME_TYPES.svg,\n }) as File & { type: typeof MIME_TYPES.svg };\n};\n\nexport const ImageURLToFile = async (\n imageUrl: string,\n filename: string = \"\",\n): Promise<File | undefined> => {\n let response;\n try {\n response = await fetch(imageUrl);\n } catch (error: any) {\n throw new Error(\"Error: failed to fetch image\", { cause: \"FETCH_ERROR\" });\n }\n\n if (!response.ok) {\n throw new Error(\"Error: failed to fetch image\", { cause: \"FETCH_ERROR\" });\n }\n\n const blob = await response.blob();\n\n if (blob.type && isSupportedImageFile(blob)) {\n const name = filename || blob.name || \"\";\n return new File([blob], name, { type: blob.type });\n }\n\n throw new Error(\"Error: unsupported file type\", { cause: \"UNSUPPORTED\" });\n};\n\nexport const getFileFromEvent = async (\n event: React.DragEvent<HTMLDivElement>,\n) => {\n const file = event.dataTransfer.files.item(0);\n const fileHandle = await getFileHandle(event);\n\n return { file: file ? await normalizeFile(file) : null, fileHandle };\n};\n\nexport const getFileHandle = async (\n event: React.DragEvent<HTMLDivElement>,\n): Promise<FileSystemHandle | null> => {\n if (nativeFileSystemSupported) {\n try {\n const item = event.dataTransfer.items[0];\n const handle: FileSystemHandle | null =\n (await (item as any).getAsFileSystemHandle()) || null;\n\n return handle;\n } catch (error: any) {\n console.warn(error.name, error.message);\n return null;\n }\n }\n return null;\n};\n\n/**\n * attempts to detect if a buffer is a valid image by checking its leading bytes\n */\nconst getActualMimeTypeFromImage = (buffer: ArrayBuffer) => {\n let mimeType: ValueOf<Pick<typeof MIME_TYPES, \"png\" | \"jpg\" | \"gif\">> | null =\n null;\n\n const first8Bytes = `${[...new Uint8Array(buffer).slice(0, 8)].join(\" \")} `;\n\n // uint8 leading bytes\n const headerBytes = {\n // https://en.wikipedia.org/wiki/Portable_Network_Graphics#File_header\n png: \"137 80 78 71 13 10 26 10 \",\n // https://en.wikipedia.org/wiki/JPEG#Syntax_and_structure\n // jpg is a bit wonky. Checking the first three bytes should be enough,\n // but may yield false positives. (https://stackoverflow.com/a/23360709/927631)\n jpg: \"255 216 255 \",\n // https://en.wikipedia.org/wiki/GIF#Example_GIF_file\n gif: \"71 73 70 56 57 97 \",\n };\n\n if (first8Bytes === headerBytes.png) {\n mimeType = MIME_TYPES.png;\n } else if (first8Bytes.startsWith(headerBytes.jpg)) {\n mimeType = MIME_TYPES.jpg;\n } else if (first8Bytes.startsWith(headerBytes.gif)) {\n mimeType = MIME_TYPES.gif;\n }\n return mimeType;\n};\n\nexport const createFile = (\n blob: File | Blob | ArrayBuffer,\n mimeType: ValueOf<typeof MIME_TYPES>,\n name: string | undefined,\n) => {\n return new File([blob], name || \"\", {\n type: mimeType,\n });\n};\n\n/** attempts to detect correct mimeType if none is set, or if an image\n * has an incorrect extension.\n * Note: doesn't handle missing .excalidraw/.excalidrawlib extension */\nexport const normalizeFile = async (file: File) => {\n if (!file.type) {\n if (file?.name?.endsWith(\".excalidrawlib\")) {\n file = createFile(\n await blobToArrayBuffer(file),\n MIME_TYPES.excalidrawlib,\n file.name,\n );\n } else if (file?.name?.endsWith(\".excalidraw\")) {\n file = createFile(\n await blobToArrayBuffer(file),\n MIME_TYPES.excalidraw,\n file.name,\n );\n } else {\n const buffer = await blobToArrayBuffer(file);\n const mimeType = getActualMimeTypeFromImage(buffer);\n if (mimeType) {\n file = createFile(buffer, mimeType, file.name);\n }\n }\n // when the file is an image, make sure the extension corresponds to the\n // actual mimeType (this is an edge case, but happens sometime)\n } else if (isSupportedImageFile(file)) {\n const buffer = await blobToArrayBuffer(file);\n const mimeType = getActualMimeTypeFromImage(buffer);\n if (mimeType && mimeType !== file.type) {\n file = createFile(buffer, mimeType, file.name);\n }\n }\n\n return file;\n};\n\nexport const blobToArrayBuffer = (blob: Blob): Promise<ArrayBuffer> => {\n if (\"arrayBuffer\" in blob) {\n return blob.arrayBuffer();\n }\n // Safari\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = (event) => {\n if (!event.target?.result) {\n return reject(new Error(\"Couldn't convert blob to ArrayBuffer\"));\n }\n resolve(event.target.result as ArrayBuffer);\n };\n reader.readAsArrayBuffer(blob);\n });\n};\n", "import {\n ARROW_TYPE,\n COLOR_WHITE,\n DEFAULT_ELEMENT_PROPS,\n DEFAULT_FONT_FAMILY,\n DEFAULT_FONT_SIZE,\n DEFAULT_TEXT_ALIGN,\n DEFAULT_GRID_SIZE,\n DEFAULT_ZOOM_VALUE,\n EXPORT_SCALES,\n STATS_PANELS,\n THEME,\n DEFAULT_GRID_STEP,\n} from \"./constants\";\nimport type { AppState } from \"./types\";\n\nconst defaultExportScale = EXPORT_SCALES.includes(devicePixelRatio)\n ? devicePixelRatio\n : 1;\n\nexport const getDefaultAppState = (): Omit<\n AppState,\n \"offsetTop\" | \"offsetLeft\" | \"width\" | \"height\"\n> => {\n return {\n showWelcomeScreen: false,\n theme: THEME.LIGHT,\n collaborators: new Map(),\n currentChartType: \"bar\",\n currentItemBackgroundColor: DEFAULT_ELEMENT_PROPS.backgroundColor,\n currentItemEndArrowhead: \"arrow\",\n currentItemFillStyle: DEFAULT_ELEMENT_PROPS.fillStyle,\n currentItemFontFamily: DEFAULT_FONT_FAMILY,\n currentItemFontSize: DEFAULT_FONT_SIZE,\n currentItemOpacity: DEFAULT_ELEMENT_PROPS.opacity,\n currentItemRoughness: DEFAULT_ELEMENT_PROPS.roughness,\n currentItemStartArrowhead: null,\n currentItemStrokeColor: DEFAULT_ELEMENT_PROPS.strokeColor,\n currentItemRoundness: \"round\",\n currentItemArrowType: ARROW_TYPE.round,\n currentItemStrokeStyle: DEFAULT_ELEMENT_PROPS.strokeStyle,\n currentItemStrokeWidth: DEFAULT_ELEMENT_PROPS.strokeWidth,\n currentItemTextAlign: DEFAULT_TEXT_ALIGN,\n currentHoveredFontFamily: null,\n cursorButton: \"up\",\n activeEmbeddable: null,\n newElement: null,\n editingTextElement: null,\n editingGroupId: null,\n editingLinearElement: null,\n activeTool: {\n type: \"selection\",\n customType: null,\n locked: DEFAULT_ELEMENT_PROPS.locked,\n lastActiveTool: null,\n },\n penMode: false,\n penDetected: false,\n errorMessage: null,\n exportBackground: true,\n exportScale: defaultExportScale,\n exportEmbedScene: false,\n exportWithDarkMode: false,\n fileHandle: null,\n gridSize: DEFAULT_GRID_SIZE,\n gridStep: DEFAULT_GRID_STEP,\n gridModeEnabled: false,\n isBindingEnabled: true,\n defaultSidebarDockedPreference: false,\n isLoading: false,\n isResizing: false,\n isRotating: false,\n lastPointerDownWith: \"mouse\",\n multiElement: null,\n name: null,\n contextMenu: null,\n openMenu: null,\n openPopup: null,\n openSidebar: null,\n openDialog: null,\n pasteDialog: { shown: false, data: null },\n previousSelectedElementIds: {},\n resizingElement: null,\n scrolledOutside: false,\n scrollX: 0,\n scrollY: 0,\n selectedElementIds: {},\n hoveredElementIds: {},\n selectedGroupIds: {},\n selectedElementsAreBeingDragged: false,\n selectionElement: null,\n shouldCacheIgnoreZoom: false,\n stats: {\n open: false,\n panels: STATS_PANELS.generalStats | STATS_PANELS.elementProperties,\n },\n startBoundElement: null,\n suggestedBindings: [],\n frameRendering: { enabled: true, clip: true, name: true, outline: true },\n frameToHighlight: null,\n editingFrame: null,\n elementsToHighlight: null,\n toast: null,\n viewBackgroundColor: COLOR_WHITE,\n zenModeEnabled: false,\n zoom: {\n value: DEFAULT_ZOOM_VALUE,\n },\n viewModeEnabled: false,\n pendingImageElementId: null,\n showHyperlinkPopup: false,\n selectedLinearElement: null,\n snapLines: [],\n originSnapOffset: {\n x: 0,\n y: 0,\n },\n objectsSnapModeEnabled: false,\n userToFollow: null,\n followedBy: new Set(),\n isCropping: false,\n croppingElementId: null,\n searchMatches: [],\n };\n};\n\n/**\n * Config containing all AppState keys. Used to determine whether given state\n * prop should be stripped when exporting to given storage type.\n */\nconst APP_STATE_STORAGE_CONF = (<\n Values extends {\n /** whether to keep when storing to browser storage (localStorage/IDB) */\n browser: boolean;\n /** whether to keep when exporting to file/database */\n export: boolean;\n /** server (shareLink/collab/...) */\n server: boolean;\n },\n T extends Record<keyof AppState, Values>,\n>(config: { [K in keyof T]: K extends keyof AppState ? T[K] : never }) =>\n config)({\n showWelcomeScreen: { browser: true, export: false, server: false },\n theme: { browser: true, export: false, server: false },\n collaborators: { browser: false, export: false, server: false },\n currentChartType: { browser: true, export: false, server: false },\n currentItemBackgroundColor: { browser: true, export: false, server: false },\n currentItemEndArrowhead: { browser: true, export: false, server: false },\n currentItemFillStyle: { browser: true, export: false, server: false },\n currentItemFontFamily: { browser: true, export: false, server: false },\n currentItemFontSize: { browser: true, export: false, server: false },\n currentItemRoundness: {\n browser: true,\n export: false,\n server: false,\n },\n currentItemArrowType: {\n browser: true,\n export: false,\n server: false,\n },\n currentItemOpacity: { browser: true, export: false, server: false },\n currentItemRoughness: { browser: true, export: false, server: false },\n currentItemStartArrowhead: { browser: true, export: false, server: false },\n currentItemStrokeColor: { browser: true, export: false, server: false },\n currentItemStrokeStyle: { browser: true, export: false, server: false },\n currentItemStrokeWidth: { browser: true, export: false, server: false },\n currentItemTextAlign: { browser: true, export: false, server: false },\n currentHoveredFontFamily: { browser: false, export: false, server: false },\n cursorButton: { browser: true, export: false, server: false },\n activeEmbeddable: { browser: false, export: false, server: false },\n newElement: { browser: false, export: false, server: false },\n editingTextElement: { browser: false, export: false, server: false },\n editingGroupId: { browser: true, export: false, server: false },\n editingLinearElement: { browser: false, export: false, server: false },\n activeTool: { browser: true, export: false, server: false },\n penMode: { browser: true, export: false, server: false },\n penDetected: { browser: true, export: false, server: false },\n errorMessage: { browser: false, export: false, server: false },\n exportBackground: { browser: true, export: false, server: false },\n exportEmbedScene: { browser: true, export: false, server: false },\n exportScale: { browser: true, export: false, server: false },\n exportWithDarkMode: { browser: true, export: false, server: false },\n fileHandle: { browser: false, export: false, server: false },\n gridSize: { browser: true, export: true, server: true },\n gridStep: { browser: true, export: true, server: true },\n gridModeEnabled: { browser: true, export: true, server: true },\n height: { browser: false, export: false, server: false },\n isBindingEnabled: { browser: false, export: false, server: false },\n defaultSidebarDockedPreference: {\n browser: true,\n export: false,\n server: false,\n },\n isLoading: { browser: false, export: false, server: false },\n isResizing: { browser: false, export: false, server: false },\n isRotating: { browser: false, export: false, server: false },\n lastPointerDownWith: { browser: true, export: false, server: false },\n multiElement: { browser: false, export: false, server: false },\n name: { browser: true, export: false, server: false },\n offsetLeft: { browser: false, export: false, server: false },\n offsetTop: { browser: false, export: false, server: false },\n contextMenu: { browser: false, export: false, server: false },\n openMenu: { browser: true, export: false, server: false },\n openPopup: { browser: false, export: false, server: false },\n openSidebar: { browser: true, export: false, server: false },\n openDialog: { browser: false, export: false, server: false },\n pasteDialog: { browser: false, export: false, server: false },\n previousSelectedElementIds: { browser: true, export: false, server: false },\n resizingElement: { browser: false, export: false, server: false },\n scrolledOutside: { browser: true, export: false, server: false },\n scrollX: { browser: true, export: false, server: false },\n scrollY: { browser: true, export: false, server: false },\n selectedElementIds: { browser: true, export: false, server: false },\n hoveredElementIds: { browser: false, export: false, server: false },\n selectedGroupIds: { browser: true, export: false, server: false },\n selectedElementsAreBeingDragged: {\n browser: false,\n export: false,\n server: false,\n },\n selectionElement: { browser: false, export: false, server: false },\n shouldCacheIgnoreZoom: { browser: true, export: false, server: false },\n stats: { browser: true, export: false, server: false },\n startBoundElement: { browser: false, export: false, server: false },\n suggestedBindings: { browser: false, export: false, server: false },\n frameRendering: { browser: false, export: false, server: false },\n frameToHighlight: { browser: false, export: false, server: false },\n editingFrame: { browser: false, export: false, server: false },\n elementsToHighlight: { browser: false, export: false, server: false },\n toast: { browser: false, export: false, server: false },\n viewBackgroundColor: { browser: true, export: true, server: true },\n width: { browser: false, export: false, server: false },\n zenModeEnabled: { browser: true, export: false, server: false },\n zoom: { browser: true, export: false, server: false },\n viewModeEnabled: { browser: false, export: false, server: false },\n pendingImageElementId: { browser: false, export: false, server: false },\n showHyperlinkPopup: { browser: false, export: false, server: false },\n selectedLinearElement: { browser: true, export: false, server: false },\n snapLines: { browser: false, export: false, server: false },\n originSnapOffset: { browser: false, export: false, server: false },\n objectsSnapModeEnabled: { browser: true, export: false, server: false },\n userToFollow: { browser: false, export: false, server: false },\n followedBy: { browser: false, export: false, server: false },\n isCropping: { browser: false, export: false, server: false },\n croppingElementId: { browser: false, export: false, server: false },\n searchMatches: { browser: false, export: false, server: false },\n});\n\nconst _clearAppStateForStorage = <\n ExportType extends \"export\" | \"browser\" | \"server\",\n>(\n appState: Partial<AppState>,\n exportType: ExportType,\n) => {\n type ExportableKeys = {\n [K in keyof typeof APP_STATE_STORAGE_CONF]: typeof APP_STATE_STORAGE_CONF[K][ExportType] extends true\n ? K\n : never;\n }[keyof typeof APP_STATE_STORAGE_CONF];\n const stateForExport = {} as { [K in ExportableKeys]?: typeof appState[K] };\n for (const key of Object.keys(appState) as (keyof typeof appState)[]) {\n const propConfig = APP_STATE_STORAGE_CONF[key];\n if (propConfig?.[exportType]) {\n const nextValue = appState[key];\n\n // https://github.com/microsoft/TypeScript/issues/31445\n (stateForExport as any)[key] = nextValue;\n }\n }\n return stateForExport;\n};\n\nexport const clearAppStateForLocalStorage = (appState: Partial<AppState>) => {\n return _clearAppStateForStorage(appState, \"browser\");\n};\n\nexport const cleanAppStateForExport = (appState: Partial<AppState>) => {\n return _clearAppStateForStorage(appState, \"export\");\n};\n\nexport const clearAppStateForDatabase = (appState: Partial<AppState>) => {\n return _clearAppStateForStorage(appState, \"server\");\n};\n\nexport const isEraserActive = ({\n activeTool,\n}: {\n activeTool: AppState[\"activeTool\"];\n}) => activeTool.type === \"eraser\";\n\nexport const isHandToolActive = ({\n activeTool,\n}: {\n activeTool: AppState[\"activeTool\"];\n}) => {\n return activeTool.type === \"hand\";\n};\n", "import throttle from \"lodash.throttle\";\nimport type {\n ExcalidrawElement,\n NonDeletedExcalidrawElement,\n NonDeleted,\n ExcalidrawFrameLikeElement,\n ElementsMapOrArray,\n SceneElementsMap,\n NonDeletedSceneElementsMap,\n OrderedExcalidrawElement,\n Ordered,\n} from \"../element/types\";\nimport { isNonDeletedElement } from \"../element\";\nimport type { LinearElementEditor } from \"../element/linearElementEditor\";\nimport { isFrameLikeElement } from \"../element/typeChecks\";\nimport { getSelectedElements } from \"./selection\";\nimport type { AppState } from \"../types\";\nimport type { Assert, SameType } from \"../utility-types\";\nimport { randomInteger } from \"../random\";\nimport {\n syncInvalidIndices,\n syncMovedIndices,\n validateFractionalIndices,\n} from \"../fractionalIndex\";\nimport { arrayToMap } from \"../utils\";\nimport { toBrandedType } from \"../utils\";\nimport { ENV } from \"../constants\";\nimport { getElementsInGroup } from \"../groups\";\n\ntype ElementIdKey = InstanceType<typeof LinearElementEditor>[\"elementId\"];\ntype ElementKey = ExcalidrawElement | ElementIdKey;\n\ntype SceneStateCallback = () => void;\ntype SceneStateCallbackRemover = () => void;\n\ntype SelectionHash = string & { __brand: \"selectionHash\" };\n\nconst getNonDeletedElements = <T extends ExcalidrawElement>(\n allElements: readonly T[],\n) => {\n const elementsMap = new Map() as NonDeletedSceneElementsMap;\n const elements: T[] = [];\n for (const element of allElements) {\n if (!element.isDeleted) {\n elements.push(element as NonDeleted<T>);\n elementsMap.set(\n element.id,\n element as Ordered<NonDeletedExcalidrawElement>,\n );\n }\n }\n return { elementsMap, elements };\n};\n\nconst validateIndicesThrottled = throttle(\n (elements: readonly ExcalidrawElement[]) => {\n if (\n import.meta.env.DEV ||\n import.meta.env.MODE === ENV.TEST ||\n window?.DEBUG_FRACTIONAL_INDICES\n ) {\n validateFractionalIndices(elements, {\n // throw only in dev & test, to remain functional on `DEBUG_FRACTIONAL_INDICES`\n shouldThrow: import.meta.env.DEV || import.meta.env.MODE === ENV.TEST,\n includeBoundTextValidation: true,\n });\n }\n },\n 1000 * 60,\n { leading: true, trailing: false },\n);\n\nconst hashSelectionOpts = (\n opts: Parameters<InstanceType<typeof Scene>[\"getSelectedElements\"]>[0],\n) => {\n const keys = [\"includeBoundTextElement\", \"includeElementsInFrames\"] as const;\n\n type HashableKeys = Omit<typeof opts, \"selectedElementIds\" | \"elements\">;\n\n // just to ensure we're hashing all expected keys\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n type _ = Assert<\n SameType<\n Required<HashableKeys>,\n Pick<Required<HashableKeys>, typeof keys[number]>\n >\n >;\n\n let hash = \"\";\n for (const key of keys) {\n hash += `${key}:${opts[key] ? \"1\" : \"0\"}`;\n }\n return hash as SelectionHash;\n};\n\n// ideally this would be a branded type but it'd be insanely hard to work with\n// in our codebase\nexport type ExcalidrawElementsIncludingDeleted = readonly ExcalidrawElement[];\n\nconst isIdKey = (elementKey: ElementKey): elementKey is ElementIdKey => {\n if (typeof elementKey === \"string\") {\n return true;\n }\n return false;\n};\n\nclass Scene {\n // ---------------------------------------------------------------------------\n // static methods/props\n // ---------------------------------------------------------------------------\n\n private static sceneMapByElement = new WeakMap<ExcalidrawElement, Scene>();\n private static sceneMapById = new Map<string, Scene>();\n\n static mapElementToScene(elementKey: ElementKey, scene: Scene) {\n if (isIdKey(elementKey)) {\n // for cases where we don't have access to the element object\n // (e.g. restore serialized appState with id references)\n this.sceneMapById.set(elementKey, scene);\n } else {\n this.sceneMapByElement.set(elementKey, scene);\n // if mapping element objects, also cache the id string when later\n // looking up by id alone\n this.sceneMapById.set(elementKey.id, scene);\n }\n }\n\n /**\n * @deprecated pass down `app.scene` and use it directly\n */\n static getScene(elementKey: ElementKey): Scene | null {\n if (isIdKey(elementKey)) {\n return this.sceneMapById.get(elementKey) || null;\n }\n return this.sceneMapByElement.get(elementKey) || null;\n }\n\n // ---------------------------------------------------------------------------\n // instance methods/props\n // ---------------------------------------------------------------------------\n\n private callbacks: Set<SceneStateCallback> = new Set();\n\n private nonDeletedElements: readonly Ordered<NonDeletedExcalidrawElement>[] =\n [];\n private nonDeletedElementsMap = toBrandedType<NonDeletedSceneElementsMap>(\n new Map(),\n );\n // ideally all elements within the scene should be wrapped around with `Ordered` type, but right now there is no real benefit doing so\n private elements: readonly OrderedExcalidrawElement[] = [];\n private nonDeletedFramesLikes: readonly NonDeleted<ExcalidrawFrameLikeElement>[] =\n [];\n private frames: readonly ExcalidrawFrameLikeElement[] = [];\n private elementsMap = toBrandedType<SceneElementsMap>(new Map());\n private selectedElementsCache: {\n selectedElementIds: AppState[\"selectedElementIds\"] | null;\n elements: readonly NonDeletedExcalidrawElement[] | null;\n cache: Map<SelectionHash, NonDeletedExcalidrawElement[]>;\n } = {\n selectedElementIds: null,\n elements: null,\n cache: new Map(),\n };\n /**\n * Random integer regenerated each scene update.\n *\n * Does not relate to elements versions, it's only a renderer\n * cache-invalidation nonce at the moment.\n */\n private sceneNonce: number | undefined;\n\n getSceneNonce() {\n return this.sceneNonce;\n }\n\n getNonDeletedElementsMap() {\n return this.nonDeletedElementsMap;\n }\n\n getElementsIncludingDeleted() {\n return this.elements;\n }\n\n getElementsMapIncludingDeleted() {\n return this.elementsMap;\n }\n\n getNonDeletedElements() {\n return this.nonDeletedElements;\n }\n\n getFramesIncludingDeleted() {\n return this.frames;\n }\n\n getSelectedElements(opts: {\n // NOTE can be ommitted by making Scene constructor require App instance\n selectedElementIds: AppState[\"selectedElementIds\"];\n /**\n * for specific cases where you need to use elements not from current\n * scene state. This in effect will likely result in cache-miss, and\n * the cache won't be updated in this case.\n */\n elements?: ElementsMapOrArray;\n // selection-related options\n includeBoundTextElement?: boolean;\n includeElementsInFrames?: boolean;\n }): NonDeleted<ExcalidrawElement>[] {\n const hash = hashSelectionOpts(opts);\n\n const elements = opts?.elements || this.nonDeletedElements;\n if (\n this.selectedElementsCache.elements === elements &&\n this.selectedElementsCache.selectedElementIds === opts.selectedElementIds\n ) {\n const cached = this.selectedElementsCache.cache.get(hash);\n if (cached) {\n return cached;\n }\n } else if (opts?.elements == null) {\n // if we're operating on latest scene elements and the cache is not\n // storing the latest elements, clear the cache\n this.selectedElementsCache.cache.clear();\n }\n\n const selectedElements = getSelectedElements(\n elements,\n { selectedElementIds: opts.selectedElementIds },\n opts,\n );\n\n // cache only if we're not using custom elements\n if (opts?.elements == null) {\n this.selectedElementsCache.selectedElementIds = opts.selectedElementIds;\n this.selectedElementsCache.elements = this.nonDeletedElements;\n this.selectedElementsCache.cache.set(hash, selectedElements);\n }\n\n return selectedElements;\n }\n\n getNonDeletedFramesLikes(): readonly NonDeleted<ExcalidrawFrameLikeElement>[] {\n return this.nonDeletedFramesLikes;\n }\n\n getElement<T extends ExcalidrawElement>(id: T[\"id\"]): T | null {\n return (this.elementsMap.get(id) as T | undefined) || null;\n }\n\n getNonDeletedElement(\n id: ExcalidrawElement[\"id\"],\n ): NonDeleted<ExcalidrawElement> | null {\n const element = this.getElement(id);\n if (element && isNonDeletedElement(element)) {\n return element;\n }\n return null;\n }\n\n /**\n * A utility method to help with updating all scene elements, with the added\n * performance optimization of not renewing the array if no change is made.\n *\n * Maps all current excalidraw elements, invoking the callback for each\n * element. The callback should either return a new mapped element, or the\n * original element if no changes are made. If no changes are made to any\n * element, this results in a no-op. Otherwise, the newly mapped elements\n * are set as the next scene's elements.\n *\n * @returns whether a change was made\n */\n mapElements(\n iteratee: (element: ExcalidrawElement) => ExcalidrawElement,\n ): boolean {\n let didChange = false;\n const newElements = this.elements.map((element) => {\n const nextElement = iteratee(element);\n if (nextElement !== element) {\n didChange = true;\n }\n return nextElement;\n });\n if (didChange) {\n this.replaceAllElements(newElements);\n }\n return didChange;\n }\n\n replaceAllElements(nextElements: ElementsMapOrArray) {\n const _nextElements =\n // ts doesn't like `Array.isArray` of `instanceof Map`\n nextElements instanceof Array\n ? nextElements\n : Array.from(nextElements.values());\n const nextFrameLikes: ExcalidrawFrameLikeElement[] = [];\n\n validateIndicesThrottled(_nextElements);\n\n this.elements = syncInvalidIndices(_nextElements);\n this.elementsMap.clear();\n this.elements.forEach((element) => {\n if (isFrameLikeElement(element)) {\n nextFrameLikes.push(element);\n }\n this.elementsMap.set(element.id, element);\n Scene.mapElementToScene(element, this);\n });\n const nonDeletedElements = getNonDeletedElements(this.elements);\n this.nonDeletedElements = nonDeletedElements.elements;\n this.nonDeletedElementsMap = nonDeletedElements.elementsMap;\n\n this.frames = nextFrameLikes;\n this.nonDeletedFramesLikes = getNonDeletedElements(this.frames).elements;\n\n this.triggerUpdate();\n }\n\n triggerUpdate() {\n this.sceneNonce = randomInteger();\n\n for (const callback of Array.from(this.callbacks)) {\n callback();\n }\n }\n\n onUpdate(cb: SceneStateCallback): SceneStateCallbackRemover {\n if (this.callbacks.has(cb)) {\n throw new Error();\n }\n\n this.callbacks.add(cb);\n\n return () => {\n if (!this.callbacks.has(cb)) {\n throw new Error();\n }\n this.callbacks.delete(cb);\n };\n }\n\n destroy() {\n this.elements = [];\n this.nonDeletedElements = [];\n this.nonDeletedFramesLikes = [];\n this.frames = [];\n this.elementsMap.clear();\n this.selectedElementsCache.selectedElementIds = null;\n this.selectedElementsCache.elements = null;\n this.selectedElementsCache.cache.clear();\n\n Scene.sceneMapById.forEach((scene, elementKey) => {\n if (scene === this) {\n Scene.sceneMapById.delete(elementKey);\n }\n });\n\n // done not for memory leaks, but to guard against possible late fires\n // (I guess?)\n this.callbacks.clear();\n }\n\n insertElementAtIndex(element: ExcalidrawElement, index: number) {\n if (!Number.isFinite(index) || index < 0) {\n throw new Error(\n \"insertElementAtIndex can only be called with index >= 0\",\n );\n }\n\n const nextElements = [\n ...this.elements.slice(0, index),\n element,\n ...this.elements.slice(index),\n ];\n\n syncMovedIndices(nextElements, arrayToMap([element]));\n\n this.replaceAllElements(nextElements);\n }\n\n insertElementsAtIndex(elements: ExcalidrawElement[], index: number) {\n if (!elements.length) {\n return;\n }\n\n if (!Number.isFinite(index) || index < 0) {\n throw new Error(\n \"insertElementAtIndex can only be called with index >= 0\",\n );\n }\n\n const nextElements = [\n ...this.elements.slice(0, index),\n ...elements,\n ...this.elements.slice(index),\n ];\n\n syncMovedIndices(nextElements, arrayToMap(elements));\n\n this.replaceAllElements(nextElements);\n }\n\n insertElement = (element: ExcalidrawElement) => {\n const index = element.frameId\n ? this.getElementIndex(element.frameId)\n : this.elements.length;\n\n this.insertElementAtIndex(element, index);\n };\n\n insertElements = (elements: ExcalidrawElement[]) => {\n if (!elements.length) {\n return;\n }\n\n const index = elements[0]?.frameId\n ? this.getElementIndex(elements[0].frameId)\n : this.elements.length;\n\n this.insertElementsAtIndex(elements, index);\n };\n\n getElementIndex(elementId: string) {\n return this.elements.findIndex((element) => element.id === elementId);\n }\n\n getContainerElement = (\n element:\n | (ExcalidrawElement & {\n containerId: ExcalidrawElement[\"id\"] | null;\n })\n | null,\n ) => {\n if (!element) {\n return null;\n }\n if (element.containerId) {\n return this.getElement(element.containerId) || null;\n }\n return null;\n };\n\n getElementsFromId = (id: string): ExcalidrawElement[] => {\n const elementsMap = this.getNonDeletedElementsMap();\n // first check if the id is an element\n const el = elementsMap.get(id);\n if (el) {\n return [el];\n }\n\n // then, check if the id is a group\n return getElementsInGroup(elementsMap, id);\n };\n}\n\nexport default Scene;\n", "import Pool from \"es6-promise-pool\";\nimport { average } from \"@excalidraw/math\";\nimport type { EVENT } from \"./constants\";\nimport {\n COLOR_TRANSPARENT,\n DEFAULT_VERSION,\n FONT_FAMILY,\n getFontFamilyFallbacks,\n isDarwin,\n WINDOWS_EMOJI_FALLBACK_FONT,\n} from \"./constants\";\nimport type {\n ExcalidrawBindableElement,\n FontFamilyValues,\n FontString,\n} from \"./element/types\";\nimport type {\n ActiveTool,\n AppState,\n ToolType,\n UnsubscribeCallback,\n Zoom,\n} from \"./types\";\nimport type { MaybePromise, ResolutionType } from \"./utility-types\";\n\nlet mockDateTime: string | null = null;\n\nexport const setDateTimeForTests = (dateTime: string) => {\n mockDateTime = dateTime;\n};\n\nexport const 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\n return `${year}-${month}-${day}-${hr}${min}`;\n};\n\nexport const capitalizeString = (str: string) =>\n str.charAt(0).toUpperCase() + str.slice(1);\n\nexport const isToolIcon = (\n target: Element | EventTarget | null,\n): target is HTMLElement =>\n target instanceof HTMLElement && target.className.includes(\"ToolIcon\");\n\nexport const isInputLike = (\n target: Element | EventTarget | null,\n): target is\n | HTMLInputElement\n | HTMLTextAreaElement\n | HTMLSelectElement\n | HTMLBRElement\n | HTMLDivElement =>\n (target instanceof HTMLElement && target.dataset.type === \"wysiwyg\") ||\n target instanceof HTMLBRElement || // newline in wysiwyg\n target instanceof HTMLInputElement ||\n target instanceof HTMLTextAreaElement ||\n target instanceof HTMLSelectElement;\n\nexport const isInteractive = (target: Element | EventTarget | null) => {\n return (\n isInputLike(target) ||\n (target instanceof Element && !!target.closest(\"label, button\"))\n );\n};\n\nexport const isWritableElement = (\n target: Element | EventTarget | null,\n): target is\n | HTMLInputElement\n | HTMLTextAreaElement\n | HTMLBRElement\n | HTMLDivElement =>\n (target instanceof HTMLElement && target.dataset.type === \"wysiwyg\") ||\n target instanceof HTMLBRElement || // newline in wysiwyg\n target instanceof HTMLTextAreaElement ||\n (target instanceof HTMLInputElement &&\n (target.type === \"text\" ||\n target.type === \"number\" ||\n target.type === \"password\"));\n\nexport const getFontFamilyString = ({\n fontFamily,\n}: {\n fontFamily: FontFamilyValues;\n}) => {\n for (const [fontFamilyString, id] of Object.entries(FONT_FAMILY)) {\n if (id === fontFamily) {\n // TODO: we should fallback first to generic family names first\n return `${fontFamilyString}${getFontFamilyFallbacks(id)\n .map((x) => `, ${x}`)\n .join(\"\")}`;\n }\n }\n return WINDOWS_EMOJI_FALLBACK_FONT;\n};\n\n/** returns fontSize+fontFamily string for assignment to DOM elements */\nexport const getFontString = ({\n fontSize,\n fontFamily,\n}: {\n fontSize: number;\n fontFamily: FontFamilyValues;\n}) => {\n return `${fontSize}px ${getFontFamilyString({ fontFamily })}` as FontString;\n};\n\nexport const debounce = <T extends any[]>(\n fn: (...args: T) => void,\n timeout: number,\n) => {\n let handle = 0;\n let lastArgs: T | null = null;\n const ret = (...args: T) => {\n lastArgs = args;\n clearTimeout(handle);\n handle = window.setTimeout(() => {\n lastArgs = null;\n fn(...args);\n }, timeout);\n };\n ret.flush = () => {\n clearTimeout(handle);\n if (lastArgs) {\n const _lastArgs = lastArgs;\n lastArgs = null;\n fn(..._lastArgs);\n }\n };\n ret.cancel = () => {\n lastArgs = null;\n clearTimeout(handle);\n };\n return ret;\n};\n\n// throttle callback to execute once per animation frame\nexport const throttleRAF = <T extends any[]>(\n fn: (...args: T) => void,\n opts?: { trailing?: boolean },\n) => {\n let timerId: number | null = null;\n let lastArgs: T | null = null;\n let lastArgsTrailing: T | null = null;\n\n const scheduleFunc = (args: T) => {\n timerId = window.requestAnimationFrame(() => {\n timerId = null;\n fn(...args);\n lastArgs = null;\n if (lastArgsTrailing) {\n lastArgs = lastArgsTrailing;\n lastArgsTrailing = null;\n scheduleFunc(lastArgs);\n }\n });\n };\n\n const ret = (...args: T) => {\n if (import.meta.env.MODE === \"test\") {\n fn(...args);\n return;\n }\n lastArgs = args;\n if (timerId === null) {\n scheduleFunc(lastArgs);\n } else if (opts?.trailing) {\n lastArgsTrailing = args;\n }\n };\n ret.flush = () => {\n if (timerId !== null) {\n cancelAnimationFrame(timerId);\n timerId = null;\n }\n if (lastArgs) {\n fn(...(lastArgsTrailing || lastArgs));\n lastArgs = lastArgsTrailing = null;\n }\n };\n ret.cancel = () => {\n lastArgs = lastArgsTrailing = null;\n if (timerId !== null) {\n cancelAnimationFrame(timerId);\n timerId = null;\n }\n };\n return ret;\n};\n\n/**\n * Exponential ease-out method\n *\n * @param {number} k - The value to be tweened.\n * @returns {number} The tweened value.\n */\nexport const easeOut = (k: number) => {\n return 1 - Math.pow(1 - k, 4);\n};\n\nconst easeOutInterpolate = (from: number, to: number, progress: number) => {\n return (to - from) * easeOut(progress) + from;\n};\n\n/**\n * Animates values from `fromValues` to `toValues` using the requestAnimationFrame API.\n * Executes the `onStep` callback on each step with the interpolated values.\n * Returns a function that can be called to cancel the animation.\n *\n * @example\n * // Example usage:\n * const fromValues = { x: 0, y: 0 };\n * const toValues = { x: 100, y: 200 };\n * const onStep = ({x, y}) => {\n * setState(x, y)\n * };\n * const onCancel = () => {\n * console.log(\"Animation canceled\");\n * };\n *\n * const cancelAnimation = easeToValuesRAF({\n * fromValues,\n * toValues,\n * onStep,\n * onCancel,\n * });\n *\n * // To cancel the animation:\n * cancelAnimation();\n */\nexport const easeToValuesRAF = <\n T extends Record<keyof T, number>,\n K extends keyof T,\n>({\n fromValues,\n toValues,\n onStep,\n duration = 250,\n interpolateValue,\n onStart,\n onEnd,\n onCancel,\n}: {\n fromValues: T;\n toValues: T;\n /**\n * Interpolate a single value.\n * Return undefined to be handled by the default interpolator.\n */\n interpolateValue?: (\n fromValue: number,\n toValue: number,\n /** no easing applied */\n progress: number,\n key: K,\n ) => number | undefined;\n onStep: (values: T) => void;\n duration?: number;\n onStart?: () => void;\n onEnd?: () => void;\n onCancel?: () => void;\n}) => {\n let canceled = false;\n let frameId = 0;\n let startTime: number;\n\n function step(timestamp: number) {\n if (canceled) {\n return;\n }\n if (startTime === undefined) {\n startTime = timestamp;\n onStart?.();\n }\n\n const elapsed = Math.min(timestamp - startTime, duration);\n const factor = easeOut(elapsed / duration);\n\n const newValues = {} as T;\n\n Object.keys(fromValues).forEach((key) => {\n const _key = key as keyof T;\n const result = ((toValues[_key] - fromValues[_key]) * factor +\n fromValues[_key]) as T[keyof T];\n newValues[_key] = result;\n });\n\n onStep(newValues);\n\n if (elapsed < duration) {\n const progress = elapsed / duration;\n\n const newValues = {} as T;\n\n Object.keys(fromValues).forEach((key) => {\n const _key = key as K;\n const startValue = fromValues[_key];\n const endValue = toValues[_key];\n\n let result;\n\n result = interpolateValue\n ? interpolateValue(startValue, endValue, progress, _key)\n : easeOutInterpolate(startValue, endValue, progress);\n\n if (result == null) {\n result = easeOutInterpolate(startValue, endValue, progress);\n }\n\n newValues[_key] = result as T[K];\n });\n onStep(newValues);\n\n frameId = window.requestAnimationFrame(step);\n } else {\n onStep(toValues);\n onEnd?.();\n }\n }\n\n frameId = window.requestAnimationFrame(step);\n\n return () => {\n onCancel?.();\n canceled = true;\n window.cancelAnimationFrame(frameId);\n };\n};\n\n// https://github.com/lodash/lodash/blob/es/chunk.js\nexport const chunk = <T extends any>(\n array: readonly T[],\n size: number,\n): T[][] => {\n if (!array.length || size < 1) {\n return [];\n }\n let index = 0;\n let resIndex = 0;\n const result = Array(Math.ceil(array.length / size));\n while (index < array.length) {\n result[resIndex++] = array.slice(index, (index += size));\n }\n return result;\n};\n\nexport const selectNode = (node: Element) => {\n const selection = window.getSelection();\n if (selection) {\n const range = document.createRange();\n range.selectNodeContents(node);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n};\n\nexport const removeSelection = () => {\n const selection = window.getSelection();\n if (selection) {\n selection.removeAllRanges();\n }\n};\n\nexport const distance = (x: number, y: number) => Math.abs(x - y);\n\nexport const updateActiveTool = (\n appState: Pick<AppState, \"activeTool\">,\n data: ((\n | {\n type: ToolType;\n }\n | { type: \"custom\"; customType: string }\n ) & { locked?: boolean }) & {\n lastActiveToolBeforeEraser?: ActiveTool | null;\n },\n): AppState[\"activeTool\"] => {\n if (data.type === \"custom\") {\n return {\n ...appState.activeTool,\n type: \"custom\",\n customType: data.customType,\n locked: data.locked ?? appState.activeTool.locked,\n };\n }\n\n return {\n ...appState.activeTool,\n lastActiveTool:\n data.lastActiveToolBeforeEraser === undefined\n ? appState.activeTool.lastActiveTool\n : data.lastActiveToolBeforeEraser,\n type: data.type,\n customType: null,\n locked: data.locked ?? appState.activeTool.locked,\n };\n};\n\nexport const isFullScreen = () =>\n document.fullscreenElement?.nodeName === \"HTML\";\n\nexport const allowFullScreen = () =>\n document.documentElement.requestFullscreen();\n\nexport const exitFullScreen = () => document.exitFullscreen();\n\nexport const getShortcutKey = (shortcut: string): string => {\n shortcut = shortcut\n .replace(/\\bAlt\\b/i, \"Alt\")\n .replace(/\\bShift\\b/i, \"Shift\")\n .replace(/\\b(Enter|Return)\\b/i, \"Enter\");\n if (isDarwin) {\n return shortcut\n .replace(/\\bCtrlOrCmd\\b/gi, \"Cmd\")\n .replace(/\\bAlt\\b/i, \"Option\");\n }\n return shortcut.replace(/\\bCtrlOrCmd\\b/gi, \"Ctrl\");\n};\n\nexport const viewportCoordsToSceneCoords = (\n { clientX, clientY }: { clientX: number; clientY: number },\n {\n zoom,\n offsetLeft,\n offsetTop,\n scrollX,\n scrollY,\n }: {\n zoom: Zoom;\n offsetLeft: number;\n offsetTop: number;\n scrollX: number;\n scrollY: number;\n },\n) => {\n const x = (clientX - offsetLeft) / zoom.value - scrollX;\n const y = (clientY - offsetTop) / zoom.value - scrollY;\n\n return { x, y };\n};\n\nexport const sceneCoordsToViewportCoords = (\n { sceneX, sceneY }: { sceneX: number; sceneY: number },\n {\n zoom,\n offsetLeft,\n offsetTop,\n scrollX,\n scrollY,\n }: {\n zoom: Zoom;\n offsetLeft: number;\n offsetTop: number;\n scrollX: number;\n scrollY: number;\n },\n) => {\n const x = (sceneX + scrollX) * zoom.value + offsetLeft;\n const y = (sceneY + scrollY) * zoom.value + offsetTop;\n return { x, y };\n};\n\nexport const getGlobalCSSVariable = (name: string) =>\n getComputedStyle(document.documentElement).getPropertyValue(`--${name}`);\n\nconst RS_LTR_CHARS =\n \"A-Za-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02B8\\u0300-\\u0590\\u0800-\\u1FFF\" +\n \"\\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/**\n * Checks whether first directional character is RTL. Meaning whether it starts\n * with RTL characters, or indeterminate (numbers etc.) characters followed by\n * RTL.\n * See https://github.com/excalidraw/excalidraw/pull/1722#discussion_r436340171\n */\nexport const isRTL = (text: string) => RE_RTL_CHECK.test(text);\n\nexport const tupleToCoors = (\n xyTuple: readonly [number, number],\n): { x: number; y: number } => {\n const [x, y] = xyTuple;\n return { x, y };\n};\n\n/** use as a rejectionHandler to mute filesystem Abort errors */\nexport const muteFSAbortError = (error?: Error) => {\n if (error?.name === \"AbortError\") {\n console.warn(error);\n return;\n }\n throw error;\n};\n\nexport const findIndex = <T>(\n array: readonly T[],\n cb: (element: T, index: number, array: readonly T[]) => boolean,\n fromIndex: number = 0,\n) => {\n if (fromIndex < 0) {\n fromIndex = array.length + fromIndex;\n }\n fromIndex = Math.min(array.length, Math.max(fromIndex, 0));\n let index = fromIndex - 1;\n while (++index < array.length) {\n if (cb(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n};\n\nexport const findLastIndex = <T>(\n array: readonly T[],\n cb: (element: T, index: number, array: readonly T[]) => boolean,\n fromIndex: number = array.length - 1,\n) => {\n if (fromIndex < 0) {\n fromIndex = array.length + fromIndex;\n }\n fromIndex = Math.min(array.length - 1, Math.max(fromIndex, 0));\n let index = fromIndex + 1;\n while (--index > -1) {\n if (cb(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n};\n\nexport const isTransparent = (color: string) => {\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 === COLOR_TRANSPARENT;\n};\n\nexport const isBindingFallthroughEnabled = (el: ExcalidrawBindableElement) =>\n el.fillStyle !== \"solid\" || isTransparent(el.backgroundColor);\n\nexport type ResolvablePromise<T> = Promise<T> & {\n resolve: [T] extends [undefined]\n ? (value?: MaybePromise<Awaited<T>>) => void\n : (value: MaybePromise<Awaited<T>>) => void;\n reject: (error: Error) => void;\n};\nexport const resolvablePromise = <T>() => {\n let resolve!: any;\n let reject!: any;\n const promise = new Promise((_resolve, _reject) => {\n resolve = _resolve;\n reject = _reject;\n });\n (promise as any).resolve = resolve;\n (promise as any).reject = reject;\n return promise as ResolvablePromise<T>;\n};\n\n//https://stackoverflow.com/a/9462382/8418\nexport const nFormatter = (num: number, digits: number): string => {\n const si = [\n { value: 1, symbol: \"b\" },\n { value: 1e3, symbol: \"k\" },\n { value: 1e6, symbol: \"M\" },\n { value: 1e9, symbol: \"G\" },\n ];\n const rx = /\\.0+$|(\\.[0-9]*[1-9])0+$/;\n let index;\n for (index = si.length - 1; index > 0; index--) {\n if (num >= si[index].value) {\n break;\n }\n }\n return (\n (num / si[index].value).toFixed(digits).replace(rx, \"$1\") + si[index].symbol\n );\n};\n\nexport const getVersion = () => {\n return (\n document.querySelector<HTMLMetaElement>('meta[name=\"version\"]')?.content ||\n DEFAULT_VERSION\n );\n};\n\n// Adapted from https://github.com/Modernizr/Modernizr/blob/master/feature-detects/emoji.js\nexport const supportsEmoji = () => {\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n return false;\n }\n const offset = 12;\n ctx.fillStyle = \"#f00\";\n ctx.textBaseline = \"top\";\n ctx.font = \"32px Arial\";\n // Modernizr used \uD83D\uDC28, but it is sort of supported on Windows 7.\n // Luckily \uD83D\uDE00 isn't supported.\n ctx.fillText(\"\uD83D\uDE00\", 0, 0);\n return ctx.getImageData(offset, offset, 1, 1).data[0] !== 0;\n};\n\nexport const getNearestScrollableContainer = (\n element: HTMLElement,\n): HTMLElement | Document => {\n let parent = element.parentElement;\n while (parent) {\n if (parent === document.body) {\n return document;\n }\n const { overflowY } = window.getComputedStyle(parent);\n const hasScrollableContent = parent.scrollHeight > parent.clientHeight;\n if (\n hasScrollableContent &&\n (overflowY === \"auto\" ||\n overflowY === \"scroll\" ||\n overflowY === \"overlay\")\n ) {\n return parent;\n }\n parent = parent.parentElement;\n }\n return document;\n};\n\nexport const focusNearestParent = (element: HTMLInputElement) => {\n let parent = element.parentElement;\n while (parent) {\n if (parent.tabIndex > -1) {\n parent.focus();\n return;\n }\n parent = parent.parentElement;\n }\n};\n\nexport const preventUnload = (event: BeforeUnloadEvent) => {\n event.preventDefault();\n // NOTE: modern browsers no longer allow showing a custom message here\n event.returnValue = \"\";\n};\n\nexport const bytesToHexString = (bytes: Uint8Array) => {\n return Array.from(bytes)\n .map((byte) => `0${byte.toString(16)}`.slice(-2))\n .join(\"\");\n};\n\nexport const getUpdatedTimestamp = () => (isTestEnv() ? 1 : Date.now());\n\n/**\n * Transforms array of objects containing `id` attribute,\n * or array of ids (strings), into a Map, keyd by `id`.\n */\nexport const arrayToMap = <T extends { id: string } | string>(\n items: readonly T[] | Map<string, T>,\n) => {\n if (items instanceof Map) {\n return items;\n }\n return items.reduce((acc: Map<string, T>, element) => {\n acc.set(typeof element === \"string\" ? element : element.id, element);\n return acc;\n }, new Map());\n};\n\nexport const arrayToMapWithIndex = <T extends { id: string }>(\n elements: readonly T[],\n) =>\n elements.reduce((acc, element: T, idx) => {\n acc.set(element.id, [element, idx]);\n return acc;\n }, new Map<string, [element: T, index: number]>());\n\n/**\n * Transform array into an object, use only when array order is irrelevant.\n */\nexport const arrayToObject = <T>(\n array: readonly T[],\n groupBy?: (value: T) => string | number,\n) =>\n array.reduce((acc, value) => {\n acc[groupBy ? groupBy(value) : String(value)] = value;\n return acc;\n }, {} as { [key: string]: T });\n\n/** Doubly linked node */\nexport type Node<T> = T & {\n prev: Node<T> | null;\n next: Node<T> | null;\n};\n\n/**\n * Creates a circular doubly linked list by adding `prev` and `next` props to the existing array nodes.\n */\nexport const arrayToList = <T>(array: readonly T[]): Node<T>[] =>\n array.reduce((acc, curr, index) => {\n const node: Node<T> = { ...curr, prev: null, next: null };\n\n // no-op for first item, we don't want circular references on a single item\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\n return acc;\n }, [] as Node<T>[]);\n\nexport const isTestEnv = () => import.meta.env.MODE === \"test\";\n\nexport const isDevEnv = () => import.meta.env.MODE === \"development\";\n\nexport const isServerEnv = () =>\n typeof process !== \"undefined\" && !!process?.env?.NODE_ENV;\n\nexport const wrapEvent = <T extends Event>(name: EVENT, nativeEvent: T) => {\n return new CustomEvent(name, {\n detail: {\n nativeEvent,\n },\n cancelable: true,\n });\n};\n\nexport const updateObject = <T extends Record<string, any>>(\n obj: T,\n updates: Partial<T>,\n): T => {\n let didChange = false;\n for (const key in updates) {\n const value = (updates as any)[key];\n if (typeof value !== \"undefined\") {\n if (\n (obj as any)[key] === value &&\n // if object, always update because its attrs could have changed\n (typeof value !== \"object\" || value === null)\n ) {\n continue;\n }\n didChange = true;\n }\n }\n\n if (!didChange) {\n return obj;\n }\n\n return {\n ...obj,\n ...updates,\n };\n};\n\nexport const isPrimitive = (val: any) => {\n const type = typeof val;\n return val == null || (type !== \"object\" && type !== \"function\");\n};\n\nexport const getFrame = () => {\n try {\n return window.self === window.top ? \"top\" : \"iframe\";\n } catch (error) {\n return \"iframe\";\n }\n};\n\nexport const isRunningInIframe = () => getFrame() === \"iframe\";\n\nexport const isPromiseLike = (\n value: any,\n): value is Promise<ResolutionType<typeof value>> => {\n return (\n !!value &&\n typeof value === \"object\" &&\n \"then\" in value &&\n \"catch\" in value &&\n \"finally\" in value\n );\n};\n\nexport const queryFocusableElements = (container: HTMLElement | null) => {\n const focusableElements = container?.querySelectorAll<HTMLElement>(\n \"button, a, input, select, textarea, div[tabindex], label[tabindex]\",\n );\n\n return focusableElements\n ? Array.from(focusableElements).filter(\n (element) =>\n element.tabIndex > -1 && !(element as HTMLInputElement).disabled,\n )\n : [];\n};\n\n/** use as a fallback after identity check (for perf reasons) */\nconst _defaultIsShallowComparatorFallback = (a: any, b: any): boolean => {\n // consider two empty arrays equal\n if (\n Array.isArray(a) &&\n Array.isArray(b) &&\n a.length === 0 &&\n b.length === 0\n ) {\n return true;\n }\n return a === b;\n};\n\n/**\n * Returns whether object/array is shallow equal.\n * Considers empty object/arrays as equal (whether top-level or second-level).\n */\nexport const isShallowEqual = <\n T extends Record<string, any>,\n K extends readonly unknown[],\n>(\n objA: T,\n objB: T,\n comparators?:\n | { [key in keyof T]?: (a: T[key], b: T[key]) => boolean }\n | (keyof T extends K[number]\n ? K extends readonly (keyof T)[]\n ? K\n : {\n _error: \"keys are either missing or include keys not in compared obj\";\n }\n : {\n _error: \"keys are either missing or include keys not in compared obj\";\n }),\n debug = false,\n) => {\n const aKeys = Object.keys(objA);\n const bKeys = Object.keys(objB);\n if (aKeys.length !== bKeys.length) {\n if (debug) {\n console.warn(\n `%cisShallowEqual: objects don't have same properties ->`,\n \"color: #8B4000\",\n objA,\n objB,\n );\n }\n return false;\n }\n\n if (comparators && Array.isArray(comparators)) {\n for (const key of comparators) {\n const ret =\n objA[key] === objB[key] ||\n _defaultIsShallowComparatorFallback(objA[key], objB[key]);\n if (!ret) {\n if (debug) {\n console.warn(\n `%cisShallowEqual: ${key} not equal ->`,\n \"color: #8B4000\",\n objA[key],\n objB[key],\n );\n }\n return false;\n }\n }\n return true;\n }\n\n return aKeys.every((key) => {\n const comparator = (\n comparators as { [key in keyof T]?: (a: T[key], b: T[key]) => boolean }\n )?.[key as keyof T];\n const ret = comparator\n ? comparator(objA[key], objB[key])\n : objA[key] === objB[key] ||\n _defaultIsShallowComparatorFallback(objA[key], objB[key]);\n\n if (!ret && debug) {\n console.warn(\n `%cisShallowEqual: ${key} not equal ->`,\n \"color: #8B4000\",\n objA[key],\n objB[key],\n );\n }\n return ret;\n });\n};\n\n// taken from Radix UI\n// https://github.com/radix-ui/primitives/blob/main/packages/core/primitive/src/primitive.tsx\nexport const composeEventHandlers = <E>(\n originalEventHandler?: (event: E) => void,\n ourEventHandler?: (event: E) => void,\n { checkForDefaultPrevented = true } = {},\n) => {\n return function handleEvent(event: E) {\n originalEventHandler?.(event);\n\n if (\n !checkForDefaultPrevented ||\n !(event as unknown as Event)?.defaultPrevented\n ) {\n return ourEventHandler?.(event);\n }\n };\n};\n\n/**\n * supply `null` as message if non-never value is valid, you just need to\n * typecheck against it\n */\nexport const assertNever = (\n value: never,\n message: string | null,\n softAssert?: boolean,\n): never => {\n if (!message) {\n return value;\n }\n if (softAssert) {\n console.error(message);\n return value;\n }\n\n throw new Error(message);\n};\n\nexport function invariant(condition: any, message: string): asserts condition {\n if (!condition) {\n throw new Error(message);\n }\n}\n\n/**\n * Memoizes on values of `opts` object (strict equality).\n */\nexport const memoize = <T extends Record<string, any>, R extends any>(\n func: (opts: T) => R,\n) => {\n let lastArgs: Map<string, any> | undefined;\n let lastResult: R | undefined;\n\n const ret = function (opts: T) {\n const currentArgs = Object.entries(opts);\n\n if (lastArgs) {\n let argsAreEqual = true;\n for (const [key, value] of currentArgs) {\n if (lastArgs.get(key) !== value) {\n argsAreEqual = false;\n break;\n }\n }\n if (argsAreEqual) {\n return lastResult;\n }\n }\n\n const result = func(opts);\n\n lastArgs = new Map(currentArgs);\n lastResult = result;\n\n return result;\n };\n\n ret.clear = () => {\n lastArgs = undefined;\n lastResult = undefined;\n };\n\n return ret as typeof func & { clear: () => void };\n};\n\n/** Checks if value is inside given collection. Useful for type-safety. */\nexport const isMemberOf = <T extends string>(\n /** Set/Map/Array/Object */\n collection: Set<T> | readonly T[] | Record<T, any> | Map<T, any>,\n /** value to look for */\n value: string,\n): value is T => {\n return collection instanceof Set || collection instanceof Map\n ? collection.has(value as T)\n : \"includes\" in collection\n ? collection.includes(value as T)\n : collection.hasOwnProperty(value);\n};\n\nexport const cloneJSON = <T>(obj: T): T => JSON.parse(JSON.stringify(obj));\n\nexport const updateStable = <T extends any[] | Record<string, any>>(\n prevValue: T,\n nextValue: T,\n) => {\n if (isShallowEqual(prevValue, nextValue)) {\n return prevValue;\n }\n return nextValue;\n};\n\n// Window\nexport function addEventListener<K extends keyof WindowEventMap>(\n target: Window & typeof globalThis,\n type: K,\n listener: (this: Window, ev: WindowEventMap[K]) => any,\n options?: boolean | AddEventListenerOptions,\n): UnsubscribeCallback;\nexport function addEventListener(\n target: Window & typeof globalThis,\n type: string,\n listener: (this: Window, ev: Event) => any,\n options?: boolean | AddEventListenerOptions,\n): UnsubscribeCallback;\n// Document\nexport function addEventListener<K extends keyof DocumentEventMap>(\n target: Document,\n type: K,\n listener: (this: Document, ev: DocumentEventMap[K]) => any,\n options?: boolean | AddEventListenerOptions,\n): UnsubscribeCallback;\nexport function addEventListener(\n target: Document,\n type: string,\n listener: (this: Document, ev: Event) => any,\n options?: boolean | AddEventListenerOptions,\n): UnsubscribeCallback;\n// FontFaceSet (document.fonts)\nexport function addEventListener<K extends keyof FontFaceSetEventMap>(\n target: FontFaceSet,\n type: K,\n listener: (this: FontFaceSet, ev: FontFaceSetEventMap[K]) => any,\n options?: boolean | AddEventListenerOptions,\n): UnsubscribeCallback;\n// HTMLElement / mix\nexport function addEventListener<K extends keyof HTMLElementEventMap>(\n target:\n | Document\n | (Window & typeof globalThis)\n | HTMLElement\n | undefined\n | null\n | false,\n type: K,\n listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any,\n options?: boolean | AddEventListenerOptions,\n): UnsubscribeCallback;\n// implem\nexport function addEventListener(\n /**\n * allows for falsy values so you don't have to type check when adding\n * event listeners to optional elements\n */\n target:\n | Document\n | (Window & typeof globalThis)\n | FontFaceSet\n | HTMLElement\n | undefined\n | null\n | false,\n type: keyof WindowEventMap | keyof DocumentEventMap | string,\n listener: (ev: Event) => any,\n options?: boolean | AddEventListenerOptions,\n): UnsubscribeCallback {\n if (!target) {\n return () => {};\n }\n target?.addEventListener?.(type, listener, options);\n return () => {\n target?.removeEventListener?.(type, listener, options);\n };\n}\n\nexport function getSvgPathFromStroke(points: number[][], 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\n let result = `M${a[0].toFixed(2)},${a[1].toFixed(2)} Q${b[0].toFixed(\n 2,\n )},${b[1].toFixed(2)} ${average(b[0], c[0]).toFixed(2)},${average(\n b[1],\n c[1],\n ).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 += `${average(a[0], b[0]).toFixed(2)},${average(a[1], b[1]).toFixed(\n 2,\n )} `;\n }\n\n if (closed) {\n result += \"Z\";\n }\n\n return result;\n}\n\nexport const normalizeEOL = (str: string) => {\n return str.replace(/\\r?\\n|\\r/g, \"\\n\");\n};\n\n// -----------------------------------------------------------------------------\ntype HasBrand<T> = {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n [K in keyof T]: K extends `~brand${infer _}` ? true : never;\n}[keyof T];\n\ntype RemoveAllBrands<T> = HasBrand<T> extends true\n ? {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n [K in keyof T as K extends `~brand~${infer _}` ? never : K]: T[K];\n }\n : never;\n\n// adapted from https://github.com/colinhacks/zod/discussions/1994#discussioncomment-6068940\n// currently does not cover all types (e.g. tuples, promises...)\ntype Unbrand<T> = T extends Map<infer E, infer F>\n ? Map<E, F>\n : T extends Set<infer E>\n ? Set<E>\n : T extends Array<infer E>\n ? Array<E>\n : RemoveAllBrands<T>;\n\n/**\n * Makes type into a branded type, ensuring that value is assignable to\n * the base ubranded type. Optionally you can explicitly supply current value\n * type to combine both (useful for composite branded types. Make sure you\n * compose branded types which are not composite themselves.)\n */\nexport const toBrandedType = <BrandedType, CurrentType = BrandedType>(\n value: Unbrand<BrandedType>,\n) => {\n return value as CurrentType & BrandedType;\n};\n\n// -----------------------------------------------------------------------------\n\n// Promise.try, adapted from https://github.com/sindresorhus/p-try\nexport const promiseTry = async <TValue, TArgs extends unknown[]>(\n fn: (...args: TArgs) => PromiseLike<TValue> | TValue,\n ...args: TArgs\n): Promise<TValue> => {\n return new Promise((resolve) => {\n resolve(fn(...args));\n });\n};\n\nexport const isAnyTrue = (...args: boolean[]): boolean =>\n Math.max(...args.map((arg) => (arg ? 1 : 0))) > 0;\n\nexport const safelyParseJSON = (json: string): Record<string, any> | null => {\n try {\n return JSON.parse(json);\n } catch {\n return null;\n }\n};\n\n// extending the missing types\n// relying on the [Index, T] to keep a correct order\ntype TPromisePool<T, Index = number> = Pool<[Index, T][]> & {\n addEventListener: (\n type: \"fulfilled\",\n listener: (event: { data: { result: [Index, T] } }) => void,\n ) => (event: { data: { result: [Index, T] } }) => void;\n removeEventListener: (\n type: \"fulfilled\",\n listener: (event: { data: { result: [Index, T] } }) => void,\n ) => void;\n};\n\nexport class PromisePool<T> {\n private readonly pool: TPromisePool<T>;\n private readonly entries: Record<number, T> = {};\n\n constructor(\n source: IterableIterator<Promise<void | readonly [number, T]>>,\n concurrency: number,\n ) {\n this.pool = new Pool(\n source as unknown as () => void | PromiseLike<[number, T][]>,\n concurrency,\n ) as TPromisePool<T>;\n }\n\n public all() {\n const listener = (event: { data: { result: void | [number, T] } }) => {\n if (event.data.result) {\n // by default pool does not return the results, so we are gathering them manually\n // with the correct call order (represented by the index in the tuple)\n const [index, value] = event.data.result;\n this.entries[index] = value;\n }\n };\n\n this.pool.addEventListener(\"fulfilled\", listener);\n\n return this.pool.start().then(() => {\n setTimeout(() => {\n this.pool.removeEventListener(\"fulfilled\", listener);\n });\n\n return Object.values(this.entries);\n });\n }\n}\n\n/**\n * use when you need to render unsafe string as HTML attribute, but MAKE SURE\n * the attribute is double-quoted when constructing the HTML string\n */\nexport const escapeDoubleQuotes = (str: string) => {\n return str.replace(/\"/g, \"&quot;\");\n};\n\nexport const castArray = <T>(value: T | T[]): T[] =>\n Array.isArray(value) ? value : [value];\n\nexport const pick = <\n R extends Record<string, any>,\n K extends readonly (keyof R)[],\n>(\n source: R,\n keys: K,\n) => {\n return keys.reduce((acc, key: K[number]) => {\n if (key in source) {\n acc[key] = source[key];\n }\n return acc;\n }, {} as Pick<R, K[number]>) as Pick<R, K[number]>;\n};\n", "export const PRECISION = 10e-5;\n\nexport const clamp = (value: number, min: number, max: number) => {\n return Math.min(Math.max(value, min), max);\n};\n\nexport const round = (\n value: number,\n precision: number,\n func: \"round\" | \"floor\" | \"ceil\" = \"round\",\n) => {\n const multiplier = Math.pow(10, precision);\n\n return Math[func]((value + Number.EPSILON) * multiplier) / multiplier;\n};\n\nexport const roundToStep = (\n value: number,\n step: number,\n func: \"round\" | \"floor\" | \"ceil\" = \"round\",\n): number => {\n const factor = 1 / step;\n return Math[func](value * factor) / factor;\n};\n\nexport const average = (a: number, b: number) => (a + b) / 2;\n\nexport const isFiniteNumber = (value: any): value is number => {\n return typeof value === \"number\" && Number.isFinite(value);\n};\n\nexport const isCloseTo = (a: number, b: number, precision = PRECISION) =>\n Math.abs(a - b) < precision;\n", "import type {\n Degrees,\n GlobalPoint,\n LocalPoint,\n PolarCoords,\n Radians,\n} from \"./types\";\nimport { PRECISION } from \"./utils\";\n\n// TODO: Simplify with modulo and fix for angles beyond 4*Math.PI and - 4*Math.PI\nexport const normalizeRadians = (angle: Radians): Radians => {\n if (angle < 0) {\n return (angle + 2 * Math.PI) as Radians;\n }\n if (angle >= 2 * Math.PI) {\n return (angle - 2 * Math.PI) as Radians;\n }\n return angle;\n};\n\n/**\n * Return the polar coordinates for the given cartesian point represented by\n * (x, y) for the center point 0,0 where the first number returned is the radius,\n * the second is the angle in radians.\n */\nexport const cartesian2Polar = <P extends GlobalPoint | LocalPoint>([\n x,\n y,\n]: P): PolarCoords => [\n Math.hypot(x, y),\n normalizeRadians(Math.atan2(y, x) as Radians),\n];\n\nexport function degreesToRadians(degrees: Degrees): Radians {\n return ((degrees * Math.PI) / 180) as Radians;\n}\n\nexport function radiansToDegrees(degrees: Radians): Degrees {\n return ((degrees * 180) / Math.PI) as Degrees;\n}\n\n/**\n * Determines if the provided angle is a right angle.\n *\n * @param rads The angle to measure\n * @returns TRUE if the provided angle is a right angle\n */\nexport function isRightAngleRads(rads: Radians): boolean {\n return Math.abs(Math.sin(2 * rads)) < PRECISION;\n}\n", "import type { GlobalPoint, LocalPoint, Vector } from \"./types\";\n\n/**\n * Create a vector from the x and y coordiante elements.\n *\n * @param x The X aspect of the vector\n * @param y T Y aspect of the vector\n * @returns The constructed vector with X and Y as the coordinates\n */\nexport function vector(\n x: number,\n y: number,\n originX: number = 0,\n originY: number = 0,\n): Vector {\n return [x - originX, y - originY] as Vector;\n}\n\n/**\n * Turn a point into a vector with the origin point.\n *\n * @param p The point to turn into a vector\n * @param origin The origin point in a given coordiante system\n * @returns The created vector from the point and the origin\n */\nexport function vectorFromPoint<Point extends GlobalPoint | LocalPoint>(\n p: Point,\n origin: Point = [0, 0] as Point,\n): Vector {\n return vector(p[0] - origin[0], p[1] - origin[1]);\n}\n\n/**\n * Cross product is a binary operation on two vectors in 2D space.\n * It results in a vector that is perpendicular to both vectors.\n *\n * @param a One of the vectors to use for the directed area calculation\n * @param b The other vector to use for the directed area calculation\n * @returns The directed area value for the two vectos\n */\nexport function vectorCross(a: Vector, b: Vector): number {\n return a[0] * b[1] - b[0] * a[1];\n}\n\n/**\n * Dot product is defined as the sum of the products of the\n * two vectors.\n *\n * @param a One of the vectors for which the sum of products is calculated\n * @param b The other vector for which the sum of products is calculated\n * @returns The sum of products of the two vectors\n */\nexport function vectorDot(a: Vector, b: Vector) {\n return a[0] * b[0] + a[1] * b[1];\n}\n\n/**\n * Determines if the value has the shape of a Vector.\n *\n * @param v The value to test\n * @returns TRUE if the value has the shape and components of a Vectors\n */\nexport function isVector(v: unknown): v is Vector {\n return (\n Array.isArray(v) &&\n v.length === 2 &&\n typeof v[0] === \"number\" &&\n !isNaN(v[0]) &&\n typeof v[1] === \"number\" &&\n !isNaN(v[1])\n );\n}\n\n/**\n * Add two vectors by adding their coordinates.\n *\n * @param a One of the vectors to add\n * @param b The other vector to add\n * @returns The sum vector of the two provided vectors\n */\nexport function vectorAdd(a: Readonly<Vector>, b: Readonly<Vector>): Vector {\n return [a[0] + b[0], a[1] + b[1]] as Vector;\n}\n\n/**\n * Add two vectors by adding their coordinates.\n *\n * @param start One of the vectors to add\n * @param end The other vector to add\n * @returns The sum vector of the two provided vectors\n */\nexport function vectorSubtract(\n start: Readonly<Vector>,\n end: Readonly<Vector>,\n): Vector {\n return [start[0] - end[0], start[1] - end[1]] as Vector;\n}\n\n/**\n * Scale vector by a scalar.\n *\n * @param v The vector to scale\n * @param scalar The scalar to multiply the vector components with\n * @returns The new scaled vector\n */\nexport function vectorScale(v: Vector, scalar: number): Vector {\n return vector(v[0] * scalar, v[1] * scalar);\n}\n\n/**\n * Calculates the sqare magnitude of a vector. Use this if you compare\n * magnitudes as it saves you an SQRT.\n *\n * @param v The vector to measure\n * @returns The scalar squared magnitude of the vector\n */\nexport function vectorMagnitudeSq(v: Vector) {\n return v[0] * v[0] + v[1] * v[1];\n}\n\n/**\n * Calculates the magnitude of a vector.\n *\n * @param v The vector to measure\n * @returns The scalar magnitude of the vector\n */\nexport function vectorMagnitude(v: Vector) {\n return Math.sqrt(vectorMagnitudeSq(v));\n}\n\n/**\n * Normalize the vector (i.e. make the vector magnitue equal 1).\n *\n * @param v The vector to normalize\n * @returns The new normalized vector\n */\nexport const vectorNormalize = (v: Vector): Vector => {\n const m = vectorMagnitude(v);\n\n if (m === 0) {\n return vector(0, 0);\n }\n\n return vector(v[0] / m, v[1] / m);\n};\n", "import { degreesToRadians } from \"./angle\";\nimport type {\n LocalPoint,\n GlobalPoint,\n Radians,\n Degrees,\n Vector,\n} from \"./types\";\nimport { PRECISION } from \"./utils\";\nimport { vectorFromPoint, vectorScale } from \"./vector\";\n\n/**\n * Create a properly typed Point instance from the X and Y coordinates.\n *\n * @param x The X coordinate\n * @param y The Y coordinate\n * @returns The branded and created point\n */\nexport function pointFrom<Point extends GlobalPoint | LocalPoint>(\n x: number,\n y: number,\n): Point {\n return [x, y] as Point;\n}\n\n/**\n * Converts and remaps an array containing a pair of numbers to Point.\n *\n * @param numberArray The number array to check and to convert to Point\n * @returns The point instance\n */\nexport function pointFromArray<Point extends GlobalPoint | LocalPoint>(\n numberArray: number[],\n): Point | undefined {\n return numberArray.length === 2\n ? pointFrom<Point>(numberArray[0], numberArray[1])\n : undefined;\n}\n\n/**\n * Converts and remaps a pair of numbers to Point.\n *\n * @param pair A number pair to convert to Point\n * @returns The point instance\n */\nexport function pointFromPair<Point extends GlobalPoint | LocalPoint>(\n pair: [number, number],\n): Point {\n return pair as Point;\n}\n\n/**\n * Convert a vector to a point.\n *\n * @param v The vector to convert\n * @returns The point the vector points at with origin 0,0\n */\nexport function pointFromVector<P extends GlobalPoint | LocalPoint>(\n v: Vector,\n offset: P = pointFrom(0, 0),\n): P {\n return pointFrom<P>(offset[0] + v[0], offset[1] + v[1]);\n}\n\n/**\n * Checks if the provided value has the shape of a Point.\n *\n * @param p The value to attempt verification on\n * @returns TRUE if the provided value has the shape of a local or global point\n */\nexport function isPoint(p: unknown): p is LocalPoint | GlobalPoint {\n return (\n Array.isArray(p) &&\n p.length === 2 &&\n typeof p[0] === \"number\" &&\n !isNaN(p[0]) &&\n typeof p[1] === \"number\" &&\n !isNaN(p[1])\n );\n}\n\n/**\n * Compare two points coordinate-by-coordinate and if\n * they are closer than INVERSE_PRECISION it returns TRUE.\n *\n * @param a Point The first point to compare\n * @param b Point The second point to compare\n * @returns TRUE if the points are sufficiently close to each other\n */\nexport function pointsEqual<Point extends GlobalPoint | LocalPoint>(\n a: Point,\n b: Point,\n): boolean {\n const abs = Math.abs;\n return abs(a[0] - b[0]) < PRECISION && abs(a[1] - b[1]) < PRECISION;\n}\n\n/**\n * Roate a point by [angle] radians.\n *\n * @param point The point to rotate\n * @param center The point to rotate around, the center point\n * @param angle The radians to rotate the point by\n * @returns The rotated point\n */\nexport function pointRotateRads<Point extends GlobalPoint | LocalPoint>(\n [x, y]: Point,\n [cx, cy]: Point,\n angle: Radians,\n): Point {\n return pointFrom(\n (x - cx) * Math.cos(angle) - (y - cy) * Math.sin(angle) + cx,\n (x - cx) * Math.sin(angle) + (y - cy) * Math.cos(angle) + cy,\n );\n}\n\n/**\n * Roate a point by [angle] degree.\n *\n * @param point The point to rotate\n * @param center The point to rotate around, the center point\n * @param angle The degree to rotate the point by\n * @returns The rotated point\n */\nexport function pointRotateDegs<Point extends GlobalPoint | LocalPoint>(\n point: Point,\n center: Point,\n angle: Degrees,\n): Point {\n return pointRotateRads(point, center, degreesToRadians(angle));\n}\n\n/**\n * Translate a point by a vector.\n *\n * WARNING: This is not for translating Excalidraw element points!\n * You need to account for rotation on base coordinates\n * on your own.\n * CONSIDER USING AN APPROPRIATE ELEMENT-AWARE TRANSLATE!\n *\n * @param p The point to apply the translation on\n * @param v The vector to translate by\n * @returns\n */\n// TODO 99% of use is translating between global and local coords, which need to be formalized\nexport function pointTranslate<\n From extends GlobalPoint | LocalPoint,\n To extends GlobalPoint | LocalPoint,\n>(p: From, v: Vector = [0, 0] as Vector): To {\n return pointFrom(p[0] + v[0], p[1] + v[1]);\n}\n\n/**\n * Find the center point at equal distance from both points.\n *\n * @param a One of the points to create the middle point for\n * @param b The other point to create the middle point for\n * @returns The middle point\n */\nexport function pointCenter<P extends LocalPoint | GlobalPoint>(a: P, b: P): P {\n return pointFrom((a[0] + b[0]) / 2, (a[1] + b[1]) / 2);\n}\n\n/**\n * Calculate the distance between two points.\n *\n * @param a First point\n * @param b Second point\n * @returns The euclidean distance between the two points.\n */\nexport function pointDistance<P extends LocalPoint | GlobalPoint>(\n a: P,\n b: P,\n): number {\n return Math.hypot(b[0] - a[0], b[1] - a[1]);\n}\n\n/**\n * Calculate the squared distance between two points.\n *\n * Note: Use this if you only compare distances, it saves a square root.\n *\n * @param a First point\n * @param b Second point\n * @returns The euclidean distance between the two points.\n */\nexport function pointDistanceSq<P extends LocalPoint | GlobalPoint>(\n a: P,\n b: P,\n): number {\n const xDiff = b[0] - a[0];\n const yDiff = b[1] - a[1];\n\n return xDiff * xDiff + yDiff * yDiff;\n}\n\n/**\n * Scale a point from a given origin by the multiplier.\n *\n * @param p The point to scale\n * @param mid The origin to scale from\n * @param multiplier The scaling factor\n * @returns\n */\nexport const pointScaleFromOrigin = <P extends GlobalPoint | LocalPoint>(\n p: P,\n mid: P,\n multiplier: number,\n) => pointTranslate(mid, vectorScale(vectorFromPoint(p, mid), multiplier));\n\n/**\n * Returns whether `q` lies inside the segment/rectangle defined by `p` and `r`.\n * This is an approximation to \"does `q` lie on a segment `pr`\" check.\n *\n * @param p The first point to compare against\n * @param q The actual point this function checks whether is in between\n * @param r The other point to compare against\n * @returns TRUE if q is indeed between p and r\n */\nexport const isPointWithinBounds = <P extends GlobalPoint | LocalPoint>(\n p: P,\n q: P,\n r: P,\n) => {\n return (\n q[0] <= Math.max(p[0], r[0]) &&\n q[0] >= Math.min(p[0], r[0]) &&\n q[1] <= Math.max(p[1], r[1]) &&\n q[1] >= Math.min(p[1], r[1])\n );\n};\n", "import { pointFrom } from \"./point\";\nimport type { GlobalPoint, Line, LocalPoint } from \"./types\";\n\n/**\n * Create a line from two points.\n *\n * @param points The two points lying on the line\n * @returns The line on which the points lie\n */\nexport function line<P extends GlobalPoint | LocalPoint>(a: P, b: P): Line<P> {\n return [a, b] as Line<P>;\n}\n\n/**\n * Determines the intersection point (unless the lines are parallel) of two\n * lines\n *\n * @param a\n * @param b\n * @returns\n */\nexport function linesIntersectAt<Point extends GlobalPoint | LocalPoint>(\n a: Line<Point>,\n b: Line<Point>,\n): Point | null {\n const A1 = a[1][1] - a[0][1];\n const B1 = a[0][0] - a[1][0];\n const A2 = b[1][1] - b[0][1];\n const B2 = b[0][0] - b[1][0];\n const D = A1 * B2 - A2 * B1;\n if (D !== 0) {\n const C1 = A1 * a[0][0] + B1 * a[0][1];\n const C2 = A2 * b[0][0] + B2 * b[0][1];\n return pointFrom<Point>((C1 * B2 - C2 * B1) / D, (A1 * C2 - A2 * C1) / D);\n }\n\n return null;\n}\n", "import { line, linesIntersectAt } from \"./line\";\nimport {\n isPoint,\n pointCenter,\n pointFromVector,\n pointRotateRads,\n} from \"./point\";\nimport type { GlobalPoint, LineSegment, LocalPoint, Radians } from \"./types\";\nimport { PRECISION } from \"./utils\";\nimport {\n vectorAdd,\n vectorCross,\n vectorFromPoint,\n vectorScale,\n vectorSubtract,\n} from \"./vector\";\n\n/**\n * Create a line segment from two points.\n *\n * @param points The two points delimiting the line segment on each end\n * @returns The line segment delineated by the points\n */\nexport function lineSegment<P extends GlobalPoint | LocalPoint>(\n a: P,\n b: P,\n): LineSegment<P> {\n return [a, b] as LineSegment<P>;\n}\n\n/**\n *\n * @param segment\n * @returns\n */\nexport const isLineSegment = <Point extends GlobalPoint | LocalPoint>(\n segment: unknown,\n): segment is LineSegment<Point> =>\n Array.isArray(segment) &&\n segment.length === 2 &&\n isPoint(segment[0]) &&\n isPoint(segment[0]);\n\n/**\n * Return the coordinates resulting from rotating the given line about an origin by an angle in radians\n * note that when the origin is not given, the midpoint of the given line is used as the origin.\n *\n * @param l\n * @param angle\n * @param origin\n * @returns\n */\nexport const lineSegmentRotate = <Point extends LocalPoint | GlobalPoint>(\n l: LineSegment<Point>,\n angle: Radians,\n origin?: Point,\n): LineSegment<Point> => {\n return lineSegment(\n pointRotateRads(l[0], origin || pointCenter(l[0], l[1]), angle),\n pointRotateRads(l[1], origin || pointCenter(l[0], l[1]), angle),\n );\n};\n\n/**\n * Calculates the point two line segments with a definite start and end point\n * intersect at.\n */\nexport const segmentsIntersectAt = <Point extends GlobalPoint | LocalPoint>(\n a: Readonly<LineSegment<Point>>,\n b: Readonly<LineSegment<Point>>,\n): Point | null => {\n const a0 = vectorFromPoint(a[0]);\n const a1 = vectorFromPoint(a[1]);\n const b0 = vectorFromPoint(b[0]);\n const b1 = vectorFromPoint(b[1]);\n const r = vectorSubtract(a1, a0);\n const s = vectorSubtract(b1, b0);\n const denominator = vectorCross(r, s);\n\n if (denominator === 0) {\n return null;\n }\n\n const i = vectorSubtract(vectorFromPoint(b[0]), vectorFromPoint(a[0]));\n const u = vectorCross(i, r) / denominator;\n const t = vectorCross(i, s) / denominator;\n\n if (u === 0) {\n return null;\n }\n\n const p = vectorAdd(a0, vectorScale(r, t));\n\n if (t >= 0 && t < 1 && u >= 0 && u < 1) {\n return pointFromVector<Point>(p);\n }\n\n return null;\n};\n\nexport const pointOnLineSegment = <Point extends LocalPoint | GlobalPoint>(\n point: Point,\n line: LineSegment<Point>,\n threshold = PRECISION,\n) => {\n const distance = distanceToLineSegment(point, line);\n\n if (distance === 0) {\n return true;\n }\n\n return distance < threshold;\n};\n\nexport const distanceToLineSegment = <Point extends LocalPoint | GlobalPoint>(\n point: Point,\n line: LineSegment<Point>,\n) => {\n const [x, y] = point;\n const [[x1, y1], [x2, y2]] = line;\n\n const A = x - x1;\n const B = y - y1;\n const C = x2 - x1;\n const D = y2 - y1;\n\n const dot = A * C + B * D;\n const len_sq = C * C + D * D;\n let param = -1;\n if (len_sq !== 0) {\n param = dot / len_sq;\n }\n\n let xx;\n let yy;\n\n if (param < 0) {\n xx = x1;\n yy = y1;\n } else if (param > 1) {\n xx = x2;\n yy = y2;\n } else {\n xx = x1 + param * C;\n yy = y1 + param * D;\n }\n\n const dx = x - xx;\n const dy = y - yy;\n return Math.sqrt(dx * dx + dy * dy);\n};\n\n/**\n * Returns the intersection point of a segment and a line\n *\n * @param l\n * @param s\n * @returns\n */\nexport function lineSegmentIntersectionPoints<\n Point extends GlobalPoint | LocalPoint,\n>(l: LineSegment<Point>, s: LineSegment<Point>): Point | null {\n const candidate = linesIntersectAt(line(l[0], l[1]), line(s[0], s[1]));\n\n if (\n !candidate ||\n !pointOnLineSegment(candidate, s) ||\n !pointOnLineSegment(candidate, l)\n ) {\n return null;\n }\n\n return candidate;\n}\n", "import { pointFrom } from \"./point\";\nimport { lineSegment, lineSegmentIntersectionPoints } from \"./segment\";\nimport type { GlobalPoint, LineSegment, LocalPoint, Rectangle } from \"./types\";\n\nexport function rectangle<P extends GlobalPoint | LocalPoint>(\n topLeft: P,\n bottomRight: P,\n): Rectangle<P> {\n return [topLeft, bottomRight] as Rectangle<P>;\n}\n\nexport function rectangleIntersectLineSegment<\n Point extends LocalPoint | GlobalPoint,\n>(r: Rectangle<Point>, l: LineSegment<Point>): Point[] {\n return [\n lineSegment(r[0], pointFrom(r[1][0], r[0][1])),\n lineSegment(pointFrom(r[1][0], r[0][1]), r[1]),\n lineSegment(r[1], pointFrom(r[0][0], r[1][1])),\n lineSegment(pointFrom(r[0][0], r[1][1]), r[0]),\n ]\n .map((s) => lineSegmentIntersectionPoints(l, s))\n .filter((i): i is Point => !!i);\n}\n", "import type { Bounds } from \"../excalidraw/element/bounds\";\nimport { isPoint, pointDistance, pointFrom } from \"./point\";\nimport { rectangle, rectangleIntersectLineSegment } from \"./rectangle\";\nimport type { Curve, GlobalPoint, LineSegment, LocalPoint } from \"./types\";\n\n/**\n *\n * @param a\n * @param b\n * @param c\n * @param d\n * @returns\n */\nexport function curve<Point extends GlobalPoint | LocalPoint>(\n a: Point,\n b: Point,\n c: Point,\n d: Point,\n) {\n return [a, b, c, d] as Curve<Point>;\n}\n\nfunction gradient(\n f: (t: number, s: number) => number,\n t0: number,\n s0: number,\n delta: number = 1e-6,\n): number[] {\n return [\n (f(t0 + delta, s0) - f(t0 - delta, s0)) / (2 * delta),\n (f(t0, s0 + delta) - f(t0, s0 - delta)) / (2 * delta),\n ];\n}\n\nfunction solve(\n f: (t: number, s: number) => [number, number],\n t0: number,\n s0: number,\n tolerance: number = 1e-3,\n iterLimit: number = 10,\n): number[] | null {\n let error = Infinity;\n let iter = 0;\n\n while (error >= tolerance) {\n if (iter >= iterLimit) {\n return null;\n }\n\n const y0 = f(t0, s0);\n const jacobian = [\n gradient((t, s) => f(t, s)[0], t0, s0),\n gradient((t, s) => f(t, s)[1], t0, s0),\n ];\n const b = [[-y0[0]], [-y0[1]]];\n const det =\n jacobian[0][0] * jacobian[1][1] - jacobian[0][1] * jacobian[1][0];\n\n if (det === 0) {\n return null;\n }\n\n const iJ = [\n [jacobian[1][1] / det, -jacobian[0][1] / det],\n [-jacobian[1][0] / det, jacobian[0][0] / det],\n ];\n const h = [\n [iJ[0][0] * b[0][0] + iJ[0][1] * b[1][0]],\n [iJ[1][0] * b[0][0] + iJ[1][1] * b[1][0]],\n ];\n\n t0 = t0 + h[0][0];\n s0 = s0 + h[1][0];\n\n const [tErr, sErr] = f(t0, s0);\n error = Math.max(Math.abs(tErr), Math.abs(sErr));\n iter += 1;\n }\n\n return [t0, s0];\n}\n\nconst bezierEquation = <Point extends GlobalPoint | LocalPoint>(\n c: Curve<Point>,\n t: number,\n) =>\n pointFrom<Point>(\n (1 - t) ** 3 * c[0][0] +\n 3 * (1 - t) ** 2 * t * c[1][0] +\n 3 * (1 - t) * t ** 2 * c[2][0] +\n t ** 3 * c[3][0],\n (1 - t) ** 3 * c[0][1] +\n 3 * (1 - t) ** 2 * t * c[1][1] +\n 3 * (1 - t) * t ** 2 * c[2][1] +\n t ** 3 * c[3][1],\n );\n\n/**\n * Computes the intersection between a cubic spline and a line segment.\n */\nexport function curveIntersectLineSegment<\n Point extends GlobalPoint | LocalPoint,\n>(c: Curve<Point>, l: LineSegment<Point>): Point[] {\n // Optimize by doing a cheap bounding box check first\n const bounds = curveBounds(c);\n if (\n rectangleIntersectLineSegment(\n rectangle(\n pointFrom(bounds[0], bounds[1]),\n pointFrom(bounds[2], bounds[3]),\n ),\n l,\n ).length === 0\n ) {\n return [];\n }\n\n const line = (s: number) =>\n pointFrom<Point>(\n l[0][0] + s * (l[1][0] - l[0][0]),\n l[0][1] + s * (l[1][1] - l[0][1]),\n );\n\n const initial_guesses: [number, number][] = [\n [0.5, 0],\n [0.2, 0],\n [0.8, 0],\n ];\n\n const calculate = ([t0, s0]: [number, number]) => {\n const solution = solve(\n (t: number, s: number) => {\n const bezier_point = bezierEquation(c, t);\n const line_point = line(s);\n\n return [\n bezier_point[0] - line_point[0],\n bezier_point[1] - line_point[1],\n ];\n },\n t0,\n s0,\n );\n\n if (!solution) {\n return null;\n }\n\n const [t, s] = solution;\n\n if (t < 0 || t > 1 || s < 0 || s > 1) {\n return null;\n }\n\n return bezierEquation(c, t);\n };\n\n let solution = calculate(initial_guesses[0]);\n if (solution) {\n return [solution];\n }\n\n solution = calculate(initial_guesses[1]);\n if (solution) {\n return [solution];\n }\n\n solution = calculate(initial_guesses[2]);\n if (solution) {\n return [solution];\n }\n\n return [];\n}\n\n/**\n * Finds the closest point on the Bezier curve from another point\n *\n * @param x\n * @param y\n * @param P0\n * @param P1\n * @param P2\n * @param P3\n * @param tolerance\n * @param maxLevel\n * @returns\n */\nexport function curveClosestPoint<Point extends GlobalPoint | LocalPoint>(\n c: Curve<Point>,\n p: Point,\n tolerance: number = 1e-3,\n): Point | null {\n const localMinimum = (\n min: number,\n max: number,\n f: (t: number) => number,\n e: number = tolerance,\n ) => {\n let m = min;\n let n = max;\n let k;\n\n while (n - m > e) {\n k = (n + m) / 2;\n if (f(k - e) < f(k + e)) {\n n = k;\n } else {\n m = k;\n }\n }\n\n return k;\n };\n\n const maxSteps = 30;\n let closestStep = 0;\n for (let min = Infinity, step = 0; step < maxSteps; step++) {\n const d = pointDistance(p, bezierEquation(c, step / maxSteps));\n if (d < min) {\n min = d;\n closestStep = step;\n }\n }\n\n const t0 = Math.max((closestStep - 1) / maxSteps, 0);\n const t1 = Math.min((closestStep + 1) / maxSteps, 1);\n const solution = localMinimum(t0, t1, (t) =>\n pointDistance(p, bezierEquation(c, t)),\n );\n\n if (!solution) {\n return null;\n }\n\n return bezierEquation(c, solution);\n}\n\n/**\n * Determines the distance between a point and the closest point on the\n * Bezier curve.\n *\n * @param c The curve to test\n * @param p The point to measure from\n */\nexport function curvePointDistance<Point extends GlobalPoint | LocalPoint>(\n c: Curve<Point>,\n p: Point,\n) {\n const closest = curveClosestPoint(c, p);\n\n if (!closest) {\n return 0;\n }\n\n return pointDistance(p, closest);\n}\n\n/**\n * Determines if the parameter is a Curve\n */\nexport function isCurve<P extends GlobalPoint | LocalPoint>(\n v: unknown,\n): v is Curve<P> {\n return (\n Array.isArray(v) &&\n v.length === 4 &&\n isPoint(v[0]) &&\n isPoint(v[1]) &&\n isPoint(v[2]) &&\n isPoint(v[3])\n );\n}\n\nfunction curveBounds<Point extends GlobalPoint | LocalPoint>(\n c: Curve<Point>,\n): Bounds {\n const [P0, P1, P2, P3] = c;\n const x = [P0[0], P1[0], P2[0], P3[0]];\n const y = [P0[1], P1[1], P2[1], P3[1]];\n return [Math.min(...x), Math.min(...y), Math.max(...x), Math.max(...y)];\n}\n", "import { pointsEqual } from \"./point\";\nimport { lineSegment, pointOnLineSegment } from \"./segment\";\nimport type { GlobalPoint, LocalPoint, Polygon } from \"./types\";\nimport { PRECISION } from \"./utils\";\n\nexport function polygon<Point extends GlobalPoint | LocalPoint>(\n ...points: Point[]\n) {\n return polygonClose(points) as Polygon<Point>;\n}\n\nexport function polygonFromPoints<Point extends GlobalPoint | LocalPoint>(\n points: Point[],\n) {\n return polygonClose(points) as Polygon<Point>;\n}\n\nexport const polygonIncludesPoint = <Point extends LocalPoint | GlobalPoint>(\n point: Point,\n polygon: Polygon<Point>,\n) => {\n const x = point[0];\n const y = point[1];\n let inside = false;\n\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const xi = polygon[i][0];\n const yi = polygon[i][1];\n const xj = polygon[j][0];\n const yj = polygon[j][1];\n\n if (\n ((yi > y && yj <= y) || (yi <= y && yj > y)) &&\n x < ((xj - xi) * (y - yi)) / (yj - yi) + xi\n ) {\n inside = !inside;\n }\n }\n\n return inside;\n};\n\nexport const pointOnPolygon = <Point extends LocalPoint | GlobalPoint>(\n p: Point,\n poly: Polygon<Point>,\n threshold = PRECISION,\n) => {\n let on = false;\n\n for (let i = 0, l = poly.length - 1; i < l; i++) {\n if (pointOnLineSegment(p, lineSegment(poly[i], poly[i + 1]), threshold)) {\n on = true;\n break;\n }\n }\n\n return on;\n};\n\nfunction polygonClose<Point extends LocalPoint | GlobalPoint>(\n polygon: Point[],\n) {\n return polygonIsClosed(polygon)\n ? polygon\n : ([...polygon, polygon[0]] as Polygon<Point>);\n}\n\nfunction polygonIsClosed<Point extends LocalPoint | GlobalPoint>(\n polygon: Point[],\n) {\n return pointsEqual(polygon[0], polygon[polygon.length - 1]);\n}\n", "import { toBrandedType } from \"@excalidraw/excalidraw/utils\";\nimport type { InclusiveRange } from \"./types\";\n\n/**\n * Create an inclusive range from the two numbers provided.\n *\n * @param start Start of the range\n * @param end End of the range\n * @returns\n */\nexport function rangeInclusive(start: number, end: number): InclusiveRange {\n return toBrandedType<InclusiveRange>([start, end]);\n}\n\n/**\n * Turn a number pair into an inclusive range.\n *\n * @param pair The number pair to convert to an inclusive range\n * @returns The new inclusive range\n */\nexport function rangeInclusiveFromPair(pair: [start: number, end: number]) {\n return toBrandedType<InclusiveRange>(pair);\n}\n\n/**\n * Given two ranges, return if the two ranges overlap with each other e.g.\n * [1, 3] overlaps with [2, 4] while [1, 3] does not overlap with [4, 5].\n *\n * @param param0 One of the ranges to compare\n * @param param1 The other range to compare against\n * @returns TRUE if the ranges overlap\n */\nexport const rangesOverlap = (\n [a0, a1]: InclusiveRange,\n [b0, b1]: InclusiveRange,\n): boolean => {\n if (a0 <= b0) {\n return a1 >= b0;\n }\n\n if (a0 >= b0) {\n return b1 >= a0;\n }\n\n return false;\n};\n\n/**\n * Given two ranges,return ther intersection of the two ranges if any e.g. the\n * intersection of [1, 3] and [2, 4] is [2, 3].\n *\n * @param param0 The first range to compare\n * @param param1 The second range to compare\n * @returns The inclusive range intersection or NULL if no intersection\n */\nexport const rangeIntersection = (\n [a0, a1]: InclusiveRange,\n [b0, b1]: InclusiveRange,\n): InclusiveRange | null => {\n const rangeStart = Math.max(a0, b0);\n const rangeEnd = Math.min(a1, b1);\n\n if (rangeStart <= rangeEnd) {\n return toBrandedType<InclusiveRange>([rangeStart, rangeEnd]);\n }\n\n return null;\n};\n\n/**\n * Determine if a value is inside a range.\n *\n * @param value The value to check\n * @param range The range\n * @returns\n */\nexport const rangeIncludesValue = (\n value: number,\n [min, max]: InclusiveRange,\n): boolean => {\n return value >= min && value <= max;\n};\n", "import type { GlobalPoint, LocalPoint, Triangle } from \"./types\";\n\n// Types\n\n/**\n * Tests if a point lies inside a triangle. This function\n * will return FALSE if the point lies exactly on the sides\n * of the triangle.\n *\n * @param triangle The triangle to test the point for\n * @param p The point to test whether is in the triangle\n * @returns TRUE if the point is inside of the triangle\n */\nexport function triangleIncludesPoint<P extends GlobalPoint | LocalPoint>(\n [a, b, c]: Triangle<P>,\n p: P,\n): boolean {\n const triangleSign = (p1: P, p2: P, p3: P) =>\n (p1[0] - p3[0]) * (p2[1] - p3[1]) - (p2[0] - p3[0]) * (p1[1] - p3[1]);\n const d1 = triangleSign(p, a, b);\n const d2 = triangleSign(p, b, c);\n const d3 = triangleSign(p, c, a);\n\n const has_neg = d1 < 0 || d2 < 0 || d3 < 0;\n const has_pos = d1 > 0 || d2 > 0 || d3 > 0;\n\n return !(has_neg && has_pos);\n}\n", "import { ROUNDNESS } from \"../constants\";\nimport type { ElementOrToolType } from \"../types\";\nimport type { MarkNonNullable } from \"../utility-types\";\nimport { assertNever } from \"../utils\";\nimport type { Bounds } from \"./bounds\";\nimport type {\n ExcalidrawElement,\n ExcalidrawTextElement,\n ExcalidrawEmbeddableElement,\n ExcalidrawLinearElement,\n ExcalidrawBindableElement,\n ExcalidrawFreeDrawElement,\n InitializedExcalidrawImageElement,\n ExcalidrawImageElement,\n ExcalidrawTextElementWithContainer,\n ExcalidrawTextContainer,\n ExcalidrawFrameElement,\n RoundnessType,\n ExcalidrawFrameLikeElement,\n ExcalidrawElementType,\n ExcalidrawIframeElement,\n ExcalidrawIframeLikeElement,\n ExcalidrawMagicFrameElement,\n ExcalidrawArrowElement,\n ExcalidrawElbowArrowElement,\n PointBinding,\n FixedPointBinding,\n ExcalidrawFlowchartNodeElement,\n} from \"./types\";\n\nexport const isInitializedImageElement = (\n element: ExcalidrawElement | null,\n): element is InitializedExcalidrawImageElement => {\n return !!element && element.type === \"image\" && !!element.fileId;\n};\n\nexport const isImageElement = (\n element: ExcalidrawElement | null,\n): element is ExcalidrawImageElement => {\n return !!element && element.type === \"image\";\n};\n\nexport const isEmbeddableElement = (\n element: ExcalidrawElement | null | undefined,\n): element is ExcalidrawEmbeddableElement => {\n return !!element && element.type === \"embeddable\";\n};\n\nexport const isIframeElement = (\n element: ExcalidrawElement | null,\n): element is ExcalidrawIframeElement => {\n return !!element && element.type === \"iframe\";\n};\n\nexport const isIframeLikeElement = (\n element: ExcalidrawElement | null,\n): element is ExcalidrawIframeLikeElement => {\n return (\n !!element && (element.type === \"iframe\" || element.type === \"embeddable\")\n );\n};\n\nexport const isTextElement = (\n element: ExcalidrawElement | null,\n): element is ExcalidrawTextElement => {\n return element != null && element.type === \"text\";\n};\n\nexport const isFrameElement = (\n element: ExcalidrawElement | null,\n): element is ExcalidrawFrameElement => {\n return element != null && element.type === \"frame\";\n};\n\nexport const isMagicFrameElement = (\n element: ExcalidrawElement | null,\n): element is ExcalidrawMagicFrameElement => {\n return element != null && element.type === \"magicframe\";\n};\n\nexport const isFrameLikeElement = (\n element: ExcalidrawElement | null,\n): element is ExcalidrawFrameLikeElement => {\n return (\n element != null &&\n (element.type === \"frame\" || element.type === \"magicframe\")\n );\n};\n\nexport const isFreeDrawElement = (\n element?: ExcalidrawElement | null,\n): element is ExcalidrawFreeDrawElement => {\n return element != null && isFreeDrawElementType(element.type);\n};\n\nexport const isFreeDrawElementType = (\n elementType: ExcalidrawElementType,\n): boolean => {\n return elementType === \"freedraw\";\n};\n\nexport const isLinearElement = (\n element?: ExcalidrawElement | null,\n): element is ExcalidrawLinearElement => {\n return element != null && isLinearElementType(element.type);\n};\n\nexport const isArrowElement = (\n element?: ExcalidrawElement | null,\n): element is ExcalidrawArrowElement => {\n return element != null && element.type === \"arrow\";\n};\n\nexport const isElbowArrow = (\n element?: ExcalidrawElement,\n): element is ExcalidrawElbowArrowElement => {\n return isArrowElement(element) && element.elbowed;\n};\n\nexport const isLinearElementType = (\n elementType: ElementOrToolType,\n): boolean => {\n return (\n elementType === \"arrow\" || elementType === \"line\" // || elementType === \"freedraw\"\n );\n};\n\nexport const isBindingElement = (\n element?: ExcalidrawElement | null,\n includeLocked = true,\n): element is ExcalidrawLinearElement => {\n return (\n element != null &&\n (!element.locked || includeLocked === true) &&\n isBindingElementType(element.type)\n );\n};\n\nexport const isBindingElementType = (\n elementType: ElementOrToolType,\n): boolean => {\n return elementType === \"arrow\";\n};\n\nexport const isBindableElement = (\n element: ExcalidrawElement | null | undefined,\n includeLocked = true,\n): element is ExcalidrawBindableElement => {\n return (\n element != null &&\n (!element.locked || includeLocked === true) &&\n (element.type === \"rectangle\" ||\n element.type === \"diamond\" ||\n element.type === \"ellipse\" ||\n element.type === \"image\" ||\n element.type === \"iframe\" ||\n element.type === \"embeddable\" ||\n element.type === \"frame\" ||\n element.type === \"magicframe\" ||\n (element.type === \"text\" && !element.containerId))\n );\n};\n\nexport const isRectanguloidElement = (\n element?: ExcalidrawElement | null,\n): element is ExcalidrawBindableElement => {\n return (\n element != null &&\n (element.type === \"rectangle\" ||\n element.type === \"diamond\" ||\n element.type === \"image\" ||\n element.type === \"iframe\" ||\n element.type === \"embeddable\" ||\n element.type === \"frame\" ||\n element.type === \"magicframe\" ||\n (element.type === \"text\" && !element.containerId))\n );\n};\n\n// TODO: Remove this when proper distance calculation is introduced\n// @see binding.ts:distanceToBindableElement()\nexport const isRectangularElement = (\n element?: ExcalidrawElement | null,\n): element is ExcalidrawBindableElement => {\n return (\n element != null &&\n (element.type === \"rectangle\" ||\n element.type === \"image\" ||\n element.type === \"text\" ||\n element.type === \"iframe\" ||\n element.type === \"embeddable\" ||\n element.type === \"frame\" ||\n element.type === \"magicframe\" ||\n element.type === \"freedraw\")\n );\n};\n\nexport const isTextBindableContainer = (\n element: ExcalidrawElement | null,\n includeLocked = true,\n): element is ExcalidrawTextContainer => {\n return (\n element != null &&\n (!element.locked || includeLocked === true) &&\n (element.type === \"rectangle\" ||\n element.type === \"diamond\" ||\n element.type === \"ellipse\" ||\n isArrowElement(element))\n );\n};\n\nexport const isExcalidrawElement = (\n element: any,\n): element is ExcalidrawElement => {\n const type: ExcalidrawElementType | undefined = element?.type;\n if (!type) {\n return false;\n }\n switch (type) {\n case \"text\":\n case \"diamond\":\n case \"rectangle\":\n case \"iframe\":\n case \"embeddable\":\n case \"ellipse\":\n case \"arrow\":\n case \"freedraw\":\n case \"line\":\n case \"frame\":\n case \"magicframe\":\n case \"image\":\n case \"selection\": {\n return true;\n }\n default: {\n assertNever(type, null);\n return false;\n }\n }\n};\n\nexport const isFlowchartNodeElement = (\n element: ExcalidrawElement,\n): element is ExcalidrawFlowchartNodeElement => {\n return (\n element.type === \"rectangle\" ||\n element.type === \"ellipse\" ||\n element.type === \"diamond\"\n );\n};\n\nexport const hasBoundTextElement = (\n element: ExcalidrawElement | null,\n): element is MarkNonNullable<ExcalidrawBindableElement, \"boundElements\"> => {\n return (\n isTextBindableContainer(element) &&\n !!element.boundElements?.some(({ type }) => type === \"text\")\n );\n};\n\nexport const isBoundToContainer = (\n element: ExcalidrawElement | null,\n): element is ExcalidrawTextElementWithContainer => {\n return (\n element !== null &&\n \"containerId\" in element &&\n element.containerId !== null &&\n isTextElement(element)\n );\n};\n\nexport const isUsingAdaptiveRadius = (type: string) =>\n type === \"rectangle\" ||\n type === \"embeddable\" ||\n type === \"iframe\" ||\n type === \"image\";\n\nexport const isUsingProportionalRadius = (type: string) =>\n type === \"line\" || type === \"arrow\" || type === \"diamond\";\n\nexport const canApplyRoundnessTypeToElement = (\n roundnessType: RoundnessType,\n element: ExcalidrawElement,\n) => {\n if (\n (roundnessType === ROUNDNESS.ADAPTIVE_RADIUS ||\n // if legacy roundness, it can be applied to elements that currently\n // use adaptive radius\n roundnessType === ROUNDNESS.LEGACY) &&\n isUsingAdaptiveRadius(element.type)\n ) {\n return true;\n }\n if (\n roundnessType === ROUNDNESS.PROPORTIONAL_RADIUS &&\n isUsingProportionalRadius(element.type)\n ) {\n return true;\n }\n\n return false;\n};\n\nexport const getDefaultRoundnessTypeForElement = (\n element: ExcalidrawElement,\n) => {\n if (isUsingProportionalRadius(element.type)) {\n return {\n type: ROUNDNESS.PROPORTIONAL_RADIUS,\n };\n }\n\n if (isUsingAdaptiveRadius(element.type)) {\n return {\n type: ROUNDNESS.ADAPTIVE_RADIUS,\n };\n }\n\n return null;\n};\n\nexport const isFixedPointBinding = (\n binding: PointBinding | FixedPointBinding,\n): binding is FixedPointBinding => {\n return (\n Object.hasOwn(binding, \"fixedPoint\") &&\n (binding as FixedPointBinding).fixedPoint != null\n );\n};\n\n// TODO: Move this to @excalidraw/math\nexport const isBounds = (box: unknown): box is Bounds =>\n Array.isArray(box) &&\n box.length === 4 &&\n typeof box[0] === \"number\" &&\n typeof box[1] === \"number\" &&\n typeof box[2] === \"number\" &&\n typeof box[3] === \"number\";\n", "import {\n BOUND_TEXT_PADDING,\n DEFAULT_FONT_SIZE,\n DEFAULT_FONT_FAMILY,\n} from \"../constants\";\nimport { getFontString, isTestEnv, normalizeEOL } from \"../utils\";\nimport type { FontString, ExcalidrawTextElement } from \"./types\";\n\nexport const measureText = (\n text: string,\n font: FontString,\n lineHeight: ExcalidrawTextElement[\"lineHeight\"],\n) => {\n const _text = text\n .split(\"\\n\")\n // replace empty lines with single space because leading/trailing empty\n // lines would be stripped from computation\n .map((x) => x || \" \")\n .join(\"\\n\");\n const fontSize = parseFloat(font);\n const height = getTextHeight(_text, fontSize, lineHeight);\n const width = getTextWidth(_text, font);\n return { width, height };\n};\n\nconst DUMMY_TEXT = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\".toLocaleUpperCase();\n\n// FIXME rename to getApproxMinContainerWidth\nexport const getApproxMinLineWidth = (\n font: FontString,\n lineHeight: ExcalidrawTextElement[\"lineHeight\"],\n) => {\n const maxCharWidth = getMaxCharWidth(font);\n if (maxCharWidth === 0) {\n return (\n measureText(DUMMY_TEXT.split(\"\").join(\"\\n\"), font, lineHeight).width +\n BOUND_TEXT_PADDING * 2\n );\n }\n return maxCharWidth + BOUND_TEXT_PADDING * 2;\n};\n\nexport const getMinTextElementWidth = (\n font: FontString,\n lineHeight: ExcalidrawTextElement[\"lineHeight\"],\n) => {\n return measureText(\"\", font, lineHeight).width + BOUND_TEXT_PADDING * 2;\n};\n\nexport const isMeasureTextSupported = () => {\n const width = getTextWidth(\n DUMMY_TEXT,\n getFontString({\n fontSize: DEFAULT_FONT_SIZE,\n fontFamily: DEFAULT_FONT_FAMILY,\n }),\n );\n return width > 0;\n};\n\nexport const normalizeText = (text: string) => {\n return (\n normalizeEOL(text)\n // replace tabs with spaces so they render and measure correctly\n .replace(/\\t/g, \" \")\n );\n};\n\nconst splitIntoLines = (text: string) => {\n return normalizeText(text).split(\"\\n\");\n};\n\n/**\n * To get unitless line-height (if unknown) we can calculate it by dividing\n * height-per-line by fontSize.\n */\nexport const detectLineHeight = (textElement: ExcalidrawTextElement) => {\n const lineCount = splitIntoLines(textElement.text).length;\n return (textElement.height /\n lineCount /\n textElement.fontSize) as ExcalidrawTextElement[\"lineHeight\"];\n};\n\n/**\n * We calculate the line height from the font size and the unitless line height,\n * aligning with the W3C spec.\n */\nexport const getLineHeightInPx = (\n fontSize: ExcalidrawTextElement[\"fontSize\"],\n lineHeight: ExcalidrawTextElement[\"lineHeight\"],\n) => {\n return fontSize * lineHeight;\n};\n\n// FIXME rename to getApproxMinContainerHeight\nexport const getApproxMinLineHeight = (\n fontSize: ExcalidrawTextElement[\"fontSize\"],\n lineHeight: ExcalidrawTextElement[\"lineHeight\"],\n) => {\n return getLineHeightInPx(fontSize, lineHeight) + BOUND_TEXT_PADDING * 2;\n};\n\nlet textMetricsProvider: TextMetricsProvider | undefined;\n\n/**\n * Set a custom text metrics provider.\n *\n * Useful for overriding the width calculation algorithm where canvas API is not available / desired.\n */\nexport const setCustomTextMetricsProvider = (provider: TextMetricsProvider) => {\n textMetricsProvider = provider;\n};\n\nexport interface TextMetricsProvider {\n getLineWidth(text: string, fontString: FontString): number;\n}\n\nclass CanvasTextMetricsProvider implements TextMetricsProvider {\n private canvas: HTMLCanvasElement;\n\n constructor() {\n this.canvas = document.createElement(\"canvas\");\n }\n\n /**\n * We need to use the advance width as that's the closest thing to the browser wrapping algo, hence using it for:\n * - text wrapping\n * - wysiwyg editor (+padding)\n *\n * > The advance width is the distance between the glyph's initial pen position and the next glyph's initial pen position.\n */\n public getLineWidth(text: string, fontString: FontString): number {\n const context = this.canvas.getContext(\"2d\")!;\n context.font = fontString;\n const metrics = context.measureText(text);\n const advanceWidth = metrics.width;\n\n // since in test env the canvas measureText algo\n // doesn't measure text and instead just returns number of\n // characters hence we assume that each letteris 10px\n if (isTestEnv()) {\n return advanceWidth * 10;\n }\n\n return advanceWidth;\n }\n}\n\nexport const getLineWidth = (text: string, font: FontString) => {\n if (!textMetricsProvider) {\n textMetricsProvider = new CanvasTextMetricsProvider();\n }\n\n return textMetricsProvider.getLineWidth(text, font);\n};\n\nexport const getTextWidth = (text: string, font: FontString) => {\n const lines = splitIntoLines(text);\n let width = 0;\n lines.forEach((line) => {\n width = Math.max(width, getLineWidth(line, font));\n });\n\n return width;\n};\n\nexport const getTextHeight = (\n text: string,\n fontSize: number,\n lineHeight: ExcalidrawTextElement[\"lineHeight\"],\n) => {\n const lineCount = splitIntoLines(text).length;\n return getLineHeightInPx(fontSize, lineHeight) * lineCount;\n};\n\nexport const charWidth = (() => {\n const cachedCharWidth: { [key: FontString]: Array<number> } = {};\n\n const calculate = (char: string, font: FontString) => {\n const unicode = char.charCodeAt(0);\n if (!cachedCharWidth[font]) {\n cachedCharWidth[font] = [];\n }\n if (!cachedCharWidth[font][unicode]) {\n const width = getLineWidth(char, font);\n cachedCharWidth[font][unicode] = width;\n }\n\n return cachedCharWidth[font][unicode];\n };\n\n const getCache = (font: FontString) => {\n return cachedCharWidth[font];\n };\n\n const clearCache = (font: FontString) => {\n cachedCharWidth[font] = [];\n };\n\n return {\n calculate,\n getCache,\n clearCache,\n };\n})();\n\nexport const getMinCharWidth = (font: FontString) => {\n const cache = charWidth.getCache(font);\n if (!cache) {\n return 0;\n }\n const cacheWithOutEmpty = cache.filter((val) => val !== undefined);\n\n return Math.min(...cacheWithOutEmpty);\n};\n\nexport const getMaxCharWidth = (font: FontString) => {\n const cache = charWidth.getCache(font);\n if (!cache) {\n return 0;\n }\n const cacheWithOutEmpty = cache.filter((val) => val !== undefined);\n return Math.max(...cacheWithOutEmpty);\n};\n", "import { ENV } from \"../constants\";\nimport { charWidth, getLineWidth } from \"./textMeasurements\";\nimport type { FontString } from \"./types\";\n\nlet cachedCjkRegex: RegExp | undefined;\nlet cachedLineBreakRegex: RegExp | undefined;\nlet cachedEmojiRegex: RegExp | undefined;\n\n/**\n * Test if a given text contains any CJK characters (including symbols, punctuation, etc,).\n */\nexport const containsCJK = (text: string) => {\n if (!cachedCjkRegex) {\n cachedCjkRegex = Regex.class(...Object.values(CJK));\n }\n\n return cachedCjkRegex.test(text);\n};\n\nconst getLineBreakRegex = () => {\n if (!cachedLineBreakRegex) {\n try {\n cachedLineBreakRegex = getLineBreakRegexAdvanced();\n } catch {\n cachedLineBreakRegex = getLineBreakRegexSimple();\n }\n }\n\n return cachedLineBreakRegex;\n};\n\nconst getEmojiRegex = () => {\n if (!cachedEmojiRegex) {\n cachedEmojiRegex = getEmojiRegexUnicode();\n }\n\n return cachedEmojiRegex;\n};\n\n/**\n * Common symbols used across different languages.\n */\nconst COMMON = {\n /**\n * Natural breaking points for any grammars.\n *\n * Hello world\n * \u2191 BREAK ALWAYS \" \" \u2192 [\"Hello\", \" \", \"world\"]\n * Hello-world\n * \u2191 BREAK AFTER \"-\" \u2192 [\"Hello-\", \"world\"]\n */\n WHITESPACE: /\\s/u,\n HYPHEN: /-/u,\n /**\n * Generally do not break, unless closed symbol is followed by an opening symbol.\n *\n * Also, western punctation is often used in modern Korean and expects to be treated\n * similarly to the CJK opening and closing symbols.\n *\n * Hello(\uD55C\uAE00)\u2192 [\"Hello\", \"(\uD55C\", \"\uAE00)\"]\n * \u2191 BREAK BEFORE \"(\"\n * \u2191 BREAK AFTER \")\"\n */\n OPENING: /<\\(\\[\\{/u,\n CLOSING: />\\)\\]\\}.,:;!\\?\u2026\\//u,\n};\n\n/**\n * Characters and symbols used in Chinese, Japanese and Korean.\n */\nconst CJK = {\n /**\n * Every CJK breaks before and after, unless it's paired with an opening or closing symbol.\n *\n * Does not include every possible char used in CJK texts, such as currency, parentheses or punctuation.\n */\n CHAR: /\\p{Script=Han}\\p{Script=Hiragana}\\p{Script=Katakana}\\p{Script=Hangul}\uFF40\uFF07\uFF3E\u3003\u3030\u3006\uFF03\uFF06\uFF0A\uFF0B\uFF0D\u30FC\uFF0F\uFF3C\uFF1D\uFF5C\uFFE4\u3012\uFFE2\uFFE3/u,\n /**\n * Opening and closing CJK punctuation breaks before and after all such characters (in case of many),\n * and creates pairs with neighboring characters.\n *\n * Hello \u305F\u3002\u2192 [\"Hello\", \"\u305F\u3002\"]\n * \u2191 DON'T BREAK \"\u305F\u3002\"\n * * Hello\u300C\u305F\u300D World \u2192 [\"Hello\", \"\u300C\u305F\u300D\", \"World\"]\n * \u2191 DON'T BREAK \"\u300C\u305F\"\n * \u2191 DON'T BREAK \"\u305F\"\n * \u2191 BREAK BEFORE \"\u300C\"\n * \u2191 BREAK AFTER \"\u300D\"\n */\n // eslint-disable-next-line prettier/prettier\n OPENING:/\uFF08\uFF3B\uFF5B\u3008\u300A\uFF5F\uFF62\u300C\u300E\u3010\u3016\u3014\u3018\u301A\uFF1C\u301D/u,\n CLOSING: /\uFF09\uFF3D\uFF5D\u3009\u300B\uFF60\uFF63\u300D\u300F\u3011\u3017\u3015\u3019\u301B\uFF1E\u3002\uFF0E\uFF0C\u3001\u301F\u2025\uFF1F\uFF01\uFF1A\uFF1B\u30FB\u301C\u301E/u,\n /**\n * Currency symbols break before, not after\n *\n * Price\uFFE5100 \u2192 [\"Price\", \"\uFFE5100\"]\n * \u2191 BREAK BEFORE \"\uFFE5\"\n */\n CURRENCY: /\uFFE5\uFFE6\uFFE1\uFFE0\uFF04/u,\n};\n\nconst EMOJI = {\n FLAG: /\\p{RI}\\p{RI}/u,\n JOINER:\n /(?:\\p{Emoji_Modifier}|\\uFE0F\\u20E3?|[\\u{E0020}-\\u{E007E}]+\\u{E007F})?/u,\n ZWJ: /\\u200D/u,\n ANY: /[\\p{Emoji}]/u,\n MOST: /[\\p{Extended_Pictographic}\\p{Emoji_Presentation}]/u,\n};\n\n/**\n * Simple fallback for browsers (mainly Safari < 16.4) that don't support \"Lookbehind assertion\".\n *\n * Browser support as of 10/2024:\n * - 91% Lookbehind assertion https://caniuse.com/mdn-javascript_regular_expressions_lookbehind_assertion\n * - 94% Unicode character class escape https://caniuse.com/mdn-javascript_regular_expressions_unicode_character_class_escape\n *\n * Does not include advanced CJK breaking rules, but covers most of the core cases, especially for latin.\n */\nconst getLineBreakRegexSimple = () =>\n Regex.or(\n getEmojiRegex(),\n Break.On(COMMON.HYPHEN, COMMON.WHITESPACE, CJK.CHAR),\n );\n\n/**\n * Specifies the line breaking rules based for alphabetic-based languages,\n * Chinese, Japanese, Korean and Emojis.\n *\n * \"Hello-world\" \u2192 [\"Hello-\", \"world\"]\n * \"Hello \u300C\u4E16\u754C\u3002\u300D\uD83C\uDF0E\uD83D\uDDFA\" \u2192 [\"Hello\", \" \", \"\u300C\u4E16\", \"\u754C\u3002\u300D\", \"\uD83C\uDF0E\", \"\uD83D\uDDFA\"]\n */\nconst getLineBreakRegexAdvanced = () =>\n Regex.or(\n // Unicode-defined regex for (multi-codepoint) Emojis\n getEmojiRegex(),\n // Rules for whitespace and hyphen\n Break.Before(COMMON.WHITESPACE).Build(),\n Break.After(COMMON.WHITESPACE, COMMON.HYPHEN).Build(),\n // Rules for CJK (chars, symbols, currency)\n Break.Before(CJK.CHAR, CJK.CURRENCY)\n .NotPrecededBy(COMMON.OPENING, CJK.OPENING)\n .Build(),\n Break.After(CJK.CHAR)\n .NotFollowedBy(COMMON.HYPHEN, COMMON.CLOSING, CJK.CLOSING)\n .Build(),\n // Rules for opening and closing punctuation\n Break.BeforeMany(CJK.OPENING).NotPrecededBy(COMMON.OPENING).Build(),\n Break.AfterMany(CJK.CLOSING).NotFollowedBy(COMMON.CLOSING).Build(),\n Break.AfterMany(COMMON.CLOSING).FollowedBy(COMMON.OPENING).Build(),\n );\n\n/**\n * Matches various emoji types.\n *\n * 1. basic emojis (\uD83D\uDE00, \uD83C\uDF0D)\n * 2. flags (\uD83C\uDDE8\uD83C\uDDFF)\n * 3. multi-codepoint emojis:\n * - skin tones (\uD83D\uDC4D\uD83C\uDFFD)\n * - variation selectors (\u2602\uFE0F)\n * - keycaps (1\uFE0F\u20E3)\n * - tag sequences (\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67\uDB40\uDC7F)\n * - emoji sequences (\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66, \uD83D\uDC69\u200D\uD83D\uDE80, \uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08)\n *\n * Unicode points:\n * - \\uFE0F: presentation selector\n * - \\u20E3: enclosing keycap\n * - \\u200D: zero width joiner\n * - \\u{E0020}-\\u{E007E}: tags\n * - \\u{E007F}: cancel tag\n *\n * @see https://unicode.org/reports/tr51/#EBNF_and_Regex, with changes:\n * - replaced \\p{Emoji} with [\\p{Extended_Pictographic}\\p{Emoji_Presentation}], see more in `should tokenize emojis mixed with mixed text` test\n * - replaced \\p{Emod} with \\p{Emoji_Modifier} as some engines do not understand the abbreviation (i.e. https://devina.io/redos-checker)\n */\nconst getEmojiRegexUnicode = () =>\n Regex.group(\n Regex.or(\n EMOJI.FLAG,\n Regex.and(\n EMOJI.MOST,\n EMOJI.JOINER,\n Regex.build(\n `(?:${EMOJI.ZWJ.source}(?:${EMOJI.FLAG.source}|${EMOJI.ANY.source}${EMOJI.JOINER.source}))*`,\n ),\n ),\n ),\n );\n\n/**\n * Regex utilities for unicode character classes.\n */\nconst Regex = {\n /**\n * Builds a regex from a string.\n */\n build: (regex: string): RegExp => new RegExp(regex, \"u\"),\n /**\n * Joins regexes into a single string.\n */\n join: (...regexes: RegExp[]): string => regexes.map((x) => x.source).join(\"\"),\n /**\n * Joins regexes into a single regex as with \"and\" operator.\n */\n and: (...regexes: RegExp[]): RegExp => Regex.build(Regex.join(...regexes)),\n /**\n * Joins regexes into a single regex with \"or\" operator.\n */\n or: (...regexes: RegExp[]): RegExp =>\n Regex.build(regexes.map((x) => x.source).join(\"|\")),\n /**\n * Puts regexes into a matching group.\n */\n group: (...regexes: RegExp[]): RegExp =>\n Regex.build(`(${Regex.join(...regexes)})`),\n /**\n * Puts regexes into a character class.\n */\n class: (...regexes: RegExp[]): RegExp =>\n Regex.build(`[${Regex.join(...regexes)}]`),\n};\n\n/**\n * Human-readable lookahead and lookbehind utilities for defining line break\n * opportunities between pairs of character classes.\n */\nconst Break = {\n /**\n * Break on the given class of characters.\n */\n On: (...regexes: RegExp[]) => {\n const joined = Regex.join(...regexes);\n return Regex.build(`([${joined}])`);\n },\n /**\n * Break before the given class of characters.\n */\n Before: (...regexes: RegExp[]) => {\n const joined = Regex.join(...regexes);\n const builder = () => Regex.build(`(?=[${joined}])`);\n return Break.Chain(builder) as Omit<\n ReturnType<typeof Break.Chain>,\n \"FollowedBy\"\n >;\n },\n /**\n * Break after the given class of characters.\n */\n After: (...regexes: RegExp[]) => {\n const joined = Regex.join(...regexes);\n const builder = () => Regex.build(`(?<=[${joined}])`);\n return Break.Chain(builder) as Omit<\n ReturnType<typeof Break.Chain>,\n \"PreceededBy\"\n >;\n },\n /**\n * Break before one or multiple characters of the same class.\n */\n BeforeMany: (...regexes: RegExp[]) => {\n const joined = Regex.join(...regexes);\n const builder = () => Regex.build(`(?<![${joined}])(?=[${joined}])`);\n return Break.Chain(builder) as Omit<\n ReturnType<typeof Break.Chain>,\n \"FollowedBy\"\n >;\n },\n /**\n * Break after one or multiple character from the same class.\n */\n AfterMany: (...regexes: RegExp[]) => {\n const joined = Regex.join(...regexes);\n const builder = () => Regex.build(`(?<=[${joined}])(?![${joined}])`);\n return Break.Chain(builder) as Omit<\n ReturnType<typeof Break.Chain>,\n \"PreceededBy\"\n >;\n },\n /**\n * Do not break before the given class of characters.\n */\n NotBefore: (...regexes: RegExp[]) => {\n const joined = Regex.join(...regexes);\n const builder = () => Regex.build(`(?![${joined}])`);\n return Break.Chain(builder) as Omit<\n ReturnType<typeof Break.Chain>,\n \"NotFollowedBy\"\n >;\n },\n /**\n * Do not break after the given class of characters.\n */\n NotAfter: (...regexes: RegExp[]) => {\n const joined = Regex.join(...regexes);\n const builder = () => Regex.build(`(?<![${joined}])`);\n return Break.Chain(builder) as Omit<\n ReturnType<typeof Break.Chain>,\n \"NotPrecededBy\"\n >;\n },\n Chain: (rootBuilder: () => RegExp) => ({\n /**\n * Build the root regex.\n */\n Build: rootBuilder,\n /**\n * Specify additional class of characters that should precede the root regex.\n */\n PreceededBy: (...regexes: RegExp[]) => {\n const root = rootBuilder();\n const preceeded = Break.After(...regexes).Build();\n const builder = () => Regex.and(preceeded, root);\n return Break.Chain(builder) as Omit<\n ReturnType<typeof Break.Chain>,\n \"PreceededBy\"\n >;\n },\n /**\n * Specify additional class of characters that should follow the root regex.\n */\n FollowedBy: (...regexes: RegExp[]) => {\n const root = rootBuilder();\n const followed = Break.Before(...regexes).Build();\n const builder = () => Regex.and(root, followed);\n return Break.Chain(builder) as Omit<\n ReturnType<typeof Break.Chain>,\n \"FollowedBy\"\n >;\n },\n /**\n * Specify additional class of characters that should not precede the root regex.\n */\n NotPrecededBy: (...regexes: RegExp[]) => {\n const root = rootBuilder();\n const notPreceeded = Break.NotAfter(...regexes).Build();\n const builder = () => Regex.and(notPreceeded, root);\n return Break.Chain(builder) as Omit<\n ReturnType<typeof Break.Chain>,\n \"NotPrecededBy\"\n >;\n },\n /**\n * Specify additional class of characters that should not follow the root regex.\n */\n NotFollowedBy: (...regexes: RegExp[]) => {\n const root = rootBuilder();\n const notFollowed = Break.NotBefore(...regexes).Build();\n const builder = () => Regex.and(root, notFollowed);\n return Break.Chain(builder) as Omit<\n ReturnType<typeof Break.Chain>,\n \"NotFollowedBy\"\n >;\n },\n }),\n};\n\n/**\n * Breaks the line into the tokens based on the found line break opporutnities.\n */\nexport const parseTokens = (line: string) => {\n const breakLineRegex = getLineBreakRegex();\n\n // normalizing to single-codepoint composed chars due to canonical equivalence\n // of multi-codepoint versions for chars like \u010D, \u3067 (~ so that we don't break a line in between c and \u02C7)\n // filtering due to multi-codepoint chars like \uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66, \uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDDB0\n return line.normalize(\"NFC\").split(breakLineRegex).filter(Boolean);\n};\n\n/**\n * Wraps the original text into the lines based on the given width.\n */\nexport const wrapText = (\n text: string,\n font: FontString,\n maxWidth: number,\n): string => {\n // if maxWidth is not finite or NaN which can happen in case of bugs in\n // computation, we need to make sure we don't continue as we'll end up\n // in an infinite loop\n if (!Number.isFinite(maxWidth) || maxWidth < 0) {\n return text;\n }\n\n const lines: Array<string> = [];\n const originalLines = text.split(\"\\n\");\n\n for (const originalLine of originalLines) {\n const currentLineWidth = getLineWidth(originalLine, font);\n\n if (currentLineWidth <= maxWidth) {\n lines.push(originalLine);\n continue;\n }\n\n const wrappedLine = wrapLine(originalLine, font, maxWidth);\n lines.push(...wrappedLine);\n }\n\n return lines.join(\"\\n\");\n};\n\n/**\n * Wraps the original line into the lines based on the given width.\n */\nconst wrapLine = (\n line: string,\n font: FontString,\n maxWidth: number,\n): string[] => {\n const lines: Array<string> = [];\n const tokens = parseTokens(line);\n const tokenIterator = tokens[Symbol.iterator]();\n\n let currentLine = \"\";\n let currentLineWidth = 0;\n\n let iterator = tokenIterator.next();\n\n while (!iterator.done) {\n const token = iterator.value;\n const testLine = currentLine + token;\n\n // cache single codepoint whitespace, CJK or emoji width calc. as kerning should not apply here\n const testLineWidth = isSingleCharacter(token)\n ? currentLineWidth + charWidth.calculate(token, font)\n : getLineWidth(testLine, font);\n\n // build up the current line, skipping length check for possibly trailing whitespaces\n if (/\\s/.test(token) || testLineWidth <= maxWidth) {\n currentLine = testLine;\n currentLineWidth = testLineWidth;\n iterator = tokenIterator.next();\n continue;\n }\n\n // current line is empty => just the token (word) is longer than `maxWidth` and needs to be wrapped\n if (!currentLine) {\n const wrappedWord = wrapWord(token, font, maxWidth);\n const trailingLine = wrappedWord[wrappedWord.length - 1] ?? \"\";\n const precedingLines = wrappedWord.slice(0, -1);\n\n lines.push(...precedingLines);\n\n // trailing line of the wrapped word might still be joined with next token/s\n currentLine = trailingLine;\n currentLineWidth = getLineWidth(trailingLine, font);\n iterator = tokenIterator.next();\n } else {\n // push & reset, but don't iterate on the next token, as we didn't use it yet!\n lines.push(currentLine.trimEnd());\n\n // purposefully not iterating and not setting `currentLine` to `token`, so that we could use a simple !currentLine check above\n currentLine = \"\";\n currentLineWidth = 0;\n }\n }\n\n // iterator done, push the trailing line if exists\n if (currentLine) {\n const trailingLine = trimLine(currentLine, font, maxWidth);\n lines.push(trailingLine);\n }\n\n return lines;\n};\n\n/**\n * Wraps the word into the lines based on the given width.\n */\nconst wrapWord = (\n word: string,\n font: FontString,\n maxWidth: number,\n): Array<string> => {\n // multi-codepoint emojis are already broken apart and shouldn't be broken further\n if (getEmojiRegex().test(word)) {\n return [word];\n }\n\n satisfiesWordInvariant(word);\n\n const lines: Array<string> = [];\n const chars = Array.from(word);\n\n let currentLine = \"\";\n let currentLineWidth = 0;\n\n for (const char of chars) {\n const _charWidth = charWidth.calculate(char, font);\n const testLineWidth = currentLineWidth + _charWidth;\n\n if (testLineWidth <= maxWidth) {\n currentLine = currentLine + char;\n currentLineWidth = testLineWidth;\n continue;\n }\n\n if (currentLine) {\n lines.push(currentLine);\n }\n\n currentLine = char;\n currentLineWidth = _charWidth;\n }\n\n if (currentLine) {\n lines.push(currentLine);\n }\n\n return lines;\n};\n\n/**\n * Similarly to browsers, does not trim all trailing whitespaces, but only those exceeding the `maxWidth`.\n */\nconst trimLine = (line: string, font: FontString, maxWidth: number) => {\n const shouldTrimWhitespaces = getLineWidth(line, font) > maxWidth;\n\n if (!shouldTrimWhitespaces) {\n return line;\n }\n\n // defensively default to `trimeEnd` in case the regex does not match\n let [, trimmedLine, whitespaces] = line.match(/^(.+?)(\\s+)$/) ?? [\n line,\n line.trimEnd(),\n \"\",\n ];\n\n let trimmedLineWidth = getLineWidth(trimmedLine, font);\n\n for (const whitespace of Array.from(whitespaces)) {\n const _charWidth = charWidth.calculate(whitespace, font);\n const testLineWidth = trimmedLineWidth + _charWidth;\n\n if (testLineWidth > maxWidth) {\n break;\n }\n\n trimmedLine = trimmedLine + whitespace;\n trimmedLineWidth = testLineWidth;\n }\n\n return trimmedLine;\n};\n\n/**\n * Check if the given string is a single character.\n *\n * Handles multi-byte chars (\u00E9, \u4E2D) and purposefully does not handle multi-codepoint char (\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66, \uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDDB0).\n */\nconst isSingleCharacter = (maybeSingleCharacter: string) => {\n return (\n maybeSingleCharacter.codePointAt(0) !== undefined &&\n maybeSingleCharacter.codePointAt(1) === undefined\n );\n};\n\n/**\n * Invariant for the word wrapping algorithm.\n */\nconst satisfiesWordInvariant = (word: string) => {\n if (import.meta.env.MODE === ENV.TEST || import.meta.env.DEV) {\n if (/\\s/.test(word)) {\n throw new Error(\"Word should not contain any whitespaces!\");\n }\n }\n};\n", "import type {\n ExcalidrawElement,\n ExcalidrawLinearElement,\n Arrowhead,\n ExcalidrawFreeDrawElement,\n NonDeleted,\n ExcalidrawTextElementWithContainer,\n ElementsMap,\n} from \"./types\";\nimport rough from \"roughjs/bin/rough\";\nimport type { Point as RoughPoint } from \"roughjs/bin/geometry\";\nimport type { Drawable, Op } from \"roughjs/bin/core\";\nimport type { AppState } from \"../types\";\nimport { generateRoughOptions } from \"../scene/Shape\";\nimport {\n isArrowElement,\n isBoundToContainer,\n isFreeDrawElement,\n isLinearElement,\n isTextElement,\n} from \"./typeChecks\";\nimport { rescalePoints } from \"../points\";\nimport { getBoundTextElement, getContainerElement } from \"./textElement\";\nimport { LinearElementEditor } from \"./linearElementEditor\";\nimport { ShapeCache } from \"../scene/ShapeCache\";\nimport { arrayToMap, invariant } from \"../utils\";\nimport type {\n Degrees,\n GlobalPoint,\n LineSegment,\n LocalPoint,\n Radians,\n} from \"@excalidraw/math\";\nimport {\n degreesToRadians,\n lineSegment,\n pointFrom,\n pointDistance,\n pointFromArray,\n pointRotateRads,\n} from \"@excalidraw/math\";\nimport type { Mutable } from \"../utility-types\";\n\nexport type RectangleBox = {\n x: number;\n y: number;\n width: number;\n height: number;\n angle: number;\n};\n\ntype MaybeQuadraticSolution = [number | null, number | null] | false;\n\n/**\n * x and y position of top left corner, x and y position of bottom right corner\n */\nexport type Bounds = readonly [\n minX: number,\n minY: number,\n maxX: number,\n maxY: number,\n];\n\nexport type SceneBounds = readonly [\n sceneX: number,\n sceneY: number,\n sceneX2: number,\n sceneY2: number,\n];\n\nexport class ElementBounds {\n private static boundsCache = new WeakMap<\n ExcalidrawElement,\n {\n bounds: Bounds;\n version: ExcalidrawElement[\"version\"];\n }\n >();\n\n static getBounds(element: ExcalidrawElement, elementsMap: ElementsMap) {\n const cachedBounds = ElementBounds.boundsCache.get(element);\n\n if (\n cachedBounds?.version &&\n cachedBounds.version === element.version &&\n // we don't invalidate cache when we update containers and not labels,\n // which is causing problems down the line. Fix TBA.\n !isBoundToContainer(element)\n ) {\n return cachedBounds.bounds;\n }\n const bounds = ElementBounds.calculateBounds(element, elementsMap);\n\n ElementBounds.boundsCache.set(element, {\n version: element.version,\n bounds,\n });\n\n return bounds;\n }\n\n private static calculateBounds(\n element: ExcalidrawElement,\n elementsMap: ElementsMap,\n ): Bounds {\n let bounds: Bounds;\n\n const [x1, y1, x2, y2, cx, cy] = getElementAbsoluteCoords(\n element,\n elementsMap,\n );\n if (isFreeDrawElement(element)) {\n const [minX, minY, maxX, maxY] = getBoundsFromPoints(\n element.points.map(([x, y]) =>\n pointRotateRads(\n pointFrom(x, y),\n pointFrom(cx - element.x, cy - element.y),\n element.angle,\n ),\n ),\n );\n\n return [\n minX + element.x,\n minY + element.y,\n maxX + element.x,\n maxY + element.y,\n ];\n } else if (isLinearElement(element)) {\n bounds = getLinearElementRotatedBounds(element, cx, cy, elementsMap);\n } else if (element.type === \"diamond\") {\n const [x11, y11] = pointRotateRads(\n pointFrom(cx, y1),\n pointFrom(cx, cy),\n element.angle,\n );\n const [x12, y12] = pointRotateRads(\n pointFrom(cx, y2),\n pointFrom(cx, cy),\n element.angle,\n );\n const [x22, y22] = pointRotateRads(\n pointFrom(x1, cy),\n pointFrom(cx, cy),\n element.angle,\n );\n const [x21, y21] = pointRotateRads(\n pointFrom(x2, cy),\n pointFrom(cx, cy),\n element.angle,\n );\n const minX = Math.min(x11, x12, x22, x21);\n const minY = Math.min(y11, y12, y22, y21);\n const maxX = Math.max(x11, x12, x22, x21);\n const maxY = Math.max(y11, y12, y22, y21);\n bounds = [minX, minY, maxX, maxY];\n } else if (element.type === \"ellipse\") {\n const w = (x2 - x1) / 2;\n const h = (y2 - y1) / 2;\n const cos = Math.cos(element.angle);\n const sin = Math.sin(element.angle);\n const ww = Math.hypot(w * cos, h * sin);\n const hh = Math.hypot(h * cos, w * sin);\n bounds = [cx - ww, cy - hh, cx + ww, cy + hh];\n } else {\n const [x11, y11] = pointRotateRads(\n pointFrom(x1, y1),\n pointFrom(cx, cy),\n element.angle,\n );\n const [x12, y12] = pointRotateRads(\n pointFrom(x1, y2),\n pointFrom(cx, cy),\n element.angle,\n );\n const [x22, y22] = pointRotateRads(\n pointFrom(x2, y2),\n pointFrom(cx, cy),\n element.angle,\n );\n const [x21, y21] = pointRotateRads(\n pointFrom(x2, y1),\n pointFrom(cx, cy),\n element.angle,\n );\n const minX = Math.min(x11, x12, x22, x21);\n const minY = Math.min(y11, y12, y22, y21);\n const maxX = Math.max(x11, x12, x22, x21);\n const maxY = Math.max(y11, y12, y22, y21);\n bounds = [minX, minY, maxX, maxY];\n }\n\n return bounds;\n }\n}\n\n// Scene -> Scene coords, but in x1,x2,y1,y2 format.\n//\n// If the element is created from right to left, the width is going to be negative\n// This set of functions retrieves the absolute position of the 4 points.\nexport const getElementAbsoluteCoords = (\n element: ExcalidrawElement,\n elementsMap: ElementsMap,\n includeBoundText: boolean = false,\n): [number, number, number, number, number, number] => {\n if (isFreeDrawElement(element)) {\n return getFreeDrawElementAbsoluteCoords(element);\n } else if (isLinearElement(element)) {\n return LinearElementEditor.getElementAbsoluteCoords(\n element,\n elementsMap,\n includeBoundText,\n );\n } else if (isTextElement(element)) {\n const container = elementsMap\n ? getContainerElement(element, elementsMap)\n : null;\n if (isArrowElement(container)) {\n const { x, y } = LinearElementEditor.getBoundTextElementPosition(\n container,\n element as ExcalidrawTextElementWithContainer,\n elementsMap,\n );\n return [\n x,\n y,\n x + element.width,\n y + element.height,\n x + element.width / 2,\n y + element.height / 2,\n ];\n }\n }\n return [\n element.x,\n element.y,\n element.x + element.width,\n element.y + element.height,\n element.x + element.width / 2,\n element.y + element.height / 2,\n ];\n};\n\n/*\n * for a given element, `getElementLineSegments` returns line segments\n * that can be used for visual collision detection (useful for frames)\n * as opposed to bounding box collision detection\n */\nexport const getElementLineSegments = (\n element: ExcalidrawElement,\n elementsMap: ElementsMap,\n): LineSegment<GlobalPoint>[] => {\n const [x1, y1, x2, y2, cx, cy] = getElementAbsoluteCoords(\n element,\n elementsMap,\n );\n\n const center: GlobalPoint = pointFrom(cx, cy);\n\n if (isLinearElement(element) || isFreeDrawElement(element)) {\n const segments: LineSegment<GlobalPoint>[] = [];\n\n let i = 0;\n\n while (i < element.points.length - 1) {\n segments.push(\n lineSegment(\n pointRotateRads(\n pointFrom(\n element.points[i][0] + element.x,\n element.points[i][1] + element.y,\n ),\n center,\n element.angle,\n ),\n pointRotateRads(\n pointFrom(\n element.points[i + 1][0] + element.x,\n element.points[i + 1][1] + element.y,\n ),\n center,\n element.angle,\n ),\n ),\n );\n i++;\n }\n\n return segments;\n }\n\n const [nw, ne, sw, se, n, s, w, e] = (\n [\n [x1, y1],\n [x2, y1],\n [x1, y2],\n [x2, y2],\n [cx, y1],\n [cx, y2],\n [x1, cy],\n [x2, cy],\n ] as GlobalPoint[]\n ).map((point) => pointRotateRads(point, center, element.angle));\n\n if (element.type === \"diamond\") {\n return [\n lineSegment(n, w),\n lineSegment(n, e),\n lineSegment(s, w),\n lineSegment(s, e),\n ];\n }\n\n if (element.type === \"ellipse\") {\n return [\n lineSegment(n, w),\n lineSegment(n, e),\n lineSegment(s, w),\n lineSegment(s, e),\n lineSegment(n, w),\n lineSegment(n, e),\n lineSegment(s, w),\n lineSegment(s, e),\n ];\n }\n\n return [\n lineSegment(nw, ne),\n lineSegment(sw, se),\n lineSegment(nw, sw),\n lineSegment(ne, se),\n lineSegment(nw, e),\n lineSegment(sw, e),\n lineSegment(ne, w),\n lineSegment(se, w),\n ];\n};\n\n/**\n * Scene -> Scene coords, but in x1,x2,y1,y2 format.\n *\n * Rectangle here means any rectangular frame, not an excalidraw element.\n */\nexport const getRectangleBoxAbsoluteCoords = (boxSceneCoords: RectangleBox) => {\n return [\n boxSceneCoords.x,\n boxSceneCoords.y,\n boxSceneCoords.x + boxSceneCoords.width,\n boxSceneCoords.y + boxSceneCoords.height,\n boxSceneCoords.x + boxSceneCoords.width / 2,\n boxSceneCoords.y + boxSceneCoords.height / 2,\n ];\n};\n\nexport const getDiamondPoints = (element: ExcalidrawElement) => {\n // Here we add +1 to avoid these numbers to be 0\n // otherwise rough.js will throw an error complaining about it\n const topX = Math.floor(element.width / 2) + 1;\n const topY = 0;\n const rightX = element.width;\n const rightY = Math.floor(element.height / 2) + 1;\n const bottomX = topX;\n const bottomY = element.height;\n const leftX = 0;\n const leftY = rightY;\n\n return [topX, topY, rightX, rightY, bottomX, bottomY, leftX, leftY];\n};\n\nexport const getCurvePathOps = (shape: Drawable): Op[] => {\n for (const set of shape.sets) {\n if (set.type === \"path\") {\n return set.ops;\n }\n }\n return shape.sets[0].ops;\n};\n\n// reference: https://eliot-jones.com/2019/12/cubic-bezier-curve-bounding-boxes\nconst getBezierValueForT = (\n t: number,\n p0: number,\n p1: number,\n p2: number,\n p3: number,\n) => {\n const oneMinusT = 1 - t;\n return (\n Math.pow(oneMinusT, 3) * p0 +\n 3 * Math.pow(oneMinusT, 2) * t * p1 +\n 3 * oneMinusT * Math.pow(t, 2) * p2 +\n Math.pow(t, 3) * p3\n );\n};\n\nconst solveQuadratic = (\n p0: number,\n p1: number,\n p2: number,\n p3: number,\n): MaybeQuadraticSolution => {\n const i = p1 - p0;\n const j = p2 - p1;\n const k = p3 - p2;\n\n const a = 3 * i - 6 * j + 3 * k;\n const b = 6 * j - 6 * i;\n const c = 3 * i;\n\n const sqrtPart = b * b - 4 * a * c;\n const hasSolution = sqrtPart >= 0;\n\n if (!hasSolution) {\n return false;\n }\n\n let s1 = null;\n let s2 = null;\n\n let t1 = Infinity;\n let t2 = Infinity;\n\n if (a === 0) {\n t1 = t2 = -c / b;\n } else {\n t1 = (-b + Math.sqrt(sqrtPart)) / (2 * a);\n t2 = (-b - Math.sqrt(sqrtPart)) / (2 * a);\n }\n\n if (t1 >= 0 && t1 <= 1) {\n s1 = getBezierValueForT(t1, p0, p1, p2, p3);\n }\n\n if (t2 >= 0 && t2 <= 1) {\n s2 = getBezierValueForT(t2, p0, p1, p2, p3);\n }\n\n return [s1, s2];\n};\n\nconst getCubicBezierCurveBound = (\n p0: GlobalPoint,\n p1: GlobalPoint,\n p2: GlobalPoint,\n p3: GlobalPoint,\n): Bounds => {\n const solX = solveQuadratic(p0[0], p1[0], p2[0], p3[0]);\n const solY = solveQuadratic(p0[1], p1[1], p2[1], p3[1]);\n\n let minX = Math.min(p0[0], p3[0]);\n let maxX = Math.max(p0[0], p3[0]);\n\n if (solX) {\n const xs = solX.filter((x) => x !== null) as number[];\n minX = Math.min(minX, ...xs);\n maxX = Math.max(maxX, ...xs);\n }\n\n let minY = Math.min(p0[1], p3[1]);\n let maxY = Math.max(p0[1], p3[1]);\n if (solY) {\n const ys = solY.filter((y) => y !== null) as number[];\n minY = Math.min(minY, ...ys);\n maxY = Math.max(maxY, ...ys);\n }\n return [minX, minY, maxX, maxY];\n};\n\nexport const getMinMaxXYFromCurvePathOps = (\n ops: Op[],\n transformXY?: (p: GlobalPoint) => GlobalPoint,\n): Bounds => {\n let currentP: GlobalPoint = pointFrom(0, 0);\n\n const { minX, minY, maxX, maxY } = ops.reduce(\n (limits, { op, data }) => {\n // There are only four operation types:\n // move, bcurveTo, lineTo, and curveTo\n if (op === \"move\") {\n // change starting point\n const p: GlobalPoint | undefined = pointFromArray(data);\n invariant(p != null, \"Op data is not a point\");\n currentP = p;\n // move operation does not draw anything; so, it always\n // returns false\n } else if (op === \"bcurveTo\") {\n const _p1 = pointFrom<GlobalPoint>(data[0], data[1]);\n const _p2 = pointFrom<GlobalPoint>(data[2], data[3]);\n const _p3 = pointFrom<GlobalPoint>(data[4], data[5]);\n\n const p1 = transformXY ? transformXY(_p1) : _p1;\n const p2 = transformXY ? transformXY(_p2) : _p2;\n const p3 = transformXY ? transformXY(_p3) : _p3;\n\n const p0 = transformXY ? transformXY(currentP) : currentP;\n currentP = _p3;\n\n const [minX, minY, maxX, maxY] = getCubicBezierCurveBound(\n p0,\n p1,\n p2,\n p3,\n );\n\n limits.minX = Math.min(limits.minX, minX);\n limits.minY = Math.min(limits.minY, minY);\n\n limits.maxX = Math.max(limits.maxX, maxX);\n limits.maxY = Math.max(limits.maxY, maxY);\n } else if (op === \"lineTo\") {\n // TODO: Implement this\n } else if (op === \"qcurveTo\") {\n // TODO: Implement this\n }\n return limits;\n },\n { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity },\n );\n return [minX, minY, maxX, maxY];\n};\n\nexport const getBoundsFromPoints = (\n points: ExcalidrawFreeDrawElement[\"points\"],\n): Bounds => {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (const [x, y] of points) {\n minX = Math.min(minX, x);\n minY = Math.min(minY, y);\n maxX = Math.max(maxX, x);\n maxY = Math.max(maxY, y);\n }\n\n return [minX, minY, maxX, maxY];\n};\n\nconst getFreeDrawElementAbsoluteCoords = (\n element: ExcalidrawFreeDrawElement,\n): [number, number, number, number, number, number] => {\n const [minX, minY, maxX, maxY] = getBoundsFromPoints(element.points);\n const x1 = minX + element.x;\n const y1 = minY + element.y;\n const x2 = maxX + element.x;\n const y2 = maxY + element.y;\n return [x1, y1, x2, y2, (x1 + x2) / 2, (y1 + y2) / 2];\n};\n\n/** @returns number in pixels */\nexport const getArrowheadSize = (arrowhead: Arrowhead): number => {\n switch (arrowhead) {\n case \"arrow\":\n return 25;\n case \"diamond\":\n case \"diamond_outline\":\n return 12;\n case \"crowfoot_many\":\n case \"crowfoot_one\":\n case \"crowfoot_one_or_many\":\n return 20;\n default:\n return 15;\n }\n};\n\n/** @returns number in degrees */\nexport const getArrowheadAngle = (arrowhead: Arrowhead): Degrees => {\n switch (arrowhead) {\n case \"bar\":\n return 90 as Degrees;\n case \"arrow\":\n return 20 as Degrees;\n default:\n return 25 as Degrees;\n }\n};\n\nexport const getArrowheadPoints = (\n element: ExcalidrawLinearElement,\n shape: Drawable[],\n position: \"start\" | \"end\",\n arrowhead: Arrowhead,\n) => {\n const ops = getCurvePathOps(shape[0]);\n if (ops.length < 1) {\n return null;\n }\n\n // The index of the bCurve operation to examine.\n const index = position === \"start\" ? 1 : ops.length - 1;\n\n const data = ops[index].data;\n\n invariant(data.length === 6, \"Op data length is not 6\");\n\n const p3 = pointFrom(data[4], data[5]);\n const p2 = pointFrom(data[2], data[3]);\n const p1 = pointFrom(data[0], data[1]);\n\n // We need to find p0 of the bezier curve.\n // It is typically the last point of the previous\n // curve; it can also be the position of moveTo operation.\n const prevOp = ops[index - 1];\n let p0 = pointFrom(0, 0);\n if (prevOp.op === \"move\") {\n const p = pointFromArray(prevOp.data);\n invariant(p != null, \"Op data is not a point\");\n p0 = p;\n } else if (prevOp.op === \"bcurveTo\") {\n p0 = pointFrom(prevOp.data[4], prevOp.data[5]);\n }\n\n // B(t) = p0 * (1-t)^3 + 3p1 * t * (1-t)^2 + 3p2 * t^2 * (1-t) + p3 * t^3\n const equation = (t: number, idx: number) =>\n Math.pow(1 - t, 3) * p3[idx] +\n 3 * t * Math.pow(1 - t, 2) * p2[idx] +\n 3 * Math.pow(t, 2) * (1 - t) * p1[idx] +\n p0[idx] * Math.pow(t, 3);\n\n // Ee know the last point of the arrow (or the first, if start arrowhead).\n const [x2, y2] = position === \"start\" ? p0 : p3;\n\n // By using cubic bezier equation (B(t)) and the given parameters,\n // we calculate a point that is closer to the last point.\n // The value 0.3 is chosen arbitrarily and it works best for all\n // the tested cases.\n const [x1, y1] = [equation(0.3, 0), equation(0.3, 1)];\n\n // Find the normalized direction vector based on the\n // previously calculated points.\n const distance = Math.hypot(x2 - x1, y2 - y1);\n const nx = (x2 - x1) / distance;\n const ny = (y2 - y1) / distance;\n\n const size = getArrowheadSize(arrowhead);\n\n let length = 0;\n\n {\n // Length for -> arrows is based on the length of the last section\n const [cx, cy] =\n position === \"end\"\n ? element.points[element.points.length - 1]\n : element.points[0];\n const [px, py] =\n element.points.length > 1\n ? position === \"end\"\n ? element.points[element.points.length - 2]\n : element.points[1]\n : [0, 0];\n\n length = Math.hypot(cx - px, cy - py);\n }\n\n // Scale down the arrowhead until we hit a certain size so that it doesn't look weird.\n // This value is selected by minimizing a minimum size with the last segment of the arrowhead\n const lengthMultiplier =\n arrowhead === \"diamond\" || arrowhead === \"diamond_outline\" ? 0.25 : 0.5;\n const minSize = Math.min(size, length * lengthMultiplier);\n const xs = x2 - nx * minSize;\n const ys = y2 - ny * minSize;\n\n if (\n arrowhead === \"dot\" ||\n arrowhead === \"circle\" ||\n arrowhead === \"circle_outline\"\n ) {\n const diameter = Math.hypot(ys - y2, xs - x2) + element.strokeWidth - 2;\n return [x2, y2, diameter];\n }\n\n const angle = getArrowheadAngle(arrowhead);\n\n if (arrowhead === \"crowfoot_many\" || arrowhead === \"crowfoot_one_or_many\") {\n // swap (xs, ys) with (x2, y2)\n const [x3, y3] = pointRotateRads(\n pointFrom(x2, y2),\n pointFrom(xs, ys),\n degreesToRadians(-angle as Degrees),\n );\n const [x4, y4] = pointRotateRads(\n pointFrom(x2, y2),\n pointFrom(xs, ys),\n degreesToRadians(angle),\n );\n return [xs, ys, x3, y3, x4, y4];\n }\n\n // Return points\n const [x3, y3] = pointRotateRads(\n pointFrom(xs, ys),\n pointFrom(x2, y2),\n ((-angle * Math.PI) / 180) as Radians,\n );\n const [x4, y4] = pointRotateRads(\n pointFrom(xs, ys),\n pointFrom(x2, y2),\n degreesToRadians(angle),\n );\n\n if (arrowhead === \"diamond\" || arrowhead === \"diamond_outline\") {\n // point opposite to the arrowhead point\n let ox;\n let oy;\n\n if (position === \"start\") {\n const [px, py] = element.points.length > 1 ? element.points[1] : [0, 0];\n\n [ox, oy] = pointRotateRads(\n pointFrom(x2 + minSize * 2, y2),\n pointFrom(x2, y2),\n Math.atan2(py - y2, px - x2) as Radians,\n );\n } else {\n const [px, py] =\n element.points.length > 1\n ? element.points[element.points.length - 2]\n : [0, 0];\n\n [ox, oy] = pointRotateRads(\n pointFrom(x2 - minSize * 2, y2),\n pointFrom(x2, y2),\n Math.atan2(y2 - py, x2 - px) as Radians,\n );\n }\n\n return [x2, y2, x3, y3, ox, oy, x4, y4];\n }\n\n return [x2, y2, x3, y3, x4, y4];\n};\n\nconst generateLinearElementShape = (\n element: ExcalidrawLinearElement,\n): Drawable => {\n const generator = rough.generator();\n const options = generateRoughOptions(element);\n\n const method = (() => {\n if (element.roundness) {\n return \"curve\";\n }\n if (options.fill) {\n return \"polygon\";\n }\n return \"linearPath\";\n })();\n\n return generator[method](\n element.points as Mutable<LocalPoint>[] as RoughPoint[],\n options,\n );\n};\n\nconst getLinearElementRotatedBounds = (\n element: ExcalidrawLinearElement,\n cx: number,\n cy: number,\n elementsMap: ElementsMap,\n): Bounds => {\n const boundTextElement = getBoundTextElement(element, elementsMap);\n\n if (element.points.length < 2) {\n const [pointX, pointY] = element.points[0];\n const [x, y] = pointRotateRads(\n pointFrom(element.x + pointX, element.y + pointY),\n pointFrom(cx, cy),\n element.angle,\n );\n\n let coords: Bounds = [x, y, x, y];\n if (boundTextElement) {\n const coordsWithBoundText = LinearElementEditor.getMinMaxXYWithBoundText(\n element,\n elementsMap,\n [x, y, x, y],\n boundTextElement,\n );\n coords = [\n coordsWithBoundText[0],\n coordsWithBoundText[1],\n coordsWithBoundText[2],\n coordsWithBoundText[3],\n ];\n }\n return coords;\n }\n\n // first element is always the curve\n const cachedShape = ShapeCache.get(element)?.[0];\n const shape = cachedShape ?? generateLinearElementShape(element);\n const ops = getCurvePathOps(shape);\n const transformXY = ([x, y]: GlobalPoint) =>\n pointRotateRads<GlobalPoint>(\n pointFrom(element.x + x, element.y + y),\n pointFrom(cx, cy),\n element.angle,\n );\n const res = getMinMaxXYFromCurvePathOps(ops, transformXY);\n let coords: Bounds = [res[0], res[1], res[2], res[3]];\n if (boundTextElement) {\n const coordsWithBoundText = LinearElementEditor.getMinMaxXYWithBoundText(\n element,\n elementsMap,\n coords,\n boundTextElement,\n );\n coords = [\n coordsWithBoundText[0],\n coordsWithBoundText[1],\n coordsWithBoundText[2],\n coordsWithBoundText[3],\n ];\n }\n return coords;\n};\n\nexport const getElementBounds = (\n element: ExcalidrawElement,\n elementsMap: ElementsMap,\n): Bounds => {\n return ElementBounds.getBounds(element, elementsMap);\n};\n\nexport const getCommonBounds = (\n elements: readonly ExcalidrawElement[],\n elementsMap?: ElementsMap,\n): Bounds => {\n if (!elements.length) {\n return [0, 0, 0, 0];\n }\n\n let minX = Infinity;\n let maxX = -Infinity;\n let minY = Infinity;\n let maxY = -Infinity;\n\n const _elementsMap = elementsMap || arrayToMap(elements);\n\n elements.forEach((element) => {\n const [x1, y1, x2, y2] = getElementBounds(element, _elementsMap);\n minX = Math.min(minX, x1);\n minY = Math.min(minY, y1);\n maxX = Math.max(maxX, x2);\n maxY = Math.max(maxY, y2);\n });\n\n return [minX, minY, maxX, maxY];\n};\n\nexport const getDraggedElementsBounds = (\n elements: ExcalidrawElement[],\n dragOffset: { x: number; y: number },\n) => {\n const [minX, minY, maxX, maxY] = getCommonBounds(elements);\n return [\n minX + dragOffset.x,\n minY + dragOffset.y,\n maxX + dragOffset.x,\n maxY + dragOffset.y,\n ];\n};\n\nexport const getResizedElementAbsoluteCoords = (\n element: ExcalidrawElement,\n nextWidth: number,\n nextHeight: number,\n normalizePoints: boolean,\n): Bounds => {\n if (!(isLinearElement(element) || isFreeDrawElement(element))) {\n return [\n element.x,\n element.y,\n element.x + nextWidth,\n element.y + nextHeight,\n ];\n }\n\n const points = rescalePoints(\n 0,\n nextWidth,\n rescalePoints(1, nextHeight, element.points, normalizePoints),\n normalizePoints,\n );\n\n let bounds: Bounds;\n\n if (isFreeDrawElement(element)) {\n // Free Draw\n bounds = getBoundsFromPoints(points);\n } else {\n // Line\n const gen = rough.generator();\n const curve = !element.roundness\n ? gen.linearPath(\n points as [number, number][],\n generateRoughOptions(element),\n )\n : gen.curve(points as [number, number][], generateRoughOptions(element));\n\n const ops = getCurvePathOps(curve);\n bounds = getMinMaxXYFromCurvePathOps(ops);\n }\n\n const [minX, minY, maxX, maxY] = bounds;\n return [\n minX + element.x,\n minY + element.y,\n maxX + element.x,\n maxY + element.y,\n ];\n};\n\nexport const getElementPointsCoords = (\n element: ExcalidrawLinearElement,\n points: readonly (readonly [number, number])[],\n): Bounds => {\n // This might be computationally heavey\n const gen = rough.generator();\n const curve =\n element.roundness == null\n ? gen.linearPath(\n points as [number, number][],\n generateRoughOptions(element),\n )\n : gen.curve(points as [number, number][], generateRoughOptions(element));\n const ops = getCurvePathOps(curve);\n const [minX, minY, maxX, maxY] = getMinMaxXYFromCurvePathOps(ops);\n return [\n minX + element.x,\n minY + element.y,\n maxX + element.x,\n maxY + element.y,\n ];\n};\n\nexport const getClosestElementBounds = (\n elements: readonly ExcalidrawElement[],\n from: { x: number; y: number },\n): Bounds => {\n if (!elements.length) {\n return [0, 0, 0, 0];\n }\n\n let minDistance = Infinity;\n let closestElement = elements[0];\n const elementsMap = arrayToMap(elements);\n elements.forEach((element) => {\n const [x1, y1, x2, y2] = getElementBounds(element, elementsMap);\n const distance = pointDistance(\n pointFrom((x1 + x2) / 2, (y1 + y2) / 2),\n pointFrom(from.x, from.y),\n );\n\n if (distance < minDistance) {\n minDistance = distance;\n closestElement = element;\n }\n });\n\n return getElementBounds(closestElement, elementsMap);\n};\n\nexport interface BoundingBox {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n midX: number;\n midY: number;\n width: number;\n height: number;\n}\n\nexport const getCommonBoundingBox = (\n elements: ExcalidrawElement[] | readonly NonDeleted<ExcalidrawElement>[],\n): BoundingBox => {\n const [minX, minY, maxX, maxY] = getCommonBounds(elements);\n return {\n minX,\n minY,\n maxX,\n maxY,\n width: maxX - minX,\n height: maxY - minY,\n midX: (minX + maxX) / 2,\n midY: (minY + maxY) / 2,\n };\n};\n\n/**\n * returns scene coords of user's editor viewport (visible canvas area) bounds\n */\nexport const getVisibleSceneBounds = ({\n scrollX,\n scrollY,\n width,\n height,\n zoom,\n}: AppState): SceneBounds => {\n return [\n -scrollX,\n -scrollY,\n -scrollX + width / zoom.value,\n -scrollY + height / zoom.value,\n ];\n};\n\nexport const getCenterForBounds = (bounds: Bounds): GlobalPoint =>\n pointFrom(\n bounds[0] + (bounds[2] - bounds[0]) / 2,\n bounds[1] + (bounds[3] - bounds[1]) / 2,\n );\n", "import type {\n ExcalidrawElement,\n ExcalidrawTextElement,\n NonDeletedExcalidrawElement,\n ExcalidrawFreeDrawElement,\n ExcalidrawImageElement,\n ExcalidrawTextElementWithContainer,\n ExcalidrawFrameLikeElement,\n NonDeletedSceneElementsMap,\n ElementsMap,\n} from \"../element/types\";\nimport {\n isTextElement,\n isLinearElement,\n isFreeDrawElement,\n isInitializedImageElement,\n isArrowElement,\n hasBoundTextElement,\n isMagicFrameElement,\n isImageElement,\n} from \"../element/typeChecks\";\nimport { getElementAbsoluteCoords } from \"../element/bounds\";\nimport type { RoughCanvas } from \"roughjs/bin/canvas\";\n\nimport type {\n StaticCanvasRenderConfig,\n RenderableElementsMap,\n InteractiveCanvasRenderConfig,\n} from \"../scene/types\";\nimport { distance, getFontString, isRTL } from \"../utils\";\nimport rough from \"roughjs/bin/rough\";\nimport type {\n AppState,\n StaticCanvasAppState,\n Zoom,\n InteractiveCanvasAppState,\n ElementsPendingErasure,\n PendingExcalidrawElements,\n} from \"../types\";\nimport { getDefaultAppState } from \"../appState\";\nimport {\n BOUND_TEXT_PADDING,\n DEFAULT_REDUCED_GLOBAL_ALPHA,\n ELEMENT_READY_TO_ERASE_OPACITY,\n FRAME_STYLE,\n MIME_TYPES,\n THEME,\n} from \"../constants\";\nimport type { StrokeOptions } from \"perfect-freehand\";\nimport { getStroke } from \"perfect-freehand\";\nimport {\n getBoundTextElement,\n getContainerCoords,\n getContainerElement,\n getBoundTextMaxHeight,\n getBoundTextMaxWidth,\n} from \"../element/textElement\";\nimport { LinearElementEditor } from \"../element/linearElementEditor\";\n\nimport { getContainingFrame } from \"../frame\";\nimport { ShapeCache } from \"../scene/ShapeCache\";\nimport { getVerticalOffset } from \"../fonts\";\nimport { isRightAngleRads } from \"@excalidraw/math\";\nimport { getCornerRadius } from \"../shapes\";\nimport { getUncroppedImageElement } from \"../element/cropElement\";\nimport { getLineHeightInPx } from \"../element/textMeasurements\";\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...)\nexport const IMAGE_INVERT_FILTER =\n \"invert(100%) hue-rotate(180deg) saturate(1.25)\";\n\nconst defaultAppState = getDefaultAppState();\n\nconst isPendingImageElement = (\n element: ExcalidrawElement,\n renderConfig: StaticCanvasRenderConfig,\n) =>\n isInitializedImageElement(element) &&\n !renderConfig.imageCache.has(element.fileId);\n\nconst shouldResetImageFilter = (\n element: ExcalidrawElement,\n renderConfig: StaticCanvasRenderConfig,\n appState: StaticCanvasAppState,\n) => {\n return (\n appState.theme === THEME.DARK &&\n isInitializedImageElement(element) &&\n !isPendingImageElement(element, renderConfig) &&\n renderConfig.imageCache.get(element.fileId)?.mimeType !== MIME_TYPES.svg\n );\n};\n\nconst getCanvasPadding = (element: ExcalidrawElement) => {\n switch (element.type) {\n case \"freedraw\":\n return element.strokeWidth * 12;\n case \"text\":\n return element.fontSize / 2;\n default:\n return 20;\n }\n};\n\nexport const getRenderOpacity = (\n element: ExcalidrawElement,\n containingFrame: ExcalidrawFrameLikeElement | null,\n elementsPendingErasure: ElementsPendingErasure,\n pendingNodes: Readonly<PendingExcalidrawElements> | null,\n globalAlpha: number = 1,\n) => {\n // multiplying frame opacity with element opacity to combine them\n // (e.g. frame 50% and element 50% opacity should result in 25% opacity)\n let opacity =\n (((containingFrame?.opacity ?? 100) * element.opacity) / 10000) *\n globalAlpha;\n\n // if pending erasure, multiply again to combine further\n // (so that erasing always results in lower opacity than original)\n if (\n elementsPendingErasure.has(element.id) ||\n (pendingNodes && pendingNodes.some((node) => node.id === element.id)) ||\n (containingFrame && elementsPendingErasure.has(containingFrame.id))\n ) {\n opacity *= ELEMENT_READY_TO_ERASE_OPACITY / 100;\n }\n\n return opacity;\n};\n\nexport interface ExcalidrawElementWithCanvas {\n element: ExcalidrawElement | ExcalidrawTextElement;\n canvas: HTMLCanvasElement;\n theme: AppState[\"theme\"];\n scale: number;\n angle: number;\n zoomValue: AppState[\"zoom\"][\"value\"];\n canvasOffsetX: number;\n canvasOffsetY: number;\n boundTextElementVersion: number | null;\n imageCrop: ExcalidrawImageElement[\"crop\"] | null;\n containingFrameOpacity: number;\n boundTextCanvas: HTMLCanvasElement;\n}\n\nconst cappedElementCanvasSize = (\n element: NonDeletedExcalidrawElement,\n elementsMap: ElementsMap,\n zoom: Zoom,\n): {\n width: number;\n height: number;\n scale: number;\n} => {\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 = 16777216;\n // ~ safari width/height limit based on developer.mozilla.org.\n const WIDTH_HEIGHT_LIMIT = 32767;\n\n const padding = getCanvasPadding(element);\n\n const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);\n const elementWidth =\n isLinearElement(element) || isFreeDrawElement(element)\n ? distance(x1, x2)\n : element.width;\n const elementHeight =\n isLinearElement(element) || isFreeDrawElement(element)\n ? distance(y1, y2)\n : element.height;\n\n let width = elementWidth * window.devicePixelRatio + padding * 2;\n let height = elementHeight * window.devicePixelRatio + padding * 2;\n\n let scale: number = zoom.value;\n\n // rescale to ensure width and height is within limits\n if (\n width * scale > WIDTH_HEIGHT_LIMIT ||\n height * scale > WIDTH_HEIGHT_LIMIT\n ) {\n scale = Math.min(WIDTH_HEIGHT_LIMIT / width, WIDTH_HEIGHT_LIMIT / height);\n }\n\n // rescale to ensure canvas area is within limits\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\n return { width, height, scale };\n};\n\nconst generateElementCanvas = (\n element: NonDeletedExcalidrawElement,\n elementsMap: NonDeletedSceneElementsMap,\n zoom: Zoom,\n renderConfig: StaticCanvasRenderConfig,\n appState: StaticCanvasAppState,\n): ExcalidrawElementWithCanvas | null => {\n const canvas = document.createElement(\"canvas\");\n const context = canvas.getContext(\"2d\")!;\n const padding = getCanvasPadding(element);\n\n const { width, height, scale } = cappedElementCanvasSize(\n element,\n elementsMap,\n zoom,\n );\n\n if (!width || !height) {\n return null;\n }\n\n canvas.width = width;\n canvas.height = height;\n\n let canvasOffsetX = -100;\n let canvasOffsetY = 0;\n\n if (isLinearElement(element) || isFreeDrawElement(element)) {\n const [x1, y1] = getElementAbsoluteCoords(element, elementsMap);\n\n canvasOffsetX =\n element.x > x1\n ? distance(element.x, x1) * window.devicePixelRatio * scale\n : 0;\n\n canvasOffsetY =\n element.y > y1\n ? distance(element.y, y1) * window.devicePixelRatio * scale\n : 0;\n\n context.translate(canvasOffsetX, canvasOffsetY);\n }\n\n context.save();\n context.translate(padding * scale, padding * scale);\n context.scale(\n window.devicePixelRatio * scale,\n window.devicePixelRatio * scale,\n );\n\n const rc = rough.canvas(canvas);\n\n // in dark theme, revert the image color filter\n if (shouldResetImageFilter(element, renderConfig, appState)) {\n context.filter = IMAGE_INVERT_FILTER;\n }\n\n drawElementOnCanvas(element, rc, context, renderConfig, appState);\n\n context.restore();\n\n const boundTextElement = getBoundTextElement(element, elementsMap);\n const boundTextCanvas = document.createElement(\"canvas\");\n const boundTextCanvasContext = boundTextCanvas.getContext(\"2d\")!;\n\n if (isArrowElement(element) && boundTextElement) {\n const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);\n // Take max dimensions of arrow canvas so that when canvas is rotated\n // the arrow doesn't get clipped\n const maxDim = Math.max(distance(x1, x2), distance(y1, y2));\n boundTextCanvas.width =\n maxDim * window.devicePixelRatio * scale + padding * scale * 10;\n boundTextCanvas.height =\n maxDim * window.devicePixelRatio * scale + padding * scale * 10;\n boundTextCanvasContext.translate(\n boundTextCanvas.width / 2,\n boundTextCanvas.height / 2,\n );\n boundTextCanvasContext.rotate(element.angle);\n boundTextCanvasContext.drawImage(\n canvas!,\n -canvas.width / 2,\n -canvas.height / 2,\n canvas.width,\n canvas.height,\n );\n\n const [, , , , boundTextCx, boundTextCy] = getElementAbsoluteCoords(\n boundTextElement,\n elementsMap,\n );\n\n boundTextCanvasContext.rotate(-element.angle);\n const offsetX = (boundTextCanvas.width - canvas!.width) / 2;\n const offsetY = (boundTextCanvas.height - canvas!.height) / 2;\n const shiftX =\n boundTextCanvas.width / 2 -\n (boundTextCx - x1) * window.devicePixelRatio * scale -\n offsetX -\n padding * scale;\n\n const shiftY =\n boundTextCanvas.height / 2 -\n (boundTextCy - y1) * window.devicePixelRatio * scale -\n offsetY -\n padding * scale;\n boundTextCanvasContext.translate(-shiftX, -shiftY);\n // Clear the bound text area\n boundTextCanvasContext.clearRect(\n -(boundTextElement.width / 2 + BOUND_TEXT_PADDING) *\n window.devicePixelRatio *\n scale,\n -(boundTextElement.height / 2 + BOUND_TEXT_PADDING) *\n window.devicePixelRatio *\n scale,\n (boundTextElement.width + BOUND_TEXT_PADDING * 2) *\n window.devicePixelRatio *\n scale,\n (boundTextElement.height + BOUND_TEXT_PADDING * 2) *\n window.devicePixelRatio *\n scale,\n );\n }\n\n return {\n element,\n canvas,\n theme: appState.theme,\n scale,\n zoomValue: zoom.value,\n canvasOffsetX,\n canvasOffsetY,\n boundTextElementVersion:\n getBoundTextElement(element, elementsMap)?.version || null,\n containingFrameOpacity:\n getContainingFrame(element, elementsMap)?.opacity || 100,\n boundTextCanvas,\n angle: element.angle,\n imageCrop: isImageElement(element) ? element.crop : null,\n };\n};\n\nexport const DEFAULT_LINK_SIZE = 14;\n\nconst IMAGE_PLACEHOLDER_IMG = document.createElement(\"img\");\nIMAGE_PLACEHOLDER_IMG.src = `data:${MIME_TYPES.svg},${encodeURIComponent(\n `<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>`,\n)}`;\n\nconst IMAGE_ERROR_PLACEHOLDER_IMG = document.createElement(\"img\");\nIMAGE_ERROR_PLACEHOLDER_IMG.src = `data:${MIME_TYPES.svg},${encodeURIComponent(\n `<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)}`;\n\nconst drawImagePlaceholder = (\n element: ExcalidrawImageElement,\n context: CanvasRenderingContext2D,\n) => {\n context.fillStyle = \"#E7E7E7\";\n context.fillRect(0, 0, element.width, element.height);\n\n const imageMinWidthOrHeight = Math.min(element.width, element.height);\n\n const size = Math.min(\n imageMinWidthOrHeight,\n Math.min(imageMinWidthOrHeight * 0.4, 100),\n );\n\n context.drawImage(\n element.status === \"error\"\n ? IMAGE_ERROR_PLACEHOLDER_IMG\n : IMAGE_PLACEHOLDER_IMG,\n element.width / 2 - size / 2,\n element.height / 2 - size / 2,\n size,\n size,\n );\n};\n\nconst drawElementOnCanvas = (\n element: NonDeletedExcalidrawElement,\n rc: RoughCanvas,\n context: CanvasRenderingContext2D,\n renderConfig: StaticCanvasRenderConfig,\n appState: StaticCanvasAppState,\n) => {\n switch (element.type) {\n case \"rectangle\":\n case \"iframe\":\n case \"embeddable\":\n case \"diamond\":\n case \"ellipse\": {\n context.lineJoin = \"round\";\n context.lineCap = \"round\";\n rc.draw(ShapeCache.get(element)!);\n break;\n }\n case \"arrow\":\n case \"line\": {\n context.lineJoin = \"round\";\n context.lineCap = \"round\";\n\n ShapeCache.get(element)!.forEach((shape) => {\n rc.draw(shape);\n });\n break;\n }\n case \"freedraw\": {\n // Draw directly to canvas\n context.save();\n context.fillStyle = element.strokeColor;\n\n const path = getFreeDrawPath2D(element) as Path2D;\n const fillShape = ShapeCache.get(element);\n\n if (fillShape) {\n rc.draw(fillShape);\n }\n\n context.fillStyle = element.strokeColor;\n context.fill(path);\n\n context.restore();\n break;\n }\n case \"image\": {\n const img = isInitializedImageElement(element)\n ? renderConfig.imageCache.get(element.fileId)?.image\n : undefined;\n if (img != null && !(img instanceof Promise)) {\n if (element.roundness && context.roundRect) {\n context.beginPath();\n context.roundRect(\n 0,\n 0,\n element.width,\n element.height,\n getCornerRadius(Math.min(element.width, element.height), element),\n );\n context.clip();\n }\n\n const { x, y, width, height } = element.crop\n ? element.crop\n : {\n x: 0,\n y: 0,\n width: img.naturalWidth,\n height: img.naturalHeight,\n };\n\n context.drawImage(\n img,\n x,\n y,\n width,\n height,\n 0 /* hardcoded for the selection box*/,\n 0,\n element.width,\n element.height,\n );\n } else {\n drawImagePlaceholder(element, context);\n }\n break;\n }\n default: {\n if (isTextElement(element)) {\n const rtl = isRTL(element.text);\n const shouldTemporarilyAttach = rtl && !context.canvas.isConnected;\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 context.canvas.setAttribute(\"dir\", rtl ? \"rtl\" : \"ltr\");\n context.save();\n context.font = getFontString(element);\n context.fillStyle = element.strokeColor;\n context.textAlign = element.textAlign as CanvasTextAlign;\n\n // Canvas does not support multiline text by default\n const lines = element.text.replace(/\\r\\n?/g, \"\\n\").split(\"\\n\");\n\n const horizontalOffset =\n element.textAlign === \"center\"\n ? element.width / 2\n : element.textAlign === \"right\"\n ? element.width\n : 0;\n\n const lineHeightPx = getLineHeightInPx(\n element.fontSize,\n element.lineHeight,\n );\n\n const verticalOffset = getVerticalOffset(\n element.fontFamily,\n element.fontSize,\n lineHeightPx,\n );\n\n for (let index = 0; index < lines.length; index++) {\n context.fillText(\n lines[index],\n horizontalOffset,\n index * lineHeightPx + verticalOffset,\n );\n }\n context.restore();\n if (shouldTemporarilyAttach) {\n context.canvas.remove();\n }\n } else {\n throw new Error(`Unimplemented type ${element.type}`);\n }\n }\n }\n};\n\nexport let elementWithCanvasCache = new WeakMap<\n ExcalidrawElement,\n ExcalidrawElementWithCanvas\n>();\n\nexport const clearRenderCache = () => {\n elementWithCanvasCache = new WeakMap();\n pathsCache = new WeakMap();\n};\n\nconst generateElementWithCanvas = (\n element: NonDeletedExcalidrawElement,\n elementsMap: NonDeletedSceneElementsMap,\n renderConfig: StaticCanvasRenderConfig,\n appState: StaticCanvasAppState,\n) => {\n const zoom: Zoom = renderConfig ? appState.zoom : defaultAppState.zoom;\n const prevElementWithCanvas = elementWithCanvasCache.get(element);\n const shouldRegenerateBecauseZoom =\n prevElementWithCanvas &&\n prevElementWithCanvas.zoomValue !== zoom.value &&\n !appState?.shouldCacheIgnoreZoom;\n const boundTextElement = getBoundTextElement(element, elementsMap);\n const boundTextElementVersion = boundTextElement?.version || null;\n const imageCrop = isImageElement(element) ? element.crop : null;\n\n const containingFrameOpacity =\n getContainingFrame(element, elementsMap)?.opacity || 100;\n\n if (\n !prevElementWithCanvas ||\n shouldRegenerateBecauseZoom ||\n prevElementWithCanvas.theme !== appState.theme ||\n prevElementWithCanvas.boundTextElementVersion !== boundTextElementVersion ||\n prevElementWithCanvas.imageCrop !== imageCrop ||\n prevElementWithCanvas.containingFrameOpacity !== containingFrameOpacity ||\n // 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 (isArrowElement(element) &&\n boundTextElement &&\n element.angle !== prevElementWithCanvas.angle)\n ) {\n const elementWithCanvas = generateElementCanvas(\n element,\n elementsMap,\n zoom,\n renderConfig,\n appState,\n );\n\n if (!elementWithCanvas) {\n return null;\n }\n\n elementWithCanvasCache.set(element, elementWithCanvas);\n\n return elementWithCanvas;\n }\n return prevElementWithCanvas;\n};\n\nconst drawElementFromCanvas = (\n elementWithCanvas: ExcalidrawElementWithCanvas,\n context: CanvasRenderingContext2D,\n renderConfig: StaticCanvasRenderConfig,\n appState: StaticCanvasAppState,\n allElementsMap: NonDeletedSceneElementsMap,\n) => {\n const element = elementWithCanvas.element;\n const padding = getCanvasPadding(element);\n const zoom = elementWithCanvas.scale;\n const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, allElementsMap);\n const cx = ((x1 + x2) / 2 + appState.scrollX) * window.devicePixelRatio;\n const cy = ((y1 + y2) / 2 + appState.scrollY) * window.devicePixelRatio;\n\n context.save();\n context.scale(1 / window.devicePixelRatio, 1 / window.devicePixelRatio);\n\n const boundTextElement = getBoundTextElement(element, allElementsMap);\n\n if (isArrowElement(element) && boundTextElement) {\n const offsetX =\n (elementWithCanvas.boundTextCanvas.width -\n elementWithCanvas.canvas!.width) /\n 2;\n const offsetY =\n (elementWithCanvas.boundTextCanvas.height -\n elementWithCanvas.canvas!.height) /\n 2;\n context.translate(cx, cy);\n context.drawImage(\n elementWithCanvas.boundTextCanvas,\n (-(x2 - x1) / 2) * window.devicePixelRatio - offsetX / zoom - padding,\n (-(y2 - y1) / 2) * window.devicePixelRatio - offsetY / zoom - padding,\n elementWithCanvas.boundTextCanvas.width / zoom,\n elementWithCanvas.boundTextCanvas.height / zoom,\n );\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\n context.rotate(element.angle);\n\n if (\n \"scale\" in elementWithCanvas.element &&\n !isPendingImageElement(element, renderConfig)\n ) {\n context.scale(\n elementWithCanvas.element.scale[0],\n elementWithCanvas.element.scale[1],\n );\n }\n\n // revert afterwards we don't have account for it during drawing\n context.translate(-cx, -cy);\n\n context.drawImage(\n elementWithCanvas.canvas!,\n (x1 + appState.scrollX) * window.devicePixelRatio -\n (padding * elementWithCanvas.scale) / elementWithCanvas.scale,\n (y1 + appState.scrollY) * window.devicePixelRatio -\n (padding * elementWithCanvas.scale) / elementWithCanvas.scale,\n elementWithCanvas.canvas!.width / elementWithCanvas.scale,\n elementWithCanvas.canvas!.height / elementWithCanvas.scale,\n );\n\n if (\n import.meta.env.VITE_APP_DEBUG_ENABLE_TEXT_CONTAINER_BOUNDING_BOX ===\n \"true\" &&\n hasBoundTextElement(element)\n ) {\n const textElement = getBoundTextElement(\n element,\n allElementsMap,\n ) as ExcalidrawTextElementWithContainer;\n const coords = getContainerCoords(element);\n context.strokeStyle = \"#c92a2a\";\n context.lineWidth = 3;\n context.strokeRect(\n (coords.x + appState.scrollX) * window.devicePixelRatio,\n (coords.y + appState.scrollY) * window.devicePixelRatio,\n getBoundTextMaxWidth(element, textElement) * window.devicePixelRatio,\n getBoundTextMaxHeight(element, textElement) * window.devicePixelRatio,\n );\n }\n }\n context.restore();\n\n // Clear the nested element we appended to the DOM\n};\n\nexport const renderSelectionElement = (\n element: NonDeletedExcalidrawElement,\n context: CanvasRenderingContext2D,\n appState: InteractiveCanvasAppState,\n selectionColor: InteractiveCanvasRenderConfig[\"selectionColor\"],\n) => {\n context.save();\n context.translate(element.x + appState.scrollX, element.y + appState.scrollY);\n context.fillStyle = \"rgba(0, 0, 200, 0.04)\";\n\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 const offset = 0.5 / appState.zoom.value;\n\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\n context.restore();\n};\n\nexport const renderElement = (\n element: NonDeletedExcalidrawElement,\n elementsMap: RenderableElementsMap,\n allElementsMap: NonDeletedSceneElementsMap,\n rc: RoughCanvas,\n context: CanvasRenderingContext2D,\n renderConfig: StaticCanvasRenderConfig,\n appState: StaticCanvasAppState,\n) => {\n const reduceAlphaForSelection =\n appState.openDialog?.name === \"elementLinkSelector\" &&\n !appState.selectedElementIds[element.id] &&\n !appState.hoveredElementIds[element.id];\n\n context.globalAlpha = getRenderOpacity(\n element,\n getContainingFrame(element, elementsMap),\n renderConfig.elementsPendingErasure,\n renderConfig.pendingFlowchartNodes,\n reduceAlphaForSelection ? DEFAULT_REDUCED_GLOBAL_ALPHA : 1,\n );\n\n switch (element.type) {\n case \"magicframe\":\n case \"frame\": {\n if (appState.frameRendering.enabled && appState.frameRendering.outline) {\n context.save();\n context.translate(\n element.x + appState.scrollX,\n element.y + appState.scrollY,\n );\n context.fillStyle = \"rgba(0, 0, 200, 0.04)\";\n\n context.lineWidth = FRAME_STYLE.strokeWidth / appState.zoom.value;\n context.strokeStyle = FRAME_STYLE.strokeColor;\n\n // TODO change later to only affect AI frames\n if (isMagicFrameElement(element)) {\n context.strokeStyle =\n appState.theme === THEME.LIGHT ? \"#7affd7\" : \"#1d8264\";\n }\n\n if (FRAME_STYLE.radius && context.roundRect) {\n context.beginPath();\n context.roundRect(\n 0,\n 0,\n element.width,\n element.height,\n FRAME_STYLE.radius / appState.zoom.value,\n );\n context.stroke();\n context.closePath();\n } else {\n context.strokeRect(0, 0, element.width, element.height);\n }\n\n context.restore();\n }\n break;\n }\n case \"freedraw\": {\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 ShapeCache.generateElementShape(element, null);\n\n if (renderConfig.isExporting) {\n const [x1, y1, x2, y2] = 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, appState);\n context.restore();\n } else {\n const elementWithCanvas = generateElementWithCanvas(\n element,\n allElementsMap,\n renderConfig,\n appState,\n );\n if (!elementWithCanvas) {\n return;\n }\n\n drawElementFromCanvas(\n elementWithCanvas,\n context,\n renderConfig,\n appState,\n allElementsMap,\n );\n }\n\n break;\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 // 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 ShapeCache.generateElementShape(element, renderConfig);\n if (renderConfig.isExporting) {\n const [x1, y1, x2, y2] = 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 if (isTextElement(element)) {\n const container = getContainerElement(element, elementsMap);\n if (isArrowElement(container)) {\n const boundTextCoords =\n LinearElementEditor.getBoundTextElementPosition(\n container,\n element as ExcalidrawTextElementWithContainer,\n elementsMap,\n );\n shiftX = (x2 - x1) / 2 - (boundTextCoords.x - x1);\n shiftY = (y2 - y1) / 2 - (boundTextCoords.y - y1);\n }\n }\n context.save();\n context.translate(cx, cy);\n\n if (shouldResetImageFilter(element, renderConfig, appState)) {\n context.filter = \"none\";\n }\n const boundTextElement = getBoundTextElement(element, elementsMap);\n\n if (isArrowElement(element) && boundTextElement) {\n const tempCanvas = document.createElement(\"canvas\");\n\n const tempCanvasContext = tempCanvas.getContext(\"2d\")!;\n\n // Take max dimensions of arrow canvas so that when canvas is rotated\n // the arrow doesn't get clipped\n const maxDim = Math.max(distance(x1, x2), distance(y1, y2));\n const padding = getCanvasPadding(element);\n tempCanvas.width =\n maxDim * appState.exportScale + padding * 10 * appState.exportScale;\n tempCanvas.height =\n maxDim * appState.exportScale + padding * 10 * appState.exportScale;\n\n tempCanvasContext.translate(\n tempCanvas.width / 2,\n tempCanvas.height / 2,\n );\n tempCanvasContext.scale(appState.exportScale, appState.exportScale);\n\n // Shift the canvas to left most point of the arrow\n shiftX = element.width / 2 - (element.x - x1);\n shiftY = element.height / 2 - (element.y - y1);\n\n tempCanvasContext.rotate(element.angle);\n const tempRc = rough.canvas(tempCanvas);\n\n tempCanvasContext.translate(-shiftX, -shiftY);\n\n drawElementOnCanvas(\n element,\n tempRc,\n tempCanvasContext,\n renderConfig,\n appState,\n );\n\n tempCanvasContext.translate(shiftX, shiftY);\n\n tempCanvasContext.rotate(-element.angle);\n\n // Shift the canvas to center of bound text\n const [, , , , boundTextCx, boundTextCy] = getElementAbsoluteCoords(\n boundTextElement,\n elementsMap,\n );\n const boundTextShiftX = (x1 + x2) / 2 - boundTextCx;\n const boundTextShiftY = (y1 + y2) / 2 - boundTextCy;\n tempCanvasContext.translate(-boundTextShiftX, -boundTextShiftY);\n\n // Clear the bound text area\n tempCanvasContext.clearRect(\n -boundTextElement.width / 2,\n -boundTextElement.height / 2,\n boundTextElement.width,\n boundTextElement.height,\n );\n context.scale(1 / appState.exportScale, 1 / appState.exportScale);\n context.drawImage(\n tempCanvas,\n -tempCanvas.width / 2,\n -tempCanvas.height / 2,\n tempCanvas.width,\n tempCanvas.height,\n );\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, appState);\n }\n\n context.restore();\n // not exporting \u2192 optimized rendering (cache & render from element\n // canvases)\n } else {\n const elementWithCanvas = generateElementWithCanvas(\n element,\n allElementsMap,\n renderConfig,\n appState,\n );\n\n if (!elementWithCanvas) {\n return;\n }\n\n const currentImageSmoothingStatus = context.imageSmoothingEnabled;\n\n if (\n // do not disable smoothing during zoom as blurry shapes look better\n // on low resolution (while still zooming in) than sharp ones\n !appState?.shouldCacheIgnoreZoom &&\n // angle is 0 -> always disable smoothing\n (!element.angle ||\n // 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 isRightAngleRads(element.angle))\n ) {\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 (\n element.id === appState.croppingElementId &&\n isImageElement(elementWithCanvas.element) &&\n elementWithCanvas.element.crop !== null\n ) {\n context.save();\n context.globalAlpha = 0.1;\n\n const uncroppedElementCanvas = generateElementCanvas(\n getUncroppedImageElement(elementWithCanvas.element, elementsMap),\n allElementsMap,\n appState.zoom,\n renderConfig,\n appState,\n );\n\n if (uncroppedElementCanvas) {\n drawElementFromCanvas(\n uncroppedElementCanvas,\n context,\n renderConfig,\n appState,\n allElementsMap,\n );\n }\n\n context.restore();\n }\n\n drawElementFromCanvas(\n elementWithCanvas,\n context,\n renderConfig,\n appState,\n allElementsMap,\n );\n\n // reset\n context.imageSmoothingEnabled = currentImageSmoothingStatus;\n }\n break;\n }\n default: {\n // @ts-ignore\n throw new Error(`Unimplemented type ${element.type}`);\n }\n }\n\n context.globalAlpha = 1;\n};\n\nexport let pathsCache = new WeakMap<ExcalidrawFreeDrawElement, Path2D>([]);\n\nexport function generateFreeDrawShape(element: ExcalidrawFreeDrawElement) {\n const svgPathData = getFreeDrawSvgPath(element);\n const path = new Path2D(svgPathData);\n pathsCache.set(element, path);\n return path;\n}\n\nexport function getFreeDrawPath2D(element: ExcalidrawFreeDrawElement) {\n return pathsCache.get(element);\n}\n\nexport function getFreeDrawSvgPath(element: ExcalidrawFreeDrawElement) {\n // If input points are empty (should they ever be?) return a dot\n const inputPoints = element.simulatePressure\n ? element.points\n : element.points.length\n ? element.points.map(([x, y], i) => [x, y, element.pressures[i]])\n : [[0, 0, 0.5]];\n\n // Consider changing the options for simulated pressure vs real pressure\n const options: StrokeOptions = {\n simulatePressure: element.simulatePressure,\n size: element.strokeWidth * 4.25,\n thinning: 0.6,\n smoothing: 0.5,\n streamline: 0.5,\n easing: (t) => Math.sin((t * Math.PI) / 2), // https://easings.net/#easeOutSine\n last: !!element.lastCommittedPoint, // LastCommittedPoint is added on pointerup\n };\n\n return getSvgPathFromStroke(getStroke(inputPoints as number[][], options));\n}\n\nfunction med(A: number[], B: number[]) {\n return [(A[0] + B[0]) / 2, (A[1] + B[1]) / 2];\n}\n\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.\nconst TO_FIXED_PRECISION = /(\\s?[A-Z]?,?-?[0-9]*\\.[0-9]{0,2})(([0-9]|e|-)*)/g;\n\nfunction getSvgPathFromStroke(points: number[][]): string {\n if (!points.length) {\n return \"\";\n }\n\n const max = points.length - 1;\n\n return points\n .reduce(\n (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 return acc;\n },\n [\"M\", points[0], \"Q\"],\n )\n .join(\" \")\n .replace(TO_FIXED_PRECISION, \"$1\");\n}\n", "import type { Drawable } from \"roughjs/bin/core\";\nimport { RoughGenerator } from \"roughjs/bin/generator\";\nimport type {\n ExcalidrawElement,\n ExcalidrawSelectionElement,\n} from \"../element/types\";\nimport { elementWithCanvasCache } from \"../renderer/renderElement\";\nimport { _generateElementShape } from \"./Shape\";\nimport type { ElementShape, ElementShapes } from \"./types\";\nimport { COLOR_PALETTE } from \"../colors\";\nimport type { EmbedsValidationStatus } from \"../types\";\nimport type { StaticCanvasRenderConfig } from \"./types\";\n\nexport class ShapeCache {\n private static rg = new RoughGenerator();\n private static cache = new WeakMap<ExcalidrawElement, ElementShape>();\n\n /**\n * Retrieves shape from cache if available. Use this only if shape\n * is optional and you have a fallback in case it's not cached.\n */\n public static get = <T extends ExcalidrawElement>(element: T) => {\n return ShapeCache.cache.get(\n element,\n ) as T[\"type\"] extends keyof ElementShapes\n ? ElementShapes[T[\"type\"]] | undefined\n : ElementShape | undefined;\n };\n\n public static set = <T extends ExcalidrawElement>(\n element: T,\n shape: T[\"type\"] extends keyof ElementShapes\n ? ElementShapes[T[\"type\"]]\n : Drawable,\n ) => ShapeCache.cache.set(element, shape);\n\n public static delete = (element: ExcalidrawElement) =>\n ShapeCache.cache.delete(element);\n\n public static destroy = () => {\n ShapeCache.cache = new WeakMap();\n };\n\n /**\n * Generates & caches shape for element if not already cached, otherwise\n * returns cached shape.\n */\n public static generateElementShape = <\n T extends Exclude<ExcalidrawElement, ExcalidrawSelectionElement>,\n >(\n element: T,\n renderConfig: {\n isExporting: boolean;\n canvasBackgroundColor: StaticCanvasRenderConfig[\"canvasBackgroundColor\"];\n embedsValidationStatus: EmbedsValidationStatus;\n } | null,\n ) => {\n // when exporting, always regenerated to guarantee the latest shape\n const cachedShape = renderConfig?.isExporting\n ? undefined\n : ShapeCache.get(element);\n\n // `null` indicates no rc shape applicable for this element type,\n // but it's considered a valid cache value (= do not regenerate)\n if (cachedShape !== undefined) {\n return cachedShape;\n }\n\n elementWithCanvasCache.delete(element);\n\n const shape = _generateElementShape(\n element,\n ShapeCache.rg,\n renderConfig || {\n isExporting: false,\n canvasBackgroundColor: COLOR_PALETTE.white,\n embedsValidationStatus: null,\n },\n ) as T[\"type\"] extends keyof ElementShapes\n ? ElementShapes[T[\"type\"]]\n : Drawable | null;\n\n ShapeCache.cache.set(element, shape);\n\n return shape;\n };\n}\n", "import oc from \"open-color\";\nimport {\n COLOR_WHITE,\n COLOR_CHARCOAL_BLACK,\n COLOR_TRANSPARENT,\n} from \"./constants\";\nimport type { Merge } from \"./utility-types\";\nimport { pick } from \"./utils\";\n\nexport type ColorPickerColor =\n | Exclude<keyof oc, \"indigo\" | \"lime\" | \"black\">\n | \"transparent\"\n | \"charcoal\"\n | \"bronze\";\nexport type ColorTuple = readonly [string, string, string, string, string];\nexport type ColorPalette = Merge<\n Record<ColorPickerColor, ColorTuple>,\n {\n charcoal: typeof COLOR_CHARCOAL_BLACK;\n white: typeof COLOR_WHITE;\n transparent: typeof COLOR_TRANSPARENT;\n }\n>;\n\n// used general type instead of specific type (ColorPalette) to support custom colors\nexport type ColorPaletteCustom = { [key: string]: ColorTuple | string };\nexport type ColorShadesIndexes = [number, number, number, number, number];\n\nexport const MAX_CUSTOM_COLORS_USED_IN_CANVAS = 5;\nexport const COLORS_PER_ROW = 5;\n\nexport const DEFAULT_CHART_COLOR_INDEX = 4;\n\nexport const DEFAULT_ELEMENT_STROKE_COLOR_INDEX = 4;\nexport const DEFAULT_ELEMENT_BACKGROUND_COLOR_INDEX = 1;\nexport const ELEMENTS_PALETTE_SHADE_INDEXES = [0, 2, 4, 6, 8] as const;\nexport const CANVAS_PALETTE_SHADE_INDEXES = [0, 1, 2, 3, 4] as const;\n\nexport const getSpecificColorShades = (\n color: Exclude<\n ColorPickerColor,\n \"transparent\" | \"charcoal\" | \"black\" | \"white\" | \"bronze\"\n >,\n indexArr: Readonly<ColorShadesIndexes>,\n) => {\n return indexArr.map((index) => oc[color][index]) as any as ColorTuple;\n};\n\nexport const COLOR_PALETTE = {\n transparent: COLOR_TRANSPARENT,\n charcoal: COLOR_CHARCOAL_BLACK,\n white: COLOR_WHITE,\n // open-colors\n gray: getSpecificColorShades(\"gray\", ELEMENTS_PALETTE_SHADE_INDEXES),\n red: getSpecificColorShades(\"red\", ELEMENTS_PALETTE_SHADE_INDEXES),\n pink: getSpecificColorShades(\"pink\", ELEMENTS_PALETTE_SHADE_INDEXES),\n grape: getSpecificColorShades(\"grape\", ELEMENTS_PALETTE_SHADE_INDEXES),\n violet: getSpecificColorShades(\"violet\", ELEMENTS_PALETTE_SHADE_INDEXES),\n blue: getSpecificColorShades(\"blue\", ELEMENTS_PALETTE_SHADE_INDEXES),\n cyan: getSpecificColorShades(\"cyan\", ELEMENTS_PALETTE_SHADE_INDEXES),\n teal: getSpecificColorShades(\"teal\", ELEMENTS_PALETTE_SHADE_INDEXES),\n green: getSpecificColorShades(\"green\", ELEMENTS_PALETTE_SHADE_INDEXES),\n yellow: getSpecificColorShades(\"yellow\", ELEMENTS_PALETTE_SHADE_INDEXES),\n orange: getSpecificColorShades(\"orange\", ELEMENTS_PALETTE_SHADE_INDEXES),\n // radix bronze shades 3,5,7,9,11\n bronze: [\"#f8f1ee\", \"#eaddd7\", \"#d2bab0\", \"#a18072\", \"#846358\"],\n} as ColorPalette;\n\nconst COMMON_ELEMENT_SHADES = pick(COLOR_PALETTE, [\n \"cyan\",\n \"blue\",\n \"violet\",\n \"grape\",\n \"pink\",\n \"green\",\n \"teal\",\n \"yellow\",\n \"orange\",\n \"red\",\n]);\n\n// -----------------------------------------------------------------------------\n// quick picks defaults\n// -----------------------------------------------------------------------------\n\n// ORDER matters for positioning in quick picker\nexport const DEFAULT_ELEMENT_STROKE_PICKS = [\n COLOR_PALETTE.charcoal,\n COLOR_PALETTE.red[DEFAULT_ELEMENT_STROKE_COLOR_INDEX],\n COLOR_PALETTE.green[DEFAULT_ELEMENT_STROKE_COLOR_INDEX],\n COLOR_PALETTE.blue[DEFAULT_ELEMENT_STROKE_COLOR_INDEX],\n COLOR_PALETTE.yellow[DEFAULT_ELEMENT_STROKE_COLOR_INDEX],\n] as ColorTuple;\n\n// ORDER matters for positioning in quick picker\nexport const DEFAULT_ELEMENT_BACKGROUND_PICKS = [\n COLOR_PALETTE.transparent,\n COLOR_PALETTE.red[DEFAULT_ELEMENT_BACKGROUND_COLOR_INDEX],\n COLOR_PALETTE.green[DEFAULT_ELEMENT_BACKGROUND_COLOR_INDEX],\n COLOR_PALETTE.blue[DEFAULT_ELEMENT_BACKGROUND_COLOR_INDEX],\n COLOR_PALETTE.yellow[DEFAULT_ELEMENT_BACKGROUND_COLOR_INDEX],\n] as ColorTuple;\n\n// ORDER matters for positioning in quick picker\nexport const DEFAULT_CANVAS_BACKGROUND_PICKS = [\n COLOR_PALETTE.white,\n // radix slate2\n \"#f8f9fa\",\n // radix blue2\n \"#f5faff\",\n // radix yellow2\n \"#fffce8\",\n // radix bronze2\n \"#fdf8f6\",\n] as ColorTuple;\n\n// -----------------------------------------------------------------------------\n// palette defaults\n// -----------------------------------------------------------------------------\n\nexport const DEFAULT_ELEMENT_STROKE_COLOR_PALETTE = {\n // 1st row\n transparent: COLOR_PALETTE.transparent,\n white: COLOR_PALETTE.white,\n gray: COLOR_PALETTE.gray,\n charcoal: COLOR_PALETTE.charcoal,\n bronze: COLOR_PALETTE.bronze,\n // rest\n ...COMMON_ELEMENT_SHADES,\n} as const;\n\n// ORDER matters for positioning in pallete (5x3 grid)s\nexport const DEFAULT_ELEMENT_BACKGROUND_COLOR_PALETTE = {\n transparent: COLOR_PALETTE.transparent,\n white: COLOR_PALETTE.white,\n gray: COLOR_PALETTE.gray,\n charcoal: COLOR_PALETTE.charcoal,\n bronze: COLOR_PALETTE.bronze,\n\n ...COMMON_ELEMENT_SHADES,\n} as const;\n\n// -----------------------------------------------------------------------------\n// helpers\n// -----------------------------------------------------------------------------\n\n// !!!MUST BE WITHOUT GRAY, TRANSPARENT AND BLACK!!!\nexport const getAllColorsSpecificShade = (index: 0 | 1 | 2 | 3 | 4) =>\n [\n // 2nd row\n COLOR_PALETTE.cyan[index],\n COLOR_PALETTE.blue[index],\n COLOR_PALETTE.violet[index],\n COLOR_PALETTE.grape[index],\n COLOR_PALETTE.pink[index],\n\n // 3rd row\n COLOR_PALETTE.green[index],\n COLOR_PALETTE.teal[index],\n COLOR_PALETTE.yellow[index],\n COLOR_PALETTE.orange[index],\n COLOR_PALETTE.red[index],\n ] as const;\n\nexport const rgbToHex = (r: number, g: number, b: number) =>\n `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;\n\n// -----------------------------------------------------------------------------\n", "//\n// All icons are imported from https://fontawesome.com/icons?d=gallery\n// Icons are under the license https://fontawesome.com/license\n//\n\n// Note: when adding new icons, review https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/RTL_Guidelines\n// to determine whether or not the icons should be mirrored in right-to-left languages.\n\nimport React from \"react\";\n\nimport oc from \"open-color\";\nimport clsx from \"clsx\";\nimport type { Theme } from \"../element/types\";\nimport { THEME } from \"../constants\";\n\nexport const iconFillColor = (theme: Theme) => \"var(--icon-fill-color)\";\n\nconst handlerColor = (theme: Theme) =>\n theme === THEME.LIGHT ? oc.white : \"#1e1e1e\";\n\ntype Opts = {\n width?: number;\n height?: number;\n mirror?: true;\n} & React.SVGProps<SVGSVGElement>;\n\nexport const createIcon = (\n d: string | React.ReactNode,\n opts: number | Opts = 512,\n) => {\n const {\n width = 512,\n height = width,\n mirror,\n style,\n ...rest\n } = typeof opts === \"number\" ? ({ width: opts } as Opts) : opts;\n return (\n <svg\n aria-hidden=\"true\"\n focusable=\"false\"\n role=\"img\"\n viewBox={`0 0 ${width} ${height}`}\n className={clsx({ \"rtl-mirror\": mirror })}\n style={style}\n {...rest}\n >\n {typeof d === \"string\" ? <path fill=\"currentColor\" d={d} /> : d}\n </svg>\n );\n};\n\nconst tablerIconProps: Opts = {\n width: 24,\n height: 24,\n fill: \"none\",\n strokeWidth: 2,\n stroke: \"currentColor\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n} as const;\n\nconst modifiedTablerIconProps: Opts = {\n width: 20,\n height: 20,\n fill: \"none\",\n stroke: \"currentColor\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n} as const;\n\n// -----------------------------------------------------------------------------\n\n// tabler-icons: home\nexport const HomeIcon = createIcon(\n <g strokeWidth={1.5}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <polyline points=\"5 12 3 12 12 3 21 12 19 12\"></polyline>\n <path d=\"M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7\"></path>\n <path d=\"M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6\"></path>\n </g>,\n tablerIconProps,\n);\n\n// tabler-icons: book\nexport const LibraryIcon = createIcon(\n <g strokeWidth=\"1.25\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M3 19a9 9 0 0 1 9 0a9 9 0 0 1 9 0\" />\n <path d=\"M3 6a9 9 0 0 1 9 0a9 9 0 0 1 9 0\" />\n <line x1=\"3\" y1=\"6\" x2=\"3\" y2=\"19\" />\n <line x1=\"12\" y1=\"6\" x2=\"12\" y2=\"19\" />\n <line x1=\"21\" y1=\"6\" x2=\"21\" y2=\"19\" />\n </g>,\n tablerIconProps,\n);\n\n// tabler-icons: plus\nexport const PlusIcon = createIcon(\n <svg strokeWidth=\"1.5\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>,\n tablerIconProps,\n);\n\n// tabler-icons: dots-vertical\nexport const DotsIcon = createIcon(\n <g strokeWidth=\"1.5\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <circle cx=\"12\" cy=\"12\" r=\"1\"></circle>\n <circle cx=\"12\" cy=\"19\" r=\"1\"></circle>\n <circle cx=\"12\" cy=\"5\" r=\"1\"></circle>\n </g>,\n tablerIconProps,\n);\n\n// tabler-icons: pinned\nexport const PinIcon = createIcon(\n <svg strokeWidth=\"1.5\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <path d=\"M9 4v6l-2 4v2h10v-2l-2 -4v-6\"></path>\n <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"21\"></line>\n <line x1=\"8\" y1=\"4\" x2=\"16\" y2=\"4\"></line>\n </svg>,\n tablerIconProps,\n);\n\n// tabler-icons: lock-open (via Figma)\nexport const UnlockedIcon = createIcon(\n <g>\n <path\n d=\"M13.542 8.542H6.458a2.5 2.5 0 0 0-2.5 2.5v3.75a2.5 2.5 0 0 0 2.5 2.5h7.084a2.5 2.5 0 0 0 2.5-2.5v-3.75a2.5 2.5 0 0 0-2.5-2.5Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n />\n <path\n d=\"M10 13.958a1.042 1.042 0 1 0 0-2.083 1.042 1.042 0 0 0 0 2.083Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n />\n <mask\n id=\"UnlockedIcon\"\n style={{ maskType: \"alpha\" }}\n maskUnits=\"userSpaceOnUse\"\n x={6}\n y={1}\n width={9}\n height={9}\n >\n <path\n stroke=\"none\"\n d=\"M6.399 9.561V5.175c0-.93.401-1.823 1.116-2.48a3.981 3.981 0 0 1 2.693-1.028c1.01 0 1.98.37 2.694 1.027.715.658 1.116 1.55 1.116 2.481\"\n fill=\"#fff\"\n />\n </mask>\n <g mask=\"url(#UnlockedIcon)\">\n <path\n stroke=\"none\"\n d=\"M5.149 9.561v1.25h2.5v-1.25h-2.5Zm5.06-7.894V.417v1.25Zm2.559 3.508v1.25h2.5v-1.25h-2.5ZM7.648 8.51V5.175h-2.5V8.51h2.5Zm0-3.334c0-.564.243-1.128.713-1.561L6.668 1.775c-.959.883-1.52 2.104-1.52 3.4h2.5Zm.713-1.561a2.732 2.732 0 0 1 1.847-.697v-2.5c-1.31 0-2.585.478-3.54 1.358L8.36 3.614Zm1.847-.697c.71 0 1.374.26 1.847.697l1.694-1.839a5.231 5.231 0 0 0-3.54-1.358v2.5Zm1.847.697c.47.433.713.997.713 1.561h2.5c0-1.296-.56-2.517-1.52-3.4l-1.693 1.839Z\"\n fill=\"currentColor\"\n />\n </g>\n </g>,\n modifiedTablerIconProps,\n);\n\n// tabler-icons: lock (via Figma)\nexport const LockedIcon = createIcon(\n <g strokeWidth=\"1.25\">\n <path d=\"M13.542 8.542H6.458a2.5 2.5 0 0 0-2.5 2.5v3.75a2.5 2.5 0 0 0 2.5 2.5h7.084a2.5 2.5 0 0 0 2.5-2.5v-3.75a2.5 2.5 0 0 0-2.5-2.5Z\" />\n <path d=\"M10 13.958a1.042 1.042 0 1 0 0-2.083 1.042 1.042 0 0 0 0 2.083Z\" />\n <path d=\"M6.667 8.333V5.417C6.667 3.806 8.159 2.5 10 2.5c1.841 0 3.333 1.306 3.333 2.917v2.916\" />\n </g>,\n modifiedTablerIconProps,\n);\n\n// custom\nexport const WelcomeScreenMenuArrow = createIcon(\n <>\n <path\n d=\"M38.5 83.5c-14-2-17.833-10.473-21-22.5C14.333 48.984 12 22 12 12.5\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"m12.005 10.478 7.905 14.423L6 25.75l6.005-15.273Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M12.005 10.478c1.92 3.495 3.838 7 7.905 14.423m-7.905-14.423c3.11 5.683 6.23 11.368 7.905 14.423m0 0c-3.68.226-7.35.455-13.91.85m13.91-.85c-5.279.33-10.566.647-13.91.85m0 0c1.936-4.931 3.882-9.86 6.005-15.273M6 25.75c2.069-5.257 4.135-10.505 6.005-15.272\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n />\n </>,\n { width: 41, height: 94, fill: \"none\" },\n);\n\n// custom\nexport const WelcomeScreenHelpArrow = createIcon(\n <>\n <path\n d=\"M18.026 1.232c-5.268 13.125-5.548 33.555 3.285 42.311 8.823 8.75 33.31 12.304 42.422 13.523\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"m72.181 59.247-13.058-10-2.948 13.62 16.006-3.62Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M72.181 59.247c-3.163-2.429-6.337-4.856-13.058-10m13.058 10c-5.145-3.936-10.292-7.882-13.058-10m0 0c-.78 3.603-1.563 7.196-2.948 13.62m2.948-13.62c-1.126 5.168-2.24 10.346-2.948 13.62m0 0c5.168-1.166 10.334-2.343 16.006-3.62m-16.006 3.62c5.51-1.248 11.01-2.495 16.006-3.62\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n />\n </>,\n { width: 85, height: 71, fill: \"none\" },\n);\n\n// custom\nexport const WelcomeScreenTopToolbarArrow = createIcon(\n <>\n <path\n d=\"M1 77c14-2 31.833-11.973 35-24 3.167-12.016-6-35-9.5-43.5\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"m24.165 1.093-2.132 16.309 13.27-4.258-11.138-12.05Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M24.165 1.093c-.522 3.953-1.037 7.916-2.132 16.309m2.131-16.309c-.835 6.424-1.68 12.854-2.13 16.308m0 0c3.51-1.125 7.013-2.243 13.27-4.257m-13.27 4.257c5.038-1.608 10.08-3.232 13.27-4.257m0 0c-3.595-3.892-7.197-7.777-11.14-12.05m11.14 12.05c-3.837-4.148-7.667-8.287-11.14-12.05\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n />\n </>,\n { width: 38, height: 78, fill: \"none\" },\n);\n\n// custom\nexport const ExcalLogo = createIcon(\n <g fill=\"currentColor\">\n <path\n d=\"M39.9 32.889a.326.326 0 0 0-.279-.056c-2.094-3.083-4.774-6-7.343-8.833l-.419-.472a.212.212 0 0 0-.056-.139.586.586 0 0 0-.167-.111l-.084-.083-.056-.056c-.084-.167-.28-.278-.475-.167-.782.39-1.507.973-2.206 1.528-.92.722-1.842 1.445-2.708 2.25a8.405 8.405 0 0 0-.977 1.028c-.14.194-.028.361.14.444-.615.611-1.23 1.223-1.843 1.861a.315.315 0 0 0-.084.223c0 .083.056.166.111.194l1.09.833v.028c1.535 1.528 4.244 3.611 7.12 5.861.418.334.865.667 1.284 1 .195.223.39.473.558.695.084.11.28.139.391.055.056.056.14.111.196.167a.398.398 0 0 0 .167.056.255.255 0 0 0 .224-.111.394.394 0 0 0 .055-.167c.029 0 .028.028.056.028a.318.318 0 0 0 .224-.084l5.082-5.528a.309.309 0 0 0 0-.444Zm-14.63-1.917a.485.485 0 0 0 .111.14c.586.5 1.2 1 1.843 1.555l-2.569-1.945-.251-.166c-.056-.028-.112-.084-.168-.111l-.195-.167.056-.056.055-.055.112-.111c.866-.861 2.346-2.306 3.1-3.028-.81.805-2.43 3.167-2.095 3.944Zm8.767 6.89-2.122-1.612a44.713 44.713 0 0 0-2.625-2.5c1.145.861 2.122 1.611 2.262 1.75 1.117.972 1.06.806 1.815 1.445l.921.666a1.06 1.06 0 0 1-.251.25Zm.558.416-.056-.028c.084-.055.168-.111.252-.194l-.196.222ZM1.089 5.75c.055.361.14.722.195 1.056.335 1.833.67 3.5 1.284 4.75l.252.944c.084.361.223.806.363.917 1.424 1.25 3.602 3.11 5.947 4.889a.295.295 0 0 0 .363 0s0 .027.028.027a.254.254 0 0 0 .196.084.318.318 0 0 0 .223-.084c2.988-3.305 5.221-6.027 6.813-8.305.112-.111.14-.278.14-.417.111-.111.195-.25.307-.333.111-.111.111-.306 0-.39l-.028-.027c0-.055-.028-.139-.084-.167-.698-.666-1.2-1.138-1.731-1.638-.922-.862-1.871-1.75-3.881-3.75l-.028-.028c-.028-.028-.056-.056-.112-.056-.558-.194-1.703-.389-3.127-.639C6.087 2.223 3.21 1.723.614.944c0 0-.168 0-.196.028l-.083.084c-.028.027-.056.055-.224.11h.056-.056c.028.167.028.278.084.473 0 .055.112.5.112.555l.782 3.556Zm15.496 3.278-.335-.334c.084.112.196.195.335.334Zm-3.546 4.666-.056.056c0-.028.028-.056.056-.056Zm-2.038-10c.168.167.866.834 1.033.973-.726-.334-2.54-1.167-3.379-1.445.838.167 1.983.334 2.346.472ZM1.424 2.306c.419.722.754 3.222 1.089 5.666-.196-.778-.335-1.555-.503-2.278-.251-1.277-.503-2.416-.838-3.416.056 0 .14 0 .252.028Zm-.168-.584c-.112 0-.223-.028-.307-.028 0-.027 0-.055-.028-.055.14 0 .223.028.335.083Zm-1.089.222c0-.027 0-.027 0 0ZM39.453 1.333c.028-.11-.558-.61-.363-.639.42-.027.42-.666 0-.666-.558.028-1.144.166-1.675.25-.977.194-1.982.389-2.96.61-2.205.473-4.383.973-6.561 1.557-.67.194-1.424.333-2.066.666-.224.111-.196.333-.084.472-.056.028-.084.028-.14.056-.195.028-.363.056-.558.083-.168.028-.252.167-.224.334 0 .027.028.083.028.11-1.173 1.556-2.485 3.195-3.909 4.945-1.396 1.611-2.876 3.306-4.356 5.056-4.719 5.5-10.052 11.75-15.943 17.25a.268.268 0 0 0 0 .389c.028.027.056.055.084.055-.084.084-.168.14-.252.222-.056.056-.084.111-.084.167a.605.605 0 0 0-.111.139c-.112.111-.112.305.028.389.111.11.307.11.39-.028.029-.028.029-.056.056-.056a.44.44 0 0 1 .615 0c.335.362.67.723.977 1.028l-.698-.583c-.112-.111-.307-.083-.39.028-.113.11-.085.305.027.389l7.427 6.194c.056.056.112.056.196.056s.14-.028.195-.084l.168-.166c.028.027.083.027.111.027.084 0 .14-.027.196-.083 10.052-10.055 18.15-17.639 27.42-24.417.083-.055.111-.166.111-.25.112 0 .196-.083.251-.194 1.704-5.194 2.039-9.806 2.15-12.083v-.028c0-.028.028-.056.028-.083.028-.056.028-.084.028-.084a1.626 1.626 0 0 0-.111-1.028ZM21.472 9.5c.446-.5.893-1.028 1.34-1.5-2.876 3.778-7.65 9.583-14.408 16.5 4.607-5.083 9.242-10.333 13.068-15ZM5.193 35.778h.084-.084Zm3.462 3.194c-.027-.028-.027-.028 0-.028v.028Zm4.16-3.583c.224-.25.448-.472.699-.722 0 0 0 .027.028.027-.252.223-.475.445-.726.695Zm1.146-1.111c.14-.14.279-.334.446-.5l.028-.028c1.648-1.694 3.351-3.389 5.082-5.111l.028-.028c.419-.333.921-.694 1.368-1.028a379.003 379.003 0 0 0-6.952 6.695ZM24.794 6.472c-.921 1.195-1.954 2.778-2.82 4.028-2.736 3.944-11.532 13.583-11.727 13.75a1976.983 1976.983 0 0 1-8.042 7.639l-.167.167c-.14-.167-.14-.417.028-.556C14.49 19.861 22.03 10.167 25.074 5.917c-.084.194-.14.36-.28.555Zm4.83 5.695c-1.116-.64-1.646-1.64-1.34-2.611l.084-.334c.028-.083.084-.194.14-.277.307-.5.754-.917 1.257-1.167.027 0 .055 0 .083-.028-.028-.056-.028-.139-.028-.222.028-.167.14-.278.335-.278.335 0 1.369.306 1.76.639.111.083.223.194.335.305.14.167.363.445.474.667.056.028.112.306.196.445.056.222.111.472.084.694-.028.028 0 .194-.028.194a2.668 2.668 0 0 1-.363 1.028c-.028.028-.028.056-.056.084l-.028.027c-.14.223-.335.417-.53.556-.643.444-1.369.583-2.095.389 0 0-.195-.084-.28-.111Zm8.154-.834a39.098 39.098 0 0 1-.893 3.167c0 .028-.028.083 0 .111-.056 0-.084.028-.14.056-2.206 1.61-4.356 3.305-6.506 5.028 1.843-1.64 3.686-3.306 5.613-4.945.558-.5.949-1.139 1.06-1.861l.28-1.667v-.055c.14-.334.67-.195.586.166Z\"\n fill=\"currentColor\"\n />\n </g>,\n { width: 40, height: 40, fill: \"none\" },\n);\n\n// custom\nexport const SelectionIcon = createIcon(\n <g stroke=\"currentColor\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M6 6l4.153 11.793a0.365 .365 0 0 0 .331 .207a0.366 .366 0 0 0 .332 -.207l2.184 -4.793l4.787 -1.994a0.355 .355 0 0 0 .213 -.323a0.355 .355 0 0 0 -.213 -.323l-11.787 -4.36z\" />\n <path d=\"M13.5 13.5l4.5 4.5\" />\n </g>,\n { fill: \"none\", width: 22, height: 22, strokeWidth: 1.25 },\n);\n\n// tabler-icons: square\nexport const RectangleIcon = createIcon(\n <g strokeWidth=\"1.5\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\"></rect>\n </g>,\n tablerIconProps,\n);\n\n// tabler-icons: square-rotated\nexport const DiamondIcon = createIcon(\n <g strokeWidth=\"1.5\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M10.5 20.4l-6.9 -6.9c-.781 -.781 -.781 -2.219 0 -3l6.9 -6.9c.781 -.781 2.219 -.781 3 0l6.9 6.9c.781 .781 .781 2.219 0 3l-6.9 6.9c-.781 .781 -2.219 .781 -3 0z\" />\n </g>,\n\n tablerIconProps,\n);\n\n// tabler-icons: circle\nexport const EllipseIcon = createIcon(\n <g strokeWidth=\"1.5\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <circle cx=\"12\" cy=\"12\" r=\"9\"></circle>\n </g>,\n\n tablerIconProps,\n);\n\n// tabler-icons: arrow-narrow-right\nexport const ArrowIcon = createIcon(\n <g strokeWidth=\"1.5\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n <line x1=\"15\" y1=\"16\" x2=\"19\" y2=\"12\" />\n <line x1=\"15\" y1=\"8\" x2=\"19\" y2=\"12\" />\n </g>,\n tablerIconProps,\n);\n\n// custom?\nexport const LineIcon = createIcon(\n <path d=\"M4.167 10h11.666\" strokeWidth=\"1.5\" />,\n modifiedTablerIconProps,\n);\n\nexport const PenModeIcon = createIcon(\n <g strokeWidth=\"1.25\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <path d=\"M20 17v-12c0 -1.121 -.879 -2 -2 -2s-2 .879 -2 2v12l2 2l2 -2z\"></path>\n <path d=\"M16 7h4\"></path>\n <path d=\"M18 19h-13a2 2 0 1 1 0 -4h4a2 2 0 1 0 0 -4h-3\"></path>\n </g>,\n tablerIconProps,\n);\n\n// modified tabler-icons: pencil\nexport const FreedrawIcon = createIcon(\n <g strokeWidth=\"1.25\">\n <path\n clipRule=\"evenodd\"\n d=\"m7.643 15.69 7.774-7.773a2.357 2.357 0 1 0-3.334-3.334L4.31 12.357a3.333 3.333 0 0 0-.977 2.357v1.953h1.953c.884 0 1.732-.352 2.357-.977Z\"\n />\n <path d=\"m11.25 5.417 3.333 3.333\" />\n </g>,\n\n modifiedTablerIconProps,\n);\n\n// tabler-icons: typography\nexport const TextIcon = createIcon(\n <g strokeWidth=\"1.5\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <line x1=\"4\" y1=\"20\" x2=\"7\" y2=\"20\" />\n <line x1=\"14\" y1=\"20\" x2=\"21\" y2=\"20\" />\n <line x1=\"6.9\" y1=\"15\" x2=\"13.8\" y2=\"15\" />\n <line x1=\"10.2\" y1=\"6.3\" x2=\"16\" y2=\"20\" />\n <polyline points=\"5 20 11 4 13 4 20 20\"></polyline>\n </g>,\n tablerIconProps,\n);\n\n// modified tabler-icons: photo\nexport const ImageIcon = createIcon(\n <g strokeWidth=\"1.25\">\n <path d=\"M12.5 6.667h.01\" />\n <path d=\"M4.91 2.625h10.18a2.284 2.284 0 0 1 2.285 2.284v10.182a2.284 2.284 0 0 1-2.284 2.284H4.909a2.284 2.284 0 0 1-2.284-2.284V4.909a2.284 2.284 0 0 1 2.284-2.284Z\" />\n <path d=\"m3.333 12.5 3.334-3.333c.773-.745 1.726-.745 2.5 0l4.166 4.166\" />\n <path d=\"m11.667 11.667.833-.834c.774-.744 1.726-.744 2.5 0l1.667 1.667\" />\n </g>,\n modifiedTablerIconProps,\n);\n\n// tabler-icons: eraser\nexport const EraserIcon = createIcon(\n <g strokeWidth=\"1.5\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M19 20h-10.5l-4.21 -4.3a1 1 0 0 1 0 -1.41l10 -10a1 1 0 0 1 1.41 0l5 5a1 1 0 0 1 0 1.41l-9.2 9.3\" />\n <path d=\"M18 13.3l-6.3 -6.3\" />\n </g>,\n tablerIconProps,\n);\n\nexport const ZoomInIcon = createIcon(\n <path strokeWidth=\"1.25\" d=\"M10 4.167v11.666M4.167 10h11.666\" />,\n modifiedTablerIconProps,\n);\n\nexport const ZoomOutIcon = createIcon(\n <path d=\"M5 10h10\" strokeWidth=\"1.25\" />,\n modifiedTablerIconProps,\n);\n\nexport const ZoomResetIcon = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M21 21l-6 -6\" />\n <path d=\"M3.268 12.043a7.017 7.017 0 0 0 6.634 4.957a7.012 7.012 0 0 0 7.043 -6.131a7 7 0 0 0 -5.314 -7.672a7.021 7.021 0 0 0 -8.241 4.403\" />\n <path d=\"M3 4v4h4\" />\n </g>,\n tablerIconProps,\n);\n\nexport const TrashIcon = createIcon(\n <path\n strokeWidth=\"1.25\"\n d=\"M3.333 5.833h13.334M8.333 9.167v5M11.667 9.167v5M4.167 5.833l.833 10c0 .92.746 1.667 1.667 1.667h6.666c.92 0 1.667-.746 1.667-1.667l.833-10M7.5 5.833v-2.5c0-.46.373-.833.833-.833h3.334c.46 0 .833.373.833.833v2.5\"\n />,\n modifiedTablerIconProps,\n);\n\nexport const EmbedIcon = createIcon(\n <g strokeWidth=\"1.25\">\n <polyline points=\"12 16 18 10 12 4\" />\n <polyline points=\"8 4 2 10 8 16\" />\n </g>,\n modifiedTablerIconProps,\n);\n\nexport const DuplicateIcon = createIcon(\n <g strokeWidth=\"1.25\">\n <path d=\"M14.375 6.458H8.958a2.5 2.5 0 0 0-2.5 2.5v5.417a2.5 2.5 0 0 0 2.5 2.5h5.417a2.5 2.5 0 0 0 2.5-2.5V8.958a2.5 2.5 0 0 0-2.5-2.5Z\" />\n <path\n clipRule=\"evenodd\"\n d=\"M11.667 3.125c.517 0 .986.21 1.325.55.34.338.55.807.55 1.325v1.458H8.333c-.485 0-.927.185-1.26.487-.343.312-.57.75-.609 1.24l-.005 5.357H5a1.87 1.87 0 0 1-1.326-.55 1.87 1.87 0 0 1-.549-1.325V5c0-.518.21-.987.55-1.326.338-.34.807-.549 1.325-.549h6.667Z\"\n />\n </g>,\n modifiedTablerIconProps,\n);\n\nexport const MoonIcon = createIcon(\n <path\n clipRule=\"evenodd\"\n d=\"M10 2.5h.328a6.25 6.25 0 0 0 6.6 10.372A7.5 7.5 0 1 1 10 2.493V2.5Z\"\n stroke=\"currentColor\"\n />,\n modifiedTablerIconProps,\n);\n\nexport const SunIcon = createIcon(\n <g stroke=\"currentColor\" strokeLinejoin=\"round\">\n <path d=\"M10 12.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5ZM10 4.167V2.5M14.167 5.833l1.166-1.166M15.833 10H17.5M14.167 14.167l1.166 1.166M10 15.833V17.5M5.833 14.167l-1.166 1.166M5 10H3.333M5.833 5.833 4.667 4.667\" />\n </g>,\n { ...modifiedTablerIconProps, strokeWidth: 1.5 },\n);\n\nexport const HamburgerMenuIcon = createIcon(\n <g strokeWidth=\"1.5\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <line x1=\"4\" y1=\"6\" x2=\"20\" y2=\"6\"></line>\n <line x1=\"4\" y1=\"12\" x2=\"20\" y2=\"12\"></line>\n <line x1=\"4\" y1=\"18\" x2=\"20\" y2=\"18\"></line>\n </g>,\n tablerIconProps,\n);\n\nexport const ExportIcon = createIcon(\n <path\n strokeWidth=\"1.25\"\n d=\"M3.333 14.167v1.666c0 .92.747 1.667 1.667 1.667h10c.92 0 1.667-.746 1.667-1.667v-1.666M5.833 9.167 10 13.333l4.167-4.166M10 3.333v10\"\n />,\n modifiedTablerIconProps,\n);\n\nexport const HelpIcon = createIcon(\n <g strokeWidth=\"1.5\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <circle cx=\"12\" cy=\"12\" r=\"9\"></circle>\n <line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"17.01\"></line>\n <path d=\"M12 13.5a1.5 1.5 0 0 1 1 -1.5a2.6 2.6 0 1 0 -3 -4\"></path>\n </g>,\n tablerIconProps,\n);\n\nexport const HelpIconThin = createIcon(\n <g strokeWidth=\"1.25\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <circle cx=\"12\" cy=\"12\" r=\"9\"></circle>\n <line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"17.01\"></line>\n <path d=\"M12 13.5a1.5 1.5 0 0 1 1 -1.5a2.6 2.6 0 1 0 -3 -4\"></path>\n </g>,\n tablerIconProps,\n);\n\nexport const ExternalLinkIcon = createIcon(\n <path\n strokeWidth=\"1.25\"\n d=\"M9.167 5.833H5.833c-1.254 0-2.5 1.282-2.5 2.5v5.834c0 1.283 1.252 2.5 2.5 2.5h5.834c1.251 0 2.5-1.25 2.5-2.5v-3.334M8.333 11.667l8.334-8.334M12.5 3.333h4.167V7.5\"\n />,\n modifiedTablerIconProps,\n);\n\nexport const GithubIcon = createIcon(\n <path\n d=\"M7.5 15.833c-3.583 1.167-3.583-2.083-5-2.5m10 4.167v-2.917c0-.833.083-1.166-.417-1.666 2.334-.25 4.584-1.167 4.584-5a3.833 3.833 0 0 0-1.084-2.667 3.5 3.5 0 0 0-.083-2.667s-.917-.25-2.917 1.084a10.25 10.25 0 0 0-5.166 0C5.417 2.333 4.5 2.583 4.5 2.583a3.5 3.5 0 0 0-.083 2.667 3.833 3.833 0 0 0-1.084 2.667c0 3.833 2.25 4.75 4.584 5-.5.5-.5 1-.417 1.666V17.5\"\n strokeWidth=\"1.25\"\n />,\n modifiedTablerIconProps,\n);\n\nexport const DiscordIcon = createIcon(\n <g strokeWidth=\"1.25\">\n <path d=\"M7.5 10.833a.833.833 0 1 0 0-1.666.833.833 0 0 0 0 1.666ZM12.5 10.833a.833.833 0 1 0 0-1.666.833.833 0 0 0 0 1.666ZM6.25 6.25c2.917-.833 4.583-.833 7.5 0M5.833 13.75c2.917.833 5.417.833 8.334 0\" />\n <path d=\"M12.917 14.167c0 .833 1.25 2.5 1.666 2.5 1.25 0 2.361-1.39 2.917-2.5.556-1.39.417-4.861-1.25-9.584-1.214-.846-2.5-1.116-3.75-1.25l-.833 2.084M7.083 14.167c0 .833-1.13 2.5-1.526 2.5-1.191 0-2.249-1.39-2.778-2.5-.529-1.39-.397-4.861 1.19-9.584 1.157-.846 2.318-1.116 3.531-1.25l.833 2.084\" />\n </g>,\n modifiedTablerIconProps,\n);\n\nexport const XBrandIcon = createIcon(\n <g strokeWidth=\"1.25\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M4 4l11.733 16h4.267l-11.733 -16z\" />\n <path d=\"M4 20l6.768 -6.768m2.46 -2.46l6.772 -6.772\" />\n </g>,\n tablerIconProps,\n);\n\nexport const checkIcon = createIcon(\n <polyline fill=\"none\" stroke=\"currentColor\" points=\"20 6 9 17 4 12\" />,\n {\n width: 24,\n height: 24,\n },\n);\n\nexport const LinkIcon = createIcon(\n <g strokeWidth=\"1.25\">\n <path d=\"M8.333 11.667a2.917 2.917 0 0 0 4.167 0l3.333-3.334a2.946 2.946 0 1 0-4.166-4.166l-.417.416\" />\n <path d=\"M11.667 8.333a2.917 2.917 0 0 0-4.167 0l-3.333 3.334a2.946 2.946 0 0 0 4.166 4.166l.417-.416\" />\n </g>,\n modifiedTablerIconProps,\n);\n\nexport const save = createIcon(\n \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z\",\n { width: 448, height: 512 },\n);\n\nexport const saveAs = createIcon(\n \"M252 54L203 8a28 27 0 00-20-8H28C12 0 0 12 0 27v195c0 15 12 26 28 26h204c15 0 28-11 28-26V73a28 27 0 00-8-19zM130 213c-21 0-37-16-37-36 0-19 16-35 37-35 20 0 37 16 37 35 0 20-17 36-37 36zm56-169v56c0 4-4 6-7 6H44c-4 0-7-2-7-6V42c0-4 3-7 7-7h133l4 2 3 2a7 7 0 012 5z M296 201l87 95-188 205-78 9c-10 1-19-8-18-20l9-84zm141-14l-41-44a31 31 0 00-46 0l-38 41 87 95 38-42c13-14 13-36 0-50z\",\n { width: 448, height: 512 },\n);\n\n// tabler-icon: folder\nexport const LoadIcon = createIcon(\n <path\n d=\"m9.257 6.351.183.183H15.819c.34 0 .727.182 1.051.506.323.323.505.708.505 1.05v5.819c0 .316-.183.7-.52 1.035-.337.338-.723.522-1.037.522H4.182c-.352 0-.74-.181-1.058-.5-.318-.318-.499-.705-.499-1.057V5.182c0-.351.181-.736.5-1.054.32-.321.71-.503 1.057-.503H6.53l2.726 2.726Z\"\n strokeWidth=\"1.25\"\n />,\n modifiedTablerIconProps,\n);\n\nexport const clipboard = createIcon(\n \"M384 112v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h80c0-35.29 28.71-64 64-64s64 28.71 64 64h80c26.51 0 48 21.49 48 48zM192 40c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24m96 114v-20a6 6 0 0 0-6-6H102a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6h180a6 6 0 0 0 6-6z\",\n { width: 384, height: 512 },\n);\n\nexport const palette = createIcon(\n \"M204.3 5C104.9 24.4 24.8 104.3 5.2 203.4c-37 187 131.7 326.4 258.8 306.7 41.2-6.4 61.4-54.6 42.5-91.7-23.1-45.4 9.9-98.4 60.9-98.4h79.7c35.8 0 64.8-29.6 64.9-65.3C511.5 97.1 368.1-26.9 204.3 5zM96 320c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm32-128c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm128-64c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm128 64c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z\",\n);\n\nexport const bucketFillIcon = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M5 16l1.465 1.638a2 2 0 1 1 -3.015 .099l1.55 -1.737z\" />\n <path d=\"M13.737 9.737c2.299 -2.3 3.23 -5.095 2.081 -6.245c-1.15 -1.15 -3.945 -.217 -6.244 2.082c-2.3 2.299 -3.231 5.095 -2.082 6.244c1.15 1.15 3.946 .218 6.245 -2.081z\" />\n <path d=\"M7.492 11.818c.362 .362 .768 .676 1.208 .934l6.895 4.047c1.078 .557 2.255 -.075 3.692 -1.512c1.437 -1.437 2.07 -2.614 1.512 -3.692c-.372 -.718 -1.72 -3.017 -4.047 -6.895a6.015 6.015 0 0 0 -.934 -1.208\" />\n </g>,\n tablerIconProps,\n);\n\nexport const ExportImageIcon = createIcon(\n <g strokeWidth=\"1.25\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <path d=\"M15 8h.01\"></path>\n <path d=\"M12 20h-5a3 3 0 0 1 -3 -3v-10a3 3 0 0 1 3 -3h10a3 3 0 0 1 3 3v5\"></path>\n <path d=\"M4 15l4 -4c.928 -.893 2.072 -.893 3 0l4 4\"></path>\n <path d=\"M14 14l1 -1c.617 -.593 1.328 -.793 2.009 -.598\"></path>\n <path d=\"M19 16v6\"></path>\n <path d=\"M22 19l-3 3l-3 -3\"></path>\n </g>,\n tablerIconProps,\n);\n\nexport const exportToFileIcon = createIcon(\n \"M216 0h80c13.3 0 24 10.7 24 24v168h87.7c17.8 0 26.7 21.5 14.1 34.1L269.7 378.3c-7.5 7.5-19.8 7.5-27.3 0L90.1 226.1c-12.6-12.6-3.7-34.1 14.1-34.1H192V24c0-13.3 10.7-24 24-24zm296 376v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h146.7l49 49c20.1 20.1 52.5 20.1 72.6 0l49-49H488c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z\",\n { width: 512, height: 512 },\n);\n\nexport const zoomIn = createIcon(\n \"M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z\",\n { width: 448, height: 512 },\n);\n\nexport const zoomOut = createIcon(\n \"M416 208H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h384c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z\",\n { width: 448, height: 512 },\n);\n\nexport const done = createIcon(\n \"M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z\",\n);\n\nexport const menu = createIcon(\n \"M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z\",\n);\n\nexport const UndoIcon = createIcon(\n <path\n d=\"M7.5 10.833 4.167 7.5 7.5 4.167M4.167 7.5h9.166a3.333 3.333 0 0 1 0 6.667H12.5\"\n strokeWidth=\"1.25\"\n />,\n modifiedTablerIconProps,\n);\n\nexport const RedoIcon = createIcon(\n <path\n d=\"M12.5 10.833 15.833 7.5 12.5 4.167M15.833 7.5H6.667a3.333 3.333 0 1 0 0 6.667H7.5\"\n strokeWidth=\"1.25\"\n />,\n modifiedTablerIconProps,\n);\n\nexport const questionCircle = createIcon(\n \"M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zM262.655 90c-54.497 0-89.255 22.957-116.549 63.758-3.536 5.286-2.353 12.415 2.715 16.258l34.699 26.31c5.205 3.947 12.621 3.008 16.665-2.122 17.864-22.658 30.113-35.797 57.303-35.797 20.429 0 45.698 13.148 45.698 32.958 0 14.976-12.363 22.667-32.534 33.976C247.128 238.528 216 254.941 216 296v4c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12v-1.333c0-28.462 83.186-29.647 83.186-106.667 0-58.002-60.165-102-116.531-102zM256 338c-25.365 0-46 20.635-46 46 0 25.364 20.635 46 46 46s46-20.636 46-46c0-25.365-20.635-46-46-46z\",\n { mirror: true },\n);\n\nexport const share = createIcon(\n <path\n d=\"M5 12.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5ZM15 7.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5ZM15 17.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5ZM7.25 8.917l5.5-2.834M7.25 11.083l5.5 2.834\"\n strokeWidth=\"1.5\"\n />,\n modifiedTablerIconProps,\n);\n\nexport const warning = createIcon(\n \"M256 32c14.2 0 27.3 7.5 34.5 19.8l216 368c7.3 12.4 7.3 27.7 .2 40.1S486.3 480 472 480H40c-14.3 0-27.6-7.7-34.7-20.1s-7-27.8 .2-40.1l216-368C228.7 39.5 241.8 32 256 32zm0 128c-13.3 0-24 10.7-24 24V296c0 13.3 10.7 24 24 24s24-10.7 24-24V184c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z\",\n);\n\nexport const shareIOS = createIcon(\n \"M16 5l-1.42 1.42-1.59-1.59V16h-1.98V4.83L9.42 6.42 8 5l4-4 4 4zm4 5v11c0 1.1-.9 2-2 2H6c-1.11 0-2-.9-2-2V10c0-1.11.89-2 2-2h3v2H6v11h12V10h-3V8h3c1.1 0 2 .89 2 2z\",\n { width: 24, height: 24 },\n);\n\nexport const exportToPlus = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M8 9h-1a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-8a2 2 0 0 0 -2 -2h-1\" />\n <path d=\"M12 14v-11\" />\n <path d=\"M9 6l3 -3l3 3\" />\n </g>,\n tablerIconProps,\n);\n\nexport const shareWindows = createIcon(\n <>\n <path\n fill=\"currentColor\"\n d=\"M40 5.6v6.1l-4.1.7c-8.9 1.4-16.5 6.9-20.6 15C13 32 10.9 43 12.4 43c.4 0 2.4-1.3 4.4-3 5-3.9 12.1-7 18.2-7.7l5-.6v12.8l11.2-11.3L62.5 22 51.2 10.8 40-.5v6.1zm10.2 22.6L44 34.5v-6.8l-6.9.6c-3.9.3-9.8 1.7-13.2 3.1-3.5 1.4-6.5 2.4-6.7 2.2-.9-1 3-7.5 6.4-10.8C28 18.6 34.4 16 40.1 16c3.7 0 3.9-.1 3.9-3.2V9.5l6.2 6.3 6.3 6.2-6.3 6.2z\"\n />\n <path\n stroke=\"currentColor\"\n fill=\"currentColor\"\n d=\"M0 36v20h48v-6.2c0-6 0-6.1-2-4.3-1.1 1-2 2.9-2 4.2V52H4V34c0-17.3-.1-18-2-18s-2 .7-2 20z\"\n />\n </>,\n { width: 64, height: 64 },\n);\n\n// Icon imported form Storybook\n// Storybook is licensed under MIT https://github.com/storybookjs/storybook/blob/next/LICENSE\nexport const resetZoom = createIcon(\n <path\n stroke=\"currentColor\"\n strokeWidth=\"40\"\n fill=\"currentColor\"\n d=\"M148 560a318 318 0 0 0 522 110 316 316 0 0 0 0-450 316 316 0 0 0-450 0c-11 11-21 22-30 34v4h47c25 0 46 21 46 46s-21 45-46 45H90c-13 0-25-6-33-14-9-9-14-20-14-33V156c0-25 20-45 45-45s45 20 45 45v32l1 1a401 401 0 0 1 623 509l212 212a42 42 0 0 1-59 59L698 757A401 401 0 0 1 65 570a42 42 0 0 1 83-10z\"\n />,\n { width: 1024 },\n);\n\nconst arrowBarToTopJSX = (\n <g strokeWidth={1.5}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M12 10l0 10\" />\n <path d=\"M12 10l4 4\" />\n <path d=\"M12 10l-4 4\" />\n <path d=\"M4 4l16 0\" />\n </g>\n);\n\nconst arrownNarrowUpJSX = (\n <g strokeWidth={1.5}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M12 5l0 14\" />\n <path d=\"M16 9l-4 -4\" />\n <path d=\"M8 9l4 -4\" />\n </g>\n);\n\nexport const BringForwardIcon = createIcon(arrownNarrowUpJSX, tablerIconProps);\n\nexport const SendBackwardIcon = createIcon(arrownNarrowUpJSX, {\n ...tablerIconProps,\n style: {\n transform: \"rotate(180deg)\",\n },\n});\n\nexport const BringToFrontIcon = createIcon(arrowBarToTopJSX, tablerIconProps);\n\nexport const SendToBackIcon = createIcon(arrowBarToTopJSX, {\n ...tablerIconProps,\n style: {\n transform: \"rotate(180deg)\",\n },\n});\n\n//\n// Align action icons created from scratch to match those of z-index actions\n// Note: vertical align icons are flipped so the larger item is always the\n// first one the user sees. Horizontal align icons should not be flipped since\n// that would make them lie about their function.\n//\nexport const AlignTopIcon = createIcon(\n <>\n <g clipPath=\"url(#a)\" stroke=\"currentColor\" strokeWidth=\"1.25\">\n <path\n d=\"M3.333 3.333h13.334\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path d=\"M13.542 6.458h-.417c-.92 0-1.667.747-1.667 1.667v7.083c0 .92.746 1.667 1.667 1.667h.417c.92 0 1.666-.746 1.666-1.667V8.125c0-.92-.746-1.667-1.666-1.667ZM6.875 6.458h-.417c-.92 0-1.666.747-1.666 1.667v3.75c0 .92.746 1.667 1.666 1.667h.417c.92 0 1.667-.746 1.667-1.667v-3.75c0-.92-.747-1.667-1.667-1.667Z\" />\n </g>\n <defs>\n <clipPath id=\"a\">\n <path fill=\"#fff\" d=\"M0 0h20v20H0z\" />\n </clipPath>\n </defs>\n </>,\n modifiedTablerIconProps,\n);\n\nexport const AlignBottomIcon = createIcon(\n <>\n <g clipPath=\"url(#a)\" stroke=\"currentColor\" strokeWidth=\"1.25\">\n <path\n d=\"M3.333 16.667h13.334\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path d=\"M6.875 3.125h-.417c-.92 0-1.666.746-1.666 1.667v7.083c0 .92.746 1.667 1.666 1.667h.417c.92 0 1.667-.746 1.667-1.667V4.792c0-.92-.747-1.667-1.667-1.667ZM13.542 5.817h-.417c-.92 0-1.667.747-1.667 1.667v4.391c0 .92.746 1.667 1.667 1.667h.417c.92 0 1.666-.746 1.666-1.667V7.484c0-.92-.746-1.667-1.666-1.667Z\" />\n </g>\n <defs>\n <clipPath id=\"a\">\n <path fill=\"#fff\" d=\"M0 0h20v20H0z\" />\n </clipPath>\n </defs>\n </>,\n modifiedTablerIconProps,\n);\n\nexport const AlignLeftIcon = createIcon(\n <>\n <g clipPath=\"url(#a)\" stroke=\"currentColor\" strokeWidth=\"1.25\">\n <path\n d=\"M3.333 3.333v13.334\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path d=\"M15.208 4.792H8.125c-.92 0-1.667.746-1.667 1.666v.417c0 .92.747 1.667 1.667 1.667h7.083c.92 0 1.667-.747 1.667-1.667v-.417c0-.92-.746-1.666-1.667-1.666ZM12.516 11.458H8.125c-.92 0-1.667.746-1.667 1.667v.417c0 .92.747 1.666 1.667 1.666h4.391c.92 0 1.667-.746 1.667-1.666v-.417c0-.92-.746-1.667-1.667-1.667Z\" />\n </g>\n <defs>\n <clipPath id=\"a\">\n <path fill=\"#fff\" d=\"M0 0h20v20H0z\" />\n </clipPath>\n </defs>\n </>,\n modifiedTablerIconProps,\n);\n\nexport const AlignRightIcon = createIcon(\n <>\n <g clipPath=\"url(#a)\" stroke=\"currentColor\" strokeWidth=\"1.25\">\n <path\n d=\"M16.667 3.333v13.334\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path d=\"M11.875 4.792H4.792c-.92 0-1.667.746-1.667 1.666v.417c0 .92.746 1.667 1.667 1.667h7.083c.92 0 1.667-.747 1.667-1.667v-.417c0-.92-.746-1.666-1.667-1.666ZM11.683 11.458H7.292c-.92 0-1.667.746-1.667 1.667v.417c0 .92.746 1.666 1.667 1.666h4.39c.921 0 1.667-.746 1.667-1.666v-.417c0-.92-.746-1.667-1.666-1.667Z\" />\n </g>\n <defs>\n <clipPath id=\"a\">\n <path fill=\"#fff\" d=\"M0 0h20v20H0z\" />\n </clipPath>\n </defs>\n </>,\n modifiedTablerIconProps,\n);\n\nexport const DistributeHorizontallyIcon = createIcon(\n <>\n <g clipPath=\"url(#a)\" stroke=\"currentColor\" strokeWidth=\"1.25\">\n <path\n d=\"M16.667 3.333v13.334M3.333 3.333v13.334\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path d=\"M14.375 10.208v-.416c0-.92-.746-1.667-1.667-1.667H7.292c-.92 0-1.667.746-1.667 1.667v.416c0 .92.746 1.667 1.667 1.667h5.416c.92 0 1.667-.746 1.667-1.667Z\" />\n </g>\n <defs>\n <clipPath id=\"a\">\n <path fill=\"#fff\" d=\"M0 0h20v20H0z\" />\n </clipPath>\n </defs>\n </>,\n modifiedTablerIconProps,\n);\n\nexport const DistributeVerticallyIcon = createIcon(\n <>\n <g clipPath=\"url(#a)\" stroke=\"currentColor\" strokeWidth=\"1.25\">\n <path\n d=\"M3.333 3.333h13.334M3.333 16.667h13.334\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path d=\"M10.208 5.625h-.416c-.92 0-1.667.746-1.667 1.667v5.416c0 .92.746 1.667 1.667 1.667h.416c.92 0 1.667-.746 1.667-1.667V7.292c0-.92-.746-1.667-1.667-1.667Z\" />\n </g>\n <defs>\n <clipPath id=\"a\">\n <path fill=\"#fff\" d=\"M0 0h20v20H0z\" />\n </clipPath>\n </defs>\n </>,\n modifiedTablerIconProps,\n);\n\nexport const CenterVerticallyIcon = createIcon(\n <g stroke=\"currentColor\" strokeWidth=\"1.25\">\n <path d=\"M1.667 10h2.916\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M8.333 10h3.334\" strokeLinejoin=\"round\" />\n <path d=\"M15.417 10h2.916\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M6.875 4.792h-.417c-.92 0-1.666.746-1.666 1.666v7.084c0 .92.746 1.666 1.666 1.666h.417c.92 0 1.667-.746 1.667-1.666V6.458c0-.92-.747-1.666-1.667-1.666ZM13.542 6.458h-.417c-.92 0-1.667.747-1.667 1.667v3.75c0 .92.746 1.667 1.667 1.667h.417c.92 0 1.666-.746 1.666-1.667v-3.75c0-.92-.746-1.667-1.666-1.667Z\" />\n </g>,\n modifiedTablerIconProps,\n);\n\nexport const CenterHorizontallyIcon = createIcon(\n <g stroke=\"currentColor\" strokeWidth=\"1.25\">\n <path d=\"M10 18.333v-2.916\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M10 11.667V8.333\" strokeLinejoin=\"round\" />\n <path d=\"M10 4.583V1.667\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M4.792 13.125v.417c0 .92.746 1.666 1.666 1.666h7.084c.92 0 1.666-.746 1.666-1.666v-.417c0-.92-.746-1.667-1.666-1.667H6.458c-.92 0-1.666.746-1.666 1.667ZM6.458 6.458v.417c0 .92.747 1.667 1.667 1.667h3.75c.92 0 1.667-.747 1.667-1.667v-.417c0-.92-.746-1.666-1.667-1.666h-3.75c-.92 0-1.667.746-1.667 1.666Z\" />\n </g>,\n modifiedTablerIconProps,\n);\n\nexport const usersIcon = createIcon(\n <g strokeWidth=\"1.5\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <circle cx=\"9\" cy=\"7\" r=\"4\"></circle>\n <path d=\"M3 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2\"></path>\n <path d=\"M16 3.13a4 4 0 0 1 0 7.75\"></path>\n <path d=\"M21 21v-2a4 4 0 0 0 -3 -3.85\"></path>\n </g>,\n tablerIconProps,\n);\n\n// not mirrored because it's inspired by a playback control, which is always RTL\nexport const start = createIcon(\n \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm115.7 272l-176 101c-15.8 8.8-35.7-2.5-35.7-21V152c0-18.4 19.8-29.8 35.7-21l176 107c16.4 9.2 16.4 32.9 0 42z\",\n);\n\nexport const stop = createIcon(\n \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm96 328c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h160c8.8 0 16 7.2 16 16v160z\",\n);\n\nexport const CloseIcon = createIcon(\n <>\n <g\n clipPath=\"url(#a)\"\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M15 5 5 15M5 5l10 10\" />\n </g>\n <defs>\n <clipPath id=\"a\">\n <path fill=\"#fff\" d=\"M0 0h20v20H0z\" />\n </clipPath>\n </defs>\n </>,\n modifiedTablerIconProps,\n);\n\nexport const clone = createIcon(\n \"M464 0c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48H176c-26.51 0-48-21.49-48-48V48c0-26.51 21.49-48 48-48h288M176 416c-44.112 0-80-35.888-80-80V128H48c-26.51 0-48 21.49-48 48v288c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-48H176z\",\n { mirror: true },\n);\n\n// modified https://feathericons.com/?query=shield\nexport const shield = createIcon(\n \"M11.553 22.894a.998.998 0 00.894 0s3.037-1.516 5.465-4.097C19.616 16.987 21 14.663 21 12V5a1 1 0 00-.649-.936l-8-3a.998.998 0 00-.702 0l-8 3A1 1 0 003 5v7c0 2.663 1.384 4.987 3.088 6.797 2.428 2.581 5.465 4.097 5.465 4.097zm-1.303-8.481l6.644-6.644a.856.856 0 111.212 1.212l-7.25 7.25a.856.856 0 01-1.212 0l-3.75-3.75a.856.856 0 111.212-1.212l3.144 3.144z\",\n { width: 24 },\n);\n\nexport const file = createIcon(\n \"M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm32-48h224V288l-23.5-23.5c-4.7-4.7-12.3-4.7-17 0L176 352l-39.5-39.5c-4.7-4.7-12.3-4.7-17 0L80 352v64zm48-240c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48z\",\n { width: 384, height: 512 },\n);\n\n// TODO barnabasmolnar/editor-redesign\n// couldn't find a new icon for this\nexport const GroupIcon = React.memo(({ theme }: { theme: Theme }) =>\n createIcon(\n <>\n <path d=\"M25 26H111V111H25\" fill={iconFillColor(theme)} />\n <path\n d=\"M25 111C25 80.2068 25 49.4135 25 26M25 26C48.6174 26 72.2348 26 111 26H25ZM25 26C53.3671 26 81.7343 26 111 26H25ZM111 26C111 52.303 111 78.606 111 111V26ZM111 26C111 51.2947 111 76.5893 111 111V26ZM111 111C87.0792 111 63.1585 111 25 111H111ZM111 111C87.4646 111 63.9293 111 25 111H111ZM25 111C25 81.1514 25 51.3028 25 26V111Z\"\n stroke={iconFillColor(theme)}\n strokeWidth=\"2\"\n />\n <path d=\"M100 100H160V160H100\" fill={iconFillColor(theme)} />\n <path\n d=\"M100 160C100 144.106 100 128.211 100 100M100 100C117.706 100 135.412 100 160 100H100ZM100 100C114.214 100 128.428 100 160 100H100ZM160 100C160 120.184 160 140.369 160 160V100ZM160 100C160 113.219 160 126.437 160 160V100ZM160 160C145.534 160 131.068 160 100 160H160ZM160 160C143.467 160 126.934 160 100 160H160ZM100 160C100 143.661 100 127.321 100 100V160Z\"\n stroke={iconFillColor(theme)}\n strokeWidth=\"2\"\n />\n <g\n fill={handlerColor(theme)}\n stroke={iconFillColor(theme)}\n strokeWidth=\"6\"\n >\n <rect x=\"2.5\" y=\"2.5\" width=\"30\" height=\"30\" />\n <rect x=\"2.5\" y=\"149.5\" width=\"30\" height=\"30\" />\n <rect x=\"147.5\" y=\"149.5\" width=\"30\" height=\"30\" />\n <rect x=\"147.5\" y=\"2.5\" width=\"30\" height=\"30\" />\n </g>\n </>,\n { width: 182, height: 182, mirror: true },\n ),\n);\n\nexport const UngroupIcon = React.memo(({ theme }: { theme: Theme }) =>\n createIcon(\n <>\n <path d=\"M25 26H111V111H25\" fill={iconFillColor(theme)} />\n <path\n d=\"M25 111C25 80.2068 25 49.4135 25 26M25 26C48.6174 26 72.2348 26 111 26H25ZM25 26C53.3671 26 81.7343 26 111 26H25ZM111 26C111 52.303 111 78.606 111 111V26ZM111 26C111 51.2947 111 76.5893 111 111V26ZM111 111C87.0792 111 63.1585 111 25 111H111ZM111 111C87.4646 111 63.9293 111 25 111H111ZM25 111C25 81.1514 25 51.3028 25 26V111Z\"\n stroke={iconFillColor(theme)}\n strokeWidth=\"2\"\n />\n <path d=\"M100 100H160V160H100\" fill={iconFillColor(theme)} />\n <path\n d=\"M100 160C100 144.106 100 128.211 100 100M100 100C117.706 100 135.412 100 160 100H100ZM100 100C114.214 100 128.428 100 160 100H100ZM160 100C160 120.184 160 140.369 160 160V100ZM160 100C160 113.219 160 126.437 160 160V100ZM160 160C145.534 160 131.068 160 100 160H160ZM160 160C143.467 160 126.934 160 100 160H160ZM100 160C100 143.661 100 127.321 100 100V160Z\"\n stroke={iconFillColor(theme)}\n strokeWidth=\"2\"\n />\n <g\n fill={handlerColor(theme)}\n stroke={iconFillColor(theme)}\n strokeWidth=\"6\"\n >\n <rect x=\"2.5\" y=\"2.5\" width=\"30\" height=\"30\" />\n <rect x=\"78.5\" y=\"149.5\" width=\"30\" height=\"30\" />\n <rect x=\"147.5\" y=\"149.5\" width=\"30\" height=\"30\" />\n <rect x=\"147.5\" y=\"78.5\" width=\"30\" height=\"30\" />\n <rect x=\"105.5\" y=\"2.5\" width=\"30\" height=\"30\" />\n <rect x=\"2.5\" y=\"102.5\" width=\"30\" height=\"30\" />\n </g>\n </>,\n { width: 182, height: 182, mirror: true },\n ),\n);\n\nexport const FillZigZagIcon = createIcon(\n <g strokeWidth={1.25}>\n <path d=\"M5.879 2.625h8.242a3.27 3.27 0 0 1 3.254 3.254v8.242a3.27 3.27 0 0 1-3.254 3.254H5.88a3.27 3.27 0 0 1-3.254-3.254V5.88A3.27 3.27 0 0 1 5.88 2.626l-.001-.001ZM4.518 16.118l7.608-12.83m.198 13.934 5.051-9.897M2.778 9.675l9.348-6.387m-7.608 12.83 12.857-8.793\" />\n </g>,\n modifiedTablerIconProps,\n);\n\nexport const FillHachureIcon = createIcon(\n <>\n <path\n d=\"M5.879 2.625h8.242a3.254 3.254 0 0 1 3.254 3.254v8.242a3.254 3.254 0 0 1-3.254 3.254H5.88a3.254 3.254 0 0 1-3.254-3.254V5.88a3.254 3.254 0 0 1 3.254-3.254Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n />\n <mask\n id=\"FillHachureIcon\"\n style={{ maskType: \"alpha\" }}\n maskUnits=\"userSpaceOnUse\"\n x={2}\n y={2}\n width={16}\n height={16}\n >\n <path\n d=\"M5.879 2.625h8.242a3.254 3.254 0 0 1 3.254 3.254v8.242a3.254 3.254 0 0 1-3.254 3.254H5.88a3.254 3.254 0 0 1-3.254-3.254V5.88a3.254 3.254 0 0 1 3.254-3.254Z\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n />\n </mask>\n <g mask=\"url(#FillHachureIcon)\">\n <path\n d=\"M2.258 15.156 15.156 2.258M7.324 20.222 20.222 7.325m-20.444 5.35L12.675-.222m-8.157 18.34L17.416 5.22\"\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </g>\n </>,\n modifiedTablerIconProps,\n);\n\nexport const FillCrossHatchIcon = createIcon(\n <>\n <g clipPath=\"url(#a)\">\n <path\n d=\"M5.879 2.625h8.242a3.254 3.254 0 0 1 3.254 3.254v8.242a3.254 3.254 0 0 1-3.254 3.254H5.88a3.254 3.254 0 0 1-3.254-3.254V5.88a3.254 3.254 0 0 1 3.254-3.254Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n />\n <mask\n id=\"FillCrossHatchIcon\"\n style={{ maskType: \"alpha\" }}\n maskUnits=\"userSpaceOnUse\"\n x={-1}\n y={-1}\n width={22}\n height={22}\n >\n <path\n d=\"M2.426 15.044 15.044 2.426M7.383 20 20 7.383M0 12.617 12.617 0m-7.98 17.941L17.256 5.324m-2.211 12.25L2.426 4.956M20 12.617 7.383 0m5.234 20L0 7.383m17.941 7.98L5.324 2.745\"\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </mask>\n <g mask=\"url(#FillCrossHatchIcon)\">\n <path\n d=\"M14.121 2H5.88A3.879 3.879 0 0 0 2 5.879v8.242A3.879 3.879 0 0 0 5.879 18h8.242A3.879 3.879 0 0 0 18 14.121V5.88A3.879 3.879 0 0 0 14.121 2Z\"\n fill=\"currentColor\"\n />\n </g>\n </g>\n <defs>\n <clipPath id=\"a\">\n <path fill=\"#fff\" d=\"M0 0h20v20H0z\" />\n </clipPath>\n </defs>\n </>,\n modifiedTablerIconProps,\n);\n\nexport const FillSolidIcon = createIcon(\n <>\n <g clipPath=\"url(#a)\">\n <path\n d=\"M4.91 2.625h10.18a2.284 2.284 0 0 1 2.285 2.284v10.182a2.284 2.284 0 0 1-2.284 2.284H4.909a2.284 2.284 0 0 1-2.284-2.284V4.909a2.284 2.284 0 0 1 2.284-2.284Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n />\n </g>\n <defs>\n <clipPath id=\"a\">\n <path fill=\"#fff\" d=\"M0 0h20v20H0z\" />\n </clipPath>\n </defs>\n </>,\n { ...modifiedTablerIconProps, fill: \"currentColor\" },\n);\n\nexport const StrokeWidthBaseIcon = createIcon(\n <>\n <path\n d=\"M4.167 10h11.666\"\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </>,\n modifiedTablerIconProps,\n);\n\nexport const StrokeWidthBoldIcon = createIcon(\n <path\n d=\"M5 10h10\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />,\n modifiedTablerIconProps,\n);\n\nexport const StrokeWidthExtraBoldIcon = createIcon(\n <path\n d=\"M5 10h10\"\n stroke=\"currentColor\"\n strokeWidth=\"3.75\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />,\n modifiedTablerIconProps,\n);\n\nexport const StrokeStyleSolidIcon = React.memo(({ theme }: { theme: Theme }) =>\n createIcon(\n <path\n d=\"M6 10H34\"\n stroke={iconFillColor(theme)}\n strokeWidth={2}\n fill=\"none\"\n strokeLinecap=\"round\"\n />,\n {\n width: 40,\n height: 20,\n },\n ),\n);\n\nexport const StrokeStyleDashedIcon = createIcon(\n <g strokeWidth=\"2\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M5 12h2\" />\n <path d=\"M17 12h2\" />\n <path d=\"M11 12h2\" />\n </g>,\n tablerIconProps,\n);\n\n// tabler-icons: line-dotted\nexport const StrokeStyleDottedIcon = createIcon(\n <g strokeWidth=\"2\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M4 12v.01\" />\n <path d=\"M8 12v.01\" />\n <path d=\"M12 12v.01\" />\n <path d=\"M16 12v.01\" />\n <path d=\"M20 12v.01\" />\n </g>,\n tablerIconProps,\n);\n\nexport const SloppinessArchitectIcon = createIcon(\n <path\n d=\"M2.5 12.038c1.655-.885 5.9-3.292 8.568-4.354 2.668-1.063.101 2.821 1.32 3.104 1.218.283 5.112-1.814 5.112-1.814\"\n strokeWidth=\"1.25\"\n />,\n modifiedTablerIconProps,\n);\n\nexport const SloppinessArtistIcon = createIcon(\n <path\n d=\"M2.5 12.563c1.655-.886 5.9-3.293 8.568-4.355 2.668-1.062.101 2.822 1.32 3.105 1.218.283 5.112-1.814 5.112-1.814m-13.469 2.23c2.963-1.586 6.13-5.62 7.468-4.998 1.338.623-1.153 4.11-.132 5.595 1.02 1.487 6.133-1.43 6.133-1.43\"\n strokeWidth=\"1.25\"\n />,\n modifiedTablerIconProps,\n);\n\nexport const SloppinessCartoonistIcon = createIcon(\n <path\n d=\"M2.5 11.936c1.737-.879 8.627-5.346 10.42-5.268 1.795.078-.418 5.138.345 5.736.763.598 3.53-1.789 4.235-2.147M2.929 9.788c1.164-.519 5.47-3.28 6.987-3.114 1.519.165 1 3.827 2.121 4.109 1.122.281 3.839-2.016 4.606-2.42\"\n strokeWidth=\"1.25\"\n />,\n modifiedTablerIconProps,\n);\n\nexport const EdgeSharpIcon = createIcon(\n <svg strokeWidth=\"1.5\">\n <path d=\"M3.33334 9.99998V6.66665C3.33334 6.04326 3.33403 4.9332 3.33539 3.33646C4.95233 3.33436 6.06276 3.33331 6.66668 3.33331H10\" />\n <path d=\"M13.3333 3.33331V3.34331\" />\n <path d=\"M16.6667 3.33331V3.34331\" />\n <path d=\"M16.6667 6.66669V6.67669\" />\n <path d=\"M16.6667 10V10.01\" />\n <path d=\"M3.33334 13.3333V13.3433\" />\n <path d=\"M16.6667 13.3333V13.3433\" />\n <path d=\"M3.33334 16.6667V16.6767\" />\n <path d=\"M6.66666 16.6667V16.6767\" />\n <path d=\"M10 16.6667V16.6767\" />\n <path d=\"M13.3333 16.6667V16.6767\" />\n <path d=\"M16.6667 16.6667V16.6767\" />\n </svg>,\n modifiedTablerIconProps,\n);\n\n// tabler-icons: border-radius\nexport const EdgeRoundIcon = createIcon(\n <g\n strokeWidth=\"1.5\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M4 12v-4a4 4 0 0 1 4 -4h4\" />\n <line x1=\"16\" y1=\"4\" x2=\"16\" y2=\"4.01\" />\n <line x1=\"20\" y1=\"4\" x2=\"20\" y2=\"4.01\" />\n <line x1=\"20\" y1=\"8\" x2=\"20\" y2=\"8.01\" />\n <line x1=\"20\" y1=\"12\" x2=\"20\" y2=\"12.01\" />\n <line x1=\"4\" y1=\"16\" x2=\"4\" y2=\"16.01\" />\n <line x1=\"20\" y1=\"16\" x2=\"20\" y2=\"16.01\" />\n <line x1=\"4\" y1=\"20\" x2=\"4\" y2=\"20.01\" />\n <line x1=\"8\" y1=\"20\" x2=\"8\" y2=\"20.01\" />\n <line x1=\"12\" y1=\"20\" x2=\"12\" y2=\"20.01\" />\n <line x1=\"16\" y1=\"20\" x2=\"16\" y2=\"20.01\" />\n <line x1=\"20\" y1=\"20\" x2=\"20\" y2=\"20.01\" />\n </g>,\n tablerIconProps,\n);\n\nexport const ArrowheadNoneIcon = createIcon(\n <g stroke=\"currentColor\" opacity={0.3} strokeWidth={2}>\n <path d=\"M12 12l9 0\" />\n <path d=\"M3 9l6 6\" />\n <path d=\"M3 15l6 -6\" />\n </g>,\n tablerIconProps,\n);\n\nexport const ArrowheadArrowIcon = React.memo(\n ({ flip = false }: { flip?: boolean }) =>\n createIcon(\n <g\n transform={flip ? \"translate(40, 0) scale(-1, 1)\" : \"\"}\n stroke=\"currentColor\"\n strokeWidth={2}\n fill=\"none\"\n >\n <path d=\"M34 10H6M34 10L27 5M34 10L27 15\" />\n <path d=\"M27.5 5L34.5 10L27.5 15\" />\n </g>,\n { width: 40, height: 20 },\n ),\n);\n\nexport const ArrowheadCircleIcon = React.memo(\n ({ flip = false }: { flip?: boolean }) =>\n createIcon(\n <g\n stroke=\"currentColor\"\n fill=\"currentColor\"\n transform={flip ? \"translate(40, 0) scale(-1, 1)\" : \"\"}\n >\n <path d=\"M32 10L6 10\" strokeWidth={2} />\n <circle r=\"4\" transform=\"matrix(-1 0 0 1 30 10)\" />\n </g>,\n { width: 40, height: 20 },\n ),\n);\n\nexport const ArrowheadCircleOutlineIcon = React.memo(\n ({ flip = false }: { flip?: boolean }) =>\n createIcon(\n <g\n stroke=\"currentColor\"\n fill=\"none\"\n transform={flip ? \"translate(40, 0) scale(-1, 1)\" : \"\"}\n strokeWidth={2}\n >\n <path d=\"M26 10L6 10\" />\n <circle r=\"4\" transform=\"matrix(-1 0 0 1 30 10)\" />\n </g>,\n { width: 40, height: 20 },\n ),\n);\n\nexport const ArrowheadBarIcon = React.memo(\n ({ flip = false }: { flip?: boolean }) =>\n createIcon(\n <g transform={flip ? \"translate(40, 0) scale(-1, 1)\" : \"\"}>\n <path\n d=\"M34 10H5.99996M34 10L34 5M34 10L34 15\"\n stroke=\"currentColor\"\n strokeWidth={2}\n fill=\"none\"\n />\n </g>,\n { width: 40, height: 20 },\n ),\n);\n\nexport const ArrowheadTriangleIcon = React.memo(\n ({ flip = false }: { flip?: boolean }) =>\n createIcon(\n <g\n stroke=\"currentColor\"\n fill=\"currentColor\"\n transform={flip ? \"translate(40, 0) scale(-1, 1)\" : \"\"}\n >\n <path d=\"M32 10L6 10\" strokeWidth={2} />\n <path d=\"M27.5 5.5L34.5 10L27.5 14.5L27.5 5.5\" />\n </g>,\n { width: 40, height: 20 },\n ),\n);\n\nexport const ArrowheadTriangleOutlineIcon = React.memo(\n ({ flip = false }: { flip?: boolean }) =>\n createIcon(\n <g\n stroke=\"currentColor\"\n fill=\"none\"\n transform={flip ? \"translate(40, 0) scale(-1, 1)\" : \"\"}\n strokeWidth={2}\n strokeLinejoin=\"round\"\n >\n <path d=\"M6,9.5H27\" />\n <path d=\"M27,5L34,10L27,14Z\" fill=\"none\" />\n </g>,\n\n { width: 40, height: 20 },\n ),\n);\n\nexport const ArrowheadDiamondIcon = React.memo(\n ({ flip = false }: { flip?: boolean }) =>\n createIcon(\n <g\n stroke=\"currentColor\"\n fill=\"currentColor\"\n transform={flip ? \"translate(40, 0) scale(-1, 1)\" : \"\"}\n strokeLinejoin=\"round\"\n strokeWidth={2}\n >\n <path d=\"M6,9.5H20\" />\n <path d=\"M27,5L34,10L27,14L20,9.5Z\" />\n </g>,\n { width: 40, height: 20 },\n ),\n);\n\nexport const ArrowheadDiamondOutlineIcon = React.memo(\n ({ flip = false }: { flip?: boolean }) =>\n createIcon(\n <g\n stroke=\"currentColor\"\n fill=\"none\"\n transform={flip ? \"translate(40, 0) scale(-1, 1)\" : \"\"}\n strokeLinejoin=\"round\"\n strokeWidth={2}\n >\n <path d=\"M6,9.5H20\" />\n <path d=\"M27,5L34,10L27,14L20,9.5Z\" />\n </g>,\n { width: 40, height: 20 },\n ),\n);\n\nexport const ArrowheadCrowfootIcon = React.memo(\n ({ flip = false }: { flip?: boolean }) =>\n createIcon(\n <g\n stroke=\"currentColor\"\n fill=\"none\"\n transform={flip ? \"\" : \"translate(40, 0) scale(-1, 1)\"}\n strokeLinejoin=\"round\"\n strokeWidth={2}\n >\n <path d=\"M34,10 H6 M15,10 L7,5 M15,10 L7,15\" />\n </g>,\n { width: 40, height: 20 },\n ),\n);\n\nexport const ArrowheadCrowfootOneIcon = React.memo(\n ({ flip = false }: { flip?: boolean }) =>\n createIcon(\n <g\n stroke=\"currentColor\"\n fill=\"none\"\n transform={flip ? \"\" : \"translate(40, 0) scale(-1, 1)\"}\n strokeLinejoin=\"round\"\n strokeWidth={2}\n >\n <path d=\"M34,10 H6 M15,10 L15,15 L15,5\" />\n </g>,\n { width: 40, height: 20 },\n ),\n);\n\nexport const ArrowheadCrowfootOneOrManyIcon = React.memo(\n ({ flip = false }: { flip?: boolean }) =>\n createIcon(\n <g\n stroke=\"currentColor\"\n fill=\"none\"\n transform={flip ? \"\" : \"translate(40, 0) scale(-1, 1)\"}\n strokeLinejoin=\"round\"\n strokeWidth={2}\n >\n <path d=\"M34,10 H6 M15,10 L15,16 L15,4 M15,10 L7,5 M15,10 L7,15\" />\n </g>,\n { width: 40, height: 20 },\n ),\n);\n\nexport const FontSizeSmallIcon = createIcon(\n <>\n <g clipPath=\"url(#a)\">\n <path\n d=\"M14.167 6.667a3.333 3.333 0 0 0-3.334-3.334H9.167a3.333 3.333 0 0 0 0 6.667h1.666a3.333 3.333 0 0 1 0 6.667H9.167a3.333 3.333 0 0 1-3.334-3.334\"\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </g>\n <defs>\n <clipPath id=\"a\">\n <path fill=\"#fff\" d=\"M0 0h20v20H0z\" />\n </clipPath>\n </defs>\n </>,\n modifiedTablerIconProps,\n);\n\nexport const FontSizeMediumIcon = createIcon(\n <>\n <g clipPath=\"url(#a)\">\n <path\n d=\"M5 16.667V3.333L10 15l5-11.667v13.334\"\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </g>\n <defs>\n <clipPath id=\"a\">\n <path fill=\"#fff\" d=\"M0 0h20v20H0z\" />\n </clipPath>\n </defs>\n </>,\n modifiedTablerIconProps,\n);\n\nexport const FontSizeLargeIcon = createIcon(\n <>\n <g clipPath=\"url(#a)\">\n <path\n d=\"M5.833 3.333v13.334h8.334\"\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </g>\n <defs>\n <clipPath id=\"a\">\n <path fill=\"#fff\" d=\"M0 0h20v20H0z\" />\n </clipPath>\n </defs>\n </>,\n modifiedTablerIconProps,\n);\n\nexport const FontSizeExtraLargeIcon = createIcon(\n <>\n <path\n d=\"m1.667 3.333 6.666 13.334M8.333 3.333 1.667 16.667M11.667 3.333v13.334h6.666\"\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </>,\n modifiedTablerIconProps,\n);\n\nexport const fontSizeIcon = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M3 7v-2h13v2\" />\n <path d=\"M10 5v14\" />\n <path d=\"M12 19h-4\" />\n <path d=\"M15 13v-1h6v1\" />\n <path d=\"M18 12v7\" />\n <path d=\"M17 19h2\" />\n </g>,\n tablerIconProps,\n);\n\nexport const FontFamilyHeadingIcon = createIcon(\n <>\n <g\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M7 12h10\" />\n <path d=\"M7 5v14\" />\n <path d=\"M17 5v14\" />\n <path d=\"M15 19h4\" />\n <path d=\"M15 5h4\" />\n <path d=\"M5 19h4\" />\n <path d=\"M5 5h4\" />\n </g>\n </>,\n tablerIconProps,\n);\n\nexport const FontFamilyNormalIcon = createIcon(\n <>\n <g\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M5.833 16.667v-10a3.333 3.333 0 0 1 3.334-3.334h1.666a3.333 3.333 0 0 1 3.334 3.334v10M5.833 10.833h8.334\" />\n </g>\n </>,\n modifiedTablerIconProps,\n);\n\nexport const FontFamilyCodeIcon = createIcon(\n <>\n <g\n clipPath=\"url(#a)\"\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M5.833 6.667 2.5 10l3.333 3.333M14.167 6.667 17.5 10l-3.333 3.333M11.667 3.333 8.333 16.667\" />\n </g>\n <defs>\n <clipPath id=\"a\">\n <path fill=\"#fff\" d=\"M0 0h20v20H0z\" />\n </clipPath>\n </defs>\n </>,\n modifiedTablerIconProps,\n);\n\nexport const TextAlignLeftIcon = createIcon(\n <g\n stroke=\"currentColor\"\n fill=\"none\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <line x1=\"4\" y1=\"8\" x2=\"20\" y2=\"8\" />\n <line x1=\"4\" y1=\"12\" x2=\"12\" y2=\"12\" />\n <line x1=\"4\" y1=\"16\" x2=\"16\" y2=\"16\" />\n </g>,\n tablerIconProps,\n);\n\nexport const TextAlignCenterIcon = createIcon(\n <g\n stroke=\"currentColor\"\n fill=\"none\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <line x1=\"4\" y1=\"8\" x2=\"20\" y2=\"8\" />\n <line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\" />\n <line x1=\"6\" y1=\"16\" x2=\"18\" y2=\"16\" />\n </g>,\n tablerIconProps,\n);\n\nexport const TextAlignRightIcon = createIcon(\n <g\n stroke=\"currentColor\"\n fill=\"none\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <line x1=\"4\" y1=\"8\" x2=\"20\" y2=\"8\" />\n <line x1=\"10\" y1=\"12\" x2=\"20\" y2=\"12\" />\n <line x1=\"8\" y1=\"16\" x2=\"20\" y2=\"16\" />\n </g>,\n tablerIconProps,\n);\n\n// tabler-icons: layout-align-top\nexport const TextAlignTopIcon = React.memo(({ theme }: { theme: Theme }) =>\n createIcon(\n <g\n strokeWidth=\"1.5\"\n stroke=\"currentColor\"\n fill=\"none\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <line x1=\"4\" y1=\"4\" x2=\"20\" y2=\"4\" />\n <rect x=\"9\" y=\"8\" width=\"6\" height=\"12\" rx=\"2\" />\n </g>,\n tablerIconProps,\n ),\n);\n\n// tabler-icons: layout-align-bottom\nexport const TextAlignBottomIcon = React.memo(({ theme }: { theme: Theme }) =>\n createIcon(\n <g\n strokeWidth=\"2\"\n stroke=\"currentColor\"\n fill=\"none\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <line x1=\"4\" y1=\"20\" x2=\"20\" y2=\"20\" />\n <rect x=\"9\" y=\"4\" width=\"6\" height=\"12\" rx=\"2\"></rect>\n </g>,\n tablerIconProps,\n ),\n);\n\n// tabler-icons: layout-align-middle\nexport const TextAlignMiddleIcon = React.memo(({ theme }: { theme: Theme }) =>\n createIcon(\n <g\n strokeWidth=\"1.5\"\n stroke=\"currentColor\"\n fill=\"none\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <line x1=\"4\" y1=\"12\" x2=\"9\" y2=\"12\" />\n <line x1=\"15\" y1=\"12\" x2=\"20\" y2=\"12\" />\n <rect x=\"9\" y=\"6\" width=\"6\" height=\"12\" rx=\"2\" />\n </g>,\n tablerIconProps,\n ),\n);\n\nexport const angleIcon = createIcon(\n <g>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M21 19h-18l9 -15\" />\n <path d=\"M20.615 15.171h.015\" />\n <path d=\"M19.515 11.771h.015\" />\n <path d=\"M17.715 8.671h.015\" />\n <path d=\"M15.415 5.971h.015\" />\n </g>,\n tablerIconProps,\n);\n\nexport const publishIcon = createIcon(\n <path\n d=\"M537.6 226.6c4.1-10.7 6.4-22.4 6.4-34.6 0-53-43-96-96-96-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32c-88.4 0-160 71.6-160 160 0 2.7.1 5.4.2 8.1C40.2 219.8 0 273.2 0 336c0 79.5 64.5 144 144 144h368c70.7 0 128-57.3 128-128 0-61.9-44-113.6-102.4-125.4zM393.4 288H328v112c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V288h-65.4c-14.3 0-21.4-17.2-11.3-27.3l105.4-105.4c6.2-6.2 16.4-6.2 22.6 0l105.4 105.4c10.1 10.1 2.9 27.3-11.3 27.3z\"\n fill=\"currentColor\"\n />,\n { width: 640, height: 512 },\n);\n\nexport const eraser = createIcon(\n <path d=\"M480 416C497.7 416 512 430.3 512 448C512 465.7 497.7 480 480 480H150.6C133.7 480 117.4 473.3 105.4 461.3L25.37 381.3C.3786 356.3 .3786 315.7 25.37 290.7L258.7 57.37C283.7 32.38 324.3 32.38 349.3 57.37L486.6 194.7C511.6 219.7 511.6 260.3 486.6 285.3L355.9 416H480zM265.4 416L332.7 348.7L195.3 211.3L70.63 336L150.6 416L265.4 416z\" />,\n);\n\nexport const handIcon = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <path d=\"M8 13v-7.5a1.5 1.5 0 0 1 3 0v6.5\"></path>\n <path d=\"M11 5.5v-2a1.5 1.5 0 1 1 3 0v8.5\"></path>\n <path d=\"M14 5.5a1.5 1.5 0 0 1 3 0v6.5\"></path>\n <path d=\"M17 7.5a1.5 1.5 0 0 1 3 0v8.5a6 6 0 0 1 -6 6h-2h.208a6 6 0 0 1 -5.012 -2.7a69.74 69.74 0 0 1 -.196 -.3c-.312 -.479 -1.407 -2.388 -3.286 -5.728a1.5 1.5 0 0 1 .536 -2.022a1.867 1.867 0 0 1 2.28 .28l1.47 1.47\"></path>\n </g>,\n tablerIconProps,\n);\n\nexport const downloadIcon = createIcon(\n <>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <path d=\"M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2\"></path>\n <path d=\"M7 11l5 5l5 -5\"></path>\n <path d=\"M12 4l0 12\"></path>\n </>,\n tablerIconProps,\n);\n\nexport const copyIcon = createIcon(\n <>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <path d=\"M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z\"></path>\n <path d=\"M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2\"></path>\n </>,\n tablerIconProps,\n);\n\nexport const cutIcon = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M7 17m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0\" />\n <path d=\"M17 17m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0\" />\n <path d=\"M9.15 14.85l8.85 -10.85\" />\n <path d=\"M6 4l8.85 10.85\" />\n </g>,\n tablerIconProps,\n);\n\nexport const helpIcon = createIcon(\n <>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <path d=\"M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0\"></path>\n <path d=\"M12 17l0 .01\"></path>\n <path d=\"M12 13.5a1.5 1.5 0 0 1 1 -1.5a2.6 2.6 0 1 0 -3 -4\"></path>\n </>,\n tablerIconProps,\n);\n\nexport const playerPlayIcon = createIcon(\n <>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <path d=\"M7 4v16l13 -8z\"></path>\n </>,\n tablerIconProps,\n);\n\nexport const playerStopFilledIcon = createIcon(\n <>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <path\n d=\"M17 4h-10a3 3 0 0 0 -3 3v10a3 3 0 0 0 3 3h10a3 3 0 0 0 3 -3v-10a3 3 0 0 0 -3 -3z\"\n strokeWidth=\"0\"\n fill=\"currentColor\"\n ></path>\n </>,\n tablerIconProps,\n);\n\nexport const tablerCheckIcon = createIcon(\n <>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <path d=\"M5 12l5 5l10 -10\"></path>\n </>,\n tablerIconProps,\n);\n\nexport const alertTriangleIcon = createIcon(\n <>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M10.24 3.957l-8.422 14.06a1.989 1.989 0 0 0 1.7 2.983h16.845a1.989 1.989 0 0 0 1.7 -2.983l-8.423 -14.06a1.989 1.989 0 0 0 -3.4 0z\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </>,\n tablerIconProps,\n);\n\nexport const eyeDropperIcon = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <path d=\"M11 7l6 6\"></path>\n <path d=\"M4 16l11.7 -11.7a1 1 0 0 1 1.4 0l2.6 2.6a1 1 0 0 1 0 1.4l-11.7 11.7h-4v-4z\"></path>\n </g>,\n tablerIconProps,\n);\n\nexport const extraToolsIcon = createIcon(\n <g strokeWidth={1.5}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <path d=\"M12 3l-4 7h8z\"></path>\n <path d=\"M17 17m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0\"></path>\n <path d=\"M4 14m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z\"></path>\n </g>,\n tablerIconProps,\n);\n\nexport const frameToolIcon = createIcon(\n <g strokeWidth={1.5}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <path d=\"M4 7l16 0\"></path>\n <path d=\"M4 17l16 0\"></path>\n <path d=\"M7 4l0 16\"></path>\n <path d=\"M17 4l0 16\"></path>\n </g>,\n tablerIconProps,\n);\n\nexport const mermaidLogoIcon = createIcon(\n <path\n fill=\"currentColor\"\n d=\"M407.48,111.18C335.587,108.103 269.573,152.338 245.08,220C220.587,152.338 154.573,108.103 82.68,111.18C80.285,168.229 107.577,222.632 154.74,254.82C178.908,271.419 193.35,298.951 193.27,328.27L193.27,379.13L296.9,379.13L296.9,328.27C296.816,298.953 311.255,271.42 335.42,254.82C382.596,222.644 409.892,168.233 407.48,111.18Z\"\n />,\n);\n\nexport const ArrowRightIcon = createIcon(\n <g strokeWidth=\"1.25\">\n <path d=\"M4.16602 10H15.8327\" />\n <path d=\"M12.5 13.3333L15.8333 10\" />\n <path d=\"M12.5 6.66666L15.8333 9.99999\" />\n </g>,\n modifiedTablerIconProps,\n);\n\nexport const laserPointerToolIcon = createIcon(\n <g\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.25\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n transform=\"rotate(90 10 10)\"\n >\n <path\n clipRule=\"evenodd\"\n d=\"m9.644 13.69 7.774-7.773a2.357 2.357 0 0 0-3.334-3.334l-7.773 7.774L8 12l1.643 1.69Z\"\n />\n <path d=\"m13.25 3.417 3.333 3.333M10 10l2-2M5 15l3-3M2.156 17.894l1-1M5.453 19.029l-.144-1.407M2.377 11.887l.866 1.118M8.354 17.273l-1.194-.758M.953 14.652l1.408.13\" />\n </g>,\n\n 20,\n);\n\nexport const MagicIcon = createIcon(\n <g stroke=\"currentColor\" fill=\"none\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M6 21l15 -15l-3 -3l-15 15l3 3\" />\n <path d=\"M15 6l3 3\" />\n <path d=\"M9 3a2 2 0 0 0 2 2a2 2 0 0 0 -2 2a2 2 0 0 0 -2 -2a2 2 0 0 0 2 -2\" />\n <path d=\"M19 13a2 2 0 0 0 2 2a2 2 0 0 0 -2 2a2 2 0 0 0 -2 -2a2 2 0 0 0 2 -2\" />\n </g>,\n tablerIconProps,\n);\n\nexport const MagicIconThin = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M6 21l15 -15l-3 -3l-15 15l3 3\" />\n <path d=\"M15 6l3 3\" />\n <path d=\"M9 3a2 2 0 0 0 2 2a2 2 0 0 0 -2 2a2 2 0 0 0 -2 -2a2 2 0 0 0 2 -2\" />\n <path d=\"M19 13a2 2 0 0 0 2 2a2 2 0 0 0 -2 2a2 2 0 0 0 -2 -2a2 2 0 0 0 2 -2\" />\n </g>,\n tablerIconProps,\n);\n\nexport const OpenAIIcon = createIcon(\n <g stroke=\"currentColor\" fill=\"none\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M11.217 19.384a3.501 3.501 0 0 0 6.783 -1.217v-5.167l-6 -3.35\" />\n <path d=\"M5.214 15.014a3.501 3.501 0 0 0 4.446 5.266l4.34 -2.534v-6.946\" />\n <path d=\"M6 7.63c-1.391 -.236 -2.787 .395 -3.534 1.689a3.474 3.474 0 0 0 1.271 4.745l4.263 2.514l6 -3.348\" />\n <path d=\"M12.783 4.616a3.501 3.501 0 0 0 -6.783 1.217v5.067l6 3.45\" />\n <path d=\"M18.786 8.986a3.501 3.501 0 0 0 -4.446 -5.266l-4.34 2.534v6.946\" />\n <path d=\"M18 16.302c1.391 .236 2.787 -.395 3.534 -1.689a3.474 3.474 0 0 0 -1.271 -4.745l-4.308 -2.514l-5.955 3.42\" />\n </g>,\n tablerIconProps,\n);\n\nexport const fullscreenIcon = createIcon(\n <g stroke=\"currentColor\" fill=\"none\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M4 8v-2a2 2 0 0 1 2 -2h2\" />\n <path d=\"M4 16v2a2 2 0 0 0 2 2h2\" />\n <path d=\"M16 4h2a2 2 0 0 1 2 2v2\" />\n <path d=\"M16 20h2a2 2 0 0 0 2 -2v-2\" />\n </g>,\n tablerIconProps,\n);\n\nexport const eyeIcon = createIcon(\n <g stroke=\"currentColor\" fill=\"none\" strokeWidth={1.5}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0\" />\n <path d=\"M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6\" />\n </g>,\n tablerIconProps,\n);\n\nexport const eyeClosedIcon = createIcon(\n <g stroke=\"currentColor\" fill=\"none\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M10.585 10.587a2 2 0 0 0 2.829 2.828\" />\n <path d=\"M16.681 16.673a8.717 8.717 0 0 1 -4.681 1.327c-3.6 0 -6.6 -2 -9 -6c1.272 -2.12 2.712 -3.678 4.32 -4.674m2.86 -1.146a9.055 9.055 0 0 1 1.82 -.18c3.6 0 6.6 2 9 6c-.666 1.11 -1.379 2.067 -2.138 2.87\" />\n <path d=\"M3 3l18 18\" />\n </g>,\n tablerIconProps,\n);\n\nexport const brainIcon = createIcon(\n <g stroke=\"currentColor\" fill=\"none\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M15.5 13a3.5 3.5 0 0 0 -3.5 3.5v1a3.5 3.5 0 0 0 7 0v-1.8\" />\n <path d=\"M8.5 13a3.5 3.5 0 0 1 3.5 3.5v1a3.5 3.5 0 0 1 -7 0v-1.8\" />\n <path d=\"M17.5 16a3.5 3.5 0 0 0 0 -7h-.5\" />\n <path d=\"M19 9.3v-2.8a3.5 3.5 0 0 0 -7 0\" />\n <path d=\"M6.5 16a3.5 3.5 0 0 1 0 -7h.5\" />\n <path d=\"M5 9.3v-2.8a3.5 3.5 0 0 1 7 0v10\" />\n </g>,\n tablerIconProps,\n);\n\nexport const brainIconThin = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M15.5 13a3.5 3.5 0 0 0 -3.5 3.5v1a3.5 3.5 0 0 0 7 0v-1.8\" />\n <path d=\"M8.5 13a3.5 3.5 0 0 1 3.5 3.5v1a3.5 3.5 0 0 1 -7 0v-1.8\" />\n <path d=\"M17.5 16a3.5 3.5 0 0 0 0 -7h-.5\" />\n <path d=\"M19 9.3v-2.8a3.5 3.5 0 0 0 -7 0\" />\n <path d=\"M6.5 16a3.5 3.5 0 0 1 0 -7h.5\" />\n <path d=\"M5 9.3v-2.8a3.5 3.5 0 0 1 7 0v10\" />\n </g>,\n tablerIconProps,\n);\n\nexport const searchIcon = createIcon(\n <g strokeWidth={1.5}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M10 10m-7 0a7 7 0 1 0 14 0a7 7 0 1 0 -14 0\" />\n <path d=\"M21 21l-6 -6\" />\n </g>,\n tablerIconProps,\n);\n\nexport const clockIcon = createIcon(\n <g strokeWidth={1.5}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M20.984 12.53a9 9 0 1 0 -7.552 8.355\" />\n <path d=\"M12 7v5l3 3\" />\n <path d=\"M19 16l-2 3h4l-2 3\" />\n </g>,\n tablerIconProps,\n);\n\nexport const microphoneIcon = createIcon(\n <g strokeWidth={1.5}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M9 2m0 3a3 3 0 0 1 3 -3h0a3 3 0 0 1 3 3v5a3 3 0 0 1 -3 3h0a3 3 0 0 1 -3 -3z\" />\n <path d=\"M5 10a7 7 0 0 0 14 0\" />\n <path d=\"M8 21l8 0\" />\n <path d=\"M12 17l0 4\" />\n </g>,\n tablerIconProps,\n);\n\nexport const microphoneMutedIcon = createIcon(\n <g strokeWidth={1.5}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M3 3l18 18\" />\n <path d=\"M9 5a3 3 0 0 1 6 0v5a3 3 0 0 1 -.13 .874m-2 2a3 3 0 0 1 -3.87 -2.872v-1\" />\n <path d=\"M5 10a7 7 0 0 0 10.846 5.85m2 -2a6.967 6.967 0 0 0 1.152 -3.85\" />\n <path d=\"M8 21l8 0\" />\n <path d=\"M12 17l0 4\" />\n </g>,\n tablerIconProps,\n);\n\nexport const boltIcon = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M13 3l0 7l6 0l-8 11l0 -7l-6 0l8 -11\" />\n </g>,\n tablerIconProps,\n);\nexport const selectAllIcon = createIcon(\n <g>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M8 8m0 1a1 1 0 0 1 1 -1h6a1 1 0 0 1 1 1v6a1 1 0 0 1 -1 1h-6a1 1 0 0 1 -1 -1z\" />\n <path d=\"M12 20v.01\" />\n <path d=\"M16 20v.01\" />\n <path d=\"M8 20v.01\" />\n <path d=\"M4 20v.01\" />\n <path d=\"M4 16v.01\" />\n <path d=\"M4 12v.01\" />\n <path d=\"M4 8v.01\" />\n <path d=\"M4 4v.01\" />\n <path d=\"M8 4v.01\" />\n <path d=\"M12 4v.01\" />\n <path d=\"M16 4v.01\" />\n <path d=\"M20 4v.01\" />\n <path d=\"M20 8v.01\" />\n <path d=\"M20 12v.01\" />\n <path d=\"M20 16v.01\" />\n <path d=\"M20 20v.01\" />\n </g>,\n tablerIconProps,\n);\n\nexport const abacusIcon = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M5 3v18\" />\n <path d=\"M19 21v-18\" />\n <path d=\"M5 7h14\" />\n <path d=\"M5 15h14\" />\n <path d=\"M8 13v4\" />\n <path d=\"M11 13v4\" />\n <path d=\"M16 13v4\" />\n <path d=\"M14 5v4\" />\n <path d=\"M11 5v4\" />\n <path d=\"M8 5v4\" />\n <path d=\"M3 21h18\" />\n </g>,\n tablerIconProps,\n);\n\nexport const flipVertical = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M3 12l18 0\" />\n <path d=\"M7 16l10 0l-10 5l0 -5\" />\n <path d=\"M7 8l10 0l-10 -5l0 5\" />\n </g>,\n tablerIconProps,\n);\n\nexport const flipHorizontal = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M12 3l0 18\" />\n <path d=\"M16 7l0 10l5 0l-5 -10\" />\n <path d=\"M8 7l0 10l-5 0l5 -10\" />\n </g>,\n tablerIconProps,\n);\n\nexport const paintIcon = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M5 3m0 2a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v2a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2z\" />\n <path d=\"M19 6h1a2 2 0 0 1 2 2a5 5 0 0 1 -5 5l-5 0v2\" />\n <path d=\"M10 15m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z\" />\n </g>,\n tablerIconProps,\n);\n\nexport const zoomAreaIcon = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M15 15m-5 0a5 5 0 1 0 10 0a5 5 0 1 0 -10 0\" />\n <path d=\"M22 22l-3 -3\" />\n <path d=\"M6 18h-1a2 2 0 0 1 -2 -2v-1\" />\n <path d=\"M3 11v-1\" />\n <path d=\"M3 6v-1a2 2 0 0 1 2 -2h1\" />\n <path d=\"M10 3h1\" />\n <path d=\"M15 3h1a2 2 0 0 1 2 2v1\" />\n </g>,\n tablerIconProps,\n);\n\nexport const svgIcon = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\" />\n <path d=\"M5 12v-7a2 2 0 0 1 2 -2h7l5 5v4\" />\n <path d=\"M4 20.25c0 .414 .336 .75 .75 .75h1.25a1 1 0 0 0 1 -1v-1a1 1 0 0 0 -1 -1h-1a1 1 0 0 1 -1 -1v-1a1 1 0 0 1 1 -1h1.25a.75 .75 0 0 1 .75 .75\" />\n <path d=\"M10 15l2 6l2 -6\" />\n <path d=\"M20 15h-1a2 2 0 0 0 -2 2v2a2 2 0 0 0 2 2h1v-3\" />\n </g>,\n tablerIconProps,\n);\n\nexport const pngIcon = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\" />\n <path d=\"M5 12v-7a2 2 0 0 1 2 -2h7l5 5v4\" />\n <path d=\"M20 15h-1a2 2 0 0 0 -2 2v2a2 2 0 0 0 2 2h1v-3\" />\n <path d=\"M5 18h1.5a1.5 1.5 0 0 0 0 -3h-1.5v6\" />\n <path d=\"M11 21v-6l3 6v-6\" />\n </g>,\n tablerIconProps,\n);\n\nexport const magnetIcon = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M4 13v-8a2 2 0 0 1 2 -2h1a2 2 0 0 1 2 2v8a2 2 0 0 0 6 0v-8a2 2 0 0 1 2 -2h1a2 2 0 0 1 2 2v8a8 8 0 0 1 -16 0\" />\n <path d=\"M4 8l5 0\" />\n <path d=\"M15 8l4 0\" />\n </g>,\n tablerIconProps,\n);\n\nexport const coffeeIcon = createIcon(\n <g strokeWidth={1.25}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M3 14c.83 .642 2.077 1.017 3.5 1c1.423 .017 2.67 -.358 3.5 -1c.83 -.642 2.077 -1.017 3.5 -1c1.423 -.017 2.67 .358 3.5 1\" />\n <path d=\"M8 3a2.4 2.4 0 0 0 -1 2a2.4 2.4 0 0 0 1 2\" />\n <path d=\"M12 3a2.4 2.4 0 0 0 -1 2a2.4 2.4 0 0 0 1 2\" />\n <path d=\"M3 10h14v5a6 6 0 0 1 -6 6h-2a6 6 0 0 1 -6 -6v-5z\" />\n <path d=\"M16.746 16.726a3 3 0 1 0 .252 -5.555\" />\n </g>,\n tablerIconProps,\n);\n\nexport const DeviceDesktopIcon = createIcon(\n <g stroke=\"currentColor\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M3 5a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1h-16a1 1 0 0 1-1-1v-10zM7 20h10M9 16v4M15 16v4\" />\n </g>,\n { ...tablerIconProps, strokeWidth: 1.5 },\n);\n\n// login\nexport const loginIcon = createIcon(\n <g strokeWidth={1.5}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M15 8v-2a2 2 0 0 0 -2 -2h-7a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h7a2 2 0 0 0 2 -2v-2\" />\n <path d=\"M21 12h-13l3 -3\" />\n <path d=\"M11 15l-3 -3\" />\n </g>,\n tablerIconProps,\n);\n\nexport const youtubeIcon = createIcon(\n <g>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M2 8a4 4 0 0 1 4 -4h12a4 4 0 0 1 4 4v8a4 4 0 0 1 -4 4h-12a4 4 0 0 1 -4 -4v-8z\" />\n <path d=\"M10 9l5 3l-5 3z\" />\n </g>,\n tablerIconProps,\n);\n\nexport const gridIcon = createIcon(\n <g strokeWidth={1.5}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M3 6h18\" />\n <path d=\"M3 12h18\" />\n <path d=\"M3 18h18\" />\n <path d=\"M6 3v18\" />\n <path d=\"M12 3v18\" />\n <path d=\"M18 3v18\" />\n </g>,\n tablerIconProps,\n);\n\nexport const lineEditorIcon = createIcon(\n <g strokeWidth={1.5}>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M17 3m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v2a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z\" />\n <path d=\"M3 17m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v2a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z\" />\n <path d=\"M17 5c-6.627 0 -12 5.373 -12 12\" />\n </g>,\n tablerIconProps,\n);\n\n// arrow-up-right (modified)\nexport const sharpArrowIcon = createIcon(\n <g>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M6 18l12 -12\" />\n <path d=\"M18 10v-4h-4\" />\n </g>,\n tablerIconProps,\n);\n\n// arrow-guide (modified)\nexport const elbowArrowIcon = createIcon(\n <g>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M4,19L10,19C11.097,19 12,18.097 12,17L12,9C12,7.903 12.903,7 14,7L21,7\" />\n <path d=\"M18 4l3 3l-3 3\" />\n </g>,\n tablerIconProps,\n);\n\n// arrow-ramp-right-2 (heavily modified)\nexport const roundArrowIcon = createIcon(\n <g>\n <path d=\"M16,12L20,9L16,6\" />\n <path d=\"M6 20c0 -6.075 4.925 -11 11 -11h3\" />\n </g>,\n tablerIconProps,\n);\n\nexport const collapseDownIcon = createIcon(\n <g>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M6 9l6 6l6 -6\" />\n </g>,\n tablerIconProps,\n);\n\nexport const collapseUpIcon = createIcon(\n <g>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M6 15l6 -6l6 6\" />\n </g>,\n tablerIconProps,\n);\n\nexport const upIcon = createIcon(\n <g>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M6 15l6 -6l6 6\" />\n </g>,\n tablerIconProps,\n);\n\nexport const cropIcon = createIcon(\n <g strokeWidth=\"1.25\">\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M8 5v10a1 1 0 0 0 1 1h10\" />\n <path d=\"M5 8h10a1 1 0 0 1 1 1v10\" />\n </g>,\n tablerIconProps,\n);\n\nexport const elementLinkIcon = createIcon(\n <g>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M5 5m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0\" />\n <path d=\"M19 5m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0\" />\n <path d=\"M5 19m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0\" />\n <path d=\"M19 19m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0\" />\n <path d=\"M5 7l0 10\" />\n <path d=\"M7 5l10 0\" />\n <path d=\"M7 19l10 0\" />\n <path d=\"M19 7l0 10\" />\n </g>,\n tablerIconProps,\n);\n", "import type { JSX } from \"react\";\nimport {\n FreedrawIcon,\n FontFamilyNormalIcon,\n FontFamilyHeadingIcon,\n FontFamilyCodeIcon,\n} from \"../components/icons\";\nimport { FONT_FAMILY, FONT_FAMILY_FALLBACKS } from \"../constants\";\n\n/**\n * Encapsulates font metrics with additional font metadata.\n * */\nexport interface FontMetadata {\n /** for head & hhea metrics read the woff2 with https://fontdrop.info/ */\n metrics: {\n /** head.unitsPerEm metric */\n unitsPerEm: 1000 | 1024 | 2048;\n /** hhea.ascender metric */\n ascender: number;\n /** hhea.descender metric */\n descender: number;\n /** harcoded unitless line-height, https://github.com/excalidraw/excalidraw/pull/6360#issuecomment-1477635971 */\n lineHeight: number;\n };\n /** element to be displayed as an icon */\n icon?: JSX.Element;\n /** flag to indicate a deprecated font */\n deprecated?: true;\n /** flag to indicate a server-side only font */\n serverSide?: true;\n /** flag to indiccate a local-only font */\n local?: true;\n /** flag to indicate a fallback font */\n fallback?: true;\n}\n\nexport const FONT_METADATA: Record<number, FontMetadata> = {\n [FONT_FAMILY.Excalifont]: {\n metrics: {\n unitsPerEm: 1000,\n ascender: 886,\n descender: -374,\n lineHeight: 1.25,\n },\n icon: FreedrawIcon,\n },\n [FONT_FAMILY.Nunito]: {\n metrics: {\n unitsPerEm: 1000,\n ascender: 1011,\n descender: -353,\n lineHeight: 1.35,\n },\n icon: FontFamilyNormalIcon,\n },\n [FONT_FAMILY[\"Lilita One\"]]: {\n metrics: {\n unitsPerEm: 1000,\n ascender: 923,\n descender: -220,\n lineHeight: 1.15,\n },\n icon: FontFamilyHeadingIcon,\n },\n [FONT_FAMILY[\"Comic Shanns\"]]: {\n metrics: {\n unitsPerEm: 1000,\n ascender: 750,\n descender: -250,\n lineHeight: 1.25,\n },\n icon: FontFamilyCodeIcon,\n },\n [FONT_FAMILY.Virgil]: {\n metrics: {\n unitsPerEm: 1000,\n ascender: 886,\n descender: -374,\n lineHeight: 1.25,\n },\n icon: FreedrawIcon,\n deprecated: true,\n },\n [FONT_FAMILY.Helvetica]: {\n metrics: {\n unitsPerEm: 2048,\n ascender: 1577,\n descender: -471,\n lineHeight: 1.15,\n },\n icon: FontFamilyNormalIcon,\n deprecated: true,\n local: true,\n },\n [FONT_FAMILY.Cascadia]: {\n metrics: {\n unitsPerEm: 2048,\n ascender: 1900,\n descender: -480,\n lineHeight: 1.2,\n },\n icon: FontFamilyCodeIcon,\n deprecated: true,\n },\n [FONT_FAMILY[\"Liberation Sans\"]]: {\n metrics: {\n unitsPerEm: 2048,\n ascender: 1854,\n descender: -434,\n lineHeight: 1.15,\n },\n serverSide: true,\n },\n [FONT_FAMILY_FALLBACKS.Xiaolai]: {\n metrics: {\n unitsPerEm: 1000,\n ascender: 880,\n descender: -144,\n lineHeight: 1.15,\n },\n fallback: true,\n },\n [FONT_FAMILY_FALLBACKS[\"Segoe UI Emoji\"]]: {\n metrics: {\n // reusing Excalifont metrics\n unitsPerEm: 1000,\n ascender: 886,\n descender: -374,\n lineHeight: 1.25,\n },\n local: true,\n fallback: true,\n },\n};\n\n/** Unicode ranges defined by google fonts */\nexport const GOOGLE_FONTS_RANGES = {\n LATIN:\n \"U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD\",\n LATIN_EXT:\n \"U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF\",\n CYRILIC_EXT:\n \"U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F\",\n CYRILIC: \"U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116\",\n VIETNAMESE:\n \"U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB\",\n};\n\n/** local protocol to skip the local font from registering or inlining */\nexport const LOCAL_FONT_PROTOCOL = \"local:\";\n", "type CANVAS_ERROR_NAMES = \"CANVAS_ERROR\" | \"CANVAS_POSSIBLY_TOO_BIG\";\n\nexport class CanvasError extends Error {\n constructor(\n message: string = \"Couldn't export canvas.\",\n name: CANVAS_ERROR_NAMES = \"CANVAS_ERROR\",\n ) {\n super();\n this.name = name;\n this.message = message;\n }\n}\n\nexport class AbortError extends DOMException {\n constructor(message: string = \"Request Aborted\") {\n super(message, \"AbortError\");\n }\n}\n\ntype ImageSceneDataErrorCode =\n | \"IMAGE_NOT_CONTAINS_SCENE_DATA\"\n | \"IMAGE_SCENE_DATA_ERROR\";\n\nexport class ImageSceneDataError extends Error {\n public code;\n constructor(\n message = \"Image Scene Data Error\",\n code: ImageSceneDataErrorCode = \"IMAGE_SCENE_DATA_ERROR\",\n ) {\n super(message);\n this.name = \"EncodingError\";\n this.code = code;\n }\n}\n\nexport class InvalidFractionalIndexError extends Error {\n public code = \"ELEMENT_HAS_INVALID_INDEX\" as const;\n}\n\ntype WorkerErrorCodes = \"WORKER_URL_NOT_DEFINED\" | \"WORKER_IN_THE_MAIN_CHUNK\";\n\nexport class WorkerUrlNotDefinedError extends Error {\n public code;\n constructor(\n message = \"Worker URL is not defined!\",\n code: WorkerErrorCodes = \"WORKER_URL_NOT_DEFINED\",\n ) {\n super(message);\n this.name = \"WorkerUrlNotDefinedError\";\n this.code = code;\n }\n}\n\nexport class WorkerInTheMainChunkError extends Error {\n public code;\n constructor(\n message = \"Worker has to be in a separate chunk!\",\n code: WorkerErrorCodes = \"WORKER_IN_THE_MAIN_CHUNK\",\n ) {\n super(message);\n this.name = \"WorkerInTheMainChunkError\";\n this.code = code;\n }\n}\n\n/**\n * Use this for generic, handled errors, so you can check against them\n * and rethrow if needed\n */\nexport class ExcalidrawError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ExcalidrawError\";\n }\n}\n", "import { WorkerInTheMainChunkError, WorkerUrlNotDefinedError } from \"./errors\";\nimport { debounce } from \"./utils\";\n\nclass IdleWorker {\n public instance: Worker;\n\n constructor(workerUrl: URL) {\n this.instance = new Worker(workerUrl, { type: \"module\" });\n }\n\n /**\n * Use to prolong the worker's life by `workerTTL` or terminate it with a flush immediately.\n */\n public debounceTerminate!: ReturnType<typeof debounce>;\n}\n\n/**\n * Pool of idle short-lived workers.\n *\n * IMPORTANT: for simplicity it does not limit the number of newly created workers, leaving it up to the caller to manage the pool size.\n */\nexport class WorkerPool<T, R> {\n private idleWorkers: Set<IdleWorker> = new Set();\n private readonly workerUrl: URL;\n private readonly workerTTL: number;\n\n private constructor(\n workerUrl: URL,\n options: {\n ttl?: number;\n },\n ) {\n this.workerUrl = workerUrl;\n // by default, active & idle workers will be terminated after 1s of inactivity\n this.workerTTL = options.ttl || 1000;\n }\n\n /**\n * Create a new worker pool.\n *\n * @param workerUrl - The URL of the worker file.\n * @param options - The options for the worker pool.\n * @throws If the worker is bundled into the main chunk.\n * @returns A new worker pool instance.\n */\n public static create<T, R>(\n workerUrl: URL | undefined,\n options: {\n ttl?: number;\n } = {},\n ): WorkerPool<T, R> {\n if (!workerUrl) {\n throw new WorkerUrlNotDefinedError();\n }\n\n if (!import.meta.url || workerUrl.toString() === import.meta.url) {\n // in case the worker code is bundled into the main chunk\n throw new WorkerInTheMainChunkError();\n }\n\n return new WorkerPool(workerUrl, options);\n }\n\n /**\n * Take idle worker from the pool or create a new one and post a message to it.\n */\n public async postMessage(\n data: T,\n options: StructuredSerializeOptions,\n ): Promise<R> {\n let worker: IdleWorker;\n\n const idleWorker = Array.from(this.idleWorkers).shift();\n if (idleWorker) {\n this.idleWorkers.delete(idleWorker);\n worker = idleWorker;\n } else {\n worker = await this.createWorker();\n }\n\n return new Promise((resolve, reject) => {\n worker.instance.onmessage = this.onMessageHandler(worker, resolve);\n worker.instance.onerror = this.onErrorHandler(worker, reject);\n\n worker.instance.postMessage(data, options);\n worker.debounceTerminate(() =>\n reject(\n new Error(`Active worker did not respond for ${this.workerTTL}ms!`),\n ),\n );\n });\n }\n\n /**\n * Terminate the idle workers in the pool.\n */\n public async clear() {\n for (const worker of this.idleWorkers) {\n worker.debounceTerminate.cancel();\n worker.instance.terminate();\n }\n\n this.idleWorkers.clear();\n }\n\n /**\n * Used to get a worker from the pool or create a new one if there is no idle available.\n */\n private async createWorker(): Promise<IdleWorker> {\n const worker = new IdleWorker(this.workerUrl);\n\n worker.debounceTerminate = debounce((reject?: () => void) => {\n worker.instance.terminate();\n\n if (this.idleWorkers.has(worker)) {\n this.idleWorkers.delete(worker);\n\n // eslint-disable-next-line no-console\n console.debug(\n \"Job finished! Idle worker has been released from the pool.\",\n );\n } else if (reject) {\n reject();\n } else {\n console.error(\"Worker has been terminated!\");\n }\n }, this.workerTTL);\n\n return worker;\n }\n\n private onMessageHandler(worker: IdleWorker, resolve: (value: R) => void) {\n return (e: { data: R }) => {\n worker.debounceTerminate();\n this.idleWorkers.add(worker);\n resolve(e.data);\n };\n }\n\n private onErrorHandler(\n worker: IdleWorker,\n reject: (reason: ErrorEvent) => void,\n ) {\n return (e: ErrorEvent) => {\n // terminate the worker immediately before rejection\n worker.debounceTerminate(() => reject(e));\n worker.debounceTerminate.flush();\n\n // clear the worker pool in case there are some idle workers left\n this.clear();\n };\n }\n}\n", "import { WorkerPool } from \"../workers\";\nimport { isServerEnv, promiseTry } from \"../utils\";\nimport { WorkerInTheMainChunkError, WorkerUrlNotDefinedError } from \"../errors\";\n\nimport type { Commands } from \"./subset-shared.chunk\";\n\nlet shouldUseWorkers = typeof Worker !== \"undefined\";\n\n/**\n * Tries to subset glyphs in a font based on the used codepoints, returning the font as dataurl.\n * Under the hood utilizes worker threads (Web Workers, if available), otherwise fallbacks to the main thread.\n *\n * Check the following diagram for details: link.excalidraw.com/readonly/MbbnWPSWXgadXdtmzgeO\n *\n * @param arrayBuffer font data buffer in the woff2 format\n * @param codePoints codepoints used to subset the glyphs\n *\n * @returns font with subsetted glyphs (all glyphs in case of errors) converted into a dataurl\n */\nexport const subsetWoff2GlyphsByCodepoints = async (\n arrayBuffer: ArrayBuffer,\n codePoints: Array<number>,\n): Promise<string> => {\n const { Commands, subsetToBase64, toBase64 } =\n await lazyLoadSharedSubsetChunk();\n\n if (!shouldUseWorkers) {\n return subsetToBase64(arrayBuffer, codePoints);\n }\n\n return promiseTry(async () => {\n try {\n const workerPool = await getOrCreateWorkerPool();\n // copy the buffer to avoid working on top of the detached array buffer in the fallback\n // i.e. in case the worker throws, the array buffer does not get automatically detached, even if the worker is terminated\n const arrayBufferCopy = arrayBuffer.slice(0);\n const result = await workerPool.postMessage(\n {\n command: Commands.Subset,\n arrayBuffer: arrayBufferCopy,\n codePoints,\n } as const,\n { transfer: [arrayBufferCopy] },\n );\n\n // encode on the main thread to avoid copying large binary strings (as dataurl) between threads\n return toBase64(result);\n } catch (e) {\n // don't use workers if they are failing\n shouldUseWorkers = false;\n\n if (\n // don't log the expected errors server-side\n !(\n isServerEnv() &&\n (e instanceof WorkerUrlNotDefinedError ||\n e instanceof WorkerInTheMainChunkError)\n )\n ) {\n // eslint-disable-next-line no-console\n console.error(\n \"Failed to use workers for subsetting, falling back to the main thread.\",\n e,\n );\n }\n\n // fallback to the main thread\n return subsetToBase64(arrayBuffer, codePoints);\n }\n });\n};\n\n// lazy-loaded and cached chunks\nlet subsetWorker: Promise<typeof import(\"./subset-worker.chunk\")> | null = null;\nlet subsetShared: Promise<typeof import(\"./subset-shared.chunk\")> | null = null;\n\nconst lazyLoadWorkerSubsetChunk = async () => {\n if (!subsetWorker) {\n subsetWorker = import(\"./subset-worker.chunk\");\n }\n\n return subsetWorker;\n};\n\nconst lazyLoadSharedSubsetChunk = async () => {\n if (!subsetShared) {\n // load dynamically to force create a shared chunk reused between main thread and the worker thread\n subsetShared = import(\"./subset-shared.chunk\");\n }\n\n return subsetShared;\n};\n\n// could be extended with multiple commands in the future\ntype SubsetWorkerData = {\n command: typeof Commands.Subset;\n arrayBuffer: ArrayBuffer;\n codePoints: Array<number>;\n};\n\ntype SubsetWorkerResult<T extends SubsetWorkerData[\"command\"]> =\n T extends typeof Commands.Subset ? ArrayBuffer : never;\n\nlet workerPool: Promise<\n WorkerPool<SubsetWorkerData, SubsetWorkerResult<SubsetWorkerData[\"command\"]>>\n> | null = null;\n\n/**\n * Lazy initialize or get the worker pool singleton.\n *\n * @throws implicitly if anything goes wrong - worker pool creation, loading wasm, initializing worker, etc.\n */\nconst getOrCreateWorkerPool = () => {\n if (!workerPool) {\n // immediate concurrent-friendly return, to ensure we have only one pool instance\n workerPool = promiseTry(async () => {\n const { WorkerUrl } = await lazyLoadWorkerSubsetChunk();\n\n const pool = WorkerPool.create<\n SubsetWorkerData,\n SubsetWorkerResult<SubsetWorkerData[\"command\"]>\n >(WorkerUrl);\n\n return pool;\n });\n }\n\n return workerPool;\n};\n", "import { promiseTry } from \"../utils\";\nimport { LOCAL_FONT_PROTOCOL } from \"./FontMetadata\";\nimport { subsetWoff2GlyphsByCodepoints } from \"../subset/subset-main\";\n\ntype DataURL = string;\n\nexport class ExcalidrawFontFace {\n public readonly urls: URL[] | DataURL[];\n public readonly fontFace: FontFace;\n\n private static readonly ASSETS_FALLBACK_URL = `https://esm.sh/${\n import.meta.env.VITE_PKG_NAME\n ? `${import.meta.env.VITE_PKG_NAME}@${import.meta.env.PKG_VERSION}` // should be provided by vite during package build\n : \"@excalidraw/excalidraw\" // fallback to latest package version (i.e. for app)\n }/dist/prod/`;\n\n constructor(family: string, uri: string, descriptors?: FontFaceDescriptors) {\n this.urls = ExcalidrawFontFace.createUrls(uri);\n\n const sources = this.urls\n .map((url) => `url(${url}) ${ExcalidrawFontFace.getFormat(url)}`)\n .join(\", \");\n\n this.fontFace = new FontFace(family, sources, {\n display: \"swap\",\n style: \"normal\",\n weight: \"400\",\n ...descriptors,\n });\n }\n\n /**\n * Generates CSS `@font-face` definition with the (subsetted) font source as a data url for the characters within the unicode range.\n *\n * Retrieves `undefined` otherwise.\n */\n public toCSS(characters: string): Promise<string> | undefined {\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 }\n\n const codepoints = Array.from(characters).map(\n (char) => char.codePointAt(0)!,\n );\n\n return this.getContent(codepoints).then(\n (content) =>\n `@font-face { font-family: ${this.fontFace.family}; src: url(${content}); }`,\n );\n }\n\n /**\n * Tries to fetch woff2 content, based on the registered urls (from first to last, treated as fallbacks).\n *\n * @returns base64 with subsetted glyphs based on the passed codepoint, last defined url otherwise\n */\n public async getContent(codePoints: Array<number>): Promise<string> {\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 subsetWoff2GlyphsByCodepoints(\n arrayBuffer,\n codePoints,\n );\n\n return base64;\n } catch (e) {\n errorMessages.push(`\"${url.toString()}\" returned error \"${e}\"`);\n }\n\n i++;\n }\n\n console.error(\n `Failed to fetch font family \"${this.fontFace.family}\"`,\n JSON.stringify(errorMessages, undefined, 2),\n );\n\n // 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 return this.urls.length ? this.urls[this.urls.length - 1].toString() : \"\";\n }\n\n public fetchFont(url: URL | DataURL): Promise<ArrayBuffer> {\n return promiseTry(async () => {\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(\n `Failed to fetch \"${urlString}\": ${response.statusText}`,\n );\n }\n\n const arrayBuffer = await response.arrayBuffer();\n return arrayBuffer;\n });\n }\n\n private 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\n .split(/,\\s*/)\n .map((range) => {\n const [start, end] = range.replace(\"U+\", \"\").split(\"-\");\n if (end) {\n return `\\\\u{${start}}-\\\\u{${end}}`;\n }\n\n return `\\\\u{${start}}`;\n })\n .join(\"\");\n\n return new RegExp(`[${unicodeRangeRegex}]`, \"u\");\n }\n\n private static createUrls(uri: string): URL[] | DataURL[] {\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(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 }\n\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 const assetUrl: string = uri.replace(/^\\/+/, \"\");\n const urls: URL[] = [];\n\n if (typeof window.EXCALIDRAW_ASSET_PATH === \"string\") {\n const normalizedBaseUrl = this.normalizeBaseUrl(\n window.EXCALIDRAW_ASSET_PATH,\n );\n\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 }\n\n // fallback url for bundled fonts\n urls.push(new URL(assetUrl, ExcalidrawFontFace.ASSETS_FALLBACK_URL));\n\n return urls;\n }\n\n private static getFormat(url: URL | DataURL) {\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 private static normalizeBaseUrl(baseUrl: string) {\n let result = baseUrl;\n\n // 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 if (/^\\.?\\//.test(result)) {\n result = new URL(\n result.replace(/^\\.?\\/+/, \"\"),\n window?.location?.origin,\n ).toString();\n }\n\n // ensure there is a trailing slash, otherwise url won't be correctly concatenated\n result = `${result.replace(/\\/+$/, \"\")}/`;\n\n return result;\n }\n}\n", "import CascadiaCodeRegular from \"./CascadiaCode-Regular.woff2\";\n\nimport { type ExcalidrawFontFaceDescriptor } from \"../Fonts\";\n\nexport const CascadiaFontFaces: ExcalidrawFontFaceDescriptor[] = [\n {\n uri: CascadiaCodeRegular,\n },\n];\n", "// The following file content was generated with https://chinese-font.netlify.app/online-split,\n// but has been manully rewritten from `@font-face` rules into TS while leveraging FontFace API.\n\nimport _0 from \"./ComicShanns-Regular-279a7b317d12eb88de06167bd672b4b4.woff2\";\nimport _1 from \"./ComicShanns-Regular-fcb0fc02dcbee4c9846b3e2508668039.woff2\";\nimport _2 from \"./ComicShanns-Regular-dc6a8806fa96795d7b3be5026f989a17.woff2\";\nimport _3 from \"./ComicShanns-Regular-6e066e8de2ac57ea9283adb9c24d7f0c.woff2\";\n\nimport { type ExcalidrawFontFaceDescriptor } from \"../Fonts\";\n\n/* Generated By cn-font-split@5.2.2 https://www.npmjs.com/package/cn-font-split\nCreateTime: Thu, 17 Oct 2024 09:57:51 GMT;\nOrigin File Name Table:\ncopyright: MIT License\n\nCopyright (c) 2018 Shannon Miwa\nCopyright (c) 2023 Jesus Gonzalez\nCopyright (c) 2023 Rodrigo Batista de Moraes\nCopyright (c) 2024 Fini Jastrow\nCopyright (c) 2024 Kyle Beechly\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\nfontFamily: Comic Shanns Mono-Regular\nfontSubfamily: Regular\nuniqueID: FontForge 2.0 : Comic Shanns Mono Regular : 17-10-2024\nfullName: Comic Shanns Mono Regular\nversion: 1.3.0\npostScriptName: ComicShannsMono-Regular\nlicense: MIT License\n\nCopyright (c) 2018 Shannon Miwa\nCopyright (c) 2023 Jesus Gonzalez\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\npreferredFamily: Comic Shanns Mono\n */\n\nexport const ComicShannsFontFaces: ExcalidrawFontFaceDescriptor[] = [\n {\n uri: _0,\n descriptors: {\n unicodeRange:\n \"U+20-7e,U+a1-a6,U+a8,U+ab-ac,U+af-b1,U+b4,U+b8,U+bb-bc,U+bf-cf,U+d1-d7,U+d9-de,U+e0-ef,U+f1-f7,U+f9-ff,U+131,U+152-153,U+2c6,U+2da,U+2dc,U+2013-2014,U+2018-201a,U+201c-201d,U+2020-2022,U+2026,U+2039-203a,U+2044,U+20ac,U+2191,U+2193,U+2212\",\n },\n },\n {\n uri: _1,\n descriptors: {\n unicodeRange:\n \"U+100-10f,U+112-125,U+128-130,U+134-137,U+139-13c,U+141-148,U+14c-151,U+154-161,U+164-165,U+168-17f,U+1bf,U+1f7,U+218-21b,U+237,U+1e80-1e85,U+1ef2-1ef3,U+a75b\",\n },\n },\n {\n uri: _2,\n descriptors: {\n unicodeRange:\n \"U+2c7,U+2d8-2d9,U+2db,U+2dd,U+315,U+2190,U+2192,U+2200,U+2203-2204,U+2264-2265,U+f6c3\",\n },\n },\n {\n uri: _3,\n descriptors: { unicodeRange: \"U+3bb\" },\n },\n];\n", "import { LOCAL_FONT_PROTOCOL } from \"../FontMetadata\";\n\nimport { type ExcalidrawFontFaceDescriptor } from \"../Fonts\";\n\nexport const EmojiFontFaces: ExcalidrawFontFaceDescriptor[] = [\n {\n uri: LOCAL_FONT_PROTOCOL,\n },\n];\n", "import _0 from \"./Excalifont-Regular-a88b72a24fb54c9f94e3b5fdaa7481c9.woff2\";\nimport _1 from \"./Excalifont-Regular-be310b9bcd4f1a43f571c46df7809174.woff2\";\nimport _2 from \"./Excalifont-Regular-b9dcf9d2e50a1eaf42fc664b50a3fd0d.woff2\";\nimport _3 from \"./Excalifont-Regular-41b173a47b57366892116a575a43e2b6.woff2\";\nimport _4 from \"./Excalifont-Regular-3f2c5db56cc93c5a6873b1361d730c16.woff2\";\nimport _5 from \"./Excalifont-Regular-349fac6ca4700ffec595a7150a0d1e1d.woff2\";\nimport _6 from \"./Excalifont-Regular-623ccf21b21ef6b3a0d87738f77eb071.woff2\";\n\nimport { type ExcalidrawFontFaceDescriptor } from \"../Fonts\";\n\n/* Generated By cn-font-split@5.2.2 https://www.npmjs.com/package/cn-font-split\nCreateTime: Mon, 14 Oct 2024 18:59:19 GMT;\nOrigin File Name Table:\ncopyright: Copyright (c) 2024 by Excalidraw. All rights reserved.\nfontFamily: Excalifont\nfontSubfamily: Regular\nuniqueID: 1.000;DSGN;Excalifont\nfullName: Excalifont Regular\nversion: Version 1.000;Glyphs 3.2 (3227)\npostScriptName: Excalifont-Regular\ntrademark: Excalifont is a trademark of Excalidraw.\nmanufacturer: Your Own Font Foundry (Virgil); J\u00E1n Fil\u00EDpek / DizajnDesign (Excalifont, modifications)\ndesigner: Your Own Font Foundry (Virgil); J\u00E1n Fil\u00EDpek / DizajnDesign (Excalifont, modifications)\nmanufacturerURL: https://dizajndesign.sk\ndesignerURL: https://dizajndesign.sk\nlicense: This Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttp://scripts.sil.org/OFL\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\nlicenseURL: http://scripts.sil.org/OFL\npreferredFamily: Excalifont\npreferredSubfamily: Regular\n */\n\nexport const ExcalifontFontFaces: ExcalidrawFontFaceDescriptor[] = [\n {\n uri: _0,\n descriptors: {\n unicodeRange:\n \"U+20-7e,U+a0-a3,U+a5-a6,U+a8-ab,U+ad-b1,U+b4,U+b6-b8,U+ba-ff,U+131,U+152-153,U+2bc,U+2c6,U+2da,U+2dc,U+304,U+308,U+2013-2014,U+2018-201a,U+201c-201e,U+2020,U+2022,U+2024-2026,U+2030,U+2039-203a,U+20ac,U+2122,U+2212\",\n },\n },\n {\n uri: _1,\n descriptors: {\n unicodeRange:\n \"U+100-130,U+132-137,U+139-149,U+14c-151,U+154-17e,U+192,U+1fc-1ff,U+218-21b,U+237,U+1e80-1e85,U+1ef2-1ef3,U+2113\",\n },\n },\n { uri: _2, descriptors: { unicodeRange: \"U+400-45f,U+490-491,U+2116\" } },\n {\n uri: _3,\n descriptors: {\n unicodeRange:\n \"U+37e,U+384-38a,U+38c,U+38e-393,U+395-3a1,U+3a3-3a8,U+3aa-3cf,U+3d7\",\n },\n },\n {\n uri: _4,\n descriptors: {\n unicodeRange:\n \"U+2c7,U+2d8-2d9,U+2db,U+2dd,U+302,U+306-307,U+30a-30c,U+326-328,U+212e,U+2211,U+fb01-fb02\",\n },\n },\n {\n uri: _5,\n descriptors: {\n unicodeRange:\n \"U+462-463,U+472-475,U+4d8-4d9,U+4e2-4e3,U+4e6-4e9,U+4ee-4ef\",\n },\n },\n { uri: _6, descriptors: { unicodeRange: \"U+300-301,U+303\" } },\n];\n", "import { LOCAL_FONT_PROTOCOL } from \"../FontMetadata\";\n\nimport { type ExcalidrawFontFaceDescriptor } from \"../Fonts\";\n\nexport const HelveticaFontFaces: ExcalidrawFontFaceDescriptor[] = [\n {\n uri: LOCAL_FONT_PROTOCOL,\n },\n];\n", "import LiberationSansRegular from \"./LiberationSans-Regular.woff2\";\n\nimport { type ExcalidrawFontFaceDescriptor } from \"../Fonts\";\n\nexport const LiberationFontFaces: ExcalidrawFontFaceDescriptor[] = [\n {\n uri: LiberationSansRegular,\n },\n];\n", "import LilitaLatin from \"./Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYEF8RXi4EwQ.woff2\";\nimport LilitaLatinExt from \"./Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYE98RXi4EwSsbg.woff2\";\n\nimport { GOOGLE_FONTS_RANGES } from \"../FontMetadata\";\n\nimport { type ExcalidrawFontFaceDescriptor } from \"../Fonts\";\n\nexport const LilitaFontFaces: ExcalidrawFontFaceDescriptor[] = [\n {\n uri: LilitaLatinExt,\n descriptors: { unicodeRange: GOOGLE_FONTS_RANGES.LATIN_EXT },\n },\n {\n uri: LilitaLatin,\n descriptors: { unicodeRange: GOOGLE_FONTS_RANGES.LATIN },\n },\n];\n", "import Latin from \"./Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg.woff2\";\nimport LatinExt from \"./Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTo3j6zbXWjgevT5.woff2\";\nimport Cyrilic from \"./Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5.woff2\";\nimport CyrilicExt from \"./Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTk3j6zbXWjgevT5.woff2\";\nimport Vietnamese from \"./Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTs3j6zbXWjgevT5.woff2\";\n\nimport { GOOGLE_FONTS_RANGES } from \"../FontMetadata\";\n\nimport { type ExcalidrawFontFaceDescriptor } from \"../Fonts\";\n\nexport const NunitoFontFaces: ExcalidrawFontFaceDescriptor[] = [\n {\n uri: CyrilicExt,\n descriptors: {\n unicodeRange: GOOGLE_FONTS_RANGES.CYRILIC_EXT,\n weight: \"500\",\n },\n },\n {\n uri: Cyrilic,\n descriptors: { unicodeRange: GOOGLE_FONTS_RANGES.CYRILIC, weight: \"500\" },\n },\n {\n uri: Vietnamese,\n descriptors: {\n unicodeRange: GOOGLE_FONTS_RANGES.VIETNAMESE,\n weight: \"500\",\n },\n },\n {\n uri: LatinExt,\n descriptors: { unicodeRange: GOOGLE_FONTS_RANGES.LATIN_EXT, weight: \"500\" },\n },\n {\n uri: Latin,\n descriptors: { unicodeRange: GOOGLE_FONTS_RANGES.LATIN, weight: \"500\" },\n },\n];\n", "import Virgil from \"./Virgil-Regular.woff2\";\n\nimport { type ExcalidrawFontFaceDescriptor } from \"../Fonts\";\n\nexport const VirgilFontFaces: ExcalidrawFontFaceDescriptor[] = [\n {\n uri: Virgil,\n },\n];\n", "// The following file content was generated with https://chinese-font.netlify.app/online-split,\n// but has been manully rewritten from `@font-face` rules into TS while leveraging FontFace API.\n\nimport _0 from \"./Xiaolai-Regular-09850c4077f3fffe707905872e0e2460.woff2\";\nimport _1 from \"./Xiaolai-Regular-7eb9fffd1aa890d07d0f88cc82e6cfe4.woff2\";\nimport _2 from \"./Xiaolai-Regular-60a3089806700d379f11827ee9843b6b.woff2\";\nimport _3 from \"./Xiaolai-Regular-6fe5c5973cc06f74b2387a631ea36b88.woff2\";\nimport _4 from \"./Xiaolai-Regular-b96d9226ce77ec94ceca043d712182e6.woff2\";\nimport _5 from \"./Xiaolai-Regular-6ae5b42180ad70b971c91e7eefb8eba2.woff2\";\nimport _6 from \"./Xiaolai-Regular-a4c34be6d42152e64b0df90bc4607f64.woff2\";\nimport _7 from \"./Xiaolai-Regular-c69f61a4ab18d0488c8d1fc12e7028e8.woff2\";\nimport _8 from \"./Xiaolai-Regular-e3fcf5180fd466c8915c4e8069491054.woff2\";\nimport _9 from \"./Xiaolai-Regular-c1f94158256bb1f3bf665b053d895af9.woff2\";\nimport _10 from \"./Xiaolai-Regular-544fc28abe2c5c30e62383fd4dac255f.woff2\";\nimport _11 from \"./Xiaolai-Regular-7197d6fda6cba7c3874c53d6381ca239.woff2\";\nimport _12 from \"./Xiaolai-Regular-70c2eb8d64e71a42a834eb857ea9df51.woff2\";\nimport _13 from \"./Xiaolai-Regular-069e77aac84590e2e991d0a0176d34f2.woff2\";\nimport _14 from \"./Xiaolai-Regular-41521fade99856108931b4768b1b2648.woff2\";\nimport _15 from \"./Xiaolai-Regular-a004ddfcb26e67bd6e678c8ed19e25ce.woff2\";\nimport _16 from \"./Xiaolai-Regular-04b718e5623574919c8b0dea5f301444.woff2\";\nimport _17 from \"./Xiaolai-Regular-7e4bde7e9c7f84cd34d8a845e384c746.woff2\";\nimport _18 from \"./Xiaolai-Regular-23686f7f29da6e8008c36dd3a80c83d6.woff2\";\nimport _19 from \"./Xiaolai-Regular-69c09cc5fa3e55c74fc4821f76909cc3.woff2\";\nimport _20 from \"./Xiaolai-Regular-25b7f38e18f035f96cb5e547bd2bd08c.woff2\";\nimport _21 from \"./Xiaolai-Regular-ba3de316d63c7e339987b16f41a0b879.woff2\";\nimport _22 from \"./Xiaolai-Regular-12b52b58eb3df36804b9a654ec9ee194.woff2\";\nimport _23 from \"./Xiaolai-Regular-b1220a3c61f85cc0408deedb4c5f57a2.woff2\";\nimport _24 from \"./Xiaolai-Regular-4535823663ad81405188a528d8f2b1a2.woff2\";\nimport _25 from \"./Xiaolai-Regular-3eaa538115d76932653c21d8dc28f207.woff2\";\nimport _26 from \"./Xiaolai-Regular-7e929f262f30c8ee78bf398150b1a7cd.woff2\";\nimport _27 from \"./Xiaolai-Regular-73e309718fd16cea44b4d54a33581811.woff2\";\nimport _28 from \"./Xiaolai-Regular-9eb5a99df4e76ac3363453ac9ca288b1.woff2\";\nimport _29 from \"./Xiaolai-Regular-3e63ed8162808a9e425ed80a8bc79114.woff2\";\nimport _30 from \"./Xiaolai-Regular-cb17fc3db95f6d139afc9d31a8e93293.woff2\";\nimport _31 from \"./Xiaolai-Regular-c8b71798409ccc126ee264a00aadcf21.woff2\";\nimport _32 from \"./Xiaolai-Regular-11c345711937f0ba4b8f7b6b919c8440.woff2\";\nimport _33 from \"./Xiaolai-Regular-e480d9c614742d05f0e78f274f1e69e6.woff2\";\nimport _34 from \"./Xiaolai-Regular-95429962233afd82db1c27df1500a28c.woff2\";\nimport _35 from \"./Xiaolai-Regular-2cf96d082d35ea3d8106851223ad0d16.woff2\";\nimport _36 from \"./Xiaolai-Regular-2d43040e86ff03ba677f6f9c04cd0805.woff2\";\nimport _37 from \"./Xiaolai-Regular-2a26d20a23b00898ce82f09d2ee47c3f.woff2\";\nimport _38 from \"./Xiaolai-Regular-a365e82ed54697a52f27adcea1315fe8.woff2\";\nimport _39 from \"./Xiaolai-Regular-f5d079153c99a25b9be5b8583c4cc8a7.woff2\";\nimport _40 from \"./Xiaolai-Regular-10a7ae9a371830a80c3d844acf1c02d7.woff2\";\nimport _41 from \"./Xiaolai-Regular-e4bca6cfa53e499cae0a6be4894a90e9.woff2\";\nimport _42 from \"./Xiaolai-Regular-60a41c7e1c68f22424e6d22df544bc82.woff2\";\nimport _43 from \"./Xiaolai-Regular-7ab2bed91166a9dca83a5ebfbe2a7f38.woff2\";\nimport _44 from \"./Xiaolai-Regular-670ba603758d94268e8606f240a42e12.woff2\";\nimport _45 from \"./Xiaolai-Regular-e656f091b9dc4709722c9f4b84d3c797.woff2\";\nimport _46 from \"./Xiaolai-Regular-15dc6d811c9cd078f9086a740d5a1038.woff2\";\nimport _47 from \"./Xiaolai-Regular-f0f13b5c60e0af5553bd359f5513be1b.woff2\";\nimport _48 from \"./Xiaolai-Regular-8c2f33cee3993174f7e87c28e4bf42ee.woff2\";\nimport _49 from \"./Xiaolai-Regular-761d05e3cd968cf574166867998ef06a.woff2\";\nimport _50 from \"./Xiaolai-Regular-642b26e2e5f5fb780b51b593dbc8c851.woff2\";\nimport _51 from \"./Xiaolai-Regular-5572b3513ba8df57a3d5d7303ee6b11b.woff2\";\nimport _52 from \"./Xiaolai-Regular-3c9de2ae0ea4bc91a510942dfa4be8d2.woff2\";\nimport _53 from \"./Xiaolai-Regular-671a2c20b1eb9e4ef8a192833940e319.woff2\";\nimport _54 from \"./Xiaolai-Regular-4dc6d5f188d5c96d44815cd1e81aa885.woff2\";\nimport _55 from \"./Xiaolai-Regular-ce4884f96f11589608b76b726a755803.woff2\";\nimport _56 from \"./Xiaolai-Regular-8f476c4c99813d57cbe6eca4727388ad.woff2\";\nimport _57 from \"./Xiaolai-Regular-5935a5775af3d5c6307ac667bd9ae74e.woff2\";\nimport _58 from \"./Xiaolai-Regular-79f007c1c6d07557120982951ea67998.woff2\";\nimport _59 from \"./Xiaolai-Regular-bafff7a14c27403dcc6cf1432e8ea836.woff2\";\nimport _60 from \"./Xiaolai-Regular-543fa46ace099a7099dad69123399400.woff2\";\nimport _61 from \"./Xiaolai-Regular-4ddc14ed3eb0c3e46364317dfc0144a3.woff2\";\nimport _62 from \"./Xiaolai-Regular-0fa55a080fcd0f9dc2e0b0058b793df8.woff2\";\nimport _63 from \"./Xiaolai-Regular-66493ba5a8367f2928812f446f47b56a.woff2\";\nimport _64 from \"./Xiaolai-Regular-57862b464a55b18c7bf234ce22907d73.woff2\";\nimport _65 from \"./Xiaolai-Regular-8d3bcabb847b56243b16afe62adaaf21.woff2\";\nimport _66 from \"./Xiaolai-Regular-2b77e8ebfb2367ab2662396a60e7d320.woff2\";\nimport _67 from \"./Xiaolai-Regular-0b5d723fdc4e249c140f0909e87d03b4.woff2\";\nimport _68 from \"./Xiaolai-Regular-cdbce89e82cc1ab53a2decbf5819278f.woff2\";\nimport _69 from \"./Xiaolai-Regular-739bc1a567439c7cffcd1614644593d2.woff2\";\nimport _70 from \"./Xiaolai-Regular-72252d73220fa3cd856677888cee1635.woff2\";\nimport _71 from \"./Xiaolai-Regular-08e0dc436ad0ad61ba5558db0674d762.woff2\";\nimport _72 from \"./Xiaolai-Regular-cf6ff4e0f491ca0cf3038187a997b9b4.woff2\";\nimport _73 from \"./Xiaolai-Regular-9cfb2a77a4e45025105ad29a1748b90d.woff2\";\nimport _74 from \"./Xiaolai-Regular-450da755d5bcb70906e1295e559b9602.woff2\";\nimport _75 from \"./Xiaolai-Regular-0986d134c05864f5025962eef9f994a0.woff2\";\nimport _76 from \"./Xiaolai-Regular-1ee544f0f1dac422545c505baa788992.woff2\";\nimport _77 from \"./Xiaolai-Regular-4806e761d750087c2d734fc64596eaff.woff2\";\nimport _78 from \"./Xiaolai-Regular-33432927cd87d40cfe393c7482bf221f.woff2\";\nimport _79 from \"./Xiaolai-Regular-be549ab72f0719d606a5c01e2c0219b6.woff2\";\nimport _80 from \"./Xiaolai-Regular-019d66dcad46dc156b162d267f981c20.woff2\";\nimport _81 from \"./Xiaolai-Regular-b5c1596551c256e0e9cf02028595b092.woff2\";\nimport _82 from \"./Xiaolai-Regular-e5f453bb04da18eed01675eeebd88bf8.woff2\";\nimport _83 from \"./Xiaolai-Regular-cf2cc71752631e579e35b0e423bf2638.woff2\";\nimport _84 from \"./Xiaolai-Regular-6f3256af8454371776bc46670d33cc65.woff2\";\nimport _85 from \"./Xiaolai-Regular-23f228f3999c01983860012330e4be08.woff2\";\nimport _86 from \"./Xiaolai-Regular-21430ee05a1248901da8d0de08744d47.woff2\";\nimport _87 from \"./Xiaolai-Regular-5330a2119a716e4e7224ed108b085dac.woff2\";\nimport _88 from \"./Xiaolai-Regular-cd145ce4a0ea18469358df53c207bc1b.woff2\";\nimport _89 from \"./Xiaolai-Regular-36925dfe329a45086cbb7fc5c20d45ac.woff2\";\nimport _90 from \"./Xiaolai-Regular-4bfaa8ffa64c5ee560aa2daba7c9cbd3.woff2\";\nimport _91 from \"./Xiaolai-Regular-112c051027b2d766c19a519f6ee1f4f7.woff2\";\nimport _92 from \"./Xiaolai-Regular-5b0ed6971aaab9c8ad563230bd5471a7.woff2\";\nimport _93 from \"./Xiaolai-Regular-98f2ad84457de7f3740d9920b8fa8667.woff2\";\nimport _94 from \"./Xiaolai-Regular-733171b4ffcd17ea1fe1c0ba627173bf.woff2\";\nimport _95 from \"./Xiaolai-Regular-684d65f1793cac449dde5d59cb3c47fb.woff2\";\nimport _96 from \"./Xiaolai-Regular-cbaaefaaf326668277aa24dfa93c4d28.woff2\";\nimport _97 from \"./Xiaolai-Regular-58fd02350d0bc52cf1ca3bb32ce9766e.woff2\";\nimport _98 from \"./Xiaolai-Regular-7ccce86603f80a099ddb0cb21d4ae3e3.woff2\";\nimport _99 from \"./Xiaolai-Regular-3717077e38f98d89eae729b6c14e56dc.woff2\";\nimport _100 from \"./Xiaolai-Regular-dbea1af6dcd9860be40c3d18254338f5.woff2\";\nimport _101 from \"./Xiaolai-Regular-4a0fdb40036e87b40aa08dd30584cb85.woff2\";\nimport _102 from \"./Xiaolai-Regular-0f626226ba1272e832aea87bafd9720e.woff2\";\nimport _103 from \"./Xiaolai-Regular-938d90c10ff8c20386af7f242c05d6b0.woff2\";\nimport _104 from \"./Xiaolai-Regular-b6d128682ee29e471486354d486a1b90.woff2\";\nimport _105 from \"./Xiaolai-Regular-e51ef413167c6e14e0c0fdcc585f2fc9.woff2\";\nimport _106 from \"./Xiaolai-Regular-9d81066dd2b337c938df6e90380a00dc.woff2\";\nimport _107 from \"./Xiaolai-Regular-20e7bf72fa05de9adf7dbcc7bf51dde6.woff2\";\nimport _108 from \"./Xiaolai-Regular-4095eb84ef3874e2600247bee0b04026.woff2\";\nimport _109 from \"./Xiaolai-Regular-4ee10ae43505e2e0bc62656ced49c0fa.woff2\";\nimport _110 from \"./Xiaolai-Regular-7494dc504ae00ee9cd0505f990f88c5d.woff2\";\nimport _111 from \"./Xiaolai-Regular-8de5b863cb50dfefdd07cb11c774d579.woff2\";\nimport _112 from \"./Xiaolai-Regular-3e1f8f654357353bf0e04ba5c34b5f7f.woff2\";\nimport _113 from \"./Xiaolai-Regular-2e33e8dc771ef5e1d9127d60a6b73679.woff2\";\nimport _114 from \"./Xiaolai-Regular-173945821411c09f70c95f98d590e697.woff2\";\nimport _115 from \"./Xiaolai-Regular-b358f7a51ece39a3247942b1feabdb29.woff2\";\nimport _116 from \"./Xiaolai-Regular-23ad2d71b280f00b1363b95b7bea94eb.woff2\";\nimport _117 from \"./Xiaolai-Regular-5882ffa04f32584d26109137e2da4352.woff2\";\nimport _118 from \"./Xiaolai-Regular-a203b91dad570bf05a58c3c3ddb529bf.woff2\";\nimport _119 from \"./Xiaolai-Regular-bd77e3c7f9e0b072d96af37f73d1aa32.woff2\";\nimport _120 from \"./Xiaolai-Regular-5a45d991244d4c7140217e1e5f5ca4f4.woff2\";\nimport _121 from \"./Xiaolai-Regular-f56414bf9bced67990def8660e306759.woff2\";\nimport _122 from \"./Xiaolai-Regular-583d166e56ba0de4b77eabb47ef67839.woff2\";\nimport _123 from \"./Xiaolai-Regular-7f855356ab893b0d2b9c1c83b8116f0e.woff2\";\nimport _124 from \"./Xiaolai-Regular-b57aaedfd8ebdf3931f25119dc6a5eb2.woff2\";\nimport _125 from \"./Xiaolai-Regular-b6fd38ca30869792244804b04bc058da.woff2\";\nimport _126 from \"./Xiaolai-Regular-452225341522a7942f0f6aab1a5c91a3.woff2\";\nimport _127 from \"./Xiaolai-Regular-866fa7613df6b3fd272bcfd4530c0bb9.woff2\";\nimport _128 from \"./Xiaolai-Regular-52a84a22fd1369bffeaf21da2d6158dc.woff2\";\nimport _129 from \"./Xiaolai-Regular-829615148e6357d826b9242eb7fbbd1e.woff2\";\nimport _130 from \"./Xiaolai-Regular-c99eda15fc26a2941579560f76c3a5cf.woff2\";\nimport _131 from \"./Xiaolai-Regular-395c35dd584b56b0789f58a0559beaf1.woff2\";\nimport _132 from \"./Xiaolai-Regular-203b0e569e3b14aac86a003dc3fa523e.woff2\";\nimport _133 from \"./Xiaolai-Regular-51a0e808bbc8361236ac521a119758a3.woff2\";\nimport _134 from \"./Xiaolai-Regular-6e092f71c1e634059ada0e52abadce67.woff2\";\nimport _135 from \"./Xiaolai-Regular-0f7fb1e0d5015bb1371343153ecf7ce3.woff2\";\nimport _136 from \"./Xiaolai-Regular-d0cf73942fea1c74edbdf0b3011f4656.woff2\";\nimport _137 from \"./Xiaolai-Regular-968cffdc8ee679da094e77ebf50f58ef.woff2\";\nimport _138 from \"./Xiaolai-Regular-7a07ddc0f0c0f5f4a9bad6ee3dda66b5.woff2\";\nimport _139 from \"./Xiaolai-Regular-ec181b795ac1fb5a50d700b6e996d745.woff2\";\nimport _140 from \"./Xiaolai-Regular-cfb211578629b7e8153b37240de6a9d5.woff2\";\nimport _141 from \"./Xiaolai-Regular-59e9ff77b0efaf684bc09274fb6908c9.woff2\";\nimport _142 from \"./Xiaolai-Regular-2adbc89c11e65905393d3dfc468b9d5b.woff2\";\nimport _143 from \"./Xiaolai-Regular-70e811fd7994e61f408c923de6ddd078.woff2\";\nimport _144 from \"./Xiaolai-Regular-c4a687ac4f0c2766eefc9f77ed99cddf.woff2\";\nimport _145 from \"./Xiaolai-Regular-51502f1206be09c565f1547c406e9558.woff2\";\nimport _146 from \"./Xiaolai-Regular-1fdc0c67ed57263a80fd108c1f6ccf24.woff2\";\nimport _147 from \"./Xiaolai-Regular-e11567fd2accf9957cd0d3c2be937d87.woff2\";\nimport _148 from \"./Xiaolai-Regular-20cc1bbf50e7efb442756cb605672c1f.woff2\";\nimport _149 from \"./Xiaolai-Regular-5d2898fbc097a7e24c6f38d80587621e.woff2\";\nimport _150 from \"./Xiaolai-Regular-ac9ceb44437becc3e9c4dbfebab7fc2d.woff2\";\nimport _151 from \"./Xiaolai-Regular-c16ed9740b85badf16e86ea782a3062f.woff2\";\nimport _152 from \"./Xiaolai-Regular-aa0d470430e6391eca720c7cfa44446f.woff2\";\nimport _153 from \"./Xiaolai-Regular-f2b54d4e7be0eaefe1c2c56836fa5368.woff2\";\nimport _154 from \"./Xiaolai-Regular-99a16ef6a64934d5781933dbd9c46b2e.woff2\";\nimport _155 from \"./Xiaolai-Regular-c40533fdf4cc57177b12803598af7e59.woff2\";\nimport _156 from \"./Xiaolai-Regular-91ddb2969bf2d31ba02ad82998d1314c.woff2\";\nimport _157 from \"./Xiaolai-Regular-774d4f764a1299da5d28ec2f2ffe0d69.woff2\";\nimport _158 from \"./Xiaolai-Regular-7718fe60986d8b42b1be9c5ace5ccf25.woff2\";\nimport _159 from \"./Xiaolai-Regular-aa5c9ca6cf4fba00433b7aa3fa10671a.woff2\";\nimport _160 from \"./Xiaolai-Regular-4f50e5136e136527280bc902c5817561.woff2\";\nimport _161 from \"./Xiaolai-Regular-093b9ef39a46ceae95a1df18a0a3a326.woff2\";\nimport _162 from \"./Xiaolai-Regular-a0ca5df4258213d7fc9fce80f65ce760.woff2\";\nimport _163 from \"./Xiaolai-Regular-d2666cbed13462c5dc36fa2f15c202ca.woff2\";\nimport _164 from \"./Xiaolai-Regular-1e6fd68f1f3902ce48ce8c69df385622.woff2\";\nimport _165 from \"./Xiaolai-Regular-87599f94b6cc129d505b375798d0d751.woff2\";\nimport _166 from \"./Xiaolai-Regular-06c77b8c66e51ed6c63ccb502dd8b8af.woff2\";\nimport _167 from \"./Xiaolai-Regular-13ae07ed2e272d26d59bc0691cd7117a.woff2\";\nimport _168 from \"./Xiaolai-Regular-353f33792a8f60dc69323ddf635a269e.woff2\";\nimport _169 from \"./Xiaolai-Regular-0facdf1ea213ba40261022f5d5ed4493.woff2\";\nimport _170 from \"./Xiaolai-Regular-f8ee5d36068a42b51d0e4a1116cfcec1.woff2\";\nimport _171 from \"./Xiaolai-Regular-79d494361ae093b69e74ee9dbe65bfd4.woff2\";\nimport _172 from \"./Xiaolai-Regular-74e2263a91439c25b91d5132ce9f4d62.woff2\";\nimport _173 from \"./Xiaolai-Regular-ee8bae97908d5147b423f77ad0d3c1bb.woff2\";\nimport _174 from \"./Xiaolai-Regular-56467a5c8840c4d23a60b2f935114848.woff2\";\nimport _175 from \"./Xiaolai-Regular-145aa02cdd91946e67dc934e1acffe75.woff2\";\nimport _176 from \"./Xiaolai-Regular-54acdfc2166ad7fcbd074f75fd4a56ba.woff2\";\nimport _177 from \"./Xiaolai-Regular-29cec36cd205b211da97acabaa62f055.woff2\";\nimport _178 from \"./Xiaolai-Regular-3756e81d3e149cf6099163ee79944fec.woff2\";\nimport _179 from \"./Xiaolai-Regular-8e9f97f01034820170065b2921b4fb5e.woff2\";\nimport _180 from \"./Xiaolai-Regular-13d2887ec8ee73c43acdabc52a05af7b.woff2\";\nimport _181 from \"./Xiaolai-Regular-72536a3d71b694a0d53dd90ddceae41e.woff2\";\nimport _182 from \"./Xiaolai-Regular-603aefd23e350ba7eb124273e3c9bcf1.woff2\";\nimport _183 from \"./Xiaolai-Regular-095c169f3314805276f603a362766abd.woff2\";\nimport _184 from \"./Xiaolai-Regular-9544732d2e62d1a429674f8ee41b5d3a.woff2\";\nimport _185 from \"./Xiaolai-Regular-d3716376641d615e2995605b29bca7b6.woff2\";\nimport _186 from \"./Xiaolai-Regular-5a1ce3117cfe90c48e8fb4a9a00f694d.woff2\";\nimport _187 from \"./Xiaolai-Regular-b7d203b051eff504ff59ddca7576b6a9.woff2\";\nimport _188 from \"./Xiaolai-Regular-4a38cc3e9cf104e69ba246d37f8cf135.woff2\";\nimport _189 from \"./Xiaolai-Regular-982b630266d87db93d2539affb1275c6.woff2\";\nimport _190 from \"./Xiaolai-Regular-9592bfc861f07bcb8d75c196b370e548.woff2\";\nimport _191 from \"./Xiaolai-Regular-a7accba310e821da5505f71c03b76bdb.woff2\";\nimport _192 from \"./Xiaolai-Regular-dac48066b5883d8b4551fc584f0c2a3e.woff2\";\nimport _193 from \"./Xiaolai-Regular-a1f916d6039285c4ffb900cd654e418f.woff2\";\nimport _194 from \"./Xiaolai-Regular-95bfd249da4902577b4b7d76ebdd0b44.woff2\";\nimport _195 from \"./Xiaolai-Regular-93fc8f28a33234bcadf1527cafabd502.woff2\";\nimport _196 from \"./Xiaolai-Regular-903bb6865f3452e2fda42e3a25547bc5.woff2\";\nimport _197 from \"./Xiaolai-Regular-4aca6a43e59aceee2166b0c7e4e85ef1.woff2\";\nimport _198 from \"./Xiaolai-Regular-24476a126f129212beb33f66853ea151.woff2\";\nimport _199 from \"./Xiaolai-Regular-1b611157cd46bb184d4fa4dae2d6a2b8.woff2\";\nimport _200 from \"./Xiaolai-Regular-56a32a7689abd0326e57c10c6c069bb4.woff2\";\nimport _201 from \"./Xiaolai-Regular-3cc70dbb64df5b21f1326cc24dee2195.woff2\";\nimport _202 from \"./Xiaolai-Regular-f6032fc06eb20480f096199713f70885.woff2\";\nimport _203 from \"./Xiaolai-Regular-e2ead7ea7da0437f085f42ffc05f8d13.woff2\";\nimport _204 from \"./Xiaolai-Regular-97f7f48ce90c9429bf32ae51469db74d.woff2\";\nimport _205 from \"./Xiaolai-Regular-24a21c1e4449222e8d1898d69ff3a404.woff2\";\nimport _206 from \"./Xiaolai-Regular-726303e0774b4e678bff8c2deb6ca603.woff2\";\nimport _207 from \"./Xiaolai-Regular-5a7fac4b8b23a6e4e5ba0c9bf1756c91.woff2\";\nimport _208 from \"./Xiaolai-Regular-2b7441d46298788ac94e610ffcc709b6.woff2\";\n\nimport { type ExcalidrawFontFaceDescriptor } from \"../Fonts\";\n\n/* Generated By cn-font-split@5.2.2 https://www.npmjs.com/package/cn-font-split\nCreateTime: Tue, 08 Oct 2024 18:34:44 GMT;\nOrigin File Name Table:\nfontFamily: Xiaolai SC\nfontSubfamily: Regular\npreferredFamily: \u5C0F\u8CF4\u5B57\u9AD4 SC\npostScriptFindFontName: \ncopyright: Copyright \u00A9 2020 LXGW\nuniqueID: Xiaolai SC:Version 3.11\nfullName: Xiaolai SC\nversion: Version 3.11;December 4, 2020;FontCreator 13.0.0.2613 64-bit\npostScriptName: XiaolaiSC\ntrademark: \u5C0F\u8D56\u5B57\u4F53 SC\ndesigner: Nozomi Seto \u702C\u6238\u306E\u305E\u307F\ndescription: This font was created using FontCreator from High-Logic.com\nlicense: This Font Software is licensed under the SIL Open Font License, Version 1.1. This Font Software is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the SIL Open Font License for the specific language, permissions and limitations governing your use of this Font Software.\nlicenseURL: http://scripts.sil.org/OFL\n */\n\n/**\n * The original font was modified with the following changes:\n * - removed non-CJK codepoints\n * - reduced any Hangul side-bearings to 40%\n * - centered in width of inproperly centered CJK codepoints\n */\n\nexport const XiaolaiFontFaces: ExcalidrawFontFaceDescriptor[] = [\n {\n uri: _0,\n descriptors: {\n unicodeRange:\n \"U+f9b8-fa6d,U+fe32,U+fe45-fe4f,U+ff02-ff0b,U+ff0d-ff1e,U+ff20-ff2a\",\n },\n },\n {\n uri: _1,\n descriptors: {\n unicodeRange:\n \"U+20dd-20de,U+25ef,U+ff2b-ffbe,U+ffc2-ffc7,U+ffca-ffcf,U+ffd2-ffd7,U+ffda-ffdc,U+ffe0-ffe6,U+ffe8-ffee\",\n },\n },\n { uri: _2, descriptors: { unicodeRange: \"U+d7eb-d7fb,U+f900-f9b7\" } },\n {\n uri: _3,\n descriptors: { unicodeRange: \"U+d6f2-d7a3,U+d7b0-d7c6,U+d7cb-d7ea\" },\n },\n { uri: _4, descriptors: { unicodeRange: \"U+d609-d6f1\" } },\n { uri: _5, descriptors: { unicodeRange: \"U+d520-d608\" } },\n { uri: _6, descriptors: { unicodeRange: \"U+d437-d51f\" } },\n { uri: _7, descriptors: { unicodeRange: \"U+d34e-d436\" } },\n { uri: _8, descriptors: { unicodeRange: \"U+d265-d34d\" } },\n { uri: _9, descriptors: { unicodeRange: \"U+d17c-d264\" } },\n { uri: _10, descriptors: { unicodeRange: \"U+d093-d17b\" } },\n { uri: _11, descriptors: { unicodeRange: \"U+cfaa-d092\" } },\n { uri: _12, descriptors: { unicodeRange: \"U+cec1-cfa9\" } },\n { uri: _13, descriptors: { unicodeRange: \"U+cdd8-cec0\" } },\n { uri: _14, descriptors: { unicodeRange: \"U+ccf1-cdd7\" } },\n { uri: _15, descriptors: { unicodeRange: \"U+cc08-ccf0\" } },\n { uri: _16, descriptors: { unicodeRange: \"U+cb43-cc07\" } },\n { uri: _17, descriptors: { unicodeRange: \"U+ca83-cb42\" } },\n { uri: _18, descriptors: { unicodeRange: \"U+c9a1-ca82\" } },\n { uri: _19, descriptors: { unicodeRange: \"U+c8b8-c9a0\" } },\n { uri: _20, descriptors: { unicodeRange: \"U+c7cf-c8b7\" } },\n { uri: _21, descriptors: { unicodeRange: \"U+c6e6-c7ce\" } },\n { uri: _22, descriptors: { unicodeRange: \"U+c5fd-c6e5\" } },\n { uri: _23, descriptors: { unicodeRange: \"U+c514-c5fc\" } },\n { uri: _24, descriptors: { unicodeRange: \"U+c42b-c513\" } },\n { uri: _25, descriptors: { unicodeRange: \"U+c341-c34e,U+c350-c42a\" } },\n { uri: _26, descriptors: { unicodeRange: \"U+c258-c340\" } },\n { uri: _27, descriptors: { unicodeRange: \"U+c16f-c257\" } },\n { uri: _28, descriptors: { unicodeRange: \"U+c086-c16e\" } },\n { uri: _29, descriptors: { unicodeRange: \"U+bf9d-c085\" } },\n { uri: _30, descriptors: { unicodeRange: \"U+beb4-bf9c\" } },\n { uri: _31, descriptors: { unicodeRange: \"U+bdcb-beb3\" } },\n { uri: _32, descriptors: { unicodeRange: \"U+bce2-bdca\" } },\n { uri: _33, descriptors: { unicodeRange: \"U+bbf9-bce1\" } },\n { uri: _34, descriptors: { unicodeRange: \"U+bb10-bbf8\" } },\n { uri: _35, descriptors: { unicodeRange: \"U+ba27-bb0f\" } },\n { uri: _36, descriptors: { unicodeRange: \"U+b93e-ba26\" } },\n { uri: _37, descriptors: { unicodeRange: \"U+b855-b93d\" } },\n { uri: _38, descriptors: { unicodeRange: \"U+b76c-b854\" } },\n { uri: _39, descriptors: { unicodeRange: \"U+b683-b76b\" } },\n { uri: _40, descriptors: { unicodeRange: \"U+b59a-b682\" } },\n { uri: _41, descriptors: { unicodeRange: \"U+b4b1-b599\" } },\n { uri: _42, descriptors: { unicodeRange: \"U+11fb-11ff,U+b3cd-b4b0\" } },\n { uri: _43, descriptors: { unicodeRange: \"U+11e6-11fa,U+b2f9-b3cc\" } },\n { uri: _44, descriptors: { unicodeRange: \"U+11d1-11e5,U+b225-b2f8\" } },\n { uri: _45, descriptors: { unicodeRange: \"U+11bc-11d0,U+b151-b224\" } },\n { uri: _46, descriptors: { unicodeRange: \"U+11a7-11bb,U+b07d-b150\" } },\n { uri: _47, descriptors: { unicodeRange: \"U+1191-11a6,U+afaa-b07c\" } },\n { uri: _48, descriptors: { unicodeRange: \"U+117c-1190,U+aed6-afa9\" } },\n { uri: _49, descriptors: { unicodeRange: \"U+1167-117b,U+ae02-aed5\" } },\n {\n uri: _50,\n descriptors: { unicodeRange: \"U+1152-115e,U+1160-1166,U+ad2d-ae01\" },\n },\n { uri: _51, descriptors: { unicodeRange: \"U+113d-1151,U+ac59-ad2c\" } },\n {\n uri: _52,\n descriptors: {\n unicodeRange:\n \"U+1100-113c,U+9f95-9f98,U+9f9c-9f9e,U+9fa1-9fce,U+9fd0,U+a960-a97c,U+ac00-ac58\",\n },\n },\n {\n uri: _53,\n descriptors: {\n unicodeRange:\n \"U+9771-9772,U+9775,U+9777-977b,U+977d-9784,U+9786-978a,U+978c,U+978e-9790,U+9793,U+9795-9797,U+9799-979f,U+97a1-97a2,U+97a4-97aa,U+97ac,U+97ae,U+97b0-97b1,U+97b3,U+97b5-97e5,U+97e8,U+97ee-97f2,U+97f4,U+97f7-982d\",\n },\n },\n {\n uri: _54,\n descriptors: {\n unicodeRange:\n \"U+9491,U+9496,U+9498,U+94c7,U+94cf,U+94d3-94d4,U+94da,U+94e6,U+94fb,U+951c,U+9520,U+9527,U+9533,U+953d,U+9543,U+9548,U+954b,U+9555,U+955a,U+9560,U+956e,U+9574-9575,U+9577-957e,U+9580-95e7,U+95ec,U+95ff,U+9607,U+9613,U+9618,U+961b,U+961e,U+9620,U+9623-9629,U+962b-962d,U+962f-9630,U+9637-963a,U+963e,U+9641,U+9643,U+964a,U+964e-964f,U+9651-9653,U+9656-965a,U+965c-965e,U+9660,U+9663,U+9665-9666,U+966b,U+966d-9671,U+9673,U+9678-9684,U+9687,U+9689-968a,U+968c,U+968e,U+9691-9693\",\n },\n },\n {\n uri: _55,\n descriptors: {\n unicodeRange:\n \"U+923c-9273,U+9275-928d,U+928f-92ad,U+92af-92c7,U+92c9-92ee\",\n },\n },\n {\n uri: _56,\n descriptors: {\n unicodeRange:\n \"U+9159,U+915b-915c,U+915f-9160,U+9166-9168,U+916b,U+916d,U+9173,U+917a-917c,U+9180-9184,U+9186,U+9188,U+918a,U+918e-918f,U+9193-9199,U+919c-91a1,U+91a4-91a9,U+91ab-91ac,U+91b0-91b3,U+91b6-91b9,U+91bb-91c6,U+91c8,U+91cb,U+91d0,U+91d2-91db,U+91dd-923b\",\n },\n },\n {\n uri: _57,\n descriptors: {\n unicodeRange:\n \"U+902b-902c,U+9030-9034,U+9037,U+9039-903a,U+903d,U+903f-9040,U+9043,U+9045-9046,U+9048-904c,U+904e,U+9054-9056,U+9059-905a,U+905c-9061,U+9064,U+9066-9067,U+9069-906c,U+906f-9073,U+9076-907c,U+907e,U+9081,U+9084-9087,U+9089-908a,U+908c-9090,U+9092,U+9094,U+9096,U+9098,U+909a,U+909c,U+909e-90a0,U+90a4-90a5,U+90a7-90a9,U+90ab,U+90ad,U+90b2,U+90b7,U+90bc-90bd,U+90bf-90c0,U+90c2-90c3,U+90c6,U+90c8-90c9,U+90cb-90cd,U+90d2,U+90d4-90d6,U+90d8-90da,U+90de-90e0,U+90e3-90e5,U+90e9-90ea,U+90ec,U+90ee,U+90f0-90f3,U+90f5-90f7,U+90f9-90fc,U+90ff-9101,U+9103,U+9105-9118,U+911a-911d,U+911f-9121,U+9124-912e,U+9130,U+9132-9138,U+913a-9142,U+9144-9145,U+9147-9148,U+9151,U+9153-9156,U+9158\",\n },\n },\n {\n uri: _58,\n descriptors: {\n unicodeRange:\n \"U+8f03-8f65,U+8f6a,U+8f80,U+8f8c,U+8f92,U+8f9d,U+8fa0-8fa2,U+8fa4-8fa7,U+8faa,U+8fac-8faf,U+8fb2-8fb5,U+8fb7-8fb8,U+8fba-8fbc,U+8fbf-8fc0,U+8fc3,U+8fc6,U+8fc9-8fcd,U+8fcf,U+8fd2,U+8fd6-8fd7,U+8fda,U+8fe0-8fe1,U+8fe3,U+8fe7,U+8fec,U+8fef,U+8ff1-8ff2,U+8ff4-8ff6,U+8ffa-8ffc,U+8ffe-8fff,U+9007-9008,U+900c,U+900e,U+9013,U+9015,U+9018-9019,U+901c,U+9023-9025,U+9027-902a\",\n },\n },\n {\n uri: _59,\n descriptors: {\n unicodeRange:\n \"U+8d03-8d1c,U+8d20,U+8d51-8d52,U+8d57,U+8d5f,U+8d65,U+8d68-8d6a,U+8d6c,U+8d6e-8d6f,U+8d71-8d72,U+8d78-8d80,U+8d82-8d83,U+8d86-8d89,U+8d8c-8d90,U+8d92-8d93,U+8d95-8d9e,U+8da0-8da2,U+8da4-8db0,U+8db2,U+8db6-8db7,U+8db9,U+8dbb,U+8dbd,U+8dc0-8dc2,U+8dc5,U+8dc7-8dca,U+8dcd,U+8dd0,U+8dd2-8dd5,U+8dd8-8dd9,U+8ddc,U+8de0-8de2,U+8de5-8de7,U+8de9,U+8ded-8dee,U+8df0-8df2,U+8df4,U+8df6,U+8dfc,U+8dfe-8e04,U+8e06-8e08,U+8e0b,U+8e0d-8e0e,U+8e10-8e13,U+8e15-8e1c,U+8e20-8e21,U+8e24-8e28,U+8e2b,U+8e2d,U+8e30,U+8e32-8e34,U+8e36-8e38,U+8e3b-8e3c,U+8e3e-8e3f,U+8e43,U+8e45-8e46\",\n },\n },\n {\n uri: _60,\n descriptors: {\n unicodeRange:\n \"U+8bea,U+8c09,U+8c1e,U+8c38-8c40,U+8c42-8c45,U+8c48,U+8c4a-8c4b,U+8c4d-8c54,U+8c56-8c59,U+8c5b-8c60,U+8c63-8c69,U+8c6c-8c72,U+8c74-8c77,U+8c7b-8c81,U+8c83-8c84,U+8c86-8c88,U+8c8b,U+8c8d-8c93,U+8c95-8c97,U+8c99-8d02\",\n },\n },\n {\n uri: _61,\n descriptors: {\n unicodeRange:\n \"U+8a64-8a78,U+8a7a-8a88,U+8a8b-8a92,U+8a94-8b06,U+8b08-8b1b\",\n },\n },\n {\n uri: _62,\n descriptors: {\n unicodeRange:\n \"U+8987-89c0,U+89c3,U+89cd,U+89d3-89d5,U+89d7-89d9,U+89db,U+89dd,U+89df-89e2,U+89e4,U+89e7-89ea,U+89ec-89ee,U+89f0-89f2,U+89f4-89ff,U+8a01-8a06,U+8a08-8a3d,U+8a3f-8a47,U+8a49-8a63\",\n },\n },\n {\n uri: _63,\n descriptors: {\n unicodeRange:\n \"U+87e3-87e4,U+87e6-87e9,U+87eb-87ed,U+87ef-87f8,U+87fa-87fd,U+87ff-8802,U+8804-8809,U+880b-8812,U+8814,U+8817-881a,U+881c-8820,U+8823-8831,U+8833-8838,U+883a-883b,U+883d-883f,U+8841-8843,U+8846-884b,U+884e-8853,U+8855-8856,U+8858,U+885a-8860,U+8866-8867,U+886a,U+886d,U+886f,U+8871,U+8873-8876,U+8878-887c,U+8880,U+8883,U+8886-8887,U+8889-888a,U+888c,U+888e-8891,U+8893-8895,U+8897-889b,U+889d-88a1,U+88a3,U+88a5-88aa,U+88ac,U+88ae-88b0,U+88b2-88b6,U+88b8-88bb\",\n },\n },\n {\n uri: _64,\n descriptors: {\n unicodeRange:\n \"U+86e7-86e8,U+86ea-86ec,U+86ef,U+86f5-86f7,U+86fa-86fd,U+86ff,U+8701,U+8704-8706,U+870b-870c,U+870e-8711,U+8714,U+8716,U+8719,U+871b,U+871d,U+871f-8720,U+8724,U+8726-8728,U+872a-872d,U+872f-8730,U+8732-8733,U+8735-8736,U+8738-873a,U+873c-873d,U+8740-8746,U+874a-874b,U+874d,U+874f-8752,U+8754-8756,U+8758,U+875a-875f,U+8761-8762,U+8766-876d,U+876f,U+8771-8773,U+8775,U+8777-877a,U+877f-8781,U+8784,U+8786-8787,U+8789-878a,U+878c,U+878e-8792,U+8794-8796,U+8798-879e,U+87a0-87a7,U+87a9-87aa,U+87ae,U+87b0-87b2,U+87b4,U+87b6-87b9,U+87bb-87bc,U+87be-87bf,U+87c1-87c5,U+87c7-87c9,U+87cc-87d0,U+87d4-87da,U+87dc-87df,U+87e1-87e2\",\n },\n },\n {\n uri: _65,\n descriptors: {\n unicodeRange:\n \"U+8604,U+8606-8610,U+8612-8615,U+8617-8626,U+8628,U+862a-8637,U+8639-863b,U+863d-864c,U+8652-8653,U+8655-8659,U+865b-865d,U+865f-8661,U+8663-866a,U+866d,U+866f-8670,U+8672-8678,U+8683-8689,U+868e-8692,U+8694,U+8696-869b,U+869e-86a2,U+86a5-86a6,U+86ab,U+86ad-86ae,U+86b2-86b3,U+86b7-86b9,U+86bb-86bf,U+86c1-86c3,U+86c5,U+86c8,U+86cc-86cd,U+86d2-86d3,U+86d5-86d7,U+86da,U+86dc-86dd,U+86e0-86e3,U+86e5-86e6\",\n },\n },\n {\n uri: _66,\n descriptors: {\n unicodeRange:\n \"U+8456,U+8458,U+845d-8460,U+8462,U+8464-8468,U+846a,U+846e-8470,U+8472,U+8474,U+8477,U+8479,U+847b-8481,U+8483-8486,U+848a,U+848d,U+848f-8496,U+8498,U+849a-849b,U+849d-84a0,U+84a2-84ae,U+84b0-84b1,U+84b3,U+84b5-84b7,U+84bb-84bc,U+84be,U+84c0,U+84c2-84c3,U+84c5-84c8,U+84cb-84cc,U+84ce-84cf,U+84d2,U+84d4-84d5,U+84d7-84dc,U+84de,U+84e1-84e2,U+84e4,U+84e7-84eb,U+84ed-84ef,U+84f1-84fb,U+84fd-84fe,U+8500-850b,U+850d-8510,U+8512,U+8514-8516,U+8518-8519,U+851b-851e,U+8520,U+8522-852a,U+852d-8536,U+853e-8542,U+8544-8547,U+854b-854f\",\n },\n },\n {\n uri: _67,\n descriptors: {\n unicodeRange:\n \"U+82c2-82c3,U+82c5-82c6,U+82c9,U+82d0,U+82d6,U+82d9-82da,U+82dd,U+82e2,U+82e7-82ea,U+82ec-82ee,U+82f0,U+82f2-82f3,U+82f5-82f6,U+82f8,U+82fa,U+82fc-8300,U+830a-830b,U+830d,U+8310,U+8312-8313,U+8316,U+8318-8319,U+831d-8326,U+8329-832a,U+832e,U+8330,U+8332,U+8337,U+833b,U+833d-833f,U+8341-8342,U+8344-8345,U+8348,U+834a-834e,U+8353,U+8355-8359,U+835d,U+8362,U+8370-8376,U+8379-837a,U+837e-8384,U+8387-8388,U+838a-838d,U+838f-8391,U+8394-8397,U+8399-839a,U+839d,U+839f,U+83a1-83a7,U+83ac-83af,U+83b5,U+83bb,U+83be-83bf,U+83c2-83c4,U+83c6,U+83c8-83c9,U+83cb,U+83cd-83ce,U+83d0-83d3,U+83d5,U+83d7,U+83d9-83db,U+83de,U+83e2-83e4,U+83e6-83e8,U+83eb-83ef,U+83f3-83f7,U+83fa-83fc,U+83fe-8400,U+8402,U+8405,U+8407-840a,U+8410,U+8412-8417,U+8419-841b,U+841e-8423,U+8429-8430,U+8432-8437,U+8439-843b,U+843e-8445,U+8447-8450,U+8452-8455\",\n },\n },\n {\n uri: _68,\n descriptors: {\n unicodeRange:\n \"U+81a4-81a5,U+81a7,U+81a9,U+81ab-81b2,U+81b4-81b9,U+81bc-81bf,U+81c4-81c5,U+81c7-81c9,U+81cb,U+81cd-81e2,U+81e4-81e6,U+81e8-81e9,U+81eb,U+81ee-81f2,U+81f5-81fa,U+81fd,U+81ff,U+8203,U+8207-820b,U+820e-820f,U+8211,U+8213,U+8215-821a,U+821d,U+8220,U+8224-8227,U+8229,U+822e,U+8232,U+823a,U+823c-823d,U+823f-8243,U+8245-8246,U+8248,U+824a,U+824c-824e,U+8250-8257,U+8259,U+825b-825e,U+8260-8267,U+8269-826d,U+8271,U+8275-8278,U+827b-827c,U+8280-8281,U+8283,U+8285-8287,U+8289,U+828c,U+8290,U+8293-8296,U+829a-829b,U+829e,U+82a0,U+82a2-82a3,U+82a7,U+82b2,U+82b5-82b6,U+82ba-82bc,U+82bf-82c0\",\n },\n },\n {\n uri: _69,\n descriptors: {\n unicodeRange:\n \"U+8059,U+805b-8068,U+806b-8070,U+8072-807e,U+8081-8082,U+8085,U+8088,U+808a,U+808d-8092,U+8094-8095,U+8097,U+8099,U+809e,U+80a3,U+80a6-80a8,U+80ac,U+80b0,U+80b3,U+80b5-80b6,U+80b8-80b9,U+80bb,U+80c5,U+80c7-80cb,U+80cf-80d5,U+80d8,U+80df-80e0,U+80e2-80e3,U+80e6,U+80ee,U+80f5,U+80f7,U+80f9,U+80fb,U+80fe-8101,U+8103-8105,U+8107-8108,U+810b-810c,U+8115,U+8117,U+8119,U+811b-811d,U+811f-812b,U+812d-812e,U+8130,U+8133-8135,U+8137,U+8139-813d,U+813f-8145,U+8147,U+8149,U+814d-814f,U+8152,U+8156-8158,U+815b-815f,U+8161-8164,U+8166,U+8168,U+816a-816c,U+816f,U+8172-8173,U+8175-8178,U+8181,U+8183-8187,U+8189,U+818b-818e,U+8190,U+8192-8197,U+8199-819a,U+819e-81a2\",\n },\n },\n {\n uri: _70,\n descriptors: {\n unicodeRange:\n \"U+7f3c-7f41,U+7f43,U+7f46-7f4f,U+7f52-7f53,U+7f56,U+7f59,U+7f5b-7f5e,U+7f60,U+7f63-7f67,U+7f6b-7f6d,U+7f6f-7f70,U+7f73,U+7f75-7f78,U+7f7a-7f7d,U+7f7f-7f80,U+7f82-7f89,U+7f8b,U+7f8d,U+7f8f-7f93,U+7f95-7f99,U+7f9b-7f9c,U+7fa0,U+7fa2-7fa3,U+7fa5-7fa6,U+7fa8-7fae,U+7fb1,U+7fb3-7fb7,U+7fba-7fbb,U+7fbe,U+7fc0,U+7fc2-7fc4,U+7fc6-7fc9,U+7fcb,U+7fcd,U+7fcf-7fd3,U+7fd6-7fd7,U+7fd9-7fde,U+7fe2-7fe4,U+7fe7-7fe8,U+7fea-7fed,U+7fef,U+7ff2,U+7ff4-7ffa,U+7ffd-7fff,U+8002,U+8007-800a,U+800e-800f,U+8011,U+8013,U+801a-801b,U+801d-801f,U+8021,U+8023-8024,U+802b-8030,U+8032,U+8034,U+8039-803a,U+803c,U+803e,U+8040-8041,U+8044-8045,U+8047-8049,U+804e-8051,U+8053,U+8055-8057\",\n },\n },\n {\n uri: _71,\n descriptors: {\n unicodeRange:\n \"U+7cd8,U+7cda-7cdb,U+7cdd-7cde,U+7ce1-7ce7,U+7ce9-7cee,U+7cf0-7cf7,U+7cf9-7cfa,U+7cfc-7d09,U+7d0b-7d1f,U+7d21,U+7d23-7d26,U+7d28-7d2a,U+7d2c-7d2e,U+7d30-7d6d,U+7d6f-7d76,U+7d78-7d94\",\n },\n },\n {\n uri: _72,\n descriptors: {\n unicodeRange:\n \"U+7afe,U+7b00-7b02,U+7b05,U+7b07,U+7b09,U+7b0c-7b0e,U+7b10,U+7b12-7b13,U+7b16-7b18,U+7b1a,U+7b1c-7b1d,U+7b1f,U+7b21-7b23,U+7b27,U+7b29,U+7b2d,U+7b2f-7b30,U+7b32,U+7b34-7b37,U+7b39,U+7b3b,U+7b3d,U+7b3f-7b44,U+7b46,U+7b48,U+7b4a,U+7b4d-7b4e,U+7b53,U+7b55,U+7b57,U+7b59,U+7b5c,U+7b5e-7b5f,U+7b61,U+7b63-7b6d,U+7b6f-7b70,U+7b73-7b74,U+7b76,U+7b78,U+7b7a,U+7b7c-7b7d,U+7b7f,U+7b81-7b84,U+7b86-7b8c,U+7b8e-7b8f,U+7b91-7b93,U+7b96,U+7b98-7b9b,U+7b9e-7ba0,U+7ba3-7ba5,U+7bae-7bb0,U+7bb2-7bb3,U+7bb5-7bb7,U+7bb9-7bc0,U+7bc2-7bc5,U+7bc8-7bcb,U+7bcd-7bd0,U+7bd2,U+7bd4-7bd8,U+7bdb-7bdc,U+7bde-7be0,U+7be2-7be4,U+7be7-7be9,U+7beb-7bed,U+7bef-7bf0,U+7bf2-7bf6,U+7bf8-7bfb,U+7bfd,U+7bff-7c06,U+7c08-7c0a,U+7c0d-7c0e,U+7c10-7c13\",\n },\n },\n {\n uri: _73,\n descriptors: {\n unicodeRange:\n \"U+7a10-7a13,U+7a15-7a16,U+7a18-7a19,U+7a1b-7a1d,U+7a1f,U+7a21-7a22,U+7a24-7a32,U+7a34-7a36,U+7a38,U+7a3a,U+7a3e,U+7a40-7a45,U+7a47-7a50,U+7a52-7a56,U+7a58-7a6f,U+7a71-7a73,U+7a75,U+7a7b-7a7e,U+7a82,U+7a85,U+7a87,U+7a89-7a8c,U+7a8e-7a90,U+7a93-7a94,U+7a99-7a9b,U+7a9e,U+7aa1-7aa4,U+7aa7,U+7aa9-7aab,U+7aae-7ab2,U+7ab4-7abe,U+7ac0-7aca,U+7acc-7ad5,U+7ad7-7ad8,U+7ada-7add,U+7ae1-7ae2,U+7ae4,U+7ae7-7aec,U+7aee,U+7af0-7af8,U+7afb-7afc\",\n },\n },\n {\n uri: _74,\n descriptors: {\n unicodeRange:\n \"U+790d-7912,U+7914-791d,U+791f-7923,U+7925-7933,U+7935-7939,U+793d,U+793f,U+7942-7945,U+7947,U+794a-7952,U+7954-7955,U+7958-7959,U+7961,U+7963-7964,U+7966,U+7969-796c,U+796e,U+7970-7976,U+7979,U+797b-797f,U+7982-7983,U+7986-7989,U+798b-798e,U+7990-7999,U+799b-79a6,U+79a8-79b2,U+79b4-79b8,U+79bc,U+79bf,U+79c2,U+79c4-79c5,U+79c7-79c8,U+79ca,U+79cc,U+79ce-79d0,U+79d3-79d4,U+79d6-79d7,U+79d9-79de,U+79e0-79e2,U+79e5,U+79e8,U+79ea,U+79ec,U+79ee,U+79f1-79f7,U+79f9-79fa,U+79fc,U+79fe-79ff,U+7a01,U+7a04-7a05,U+7a07-7a0a,U+7a0c,U+7a0f\",\n },\n },\n {\n uri: _75,\n descriptors: {\n unicodeRange:\n \"U+77d8-77da,U+77dd-77e1,U+77e4,U+77e6,U+77e8,U+77ea,U+77ef-77f2,U+77f4-77f5,U+77f7,U+77f9-77fc,U+7803-7808,U+780a-780b,U+780e-7810,U+7813,U+7815,U+7819,U+781b,U+781e,U+7820-7822,U+7824,U+7828,U+782a-782b,U+782e-782f,U+7831-7833,U+7835-7836,U+783d,U+783f,U+7841-7844,U+7846,U+7848-784b,U+784d,U+784f,U+7851,U+7853-7854,U+7858-785c,U+785e-7869,U+786f-7876,U+7878-787b,U+787d-7886,U+7888,U+788a-788b,U+788f-7890,U+7892,U+7894-7896,U+7899,U+789d-789e,U+78a0,U+78a2,U+78a4,U+78a6,U+78a8-78af,U+78b5-78b8,U+78ba-78bd,U+78bf-78c0,U+78c2-78c4,U+78c6-78c8,U+78cc-78cf,U+78d1-78d3,U+78d6-78d8,U+78da-78e7,U+78e9-78eb,U+78ed-78f1,U+78f3,U+78f5-78f6,U+78f8-78f9,U+78fb-7900,U+7902-7904,U+7906-790c\",\n },\n },\n {\n uri: _76,\n descriptors: {\n unicodeRange:\n \"U+76af-76b0,U+76b3,U+76b5-76be,U+76c0-76c1,U+76c3-76c4,U+76c7,U+76c9,U+76cb-76cc,U+76d3,U+76d5,U+76d9-76da,U+76dc-76de,U+76e0-76e4,U+76e6-76ed,U+76f0,U+76f3,U+76f5-76f7,U+76fa-76fb,U+76fd,U+76ff-7703,U+7705-7706,U+770a,U+770c,U+770e-7718,U+771b-771e,U+7721,U+7723-7725,U+7727,U+772a-772c,U+772e,U+7730-7734,U+7739,U+773b,U+773d-773f,U+7742,U+7744-7746,U+7748-774f,U+7752-7759,U+775c-7760,U+7764,U+7767,U+7769-776a,U+776d-7778,U+777a-777c,U+7781-7783,U+7786-778b,U+778f-7790,U+7793-779e,U+77a1,U+77a3-77a4,U+77a6,U+77a8,U+77ab,U+77ad-77af,U+77b1-77b2,U+77b4,U+77b6-77ba,U+77bc,U+77be,U+77c0-77cc,U+77ce-77d6\",\n },\n },\n {\n uri: _77,\n descriptors: {\n unicodeRange:\n \"U+7589-758a,U+758c-758e,U+7590,U+7593,U+7595,U+7598,U+759b-759c,U+759e,U+75a2,U+75a6-75aa,U+75ad,U+75b6-75b7,U+75ba-75bb,U+75bf-75c1,U+75c6,U+75cb-75cc,U+75ce-75d1,U+75d3,U+75d7,U+75d9-75da,U+75dc-75dd,U+75df-75e1,U+75e5,U+75e9,U+75ec-75ef,U+75f2-75f3,U+75f5-75f8,U+75fa-75fb,U+75fd-75fe,U+7602,U+7604,U+7606-7609,U+760b,U+760d-760f,U+7611-7614,U+7616,U+761a,U+761c-761e,U+7621,U+7623,U+7627-7628,U+762c,U+762e-762f,U+7631-7632,U+7636-7637,U+7639-763b,U+763d,U+7641-7642,U+7644-764b,U+764e-7653,U+7655,U+7657-765b,U+765d,U+765f-7662,U+7664-766a,U+766c-766e,U+7670-7677,U+7679-767a,U+767c,U+767f-7681,U+7683,U+7685,U+7689-768a,U+768c-768d,U+768f-7690,U+7692,U+7694-7695,U+7697-7698,U+769a-76a3,U+76a5-76ad\",\n },\n },\n {\n uri: _78,\n descriptors: {\n unicodeRange:\n \"U+7492-749b,U+749d,U+749f-74a6,U+74aa-74b9,U+74bb-74d1,U+74d3-74db,U+74dd,U+74df,U+74e1,U+74e5,U+74e7-74ed,U+74f0-74f3,U+74f5,U+74f8-74fe,U+7500-7503,U+7505-750c,U+750e,U+7510,U+7512,U+7514-7517,U+751b,U+751d-751e,U+7520-7524,U+7526-7527,U+752a,U+752e,U+7534,U+7536,U+7539,U+753c-753d,U+753f,U+7541-7544,U+7546-7547,U+7549-754a,U+754d,U+7550-7553,U+7555-7558,U+755d-7564,U+7567-7569,U+756b-7571,U+7573,U+7575-7577,U+757a-757e,U+7580-7582,U+7584-7585,U+7587-7588\",\n },\n },\n {\n uri: _79,\n descriptors: {\n unicodeRange:\n \"U+7372-737d,U+737f-7383,U+7385-7386,U+7388,U+738a,U+738c-738d,U+738f-7390,U+7392-7395,U+7397-739a,U+739c-739e,U+73a0-73a1,U+73a3-73a8,U+73aa,U+73ac-73ad,U+73b1,U+73b4-73b6,U+73b8-73b9,U+73bc-73bf,U+73c1,U+73c3-73c7,U+73cb-73cc,U+73ce,U+73d2-73d8,U+73da-73dd,U+73df,U+73e1-73e4,U+73e6,U+73e8,U+73ea-73ec,U+73ee-73f1,U+73f3-7402,U+7404,U+7407-7408,U+740b-740e,U+7411-7419,U+741c-7421,U+7423-7424,U+7427,U+7429,U+742b,U+742d,U+742f,U+7431-7432,U+7437-743b,U+743d-7440,U+7442-7454,U+7456,U+7458,U+745d,U+7460-746c,U+746e-746f,U+7471-7475,U+7478-747d,U+747f,U+7482,U+7484-7486,U+7488-748a,U+748c-748d,U+748f,U+7491\",\n },\n },\n {\n uri: _80,\n descriptors: {\n unicodeRange:\n \"U+7054-705d,U+705f-706a,U+706e,U+7071-7074,U+7077,U+7079-707b,U+707d,U+7081-7084,U+7086-7088,U+708b-708d,U+708f-7091,U+7093,U+7097-7098,U+709a-709b,U+709e-70aa,U+70b0,U+70b2,U+70b4-70b6,U+70ba,U+70be-70bf,U+70c4-70c7,U+70c9,U+70cb-70d7,U+70da,U+70dc-70de,U+70e0-70e3,U+70e5,U+70ea,U+70ee,U+70f0-70f6,U+70f8,U+70fa-70fc,U+70fe-7108,U+710b-710f,U+7111-7112,U+7114,U+7117,U+711b-7125,U+7127-712e,U+7132-7135,U+7137-7144,U+7146-7149,U+714b,U+714d,U+714f-715b,U+715d,U+715f-7163,U+7165,U+7169-716d,U+716f-7171,U+7174-7177\",\n },\n },\n {\n uri: _81,\n descriptors: {\n unicodeRange:\n \"U+722e-722f,U+7232-7234,U+723a,U+723c,U+723e,U+7240-7246,U+7249-724b,U+724e-7251,U+7253-7255,U+7257-7258,U+725a,U+725c,U+725e,U+7260,U+7263-7265,U+7268,U+726a-726d,U+7270-7271,U+7273-7274,U+7276-7278,U+727b-727d,U+7282-7283,U+7285-7289,U+728c,U+728e,U+7290-7291,U+7293-729e,U+72a0-72ab,U+72ae,U+72b1-72b3,U+72b5,U+72ba-72c0,U+72c5-72c7,U+72c9-72cc,U+72cf,U+72d1,U+72d3-72d6,U+72d8,U+72da-72dd,U+72df,U+72e2-72e7,U+72ea-72eb,U+72f5-72f6,U+72f9,U+72fd-7300,U+7302,U+7304-7309,U+730b-730d,U+730f-7312,U+7314,U+7318-731a,U+731f-7320,U+7323-7324,U+7326-7328,U+732d,U+732f-7330,U+7332-7333,U+7335-7336,U+733a-733d,U+7340-734c,U+734e-734f,U+7351,U+7353-7356,U+7358-735f,U+7361-736b,U+736e,U+7370-7371\",\n },\n },\n {\n uri: _82,\n descriptors: {\n unicodeRange:\n \"U+6ec5-6ec6,U+6ec8-6eca,U+6ecc-6ece,U+6ed0,U+6ed2,U+6ed6,U+6ed8-6ed9,U+6edb-6edd,U+6ee3,U+6ee7,U+6eea-6ef3,U+6ef5-6ef8,U+6efa-6f01,U+6f03-6f05,U+6f07-6f08,U+6f0a-6f0e,U+6f10-6f12,U+6f16-6f1f,U+6f21-6f23,U+6f25-6f28,U+6f2c,U+6f2e,U+6f30,U+6f32,U+6f34-6f35,U+6f37-6f3d,U+6f3f-6f45,U+6f48-6f4a,U+6f4c,U+6f4e-6f57,U+6f59-6f5b,U+6f5d,U+6f5f-6f61,U+6f63-6f65,U+6f67-6f6c,U+6f6f-6f71,U+6f73,U+6f75-6f77,U+6f79,U+6f7b,U+6f7d-6f83,U+6f85-6f87,U+6f8a-6f8b,U+6f8f-6f9b,U+6f9d-6fa0,U+6fa2-6fa6,U+6fa8-6fb1\",\n },\n },\n {\n uri: _83,\n descriptors: {\n unicodeRange:\n \"U+6d73,U+6d75-6d76,U+6d79-6d7b,U+6d7d-6d81,U+6d83-6d84,U+6d86-6d87,U+6d8a-6d8b,U+6d8d,U+6d8f-6d90,U+6d92,U+6d96-6d9a,U+6d9c,U+6da2,U+6da5,U+6dac-6dad,U+6db0-6db1,U+6db3-6db4,U+6db6-6db7,U+6db9-6dbe,U+6dc1-6dc3,U+6dc8-6dca,U+6dcd-6dd0,U+6dd2-6dd5,U+6dd7,U+6dda-6ddc,U+6ddf,U+6de2-6de3,U+6de5,U+6de7-6dea,U+6ded,U+6def-6df0,U+6df2,U+6df4-6df6,U+6df8,U+6dfa,U+6dfd-6e04,U+6e06-6e09,U+6e0b,U+6e0f,U+6e12-6e13,U+6e15,U+6e18-6e19,U+6e1b-6e1c,U+6e1e-6e1f,U+6e22,U+6e26-6e28,U+6e2a,U+6e2c,U+6e2e,U+6e30-6e31,U+6e33,U+6e35-6e37,U+6e39,U+6e3b-6e42,U+6e45-6e4c,U+6e4f-6e52,U+6e55,U+6e57,U+6e59-6e5a,U+6e5c-6e5e,U+6e60-6e6a,U+6e6c-6e6d,U+6e6f-6e7d,U+6e80-6e82,U+6e84,U+6e87-6e88,U+6e8a-6e8e,U+6e91-6e97,U+6e99-6e9b,U+6e9d-6e9e,U+6ea0-6ea1,U+6ea3-6ea4,U+6ea6,U+6ea8-6ea9,U+6eab-6eae,U+6eb0,U+6eb3,U+6eb5,U+6eb8-6eb9,U+6ebc,U+6ebe-6ec0,U+6ec3-6ec4\",\n },\n },\n {\n uri: _84,\n descriptors: {\n unicodeRange:\n \"U+6bbb-6bbe,U+6bc0,U+6bc3-6bc4,U+6bc6-6bca,U+6bcc,U+6bce,U+6bd0-6bd1,U+6bd8,U+6bda,U+6bdc-6be0,U+6be2-6be9,U+6bec-6bee,U+6bf0-6bf2,U+6bf4,U+6bf6-6bf8,U+6bfa-6bfc,U+6bfe-6c04,U+6c08-6c0c,U+6c0e,U+6c12,U+6c17,U+6c1c-6c1e,U+6c20,U+6c23,U+6c25,U+6c2b-6c2d,U+6c31,U+6c33,U+6c36-6c37,U+6c39-6c3c,U+6c3e-6c3f,U+6c43-6c45,U+6c48,U+6c4b-6c4f,U+6c51-6c53,U+6c56,U+6c58-6c5a,U+6c62-6c63,U+6c65-6c67,U+6c6b-6c6f,U+6c71,U+6c73,U+6c75,U+6c77-6c78,U+6c7a-6c7c,U+6c7f-6c80,U+6c84,U+6c87,U+6c8a-6c8b,U+6c8d-6c8e,U+6c91-6c92,U+6c95-6c98,U+6c9a,U+6c9c-6c9e,U+6ca0,U+6ca2,U+6ca8,U+6cac,U+6caf-6cb0,U+6cb4-6cb7,U+6cba,U+6cc0-6cc3,U+6cc6-6cc8,U+6ccb,U+6ccd-6ccf,U+6cd1-6cd2,U+6cd8-6cda,U+6cdc-6cdd,U+6cdf,U+6ce4,U+6ce6-6ce7,U+6ce9,U+6cec-6ced,U+6cf2,U+6cf4,U+6cf9,U+6cff-6d00,U+6d02-6d03,U+6d05-6d06,U+6d08-6d0a,U+6d0d,U+6d0f-6d11,U+6d13-6d16,U+6d18,U+6d1c-6d1d,U+6d1f-6d24,U+6d26,U+6d28-6d29,U+6d2c-6d2d,U+6d2f-6d30,U+6d34,U+6d36-6d38,U+6d3a,U+6d3f-6d40,U+6d42,U+6d44,U+6d49,U+6d4c,U+6d50,U+6d55-6d58,U+6d5b,U+6d5d,U+6d5f,U+6d61-6d62,U+6d64-6d65,U+6d67-6d68,U+6d6b-6d6d,U+6d70-6d72\",\n },\n },\n {\n uri: _85,\n descriptors: {\n unicodeRange:\n \"U+6967-696a,U+696c-696d,U+696f-6970,U+6972-6976,U+697a-697b,U+697d-697f,U+6981,U+6983,U+6985,U+698a-698c,U+698e-6993,U+6996-6997,U+6999-699a,U+699d-69a6,U+69a9-69aa,U+69ac,U+69ae-69b0,U+69b2-69b3,U+69b5-69b6,U+69b8-69ba,U+69bc-69c0,U+69c2-69c9,U+69cb,U+69cd,U+69cf,U+69d1-69d3,U+69d5-69da,U+69dc-69de,U+69e1-69ec,U+69ee-69f1,U+69f3-69fc,U+69fe,U+6a00-6a09,U+6a0b-6a16,U+6a19-6a1e,U+6a20,U+6a22-6a27,U+6a29,U+6a2b-6a2e,U+6a30,U+6a32-6a34,U+6a36-6a3c,U+6a3f-6a43,U+6a45-6a46,U+6a48-6a4a\",\n },\n },\n {\n uri: _86,\n descriptors: {\n unicodeRange:\n \"U+6830-6831,U+6834-6836,U+683a-683b,U+683f,U+6847,U+684b,U+684d,U+684f,U+6852,U+6856-685f,U+686a,U+686c-6873,U+6875,U+6878-6880,U+6882,U+6884,U+6887-688e,U+6890-6892,U+6894-6896,U+6898-68a1,U+68a3-68a5,U+68a9-68ac,U+68ae,U+68b1-68b2,U+68b4,U+68b6-68bf,U+68c1,U+68c3-68c8,U+68ca,U+68cc,U+68ce-68d1,U+68d3-68d4,U+68d6-68d7,U+68d9,U+68db-68df,U+68e1-68e2,U+68e4-68ed,U+68ef,U+68f2-68f4,U+68f6-68f8,U+68fb,U+68fd-6900,U+6902-6904,U+6906-690a,U+690c,U+690f,U+6911,U+6913-691e,U+6921-6923,U+6925-692c,U+692e-692f,U+6931-6933,U+6935-6938,U+693a-693c,U+693e,U+6940-6941,U+6943-6953,U+6955-6956,U+6958-6959,U+695b-695c,U+695f,U+6961-6962,U+6964-6965\",\n },\n },\n {\n uri: _87,\n descriptors: {\n unicodeRange:\n \"U+66b8,U+66ba-66bd,U+66bf-66d8,U+66da,U+66de-66e5,U+66e7-66e8,U+66ea-66ef,U+66f1,U+66f5-66f6,U+66f8,U+66fa-66fb,U+66fd,U+6701-6707,U+670c,U+670e-670f,U+6711-6713,U+6716,U+6718-671a,U+671c,U+671e,U+6720-6725,U+6727,U+6729,U+672e,U+6730,U+6732-6733,U+6736-6739,U+673b-673c,U+673e-673f,U+6741,U+6744-6745,U+6747,U+674a-674b,U+674d,U+6752,U+6754-6755,U+6757-675b,U+675d,U+6762-6764,U+6766-6767,U+676b-676c,U+676e,U+6771,U+6774,U+6776,U+6778-677b,U+677d,U+6780,U+6782-6783,U+6785-6786,U+6788,U+678a,U+678c-678f,U+6791-6794,U+6796,U+6799,U+679b,U+679f-67a1,U+67a4,U+67a6,U+67a9,U+67ac,U+67ae,U+67b1-67b2,U+67b4,U+67b9-67c0,U+67c2,U+67c5-67ce,U+67d5-67d7,U+67db,U+67df,U+67e1,U+67e3-67e4,U+67e6-67e8,U+67ea-67eb,U+67ed-67ee,U+67f2,U+67f5-67fc,U+67fe,U+6801-6804,U+6806,U+680d,U+6810,U+6812,U+6814-6815,U+6818-681c,U+681e-6820,U+6822-6828,U+682b-682f\",\n },\n },\n {\n uri: _88,\n descriptors: {\n unicodeRange:\n \"U+6569-656a,U+656d-656f,U+6571,U+6573,U+6575-6576,U+6578-6586,U+6588-658a,U+658d-658f,U+6592,U+6594-6596,U+6598,U+659a,U+659d-659e,U+65a0,U+65a2-65a3,U+65a6,U+65a8,U+65aa,U+65ac,U+65ae,U+65b1-65b8,U+65ba-65bb,U+65be-65c0,U+65c2,U+65c7-65ca,U+65cd,U+65d0-65d1,U+65d3-65d5,U+65d8-65df,U+65e1,U+65e3-65e4,U+65ea-65eb,U+65f2-65f5,U+65f8-65f9,U+65fb-65ff,U+6601,U+6604-6605,U+6607-6609,U+660b,U+660d,U+6610-6612,U+6616-6618,U+661a-661c,U+661e,U+6621-6624,U+6626,U+6629-662c,U+662e,U+6630,U+6632-6633,U+6637-663b,U+663d,U+663f-6640,U+6642,U+6644-664a,U+664d-664e,U+6650-6651,U+6658-6659,U+665b-665e,U+6660,U+6662-6663,U+6665,U+6667,U+6669-666d,U+6671-6673,U+6675,U+6678-6679,U+667b-667d,U+667f-6681,U+6683,U+6685-6686,U+6688-668b,U+668d-6690,U+6692-6695,U+6698-669c,U+669e-66a6,U+66a9-66ad,U+66af-66b3,U+66b5-66b7\",\n },\n },\n {\n uri: _89,\n descriptors: {\n unicodeRange:\n \"U+5f30,U+5f32-5f38,U+5f3b,U+5f3d-5f3f,U+5f41-5f4f,U+5f51,U+5f54,U+5f59-5f5c,U+5f5e-5f60,U+5f63,U+5f65,U+5f67-5f68,U+5f6b,U+5f6e-5f6f,U+5f72,U+5f74-5f76,U+5f78,U+5f7a,U+5f7d-5f7f,U+5f83,U+5f86,U+5f8d-5f8f,U+5f91,U+5f93-5f94,U+5f96,U+5f9a-5f9b,U+5f9d-5fa0,U+5fa2-5fa7,U+5fa9,U+5fab-5fac,U+5faf-5fb4,U+5fb6,U+5fb8-5fbb,U+5fbe-5fc2,U+5fc7-5fc8,U+5fca-5fcb,U+5fce,U+5fd3-5fd5,U+5fda-5fdc,U+5fde-5fdf,U+5fe2-5fe3,U+5fe5-5fe6,U+5fe8-5fe9,U+5fec,U+5fef-5ff0,U+5ff2-5ff4,U+5ff6-5ff7,U+5ff9-5ffa,U+5ffc,U+6007-6009,U+600b-600c,U+6010-6011,U+6013,U+6017-6018,U+601a,U+601e-601f,U+6022-6024,U+602c-602e,U+6030-6034,U+6036-603a,U+603d-603e,U+6040,U+6044-604a,U+604c,U+604e-604f,U+6051,U+6053-6054,U+6056-6058,U+605b-605c,U+605e-6061,U+6065-6066,U+606e,U+6071-6072,U+6074-6075,U+6077,U+607e,U+6080-6082,U+6085-6088,U+608a-608b,U+608e-6091,U+6093,U+6095,U+6097-6099,U+609c,U+609e,U+60a1-60a2,U+60a4-60a5,U+60a7,U+60a9-60aa,U+60ae,U+60b0,U+60b3,U+60b5-60b7,U+60b9-60ba,U+60bd-60c4,U+60c7-60c9,U+60cc\",\n },\n },\n {\n uri: _90,\n descriptors: {\n unicodeRange:\n \"U+635a-635d,U+6360,U+6364-6366,U+6368,U+636a-636c,U+636f-6370,U+6372-6375,U+6378-6379,U+637c-637f,U+6381,U+6383-6386,U+638b,U+638d,U+6391,U+6393-6395,U+6397,U+6399-639f,U+63a1,U+63a4,U+63a6,U+63ab,U+63af,U+63b1-63b2,U+63b5-63b6,U+63b9,U+63bb,U+63bd,U+63bf-63c3,U+63c5,U+63c7-63c8,U+63ca-63cc,U+63d1,U+63d3-63d5,U+63d7-63dd,U+63df,U+63e2,U+63e4-63e8,U+63eb-63ec,U+63ee-63f1,U+63f3,U+63f5,U+63f7,U+63f9-63fc,U+63fe,U+6403-6404,U+6406-640a,U+640d-640e,U+6411-6412,U+6415-641a,U+641d,U+641f,U+6422-6425,U+6427-6429,U+642b,U+642e-6433,U+6435-6439,U+643b-643c,U+643e,U+6440,U+6442-6443,U+6449,U+644b-6451,U+6453,U+6455-6457,U+6459-645d,U+645f-6466,U+6468,U+646a-646c,U+646e-6477,U+647b-6481,U+6483,U+6486,U+6488-648f\",\n },\n },\n {\n uri: _91,\n descriptors: {\n unicodeRange:\n \"U+61c5-61c7,U+61c9,U+61cc-61d0,U+61d3,U+61d5-61e5,U+61e7-61f4,U+61f6-61fe,U+6200-6205,U+6207,U+6209,U+6213-6214,U+6219,U+621c-621e,U+6220,U+6223,U+6226-6229,U+622b,U+622d,U+622f-6232,U+6235-6236,U+6238-623c,U+6242,U+6244-6246,U+624a,U+624f-6250,U+6255-6257,U+6259-625a,U+625c-6262,U+6264-6265,U+6268,U+6271-6272,U+6274-6275,U+6277-6278,U+627a-627b,U+627d,U+6281-6283,U+6285-6288,U+628b-6290,U+6294,U+6299,U+629c-629e,U+62a3,U+62a6-62a7,U+62a9-62aa,U+62ad-62b0,U+62b2-62b4,U+62b6-62b8,U+62ba,U+62be,U+62c0-62c1,U+62c3,U+62cb,U+62cf,U+62d1,U+62d5,U+62dd-62de,U+62e0-62e1,U+62e4,U+62ea-62eb,U+62f0,U+62f2,U+62f5,U+62f8-62fb,U+6300,U+6303-6306,U+630a-630d,U+630f-6310,U+6312-6315,U+6317-6319,U+631c,U+6326-6327,U+6329,U+632c-632e,U+6330-6331,U+6333-6338,U+633b-633c,U+633e-6341,U+6344,U+6347-6348,U+634a,U+6351-6354,U+6356-6359\",\n },\n },\n {\n uri: _92,\n descriptors: {\n unicodeRange:\n \"U+5dd0-5dda,U+5ddc,U+5ddf-5de0,U+5de3-5de4,U+5dea,U+5dec-5ded,U+5df0,U+5df5-5df6,U+5df8-5dfc,U+5dff-5e00,U+5e04,U+5e07,U+5e09-5e0b,U+5e0d-5e0e,U+5e12-5e13,U+5e17,U+5e1e-5e25,U+5e28-5e2c,U+5e2f-5e30,U+5e32-5e36,U+5e39-5e3a,U+5e3e-5e41,U+5e43,U+5e46-5e4b,U+5e4d-5e53,U+5e56-5e5a,U+5e5c-5e5d,U+5e5f-5e60,U+5e63-5e71,U+5e75,U+5e77,U+5e79,U+5e7e,U+5e81-5e83,U+5e85,U+5e88-5e89,U+5e8c-5e8e,U+5e92,U+5e98,U+5e9b,U+5e9d,U+5ea1-5ea4,U+5ea8-5eac,U+5eae-5eb2,U+5eb4,U+5eba-5ebd,U+5ebf-5ec8,U+5ecb-5ed0,U+5ed4-5ed5,U+5ed7-5eda,U+5edc-5ee7,U+5ee9,U+5eeb-5ef3,U+5ef5,U+5ef8-5ef9,U+5efb-5efd,U+5f05-5f07,U+5f09,U+5f0c-5f0e,U+5f10,U+5f12,U+5f14,U+5f16,U+5f19-5f1a,U+5f1c-5f1e,U+5f21-5f24,U+5f28,U+5f2b-5f2c,U+5f2e\",\n },\n },\n {\n uri: _93,\n descriptors: {\n unicodeRange:\n \"U+60cd-60d0,U+60d2-60d4,U+60d6-60d7,U+60d9,U+60db,U+60de,U+60e1-60e5,U+60ea,U+60f1-60f2,U+60f5,U+60f7-60f8,U+60fb-60ff,U+6102-6105,U+6107,U+610a-610c,U+6110-6114,U+6116-6119,U+611b-611e,U+6121-6122,U+6125,U+6128-612a,U+612c-613e,U+6140-6147,U+6149,U+614b,U+614d,U+614f-6150,U+6152-6154,U+6156-615c,U+615e-6161,U+6163-6166,U+6169-616f,U+6171-6174,U+6176,U+6178-618a,U+618c-618d,U+618f-6193,U+6195-619c,U+619e-61a6,U+61aa-61ab,U+61ad-61b6,U+61b8-61bd,U+61bf-61c1,U+61c3-61c4\",\n },\n },\n {\n uri: _94,\n descriptors: {\n unicodeRange:\n \"U+5cf4-5cfa,U+5cfc-5d01,U+5d04-5d05,U+5d08-5d0d,U+5d0f-5d13,U+5d15,U+5d17-5d1a,U+5d1c-5d1d,U+5d1f-5d23,U+5d25,U+5d28,U+5d2a-5d2c,U+5d2f-5d33,U+5d35-5d3c,U+5d3f-5d46,U+5d48-5d49,U+5d4d-5d57,U+5d59-5d5a,U+5d5c,U+5d5e-5d68,U+5d6a,U+5d6d-5d6e,U+5d70-5d73,U+5d75-5d81,U+5d83-5d98,U+5d9a-5d9c,U+5d9e-5db6,U+5db8-5dc4,U+5dc6-5dcc,U+5dce-5dcf\",\n },\n },\n {\n uri: _95,\n descriptors: {\n unicodeRange:\n \"U+5b52,U+5b56,U+5b5e,U+5b60-5b61,U+5b67-5b68,U+5b6b,U+5b6d-5b6f,U+5b72,U+5b74,U+5b76-5b79,U+5b7b-5b7c,U+5b7e-5b7f,U+5b82,U+5b86,U+5b8a,U+5b8d-5b8e,U+5b90-5b92,U+5b94,U+5b96,U+5b9f,U+5ba7-5ba9,U+5bac-5baf,U+5bb1-5bb2,U+5bb7,U+5bba-5bbc,U+5bc0-5bc1,U+5bc3,U+5bc8-5bcb,U+5bcd-5bcf,U+5bd1,U+5bd4-5bdc,U+5be0,U+5be2-5be3,U+5be6-5be7,U+5be9-5bed,U+5bef,U+5bf1-5bf7,U+5bfd-5bfe,U+5c00,U+5c02-5c03,U+5c05,U+5c07-5c08,U+5c0b-5c0e,U+5c10,U+5c12-5c13,U+5c17,U+5c19,U+5c1b,U+5c1e-5c21,U+5c23,U+5c26,U+5c28-5c2b,U+5c2d-5c30,U+5c32-5c33,U+5c35-5c37,U+5c43-5c44,U+5c46-5c47,U+5c4c-5c4d,U+5c52-5c54,U+5c56-5c58,U+5c5a-5c5d,U+5c5f,U+5c62,U+5c64,U+5c67-5c6d,U+5c70,U+5c72-5c78,U+5c7b-5c7e,U+5c80,U+5c83-5c87,U+5c89-5c8b,U+5c8e-5c8f,U+5c92-5c93,U+5c95,U+5c9d-5ca1,U+5ca4-5ca8,U+5caa,U+5cae-5cb0,U+5cb2,U+5cb4,U+5cb6,U+5cb9-5cbc,U+5cbe,U+5cc0,U+5cc2-5cc3,U+5cc5-5cca,U+5ccc-5cd1,U+5cd3-5cd8,U+5cda-5ce0,U+5ce2-5ce3,U+5ce7,U+5ce9,U+5ceb-5cec,U+5cee-5cef,U+5cf1-5cf3\",\n },\n },\n {\n uri: _96,\n descriptors: {\n unicodeRange:\n \"U+593b,U+593d-5940,U+5943,U+5945-5946,U+594a,U+594c-594d,U+5950,U+5952-5953,U+5959,U+595b-595f,U+5961,U+5963-5964,U+5966-5972,U+5975,U+5977,U+597a-597c,U+597e-5980,U+5985,U+5989,U+598b-598c,U+598e-5991,U+5994-5995,U+5998,U+599a-599d,U+599f-59a2,U+59a6-59a7,U+59ac-59ad,U+59b0-59b1,U+59b3-59b8,U+59ba,U+59bc-59bd,U+59bf-59c5,U+59c7-59c9,U+59cc-59cf,U+59d5-59d6,U+59d9,U+59db,U+59de-59e2,U+59e4,U+59e6-59e7,U+59e9-59eb,U+59ed-59f8,U+59fa,U+59fc-59fe,U+5a00,U+5a02,U+5a0a-5a0b,U+5a0d-5a10,U+5a12,U+5a14-5a17,U+5a19-5a1b,U+5a1d-5a1e,U+5a21-5a22,U+5a24,U+5a26-5a28,U+5a2a-5a30,U+5a33,U+5a35,U+5a37-5a3b,U+5a3d-5a3f,U+5a41-5a45,U+5a47-5a48,U+5a4b-5a54,U+5a56-5a59,U+5a5b-5a61,U+5a63-5a66,U+5a68-5a69,U+5a6b-5a73,U+5a78-5a79,U+5a7b-5a7e,U+5a80-5a90\",\n },\n },\n {\n uri: _97,\n descriptors: {\n unicodeRange:\n \"U+5a91,U+5a93-5a99,U+5a9c-5aa9,U+5aab-5ab1,U+5ab4,U+5ab6-5ab7,U+5ab9-5abd,U+5abf-5ac0,U+5ac3-5ac8,U+5aca-5acb,U+5acd-5ad1,U+5ad3,U+5ad5,U+5ad7,U+5ad9-5adb,U+5add-5adf,U+5ae2,U+5ae4-5ae5,U+5ae7-5ae8,U+5aea,U+5aec-5af0,U+5af2-5b08,U+5b0a-5b15,U+5b18-5b31,U+5b33,U+5b35-5b36,U+5b38-5b3f,U+5b41-5b4f\",\n },\n },\n {\n uri: _98,\n descriptors: {\n unicodeRange:\n \"U+5843,U+5845-584b,U+584e-5850,U+5852-5853,U+5855-5857,U+5859-585d,U+585f-5864,U+5866-586a,U+586d-587d,U+587f,U+5882,U+5884,U+5886-5888,U+588a-5891,U+5894-5898,U+589b-589d,U+58a0-58a7,U+58aa-58bb,U+58bd-58c0,U+58c2-58c4,U+58c6-58d0,U+58d2-58d4,U+58d6-58e3,U+58e5-58ea,U+58ed,U+58ef,U+58f1-58f2,U+58f4-58f5,U+58f7-58f8,U+58fa-5901,U+5903,U+5905-5906,U+5908-590c,U+590e,U+5910-5913,U+5917-5918,U+591b,U+591d-591e,U+5920-5923,U+5926,U+5928,U+592c,U+5930,U+5932-5933,U+5935-5936\",\n },\n },\n {\n uri: _99,\n descriptors: {\n unicodeRange:\n \"U+56d0-56d3,U+56d5-56d6,U+56d8-56d9,U+56dc,U+56e3,U+56e5-56ea,U+56ec,U+56ee-56ef,U+56f2-56f3,U+56f6-56f8,U+56fb-56fc,U+5700-5702,U+5705,U+5707,U+570b-571b,U+571d-571e,U+5720-5722,U+5724-5727,U+572b,U+5731-5732,U+5734-5738,U+573c-573d,U+573f,U+5741,U+5743-5746,U+5748-5749,U+574b,U+5752-5756,U+5758-5759,U+5762-5763,U+5765,U+5767,U+576c,U+576e,U+5770-5772,U+5774-5775,U+5778-577a,U+577d-5781,U+5787-578a,U+578d-5791,U+5794-579a,U+579c-579f,U+57a5,U+57a8,U+57aa,U+57ac,U+57af-57b1,U+57b3,U+57b5-57b7,U+57b9-57c1,U+57c4-57ca,U+57cc-57cd,U+57d0-57d1,U+57d3,U+57d6-57d7,U+57db-57dc,U+57de,U+57e1-57e3,U+57e5-57ec,U+57ee,U+57f0-57f3,U+57f5-57f7,U+57fb-57fc,U+57fe-57ff,U+5801,U+5803-5805,U+5808-580a,U+580c,U+580e-5810,U+5812-5814,U+5816-5818,U+581a-581d,U+581f,U+5822-5823,U+5825-5829,U+582b-582f,U+5831-5834,U+5836-5842\",\n },\n },\n {\n uri: _100,\n descriptors: {\n unicodeRange:\n \"U+55f9-55fc,U+55ff,U+5602-5607,U+560a-560b,U+560d,U+5610-5617,U+5619-561a,U+561c-561d,U+5620-5622,U+5625-5626,U+5628-562b,U+562e-5630,U+5633,U+5635,U+5637-5638,U+563a,U+563c-563e,U+5640-564b,U+564f-5653,U+5655-5656,U+565a-565b,U+565d-5661,U+5663,U+5665-5667,U+566d-5670,U+5672-5675,U+5677-567a,U+567d-5684,U+5687-568d,U+5690-5692,U+5694-56a2,U+56a4-56ae,U+56b0-56b6,U+56b8-56bb,U+56bd-56c9,U+56cb-56cf\",\n },\n },\n {\n uri: _101,\n descriptors: {\n unicodeRange:\n \"U+5286-5287,U+5289-528f,U+5291-5292,U+5294-529a,U+529c,U+52a4-52a7,U+52ae-52b0,U+52b4-52bd,U+52c0-52c2,U+52c4-52c6,U+52c8,U+52ca,U+52cc-52cf,U+52d1,U+52d3-52d5,U+52d7,U+52d9-52de,U+52e0-52e3,U+52e5-52ef,U+52f1-52f8,U+52fb-52fd,U+5301-5304,U+5307,U+5309-530c,U+530e,U+5311-5314,U+5318,U+531b-531c,U+531e-531f,U+5322,U+5324-5325,U+5327-5329,U+532b-532d,U+532f-5338,U+533c-533d,U+5340,U+5342,U+5344,U+5346,U+534b-534d,U+5350,U+5354,U+5358-5359,U+535b,U+535d,U+5365,U+5368,U+536a,U+536c-536d,U+5372,U+5376,U+5379,U+537b-537e,U+5380-5381,U+5383,U+5387-5388,U+538a,U+538e-5394,U+5396-5397,U+5399,U+539b-539c,U+539e,U+53a0-53a1,U+53a4,U+53a7,U+53aa-53ad,U+53af-53b5,U+53b7-53ba,U+53bc-53be,U+53c0,U+53c3-53c7,U+53ce-53d0,U+53d2-53d3,U+53d5,U+53da,U+53dc-53de,U+53e1-53e2,U+53e7,U+53f4,U+53fa,U+53fe-5400,U+5402,U+5405,U+5407,U+540b,U+5414,U+5418-541a,U+541c,U+5422,U+5424-5425,U+542a,U+5430,U+5433,U+5436-5437,U+543a\",\n },\n },\n {\n uri: _102,\n descriptors: {\n unicodeRange:\n \"U+5101-5105,U+5108-510a,U+510c-5111,U+5113-5120,U+5122-513e,U+5142,U+5147,U+514a,U+514c,U+514e-5150,U+5152-5153,U+5157-5159,U+515b,U+515d-5161,U+5163-5164,U+5166-5167,U+5169-516a,U+516f,U+5172,U+517a,U+517e-517f,U+5183-5184,U+5186-5187,U+518a-518b,U+518e-5191,U+5193-5194,U+5198,U+519a,U+519d-519f,U+51a1,U+51a3,U+51a6-51aa,U+51ad-51ae,U+51b4,U+51b8-51ba,U+51be-51bf,U+51c1-51c3,U+51c5,U+51c8,U+51ca,U+51cd-51ce,U+51d0,U+51d2-51da,U+51dc,U+51de-51df,U+51e2-51e3,U+51e5-51ea,U+51ec,U+51ee,U+51f1-51f2,U+51f4,U+51f7,U+51fe,U+5204-5205,U+5209,U+520b-520c,U+520f-5210,U+5213-5215,U+521c,U+521e-521f,U+5221-5223,U+5225-5227,U+522a,U+522c,U+522f,U+5231-5232,U+5234-5235,U+523c,U+523e,U+5244-5249,U+524b,U+524e-524f,U+5252-5253,U+5255,U+5257-525b,U+525d,U+525f-5260,U+5262-5264,U+5266,U+5268,U+526b-526e,U+5270-5271,U+5273-527c,U+527e,U+5280,U+5283-5285\",\n },\n },\n {\n uri: _103,\n descriptors: {\n unicodeRange:\n \"U+543d,U+543f,U+5441-5442,U+5444-5445,U+5447,U+5449,U+544c-544f,U+5451,U+545a,U+545d-5461,U+5463,U+5465,U+5467,U+5469-5470,U+5474,U+5479-547a,U+547e-547f,U+5481,U+5483,U+5485,U+5487-548a,U+548d,U+5491,U+5493,U+5497-5498,U+549c,U+549e-54a2,U+54a5,U+54ae,U+54b0,U+54b2,U+54b5-54b7,U+54b9-54ba,U+54bc,U+54be,U+54c3,U+54c5,U+54ca-54cb,U+54d6,U+54d8,U+54db,U+54e0-54e4,U+54eb-54ec,U+54ef-54f1,U+54f4-54f9,U+54fb,U+54fe,U+5500,U+5502-5505,U+5508,U+550a-550e,U+5512-5513,U+5515-551a,U+551c-551f,U+5521,U+5525-5526,U+5528-5529,U+552b,U+552d,U+5532,U+5534-5536,U+5538-553b,U+553d,U+5540,U+5542,U+5545,U+5547-5548,U+554b-554f,U+5551-5554,U+5557-555b,U+555d-5560,U+5562-5563,U+5568-5569,U+556b,U+556f-5574,U+5579-557a,U+557d,U+557f,U+5585-5586,U+558c-558e,U+5590,U+5592-5593,U+5595-5597,U+559a-559b,U+559e,U+55a0-55a6,U+55a8-55b0,U+55b2,U+55b4,U+55b6,U+55b8,U+55ba,U+55bc,U+55bf-55c3,U+55c6-55c8,U+55ca-55cb,U+55ce-55d0,U+55d5,U+55d7-55db,U+55de,U+55e0,U+55e2,U+55e7,U+55e9,U+55ed-55ee,U+55f0-55f1,U+55f4,U+55f6,U+55f8\",\n },\n },\n {\n uri: _104,\n descriptors: {\n unicodeRange:\n \"U+4fe0,U+4fe2,U+4fe4-4fe5,U+4fe7,U+4feb-4fec,U+4ff0,U+4ff2,U+4ff4-4ff7,U+4ff9,U+4ffb-4ffd,U+4fff-500b,U+500e,U+5010-5011,U+5013,U+5015-5017,U+501b,U+501d-501e,U+5020,U+5022-5024,U+5027,U+502b,U+502f-5039,U+503b,U+503d,U+503f-5042,U+5044-5046,U+5049-504b,U+504d,U+5050-5054,U+5056-5059,U+505b,U+505d-5064,U+5066-506b,U+506d-5075,U+5078-507a,U+507c-507d,U+5081-5084,U+5086-5087,U+5089-508c,U+508e-50a2,U+50a4,U+50a6,U+50aa-50ab,U+50ad-50b1,U+50b3-50b9,U+50bc-50ce,U+50d0-50d5,U+50d7-50d9,U+50db-50e5,U+50e8-50eb,U+50ef-50f2,U+50f4,U+50f6-50fa,U+50fc-5100\",\n },\n },\n { uri: _105, descriptors: { unicodeRange: \"U+49d5-4a77\" } },\n {\n uri: _106,\n descriptors: {\n unicodeRange:\n \"U+4dac-4dad,U+4daf-4db5,U+4e02,U+4e04-4e06,U+4e0f,U+4e12,U+4e17,U+4e1f-4e21,U+4e23,U+4e26,U+4e29,U+4e2e-4e2f,U+4e31,U+4e33,U+4e35,U+4e37,U+4e3c,U+4e40-4e42,U+4e44,U+4e46,U+4e4a,U+4e51,U+4e55,U+4e57,U+4e5a-4e5b,U+4e62-4e65,U+4e67-4e68,U+4e6a-4e6f,U+4e72,U+4e74-4e7d,U+4e7f-4e85,U+4e87,U+4e8a,U+4e90,U+4e96-4e97,U+4e99,U+4e9c-4e9e,U+4ea3,U+4eaa,U+4eaf-4eb1,U+4eb4,U+4eb6-4eb9,U+4ebc-4ebe,U+4ec8,U+4ecc,U+4ecf-4ed0,U+4ed2,U+4eda-4edc,U+4ee0,U+4ee2,U+4ee6-4ee7,U+4ee9,U+4eed-4eef,U+4ef1,U+4ef4,U+4ef8-4efa,U+4efc,U+4efe,U+4f00,U+4f02-4f08,U+4f0b-4f0c,U+4f12-4f16,U+4f1c-4f1d,U+4f21,U+4f23,U+4f28-4f29,U+4f2c-4f2e,U+4f31,U+4f33,U+4f35,U+4f37,U+4f39,U+4f3b,U+4f3e-4f42,U+4f44-4f45,U+4f47-4f4c,U+4f52,U+4f54,U+4f56,U+4f61-4f62,U+4f66,U+4f68,U+4f6a-4f6b,U+4f6d-4f6e,U+4f71-4f72,U+4f75,U+4f77-4f7a,U+4f7d,U+4f80-4f82,U+4f85-4f87,U+4f8a,U+4f8c,U+4f8e,U+4f90,U+4f92-4f93,U+4f95-4f96,U+4f98-4f9a,U+4f9c,U+4f9e-4f9f,U+4fa1-4fa2,U+4fa4,U+4fab,U+4fad,U+4fb0-4fb4,U+4fb6-4fbe,U+4fc0-4fc2,U+4fc6-4fc9,U+4fcb-4fcd,U+4fd2-4fd6,U+4fd9,U+4fdb\",\n },\n },\n { uri: _107, descriptors: { unicodeRange: \"U+4933-49d4\" } },\n { uri: _108, descriptors: { unicodeRange: \"U+487a-4932\" } },\n {\n uri: _109,\n descriptors: { unicodeRange: \"U+47d2-4879,U+2ce7c,U+2ce88,U+2ce93\" },\n },\n {\n uri: _110,\n descriptors: {\n unicodeRange:\n \"U+4756-47d1,U+2ca02,U+2ca0e,U+2ca7d,U+2caa9,U+2cb29,U+2cb2e,U+2cb31,U+2cb38-2cb39,U+2cb3f,U+2cb41,U+2cb4e,U+2cb5a,U+2cb64,U+2cb69,U+2cb6c,U+2cb6f,U+2cb76,U+2cb78,U+2cb7c,U+2cbb1,U+2cbbf-2cbc0,U+2cbce,U+2cc5f,U+2ccf5-2ccf6,U+2ccfd,U+2ccff,U+2cd02-2cd03,U+2cd0a,U+2cd8b,U+2cd8d,U+2cd8f-2cd90,U+2cd9f-2cda0,U+2cda8,U+2cdad-2cdae,U+2cdd5,U+2ce18,U+2ce1a,U+2ce23,U+2ce26,U+2ce2a\",\n },\n },\n {\n uri: _111,\n descriptors: {\n unicodeRange:\n \"U+46c3-4755,U+2c488,U+2c494,U+2c497,U+2c542,U+2c613,U+2c618,U+2c621,U+2c629,U+2c62b-2c62d,U+2c62f,U+2c642,U+2c64a-2c64b,U+2c72c,U+2c72f,U+2c79f,U+2c7c1,U+2c7fd,U+2c8d9,U+2c8de,U+2c8e1,U+2c8f3,U+2c907,U+2c90a,U+2c91d\",\n },\n },\n {\n uri: _112,\n descriptors: {\n unicodeRange:\n \"U+4629-46c2,U+2bdf7,U+2be29,U+2c029-2c02a,U+2c0a9,U+2c0ca,U+2c1d5,U+2c1d9,U+2c1f9,U+2c27c,U+2c288,U+2c2a4,U+2c317,U+2c35b,U+2c361,U+2c364\",\n },\n },\n {\n uri: _113,\n descriptors: {\n unicodeRange:\n \"U+458e-4628,U+2b7a9,U+2b7c5,U+2b7e6,U+2b7f9,U+2b806,U+2b80a,U+2b81c,U+2b8b8,U+2bac7,U+2bb5f,U+2bb62,U+2bb7c,U+2bb83,U+2bc1b,U+2bd77,U+2bd87\",\n },\n },\n {\n uri: _114,\n descriptors: {\n unicodeRange: \"U+4449-4511,U+2afa2,U+2b127-2b128,U+2b137-2b138,U+2b1ed\",\n },\n },\n {\n uri: _115,\n descriptors: {\n unicodeRange:\n \"U+439b-4448,U+2a437,U+2a5f1,U+2a602,U+2a61a,U+2a6b2,U+2a7dd,U+2a8fb,U+2a917,U+2aa30,U+2aa36,U+2aa58\",\n },\n },\n {\n uri: _116,\n descriptors: {\n unicodeRange:\n \"U+4275-430d,U+298c6,U+29a72,U+29d98,U+29ddb,U+29e15,U+29e3d,U+29e49\",\n },\n },\n {\n uri: _117,\n descriptors: {\n unicodeRange:\n \"U+4132-41de,U+28bef,U+28c47,U+28c4f,U+28c51,U+28c54,U+28d10,U+28d71,U+28dfb,U+28e1f,U+28e36,U+28e89,U+28e99,U+28eeb,U+28f32,U+28ff8,U+292a0\",\n },\n },\n {\n uri: _118,\n descriptors: {\n unicodeRange:\n \"U+41df-4274,U+292b1,U+29490,U+295cf,U+2967f,U+296f0,U+29719,U+29750\",\n },\n },\n {\n uri: _119,\n descriptors: {\n unicodeRange:\n \"U+408e-4131,U+285c8-285c9,U+28678,U+28695,U+286d7,U+286fa,U+287e0,U+28946,U+28949,U+2896b,U+28987-28988,U+289ba-289bb,U+28a1e,U+28a29,U+28a43,U+28a71,U+28a99,U+28acd,U+28add,U+28ae4,U+28b49,U+28bc1\",\n },\n },\n {\n uri: _120,\n descriptors: {\n unicodeRange:\n \"U+3e83-3f2f,U+27139,U+273da-273db,U+273fe,U+27410,U+27449,U+27614-27615,U+27631,U+27684,U+27693,U+2770e,U+27723,U+27752\",\n },\n },\n {\n uri: _121,\n descriptors: {\n unicodeRange:\n \"U+3f30-3fdb,U+27985,U+27a84,U+27bb3,U+27bbe,U+27bc7,U+27cb8,U+27da0,U+27e10\",\n },\n },\n {\n uri: _122,\n descriptors: {\n unicodeRange:\n \"U+3fdc-408d,U+27fb7,U+27ff9,U+2808a,U+280bb,U+2815d,U+28277,U+28282,U+282e2,U+282f3,U+283cd,U+28408,U+2840c,U+28455,U+28468,U+2856b\",\n },\n },\n {\n uri: _123,\n descriptors: {\n unicodeRange:\n \"U+3dd2-3e82,U+26a58,U+26a8c,U+26ab7,U+26aff,U+26b5c,U+26c21,U+26c29,U+26c73,U+26cdd,U+26e40,U+26e65,U+26f94,U+26ff6-26ff8,U+270f4,U+2710d\",\n },\n },\n {\n uri: _124,\n descriptors: {\n unicodeRange:\n \"U+3d34-3dd1,U+2648d,U+26676,U+2667e,U+266b0,U+2671d,U+2677c,U+267cc,U+268dd,U+268ea,U+26951,U+2696f,U+269dd,U+269fa,U+26a1e\",\n },\n },\n {\n uri: _125,\n descriptors: {\n unicodeRange:\n \"U+3c76-3d33,U+25d0a,U+25da1,U+25e2e,U+25e56,U+25e62,U+25e65,U+25ec2,U+25ed7-25ed8,U+25ee8,U+25f23,U+25f5c,U+25fd4,U+25fe0,U+25ffb,U+2600c,U+26017,U+26060,U+260ed,U+26221,U+26270,U+26286,U+2634c,U+26402\",\n },\n },\n {\n uri: _126,\n descriptors: {\n unicodeRange:\n \"U+3bda-3c75,U+25771,U+257a9,U+257b4,U+259c4,U+259d4,U+25ae3-25ae4,U+25af1,U+25bb2,U+25c14,U+25c4b,U+25c64\",\n },\n },\n {\n uri: _127,\n descriptors: {\n unicodeRange:\n \"U+3b25-3bd9,U+2504a,U+25055,U+25122,U+2512b,U+251a9,U+251cd,U+251e5,U+2521e,U+2524c,U+2542e,U+2548e,U+254d9,U+2550e,U+25532,U+25562,U+255a7-255a8\",\n },\n },\n {\n uri: _128,\n descriptors: {\n unicodeRange:\n \"U+3a6b-3b24,U+24896,U+249db,U+24a4d,U+24a7d,U+24ac9,U+24b56,U+24b6f,U+24c16,U+24d14,U+24dea,U+24e0e,U+24e37,U+24e6a,U+24e8b,U+24eaa\",\n },\n },\n {\n uri: _129,\n descriptors: {\n unicodeRange:\n \"U+39a9-3a6a,U+24096,U+24103,U+241ac,U+241c6,U+241fe,U+243bc,U+243f8,U+244d3,U+24629,U+246a5,U+247f1\",\n },\n },\n {\n uri: _130,\n descriptors: {\n unicodeRange:\n \"U+38e3-39a8,U+23a98,U+23c7f,U+23c97-23c98,U+23cfe,U+23d00,U+23d0e,U+23d40,U+23dd3,U+23df9-23dfa,U+23e23,U+23f7e\",\n },\n },\n {\n uri: _131,\n descriptors: {\n unicodeRange:\n \"U+3760-382a,U+22ab8,U+22b43,U+22b46,U+22b4f-22b50,U+22ba6,U+22bca,U+22c1d,U+22c24,U+22c55,U+22d4c,U+22de1\",\n },\n },\n {\n uri: _132,\n descriptors: {\n unicodeRange:\n \"U+382b-38e2,U+231b6,U+231c3-231c4,U+231f5,U+23350,U+23372,U+233d0,U+233d2-233d3,U+233d5,U+233da,U+233df,U+233e4,U+2344a-2344b,U+23451,U+23465,U+234e4,U+2355a,U+23594,U+235c4,U+235cb,U+23638-2363a,U+23647,U+2370c,U+2371c,U+2373f,U+23763-23764,U+237e7,U+237ff,U+23824,U+2383d\",\n },\n },\n {\n uri: _133,\n descriptors: {\n unicodeRange:\n \"U+3698-375f,U+22218,U+2231e,U+223ad,U+224dc,U+226f3,U+2285b,U+228ab,U+2298f\",\n },\n },\n {\n uri: _134,\n descriptors: {\n unicodeRange:\n \"U+35e6-3697,U+21c56,U+21cde,U+21d2d,U+21d45,U+21d62,U+21d78,U+21d92,U+21d9c,U+21da1,U+21db7,U+21de0,U+21e33-21e34,U+21f1e,U+21f76,U+21ffa,U+2217b\",\n },\n },\n {\n uri: _135,\n descriptors: {\n unicodeRange:\n \"U+3444-350e,U+20ad3,U+20b1d,U+20b9f,U+20c41,U+20cbf,U+20cd0,U+20d45,U+20de1,U+20e64,U+20e6d,U+20e95,U+20e9d,U+20ea2,U+20f5f,U+210c1,U+21201,U+2123d,U+21255,U+21274,U+2127b\",\n },\n },\n {\n uri: _136,\n descriptors: {\n unicodeRange:\n \"U+350f-35e5,U+212d7,U+212e4,U+212fd,U+2131b,U+21336,U+21344,U+2139a,U+213c4,U+21413,U+2146d-2146e,U+215d7,U+21647,U+216b4,U+21706,U+21742,U+218bd,U+219c3\",\n },\n },\n {\n uri: _137,\n descriptors: {\n unicodeRange:\n \"U+336d-3443,U+2032b,U+20371,U+20381,U+203f9,U+2044a,U+20509,U+20547,U+205d6,U+20628,U+20676,U+2074f,U+20779,U+20807,U+2083a,U+20895,U+208b9,U+2097c,U+2099d\",\n },\n },\n {\n uri: _138,\n descriptors: {\n unicodeRange:\n \"U+328b-336c,U+2000b,U+20089,U+200a2,U+200a4,U+20164,U+201a2,U+20213\",\n },\n },\n {\n uri: _139,\n descriptors: {\n unicodeRange:\n \"U+3192-31ba,U+31c0-31e3,U+31f0-321e,U+3220-328a,U+1f250-1f251\",\n },\n },\n {\n uri: _140,\n descriptors: {\n unicodeRange:\n \"U+2f74-2fd5,U+3000,U+3003-3007,U+3012-3013,U+3018-301c,U+3020-3029,U+302f-303f,U+3041-3096,U+3099-30a1\",\n },\n },\n {\n uri: _141,\n descriptors: {\n unicodeRange: \"U+30a2-30ff,U+3105-312f,U+3131-318e,U+3190-3191\",\n },\n },\n {\n uri: _142,\n descriptors: {\n unicodeRange:\n \"U+4e36,U+4ea0,U+4f74,U+4f91,U+4f94,U+4fc5,U+507e,U+50ed,U+5182,U+51f5,U+525e,U+5282,U+52f9,U+5326,U+537a,U+53a3,U+5423,U+5459,U+54b4,U+54d9,U+55c9,U+57f4,U+580b,U+5902,U+5925,U+5a08,U+5ab5,U+5b84,U+5be4,U+5c22,U+5cb5,U+5cbd,U+5d3e,U+5e31,U+5e5e,U+5e80,U+5ee8,U+5f82,U+5fc9,U+5fed,U+600a,U+605d,U+609b,U+609d,U+60dd,U+6243,U+6322,U+63ce,U+640c,U+643f,U+6445,U+64d7,U+6534,U+6549,U+656b,U+6603,U+674c,U+680a,U+6864,U+69d4,U+6a65,U+6c2a,U+6c46,U+6c5c,U+6d0e,U+6d48,U+6e2b,U+6eb2,U+6eb7,U+6f89,U+706c,U+70b1,U+7113,U+71d4,U+727f,U+72f3,U+7303,U+7321,U+736c,U+736f,U+74a9,U+74de,U+750d,U+7513,U+7592,U+75c4,U+7605,U+760a,U+761b,U+7625,U+762d,U+7643,U+7707,U+7747,U+77b5,U+7839,U+784e,U+78a5,U+7924,U+793b,U+798a,U+7a03,U+7a06,U+7a78,U+7a80,U+7aad,U+7ba8,U+7be5,U+7cc8,U+7ec1,U+7f0b,U+7f0f,U+7f12,U+7f68,U+7f9d,U+8025,U+809c,U+80ad,U+80b7,U+80e8,U+811e,U+8204,U+8223,U+822d,U+823b,U+824b,U+825a,U+827d,U+827f,U+828f,U+82c8,U+8307,U+831b,U+8347,U+837d,U+839b,U+83a9,U+83f9,U+84b9,U+8579,U+864d,U+867f,U+86b0,U+86d1,U+86d8,U+86f2,U+8764,U+8770,U+8788,U+8797,U+87ac-87ad,U+87b5,U+881b,U+8844,U+88bc,U+88fc,U+8930,U+89cf,U+89d6,U+8ba0,U+8bd4,U+8c02,U+8c2b,U+8c85,U+8e23,U+8f81-8f82,U+8fd5,U+90b6,U+90db,U+914e,U+9164,U+91ad,U+943e,U+94b7-94b8,U+94eb,U+950d,U+9514,U+9516,U+9518,U+9529,U+9538,U+953f,U+954e,U+955f,U+95fc,U+9667,U+96b3,U+9792,U+97b2,U+98a1,U+9969,U+9987,U+9998,U+9a80,U+9a92,U+9a96,U+9adf,U+9cb4,U+9cbd,U+9cd0,U+9cd4,U+9e31,U+9e3a,U+9e71,U+9ee5,U+9eea,U+9ef9,U+9fa0\",\n },\n },\n {\n uri: _143,\n descriptors: {\n unicodeRange:\n \"U+4e0c,U+4e28,U+4e3f,U+4ec2,U+502e,U+50ba,U+5155,U+5181,U+522d,U+5281,U+5290,U+5369,U+53b6,U+54d5,U+54dc,U+54ff,U+552a,U+553c,U+5588,U+55b5,U+5686,U+570a,U+5776,U+5786,U+57a4,U+5820,U+5865,U+58bc,U+5b32,U+5b65,U+5c1c,U+5c66,U+5c6e,U+5c8d,U+5ddb,U+5f2a,U+5f50,U+5f61,U+6067,U+614a,U+615d,U+619d,U+61d4,U+620b,U+6224-6225,U+6343,U+63ad,U+63f2,U+640b,U+6420,U+6434,U+6496,U+64d0,U+6509,U+652e,U+67a8,U+6833,U+6844,U+684a,U+6920,U+6957,U+6971,U+6a8e,U+6a91,U+6aa0,U+6b43,U+6bea,U+6bf5,U+6c15,U+6cd0,U+6ee0,U+6f24,U+6f2d,U+70c0,U+721d,U+728b,U+72c3,U+72e8,U+730a,U+7338-7339,U+734d,U+746d,U+752f,U+754e,U+770d,U+7735,U+778d,U+77a2,U+77e7,U+7857,U+786d,U+78c9,U+78f2,U+791e,U+7953,U+7b58,U+7b9d,U+7bda,U+7cd7,U+7f32-7f33,U+8022,U+8028-8029,U+8035,U+804d,U+8080,U+80c2,U+80e9,U+80ec,U+80f2,U+810e,U+8221,U+8274,U+82b0,U+82e0,U+83b0,U+8487-8488,U+848e,U+84cd,U+84d0,U+8539,U+857a,U+85a8,U+85b7,U+867c,U+871e,U+8723,U+877e,U+878b,U+8793,U+8803,U+88d2,U+8966,U+89cc,U+89eb,U+8b26,U+8c8a,U+8c98,U+8d33,U+8d47,U+8d55,U+8dbc,U+8e40,U+8e94,U+8f77,U+8f79,U+9058,U+91a2,U+91b5,U+928e,U+9494,U+94b6,U+94de,U+94f4,U+94f9,U+950a,U+950e,U+951e,U+952b,U+953c,U+953e,U+9544,U+9561,U+9564,U+9569,U+95f6,U+9603,U+960d,U+963d,U+9674,U+9794,U+97ab,U+98a5,U+9a9f,U+9ab1,U+9ad1,U+9b0f,U+9b2f,U+9c92,U+9c95,U+9cba,U+9cbc,U+9cc6,U+9ccb,U+9cd8,U+9e32,U+9e38,U+9e5b,U+9e7e,U+9eb4,U+9efb-9efc,U+9f3d\",\n },\n },\n {\n uri: _144,\n descriptors: {\n unicodeRange: \"U+2e3b,U+2e80-2e99,U+2e9b-2ef3,U+2f00-2f73,U+ffffd\",\n },\n },\n {\n uri: _145,\n descriptors: {\n unicodeRange:\n \"U+4e69,U+4f1b,U+4f67,U+4f7e,U+4fdc,U+50e6,U+5196,U+5202,U+5233,U+523f,U+52a2,U+536e,U+5476,U+54ad,U+54cf,U+5537,U+561e,U+56dd,U+56df,U+5709,U+572c,U+57cf,U+57f8,U+580d,U+5881,U+589a,U+5941,U+59b2,U+5c25,U+5d24,U+5d74,U+5e42,U+5e8b,U+5eb3,U+5ed2,U+5fad,U+6003,U+603c,U+6083,U+6100,U+6126,U+6206,U+62ca,U+638e,U+63b4,U+6426,U+646d,U+6535,U+65c4,U+66db,U+6715,U+6769,U+6798,U+67c3,U+6861,U+698d,U+69ca,U+69ed,U+69f2,U+69ff,U+6a18,U+6b39,U+6bb3,U+6c0d,U+6cb2,U+6cd6,U+6cf7,U+6cfa,U+6d33,U+6e16,U+6e53-6e54,U+6ebb,U+6fb6,U+709d,U+72ad,U+72f7,U+72fb,U+7313,U+739f,U+74ba,U+754b,U+755b,U+758b,U+75ac,U+75d6,U+7617,U+7635,U+7640,U+76a4,U+76b2,U+775a,U+77bd,U+781f,U+79b3,U+7b2b,U+7b31,U+7b3e,U+7b6e,U+7b9c,U+7c0b,U+7c9e,U+7cc1,U+7ce8,U+7ea5,U+7f21,U+7f27,U+7f74,U+7fb0,U+8031,U+8071,U+80ea,U+8114,U+8160,U+81a6,U+81c1,U+829f,U+82a4,U+82fb,U+831a,U+8333,U+836c,U+83b6,U+83f8,U+8411,U+841c,U+8489,U+848c,U+85a4,U+8627,U+8629,U+866e,U+86b5,U+872e,U+8731,U+877b,U+877d,U+87ea,U+8813,U+8816,U+8864,U+88ce,U+88e5,U+897b,U+89cb,U+89f3,U+8bfc,U+8c35,U+8d46,U+8d4d,U+8dba,U+8e3a,U+8f75,U+8f7e,U+8fd3,U+9161,U+9179,U+917e,U+91a3,U+94ac,U+94d7,U+94e5,U+952a,U+952c,U+9545,U+9565,U+9568,U+956a,U+961d,U+96e0,U+972a,U+9730,U+989f,U+98e7,U+990d,U+9967,U+9993,U+9aa3,U+9ac0,U+9ae1,U+9aeb,U+9af9,U+9c86,U+9c8b,U+9ca0-9ca1,U+9ca3,U+9ce2,U+9e48,U+9e6a,U+9e87,U+9ee2,U+9ee9,U+9f17,U+9f19,U+9f2c,U+9f80\",\n },\n },\n {\n uri: _146,\n descriptors: {\n unicodeRange:\n \"U+4ef3,U+50d6,U+50ec,U+51ab,U+51b1,U+52d6,U+54a9,U+54da,U+55be,U+55cd,U+564d,U+572f,U+574c,U+576b,U+57d8,U+57fd,U+5844,U+59d2,U+5ae0,U+5b16,U+5b37,U+5b5b,U+5b80,U+5d1e,U+5d6b,U+5efe,U+5f11,U+5f56,U+5f58,U+5f73,U+5f8c,U+5fc4,U+5fe4,U+602b,U+6106,U+610d,U+63de,U+63f8,U+641b,U+64e4,U+6634,U+676a,U+67b5,U+681d,U+6883,U+69b1,U+69e0,U+6b37,U+6b9b,U+6d7c,U+6ed7,U+6f36,U+6f72,U+6f8c,U+7035,U+7039,U+7173,U+7178,U+7228,U+728f,U+72b4,U+72ef,U+72f4,U+7331,U+7481,U+74e0,U+7540,U+75c3,U+75e6,U+763c,U+764d,U+76cd,U+7704,U+7743,U+7780,U+7847,U+786a,U+78b9,U+7962,U+7a02,U+7aac,U+7ab3,U+7b0a,U+7b4c,U+7b7b,U+7bfc,U+7c0f,U+7c16,U+7c40,U+7ca2,U+7cc7,U+7cf8,U+7d77,U+7e3b,U+7ea1,U+7ea9,U+7ef2,U+7f02,U+7f07,U+7f0c,U+7f23,U+7f2f,U+7fbc,U+8016,U+8020,U+812c,U+8136,U+8182,U+822f,U+8233,U+825f,U+8268,U+8284,U+8288,U+8291,U+8308,U+8311,U+835b,U+836d,U+83dd,U+8406,U+840f,U+845c,U+84b4,U+84e3,U+850c,U+855e,U+863c,U+86ba,U+86c4,U+86de,U+86f1,U+873e,U+87bd,U+87db,U+880a,U+883c,U+887f,U+88f0,U+890a,U+892b,U+895e,U+89ef,U+8a48,U+8bdc,U+8c18,U+8c33,U+8c94,U+8db1,U+8dcf,U+8dd6,U+8de3,U+8e6f,U+8e90,U+8f7a,U+8fb6,U+902d,U+90be,U+91af,U+936a,U+948b,U+94d8,U+9513,U+953a,U+956c,U+963c,U+9654,U+966c,U+9688,U+97b4,U+996b,U+9a75,U+9a7a,U+9aba,U+9aed,U+9b08,U+9b43,U+9c8e,U+9c94,U+9c9a,U+9e2b,U+9e36,U+9e4b,U+9e4e,U+9e55,U+9e63,U+9e68-9e69,U+9ebd,U+9ec9,U+9f0d,U+9f37,U+9f51\",\n },\n },\n {\n uri: _147,\n descriptors: {\n unicodeRange:\n \"U+50a7,U+5240,U+5261,U+52ac,U+531a,U+5363,U+5432,U+5452,U+5456,U+5472,U+5478,U+553f,U+5575,U+5581,U+55cc,U+55fe,U+5601,U+572e,U+57d2,U+57ef,U+581e,U+5924,U+5981,U+5997,U+59a3,U+5aaa,U+5ab8,U+5b34,U+5d5d,U+5def,U+5e11,U+5e91,U+5ed1,U+5ef4,U+5f40,U+600d,U+6019,U+601b,U+605a,U+6092,U+60ab,U+6217,U+623d,U+6369,U+65d2,U+6661,U+670a,U+6753,U+67a7,U+6855,U+68f9,U+6939,U+696e,U+6980,U+6a7c,U+6aab,U+6b82,U+6bf3,U+6bf9,U+6c05,U+6c19-6c1a,U+6ca9,U+6cf6,U+6d1a,U+6dab,U+6f74,U+7085,U+7198,U+71b5,U+7256,U+725d,U+727e,U+72fa,U+7322,U+738e,U+73e5,U+750f,U+755a,U+7594,U+75b3,U+760c,U+7615,U+7630,U+763f,U+77ec,U+7817,U+78a1,U+78d9,U+7905,U+7b2a,U+7b2e,U+7b62,U+7b85,U+7bcc,U+7bea,U+7c26,U+7c74,U+7c9c-7c9d,U+7e47,U+7e9b,U+7e9f,U+7ee0,U+7ee8,U+7ef1,U+7f01,U+7f11,U+7f17,U+7f36,U+7f7e,U+7fee,U+802a,U+80cd,U+8112,U+8169,U+8234,U+8279,U+8298,U+82ca,U+82d8,U+82e1,U+83c0,U+83d4,U+83df,U+8401,U+8451,U+845a,U+8476,U+8478,U+84ba,U+84bd,U+84e0,U+851f,U+8548,U+8556,U+8585,U+868d,U+86e9,U+86f4,U+86f8,U+8765,U+8785,U+87ab,U+87ee,U+8832,U+8872,U+88b7,U+88e2-88e3,U+89da,U+8bce,U+8bd3,U+8bd6,U+8bf9,U+8c16,U+8c73,U+8d5c,U+8dde,U+8f6d,U+8f94,U+8fe8,U+9011,U+915e,U+9185,U+918c,U+94ab,U+94d1,U+94f3,U+9515,U+951d,U+9558,U+9567,U+96ce,U+96e9,U+9785,U+9878,U+987c,U+9883,U+98d1,U+9954,U+9963,U+9a93,U+9ac1,U+9acc,U+9b1f,U+9b49,U+9b4d,U+9b51,U+9ca7,U+9cae,U+9cce,U+9cd3,U+9e37,U+9e39,U+9e41,U+9e46,U+9f22,U+9f2f,U+9f39,U+9f85\",\n },\n },\n {\n uri: _148,\n descriptors: {\n unicodeRange:\n \"U+4e5c,U+4edf,U+4f25,U+4f32,U+4f5e,U+4f76,U+4faa,U+4fe6,U+5028,U+5048,U+5250,U+535f,U+538d,U+53c1,U+5412,U+5443,U+54d4,U+54dd,U+5541,U+5550,U+5577,U+55dd,U+55f3,U+560f,U+562c,U+5657-5658,U+5664,U+56af,U+575c,U+577c,U+57b2,U+57da,U+5800,U+5a62,U+5aeb,U+5c3b,U+5ca3,U+5d26,U+5d9d,U+5f01,U+5fb5,U+5fdd,U+5ff8,U+6029,U+6041,U+6079,U+60b1,U+6222,U+629f,U+6332,U+63bc,U+63e0,U+6485,U+65ab,U+65c3,U+65c6,U+668c,U+669d,U+66be,U+67fd,U+6800,U+68fc,U+690b,U+6924,U+6978,U+69a7,U+6a3e,U+6a50,U+6a5b,U+6a97,U+6b24,U+6b8d,U+6baa,U+6c10,U+6c54,U+6ceb,U+6d04,U+6d4d,U+6eb1,U+6ebd,U+7110,U+71b3,U+71f9,U+7230,U+728d,U+7292,U+72b8,U+72d2,U+7360,U+73a2,U+7511,U+75a0,U+75c8,U+779f,U+7826,U+7877,U+7a39,U+7aa8,U+7ae6,U+7b04,U+7b0f,U+7baa,U+7bac,U+7c1f,U+7ccd,U+7ecb,U+7ed4,U+7ed7,U+7efb,U+7f0d,U+7f5f,U+7faf,U+7fd5,U+7fe5,U+8027,U+80bc,U+80dd,U+80fc,U+8132,U+815a,U+8167,U+816d,U+81ca,U+8228,U+82a1,U+82a9,U+82ab,U+82cc,U+8351,U+8368,U+83b8,U+83d8,U+83ea,U+83f0,U+8497,U+84c1,U+858f,U+85ff,U+867b,U+86a8-86a9,U+870a,U+8722,U+876e,U+877c,U+87e5,U+8888,U+88df,U+8919,U+8bcc,U+8bdf,U+8be8,U+8bee,U+8c20,U+8c2f,U+8d36,U+8df8,U+8e05,U+8e2f,U+8f9a,U+9021,U+908b,U+90b4,U+90ba,U+90d0,U+90eb,U+90fe,U+91aa,U+933e,U+9486-9487,U+948d,U+9490,U+94ad,U+94bd,U+94d6,U+94d9,U+9507,U+9546,U+955e,U+956b,U+95e9,U+9604,U+960b,U+9612,U+9615,U+9617,U+96b9,U+989a-989b,U+989e,U+9a78,U+9a7d,U+9aa0,U+9aa2,U+9ac2,U+9b23,U+9b3b,U+9c82,U+9cca,U+9cd9,U+9e28,U+9e5a,U+9e5e,U+9e6c,U+9efe,U+9f0b\",\n },\n },\n {\n uri: _149,\n descriptors: {\n unicodeRange:\n \"U+4e47,U+4e8d,U+4f65,U+4f89,U+50ee,U+520e,U+5416,U+5454,U+54bb,U+54c2,U+54d3,U+54de,U+5591,U+55e5,U+560c,U+566b,U+5769,U+578c,U+5793,U+57e4,U+5889,U+593c,U+59ab,U+5ad4,U+5ad8,U+5af1,U+5b53,U+5ba5,U+5c59,U+5c63,U+5d5b,U+5e0f,U+5e14,U+5edb,U+5fbc,U+6004,U+60ad,U+610e,U+61b7,U+624c,U+634c,U+647a,U+64ba,U+65f0,U+6600,U+66f7,U+67e2,U+67f0,U+680c,U+686b,U+6874,U+691f,U+6989,U+6a17,U+6b81,U+6b84,U+6c06-6c07,U+6c3d,U+6d07,U+6d27,U+6d2b,U+6d91,U+6e6b,U+6e8f,U+6fde,U+70bb,U+723b,U+726e,U+72b0,U+72ce,U+72f2,U+7301,U+731e,U+737e,U+7477,U+748e,U+74ff,U+7633,U+7654,U+771a,U+7726,U+7765,U+7768,U+781c,U+7829,U+78d4,U+7913,U+7957,U+79d5,U+79eb,U+7a70,U+7a86,U+7b25,U+7b38,U+7b47,U+7b72,U+7ba6-7ba7,U+7dae,U+7ee1,U+7efe,U+7f26,U+7f31,U+7f35,U+801c,U+8043,U+809f,U+80ab,U+80d7,U+8118,U+8188,U+81cc,U+823e,U+8244,U+824f,U+82b4,U+82c1,U+82e4,U+82f4,U+8306,U+833a,U+835c,U+839c,U+83b3,U+83bc,U+846d,U+867a,U+868b,U+8734,U+87ca,U+886e,U+887e,U+88a2,U+88c9,U+8921,U+8bb5,U+8bf3,U+8c04,U+8c17,U+8c1d,U+8c25,U+8c36,U+8c55,U+8c78,U+8d3d,U+8d40,U+8d59,U+8d67,U+8d91,U+8dbf,U+8deb-8dec,U+8dfd,U+8e14,U+8e41,U+8f8e,U+900b,U+9044,U+9062,U+90cf,U+9123,U+9146,U+9162,U+9172,U+918d,U+9190,U+92c8,U+93ca,U+948c,U+94aa,U+94b2,U+94c8,U+94ca,U+94d5,U+94df,U+94e9-94ea,U+94f7,U+94fc-94fd,U+951b,U+954f,U+9554,U+9559,U+9566,U+9571-9572,U+95f1,U+9608,U+960f,U+97af,U+988f,U+98d5,U+992e,U+9955,U+9ab0,U+9b32,U+9c90,U+9c9e,U+9ca5,U+9ca9,U+9cad,U+9cb1,U+9cc3,U+9e47,U+9ee7,U+9f87\",\n },\n },\n {\n uri: _150,\n descriptors: {\n unicodeRange:\n \"U+4e93,U+4ec4,U+4ef5,U+4f27,U+4f7b,U+4fe3,U+5080,U+5121,U+51eb,U+5208,U+52f0,U+53f5,U+5453,U+5466,U+54a6,U+54bf,U+54d0,U+5533,U+5549,U+5556,U+556d,U+558f,U+55f2,U+55f5,U+5627,U+567b,U+56d4,U+571c,U+5739,U+57b4,U+5807,U+58c5,U+59a4,U+59af,U+59d8,U+5a09,U+5a0c,U+5a4a,U+5ad2,U+5b6c,U+5ca2,U+5cac,U+5d03,U+5d6c,U+5db7,U+5ebe,U+5f2d,U+5fea,U+6042,U+6120,U+6175,U+6221,U+623e,U+6339,U+638a,U+643d,U+64b8,U+64e2,U+66e9,U+67b3,U+67c1,U+67d2,U+6832,U+6877,U+68f0,U+6934,U+6966,U+6987,U+6998,U+69c1,U+69ce,U+6a3d,U+6a84,U+6aa9,U+6b87,U+6bd6,U+6c16,U+6c18,U+6cd4,U+6cee,U+6de0,U+6e0c,U+6ecf,U+6f4b,U+70b7,U+7168,U+72d9,U+7352,U+73b3,U+73d0,U+7441,U+74d2,U+75a5,U+75e7-75e8,U+7610,U+7619,U+765e,U+772d,U+7812,U+782c,U+784c,U+7850,U+7856,U+789b,U+78f4,U+7a51,U+7b15,U+7b1e,U+7b24,U+7b5a,U+7bb8,U+7bc1,U+7bd9,U+7ed0,U+7ee6,U+7efa,U+7f1b,U+7f1f,U+7f22,U+7f45,U+7f71,U+7fa7,U+7fbf,U+7ff3,U+8052,U+80b1,U+80db,U+80f4,U+81bb,U+81ec,U+8202,U+8210,U+8249,U+828a,U+828e,U+82e3,U+8315,U+8369,U+8378,U+83a8,U+83aa,U+83b4,U+83e1,U+84fc,U+8538,U+853b,U+859c,U+85ae,U+86b4,U+86c9,U+86cf,U+8725,U+879f,U+87b3,U+887d,U+88fe,U+8a8a,U+8ba7,U+8c07,U+8c14,U+8c30,U+8c47,U+8db5,U+8dd7,U+8e1f,U+8e69,U+8e70,U+8e85,U+8f78,U+8f87,U+8f8b,U+8f8f,U+90c4,U+9143,U+917d,U+948f,U+94cd,U+94d2,U+94ef,U+954a,U+9609-960a,U+96d2,U+9708,U+9765,U+97ea,U+9880,U+98a7,U+996c,U+9980,U+9991,U+9a88,U+9ab6,U+9afb,U+9b47,U+9c87,U+9c9b,U+9cb5,U+9cc7,U+9e2c,U+9e42,U+9e58,U+9ecd,U+9ecf,U+9f8a,U+9f8c\",\n },\n },\n {\n uri: _151,\n descriptors: {\n unicodeRange:\n \"U+4ebb,U+4edd,U+4fa9,U+502c,U+50a5,U+51c7,U+51fc,U+523d,U+5241,U+530f,U+5464,U+549d,U+54a3,U+5514,U+5527,U+555c,U+556e,U+5576,U+55b1,U+55b9,U+55eb,U+5624,U+564c,U+5671,U+5685,U+568f,U+56d7,U+56e1,U+57a1,U+57d9,U+5942,U+5a67,U+5c50,U+5c7a,U+5c98,U+5d06,U+5d27,U+5d6f,U+5df3,U+5dfd,U+5e19,U+5ea0,U+5eb9,U+5eea,U+5ffe,U+600f,U+606b,U+6215,U+622c,U+6266,U+62bb,U+62bf,U+6308,U+6387,U+63b8,U+63c4,U+63c6,U+63f6,U+6441,U+6555,U+659b,U+6677,U+66a7,U+6775,U+678b,U+679e,U+6840,U+6849,U+6860,U+68c2,U+6910,U+6a28,U+6a2f,U+6a79,U+6b92-6b93,U+6bc2,U+6bfd,U+6c29,U+6c32,U+6c86,U+6cc5,U+6d0c,U+6d60,U+6da0,U+6ddd,U+6e86,U+6ed3,U+6edf,U+6fb9,U+6fd1,U+6fef,U+7023,U+7080,U+70ca,U+712f,U+7145,U+7284,U+732c,U+73c8,U+73d9,U+740a,U+7457,U+7596,U+759d,U+75a3,U+75d8,U+75e3-75e4,U+75ff,U+7622,U+7688,U+76b4,U+76e5,U+7818,U+7887,U+789a,U+78b2,U+7b08,U+7b33,U+7c2a,U+7ccc,U+7ea8,U+7ec0,U+7fe6,U+8012,U+8084,U+8093,U+80e4,U+80ef,U+8297,U+82a8,U+82be,U+8331,U+8366,U+83c5,U+83fd,U+8473,U+84a1,U+84ca,U+84d1,U+857b,U+85c1,U+85d3,U+8605,U+8662,U+86aa,U+86b1,U+86d4,U+86ed,U+86f3,U+8709,U+8748,U+874c,U+8763,U+89c7,U+89de,U+89e5,U+8a3e,U+8ba6,U+8c00,U+8c21,U+8c49,U+8c7a,U+8d30,U+8df9,U+8e51,U+8e59,U+8f6b,U+8f73,U+8ff3,U+9016,U+9026,U+902f,U+9099,U+909b,U+90c7,U+914a,U+91ae,U+91ba,U+9495,U+94a3,U+94af,U+94ba,U+94bf,U+94cc,U+94e1,U+94f0,U+9531,U+955d,U+95f3,U+9697,U+96bc,U+975b,U+977c,U+98a2,U+998a,U+9994-9995,U+9a9b,U+9ab7,U+9ac5,U+9c91,U+9ccf,U+9cd5,U+9e29,U+9edc,U+9edf,U+9f83,U+9f88-9f89\",\n },\n },\n {\n uri: _152,\n descriptors: {\n unicodeRange:\n \"U+4ee8,U+4f22,U+4f43,U+4f57,U+4f5d,U+4f6f,U+4ff8,U+502d,U+507b,U+5345,U+53df,U+53fb,U+544b,U+5482,U+54a7,U+54cc,U+550f,U+5544,U+5555,U+5594,U+55e8,U+55ec,U+55ef,U+564e,U+56f9,U+5704,U+576d,U+5785,U+57ad,U+5914,U+5958,U+599e,U+59aa,U+59be,U+5a06,U+5abe,U+5ae1,U+5b40,U+5bee,U+5cbf,U+5cc4,U+5ccb,U+5d47,U+603f,U+6078,U+607d,U+607f,U+608c,U+609a,U+60fa,U+61ff,U+621b,U+622e,U+626a,U+6371,U+63ae,U+63cd,U+63d6,U+6410,U+6414,U+6421,U+6448,U+64d8,U+6710,U+6748,U+6772,U+680e,U+6954,U+69ab,U+6c68,U+6c8f,U+6ca4,U+6d2e,U+6e4e,U+6e98,U+6fe0,U+7094,U+70e9,U+7116,U+7119,U+723f,U+73c9,U+74e4,U+753e,U+7548,U+75bd,U+75cd,U+7618,U+7634,U+76c5,U+76f1,U+7708,U+7719,U+777e,U+7791,U+77b3,U+7823,U+7827,U+7830,U+7889,U+7893,U+7949,U+795c,U+79e3,U+7a14,U+7a88,U+7a95,U+7aa0,U+7afd,U+7b90,U+7bd1,U+7bfe,U+7da6,U+7ec2,U+7eef,U+7f03-7f04,U+7f08,U+7f58,U+7f61,U+7f9f,U+8174,U+8200,U+828d,U+82c4,U+82d5,U+82dc,U+82f7,U+832d,U+835a,U+840b,U+8438,U+852b,U+869d,U+86ac,U+86d0,U+86f0,U+8782,U+87a8,U+87d1-87d2,U+87e0,U+8839,U+8913,U+891b,U+8934,U+8941,U+89ca,U+89ce,U+8a07,U+8ba3,U+8bc5,U+8bcb,U+8bdb,U+8c11,U+8c15,U+8c29,U+8c32,U+8dc4,U+8dce,U+8ddb,U+8dfa,U+8e09,U+8e1d,U+8e39,U+8e42,U+8e49,U+8e4b,U+8e8f,U+8f71-8f72,U+9004,U+9036,U+9097,U+90dc,U+90e2,U+90e6,U+90ef,U+9104,U+919a,U+91b4,U+938f,U+9497,U+950f,U+9557,U+9562-9563,U+9573,U+9606,U+9649,U+972d,U+973e,U+97a3,U+97eb,U+988c,U+9894,U+98a6,U+9974,U+9977,U+997d,U+9a90,U+9a9d,U+9aef,U+9ca2,U+9ccd,U+9cdf,U+9e20,U+9e4c,U+9e6b,U+9f3e\",\n },\n },\n {\n uri: _153,\n descriptors: {\n unicodeRange:\n \"U+4ede,U+4ee1,U+4eeb,U+4fda,U+4ffe,U+5025,U+506c,U+50f3,U+5106,U+520d,U+525c,U+52ad,U+530d,U+5310,U+539d,U+53a9,U+53fc,U+5421,U+5477,U+54e7,U+551b,U+5530,U+557e,U+5599,U+55c4,U+55d1,U+55d4,U+55df,U+55e4,U+55ea,U+5623,U+562d,U+5654,U+56eb,U+56f5,U+57a7,U+57d5,U+57dd,U+584d,U+5880,U+58ec,U+59dd,U+5a32,U+5a55,U+5a75,U+5b51,U+5b71,U+5b73,U+5cd2,U+5ce4,U+5e5b,U+5e96,U+5fd2,U+607b,U+61d1,U+634b,U+636d,U+63b3,U+63ff,U+64c0,U+661d,U+6657,U+66dc,U+67a5,U+6841,U+6867,U+6901,U+699b,U+6a47,U+6b46,U+6c21,U+6c24,U+6c35,U+6c4a,U+6c94,U+6ca3,U+6d39,U+6d63,U+6d6f,U+6d94,U+705e,U+71e7,U+726f,U+72cd,U+72de,U+72f0,U+7325,U+7350,U+7391,U+741a,U+757f,U+7583,U+75b1,U+75b4,U+75b8,U+75c2,U+75f1,U+766f,U+7699,U+7751,U+789c,U+7a17,U+7be6,U+7cb2,U+7ea3,U+7eb0,U+7ebe,U+7eeb,U+7f25,U+7f2c,U+7fb8,U+8026,U+8037,U+8153,U+8171,U+8191,U+8214,U+821b,U+8222,U+826e,U+82eb,U+830c,U+8314,U+8334,U+83d6,U+8418,U+843c,U+84ff,U+8564,U+8572,U+8616,U+866c,U+8693,U+86a3,U+86a7,U+86af,U+86b6,U+86c6,U+86ca,U+8708,U+870d,U+8759,U+8760,U+87af,U+87c6,U+8869,U+88c6,U+89d0,U+8b07,U+8baa-8bab,U+8bc2,U+8be4,U+8bf0,U+8c2a,U+8c62,U+8c89,U+8d49,U+8d6d,U+8d84,U+8d94,U+8db8,U+8dc6,U+8e2e,U+8e3d,U+8e47,U+8e7f,U+9005,U+9051,U+907d,U+9082,U+9088,U+90b0,U+90d3,U+9150,U+949c,U+94a4,U+94b9,U+94cb,U+94e0,U+9509,U+9512,U+951f,U+9534,U+9552-9553,U+965f,U+96b0,U+9791,U+9889,U+9990,U+9a9c,U+9aa7,U+9c88,U+9cb2-9cb3,U+9cb6-9cb7,U+9cc5,U+9cdc,U+9e22,U+9e2a,U+9e57,U+9e67,U+9e73,U+9e82,U+9eb8,U+9ee0,U+9f9b\",\n },\n },\n {\n uri: _154,\n descriptors: {\n unicodeRange:\n \"U+4eb5,U+4f09,U+4f5a,U+4f8f,U+4fce,U+4fdf,U+4fea,U+4ff3,U+500c,U+500f,U+504e,U+5088,U+52be,U+5420,U+5457,U+5499,U+549b,U+54c6,U+54d2,U+558b,U+559f,U+55bd,U+55d6,U+565c,U+567c,U+568e,U+5768,U+577b,U+57a9,U+57ed,U+59f9,U+5a11,U+5a40,U+5ae6,U+5b6a,U+5b93,U+5bb8,U+5c15,U+5c99,U+5c9c,U+5cc1,U+5d2e,U+5d4b,U+5d99,U+5e54,U+5e61,U+5fcf-5fd1,U+6002,U+6006,U+6014,U+60af,U+60c6,U+60da,U+60f4,U+621f,U+62c8,U+631b,U+631e,U+63e9,U+64b5,U+655d,U+6619,U+6635,U+6641,U+67ad,U+67b0,U+67b7,U+67e9,U+684e,U+688f,U+695d,U+696b,U+69b7,U+6a58,U+6c26,U+6d35,U+6d43,U+6d9e,U+6dd9,U+6dec,U+6e11,U+6e6e,U+6e9f,U+6ec2,U+6ee2,U+6ef9,U+6f09,U+6f66,U+6f8d,U+6fc2,U+6fc9,U+729f,U+72c8,U+73de,U+7430,U+7566,U+7579,U+75c9,U+75e2,U+75fc,U+762a,U+7638,U+7678,U+76c2,U+76f9,U+778c,U+77cd,U+77dc,U+7800,U+781d,U+782d,U+783b-783c,U+78a3,U+78ec,U+7980,U+7a23,U+7b95,U+7bdd,U+7c0c,U+7c41,U+7c91,U+7cb3,U+7cc5,U+7ecc,U+7f19,U+7fca,U+8006,U+8069,U+807f,U+80bd,U+80ed,U+814b,U+8198,U+82cb,U+82d2,U+834f,U+8360,U+847a,U+84d6,U+84e5,U+8537,U+85d0,U+8671,U+86a4,U+86ce,U+86f9,U+8703,U+8707,U+8737,U+873b,U+8815,U+8936,U+8bc3,U+8bcf,U+8bd2,U+8bd8,U+8be9,U+8c0c,U+8c0f,U+8c4c,U+8d45,U+8d5d,U+8d73,U+8e31,U+8e6d,U+8e76,U+8fe4,U+9041,U+90d7,U+9169,U+92ae,U+94a1,U+94c4,U+94c9,U+94db,U+94e7,U+9503,U+9506,U+9517,U+9528,U+9537,U+9542,U+9549,U+95fe,U+9616,U+961a,U+96c9,U+96f3,U+9701,U+970e,U+9739,U+9753,U+9798,U+98d2-98d3,U+98d9-98da,U+9968,U+996f,U+9984,U+9997,U+9acb,U+9b03,U+9c85,U+9ca8,U+9cab,U+9e49,U+9e51,U+9e66,U+9f10\",\n },\n },\n {\n uri: _155,\n descriptors: {\n unicodeRange:\n \"U+4e15,U+4e1e,U+4e2b,U+4eb3,U+4ec9,U+4f0e,U+4f64,U+501c,U+50a9,U+510b,U+51a2,U+51bc,U+527d,U+52d0,U+53fd,U+5429,U+542e,U+5486,U+54af,U+5506,U+5511,U+5522,U+552c,U+556c,U+55b3,U+55d2,U+55e6,U+55fd,U+561f,U+5639,U+5659,U+5662,U+5693,U+572a,U+5892,U+598a,U+5992,U+59a9,U+5a20,U+5ae3,U+5b17,U+5b7d,U+5d34,U+5d3d,U+5d4a,U+5d82,U+5e1a-5e1b,U+5ea5,U+5f0b,U+5f77,U+5fd6,U+5fff,U+6026,U+6035,U+6063,U+60b4,U+60bb,U+60ee,U+612b,U+6194,U+61ca,U+61e6,U+61f5,U+620a,U+6248,U+62a1,U+62d7,U+6376,U+637b,U+652b,U+65bc,U+65cc,U+65ce,U+65d6,U+664c,U+665f,U+6666,U+6684,U+66b9,U+6773,U+6777,U+6787,U+67de,U+6845,U+693d,U+6994,U+6a35,U+6d54,U+6d5c,U+6d8e,U+6dd6,U+6eb4,U+6f2a,U+6f78,U+704f,U+70ec,U+7118,U+714a,U+7172,U+71b9,U+724d,U+728a,U+7337,U+733e,U+7396,U+73b7,U+73cf,U+7428,U+742c,U+742e,U+74ee,U+74f4,U+7525,U+753a,U+7572,U+75d4,U+765c,U+768e,U+7762,U+777d,U+77fd,U+7825,U+7837,U+78b4,U+795f,U+79ed,U+7a1e,U+7b06,U+7b20,U+7ba9,U+7bab,U+7c7c,U+7cbd,U+7cdc,U+7ec9,U+7ef6,U+7f30,U+7f42,U+7f44,U+7f54,U+7f94,U+8004,U+800b,U+8019,U+809b,U+80ae,U+80c4,U+80f1,U+8146,U+816e,U+817c,U+81c0,U+81fc,U+81fe,U+822b,U+830f,U+832f,U+8340,U+8365,U+8385,U+8392,U+83a0,U+8424,U+84af,U+869c,U+8713,U+8717-8718,U+87c0,U+87cb,U+87fe,U+8821,U+8902,U+89d1,U+8bb9,U+8c12,U+8d32,U+8d53,U+8df7,U+8e7c,U+8f7c,U+8f95,U+8fab,U+9052,U+905b,U+9095,U+909d,U+90c5,U+911e,U+9122,U+916a,U+919b,U+948e,U+9492,U+949a,U+94b5,U+94bc,U+94c6,U+94f1,U+9502,U+9511,U+9536,U+956f-9570,U+9602,U+9621,U+9631,U+998b,U+99a5,U+9a81,U+9a9e,U+9ebe,U+9f8b\",\n },\n },\n {\n uri: _156,\n descriptors: {\n unicodeRange:\n \"U+4f2b,U+4f3d,U+4fac,U+5043,U+5055,U+5140,U+5156,U+51cb,U+5243,U+531d,U+536f,U+53a5,U+53ae,U+53f1,U+541d,U+5431,U+547b,U+5492,U+5494,U+54a4,U+54aa,U+54ce,U+54fd,U+5509,U+5520,U+553e,U+557b,U+55c5,U+55e1,U+55f7,U+5608,U+5636,U+563b,U+5773,U+57a0,U+5811,U+587e,U+58d5,U+59e3,U+5a29,U+5a6a,U+5a76,U+5a7a,U+5ac9,U+5b62,U+5b95,U+5c49,U+5c8c,U+5cab,U+5cb7,U+5d02,U+5d58,U+5e44,U+5e7a,U+5eff,U+5f29,U+5f89,U+5f9c,U+5fa8,U+6005,U+6043,U+60b8,U+60d8,U+60ec,U+60f0,U+6115,U+618e,U+630e,U+637a,U+6390,U+63ac,U+63b0,U+64de,U+6525,U+6538,U+65ee-65ef,U+6631,U+6636,U+6654,U+677c,U+67b8,U+67d8,U+683e,U+6886,U+68b5,U+692d,U+6963,U+6979,U+6988,U+6b59,U+6b9a,U+6c69,U+6c74,U+6cae,U+6ce0,U+6cef,U+6d95,U+6dc5,U+6dde,U+6de6,U+6dfc,U+6ea7,U+6f15,U+6f29,U+7096,U+70c3,U+7131,U+715c,U+7166,U+7266,U+7317,U+731d,U+7329,U+73e9,U+7425,U+7455,U+7490,U+74ef,U+7519,U+75b5,U+75b9,U+75de,U+7656,U+7663,U+7691,U+7729,U+77fe,U+783e,U+787c,U+795a,U+7a79,U+7abf,U+7b3a,U+7b4f,U+7b60,U+7b75,U+7b8d,U+7bb4,U+7bd3,U+7be1,U+7cbc,U+7edb,U+7f1c,U+7f8c,U+7fb2,U+7fb9,U+7fce,U+7ff1,U+810d,U+81c6,U+82a5,U+82aa,U+82de,U+8317,U+8343,U+835e,U+8364,U+836a,U+853a,U+8543,U+854a,U+8559,U+8568,U+85b0,U+85b9,U+864f,U+86e4,U+8715,U+8845,U+8884,U+88e8,U+88f1,U+8983,U+8be1,U+8c1f,U+8c27,U+8c5a,U+8c82,U+8d58,U+8dbe,U+8f98,U+9035,U+9074,U+90a1,U+9149,U+9157,U+93d6,U+949d,U+94c2,U+94e3-94e4,U+95eb,U+95f0,U+9611,U+9619,U+9642,U+968d,U+9706,U+970f,U+97ed,U+988a,U+9893,U+98e8,U+9a77,U+9a87,U+9aa1,U+9abc,U+9cdd,U+9e2f,U+9e33,U+9e44,U+9e5c,U+9e9d,U+9edd\",\n },\n },\n {\n uri: _157,\n descriptors: {\n unicodeRange:\n \"U+4f58,U+4f6c,U+4f70,U+4fd0,U+5014,U+51bd,U+524c,U+5315,U+5323,U+535e,U+540f,U+542d,U+545b,U+548e,U+549a,U+54ab,U+54fc,U+5567,U+556a,U+5600,U+5618,U+563f,U+5669,U+56f1,U+56ff,U+573b,U+574d,U+579b,U+57b8,U+57c2,U+586c,U+58f9,U+595a,U+598d,U+5993,U+5996,U+59d7,U+5b7a,U+5ba6,U+5c4e,U+5c96,U+5ce5,U+5eb6,U+5f08,U+5f99,U+602f,U+6059,U+606c,U+607a,U+60ed,U+61a9,U+620c,U+6249,U+62a8,U+62c4,U+62ed,U+62fd,U+6342,U+6345,U+6396,U+63a3,U+6402,U+6413,U+642a,U+6487,U+64a9,U+64ac,U+64ae,U+64b7,U+659f,U+65a1,U+667e,U+66f3,U+67e0,U+69db,U+69df,U+6aac,U+6b86,U+6c50,U+6c5e,U+6c76,U+6c85,U+6c8c,U+6cde,U+6d19,U+6d52,U+6da7,U+6db8,U+6e1a,U+6e25,U+6e4d,U+6e5f,U+6ec1,U+6f31,U+6f7a,U+6fa7,U+6fe1,U+701b,U+70ab,U+70f7,U+717d,U+71a8,U+7252,U+72c4,U+72e1,U+7315,U+736d,U+73ae,U+73c0,U+73c2,U+740f,U+75a4,U+7600-7601,U+768b,U+76bf,U+76d4,U+7728,U+772f,U+776c,U+77a0,U+77b0,U+77f8,U+783a,U+78d0,U+78fa,U+7977,U+7a37,U+7a92,U+7afa,U+7b71,U+7b94,U+7cef,U+7f28,U+7fe1,U+808b,U+80e5,U+80eb,U+8110,U+8113,U+812f,U+814c,U+81c3,U+8235,U+82d4,U+8309,U+83c1,U+8431,U+8469,U+84bf,U+84d3,U+84df,U+84e6,U+8511,U+8638,U+86c0,U+86db,U+86fe,U+8757,U+8822,U+8882,U+8885,U+8892,U+88f3,U+892a,U+8ba5,U+8bd9,U+8be0,U+8be7,U+8bfd,U+8c1a,U+8d4a,U+8d4e,U+8d66,U+8dda,U+8e0c,U+8e52,U+8e74,U+8e87,U+8f76,U+8fc2,U+8fe6,U+900d,U+9068,U+90ac,U+90b3,U+90b8,U+90e7,U+9119,U+9131,U+915a,U+916e,U+94b4,U+94d0,U+94e2,U+94ec,U+94ff,U+9522,U+9535,U+9556,U+965b,U+96f9,U+9774,U+9981,U+998d,U+998f,U+9a6e,U+9a7f,U+9a8a,U+9b13,U+9c9f,U+9e3e,U+9e43,U+9e6d,U+9e8b,U+9e92,U+9edb,U+9eef\",\n },\n },\n {\n uri: _158,\n descriptors: {\n unicodeRange:\n \"U+4e10,U+4e56,U+4e98,U+4ec3,U+4f3a,U+4f5f,U+4f88,U+4f97,U+4fa5,U+4fe8,U+504c,U+5197,U+52fa,U+5364,U+53e8,U+5406,U+543c,U+545c,U+5471,U+5480,U+5495,U+54b3,U+54df,U+54e6,U+54ee,U+557c,U+5583,U+55dc,U+55e3,U+566c,U+592f,U+5944,U+5983,U+59ca,U+59e5,U+5a13,U+5a7f,U+5b09,U+5bd0,U+5e4c,U+5eb5,U+5f1b,U+5f3c,U+608d,U+60cb,U+61a7,U+61ac,U+61cb,U+6233,U+62a0,U+62e7,U+62ee,U+62f4,U+62f7,U+634e,U+6382,U+63c9,U+63ea,U+6400,U+645e,U+6482,U+6556,U+6593,U+6615,U+664f,U+66e6,U+672d,U+675e,U+67da,U+6805,U+6808,U+6868,U+68a2,U+695e,U+69ad,U+6a80,U+6a90,U+6b83,U+6be1,U+6c30,U+6cad,U+6cb1,U+6cf1,U+6d31,U+6d93,U+6dae,U+6dbf,U+6dc6-6dc7,U+6e0d,U+6e32,U+6e3a,U+6e85,U+6eba,U+6f3e,U+6f5e,U+6f7c,U+6fee,U+71ee,U+722a,U+72b7,U+72e9,U+73ba,U+73d1,U+7409,U+7435-7436,U+7459-745a,U+747e,U+7487,U+74e2,U+7504,U+752c-752d,U+7599,U+759f,U+75a1,U+75ca,U+75f0,U+761f,U+7629,U+777f,U+7785,U+77a5,U+77bf,U+78d5,U+7934,U+7940,U+79a7,U+7b19,U+7c38,U+7c95,U+7cb1,U+7ce0,U+7eca,U+7ef7,U+7f2b,U+7f81,U+7fcc,U+8046,U+8148,U+8165,U+819b,U+81ba,U+828b,U+82ae,U+82b7,U+82d3,U+8301,U+830e,U+831c,U+8338,U+837c,U+8393,U+8398,U+83ba,U+83e0,U+83e9,U+853c,U+8654,U+86df,U+8712,U+873f,U+874e,U+8783,U+8859,U+88a4,U+8925,U+8bb7,U+8bff,U+8c19,U+8c1b,U+8c24,U+8c2c,U+8d61,U+8db4,U+8e6c,U+8f8a,U+8fe5,U+8ff8,U+901e,U+90f4,U+912f,U+9163,U+9170,U+91dc,U+949b,U+94a8,U+94b3,U+94c0,U+94e8,U+9525,U+9530,U+9539,U+954c-954d,U+9550,U+955b,U+962a,U+9685,U+96cc,U+9776,U+988d,U+9975,U+9985,U+9a6f,U+9aa5,U+9ab8,U+9c7f,U+9ca4,U+9cb8,U+9e25,U+9e35,U+9e4a\",\n },\n },\n {\n uri: _159,\n descriptors: {\n unicodeRange:\n \"U+4ea2,U+4ea5,U+4f36,U+4f84,U+4f8d,U+501a,U+5029,U+516e,U+51a5,U+51c4,U+51f8,U+5201,U+527f,U+5321,U+5352,U+5366,U+53e9,U+54c7,U+5632,U+5676,U+56b7,U+56bc,U+56da,U+56e4,U+5703,U+5729,U+5742,U+57a2-57a3,U+5815,U+58d1,U+5919,U+592d,U+5955,U+5a05,U+5a25,U+5a34,U+5b70,U+5b75,U+5bdd,U+5bf0,U+5c41,U+5c79,U+5c91,U+5c94,U+5ce6,U+5ced,U+5d69,U+5dc5,U+5e16,U+5e27,U+5f27,U+5f95,U+5ffb,U+6020,U+604d,U+6055,U+60e6,U+60eb,U+6123,U+618b,U+61a8,U+620d,U+62c7,U+62ce,U+62d9,U+631f,U+634d,U+6452,U+6479,U+64ce,U+64d2,U+655b,U+660a,U+6726,U+67c4,U+6809,U+6853,U+68e3,U+68f1,U+68fa,U+693f,U+6942,U+6995,U+69a8,U+69b4,U+6a71,U+6b89,U+6bcb,U+6bd3,U+6bd9,U+6c40,U+6cf8,U+6cfe,U+6d85,U+6da3,U+6daa,U+6e0e,U+6e43-6e44,U+6f88,U+7078,U+7099,U+70bd,U+70d9,U+70fd,U+7109,U+7184,U+7239,U+733f,U+73f2,U+748b,U+749c,U+749e,U+759a,U+75d2,U+75eb,U+7620,U+766b,U+7693,U+76cf,U+7738,U+773a,U+776b,U+778e,U+77aa,U+7852,U+78be,U+7948,U+795b,U+7960,U+796f,U+79ba,U+7a20,U+7a96,U+7aa5,U+7b03,U+7b28,U+7b50,U+7b77,U+7bc6,U+7bf1,U+7c27,U+7d0a,U+7ead,U+7ec5,U+7ee2,U+7ef0,U+7efd,U+7f0e,U+7f2e,U+7f79,U+7f9a,U+8098,U+80da,U+80e7,U+80f0,U+80f3,U+80fa,U+818a,U+81e7,U+8237-8238,U+8299,U+82b8,U+82ce,U+837b,U+83bd,U+83cf,U+8426,U+8475,U+85c9,U+85d5,U+85dc,U+85e9,U+871a,U+8747,U+8749,U+888d,U+8910,U+891a,U+8bb4,U+8be3,U+8bec,U+8bf2,U+8c06,U+8c0d,U+8d31,U+8d48,U+8de4,U+8e1e,U+8e4a,U+8e66,U+8f84,U+8f97,U+9083,U+90e1,U+9165,U+91c9,U+94b0,U+94f5,U+9504,U+9532,U+956d,U+95f5,U+95fa,U+9668,U+9698,U+96bd,U+9704,U+9773,U+9890,U+996a,U+997a,U+9a74,U+9a8b,U+9cc4,U+9ccc\",\n },\n },\n {\n uri: _160,\n descriptors: {\n unicodeRange:\n \"U+4ea8,U+4f1e,U+4f51,U+4f63,U+4f7c,U+4f83,U+4fa0,U+4fd1,U+4ffa,U+5018,U+5026,U+508d,U+50bb,U+50f5,U+50fb,U+5162,U+5319,U+5320,U+538c,U+5413,U+541f,U+5475,U+54bd,U+54d1,U+5589,U+5598,U+575f,U+57ae,U+57e0,U+5937,U+5974,U+5978,U+59ae,U+5a1f,U+5a49,U+5ab3,U+5b99,U+5b9b,U+5ba0,U+5be1,U+5be5,U+5c09,U+5c27,U+5de2,U+5e9a,U+5f26,U+5f8a,U+5f98,U+6021,U+606d,U+60bc,U+60d5,U+60e7,U+611a,U+614c,U+6254,U+626f,U+6292,U+6296,U+62b9,U+62e2,U+631a,U+631d,U+6320,U+6346,U+63ba,U+6467,U+64bc,U+658b,U+663c,U+6643,U+6652,U+6656,U+6687,U+66d9,U+66dd,U+66f0,U+673d,U+67ab,U+6816-6817,U+68a7,U+68ad,U+68cd,U+68e0,U+6986,U+69fd,U+6b47,U+6bd7,U+6c1f,U+6c2e-6c2f,U+6cbe,U+6de4,U+6e1d,U+6e83,U+6e9c,U+6ed4-6ed5,U+6f4d,U+70f9,U+7130,U+716e,U+718f,U+71ac,U+71e5,U+72fc,U+731c,U+7334,U+73ca,U+7422,U+7426,U+745f,U+7470,U+75af,U+75f4,U+762b,U+763e,U+7696,U+7737,U+7741,U+77a7,U+77bb,U+77ee,U+785d,U+788c,U+78ca,U+7901,U+796d,U+7985,U+79fd,U+7a3c,U+7a57,U+7a74,U+7b5b,U+7caa,U+7cb9,U+7cd5,U+7eac,U+7eb6,U+7ed1,U+7ee5,U+7f20,U+7f2a,U+7f38,U+7f69,U+7fa1,U+8018,U+8038,U+803f,U+804b,U+80a2,U+80be,U+80d6,U+817a,U+81fb,U+820c,U+82ad,U+82af,U+82bd,U+8327,U+8354,U+835f,U+8367,U+836b,U+840c,U+841d,U+8471,U+849c,U+84b2,U+84c9,U+8517,U+851a,U+8549,U+8681,U+8721,U+8776,U+88d9,U+88f9,U+89c5,U+8c1c,U+8c34,U+8d81,U+8d9f,U+8e0a,U+8e72,U+8eb2,U+8fed,U+901b,U+902e,U+906e,U+9091,U+90aa,U+90af,U+915d,U+9171,U+946b,U+9489,U+9499,U+94a5,U+9508,U+9524,U+952d,U+9551,U+9576,U+95f7,U+9600,U+96b6,U+96c0,U+9756,U+97f6,U+98a0,U+98a4,U+997f,U+9a73,U+9a86,U+9ad3,U+9e3d,U+9ed4\",\n },\n },\n {\n uri: _161,\n descriptors: {\n unicodeRange:\n \"U+4e4d,U+4e5e,U+4ec7,U+4ed5,U+50da,U+50e7,U+515c,U+51a4,U+51ff,U+5203,U+5254,U+5300,U+533e,U+5375,U+53ee,U+5435,U+543b,U+5455,U+548b,U+548f,U+54d7,U+54fa,U+5578,U+5587,U+55a7,U+560e,U+5760,U+576f,U+5777,U+5830,U+58a9,U+5962,U+59e8,U+5a07,U+5a23,U+5a3c,U+5b5a,U+5bb5,U+5bc5,U+5bde,U+5c7f,U+5cb1,U+5ce8,U+5cea,U+5d29,U+5d4c,U+5e18,U+5f57,U+5f5d,U+5f87,U+5ff1,U+6016,U+601c,U+6064,U+6177,U+61d2,U+625b,U+62e3,U+62f1,U+634f,U+63a0,U+6401,U+6405,U+6495,U+64c2,U+6512,U+6577,U+6590,U+65a7,U+65a9,U+65f7,U+6627,U+6655,U+6714,U+6795,U+67d1,U+67ff,U+68b3,U+68d5,U+68d8,U+6930,U+6960,U+6977,U+69bb,U+69d0,U+6a31,U+6b7c,U+6bb4,U+6c22,U+6c72,U+6c79,U+6c7e,U+6c81,U+6c93,U+6ca5,U+6cbc,U+6ce3,U+6cfb,U+6d3c,U+6da9,U+6df3,U+6e2d,U+6eaf,U+6ec7,U+6f13,U+6f33,U+6f62,U+6fa1,U+7011,U+707c,U+708a,U+70c1,U+70d8,U+70eb,U+711a,U+7194,U+7281,U+7316,U+7357,U+7384,U+7405,U+742a,U+745b,U+7574,U+7578,U+75ea,U+7682,U+7792,U+77d7,U+77e9,U+77eb,U+77f6,U+780c,U+78c5,U+7941,U+79e4,U+7a1a,U+7a9c,U+7ad6,U+7b5d,U+7bf7,U+7c07,U+7c3f,U+7c9f,U+7ca5,U+7cdf,U+7e82,U+7eab,U+7ece,U+7eda,U+7f09,U+7f15,U+7f9e,U+7fdf,U+7fe9,U+803b,U+803d,U+80aa,U+80b4,U+813e,U+8155,U+817b,U+819d,U+821c,U+82b9,U+82df,U+82ef,U+8304,U+83b9,U+8446,U+853d,U+85af,U+85fb,U+8650,U+865e,U+86d9,U+86ee,U+8700,U+8862,U+889c,U+88d4,U+88f8,U+895f,U+8a79,U+8bb3,U+8bb6,U+8bc0,U+8beb,U+8bf5,U+8c23,U+8c79,U+8d1e,U+8dcb,U+8e29,U+8e44,U+8e81,U+8eac,U+8eaf,U+8f8d,U+9050,U+90f8,U+914b,U+948a,U+94be,U+94ee,U+950c,U+9540,U+962e,U+9647,U+9661,U+9699,U+96cf,U+9716,U+9761,U+97a0,U+97e7,U+9a7c,U+9a8f,U+9ae6,U+9cd6,U+9e26\",\n },\n },\n {\n uri: _162,\n descriptors: {\n unicodeRange:\n \"U+4fa3,U+4fae,U+4fd8,U+4fef,U+50a3,U+5189,U+5195,U+51db,U+51f3,U+51f9,U+5220,U+5228,U+5288,U+52ff,U+532e,U+533f,U+5351,U+53db,U+53ed,U+5450,U+5484,U+5490,U+54c9,U+54e9,U+5501,U+5507,U+5543,U+55d3,U+56a3,U+575e,U+589f,U+5984,U+59ec,U+5a04,U+5a36,U+5a77,U+5a9a-5a9b,U+5ab2,U+5ac2,U+5ad6,U+5bc7,U+5c2c,U+5c34,U+5c51,U+5cd9,U+5d0e,U+5deb,U+5e3c,U+5e87,U+5ed3,U+5f13,U+5f64,U+5fe1,U+606a,U+6096,U+60df,U+60f6,U+60f9,U+6151,U+620e,U+6241,U+6252,U+6273,U+627c,U+6289,U+62c2,U+62cc,U+62ef,U+6361,U+6363,U+63b7,U+63e3,U+6518,U+66ae,U+6756,U+6789,U+6813,U+6829,U+6862,U+6866,U+6893,U+6897,U+690e,U+6984,U+69cc,U+6a1f,U+6a44,U+6a59,U+6ba1,U+6c13,U+6c90,U+6ca6,U+6cbd,U+6ccc,U+6cd3,U+6cd7,U+6d4a,U+6d4f,U+6d5a,U+6d9f,U+6da1,U+6dcc,U+6ea5,U+6ee4,U+6ee6,U+6f2f,U+6f8e,U+701a,U+7095,U+709c,U+70af,U+70db,U+70e8,U+714e,U+715e,U+71a0,U+71ce,U+7235,U+7280,U+72d0,U+72f8,U+73ab,U+7410,U+745c,U+7480,U+74a7-74a8,U+74e3,U+75ae,U+75f9,U+76b1,U+76ce,U+7736,U+77e2-77e3,U+781a,U+789f,U+797a,U+79be,U+79c3,U+79c6,U+79f8,U+7a8d,U+7a98,U+7aa6,U+7aff,U+7b1b,U+7cd9,U+7d6e,U+7ede,U+7eee,U+7f00,U+7f24,U+7f2d,U+7fd8,U+800d,U+8116,U+8151,U+81b3,U+8205,U+82c7,U+82db,U+832c,U+8335,U+8339,U+8386,U+846b,U+8587,U+8611,U+8682,U+868a,U+868c,U+8774,U+88d8,U+88f4,U+8912,U+8b6c,U+8bbd,U+8c0e,U+8c41,U+8d26,U+8d3b-8d3c,U+8d50,U+8dea,U+8e35,U+8f99,U+8fe2,U+8fe9,U+9017,U+914c,U+916f,U+9175-9176,U+918b,U+94a0,U+94ae,U+94ce,U+94f2,U+951a,U+952f,U+9541,U+9640,U+9672,U+968b,U+96cd,U+96ef,U+9713,U+97ec,U+9885,U+9992,U+9a6d,U+9a79,U+9a85,U+9cbb,U+9cd7,U+9cde,U+9e93,U+9f9f\",\n },\n },\n {\n uri: _163,\n descriptors: {\n unicodeRange:\n \"U+4e11,U+4ed7,U+4fcf,U+4fe9,U+4fed,U+50ac,U+50b2,U+5112,U+5180,U+5188,U+51f6,U+522e,U+5265,U+52cb,U+52df,U+5349,U+5367,U+5378,U+537f,U+5395,U+5398,U+53d4,U+543e,U+5440,U+5446,U+54b8,U+5565-5566,U+5580,U+55bb,U+56ca,U+572d,U+573e,U+574e,U+5782-5784,U+58f3,U+5938-5939,U+5948,U+594e,U+5a1c,U+5a74,U+5ae9,U+5b55,U+5b5c,U+5bb0,U+5bd3,U+5bf8,U+5c3f,U+5d14,U+5d2d,U+5df7,U+5dfe,U+5e05-5e06,U+5e1c,U+5e62,U+5e7b,U+5e7d,U+5ed6,U+5f2f,U+5f66,U+5f6c,U+5fa1,U+604b,U+609f,U+60a6,U+60e8,U+6101,U+6124,U+6127,U+6148,U+61be,U+6247,U+62d8,U+62da,U+633d,U+635e,U+6367,U+6380,U+638f,U+63a9,U+63fd,U+641c,U+64e6,U+655e,U+6572,U+6591,U+65a5,U+6691,U+6735,U+67a2-67a3,U+67ef,U+680b,U+6876,U+6905,U+6a0a,U+6a61,U+6b79,U+6bb7,U+6bbf,U+6c41,U+6c55,U+6c83,U+6c9b,U+6ca7,U+6cfc,U+6d46,U+6d51,U+6d74,U+6d9d,U+6daf,U+6dc0,U+6deb,U+6e17,U+6e24,U+6e89,U+6ea2,U+6ef4,U+6f6d,U+707f,U+70b3,U+70e4,U+70ef,U+710a,U+722c,U+725f,U+7261,U+72ee,U+72f1,U+730e,U+732b,U+7433,U+7538,U+75bc,U+7624,U+7709,U+7750,U+7779,U+7802,U+7898,U+78a7,U+78b1,U+78cb,U+78f7,U+7984,U+7a83,U+7aed,U+7b3c,U+7b4b,U+7c92,U+7c98,U+7ca4,U+7eb9,U+7ee3,U+7ef3,U+7ef5,U+7f05,U+7f55,U+7f62,U+7fc1,U+7fd4,U+7fe0,U+8042,U+806a,U+80a0,U+80a4,U+80c3,U+8102,U+8106,U+814a,U+8154,U+8247,U+8258,U+82cd,U+8328,U+832b,U+8389,U+83ca,U+845b,U+846c,U+84b8,U+8574,U+859b,U+8680,U+8695,U+86c7,U+8702,U+886c,U+8896,U+88b1,U+88e4,U+8bc8,U+8c10,U+8c26,U+8c28,U+8c2d,U+8d4c,U+8d63,U+8f67,U+8f74,U+8fc4,U+9006,U+9063,U+90a2,U+90b1,U+90c1,U+9177,U+9189,U+9493,U+949e,U+94fe,U+9610,U+961c,U+96a7,U+96fe,U+978d,U+97f5,U+9888,U+997c,U+9a84,U+9b3c,U+9b44-9b45,U+9b54,U+9e64,U+9f0e,U+9f9a\",\n },\n },\n {\n uri: _164,\n descriptors: {\n unicodeRange:\n \"U+4e19,U+4e38,U+4e53,U+4e7e,U+4e9f,U+4ec6,U+4f50,U+4fde,U+502a,U+5154,U+517d,U+51d1,U+51f0,U+5239,U+5256,U+52c9,U+52fe,U+5308,U+532a,U+535c,U+5384,U+53a2,U+53a8,U+53c9,U+53e0,U+5496,U+54ac,U+54c0,U+54c4,U+54e8,U+5561,U+5582,U+561b,U+5631,U+566a,U+5764,U+576a,U+5792,U+57ab,U+584c,U+5885,U+58f6,U+59a8,U+5acc,U+5bc2,U+5c38-5c39,U+5c60,U+5c6f,U+5c82,U+5c90,U+5d16,U+5dcd,U+5e37,U+5e90,U+5eb8,U+5f6a,U+5fcc,U+6012,U+6068,U+6073,U+607c,U+6094,U+6109,U+621a,U+626e,U+6284,U+62d0,U+62e6,U+62fe,U+6321,U+6328,U+632b,U+6349,U+6454,U+65ed,U+660f,U+6674,U+66a8,U+6749,U+674f,U+6760,U+67af,U+6850,U+6854,U+6869,U+68a8,U+68d2,U+68f5,U+6912,U+6b49,U+6b6a,U+6bef,U+6c28,U+6c5d,U+6c82,U+6cab,U+6cb8,U+6cc4,U+6cf5,U+6d47,U+6d78,U+6da4,U+6dc4,U+6dcb,U+6df9,U+6e0a,U+6e23,U+6e5b,U+6eb6,U+6f06,U+6f47,U+6f84,U+6f9c,U+6fd2,U+7076,U+70ac,U+7199,U+723d,U+72ac,U+72ed,U+7476,U+7529,U+752b,U+754f,U+7554,U+75d5,U+7626,U+76ef,U+7720,U+7766,U+7784,U+77ac,U+780d,U+7838,U+7845,U+786b,U+78b3,U+7978,U+79b9,U+79c9,U+79e7,U+7a3d,U+7a84,U+7a9f,U+7b0b,U+7b52,U+7c7d,U+7f1a,U+7fc5,U+7ff0,U+804a,U+8086-8087,U+808c,U+809a,U+80ba,U+810a,U+8180,U+818f,U+81c2,U+81ed,U+8231,U+8292,U+829c,U+82a6,U+82d1,U+8346,U+838e,U+839e,U+83c7,U+83f1,U+8403,U+840e,U+8513,U+857e,U+85e4,U+867e,U+871c,U+87ba,U+87f9,U+884d,U+8944,U+8a93,U+8c05,U+8d2c,U+8d2e,U+8d42-8d43,U+8dfb,U+8e22,U+8eba,U+8f69,U+8f9c,U+8fa3,U+8fa8,U+8fb1,U+900a,U+9038,U+903b,U+9042,U+904f,U+90b5,U+90dd,U+9102,U+9187,U+94a7,U+94c5,U+9523,U+95f8,U+95fd,U+960e,U+964b-964c,U+96c1,U+9709,U+971c,U+97ad,U+9882,U+9965,U+9976,U+9988,U+99a8,U+9a82,U+9a9a,U+9b41,U+9c8d,U+9e45,U+9e70,U+9e9f,U+9f3b,U+9f7f\",\n },\n },\n {\n uri: _165,\n descriptors: {\n unicodeRange:\n \"U+4e08,U+4e18,U+4e1b,U+4e22,U+4e27,U+4e32,U+4e52,U+4e73,U+4ead,U+4ed4,U+4ed9,U+4ef0,U+4fa6,U+5076,U+5179,U+51bb,U+51c9,U+51ef,U+51fd,U+524a,U+526a,U+529d,U+52ab,U+5306,U+5339,U+53d9,U+540a,U+5410,U+541e,U+5439,U+54b1,U+54ed,U+5564,U+558a,U+55b7,U+5634,U+574a,U+5751,U+57a6,U+57cb,U+57d4,U+5824,U+582a,U+5835,U+5858,U+5893,U+58e4,U+5951,U+5986,U+59da,U+59fb,U+59ff,U+5a03,U+5a46,U+5ac1,U+5b5d,U+5bfa,U+5c18,U+5c3a,U+5c48,U+5c4f,U+5c61,U+5cb3,U+5d1b,U+5e15,U+5e3d,U+5e99,U+5e9e,U+5eca,U+5f0a,U+5f17-5f18,U+5f25,U+5f7c,U+5fcd,U+6028,U+60a0,U+60ac,U+60d1,U+614e,U+6155,U+6168,U+61c8,U+6208,U+6212,U+6251,U+629a-629b,U+62ab-62ac,U+62fc,U+6323,U+632a,U+63d2,U+643a,U+6491-6492,U+649e,U+64b0,U+64c5,U+659c,U+6614,U+662d,U+6664,U+6670,U+6676,U+6746,U+67cf,U+67d4,U+682a,U+6843,U+6846,U+68da,U+6b3a,U+6b67,U+6c27,U+6c5b,U+6c64,U+6c70,U+6caa,U+6cca,U+6ce1,U+6d12,U+6d45,U+6dd1,U+6dd8,U+6e34,U+6e7f,U+6ee5,U+6f02,U+7092,U+70c2,U+70e6,U+7115,U+7237,U+7272,U+727a,U+72c2,U+739b,U+73b2,U+743c,U+751c,U+758f,U+75b2,U+7686,U+76c6,U+76d2,U+76fc,U+775b,U+77a9,U+7816,U+788e,U+7897,U+78b0,U+79bd,U+7a0d,U+7a91,U+7a9d,U+7ae3,U+7bad,U+7cca,U+7d2b,U+7eb1,U+7f06,U+7f14,U+7f1d,U+7f50,U+7ffc,U+8036,U+80bf,U+80c1,U+80ce,U+80f8,U+8109,U+810f,U+8170,U+8179,U+819c,U+821f,U+8230,U+8236,U+8273,U+829d,U+82f9,U+8305,U+8350,U+83b2,U+83cc,U+8404,U+840d,U+8427,U+8482,U+8679,U+8854,U+886b,U+8bbc,U+8be6,U+8c31,U+8c6b,U+8d4b,U+8dcc,U+8e2a,U+8e48,U+8f90,U+8fb0,U+9022,U+903c,U+903e,U+9065,U+916c,U+917f,U+94a9,U+94c3,U+94dd,U+94ed,U+9510,U+953b,U+96c7,U+970d,U+9738,U+9877,U+987d,U+989c,U+98d8,U+9a70,U+9a91,U+9aa4,U+9b42,U+9b4f,U+9e2d,U+9e3f,U+9e7f,U+9f20\",\n },\n },\n {\n uri: _166,\n descriptors: {\n unicodeRange:\n \"U+4e59,U+4ed3,U+4f0f,U+4f38,U+4f69,U+4fa7,U+4faf,U+4ff1,U+5077,U+5085,U+5144,U+5151,U+51af,U+51b6,U+51cc,U+523a,U+5251,U+5269,U+5272,U+52d8,U+5353,U+5389,U+53f9,U+5401,U+5415,U+541b,U+54f2,U+5524,U+554a,U+559d,U+5609,U+5740,U+575d,U+5806,U+5821,U+586b,U+5915,U+594f,U+5960,U+5999,U+59a5,U+59b9,U+59c6,U+59d1,U+59dc,U+5b5f,U+5b64,U+5b87,U+5bb4,U+5bbf,U+5c16,U+5c1d,U+5c3e,U+5c9a,U+5ca9,U+5cad,U+5cfb,U+5de1,U+5de7,U+5de9,U+5ef7,U+5f04,U+5f70,U+5f79,U+5fc6,U+602a,U+6050,U+6052,U+6070,U+6084,U+60b2,U+60dc,U+60e9,U+6167,U+6170,U+61c2,U+6270,U+6291,U+62b1,U+62bc,U+62dc,U+62df,U+62f3,U+6324,U+633a,U+6377,U+6398,U+63cf,U+640f,U+642c-642d,U+6458,U+6478,U+6500,U+654c,U+6566,U+658c,U+65c1,U+65cb,U+65e8,U+65ec,U+6696-6697,U+6734,U+679a,U+679d,U+67dc,U+67f3-67f4,U+680f,U+683d,U+684c,U+68af,U+699c,U+6bc1,U+6c0f,U+6c1b,U+6c57,U+6c6a,U+6d3d,U+6d6e,U+6d82,U+6db5,U+6dee,U+6e58,U+6eaa,U+6ecb,U+6ede,U+6ee9,U+6f0f,U+6f20,U+6f58,U+704c,U+7070,U+70b8,U+718a,U+7238,U+7262,U+7275,U+72b9,U+72d7,U+72e0,U+741b,U+7434,U+7483,U+74f6-74f7,U+75ab,U+764c,U+7761,U+7855,U+7891,U+78c1,U+79d2,U+7a00,U+7a3b,U+7c97,U+7ea4,U+7eb2,U+7ed2,U+7eea,U+7ef8,U+7f18,U+7fbd,U+8000,U+8010,U+8096,U+809d,U+80a9,U+817f,U+81e3,U+8206,U+8212,U+82ac,U+8302,U+8361,U+8377,U+83f2,U+8461,U+848b,U+84ec,U+8521,U+85aa,U+8870,U+8877,U+8881,U+888b,U+88ad,U+88c2,U+8986,U+8bd1,U+8bf1,U+8d24,U+8d2a,U+8d3e-8d3f,U+8d41,U+8d56,U+8d64,U+8d6b,U+8e0f,U+8f70,U+8f85,U+8f88,U+8fa9,U+9003,U+901d,U+90b9,U+90ce,U+94a6,U+94f8,U+9505,U+95ea,U+95ef,U+95f2,U+95f9,U+9601,U+9605,U+9634,U+966a,U+9677,U+9690,U+9694,U+96d5,U+971e,U+9896-9897,U+9972,U+9a71,U+9a76,U+9a7e,U+9e1f,U+9e23\",\n },\n },\n {\n uri: _167,\n descriptors: {\n unicodeRange:\n \"U+4e01,U+4e43,U+4ea6,U+4ef2,U+4eff,U+4f26,U+4f2a,U+4f2f,U+4f5b,U+4fa8,U+4fca,U+4fd7,U+5021,U+504f,U+5141,U+51c0,U+51dd,U+51e4,U+51ed,U+5200,U+5237,U+5427,U+5448,U+54a8,U+5706,U+5708,U+5723,U+575b,U+57c3,U+5899,U+58a8,U+58c1,U+5976,U+5988,U+59bb,U+59d0,U+59d3,U+5a18,U+5a31,U+5a92,U+5b54,U+5b85,U+5baa-5bab,U+5bc4,U+5bd2,U+5be8,U+5bff,U+5c65,U+5d07,U+5e1d,U+5e78,U+5e7c,U+5f03,U+5f1f,U+5f39,U+5f6d,U+5f92,U+5faa,U+5fbd,U+5fe7,U+5ffd,U+60a8,U+60ef,U+6108,U+6162,U+622a,U+6234,U+626b,U+626d,U+62c6,U+62d2,U+62d4,U+62d6,U+62e8,U+6316,U+6355,U+63ed,U+6447,U+64a4,U+65f1,U+6606,U+6628,U+664b,U+6668,U+6682,U+66f9,U+66fc,U+66ff,U+6717,U+6740,U+676d,U+67aa,U+67ec,U+67f1,U+6842,U+6851,U+695a,U+6982,U+6a2a,U+6b20,U+6b23,U+6b32,U+6b96,U+6bc5,U+6beb,U+6c60,U+6c9f,U+6cea,U+6cf3,U+6d1e,U+6d53,U+6d66,U+6d69,U+6d8c,U+6d9b,U+6db2,U+6de1,U+6dfb,U+6e14,U+6ed1,U+6eda,U+6ee8,U+6f2b,U+706d,U+7089,U+708e,U+70ad-70ae,U+70e7,U+7126,U+714c,U+71c3,U+71d5,U+7206,U+7259,U+731b,U+73a9,U+73bb,U+74dc,U+7532,U+7545,U+755c,U+75c7,U+7687,U+76d7,U+76f2,U+788d,U+78e8,U+79e6,U+79e9,U+7a3f,U+7a46,U+7a97,U+7af9,U+7bee,U+7c4d,U+7c89,U+7cd6,U+7eb5,U+7ebd,U+7ed8,U+8017,U+8033,U+80c0,U+80de,U+80f6,U+8138,U+817e,U+81a8,U+820d,U+827e,U+82b3,U+82d7,U+83b1,U+84c4,U+84dd,U+8584,U+864e,U+865a,U+866b,U+86cb,U+88d5,U+89e6,U+8bca,U+8bde,U+8bfa,U+8c0a,U+8c37,U+8c46,U+8c6a,U+8c8c,U+8d1d,U+8d29,U+8d4f,U+8d54,U+8d5a,U+8d60,U+8d62,U+8f7f,U+8f96,U+8f9e-8f9f,U+8fc1,U+8fdf,U+8fea,U+8ff7,U+9012,U+906d,U+9075,U+90a6,U+90bb,U+90ca,U+9178,U+9192,U+91ca,U+94bb,U+94dc,U+94fa,U+9501,U+950b,U+9521,U+955c,U+963b,U+9655,U+9675-9676,U+9887,U+9891,U+9971,U+9a97,U+9ece,U+9ed8\",\n },\n },\n {\n uri: _168,\n descriptors: {\n unicodeRange:\n \"U+4e1d,U+4e39,U+4e4c,U+4e4f,U+4e54,U+4e58,U+4e95,U+4ea1,U+4eab,U+4eae,U+4ec1,U+4f10,U+4f19,U+4f30,U+4f34,U+4fb5,U+503e,U+518c,U+5192,U+51a0,U+51ac,U+51b0,U+51e1,U+5211,U+5242,U+52a3,U+52b2,U+52c3,U+52c7,U+52d2,U+52e4,U+5377,U+539a,U+53a6,U+53e5,U+5417,U+5510,U+552f,U+5531,U+574f-5750,U+5761,U+5851,U+5854,U+58ee,U+593a,U+5949,U+5954,U+5a5a,U+5b8b,U+5bbd,U+5c04,U+5c0a,U+5c4b,U+5ce1,U+5cf0,U+5e10,U+5e8a,U+5e9f,U+5ec9,U+5f31,U+5f84,U+5fd8-5fd9,U+5fe0,U+6015,U+6062,U+6069,U+6076,U+6089,U+60a3,U+60ca,U+620f,U+624e,U+6263,U+6298,U+62a2,U+62bd,U+6311,U+6350,U+6389,U+638c,U+63f4,U+6446,U+644a,U+6469,U+64cd,U+654f,U+6562,U+656c,U+65d7,U+65e6,U+65fa,U+660c,U+6653,U+66b4,U+670b,U+672b,U+676f-6770,U+6881,U+6885,U+68a6,U+68cb,U+68ee,U+6b8a,U+6c88-6c89,U+6cc9,U+6ce5,U+6d01,U+6d17,U+6d1b,U+6d59,U+6d6a,U+6da8,U+6df7,U+6e10,U+6e20-6e21,U+6f5c,U+706f,U+70bc,U+719f,U+7267,U+732a,U+73cd,U+7518,U+756a,U+7586,U+7591,U+75db,U+76c8,U+76d0,U+76d6,U+76d8,U+76df,U+76fe,U+77db,U+7801,U+786c,U+795d,U+7965,U+79cb,U+7a77,U+7a7f,U+7aef,U+7b11,U+7bb1,U+7bc7,U+7ea0,U+7eaf,U+7ed5,U+7edc,U+7f13,U+7f29,U+7f34,U+7f8a,U+7ffb,U+8015,U+8058,U+805a,U+8083,U+80af,U+80c6,U+80cc,U+811a,U+8150,U+82e5,U+8336,U+8352,U+83ab,U+8428,U+8463,U+852c,U+8861,U+89c8,U+8bcd,U+8bd7,U+8bda,U+8be2,U+8bef,U+8bf8,U+8c0b,U+8c13,U+8d34,U+8d3a,U+8d74,U+8d76,U+8da3,U+8dd1,U+8ddd,U+8ddf,U+8df3,U+8f68,U+8f6f,U+8f7d,U+8f91,U+8f9b,U+8fbd,U+8fc8,U+8fd4,U+8feb,U+8ff9,U+900f,U+9057,U+907f-9080,U+90d1,U+90ed,U+91ce,U+9519,U+9526,U+95ed,U+9614,U+9635,U+9644,U+9686,U+96c5,U+96ea,U+9707,U+9732,U+9759,U+978b,U+9876,U+9881,U+9910,U+996e,U+9970,U+9c81,U+9e21,U+9ebb,U+9f84\",\n },\n },\n {\n uri: _169,\n descriptors: {\n unicodeRange:\n \"U+4e3d,U+4e4e,U+4e71,U+4e8f,U+4ed8,U+4eea,U+4f0a,U+4f0d,U+4f11,U+4f1f,U+4f24,U+4f3c,U+4f73,U+4fc4,U+500d,U+5012,U+501f,U+503a,U+505c,U+507f,U+50a8,U+514d,U+5178,U+517c,U+51b2,U+51b7,U+520a,U+5238,U+523b,U+52b1,U+535a,U+5371,U+5385,U+53eb-53ec,U+53f3,U+53f6,U+5409,U+542b,U+542f,U+5434,U+5462,U+5473,U+547c,U+54c8,U+54ea,U+56fa,U+5733,U+5757,U+5766,U+5802,U+585e,U+590f,U+591c,U+591f,U+5947,U+594b,U+5987,U+5a01,U+5b59,U+5b63,U+5b88,U+5b97,U+5b9c,U+5bbe,U+5bfb,U+5c01,U+5c1a,U+5c24,U+5c3c,U+5c97,U+5c9b,U+5cb8,U+5de6,U+5e01,U+5e2e,U+5e45,U+5e55,U+5e84,U+5ef6,U+5f02,U+5f52,U+5f69,U+5f7b,U+5f90,U+5fae,U+6000,U+600e,U+6025,U+60e0,U+6276,U+6297,U+62b5,U+62cd,U+62d3,U+62e5,U+62e9,U+62ff,U+6302,U+632f,U+63e1,U+6444,U+64ad,U+653b,U+6551,U+6563,U+65a4,U+65e7,U+6620,U+667a,U+66f2,U+671d,U+6731,U+6742,U+675f,U+6768,U+677e-677f,U+6790,U+67b6,U+67d3,U+6863,U+68b0,U+68c9,U+690d,U+6b8b,U+6bcd,U+6bd2,U+6bd5,U+6c38,U+6c61,U+6cbf,U+6cdb,U+6cf0,U+6d2a,U+6d89,U+6da6,U+6f6e,U+6fb3,U+7075,U+707e,U+70df,U+7164,U+7236,U+725b,U+7389,U+73e0,U+745e,U+74e6,U+751a,U+7537,U+75be,U+76ae,U+76db,U+793c,U+7956,U+7981,U+79d8,U+79df,U+79fb,U+7adf,U+7ae5,U+7b14,U+7b26,U+7b54,U+7b79,U+7d2f,U+7eb8,U+7eba,U+7ec6,U+7ee9,U+7eff,U+7f5a,U+7f6a,U+7f72,U+8089,U+80a5,U+80e1,U+8111,U+8131,U+821e,U+822c,U+8270,U+8499,U+8651,U+867d,U+8840,U+8857,U+8863,U+88c1,U+89c9,U+89d2,U+8a89,U+8bed,U+8bfe,U+8c01,U+8c22,U+8d21,U+8d25,U+8d2f,U+8d5e,U+8d75,U+8d8b,U+8dc3,U+8de8,U+8df5,U+8f6e,U+8f86,U+8f89,U+8fc5,U+8ff0,U+8ffd,U+9014,U+904d,U+90ae,U+9274,U+949f,U+952e,U+969c,U+96c4,U+96e8,U+96f6-96f7,U+97e9,U+987f,U+996d,U+9a7b,U+9aa8,U+9c7c,U+9c9c,U+9e4f,U+9f13,U+9f50\",\n },\n },\n {\n uri: _170,\n descriptors: {\n unicodeRange:\n \"U+4e13,U+4e16,U+4e1c,U+4e24,U+4e3e,U+4e49,U+4e61,U+4e66,U+4e89,U+4e8c,U+4e94,U+4e9b,U+4ea4,U+4eac,U+4ebf,U+4eca,U+4ef6-4ef7,U+4efb,U+4f18,U+4f20,U+4f46,U+4f7f,U+4fe1,U+503c,U+505a,U+5146,U+5148,U+515a,U+5171,U+5177,U+519b,U+51b3,U+51c6,U+51e0,U+5212,U+521b,U+522b,U+529e,U+52bf,U+534e-534f,U+5355,U+5357,U+5382,U+539f,U+53bb,U+53bf,U+53c2,U+53c8,U+53ca,U+53d6-53d8,U+53e3,U+53ea,U+53f0,U+540d,U+5411,U+56db,U+56de,U+56e0,U+56e2,U+578b,U+57ce,U+57fa,U+589e,U+5904,U+5934,U+5982,U+5b89,U+5b8c,U+5bfc,U+5c06,U+5c11,U+5c40,U+5c71,U+5e38,U+5e72,U+5e76,U+5e7f,U+5e94,U+5e9c,U+5f0f,U+5f15,U+5f20,U+5f3a,U+5f62,U+5f88,U+5fc5,U+5fd7,U+5feb,U+601d,U+6027,U+60c5,U+60f3,U+610f,U+6216,U+6218,U+624b,U+624d,U+6279,U+628a,U+6295,U+6301,U+6307,U+636e,U+63a5,U+63a8,U+652f,U+6536,U+653e,U+6548,U+6559,U+6570,U+65bd,U+65e0,U+6602,U+660e,U+6613,U+66f4,U+6700,U+670d,U+671f,U+672f,U+6743,U+674e,U+6751,U+6761,U+6784,U+6797,U+679c,U+67e5,U+6807,U+6837,U+683c,U+6b21,U+6b63-6b65,U+6bcf,U+6bd4,U+6c42,U+6c5f,U+6ca1,U+6cbb,U+6d3b,U+6d41,U+6d88,U+6df1,U+70b9,U+7136,U+7269,U+7279,U+7531,U+754c,U+767e,U+76ca,U+76f8,U+770b,U+7740,U+7814,U+79ef,U+7a0b,U+7a0e,U+7a76,U+7b80,U+7cbe,U+7cfb,U+7e41,U+7ea7,U+7ec4,U+7ec7,U+7ed3,U+7ed9,U+7edf,U+7f8e,U+8001,U+804c,U+8054,U+80b2,U+81f3,U+8425,U+8868,U+88ab,U+897f,U+89c1-89c2,U+89c4,U+89c6,U+89e3,U+8ba1,U+8ba4,U+8bae,U+8bb0,U+8bba,U+8bc1,U+8c03,U+8d28,U+8d39,U+8def,U+8f66,U+8f6c,U+8fd0-8fd1,U+9020,U+9053,U+90a3,U+90fd,U+91cc,U+9500,U+9547,U+95e8,U+95f4,U+961f,U+9645,U+9662,U+96be,U+96c6,U+9700,U+9769,U+97e6,U+9875,U+9879,U+9886,U+9898,U+98ce,U+9996,U+2b5af,U+2cc56,U+2e9f5,U+30edd-30ede\",\n },\n },\n {\n uri: _171,\n descriptors: {\n unicodeRange:\n \"U+4e03,U+4e30,U+4e34,U+4e45,U+4e60,U+4e70,U+4e88,U+4e91-4e92,U+4ea9,U+4eb2,U+4ec0,U+4ecb,U+4ecd,U+4ee4,U+4fee,U+5019,U+5047,U+50cf,U+5145,U+516d,U+5170,U+5175,U+5199,U+51cf,U+51fb,U+521a,U+5224,U+5267,U+52aa,U+5347-5348,U+534a,U+5356,U+5361,U+536b,U+5370,U+538b,U+53e4,U+53e6,U+5403,U+5426,U+5428,U+542c,U+5438,U+5668,U+56ed,U+56f4,U+56fe,U+57df,U+592a,U+5957,U+5b69,U+5b81,U+5b8f,U+5b98,U+5b9d,U+5ba1,U+5ba4,U+5bb3,U+5bc6,U+5bdf,U+5c3d,U+5c5e,U+5c81,U+5ddd,U+5de8,U+5dee,U+5e0c,U+5e86,U+5e8f,U+5e93,U+5e95,U+5e97,U+5ea7,U+5ead,U+5eb7,U+5f55,U+5f81,U+5f85,U+5ff5,U+6001,U+613f,U+6258,U+6267,U+6269,U+626c,U+627e,U+62db,U+62ec,U+6325,U+635f,U+6362,U+6388,U+6392,U+63a2,U+63a7,U+63aa,U+641e,U+6545,U+6597,U+65e2,U+65e9,U+661f,U+665a,U+666e-666f,U+66fe,U+6728,U+67d0,U+6811,U+6838,U+6865,U+697c,U+6b22,U+6b27,U+6b4c,U+6b62,U+6b66,U+6b7b,U+6bdb,U+6c47,U+6c49,U+6c7d,U+6c99,U+6cfd,U+6d0b,U+6d25,U+6d32,U+6d3e,U+6d4b,U+6e29,U+6e56,U+6e7e,U+6f14,U+6fc0,U+706b,U+70c8,U+7247,U+72af,U+72b6,U+72ec,U+732e,U+73ed,U+7403,U+7533,U+753b,U+7559,U+7565,U+7597,U+767b,U+773c,U+7763,U+77ed,U+77ff,U+7968,U+798f,U+79bb,U+79c0-79c1,U+7ad9,U+7ae0,U+7b51,U+7b7e,U+7cae,U+7d22,U+7ea2,U+7eb3,U+7eb7,U+7ec3,U+7ec8,U+7ecd,U+7edd,U+7efc,U+7f16,U+7f3a,U+7f51,U+7f57,U+7f6e,U+80dc,U+822a,U+8239,U+826f,U+82cf,U+82e6,U+8349,U+8363,U+83dc,U+8457,U+85cf,U+878d,U+8865,U+8a00,U+8b66,U+8ba2,U+8ba8,U+8bad,U+8bb2,U+8bc9,U+8bd5,U+8bfb,U+8d2b,U+8d35,U+8d37,U+8f7b,U+8f93,U+8fce,U+8fdd,U+9000-9002,U+9010,U+9047,U+9093,U+9152,U+9488,U+94a2,U+9633,U+9636,U+963f,U+9646,U+9648,U+964d,U+9664,U+9669,U+9760,U+97f3,U+987a,U+987e,U+9884,U+98de,U+9986,U+9ed1\",\n },\n },\n {\n uri: _172,\n descriptors: {\n unicodeRange:\n \"U+4e14,U+4e25,U+4e48,U+4e50,U+4e5d,U+4e9a,U+4ec5,U+4efd,U+4f17,U+4f4e-4f4f,U+4f55,U+4f59,U+4f60,U+4f8b,U+4f9b,U+4f9d,U+4fbf,U+4fc3,U+5065,U+513f,U+5149,U+514b,U+516b,U+5174,U+517b,U+518d,U+51b5,U+5207,U+5217-5219,U+521d,U+526f,U+529f,U+52a9,U+52b3,U+5305,U+533b,U+5343,U+5360,U+5373-5374,U+5386,U+53cb-53cd,U+53f2,U+53f7,U+544a,U+5468,U+547d,U+54cd,U+552e,U+5584,U+56f0,U+571f,U+5747,U+575a,U+57f9,U+5883,U+58eb,U+58f0,U+5907,U+590d,U+592e,U+5931,U+5956,U+5965,U+5973,U+5979,U+59cb,U+5b57-5b58,U+5b83,U+5ba2-5ba3,U+5bb9,U+5bcc,U+5c42,U+5c45,U+5c4a,U+5dde,U+5df1,U+5df4,U+5e03,U+5e08,U+5e26,U+5e2d,U+5f71,U+5f80,U+5f8b,U+5fb7,U+606f,U+611f,U+6237,U+623f,U+6253,U+627f,U+6293,U+62a4,U+62c5,U+62c9,U+6309,U+6574,U+6599,U+65ad,U+65af,U+65c5,U+65cf,U+6625,U+663e,U+671b,U+672a,U+6750,U+6781,U+6821,U+6839,U+6848,U+68c0,U+6a21,U+6b3e,U+6bb5,U+6c14,U+6cb3,U+6cb9,U+6ce8,U+6e05,U+6e2f,U+6e38,U+6e90,U+6ee1,U+70ed,U+7167,U+7231,U+7248,U+724c,U+7387,U+738b,U+73af,U+7530,U+75c5,U+767d,U+76d1,U+76f4,U+771f,U+77e5,U+77f3,U+7834,U+7840,U+786e,U+793a,U+795e,U+79f0,U+7a33,U+7a7a,U+7a81,U+7ade,U+7b56,U+7b97,U+7c73,U+7c7b,U+7d20,U+7d27,U+7ea6,U+7eaa,U+7ebf,U+7ee7,U+7eed,U+7ef4,U+7fa4,U+8003,U+80a1,U+81f4,U+8272,U+827a,U+8282,U+82b1,U+82f1,U+8303,U+836f,U+83b7,U+843d,U+88c5,U+8ba9,U+8baf,U+8bb8,U+8bbf,U+8bc4,U+8bc6,U+8bdd,U+8be5,U+8bf7,U+8c08,U+8c61,U+8d1f,U+8d22-8d23,U+8d27,U+8d2d,U+8d38,U+8d5b,U+8d70,U+8d85,U+8d8a,U+8db3,U+8eab,U+8f83,U+8fb9,U+8fdc,U+8fde,U+9009,U+901f,U+914d,U+91c7,U+94b1,U+94c1,U+94f6,U+95fb,U+9632,U+9650,U+968f,U+9752,U+975e,U+987b,U+989d,U+98df,U+9999,U+9a6c,U+9a8c,U+9ec4,U+9feb-9fec\",\n },\n },\n {\n uri: _173,\n descriptors: {\n unicodeRange:\n \"U+98fb-990c,U+990e-990f,U+9911-992d,U+992f-9953,U+9956-9962,U+9964,U+9966,U+9973,U+9978-9979,U+997b,U+997e,U+9982-9983,U+9989,U+998c,U+998e,U+999a-99a4,U+99a6-99a7,U+99a9-99c8\",\n },\n },\n {\n uri: _174,\n descriptors: {\n unicodeRange:\n \"U+8e4c-8e50,U+8e53-8e58,U+8e5a-8e65,U+8e67-8e68,U+8e6a-8e6b,U+8e6e,U+8e71,U+8e73,U+8e75,U+8e77-8e7b,U+8e7d-8e7e,U+8e80,U+8e82-8e84,U+8e86,U+8e88-8e8e,U+8e91-8e93,U+8e95-8e9b,U+8e9d,U+8e9f-8eaa,U+8ead-8eae,U+8eb0-8eb1,U+8eb3-8eb9,U+8ebb-8ecd,U+8ecf-8f02\",\n },\n },\n {\n uri: _175,\n descriptors: {\n unicodeRange:\n \"U+2e3a,U+3001-3002,U+3008-3011,U+3014-3017,U+301d-301f,U+4dae,U+4e00,U+4e07,U+4e09-4e0b,U+4e0d-4e0e,U+4e1a,U+4e2a,U+4e2d,U+4e3a-4e3b,U+4e4b,U+4e5f,U+4e86,U+4e8b,U+4e8e,U+4ea7,U+4eba,U+4ece,U+4ed1,U+4ed6,U+4ee3,U+4ee5,U+4eec,U+4f01,U+4f1a,U+4f4d,U+4f53,U+4f5c,U+4fdd,U+5143,U+5165,U+5168,U+516c,U+5173,U+5176,U+5185,U+519c,U+51fa,U+5206,U+5229,U+5230,U+5236,U+524d,U+529b,U+52a0-52a1,U+52a8,U+5316-5317,U+533a,U+5341,U+5362,U+53d1,U+53ef,U+53f8,U+5404,U+5408,U+540c,U+540e,U+5458,U+548c,U+54c1,U+54e5,U+5546,U+559c,U+56fd,U+5728,U+5730,U+573a,U+5916,U+591a,U+5927,U+5929,U+592b,U+597d,U+59d4,U+5b50,U+5b66,U+5b9a,U+5b9e,U+5bb6,U+5bf9,U+5c0f,U+5c14,U+5c31,U+5c55,U+5de5,U+5df2,U+5e02,U+5e73-5e74,U+5ea6,U+5efa,U+5f00,U+5f53,U+5f97,U+5fc3,U+603b,U+6210-6211,U+6240,U+6280,U+62a5,U+63d0,U+6539,U+653f,U+6587,U+65b0,U+65b9,U+65e5,U+65f6,U+662f,U+6708-6709,U+672c,U+673a,U+675c,U+6765,U+6c11,U+6c34,U+6cd5,U+6ce2,U+6d4e,U+6d77,U+73b0,U+7406,U+751f,U+7528,U+7535,U+7684,U+76ee,U+793e,U+79cd,U+79d1,U+7acb,U+7b2c,U+7b49,U+7ba1,U+7ecf,U+8005,U+800c,U+80fd,U+81ea,U+884c,U+8981,U+8bbe,U+8bf4,U+8d44,U+8d77,U+8fbe,U+8fc7,U+8fd8-8fd9,U+8fdb,U+901a,U+90e8,U+91cd,U+91cf,U+91d1,U+9485,U+957f,U+95ee,U+9762,U+9ad8,U+9ea6,U+9f99,U+9fcf,U+9fd4,U+9fed,U+fe10-fe19,U+fe30-fe31,U+fe33-fe44,U+ff01,U+ff0c,U+ff1f,U+2b4e7,U+2b7f7,U+2b7fc,U+2cb2d,U+2cb3b,U+2cb4a,U+2cb5b,U+2cb73\",\n },\n },\n {\n uri: _176,\n descriptors: {\n unicodeRange:\n \"U+6490,U+6493-6494,U+6497-6498,U+649a-649d,U+649f-64a3,U+64a5-64a8,U+64aa-64ab,U+64af,U+64b1-64b4,U+64b6,U+64b9,U+64bb,U+64bd-64bf,U+64c1,U+64c3-64c4,U+64c6-64cc,U+64cf,U+64d1,U+64d3-64d6,U+64d9-64dd,U+64df-64e1,U+64e3,U+64e5,U+64e7-64ff,U+6501-6508,U+650a-6511,U+6513-6517,U+6519-6524,U+6526-652a,U+652c-652d,U+6530-6533,U+6537,U+653a,U+653c-653d,U+6540-6544,U+6546-6547,U+654a-654b,U+654d-654e,U+6550,U+6552-6554,U+6557-6558,U+655a,U+655c,U+655f-6561,U+6564-6565,U+6567-6568\",\n },\n },\n {\n uri: _177,\n descriptors: {\n unicodeRange:\n \"U+9695-9696,U+969a-969b,U+969d-96a6,U+96a8-96af,U+96b1-96b2,U+96b4-96b5,U+96b7-96b8,U+96ba-96bb,U+96bf,U+96c2-96c3,U+96c8,U+96ca-96cb,U+96d0-96d1,U+96d3-96d4,U+96d6-96df,U+96e1-96e7,U+96eb-96ee,U+96f0-96f2,U+96f4-96f5,U+96f8,U+96fa-96fd,U+96ff,U+9702-9703,U+9705,U+970a-970c,U+9710-9712,U+9714-9715,U+9717-971b,U+971d,U+971f-9729,U+972b-972c,U+972e-972f,U+9731,U+9733-9737,U+973a-973d,U+973f-9751,U+9754-9755,U+9757-9758,U+975a,U+975c-975d,U+975f,U+9763-9764,U+9766-9768,U+976a-9770\",\n },\n },\n {\n uri: _178,\n descriptors: {\n unicodeRange:\n \"U+6af0-6b1f,U+6b25-6b26,U+6b28-6b31,U+6b33-6b36,U+6b38,U+6b3b-6b3d,U+6b3f-6b42,U+6b44-6b45,U+6b48,U+6b4a-6b4b,U+6b4d-6b58,U+6b5a-6b61,U+6b68-6b69,U+6b6b-6b78,U+6b7a,U+6b7d-6b80,U+6b85,U+6b88,U+6b8c,U+6b8e-6b91,U+6b94-6b95,U+6b97-6b99,U+6b9c-6ba0,U+6ba2-6ba9,U+6bab-6bb2,U+6bb6,U+6bb8-6bba\",\n },\n },\n {\n uri: _179,\n descriptors: {\n unicodeRange:\n \"U+430e-439a,U+29e8a,U+29ec4,U+29edb,U+29ee9,U+29f7e,U+29f83,U+29f8c,U+29fce,U+2a01a,U+2a02f,U+2a082,U+2a0f9,U+2a190,U+2a38c\",\n },\n },\n {\n uri: _180,\n descriptors: { unicodeRange: \"U+92ef-933d,U+933f-9369,U+936b-9388\" },\n },\n {\n uri: _181,\n descriptors: {\n unicodeRange:\n \"U+4512-458d,U+2b300,U+2b363,U+2b36f,U+2b372,U+2b37d,U+2b404,U+2b410,U+2b413,U+2b461,U+2b4ef,U+2b4f6,U+2b4f9,U+2b50d-2b50e,U+2b536,U+2b5ae,U+2b5b3,U+2b5e7,U+2b5f4,U+2b61c-2b61d,U+2b626-2b628,U+2b62a,U+2b62c,U+2b695-2b696,U+2b6ad,U+2b6ed\",\n },\n },\n {\n uri: _182,\n descriptors: {\n unicodeRange:\n \"U+88bd-88c0,U+88c3-88c4,U+88c7-88c8,U+88ca-88cd,U+88cf-88d1,U+88d3,U+88d6-88d7,U+88da-88de,U+88e0-88e1,U+88e6-88e7,U+88e9-88ef,U+88f2,U+88f5-88f7,U+88fa-88fb,U+88fd,U+88ff-8901,U+8903-8909,U+890b-890f,U+8911,U+8914-8918,U+891c-8920,U+8922-8924,U+8926-8929,U+892c-892f,U+8931-8933,U+8935,U+8937-8940,U+8942-8943,U+8945-895d,U+8960-8965,U+8967-897a,U+897c-897e,U+8980,U+8982,U+8984-8985\",\n },\n },\n { uri: _183, descriptors: { unicodeRange: \"U+4b0b-4ba0\" } },\n {\n uri: _184,\n descriptors: {\n unicodeRange:\n \"U+7179,U+717b-717c,U+717e-7183,U+7185-7189,U+718b-718e,U+7190-7193,U+7195-7197,U+719a-719e,U+71a1-71a7,U+71a9-71ab,U+71ad-71b2,U+71b4,U+71b6-71b8,U+71ba-71c2,U+71c4-71cd,U+71cf-71d3,U+71d6-71df,U+71e1-71e4,U+71e6,U+71e8-71ed,U+71ef-71f8,U+71fa-7205,U+7207-721c,U+721e-7227,U+7229,U+722b,U+722d\",\n },\n },\n {\n uri: _185,\n descriptors: {\n unicodeRange:\n \"U+982e-9874,U+988b,U+988e,U+9892,U+9895,U+9899,U+98a3,U+98a8-98cd,U+98cf-98d0,U+98d4,U+98d6-98d7,U+98db-98dd,U+98e0-98e6,U+98e9-98fa\",\n },\n },\n {\n uri: _186,\n descriptors: {\n unicodeRange:\n \"U+7c14-7c15,U+7c17-7c1e,U+7c20-7c25,U+7c28-7c29,U+7c2b-7c37,U+7c39-7c3e,U+7c42-7c4c,U+7c4e-7c72,U+7c75-7c7a,U+7c7e-7c88,U+7c8a-7c90,U+7c93-7c94,U+7c96,U+7c99-7c9b,U+7ca0-7ca1,U+7ca3,U+7ca6-7ca9,U+7cab-7cad,U+7caf-7cb0,U+7cb4-7cb8,U+7cba-7cbb,U+7cbf-7cc0,U+7cc2-7cc4,U+7cc6,U+7cc9,U+7ccb,U+7cce-7cd4\",\n },\n },\n {\n uri: _187,\n descriptors: { unicodeRange: \"U+7d95-7da5,U+7da7-7dad,U+7daf-7e2a\" },\n },\n { uri: _188, descriptors: { unicodeRange: \"U+4a78-4b0a\" } },\n {\n uri: _189,\n descriptors: {\n unicodeRange:\n \"U+9b30-9b31,U+9b33-9b3a,U+9b3d-9b40,U+9b46,U+9b4a-9b4c,U+9b4e,U+9b50,U+9b52-9b53,U+9b55-9bcf\",\n },\n },\n {\n uri: _190,\n descriptors: {\n unicodeRange:\n \"U+6a4b-6a4f,U+6a51-6a57,U+6a5a,U+6a5c-6a60,U+6a62-6a64,U+6a66-6a70,U+6a72-6a78,U+6a7a-6a7b,U+6a7d-6a7f,U+6a81-6a83,U+6a85-6a8d,U+6a8f,U+6a92-6a96,U+6a98-6a9f,U+6aa1-6aa8,U+6aaa,U+6aad-6aef\",\n },\n },\n { uri: _191, descriptors: { unicodeRange: \"U+99c9-9a53\" } },\n {\n uri: _192,\n descriptors: {\n unicodeRange:\n \"U+8550-8555,U+8557-8558,U+855a-855d,U+855f-8563,U+8565-8567,U+8569-8571,U+8573,U+8575-8578,U+857c-857d,U+857f-8583,U+8586,U+8588-858e,U+8590-859a,U+859d-85a3,U+85a5-85a7,U+85a9,U+85ab-85ad,U+85b1-85b6,U+85b8,U+85ba-85c0,U+85c2-85c8,U+85ca-85ce,U+85d1-85d2,U+85d4,U+85d6-85db,U+85dd-85e3,U+85e5-85e8,U+85ea-85fa,U+85fc-85fe,U+8600-8603\",\n },\n },\n {\n uri: _193,\n descriptors: {\n unicodeRange:\n \"U+6fb2,U+6fb4-6fb5,U+6fb7-6fb8,U+6fba-6fbf,U+6fc1,U+6fc3-6fc8,U+6fca-6fd0,U+6fd3-6fdd,U+6fdf,U+6fe2-6fed,U+6ff0-7010,U+7012-7019,U+701c-7022,U+7024-7034,U+7036-7038,U+703a-704b,U+704d-704e,U+7050-7053\",\n },\n },\n { uri: _194, descriptors: { unicodeRange: \"U+4ba1-4c2c\" } },\n {\n uri: _195,\n descriptors: {\n unicodeRange:\n \"U+9a54-9a6b,U+9a72,U+9a83,U+9a89,U+9a8d-9a8e,U+9a94-9a95,U+9a99,U+9aa6,U+9aa9-9aaf,U+9ab2-9ab5,U+9ab9,U+9abb,U+9abd-9abf,U+9ac3-9ac4,U+9ac6-9aca,U+9acd-9ad0,U+9ad2,U+9ad4-9ad7,U+9ad9-9ade,U+9ae0,U+9ae2-9ae5,U+9ae7-9aea,U+9aec,U+9aee,U+9af0-9af8,U+9afa,U+9afc-9b02,U+9b04-9b07,U+9b09-9b0e,U+9b10-9b12,U+9b14-9b1e,U+9b20-9b22,U+9b24-9b2e\",\n },\n },\n { uri: _196, descriptors: { unicodeRange: \"U+9d1a-9da1\" } },\n {\n uri: _197,\n descriptors: {\n unicodeRange:\n \"U+9e13-9e1e,U+9e24,U+9e27,U+9e2e,U+9e30,U+9e34,U+9e3b-9e3c,U+9e40,U+9e4d,U+9e50,U+9e52-9e54,U+9e56,U+9e59,U+9e5d,U+9e5f-9e62,U+9e65,U+9e6e-9e6f,U+9e72,U+9e74-9e7d,U+9e80-9e81,U+9e83-9e86,U+9e89-9e8a,U+9e8c-9e91,U+9e94-9e9c,U+9e9e,U+9ea0-9ea5,U+9ea7-9eb3,U+9eb5-9eb7,U+9eb9-9eba,U+9ebc,U+9ebf-9ec3,U+9ec5-9ec8,U+9eca-9ecc,U+9ed0,U+9ed2-9ed3,U+9ed5-9ed7,U+9ed9-9eda,U+9ede,U+9ee1,U+9ee3-9ee4,U+9ee6,U+9ee8,U+9eeb-9eee,U+9ef0-9ef8\",\n },\n },\n {\n uri: _198,\n descriptors: {\n unicodeRange:\n \"U+8b1c-8b25,U+8b27-8b65,U+8b67-8b6b,U+8b6d-8b9f,U+8bac,U+8bb1,U+8bbb,U+8bc7,U+8bd0\",\n },\n },\n { uri: _199, descriptors: { unicodeRange: \"U+4cad-4d2f\" } },\n {\n uri: _200,\n descriptors: {\n unicodeRange:\n \"U+9c4b-9c7b,U+9c7d-9c7e,U+9c80,U+9c83-9c84,U+9c89-9c8a,U+9c8c,U+9c8f,U+9c93,U+9c96-9c99,U+9c9d,U+9caa,U+9cac,U+9caf,U+9cb9,U+9cbe-9cc2,U+9cc8-9cc9,U+9cd1-9cd2,U+9cda-9cdb,U+9ce0-9ce1,U+9ce3-9d19\",\n },\n },\n {\n uri: _201,\n descriptors: {\n unicodeRange: \"U+9389-938e,U+9390-93c9,U+93cb-93d5,U+93d7-9410\",\n },\n },\n {\n uri: _202,\n descriptors: {\n unicodeRange:\n \"U+20a0-20b5,U+20b9-20ba,U+20bc-20bd,U+4e2c,U+5107,U+5216,U+5293,U+54f3,U+5523,U+5819,U+5adc,U+5c88,U+5e3b,U+5fee,U+62f6,U+63be,U+6484,U+6499,U+67d9,U+67dd,U+6d5e,U+6f46,U+717a,U+71e0,U+72c1,U+73e7,U+75b0,U+7603,U+7722,U+7809,U+7811,U+7946,U+7967,U+799a,U+7b45,U+7ba2,U+8014,U+80d9,U+8159,U+817d,U+81a3,U+81aa,U+8201,U+833c,U+836e,U+83e5,U+8459,U+84f0,U+8729,U+8753,U+87d3,U+89dc,U+8bf6,U+8c2e,U+8e2c,U+8e9c,U+8e9e,U+8ece,U+8fee,U+9139,U+914f,U+9174,U+9191,U+960c,U+9622,U+9a98,U+9b48,U+9ca6,U+9cb0,U+9da2-9e12,U+9e88,U+9f44,U+9f86\",\n },\n },\n { uri: _203, descriptors: { unicodeRange: \"U+9bd0-9c4a\" } },\n { uri: _204, descriptors: { unicodeRange: \"U+4c2d-4cac\" } },\n { uri: _205, descriptors: { unicodeRange: \"U+4d30-4dab\" } },\n {\n uri: _206,\n descriptors: { unicodeRange: \"U+9411-943d,U+943f-946a,U+946c-9484\" },\n },\n {\n uri: _207,\n descriptors: {\n unicodeRange:\n \"U+9efa,U+9efd,U+9eff-9f0a,U+9f0c,U+9f0f,U+9f11-9f12,U+9f14-9f16,U+9f18,U+9f1a-9f1f,U+9f21,U+9f23-9f2b,U+9f2d-9f2e,U+9f30-9f36,U+9f38,U+9f3a,U+9f3c,U+9f3f-9f43,U+9f45-9f4f,U+9f52-9f7e,U+9f81-9f82,U+9f8d-9f94\",\n },\n },\n {\n uri: _208,\n descriptors: {\n unicodeRange:\n \"U+7e2b-7e3a,U+7e3c-7e40,U+7e42-7e46,U+7e48-7e81,U+7e83-7e9a,U+7e9c-7e9e,U+7eae,U+7eb4,U+7ebb-7ebc,U+7ed6,U+7ee4,U+7eec,U+7ef9,U+7f0a,U+7f10,U+7f1e,U+7f37,U+7f39,U+7f3b\",\n },\n },\n];\n", "import {\n FONT_FAMILY,\n FONT_FAMILY_FALLBACKS,\n CJK_HAND_DRAWN_FALLBACK_FONT,\n WINDOWS_EMOJI_FALLBACK_FONT,\n getFontFamilyFallbacks,\n} from \"../constants\";\nimport { isTextElement } from \"../element\";\nimport { getContainerElement } from \"../element/textElement\";\nimport { containsCJK } from \"../element/textWrapping\";\nimport { ShapeCache } from \"../scene/ShapeCache\";\nimport { getFontString, PromisePool, promiseTry } from \"../utils\";\nimport { ExcalidrawFontFace } from \"./ExcalidrawFontFace\";\n\nimport { CascadiaFontFaces } from \"./Cascadia\";\nimport { ComicShannsFontFaces } from \"./ComicShanns\";\nimport { EmojiFontFaces } from \"./Emoji\";\nimport { ExcalifontFontFaces } from \"./Excalifont\";\nimport { HelveticaFontFaces } from \"./Helvetica\";\nimport { LiberationFontFaces } from \"./Liberation\";\nimport { LilitaFontFaces } from \"./Lilita\";\nimport { NunitoFontFaces } from \"./Nunito\";\nimport { VirgilFontFaces } from \"./Virgil\";\nimport { XiaolaiFontFaces } from \"./Xiaolai\";\n\nimport { FONT_METADATA, type FontMetadata } from \"./FontMetadata\";\nimport type {\n ExcalidrawElement,\n ExcalidrawTextElement,\n FontFamilyValues,\n} from \"../element/types\";\nimport type Scene from \"../scene/Scene\";\nimport type { ValueOf } from \"../utility-types\";\nimport { charWidth } from \"../element/textMeasurements\";\n\nexport class Fonts {\n // it's ok to track fonts across multiple instances only once, so let's use\n // a static member to reduce memory footprint\n public static readonly loadedFontsCache = new Set<string>();\n\n private static _registered:\n | Map<\n number,\n {\n metadata: FontMetadata;\n fontFaces: ExcalidrawFontFace[];\n }\n >\n | undefined;\n\n private static _initialized: boolean = false;\n\n public static get registered() {\n // lazy load the font registration\n if (!Fonts._registered) {\n Fonts._registered = Fonts.init();\n } else if (!Fonts._initialized) {\n // case when host app register fonts before they are lazy loaded\n // don't override whatever has been previously registered\n Fonts._registered = new Map([\n ...Fonts.init().entries(),\n ...Fonts._registered.entries(),\n ]);\n }\n\n return Fonts._registered;\n }\n\n public get registered() {\n return Fonts.registered;\n }\n\n private readonly scene: Scene;\n\n constructor(scene: Scene) {\n this.scene = scene;\n }\n\n /**\n * Get all the font families for the given scene.\n */\n public getSceneFamilies = () => {\n return Fonts.getUniqueFamilies(this.scene.getNonDeletedElements());\n };\n\n /**\n * if we load a (new) font, it's likely that text elements using it have\n * already been rendered using a fallback font. Thus, we want invalidate\n * their shapes and rerender. See #637.\n *\n * Invalidates text elements and rerenders scene, provided that at least one\n * of the supplied fontFaces has not already been processed.\n */\n public onLoaded = (fontFaces: readonly FontFace[]): void => {\n // bail if all fonts with have been processed. We're checking just a\n // subset of the font properties (though it should be enough), so it\n // can technically bail on a false positive.\n let shouldBail = true;\n\n for (const fontFace of fontFaces) {\n const sig = `${fontFace.family}-${fontFace.style}-${fontFace.weight}-${fontFace.unicodeRange}`;\n\n // make sure to update our cache with all the loaded font faces\n if (!Fonts.loadedFontsCache.has(sig)) {\n Fonts.loadedFontsCache.add(sig);\n shouldBail = false;\n }\n }\n\n if (shouldBail) {\n return;\n }\n\n let didUpdate = false;\n\n const elementsMap = this.scene.getNonDeletedElementsMap();\n\n for (const element of this.scene.getNonDeletedElements()) {\n if (isTextElement(element)) {\n didUpdate = true;\n ShapeCache.delete(element);\n\n // clear the width cache, so that we don't perform subsequent wrapping based on the stale fallback font metrics\n charWidth.clearCache(getFontString(element));\n\n const container = getContainerElement(element, elementsMap);\n if (container) {\n ShapeCache.delete(container);\n }\n }\n }\n\n if (didUpdate) {\n this.scene.triggerUpdate();\n }\n };\n\n /**\n * Load font faces for a given scene and trigger scene update.\n */\n public loadSceneFonts = async (): Promise<FontFace[]> => {\n const sceneFamilies = this.getSceneFamilies();\n const charsPerFamily = Fonts.getCharsPerFamily(\n this.scene.getNonDeletedElements(),\n );\n\n return Fonts.loadFontFaces(sceneFamilies, charsPerFamily);\n };\n\n /**\n * Load font faces for passed elements - use when the scene is unavailable (i.e. export).\n */\n public static loadElementsFonts = async (\n elements: readonly ExcalidrawElement[],\n ): Promise<FontFace[]> => {\n const fontFamilies = Fonts.getUniqueFamilies(elements);\n const charsPerFamily = Fonts.getCharsPerFamily(elements);\n\n return Fonts.loadFontFaces(fontFamilies, charsPerFamily);\n };\n\n /**\n * Generate CSS @font-face declarations for the given elements.\n */\n public static async generateFontFaceDeclarations(\n elements: readonly ExcalidrawElement[],\n ) {\n const families = Fonts.getUniqueFamilies(elements);\n const charsPerFamily = Fonts.getCharsPerFamily(elements);\n\n // for simplicity, assuming we have just one family with the CJK handdrawn fallback\n const familyWithCJK = families.find((x) =>\n getFontFamilyFallbacks(x).includes(CJK_HAND_DRAWN_FALLBACK_FONT),\n );\n\n if (familyWithCJK) {\n const characters = Fonts.getCharacters(charsPerFamily, familyWithCJK);\n\n if (containsCJK(characters)) {\n const family = FONT_FAMILY_FALLBACKS[CJK_HAND_DRAWN_FALLBACK_FONT];\n\n // adding the same characters to the CJK handrawn family\n charsPerFamily[family] = new Set(characters);\n\n // the order between the families and fallbacks is important, as fallbacks need to be defined first and in the reversed order\n // so that they get overriden with the later defined font faces, i.e. in case they share some codepoints\n families.unshift(FONT_FAMILY_FALLBACKS[CJK_HAND_DRAWN_FALLBACK_FONT]);\n }\n }\n\n // don't trigger hundreds of concurrent requests (each performing fetch, creating a worker, etc.),\n // instead go three requests at a time, in a controlled manner, without completely blocking the main thread\n // and avoiding potential issues such as rate limits\n const iterator = Fonts.fontFacesStylesGenerator(families, charsPerFamily);\n const concurrency = 3;\n const fontFaces = await new PromisePool(iterator, concurrency).all();\n\n // dedup just in case (i.e. could be the same font faces with 0 glyphs)\n return Array.from(new Set(fontFaces));\n }\n\n private static async loadFontFaces(\n fontFamilies: Array<ExcalidrawTextElement[\"fontFamily\"]>,\n charsPerFamily: Record<number, Set<string>>,\n ) {\n // add all registered font faces into the `document.fonts` (if not added already)\n for (const { fontFaces, metadata } of Fonts.registered.values()) {\n // skip registering font faces for local fonts (i.e. Helvetica)\n if (metadata.local) {\n continue;\n }\n\n for (const { fontFace } of fontFaces) {\n if (!window.document.fonts.has(fontFace)) {\n window.document.fonts.add(fontFace);\n }\n }\n }\n\n // loading 10 font faces at a time, in a controlled manner\n const iterator = Fonts.fontFacesLoader(fontFamilies, charsPerFamily);\n const concurrency = 10;\n const fontFaces = await new PromisePool(iterator, concurrency).all();\n return fontFaces.flat().filter(Boolean);\n }\n\n private static *fontFacesLoader(\n fontFamilies: Array<ExcalidrawTextElement[\"fontFamily\"]>,\n charsPerFamily: Record<number, Set<string>>,\n ): Generator<Promise<void | readonly [number, FontFace[]]>> {\n for (const [index, fontFamily] of fontFamilies.entries()) {\n const font = getFontString({\n fontFamily,\n fontSize: 16,\n });\n\n // WARN: without \"text\" param it does not have to mean that all font faces are loaded as it could be just one irrelevant font face!\n // instead, we are always checking chars used in the family, so that no required font faces remain unloaded\n const text = Fonts.getCharacters(charsPerFamily, fontFamily);\n\n if (!window.document.fonts.check(font, text)) {\n yield promiseTry(async () => {\n try {\n // WARN: browser prioritizes loading only font faces with unicode ranges for characters which are present in the document (html & canvas), other font faces could stay unloaded\n // we might want to retry here, i.e. in case CDN is down, but so far I didn't experience any issues - maybe it handles retry-like logic under the hood\n const fontFaces = await window.document.fonts.load(font, text);\n\n return [index, fontFaces];\n } catch (e) {\n // don't let it all fail if just one font fails to load\n console.error(\n `Failed to load font \"${font}\" from urls \"${Fonts.registered\n .get(fontFamily)\n ?.fontFaces.map((x) => x.urls)}\"`,\n e,\n );\n }\n });\n }\n }\n }\n\n private static *fontFacesStylesGenerator(\n families: Array<number>,\n charsPerFamily: Record<number, Set<string>>,\n ): Generator<Promise<void | readonly [number, string]>> {\n for (const [familyIndex, family] of families.entries()) {\n const { fontFaces, metadata } = Fonts.registered.get(family) ?? {};\n\n if (!Array.isArray(fontFaces)) {\n console.error(\n `Couldn't find registered fonts for font-family \"${family}\"`,\n Fonts.registered,\n );\n continue;\n }\n\n if (metadata?.local) {\n // don't inline local fonts\n continue;\n }\n\n for (const [fontFaceIndex, fontFace] of fontFaces.entries()) {\n yield promiseTry(async () => {\n try {\n const characters = Fonts.getCharacters(charsPerFamily, family);\n const fontFaceCSS = await fontFace.toCSS(characters);\n\n if (!fontFaceCSS) {\n return;\n }\n\n // giving a buffer of 10K font faces per family\n const fontFaceOrder = familyIndex * 10_000 + fontFaceIndex;\n const fontFaceTuple = [fontFaceOrder, fontFaceCSS] as const;\n\n return fontFaceTuple;\n } catch (error) {\n console.error(\n `Couldn't transform font-face to css for family \"${fontFace.fontFace.family}\"`,\n error,\n );\n }\n });\n }\n }\n }\n\n /**\n * Register a new font.\n *\n * @param family font family\n * @param metadata font metadata\n * @param fontFacesDecriptors font faces descriptors\n */\n private static register(\n this:\n | Fonts\n | {\n registered: Map<\n number,\n { metadata: FontMetadata; fontFaces: ExcalidrawFontFace[] }\n >;\n },\n family: string,\n metadata: FontMetadata,\n ...fontFacesDecriptors: ExcalidrawFontFaceDescriptor[]\n ) {\n // TODO: likely we will need to abandon number value in order to support custom fonts\n const fontFamily =\n FONT_FAMILY[family as keyof typeof FONT_FAMILY] ??\n FONT_FAMILY_FALLBACKS[family as keyof typeof FONT_FAMILY_FALLBACKS];\n\n const registeredFamily = this.registered.get(fontFamily);\n\n if (!registeredFamily) {\n this.registered.set(fontFamily, {\n metadata,\n fontFaces: fontFacesDecriptors.map(\n ({ uri, descriptors }) =>\n new ExcalidrawFontFace(family, uri, descriptors),\n ),\n });\n }\n\n return this.registered;\n }\n\n /**\n * WARN: should be called just once on init, even across multiple instances.\n */\n private static init() {\n const fonts = {\n registered: new Map<\n ValueOf<typeof FONT_FAMILY | typeof FONT_FAMILY_FALLBACKS>,\n { metadata: FontMetadata; fontFaces: ExcalidrawFontFace[] }\n >(),\n };\n\n const init = (\n family: keyof typeof FONT_FAMILY | keyof typeof FONT_FAMILY_FALLBACKS,\n ...fontFacesDescriptors: ExcalidrawFontFaceDescriptor[]\n ) => {\n const fontFamily =\n FONT_FAMILY[family as keyof typeof FONT_FAMILY] ??\n FONT_FAMILY_FALLBACKS[family as keyof typeof FONT_FAMILY_FALLBACKS];\n\n // default to Excalifont metrics\n const metadata =\n FONT_METADATA[fontFamily] ?? FONT_METADATA[FONT_FAMILY.Excalifont];\n\n Fonts.register.call(fonts, family, metadata, ...fontFacesDescriptors);\n };\n\n init(\"Cascadia\", ...CascadiaFontFaces);\n init(\"Comic Shanns\", ...ComicShannsFontFaces);\n init(\"Excalifont\", ...ExcalifontFontFaces);\n // keeping for backwards compatibility reasons, uses system font (Helvetica on MacOS, Arial on Win)\n init(\"Helvetica\", ...HelveticaFontFaces);\n // used for server-side pdf & png export instead of helvetica (technically does not need metrics, but kept in for consistency)\n init(\"Liberation Sans\", ...LiberationFontFaces);\n init(\"Lilita One\", ...LilitaFontFaces);\n init(\"Nunito\", ...NunitoFontFaces);\n init(\"Virgil\", ...VirgilFontFaces);\n\n // fallback font faces\n init(CJK_HAND_DRAWN_FALLBACK_FONT, ...XiaolaiFontFaces);\n init(WINDOWS_EMOJI_FALLBACK_FONT, ...EmojiFontFaces);\n\n Fonts._initialized = true;\n\n return fonts.registered;\n }\n\n /**\n * Get all the unique font families for the given elements.\n */\n private static getUniqueFamilies(\n elements: ReadonlyArray<ExcalidrawElement>,\n ): Array<ExcalidrawTextElement[\"fontFamily\"]> {\n return Array.from(\n elements.reduce((families, element) => {\n if (isTextElement(element)) {\n families.add(element.fontFamily);\n }\n return families;\n }, new Set<number>()),\n );\n }\n\n /**\n * Get all the unique characters per font family for the given scene.\n */\n private static getCharsPerFamily(\n elements: ReadonlyArray<ExcalidrawElement>,\n ): Record<number, Set<string>> {\n const charsPerFamily: Record<number, Set<string>> = {};\n\n for (const element of elements) {\n if (!isTextElement(element)) {\n continue;\n }\n\n // gather unique codepoints only when inlining fonts\n for (const char of element.originalText) {\n if (!charsPerFamily[element.fontFamily]) {\n charsPerFamily[element.fontFamily] = new Set();\n }\n\n charsPerFamily[element.fontFamily].add(char);\n }\n }\n\n return charsPerFamily;\n }\n\n /**\n * Get characters for a given family.\n */\n private static getCharacters(\n charsPerFamily: Record<number, Set<string>>,\n family: number,\n ) {\n return charsPerFamily[family]\n ? Array.from(charsPerFamily[family]).join(\"\")\n : \"\";\n }\n\n /**\n * Get all registered font families.\n */\n private static getAllFamilies() {\n return Array.from(Fonts.registered.keys());\n }\n}\n\n/**\n * Calculates vertical offset for a text with alphabetic baseline.\n */\nexport const getVerticalOffset = (\n fontFamily: ExcalidrawTextElement[\"fontFamily\"],\n fontSize: ExcalidrawTextElement[\"fontSize\"],\n lineHeightPx: number,\n) => {\n const { unitsPerEm, ascender, descender } =\n Fonts.registered.get(fontFamily)?.metadata.metrics ||\n FONT_METADATA[FONT_FAMILY.Virgil].metrics;\n\n const fontSizeEm = fontSize / unitsPerEm;\n const lineGap =\n (lineHeightPx - fontSizeEm * ascender + fontSizeEm * descender) / 2;\n\n const verticalOffset = fontSizeEm * ascender + lineGap;\n return verticalOffset;\n};\n\n/**\n * Gets line height forr a selected family.\n */\nexport const getLineHeight = (fontFamily: FontFamilyValues) => {\n const { lineHeight } =\n Fonts.registered.get(fontFamily)?.metadata.metrics ||\n FONT_METADATA[FONT_FAMILY.Excalifont].metrics;\n\n return lineHeight as ExcalidrawTextElement[\"lineHeight\"];\n};\n\nexport interface ExcalidrawFontFaceDescriptor {\n uri: string;\n descriptors?: FontFaceDescriptors;\n}\n", "/**\n * this file defines pure geometric shapes\n *\n * for instance, a cubic bezier curve is specified by its four control points and\n * an ellipse is defined by its center, angle, semi major axis and semi minor axis\n * (but in semi-width and semi-height so it's more relevant to Excalidraw)\n *\n * the idea with pure shapes is so that we can provide collision and other geoemtric methods not depending on\n * the specifics of roughjs or elements in Excalidraw; instead, we can focus on the pure shapes themselves\n *\n * also included in this file are methods for converting an Excalidraw element or a Drawable from roughjs\n * to pure shapes\n */\n\nimport type { Curve, LineSegment, Polygon, Radians } from \"@excalidraw/math\";\nimport {\n curve,\n lineSegment,\n pointFrom,\n pointDistance,\n pointFromArray,\n pointFromVector,\n pointRotateRads,\n polygon,\n polygonFromPoints,\n PRECISION,\n segmentsIntersectAt,\n vector,\n vectorAdd,\n vectorFromPoint,\n vectorScale,\n type GlobalPoint,\n type LocalPoint,\n} from \"@excalidraw/math\";\nimport { getElementAbsoluteCoords } from \"@excalidraw/excalidraw/element\";\nimport type {\n ElementsMap,\n ExcalidrawBindableElement,\n ExcalidrawDiamondElement,\n ExcalidrawElement,\n ExcalidrawEllipseElement,\n ExcalidrawEmbeddableElement,\n ExcalidrawFrameLikeElement,\n ExcalidrawFreeDrawElement,\n ExcalidrawIframeElement,\n ExcalidrawImageElement,\n ExcalidrawLinearElement,\n ExcalidrawRectangleElement,\n ExcalidrawSelectionElement,\n ExcalidrawTextElement,\n} from \"@excalidraw/excalidraw/element/types\";\nimport { pointsOnBezierCurves } from \"points-on-curve\";\nimport type { Drawable, Op } from \"roughjs/bin/core\";\nimport { invariant } from \"@excalidraw/excalidraw/utils\";\n\n// a polyline (made up term here) is a line consisting of other line segments\n// this corresponds to a straight line element in the editor but it could also\n// be used to model other elements\nexport type Polyline<Point extends GlobalPoint | LocalPoint> =\n LineSegment<Point>[];\n\n// a polycurve is a curve consisting of ther curves, this corresponds to a complex\n// curve on the canvas\nexport type Polycurve<Point extends GlobalPoint | LocalPoint> = Curve<Point>[];\n\n// an ellipse is specified by its center, angle, and its major and minor axes\n// but for the sake of simplicity, we've used halfWidth and halfHeight instead\n// in replace of semi major and semi minor axes\nexport type Ellipse<Point extends GlobalPoint | LocalPoint> = {\n center: Point;\n angle: Radians;\n halfWidth: number;\n halfHeight: number;\n};\n\nexport type GeometricShape<Point extends GlobalPoint | LocalPoint> =\n | {\n type: \"line\";\n data: LineSegment<Point>;\n }\n | {\n type: \"polygon\";\n data: Polygon<Point>;\n }\n | {\n type: \"curve\";\n data: Curve<Point>;\n }\n | {\n type: \"ellipse\";\n data: Ellipse<Point>;\n }\n | {\n type: \"polyline\";\n data: Polyline<Point>;\n }\n | {\n type: \"polycurve\";\n data: Polycurve<Point>;\n };\n\ntype RectangularElement =\n | ExcalidrawRectangleElement\n | ExcalidrawDiamondElement\n | ExcalidrawFrameLikeElement\n | ExcalidrawEmbeddableElement\n | ExcalidrawImageElement\n | ExcalidrawIframeElement\n | ExcalidrawTextElement\n | ExcalidrawSelectionElement;\n\n// polygon\nexport const getPolygonShape = <Point extends GlobalPoint | LocalPoint>(\n element: RectangularElement,\n): GeometricShape<Point> => {\n const { angle, width, height, x, y } = element;\n\n const cx = x + width / 2;\n const cy = y + height / 2;\n\n const center: Point = pointFrom(cx, cy);\n\n let data: Polygon<Point>;\n\n if (element.type === \"diamond\") {\n data = polygon(\n pointRotateRads(pointFrom(cx, y), center, angle),\n pointRotateRads(pointFrom(x + width, cy), center, angle),\n pointRotateRads(pointFrom(cx, y + height), center, angle),\n pointRotateRads(pointFrom(x, cy), center, angle),\n );\n } else {\n data = polygon(\n pointRotateRads(pointFrom(x, y), center, angle),\n pointRotateRads(pointFrom(x + width, y), center, angle),\n pointRotateRads(pointFrom(x + width, y + height), center, angle),\n pointRotateRads(pointFrom(x, y + height), center, angle),\n );\n }\n\n return {\n type: \"polygon\",\n data,\n };\n};\n\n// return the selection box for an element, possibly rotated as well\nexport const getSelectionBoxShape = <Point extends GlobalPoint | LocalPoint>(\n element: ExcalidrawElement,\n elementsMap: ElementsMap,\n padding = 10,\n) => {\n let [x1, y1, x2, y2, cx, cy] = getElementAbsoluteCoords(\n element,\n elementsMap,\n true,\n );\n\n x1 -= padding;\n x2 += padding;\n y1 -= padding;\n y2 += padding;\n\n //const angleInDegrees = angleToDegrees(element.angle);\n const center = pointFrom(cx, cy);\n const topLeft = pointRotateRads(pointFrom(x1, y1), center, element.angle);\n const topRight = pointRotateRads(pointFrom(x2, y1), center, element.angle);\n const bottomLeft = pointRotateRads(pointFrom(x1, y2), center, element.angle);\n const bottomRight = pointRotateRads(pointFrom(x2, y2), center, element.angle);\n\n return {\n type: \"polygon\",\n data: [topLeft, topRight, bottomRight, bottomLeft],\n } as GeometricShape<Point>;\n};\n\n// ellipse\nexport const getEllipseShape = <Point extends GlobalPoint | LocalPoint>(\n element: ExcalidrawEllipseElement,\n): GeometricShape<Point> => {\n const { width, height, angle, x, y } = element;\n\n return {\n type: \"ellipse\",\n data: {\n center: pointFrom(x + width / 2, y + height / 2),\n angle,\n halfWidth: width / 2,\n halfHeight: height / 2,\n },\n };\n};\n\nexport const getCurvePathOps = (shape: Drawable): Op[] => {\n for (const set of shape.sets) {\n if (set.type === \"path\") {\n return set.ops;\n }\n }\n return shape.sets[0].ops;\n};\n\n// linear\nexport const getCurveShape = <Point extends GlobalPoint | LocalPoint>(\n roughShape: Drawable,\n startingPoint: Point = pointFrom(0, 0),\n angleInRadian: Radians,\n center: Point,\n): GeometricShape<Point> => {\n const transform = (p: Point): Point =>\n pointRotateRads(\n pointFrom(p[0] + startingPoint[0], p[1] + startingPoint[1]),\n center,\n angleInRadian,\n );\n\n const ops = getCurvePathOps(roughShape);\n const polycurve: Polycurve<Point> = [];\n let p0 = pointFrom<Point>(0, 0);\n\n for (const op of ops) {\n if (op.op === \"move\") {\n const p = pointFromArray<Point>(op.data);\n invariant(p != null, \"Ops data is not a point\");\n p0 = transform(p);\n }\n if (op.op === \"bcurveTo\") {\n const p1 = transform(pointFrom<Point>(op.data[0], op.data[1]));\n const p2 = transform(pointFrom<Point>(op.data[2], op.data[3]));\n const p3 = transform(pointFrom<Point>(op.data[4], op.data[5]));\n polycurve.push(curve<Point>(p0, p1, p2, p3));\n p0 = p3;\n }\n }\n\n return {\n type: \"polycurve\",\n data: polycurve,\n };\n};\n\nconst polylineFromPoints = <Point extends GlobalPoint | LocalPoint>(\n points: Point[],\n): Polyline<Point> => {\n let previousPoint: Point = points[0];\n const polyline: LineSegment<Point>[] = [];\n\n for (let i = 1; i < points.length; i++) {\n const nextPoint = points[i];\n polyline.push(lineSegment<Point>(previousPoint, nextPoint));\n previousPoint = nextPoint;\n }\n\n return polyline;\n};\n\nexport const getFreedrawShape = <Point extends GlobalPoint | LocalPoint>(\n element: ExcalidrawFreeDrawElement,\n center: Point,\n isClosed: boolean = false,\n): GeometricShape<Point> => {\n const transform = (p: Point) =>\n pointRotateRads(\n pointFromVector(\n vectorAdd(vectorFromPoint(p), vector(element.x, element.y)),\n ),\n center,\n element.angle,\n );\n\n const polyline = polylineFromPoints(\n element.points.map((p) => transform(p as Point)),\n );\n\n return (\n isClosed\n ? {\n type: \"polygon\",\n data: polygonFromPoints(polyline.flat()),\n }\n : {\n type: \"polyline\",\n data: polyline,\n }\n ) as GeometricShape<Point>;\n};\n\nexport const getClosedCurveShape = <Point extends GlobalPoint | LocalPoint>(\n element: ExcalidrawLinearElement,\n roughShape: Drawable,\n startingPoint: Point = pointFrom<Point>(0, 0),\n angleInRadian: Radians,\n center: Point,\n): GeometricShape<Point> => {\n const transform = (p: Point) =>\n pointRotateRads(\n pointFrom(p[0] + startingPoint[0], p[1] + startingPoint[1]),\n center,\n angleInRadian,\n );\n\n if (element.roundness === null) {\n return {\n type: \"polygon\",\n data: polygonFromPoints(\n element.points.map((p) => transform(p as Point)) as Point[],\n ),\n };\n }\n\n const ops = getCurvePathOps(roughShape);\n\n const points: Point[] = [];\n let odd = false;\n for (const operation of ops) {\n if (operation.op === \"move\") {\n odd = !odd;\n if (odd) {\n points.push(pointFrom(operation.data[0], operation.data[1]));\n }\n } else if (operation.op === \"bcurveTo\") {\n if (odd) {\n points.push(pointFrom(operation.data[0], operation.data[1]));\n points.push(pointFrom(operation.data[2], operation.data[3]));\n points.push(pointFrom(operation.data[4], operation.data[5]));\n }\n } else if (operation.op === \"lineTo\") {\n if (odd) {\n points.push(pointFrom(operation.data[0], operation.data[1]));\n }\n }\n }\n\n const polygonPoints = pointsOnBezierCurves(points, 10, 5).map((p) =>\n transform(p as Point),\n ) as Point[];\n\n return {\n type: \"polygon\",\n data: polygonFromPoints<Point>(polygonPoints),\n };\n};\n\n/**\n * Determine intersection of a rectangular shaped element and a\n * line segment.\n *\n * @param element The rectangular element to test against\n * @param segment The segment intersecting the element\n * @param gap Optional value to inflate the shape before testing\n * @returns An array of intersections\n */\n// TODO: Replace with final rounded rectangle code\nexport const segmentIntersectRectangleElement = <\n Point extends LocalPoint | GlobalPoint,\n>(\n element: ExcalidrawBindableElement,\n segment: LineSegment<Point>,\n gap: number = 0,\n): Point[] => {\n const bounds = [\n element.x - gap,\n element.y - gap,\n element.x + element.width + gap,\n element.y + element.height + gap,\n ];\n const center = pointFrom(\n (bounds[0] + bounds[2]) / 2,\n (bounds[1] + bounds[3]) / 2,\n );\n\n return [\n lineSegment(\n pointRotateRads(pointFrom(bounds[0], bounds[1]), center, element.angle),\n pointRotateRads(pointFrom(bounds[2], bounds[1]), center, element.angle),\n ),\n lineSegment(\n pointRotateRads(pointFrom(bounds[2], bounds[1]), center, element.angle),\n pointRotateRads(pointFrom(bounds[2], bounds[3]), center, element.angle),\n ),\n lineSegment(\n pointRotateRads(pointFrom(bounds[2], bounds[3]), center, element.angle),\n pointRotateRads(pointFrom(bounds[0], bounds[3]), center, element.angle),\n ),\n lineSegment(\n pointRotateRads(pointFrom(bounds[0], bounds[3]), center, element.angle),\n pointRotateRads(pointFrom(bounds[0], bounds[1]), center, element.angle),\n ),\n ]\n .map((s) => segmentsIntersectAt(segment, s))\n .filter((i): i is Point => !!i);\n};\n\nconst distanceToEllipse = <Point extends LocalPoint | GlobalPoint>(\n p: Point,\n ellipse: Ellipse<Point>,\n) => {\n const { angle, halfWidth, halfHeight, center } = ellipse;\n const a = halfWidth;\n const b = halfHeight;\n const translatedPoint = vectorAdd(\n vectorFromPoint(p),\n vectorScale(vectorFromPoint(center), -1),\n );\n const [rotatedPointX, rotatedPointY] = pointRotateRads(\n pointFromVector(translatedPoint),\n pointFrom(0, 0),\n -angle as Radians,\n );\n\n const px = Math.abs(rotatedPointX);\n const py = Math.abs(rotatedPointY);\n\n let tx = 0.707;\n let ty = 0.707;\n\n for (let i = 0; i < 3; i++) {\n const x = a * tx;\n const y = b * ty;\n\n const ex = ((a * a - b * b) * tx ** 3) / a;\n const ey = ((b * b - a * a) * ty ** 3) / b;\n\n const rx = x - ex;\n const ry = y - ey;\n\n const qx = px - ex;\n const qy = py - ey;\n\n const r = Math.hypot(ry, rx);\n const q = Math.hypot(qy, qx);\n\n tx = Math.min(1, Math.max(0, ((qx * r) / q + ex) / a));\n ty = Math.min(1, Math.max(0, ((qy * r) / q + ey) / b));\n const t = Math.hypot(ty, tx);\n tx /= t;\n ty /= t;\n }\n\n const [minX, minY] = [\n a * tx * Math.sign(rotatedPointX),\n b * ty * Math.sign(rotatedPointY),\n ];\n\n return pointDistance(\n pointFrom(rotatedPointX, rotatedPointY),\n pointFrom(minX, minY),\n );\n};\n\nexport const pointOnEllipse = <Point extends LocalPoint | GlobalPoint>(\n point: Point,\n ellipse: Ellipse<Point>,\n threshold = PRECISION,\n) => {\n return distanceToEllipse(point, ellipse) <= threshold;\n};\n\nexport const pointInEllipse = <Point extends LocalPoint | GlobalPoint>(\n p: Point,\n ellipse: Ellipse<Point>,\n) => {\n const { center, angle, halfWidth, halfHeight } = ellipse;\n const translatedPoint = vectorAdd(\n vectorFromPoint(p),\n vectorScale(vectorFromPoint(center), -1),\n );\n const [rotatedPointX, rotatedPointY] = pointRotateRads(\n pointFromVector(translatedPoint),\n pointFrom(0, 0),\n -angle as Radians,\n );\n\n return (\n (rotatedPointX / halfWidth) * (rotatedPointX / halfWidth) +\n (rotatedPointY / halfHeight) * (rotatedPointY / halfHeight) <=\n 1\n );\n};\n\nexport const ellipseAxes = <Point extends LocalPoint | GlobalPoint>(\n ellipse: Ellipse<Point>,\n) => {\n const widthGreaterThanHeight = ellipse.halfWidth > ellipse.halfHeight;\n\n const majorAxis = widthGreaterThanHeight\n ? ellipse.halfWidth * 2\n : ellipse.halfHeight * 2;\n const minorAxis = widthGreaterThanHeight\n ? ellipse.halfHeight * 2\n : ellipse.halfWidth * 2;\n\n return {\n majorAxis,\n minorAxis,\n };\n};\n\nexport const ellipseFocusToCenter = <Point extends LocalPoint | GlobalPoint>(\n ellipse: Ellipse<Point>,\n) => {\n const { majorAxis, minorAxis } = ellipseAxes(ellipse);\n\n return Math.sqrt(majorAxis ** 2 - minorAxis ** 2);\n};\n\nexport const ellipseExtremes = <Point extends LocalPoint | GlobalPoint>(\n ellipse: Ellipse<Point>,\n) => {\n const { center, angle } = ellipse;\n const { majorAxis, minorAxis } = ellipseAxes(ellipse);\n\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n\n const sqSum = majorAxis ** 2 + minorAxis ** 2;\n const sqDiff = (majorAxis ** 2 - minorAxis ** 2) * Math.cos(2 * angle);\n\n const yMax = Math.sqrt((sqSum - sqDiff) / 2);\n const xAtYMax =\n (yMax * sqSum * sin * cos) /\n (majorAxis ** 2 * sin ** 2 + minorAxis ** 2 * cos ** 2);\n\n const xMax = Math.sqrt((sqSum + sqDiff) / 2);\n const yAtXMax =\n (xMax * sqSum * sin * cos) /\n (majorAxis ** 2 * cos ** 2 + minorAxis ** 2 * sin ** 2);\n const centerVector = vectorFromPoint(center);\n\n return [\n vectorAdd(vector(xAtYMax, yMax), centerVector),\n vectorAdd(vectorScale(vector(xAtYMax, yMax), -1), centerVector),\n vectorAdd(vector(xMax, yAtXMax), centerVector),\n vectorAdd(vector(xMax, yAtXMax), centerVector),\n ];\n};\n", "import type { Polycurve, Polyline } from \"./geometry/shape\";\nimport {\n pointInEllipse,\n pointOnEllipse,\n type GeometricShape,\n} from \"./geometry/shape\";\nimport type { Curve } from \"@excalidraw/math\";\nimport {\n lineSegment,\n pointFrom,\n polygonIncludesPoint,\n pointOnLineSegment,\n pointOnPolygon,\n polygonFromPoints,\n type GlobalPoint,\n type LocalPoint,\n type Polygon,\n} from \"@excalidraw/math\";\n\n// check if the given point is considered on the given shape's border\nexport const isPointOnShape = <Point extends GlobalPoint | LocalPoint>(\n point: Point,\n shape: GeometricShape<Point>,\n tolerance = 0,\n) => {\n // get the distance from the given point to the given element\n // check if the distance is within the given epsilon range\n switch (shape.type) {\n case \"polygon\":\n return pointOnPolygon(point, shape.data, tolerance);\n case \"ellipse\":\n return pointOnEllipse(point, shape.data, tolerance);\n case \"line\":\n return pointOnLineSegment(point, shape.data, tolerance);\n case \"polyline\":\n return pointOnPolyline(point, shape.data, tolerance);\n case \"curve\":\n return pointOnCurve(point, shape.data, tolerance);\n case \"polycurve\":\n return pointOnPolycurve(point, shape.data, tolerance);\n default:\n throw Error(`shape ${shape} is not implemented`);\n }\n};\n\n// check if the given point is considered inside the element's border\nexport const isPointInShape = <Point extends GlobalPoint | LocalPoint>(\n point: Point,\n shape: GeometricShape<Point>,\n) => {\n switch (shape.type) {\n case \"polygon\":\n return polygonIncludesPoint(point, shape.data);\n case \"line\":\n return false;\n case \"curve\":\n return false;\n case \"ellipse\":\n return pointInEllipse(point, shape.data);\n case \"polyline\": {\n const polygon = polygonFromPoints(shape.data.flat());\n return polygonIncludesPoint(point, polygon);\n }\n case \"polycurve\": {\n return false;\n }\n default:\n throw Error(`shape ${shape} is not implemented`);\n }\n};\n\n// check if the given element is in the given bounds\nexport const isPointInBounds = <Point extends GlobalPoint | LocalPoint>(\n point: Point,\n bounds: Polygon<Point>,\n) => {\n return polygonIncludesPoint(point, bounds);\n};\n\nconst pointOnPolycurve = <Point extends LocalPoint | GlobalPoint>(\n point: Point,\n polycurve: Polycurve<Point>,\n tolerance: number,\n) => {\n return polycurve.some((curve) => pointOnCurve(point, curve, tolerance));\n};\n\nconst cubicBezierEquation = <Point extends LocalPoint | GlobalPoint>(\n curve: Curve<Point>,\n) => {\n const [p0, p1, p2, p3] = curve;\n // B(t) = p0 * (1-t)^3 + 3p1 * t * (1-t)^2 + 3p2 * t^2 * (1-t) + p3 * t^3\n return (t: number, idx: number) =>\n Math.pow(1 - t, 3) * p3[idx] +\n 3 * t * Math.pow(1 - t, 2) * p2[idx] +\n 3 * Math.pow(t, 2) * (1 - t) * p1[idx] +\n p0[idx] * Math.pow(t, 3);\n};\n\nconst polyLineFromCurve = <Point extends LocalPoint | GlobalPoint>(\n curve: Curve<Point>,\n segments = 10,\n): Polyline<Point> => {\n const equation = cubicBezierEquation(curve);\n let startingPoint = [equation(0, 0), equation(0, 1)] as Point;\n const lineSegments: Polyline<Point> = [];\n let t = 0;\n const increment = 1 / segments;\n\n for (let i = 0; i < segments; i++) {\n t += increment;\n if (t <= 1) {\n const nextPoint: Point = pointFrom(equation(t, 0), equation(t, 1));\n lineSegments.push(lineSegment(startingPoint, nextPoint));\n startingPoint = nextPoint;\n }\n }\n\n return lineSegments;\n};\n\nexport const pointOnCurve = <Point extends LocalPoint | GlobalPoint>(\n point: Point,\n curve: Curve<Point>,\n threshold: number,\n) => {\n return pointOnPolyline(point, polyLineFromCurve(curve), threshold);\n};\n\nexport const pointOnPolyline = <Point extends LocalPoint | GlobalPoint>(\n point: Point,\n polyline: Polyline<Point>,\n threshold = 10e-5,\n) => {\n return polyline.some((line) => pointOnLineSegment(point, line, threshold));\n};\n", "import {\n pointFrom,\n pointDistance,\n pointFromVector,\n pointsEqual,\n} from \"./point\";\nimport type {\n Ellipse,\n GlobalPoint,\n Line,\n LineSegment,\n LocalPoint,\n} from \"./types\";\nimport { PRECISION } from \"./utils\";\nimport {\n vector,\n vectorAdd,\n vectorDot,\n vectorFromPoint,\n vectorScale,\n} from \"./vector\";\n\n/**\n * Construct an Ellipse object from the parameters\n *\n * @param center The center of the ellipse\n * @param angle The slanting of the ellipse in radians\n * @param halfWidth Half of the width of a non-slanted version of the ellipse\n * @param halfHeight Half of the height of a non-slanted version of the ellipse\n * @returns The constructed Ellipse object\n */\nexport function ellipse<Point extends GlobalPoint | LocalPoint>(\n center: Point,\n halfWidth: number,\n halfHeight: number,\n): Ellipse<Point> {\n return {\n center,\n halfWidth,\n halfHeight,\n } as Ellipse<Point>;\n}\n\n/**\n * Determines if a point is inside or on the ellipse outline\n *\n * @param p The point to test\n * @param ellipse The ellipse to compare against\n * @returns TRUE if the point is inside or on the outline of the ellipse\n */\nexport const ellipseIncludesPoint = <Point extends GlobalPoint | LocalPoint>(\n p: Point,\n ellipse: Ellipse<Point>,\n) => {\n const { center, halfWidth, halfHeight } = ellipse;\n const normalizedX = (p[0] - center[0]) / halfWidth;\n const normalizedY = (p[1] - center[1]) / halfHeight;\n\n return normalizedX * normalizedX + normalizedY * normalizedY <= 1;\n};\n\n/**\n * Tests whether a point lies on the outline of the ellipse within a given\n * tolerance\n *\n * @param point The point to test\n * @param ellipse The ellipse to compare against\n * @param threshold The distance to consider a point close enough to be \"on\" the outline\n * @returns TRUE if the point is on the ellise outline\n */\nexport const ellipseTouchesPoint = <Point extends GlobalPoint | LocalPoint>(\n point: Point,\n ellipse: Ellipse<Point>,\n threshold = PRECISION,\n) => {\n return ellipseDistanceFromPoint(point, ellipse) <= threshold;\n};\n\n/**\n * Determine the shortest euclidean distance from a point to the\n * outline of the ellipse\n *\n * @param p The point to consider\n * @param ellipse The ellipse to calculate the distance to\n * @returns The eucledian distance\n */\nexport const ellipseDistanceFromPoint = <\n Point extends GlobalPoint | LocalPoint,\n>(\n p: Point,\n ellipse: Ellipse<Point>,\n): number => {\n const { halfWidth, halfHeight, center } = ellipse;\n const a = halfWidth;\n const b = halfHeight;\n const translatedPoint = vectorAdd(\n vectorFromPoint(p),\n vectorScale(vectorFromPoint(center), -1),\n );\n\n const px = Math.abs(translatedPoint[0]);\n const py = Math.abs(translatedPoint[1]);\n\n let tx = 0.707;\n let ty = 0.707;\n\n for (let i = 0; i < 3; i++) {\n const x = a * tx;\n const y = b * ty;\n\n const ex = ((a * a - b * b) * tx ** 3) / a;\n const ey = ((b * b - a * a) * ty ** 3) / b;\n\n const rx = x - ex;\n const ry = y - ey;\n\n const qx = px - ex;\n const qy = py - ey;\n\n const r = Math.hypot(ry, rx);\n const q = Math.hypot(qy, qx);\n\n tx = Math.min(1, Math.max(0, ((qx * r) / q + ex) / a));\n ty = Math.min(1, Math.max(0, ((qy * r) / q + ey) / b));\n const t = Math.hypot(ty, tx);\n tx /= t;\n ty /= t;\n }\n\n const [minX, minY] = [\n a * tx * Math.sign(translatedPoint[0]),\n b * ty * Math.sign(translatedPoint[1]),\n ];\n\n return pointDistance(pointFromVector(translatedPoint), pointFrom(minX, minY));\n};\n\n/**\n * Calculate a maximum of two intercept points for a line going throug an\n * ellipse.\n */\nexport function ellipseSegmentInterceptPoints<\n Point extends GlobalPoint | LocalPoint,\n>(e: Readonly<Ellipse<Point>>, s: Readonly<LineSegment<Point>>): Point[] {\n const rx = e.halfWidth;\n const ry = e.halfHeight;\n\n const dir = vectorFromPoint(s[1], s[0]);\n const diff = vector(s[0][0] - e.center[0], s[0][1] - e.center[1]);\n const mDir = vector(dir[0] / (rx * rx), dir[1] / (ry * ry));\n const mDiff = vector(diff[0] / (rx * rx), diff[1] / (ry * ry));\n\n const a = vectorDot(dir, mDir);\n const b = vectorDot(dir, mDiff);\n const c = vectorDot(diff, mDiff) - 1.0;\n const d = b * b - a * c;\n\n const intersections: Point[] = [];\n\n if (d > 0) {\n const t_a = (-b - Math.sqrt(d)) / a;\n const t_b = (-b + Math.sqrt(d)) / a;\n\n if (0 <= t_a && t_a <= 1) {\n intersections.push(\n pointFrom(\n s[0][0] + (s[1][0] - s[0][0]) * t_a,\n s[0][1] + (s[1][1] - s[0][1]) * t_a,\n ),\n );\n }\n\n if (0 <= t_b && t_b <= 1) {\n intersections.push(\n pointFrom(\n s[0][0] + (s[1][0] - s[0][0]) * t_b,\n s[0][1] + (s[1][1] - s[0][1]) * t_b,\n ),\n );\n }\n } else if (d === 0) {\n const t = -b / a;\n if (0 <= t && t <= 1) {\n intersections.push(\n pointFrom(\n s[0][0] + (s[1][0] - s[0][0]) * t,\n s[0][1] + (s[1][1] - s[0][1]) * t,\n ),\n );\n }\n }\n\n return intersections;\n}\n\nexport function ellipseLineIntersectionPoints<\n Point extends GlobalPoint | LocalPoint,\n>(\n { center, halfWidth, halfHeight }: Ellipse<Point>,\n [g, h]: Line<Point>,\n): Point[] {\n const [cx, cy] = center;\n const x1 = g[0] - cx;\n const y1 = g[1] - cy;\n const x2 = h[0] - cx;\n const y2 = h[1] - cy;\n const a =\n Math.pow(x2 - x1, 2) / Math.pow(halfWidth, 2) +\n Math.pow(y2 - y1, 2) / Math.pow(halfHeight, 2);\n const b =\n 2 *\n ((x1 * (x2 - x1)) / Math.pow(halfWidth, 2) +\n (y1 * (y2 - y1)) / Math.pow(halfHeight, 2));\n const c =\n Math.pow(x1, 2) / Math.pow(halfWidth, 2) +\n Math.pow(y1, 2) / Math.pow(halfHeight, 2) -\n 1;\n const t1 = (-b + Math.sqrt(Math.pow(b, 2) - 4 * a * c)) / (2 * a);\n const t2 = (-b - Math.sqrt(Math.pow(b, 2) - 4 * a * c)) / (2 * a);\n const candidates = [\n pointFrom<Point>(x1 + t1 * (x2 - x1) + cx, y1 + t1 * (y2 - y1) + cy),\n pointFrom<Point>(x1 + t2 * (x2 - x1) + cx, y1 + t2 * (y2 - y1) + cy),\n ].filter((p) => !isNaN(p[0]) && !isNaN(p[1]));\n\n if (candidates.length === 2 && pointsEqual(candidates[0], candidates[1])) {\n return [candidates[0]];\n }\n\n return candidates;\n}\n", "import { getDiamondPoints } from \".\";\nimport type { Curve, LineSegment } from \"@excalidraw/math\";\nimport {\n curve,\n lineSegment,\n pointFrom,\n pointFromVector,\n rectangle,\n vectorFromPoint,\n vectorNormalize,\n vectorScale,\n type GlobalPoint,\n} from \"@excalidraw/math\";\nimport { getCornerRadius } from \"../shapes\";\nimport type {\n ExcalidrawDiamondElement,\n ExcalidrawRectanguloidElement,\n} from \"./types\";\n\n/**\n * Get the building components of a rectanguloid element in the form of\n * line segments and curves.\n *\n * @param element Target rectanguloid element\n * @param offset Optional offset to expand the rectanguloid shape\n * @returns Tuple of line segments (0) and curves (1)\n */\nexport function deconstructRectanguloidElement(\n element: ExcalidrawRectanguloidElement,\n offset: number = 0,\n): [LineSegment<GlobalPoint>[], Curve<GlobalPoint>[]] {\n const roundness = getCornerRadius(\n Math.min(element.width, element.height),\n element,\n );\n\n if (roundness <= 0) {\n const r = rectangle(\n pointFrom(element.x - offset, element.y - offset),\n pointFrom(\n element.x + element.width + offset,\n element.y + element.height + offset,\n ),\n );\n\n const top = lineSegment<GlobalPoint>(\n pointFrom<GlobalPoint>(r[0][0] + roundness, r[0][1]),\n pointFrom<GlobalPoint>(r[1][0] - roundness, r[0][1]),\n );\n const right = lineSegment<GlobalPoint>(\n pointFrom<GlobalPoint>(r[1][0], r[0][1] + roundness),\n pointFrom<GlobalPoint>(r[1][0], r[1][1] - roundness),\n );\n const bottom = lineSegment<GlobalPoint>(\n pointFrom<GlobalPoint>(r[0][0] + roundness, r[1][1]),\n pointFrom<GlobalPoint>(r[1][0] - roundness, r[1][1]),\n );\n const left = lineSegment<GlobalPoint>(\n pointFrom<GlobalPoint>(r[0][0], r[1][1] - roundness),\n pointFrom<GlobalPoint>(r[0][0], r[0][1] + roundness),\n );\n const sides = [top, right, bottom, left];\n\n return [sides, []];\n }\n\n const center = pointFrom<GlobalPoint>(\n element.x + element.width / 2,\n element.y + element.height / 2,\n );\n\n const r = rectangle(\n pointFrom(element.x, element.y),\n pointFrom(element.x + element.width, element.y + element.height),\n );\n\n const top = lineSegment<GlobalPoint>(\n pointFrom<GlobalPoint>(r[0][0] + roundness, r[0][1]),\n pointFrom<GlobalPoint>(r[1][0] - roundness, r[0][1]),\n );\n const right = lineSegment<GlobalPoint>(\n pointFrom<GlobalPoint>(r[1][0], r[0][1] + roundness),\n pointFrom<GlobalPoint>(r[1][0], r[1][1] - roundness),\n );\n const bottom = lineSegment<GlobalPoint>(\n pointFrom<GlobalPoint>(r[0][0] + roundness, r[1][1]),\n pointFrom<GlobalPoint>(r[1][0] - roundness, r[1][1]),\n );\n const left = lineSegment<GlobalPoint>(\n pointFrom<GlobalPoint>(r[0][0], r[1][1] - roundness),\n pointFrom<GlobalPoint>(r[0][0], r[0][1] + roundness),\n );\n\n const offsets = [\n vectorScale(\n vectorNormalize(\n vectorFromPoint(pointFrom(r[0][0] - offset, r[0][1] - offset), center),\n ),\n offset,\n ), // TOP LEFT\n vectorScale(\n vectorNormalize(\n vectorFromPoint(pointFrom(r[1][0] + offset, r[0][1] - offset), center),\n ),\n offset,\n ), //TOP RIGHT\n vectorScale(\n vectorNormalize(\n vectorFromPoint(pointFrom(r[1][0] + offset, r[1][1] + offset), center),\n ),\n offset,\n ), // BOTTOM RIGHT\n vectorScale(\n vectorNormalize(\n vectorFromPoint(pointFrom(r[0][0] - offset, r[1][1] + offset), center),\n ),\n offset,\n ), // BOTTOM LEFT\n ];\n\n const corners = [\n curve(\n pointFromVector(offsets[0], left[1]),\n pointFromVector(\n offsets[0],\n pointFrom<GlobalPoint>(\n left[1][0] + (2 / 3) * (r[0][0] - left[1][0]),\n left[1][1] + (2 / 3) * (r[0][1] - left[1][1]),\n ),\n ),\n pointFromVector(\n offsets[0],\n pointFrom<GlobalPoint>(\n top[0][0] + (2 / 3) * (r[0][0] - top[0][0]),\n top[0][1] + (2 / 3) * (r[0][1] - top[0][1]),\n ),\n ),\n pointFromVector(offsets[0], top[0]),\n ), // TOP LEFT\n curve(\n pointFromVector(offsets[1], top[1]),\n pointFromVector(\n offsets[1],\n pointFrom<GlobalPoint>(\n top[1][0] + (2 / 3) * (r[1][0] - top[1][0]),\n top[1][1] + (2 / 3) * (r[0][1] - top[1][1]),\n ),\n ),\n pointFromVector(\n offsets[1],\n pointFrom<GlobalPoint>(\n right[0][0] + (2 / 3) * (r[1][0] - right[0][0]),\n right[0][1] + (2 / 3) * (r[0][1] - right[0][1]),\n ),\n ),\n pointFromVector(offsets[1], right[0]),\n ), // TOP RIGHT\n curve(\n pointFromVector(offsets[2], right[1]),\n pointFromVector(\n offsets[2],\n pointFrom<GlobalPoint>(\n right[1][0] + (2 / 3) * (r[1][0] - right[1][0]),\n right[1][1] + (2 / 3) * (r[1][1] - right[1][1]),\n ),\n ),\n pointFromVector(\n offsets[2],\n pointFrom<GlobalPoint>(\n bottom[1][0] + (2 / 3) * (r[1][0] - bottom[1][0]),\n bottom[1][1] + (2 / 3) * (r[1][1] - bottom[1][1]),\n ),\n ),\n pointFromVector(offsets[2], bottom[1]),\n ), // BOTTOM RIGHT\n curve(\n pointFromVector(offsets[3], bottom[0]),\n pointFromVector(\n offsets[3],\n pointFrom<GlobalPoint>(\n bottom[0][0] + (2 / 3) * (r[0][0] - bottom[0][0]),\n bottom[0][1] + (2 / 3) * (r[1][1] - bottom[0][1]),\n ),\n ),\n pointFromVector(\n offsets[3],\n pointFrom<GlobalPoint>(\n left[0][0] + (2 / 3) * (r[0][0] - left[0][0]),\n left[0][1] + (2 / 3) * (r[1][1] - left[0][1]),\n ),\n ),\n pointFromVector(offsets[3], left[0]),\n ), // BOTTOM LEFT\n ];\n\n const sides = [\n lineSegment<GlobalPoint>(corners[0][3], corners[1][0]),\n lineSegment<GlobalPoint>(corners[1][3], corners[2][0]),\n lineSegment<GlobalPoint>(corners[2][3], corners[3][0]),\n lineSegment<GlobalPoint>(corners[3][3], corners[0][0]),\n ];\n\n return [sides, corners];\n}\n\n/**\n * Get the building components of a diamond element in the form of\n * line segments and curves as a tuple, in this order.\n *\n * @param element The element to deconstruct\n * @param offset An optional offset\n * @returns Tuple of line segments (0) and curves (1)\n */\nexport function deconstructDiamondElement(\n element: ExcalidrawDiamondElement,\n offset: number = 0,\n): [LineSegment<GlobalPoint>[], Curve<GlobalPoint>[]] {\n const [topX, topY, rightX, rightY, bottomX, bottomY, leftX, leftY] =\n getDiamondPoints(element);\n const verticalRadius = getCornerRadius(Math.abs(topX - leftX), element);\n const horizontalRadius = getCornerRadius(Math.abs(rightY - topY), element);\n\n if (element.roundness?.type == null) {\n const [top, right, bottom, left]: GlobalPoint[] = [\n pointFrom(element.x + topX, element.y + topY - offset),\n pointFrom(element.x + rightX + offset, element.y + rightY),\n pointFrom(element.x + bottomX, element.y + bottomY + offset),\n pointFrom(element.x + leftX - offset, element.y + leftY),\n ];\n\n // Create the line segment parts of the diamond\n // NOTE: Horizontal and vertical seems to be flipped here\n const topRight = lineSegment<GlobalPoint>(\n pointFrom(top[0] + verticalRadius, top[1] + horizontalRadius),\n pointFrom(right[0] - verticalRadius, right[1] - horizontalRadius),\n );\n const bottomRight = lineSegment<GlobalPoint>(\n pointFrom(right[0] - verticalRadius, right[1] + horizontalRadius),\n pointFrom(bottom[0] + verticalRadius, bottom[1] - horizontalRadius),\n );\n const bottomLeft = lineSegment<GlobalPoint>(\n pointFrom(bottom[0] - verticalRadius, bottom[1] - horizontalRadius),\n pointFrom(left[0] + verticalRadius, left[1] + horizontalRadius),\n );\n const topLeft = lineSegment<GlobalPoint>(\n pointFrom(left[0] + verticalRadius, left[1] - horizontalRadius),\n pointFrom(top[0] - verticalRadius, top[1] + horizontalRadius),\n );\n\n return [[topRight, bottomRight, bottomLeft, topLeft], []];\n }\n\n const center = pointFrom<GlobalPoint>(\n element.x + element.width / 2,\n element.y + element.height / 2,\n );\n\n const [top, right, bottom, left]: GlobalPoint[] = [\n pointFrom(element.x + topX, element.y + topY),\n pointFrom(element.x + rightX, element.y + rightY),\n pointFrom(element.x + bottomX, element.y + bottomY),\n pointFrom(element.x + leftX, element.y + leftY),\n ];\n\n const offsets = [\n vectorScale(vectorNormalize(vectorFromPoint(right, center)), offset), // RIGHT\n vectorScale(vectorNormalize(vectorFromPoint(bottom, center)), offset), // BOTTOM\n vectorScale(vectorNormalize(vectorFromPoint(left, center)), offset), // LEFT\n vectorScale(vectorNormalize(vectorFromPoint(top, center)), offset), // TOP\n ];\n\n const corners = [\n curve(\n pointFromVector(\n offsets[0],\n pointFrom<GlobalPoint>(\n right[0] - verticalRadius,\n right[1] - horizontalRadius,\n ),\n ),\n pointFromVector(offsets[0], right),\n pointFromVector(offsets[0], right),\n pointFromVector(\n offsets[0],\n pointFrom<GlobalPoint>(\n right[0] - verticalRadius,\n right[1] + horizontalRadius,\n ),\n ),\n ), // RIGHT\n curve(\n pointFromVector(\n offsets[1],\n pointFrom<GlobalPoint>(\n bottom[0] + verticalRadius,\n bottom[1] - horizontalRadius,\n ),\n ),\n pointFromVector(offsets[1], bottom),\n pointFromVector(offsets[1], bottom),\n pointFromVector(\n offsets[1],\n pointFrom<GlobalPoint>(\n bottom[0] - verticalRadius,\n bottom[1] - horizontalRadius,\n ),\n ),\n ), // BOTTOM\n curve(\n pointFromVector(\n offsets[2],\n pointFrom<GlobalPoint>(\n left[0] + verticalRadius,\n left[1] + horizontalRadius,\n ),\n ),\n pointFromVector(offsets[2], left),\n pointFromVector(offsets[2], left),\n pointFromVector(\n offsets[2],\n pointFrom<GlobalPoint>(\n left[0] + verticalRadius,\n left[1] - horizontalRadius,\n ),\n ),\n ), // LEFT\n curve(\n pointFromVector(\n offsets[3],\n pointFrom<GlobalPoint>(\n top[0] - verticalRadius,\n top[1] + horizontalRadius,\n ),\n ),\n pointFromVector(offsets[3], top),\n pointFromVector(offsets[3], top),\n pointFromVector(\n offsets[3],\n pointFrom<GlobalPoint>(\n top[0] + verticalRadius,\n top[1] + horizontalRadius,\n ),\n ),\n ), // TOP\n ];\n\n const sides = [\n lineSegment<GlobalPoint>(corners[0][3], corners[1][0]),\n lineSegment<GlobalPoint>(corners[1][3], corners[2][0]),\n lineSegment<GlobalPoint>(corners[2][3], corners[3][0]),\n lineSegment<GlobalPoint>(corners[3][3], corners[0][0]),\n ];\n\n return [sides, corners];\n}\n", "import type {\n ElementsMap,\n ExcalidrawDiamondElement,\n ExcalidrawElement,\n ExcalidrawEllipseElement,\n ExcalidrawRectangleElement,\n ExcalidrawRectanguloidElement,\n} from \"./types\";\nimport { getElementBounds } from \"./bounds\";\nimport type { FrameNameBounds } from \"../types\";\nimport type { GeometricShape } from \"@excalidraw/utils/geometry/shape\";\nimport { getPolygonShape } from \"@excalidraw/utils/geometry/shape\";\nimport { isPointInShape, isPointOnShape } from \"@excalidraw/utils/collision\";\nimport { isTransparent } from \"../utils\";\nimport {\n hasBoundTextElement,\n isIframeLikeElement,\n isImageElement,\n isTextElement,\n} from \"./typeChecks\";\nimport { getBoundTextShape, isPathALoop } from \"../shapes\";\nimport type {\n GlobalPoint,\n LineSegment,\n LocalPoint,\n Polygon,\n Radians,\n} from \"@excalidraw/math\";\nimport {\n curveIntersectLineSegment,\n isPointWithinBounds,\n line,\n lineSegment,\n lineSegmentIntersectionPoints,\n pointFrom,\n pointRotateRads,\n pointsEqual,\n} from \"@excalidraw/math\";\nimport {\n ellipse,\n ellipseLineIntersectionPoints,\n} from \"@excalidraw/math/ellipse\";\nimport {\n deconstructDiamondElement,\n deconstructRectanguloidElement,\n} from \"./utils\";\n\nexport const shouldTestInside = (element: ExcalidrawElement) => {\n if (element.type === \"arrow\") {\n return false;\n }\n\n const isDraggableFromInside =\n !isTransparent(element.backgroundColor) ||\n hasBoundTextElement(element) ||\n isIframeLikeElement(element) ||\n isTextElement(element);\n\n if (element.type === \"line\") {\n return isDraggableFromInside && isPathALoop(element.points);\n }\n\n if (element.type === \"freedraw\") {\n return isDraggableFromInside && isPathALoop(element.points);\n }\n\n return isDraggableFromInside || isImageElement(element);\n};\n\nexport type HitTestArgs<Point extends GlobalPoint | LocalPoint> = {\n x: number;\n y: number;\n element: ExcalidrawElement;\n shape: GeometricShape<Point>;\n threshold?: number;\n frameNameBound?: FrameNameBounds | null;\n};\n\nexport const hitElementItself = <Point extends GlobalPoint | LocalPoint>({\n x,\n y,\n element,\n shape,\n threshold = 10,\n frameNameBound = null,\n}: HitTestArgs<Point>) => {\n let hit = shouldTestInside(element)\n ? // Since `inShape` tests STRICTLY againt the insides of a shape\n // we would need `onShape` as well to include the \"borders\"\n isPointInShape(pointFrom(x, y), shape) ||\n isPointOnShape(pointFrom(x, y), shape, threshold)\n : isPointOnShape(pointFrom(x, y), shape, threshold);\n\n // hit test against a frame's name\n if (!hit && frameNameBound) {\n hit = isPointInShape(pointFrom(x, y), {\n type: \"polygon\",\n data: getPolygonShape(frameNameBound as ExcalidrawRectangleElement)\n .data as Polygon<Point>,\n });\n }\n\n return hit;\n};\n\nexport const hitElementBoundingBox = (\n x: number,\n y: number,\n element: ExcalidrawElement,\n elementsMap: ElementsMap,\n tolerance = 0,\n) => {\n let [x1, y1, x2, y2] = getElementBounds(element, elementsMap);\n x1 -= tolerance;\n y1 -= tolerance;\n x2 += tolerance;\n y2 += tolerance;\n return isPointWithinBounds(\n pointFrom(x1, y1),\n pointFrom(x, y),\n pointFrom(x2, y2),\n );\n};\n\nexport const hitElementBoundingBoxOnly = <\n Point extends GlobalPoint | LocalPoint,\n>(\n hitArgs: HitTestArgs<Point>,\n elementsMap: ElementsMap,\n) => {\n return (\n !hitElementItself(hitArgs) &&\n // bound text is considered part of the element (even if it's outside the bounding box)\n !hitElementBoundText(\n hitArgs.x,\n hitArgs.y,\n getBoundTextShape(hitArgs.element, elementsMap),\n ) &&\n hitElementBoundingBox(hitArgs.x, hitArgs.y, hitArgs.element, elementsMap)\n );\n};\n\nexport const hitElementBoundText = <Point extends GlobalPoint | LocalPoint>(\n x: number,\n y: number,\n textShape: GeometricShape<Point> | null,\n): boolean => {\n return !!textShape && isPointInShape(pointFrom(x, y), textShape);\n};\n\n/**\n * Intersect a line with an element for binding test\n *\n * @param element\n * @param line\n * @param offset\n * @returns\n */\nexport const intersectElementWithLineSegment = (\n element: ExcalidrawElement,\n line: LineSegment<GlobalPoint>,\n offset: number = 0,\n): GlobalPoint[] => {\n switch (element.type) {\n case \"rectangle\":\n case \"image\":\n case \"text\":\n case \"iframe\":\n case \"embeddable\":\n case \"frame\":\n case \"magicframe\":\n return intersectRectanguloidWithLineSegment(element, line, offset);\n case \"diamond\":\n return intersectDiamondWithLineSegment(element, line, offset);\n case \"ellipse\":\n return intersectEllipseWithLineSegment(element, line, offset);\n default:\n throw new Error(`Unimplemented element type '${element.type}'`);\n }\n};\n\nconst intersectRectanguloidWithLineSegment = (\n element: ExcalidrawRectanguloidElement,\n l: LineSegment<GlobalPoint>,\n offset: number = 0,\n): GlobalPoint[] => {\n const center = pointFrom<GlobalPoint>(\n element.x + element.width / 2,\n element.y + element.height / 2,\n );\n // To emulate a rotated rectangle we rotate the point in the inverse angle\n // instead. It's all the same distance-wise.\n const rotatedA = pointRotateRads<GlobalPoint>(\n l[0],\n center,\n -element.angle as Radians,\n );\n const rotatedB = pointRotateRads<GlobalPoint>(\n l[1],\n center,\n -element.angle as Radians,\n );\n\n // Get the element's building components we can test against\n const [sides, corners] = deconstructRectanguloidElement(element, offset);\n\n return (\n [\n // Test intersection against the sides, keep only the valid\n // intersection points and rotate them back to scene space\n ...sides\n .map((s) =>\n lineSegmentIntersectionPoints(\n lineSegment<GlobalPoint>(rotatedA, rotatedB),\n s,\n ),\n )\n .filter((x) => x != null)\n .map((j) => pointRotateRads<GlobalPoint>(j!, center, element.angle)),\n // Test intersection against the corners which are cubic bezier curves,\n // keep only the valid intersection points and rotate them back to scene\n // space\n ...corners\n .flatMap((t) =>\n curveIntersectLineSegment(t, lineSegment(rotatedA, rotatedB)),\n )\n .filter((i) => i != null)\n .map((j) => pointRotateRads(j, center, element.angle)),\n ]\n // Remove duplicates\n .filter(\n (p, idx, points) => points.findIndex((d) => pointsEqual(p, d)) === idx,\n )\n );\n};\n\n/**\n *\n * @param element\n * @param a\n * @param b\n * @returns\n */\nconst intersectDiamondWithLineSegment = (\n element: ExcalidrawDiamondElement,\n l: LineSegment<GlobalPoint>,\n offset: number = 0,\n): GlobalPoint[] => {\n const center = pointFrom<GlobalPoint>(\n element.x + element.width / 2,\n element.y + element.height / 2,\n );\n\n // Rotate the point to the inverse direction to simulate the rotated diamond\n // points. It's all the same distance-wise.\n const rotatedA = pointRotateRads(l[0], center, -element.angle as Radians);\n const rotatedB = pointRotateRads(l[1], center, -element.angle as Radians);\n\n const [sides, curves] = deconstructDiamondElement(element, offset);\n\n return (\n [\n ...sides\n .map((s) =>\n lineSegmentIntersectionPoints(\n lineSegment<GlobalPoint>(rotatedA, rotatedB),\n s,\n ),\n )\n .filter((p): p is GlobalPoint => p != null)\n // Rotate back intersection points\n .map((p) => pointRotateRads<GlobalPoint>(p!, center, element.angle)),\n ...curves\n .flatMap((p) =>\n curveIntersectLineSegment(p, lineSegment(rotatedA, rotatedB)),\n )\n .filter((p) => p != null)\n // Rotate back intersection points\n .map((p) => pointRotateRads(p, center, element.angle)),\n ]\n // Remove duplicates\n .filter(\n (p, idx, points) => points.findIndex((d) => pointsEqual(p, d)) === idx,\n )\n );\n};\n\n/**\n *\n * @param element\n * @param a\n * @param b\n * @returns\n */\nconst intersectEllipseWithLineSegment = (\n element: ExcalidrawEllipseElement,\n l: LineSegment<GlobalPoint>,\n offset: number = 0,\n): GlobalPoint[] => {\n const center = pointFrom<GlobalPoint>(\n element.x + element.width / 2,\n element.y + element.height / 2,\n );\n\n const rotatedA = pointRotateRads(l[0], center, -element.angle as Radians);\n const rotatedB = pointRotateRads(l[1], center, -element.angle as Radians);\n\n return ellipseLineIntersectionPoints(\n ellipse(center, element.width / 2 + offset, element.height / 2 + offset),\n line(rotatedA, rotatedB),\n ).map((p) => pointRotateRads(p, center, element.angle));\n};\n", "import { isDarwin } from \"./constants\";\nimport type { ValueOf } from \"./utility-types\";\n\nexport const CODES = {\n EQUAL: \"Equal\",\n MINUS: \"Minus\",\n NUM_ADD: \"NumpadAdd\",\n NUM_SUBTRACT: \"NumpadSubtract\",\n NUM_ZERO: \"Numpad0\",\n BRACKET_RIGHT: \"BracketRight\",\n BRACKET_LEFT: \"BracketLeft\",\n ONE: \"Digit1\",\n TWO: \"Digit2\",\n THREE: \"Digit3\",\n NINE: \"Digit9\",\n QUOTE: \"Quote\",\n ZERO: \"Digit0\",\n SLASH: \"Slash\",\n C: \"KeyC\",\n D: \"KeyD\",\n H: \"KeyH\",\n V: \"KeyV\",\n Z: \"KeyZ\",\n Y: \"KeyY\",\n R: \"KeyR\",\n S: \"KeyS\",\n} as const;\n\nexport const KEYS = {\n ARROW_DOWN: \"ArrowDown\",\n ARROW_LEFT: \"ArrowLeft\",\n ARROW_RIGHT: \"ArrowRight\",\n ARROW_UP: \"ArrowUp\",\n PAGE_UP: \"PageUp\",\n PAGE_DOWN: \"PageDown\",\n BACKSPACE: \"Backspace\",\n ALT: \"Alt\",\n CTRL_OR_CMD: isDarwin ? \"metaKey\" : \"ctrlKey\",\n DELETE: \"Delete\",\n ENTER: \"Enter\",\n ESCAPE: \"Escape\",\n QUESTION_MARK: \"?\",\n SPACE: \" \",\n TAB: \"Tab\",\n CHEVRON_LEFT: \"<\",\n CHEVRON_RIGHT: \">\",\n PERIOD: \".\",\n COMMA: \",\",\n SUBTRACT: \"-\",\n SLASH: \"/\",\n\n A: \"a\",\n C: \"c\",\n D: \"d\",\n E: \"e\",\n F: \"f\",\n G: \"g\",\n H: \"h\",\n I: \"i\",\n L: \"l\",\n O: \"o\",\n P: \"p\",\n Q: \"q\",\n R: \"r\",\n S: \"s\",\n T: \"t\",\n V: \"v\",\n X: \"x\",\n Y: \"y\",\n Z: \"z\",\n K: \"k\",\n W: \"w\",\n\n 0: \"0\",\n 1: \"1\",\n 2: \"2\",\n 3: \"3\",\n 4: \"4\",\n 5: \"5\",\n 6: \"6\",\n 7: \"7\",\n 8: \"8\",\n 9: \"9\",\n} as const;\n\nexport type Key = keyof typeof KEYS;\n\n// defines key code mapping for matching codes as fallback to respective keys on non-latin keyboard layouts\nexport const KeyCodeMap = new Map<ValueOf<typeof KEYS>, ValueOf<typeof CODES>>([\n [KEYS.Z, CODES.Z],\n [KEYS.Y, CODES.Y],\n]);\n\nexport const isLatinChar = (key: string) => /^[a-z]$/.test(key.toLowerCase());\n\n/**\n * Used to match key events for any keyboard layout, especially on Windows and Linux,\n * where non-latin character with modified (CMD) is not substituted with latin-based alternative.\n *\n * Uses `event.key` when it's latin, otherwise fallbacks to `event.code` (if mapping exists).\n *\n * Example of pressing \"z\" on different layouts, with the chosen key or code highlighted in []:\n *\n * Layout | Code | Key | Comment\n * --------------------- | ----- | --- | -------\n * U.S. | KeyZ | [z] |\n * Czech | KeyY | [z] |\n * Turkish | KeyN | [z] |\n * French | KeyW | [z] |\n * Macedonian | [KeyZ] | \u0437 | z with cmd; \u0437 is Cyrillic equivalent of z\n * Russian | [KeyZ] | \u044F | z with cmd\n * Serbian | [KeyZ] | \u0455 | z with cmd\n * Greek | [KeyZ] | \u03B6 | z with cmd; also \u03B6 is Greek equivalent of z\n * Hebrew | [KeyZ] | \u05D6 | z with cmd; also \u05D6 is Hebrew equivalent of z\n * Pinyin - Simplified | KeyZ | [z] | due to IME\n * Cangije - Traditional | [KeyZ] | \u91CD | z with cmd\n * Japanese | [KeyZ] | \u3064 | z with cmd\n * 2-Set Korean | [KeyZ] | \u314B | z with cmd\n *\n * More details in https://github.com/excalidraw/excalidraw/pull/5944\n */\nexport const matchKey = (\n event: KeyboardEvent | React.KeyboardEvent<Element>,\n key: ValueOf<typeof KEYS>,\n): boolean => {\n // for latin layouts use key\n if (key === event.key.toLowerCase()) {\n return true;\n }\n\n // non-latin layouts fallback to code\n const code = KeyCodeMap.get(key);\n return Boolean(code && !isLatinChar(event.key) && event.code === code);\n};\n\nexport const isArrowKey = (key: string) =>\n key === KEYS.ARROW_LEFT ||\n key === KEYS.ARROW_RIGHT ||\n key === KEYS.ARROW_DOWN ||\n key === KEYS.ARROW_UP;\n\nexport const shouldResizeFromCenter = (event: MouseEvent | KeyboardEvent) =>\n event.altKey;\n\nexport const shouldMaintainAspectRatio = (event: MouseEvent | KeyboardEvent) =>\n event.shiftKey;\n\nexport const shouldRotateWithDiscreteAngle = (\n event: MouseEvent | KeyboardEvent | React.PointerEvent<HTMLCanvasElement>,\n) => event.shiftKey;\n", "import {\n isPoint,\n pointFrom,\n pointDistance,\n pointFromPair,\n pointRotateRads,\n pointsEqual,\n type GlobalPoint,\n type LocalPoint,\n} from \"@excalidraw/math\";\nimport {\n getClosedCurveShape,\n getCurvePathOps,\n getCurveShape,\n getEllipseShape,\n getFreedrawShape,\n getPolygonShape,\n type GeometricShape,\n} from \"@excalidraw/utils/geometry/shape\";\nimport {\n ArrowIcon,\n DiamondIcon,\n EllipseIcon,\n EraserIcon,\n FreedrawIcon,\n ImageIcon,\n LineIcon,\n RectangleIcon,\n SelectionIcon,\n TextIcon,\n} from \"./components/icons\";\nimport {\n DEFAULT_ADAPTIVE_RADIUS,\n DEFAULT_PROPORTIONAL_RADIUS,\n LINE_CONFIRM_THRESHOLD,\n ROUNDNESS,\n} from \"./constants\";\nimport { getElementAbsoluteCoords } from \"./element\";\nimport type { Bounds } from \"./element/bounds\";\nimport { shouldTestInside } from \"./element/collision\";\nimport { LinearElementEditor } from \"./element/linearElementEditor\";\nimport { getBoundTextElement } from \"./element/textElement\";\nimport type {\n ElementsMap,\n ExcalidrawElement,\n ExcalidrawLinearElement,\n NonDeleted,\n} from \"./element/types\";\nimport { KEYS } from \"./keys\";\nimport { ShapeCache } from \"./scene/ShapeCache\";\nimport type { NormalizedZoomValue, Zoom } from \"./types\";\nimport { invariant } from \"./utils\";\n\nexport const SHAPES = [\n {\n icon: SelectionIcon,\n value: \"selection\",\n key: KEYS.V,\n numericKey: KEYS[\"1\"],\n fillable: true,\n },\n {\n icon: RectangleIcon,\n value: \"rectangle\",\n key: KEYS.R,\n numericKey: KEYS[\"2\"],\n fillable: true,\n },\n {\n icon: DiamondIcon,\n value: \"diamond\",\n key: KEYS.D,\n numericKey: KEYS[\"3\"],\n fillable: true,\n },\n {\n icon: EllipseIcon,\n value: \"ellipse\",\n key: KEYS.O,\n numericKey: KEYS[\"4\"],\n fillable: true,\n },\n {\n icon: ArrowIcon,\n value: \"arrow\",\n key: KEYS.A,\n numericKey: KEYS[\"5\"],\n fillable: true,\n },\n {\n icon: LineIcon,\n value: \"line\",\n key: KEYS.L,\n numericKey: KEYS[\"6\"],\n fillable: true,\n },\n {\n icon: FreedrawIcon,\n value: \"freedraw\",\n key: [KEYS.P, KEYS.X],\n numericKey: KEYS[\"7\"],\n fillable: false,\n },\n {\n icon: TextIcon,\n value: \"text\",\n key: KEYS.T,\n numericKey: KEYS[\"8\"],\n fillable: false,\n },\n {\n icon: ImageIcon,\n value: \"image\",\n key: null,\n numericKey: KEYS[\"9\"],\n fillable: false,\n },\n {\n icon: EraserIcon,\n value: \"eraser\",\n key: KEYS.E,\n numericKey: KEYS[\"0\"],\n fillable: false,\n },\n] as const;\n\nexport const findShapeByKey = (key: string) => {\n const shape = SHAPES.find((shape, index) => {\n return (\n (shape.numericKey != null && key === shape.numericKey.toString()) ||\n (shape.key &&\n (typeof shape.key === \"string\"\n ? shape.key === key\n : (shape.key as readonly string[]).includes(key)))\n );\n });\n return shape?.value || null;\n};\n\n/**\n * get the pure geometric shape of an excalidraw element\n * which is then used for hit detection\n */\nexport const getElementShape = <Point extends GlobalPoint | LocalPoint>(\n element: ExcalidrawElement,\n elementsMap: ElementsMap,\n): GeometricShape<Point> => {\n switch (element.type) {\n case \"rectangle\":\n case \"diamond\":\n case \"frame\":\n case \"magicframe\":\n case \"embeddable\":\n case \"image\":\n case \"iframe\":\n case \"text\":\n case \"selection\":\n return getPolygonShape(element);\n case \"arrow\":\n case \"line\": {\n const roughShape =\n ShapeCache.get(element)?.[0] ??\n ShapeCache.generateElementShape(element, null)[0];\n const [, , , , cx, cy] = getElementAbsoluteCoords(element, elementsMap);\n\n return shouldTestInside(element)\n ? getClosedCurveShape<Point>(\n element,\n roughShape,\n pointFrom<Point>(element.x, element.y),\n element.angle,\n pointFrom(cx, cy),\n )\n : getCurveShape<Point>(\n roughShape,\n pointFrom<Point>(element.x, element.y),\n element.angle,\n pointFrom(cx, cy),\n );\n }\n\n case \"ellipse\":\n return getEllipseShape(element);\n\n case \"freedraw\": {\n const [, , , , cx, cy] = getElementAbsoluteCoords(element, elementsMap);\n return getFreedrawShape(\n element,\n pointFrom(cx, cy),\n shouldTestInside(element),\n );\n }\n }\n};\n\nexport const getBoundTextShape = <Point extends GlobalPoint | LocalPoint>(\n element: ExcalidrawElement,\n elementsMap: ElementsMap,\n): GeometricShape<Point> | null => {\n const boundTextElement = getBoundTextElement(element, elementsMap);\n\n if (boundTextElement) {\n if (element.type === \"arrow\") {\n return getElementShape(\n {\n ...boundTextElement,\n // arrow's bound text accurate position is not stored in the element's property\n // but rather calculated and returned from the following static method\n ...LinearElementEditor.getBoundTextElementPosition(\n element,\n boundTextElement,\n elementsMap,\n ),\n },\n elementsMap,\n );\n }\n return getElementShape(boundTextElement, elementsMap);\n }\n\n return null;\n};\n\nexport const getControlPointsForBezierCurve = <\n P extends GlobalPoint | LocalPoint,\n>(\n element: NonDeleted<ExcalidrawLinearElement>,\n endPoint: P,\n) => {\n const shape = ShapeCache.generateElementShape(element, null);\n if (!shape) {\n return null;\n }\n\n const ops = getCurvePathOps(shape[0]);\n let currentP = pointFrom<P>(0, 0);\n let index = 0;\n let minDistance = Infinity;\n let controlPoints: P[] | null = null;\n\n while (index < ops.length) {\n const { op, data } = ops[index];\n if (op === \"move\") {\n invariant(\n isPoint(data),\n \"The returned ops is not compatible with a point\",\n );\n currentP = pointFromPair(data);\n }\n if (op === \"bcurveTo\") {\n const p0 = currentP;\n const p1 = pointFrom<P>(data[0], data[1]);\n const p2 = pointFrom<P>(data[2], data[3]);\n const p3 = pointFrom<P>(data[4], data[5]);\n const distance = pointDistance(p3, endPoint);\n if (distance < minDistance) {\n minDistance = distance;\n controlPoints = [p0, p1, p2, p3];\n }\n currentP = p3;\n }\n index++;\n }\n\n return controlPoints;\n};\n\nexport const getBezierXY = <P extends GlobalPoint | LocalPoint>(\n p0: P,\n p1: P,\n p2: P,\n p3: P,\n t: number,\n): P => {\n const equation = (t: number, idx: number) =>\n Math.pow(1 - t, 3) * p3[idx] +\n 3 * t * Math.pow(1 - t, 2) * p2[idx] +\n 3 * Math.pow(t, 2) * (1 - t) * p1[idx] +\n p0[idx] * Math.pow(t, 3);\n const tx = equation(t, 0);\n const ty = equation(t, 1);\n return pointFrom(tx, ty);\n};\n\nconst getPointsInBezierCurve = <P extends GlobalPoint | LocalPoint>(\n element: NonDeleted<ExcalidrawLinearElement>,\n endPoint: P,\n) => {\n const controlPoints: P[] = getControlPointsForBezierCurve(element, endPoint)!;\n if (!controlPoints) {\n return [];\n }\n const pointsOnCurve: P[] = [];\n let t = 1;\n // Take 20 points on curve for better accuracy\n while (t > 0) {\n const p = getBezierXY(\n controlPoints[0],\n controlPoints[1],\n controlPoints[2],\n controlPoints[3],\n t,\n );\n pointsOnCurve.push(pointFrom(p[0], p[1]));\n t -= 0.05;\n }\n if (pointsOnCurve.length) {\n if (pointsEqual(pointsOnCurve.at(-1)!, endPoint)) {\n pointsOnCurve.push(pointFrom(endPoint[0], endPoint[1]));\n }\n }\n return pointsOnCurve;\n};\n\nconst getBezierCurveArcLengths = <P extends GlobalPoint | LocalPoint>(\n element: NonDeleted<ExcalidrawLinearElement>,\n endPoint: P,\n) => {\n const arcLengths: number[] = [];\n arcLengths[0] = 0;\n const points = getPointsInBezierCurve(element, endPoint);\n let index = 0;\n let distance = 0;\n while (index < points.length - 1) {\n const segmentDistance = pointDistance(points[index], points[index + 1]);\n distance += segmentDistance;\n arcLengths.push(distance);\n index++;\n }\n\n return arcLengths;\n};\n\nexport const getBezierCurveLength = <P extends GlobalPoint | LocalPoint>(\n element: NonDeleted<ExcalidrawLinearElement>,\n endPoint: P,\n) => {\n const arcLengths = getBezierCurveArcLengths(element, endPoint);\n return arcLengths.at(-1) as number;\n};\n\n// This maps interval to actual interval t on the curve so that when t = 0.5, its actually the point at 50% of the length\nexport const mapIntervalToBezierT = <P extends GlobalPoint | LocalPoint>(\n element: NonDeleted<ExcalidrawLinearElement>,\n endPoint: P,\n interval: number, // The interval between 0 to 1 for which you want to find the point on the curve,\n) => {\n const arcLengths = getBezierCurveArcLengths(element, endPoint);\n const pointsCount = arcLengths.length - 1;\n const curveLength = arcLengths.at(-1) as number;\n const targetLength = interval * curveLength;\n let low = 0;\n let high = pointsCount;\n let index = 0;\n // Doing a binary search to find the largest length that is less than the target length\n while (low < high) {\n index = Math.floor(low + (high - low) / 2);\n if (arcLengths[index] < targetLength) {\n low = index + 1;\n } else {\n high = index;\n }\n }\n if (arcLengths[index] > targetLength) {\n index--;\n }\n if (arcLengths[index] === targetLength) {\n return index / pointsCount;\n }\n\n return (\n 1 -\n (index +\n (targetLength - arcLengths[index]) /\n (arcLengths[index + 1] - arcLengths[index])) /\n pointsCount\n );\n};\n\n/**\n * Get the axis-aligned bounding box for a given element\n */\nexport const aabbForElement = (\n element: Readonly<ExcalidrawElement>,\n offset?: [number, number, number, number],\n) => {\n const bbox = {\n minX: element.x,\n minY: element.y,\n maxX: element.x + element.width,\n maxY: element.y + element.height,\n midX: element.x + element.width / 2,\n midY: element.y + element.height / 2,\n };\n\n const center = pointFrom(bbox.midX, bbox.midY);\n const [topLeftX, topLeftY] = pointRotateRads(\n pointFrom(bbox.minX, bbox.minY),\n center,\n element.angle,\n );\n const [topRightX, topRightY] = pointRotateRads(\n pointFrom(bbox.maxX, bbox.minY),\n center,\n element.angle,\n );\n const [bottomRightX, bottomRightY] = pointRotateRads(\n pointFrom(bbox.maxX, bbox.maxY),\n center,\n element.angle,\n );\n const [bottomLeftX, bottomLeftY] = pointRotateRads(\n pointFrom(bbox.minX, bbox.maxY),\n center,\n element.angle,\n );\n\n const bounds = [\n Math.min(topLeftX, topRightX, bottomRightX, bottomLeftX),\n Math.min(topLeftY, topRightY, bottomRightY, bottomLeftY),\n Math.max(topLeftX, topRightX, bottomRightX, bottomLeftX),\n Math.max(topLeftY, topRightY, bottomRightY, bottomLeftY),\n ] as Bounds;\n\n if (offset) {\n const [topOffset, rightOffset, downOffset, leftOffset] = offset;\n return [\n bounds[0] - leftOffset,\n bounds[1] - topOffset,\n bounds[2] + rightOffset,\n bounds[3] + downOffset,\n ] as Bounds;\n }\n\n return bounds;\n};\n\nexport const pointInsideBounds = <P extends GlobalPoint | LocalPoint>(\n p: P,\n bounds: Bounds,\n): boolean =>\n p[0] > bounds[0] && p[0] < bounds[2] && p[1] > bounds[1] && p[1] < bounds[3];\n\nexport const aabbsOverlapping = (a: Bounds, b: Bounds) =>\n pointInsideBounds(pointFrom(a[0], a[1]), b) ||\n pointInsideBounds(pointFrom(a[2], a[1]), b) ||\n pointInsideBounds(pointFrom(a[2], a[3]), b) ||\n pointInsideBounds(pointFrom(a[0], a[3]), b) ||\n pointInsideBounds(pointFrom(b[0], b[1]), a) ||\n pointInsideBounds(pointFrom(b[2], b[1]), a) ||\n pointInsideBounds(pointFrom(b[2], b[3]), a) ||\n pointInsideBounds(pointFrom(b[0], b[3]), a);\n\nexport const getCornerRadius = (x: number, element: ExcalidrawElement) => {\n if (\n element.roundness?.type === ROUNDNESS.PROPORTIONAL_RADIUS ||\n element.roundness?.type === ROUNDNESS.LEGACY\n ) {\n return x * DEFAULT_PROPORTIONAL_RADIUS;\n }\n\n if (element.roundness?.type === ROUNDNESS.ADAPTIVE_RADIUS) {\n const fixedRadiusSize = element.roundness?.value ?? DEFAULT_ADAPTIVE_RADIUS;\n\n const CUTOFF_SIZE = fixedRadiusSize / DEFAULT_PROPORTIONAL_RADIUS;\n\n if (x <= CUTOFF_SIZE) {\n return x * DEFAULT_PROPORTIONAL_RADIUS;\n }\n\n return fixedRadiusSize;\n }\n\n return 0;\n};\n\n// Checks if the first and last point are close enough\n// to be considered a loop\nexport const isPathALoop = (\n points: ExcalidrawLinearElement[\"points\"],\n /** supply if you want the loop detection to account for current zoom */\n zoomValue: Zoom[\"value\"] = 1 as NormalizedZoomValue,\n): boolean => {\n if (points.length >= 3) {\n const [first, last] = [points[0], points[points.length - 1]];\n const distance = pointDistance(first, last);\n\n // Adjusting LINE_CONFIRM_THRESHOLD to current zoom so that when zoomed in\n // really close we make the threshold smaller, and vice versa.\n return distance <= LINE_CONFIRM_THRESHOLD / zoomValue;\n }\n return false;\n};\n", "import { type Point } from \"points-on-curve\";\nimport {\n type Radians,\n pointFrom,\n pointCenter,\n pointRotateRads,\n vectorFromPoint,\n vectorNormalize,\n vectorSubtract,\n vectorAdd,\n vectorScale,\n pointFromVector,\n clamp,\n isCloseTo,\n} from \"@excalidraw/math\";\nimport type { TransformHandleType } from \"./transformHandles\";\nimport type {\n ElementsMap,\n ExcalidrawElement,\n ExcalidrawImageElement,\n ImageCrop,\n NonDeleted,\n} from \"./types\";\nimport {\n getElementAbsoluteCoords,\n getResizedElementAbsoluteCoords,\n} from \"./bounds\";\n\nexport const MINIMAL_CROP_SIZE = 10;\n\nexport const cropElement = (\n element: ExcalidrawImageElement,\n transformHandle: TransformHandleType,\n naturalWidth: number,\n naturalHeight: number,\n pointerX: number,\n pointerY: number,\n widthAspectRatio?: number,\n) => {\n const { width: uncroppedWidth, height: uncroppedHeight } =\n getUncroppedWidthAndHeight(element);\n\n const naturalWidthToUncropped = naturalWidth / uncroppedWidth;\n const naturalHeightToUncropped = naturalHeight / uncroppedHeight;\n\n const croppedLeft = (element.crop?.x ?? 0) / naturalWidthToUncropped;\n const croppedTop = (element.crop?.y ?? 0) / naturalHeightToUncropped;\n\n /**\n * uncropped width\n * *\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013*\n * | (x,y) (natural) |\n * | *\u2013\u2013\u2013\u2013\u2013\u2013\u2013* |\n * | |///////| height | uncropped height\n * | *\u2013\u2013\u2013\u2013\u2013\u2013\u2013* |\n * | width (natural) |\n * *\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013*\n */\n\n const rotatedPointer = pointRotateRads(\n pointFrom(pointerX, pointerY),\n pointFrom(element.x + element.width / 2, element.y + element.height / 2),\n -element.angle as Radians,\n );\n\n pointerX = rotatedPointer[0];\n pointerY = rotatedPointer[1];\n\n let nextWidth = element.width;\n let nextHeight = element.height;\n\n let crop: ImageCrop | null = element.crop ?? {\n x: 0,\n y: 0,\n width: naturalWidth,\n height: naturalHeight,\n naturalWidth,\n naturalHeight,\n };\n\n const previousCropHeight = crop.height;\n const previousCropWidth = crop.width;\n\n const isFlippedByX = element.scale[0] === -1;\n const isFlippedByY = element.scale[1] === -1;\n\n let changeInHeight = pointerY - element.y;\n let changeInWidth = pointerX - element.x;\n\n if (transformHandle.includes(\"n\")) {\n nextHeight = clamp(\n element.height - changeInHeight,\n MINIMAL_CROP_SIZE,\n isFlippedByY ? uncroppedHeight - croppedTop : element.height + croppedTop,\n );\n }\n\n if (transformHandle.includes(\"s\")) {\n changeInHeight = pointerY - element.y - element.height;\n nextHeight = clamp(\n element.height + changeInHeight,\n MINIMAL_CROP_SIZE,\n isFlippedByY ? element.height + croppedTop : uncroppedHeight - croppedTop,\n );\n }\n\n if (transformHandle.includes(\"e\")) {\n changeInWidth = pointerX - element.x - element.width;\n\n nextWidth = clamp(\n element.width + changeInWidth,\n MINIMAL_CROP_SIZE,\n isFlippedByX ? element.width + croppedLeft : uncroppedWidth - croppedLeft,\n );\n }\n\n if (transformHandle.includes(\"w\")) {\n nextWidth = clamp(\n element.width - changeInWidth,\n MINIMAL_CROP_SIZE,\n isFlippedByX ? uncroppedWidth - croppedLeft : element.width + croppedLeft,\n );\n }\n\n const updateCropWidthAndHeight = (crop: ImageCrop) => {\n crop.height = nextHeight * naturalHeightToUncropped;\n crop.width = nextWidth * naturalWidthToUncropped;\n };\n\n updateCropWidthAndHeight(crop);\n\n const adjustFlipForHandle = (\n handle: TransformHandleType,\n crop: ImageCrop,\n ) => {\n updateCropWidthAndHeight(crop);\n if (handle.includes(\"n\")) {\n if (!isFlippedByY) {\n crop.y += previousCropHeight - crop.height;\n }\n }\n if (handle.includes(\"s\")) {\n if (isFlippedByY) {\n crop.y += previousCropHeight - crop.height;\n }\n }\n if (handle.includes(\"e\")) {\n if (isFlippedByX) {\n crop.x += previousCropWidth - crop.width;\n }\n }\n if (handle.includes(\"w\")) {\n if (!isFlippedByX) {\n crop.x += previousCropWidth - crop.width;\n }\n }\n };\n\n switch (transformHandle) {\n case \"n\": {\n if (widthAspectRatio) {\n const distanceToLeft = croppedLeft + element.width / 2;\n const distanceToRight =\n uncroppedWidth - croppedLeft - element.width / 2;\n\n const MAX_WIDTH = Math.min(distanceToLeft, distanceToRight) * 2;\n\n nextWidth = clamp(\n nextHeight * widthAspectRatio,\n MINIMAL_CROP_SIZE,\n MAX_WIDTH,\n );\n nextHeight = nextWidth / widthAspectRatio;\n }\n\n adjustFlipForHandle(transformHandle, crop);\n\n if (widthAspectRatio) {\n crop.x += (previousCropWidth - crop.width) / 2;\n }\n\n break;\n }\n case \"s\": {\n if (widthAspectRatio) {\n const distanceToLeft = croppedLeft + element.width / 2;\n const distanceToRight =\n uncroppedWidth - croppedLeft - element.width / 2;\n\n const MAX_WIDTH = Math.min(distanceToLeft, distanceToRight) * 2;\n\n nextWidth = clamp(\n nextHeight * widthAspectRatio,\n MINIMAL_CROP_SIZE,\n MAX_WIDTH,\n );\n nextHeight = nextWidth / widthAspectRatio;\n }\n\n adjustFlipForHandle(transformHandle, crop);\n\n if (widthAspectRatio) {\n crop.x += (previousCropWidth - crop.width) / 2;\n }\n\n break;\n }\n case \"w\": {\n if (widthAspectRatio) {\n const distanceToTop = croppedTop + element.height / 2;\n const distanceToBottom =\n uncroppedHeight - croppedTop - element.height / 2;\n\n const MAX_HEIGHT = Math.min(distanceToTop, distanceToBottom) * 2;\n\n nextHeight = clamp(\n nextWidth / widthAspectRatio,\n MINIMAL_CROP_SIZE,\n MAX_HEIGHT,\n );\n nextWidth = nextHeight * widthAspectRatio;\n }\n\n adjustFlipForHandle(transformHandle, crop);\n\n if (widthAspectRatio) {\n crop.y += (previousCropHeight - crop.height) / 2;\n }\n\n break;\n }\n case \"e\": {\n if (widthAspectRatio) {\n const distanceToTop = croppedTop + element.height / 2;\n const distanceToBottom =\n uncroppedHeight - croppedTop - element.height / 2;\n\n const MAX_HEIGHT = Math.min(distanceToTop, distanceToBottom) * 2;\n\n nextHeight = clamp(\n nextWidth / widthAspectRatio,\n MINIMAL_CROP_SIZE,\n MAX_HEIGHT,\n );\n nextWidth = nextHeight * widthAspectRatio;\n }\n\n adjustFlipForHandle(transformHandle, crop);\n\n if (widthAspectRatio) {\n crop.y += (previousCropHeight - crop.height) / 2;\n }\n\n break;\n }\n case \"ne\": {\n if (widthAspectRatio) {\n if (changeInWidth > -changeInHeight) {\n const MAX_HEIGHT = isFlippedByY\n ? uncroppedHeight - croppedTop\n : croppedTop + element.height;\n\n nextHeight = clamp(\n nextWidth / widthAspectRatio,\n MINIMAL_CROP_SIZE,\n MAX_HEIGHT,\n );\n nextWidth = nextHeight * widthAspectRatio;\n } else {\n const MAX_WIDTH = isFlippedByX\n ? croppedLeft + element.width\n : uncroppedWidth - croppedLeft;\n\n nextWidth = clamp(\n nextHeight * widthAspectRatio,\n MINIMAL_CROP_SIZE,\n MAX_WIDTH,\n );\n nextHeight = nextWidth / widthAspectRatio;\n }\n }\n\n adjustFlipForHandle(transformHandle, crop);\n break;\n }\n case \"nw\": {\n if (widthAspectRatio) {\n if (changeInWidth < changeInHeight) {\n const MAX_HEIGHT = isFlippedByY\n ? uncroppedHeight - croppedTop\n : croppedTop + element.height;\n nextHeight = clamp(\n nextWidth / widthAspectRatio,\n MINIMAL_CROP_SIZE,\n MAX_HEIGHT,\n );\n nextWidth = nextHeight * widthAspectRatio;\n } else {\n const MAX_WIDTH = isFlippedByX\n ? uncroppedWidth - croppedLeft\n : croppedLeft + element.width;\n\n nextWidth = clamp(\n nextHeight * widthAspectRatio,\n MINIMAL_CROP_SIZE,\n MAX_WIDTH,\n );\n nextHeight = nextWidth / widthAspectRatio;\n }\n }\n\n adjustFlipForHandle(transformHandle, crop);\n break;\n }\n case \"se\": {\n if (widthAspectRatio) {\n if (changeInWidth > changeInHeight) {\n const MAX_HEIGHT = isFlippedByY\n ? croppedTop + element.height\n : uncroppedHeight - croppedTop;\n\n nextHeight = clamp(\n nextWidth / widthAspectRatio,\n MINIMAL_CROP_SIZE,\n MAX_HEIGHT,\n );\n nextWidth = nextHeight * widthAspectRatio;\n } else {\n const MAX_WIDTH = isFlippedByX\n ? croppedLeft + element.width\n : uncroppedWidth - croppedLeft;\n\n nextWidth = clamp(\n nextHeight * widthAspectRatio,\n MINIMAL_CROP_SIZE,\n MAX_WIDTH,\n );\n nextHeight = nextWidth / widthAspectRatio;\n }\n }\n\n adjustFlipForHandle(transformHandle, crop);\n break;\n }\n case \"sw\": {\n if (widthAspectRatio) {\n if (-changeInWidth > changeInHeight) {\n const MAX_HEIGHT = isFlippedByY\n ? croppedTop + element.height\n : uncroppedHeight - croppedTop;\n\n nextHeight = clamp(\n nextWidth / widthAspectRatio,\n MINIMAL_CROP_SIZE,\n MAX_HEIGHT,\n );\n nextWidth = nextHeight * widthAspectRatio;\n } else {\n const MAX_WIDTH = isFlippedByX\n ? uncroppedWidth - croppedLeft\n : croppedLeft + element.width;\n\n nextWidth = clamp(\n nextHeight * widthAspectRatio,\n MINIMAL_CROP_SIZE,\n MAX_WIDTH,\n );\n nextHeight = nextWidth / widthAspectRatio;\n }\n }\n\n adjustFlipForHandle(transformHandle, crop);\n break;\n }\n default:\n break;\n }\n\n const newOrigin = recomputeOrigin(\n element,\n transformHandle,\n nextWidth,\n nextHeight,\n !!widthAspectRatio,\n );\n\n // reset crop to null if we're back to orig size\n if (\n isCloseTo(crop.width, crop.naturalWidth) &&\n isCloseTo(crop.height, crop.naturalHeight)\n ) {\n crop = null;\n }\n\n return {\n x: newOrigin[0],\n y: newOrigin[1],\n width: nextWidth,\n height: nextHeight,\n crop,\n };\n};\n\nconst recomputeOrigin = (\n stateAtCropStart: NonDeleted<ExcalidrawElement>,\n transformHandle: TransformHandleType,\n width: number,\n height: number,\n shouldMaintainAspectRatio?: boolean,\n) => {\n const [x1, y1, x2, y2] = getResizedElementAbsoluteCoords(\n stateAtCropStart,\n stateAtCropStart.width,\n stateAtCropStart.height,\n true,\n );\n const startTopLeft = pointFrom(x1, y1);\n const startBottomRight = pointFrom(x2, y2);\n const startCenter: any = pointCenter(startTopLeft, startBottomRight);\n\n const [newBoundsX1, newBoundsY1, newBoundsX2, newBoundsY2] =\n getResizedElementAbsoluteCoords(stateAtCropStart, width, height, true);\n const newBoundsWidth = newBoundsX2 - newBoundsX1;\n const newBoundsHeight = newBoundsY2 - newBoundsY1;\n\n // Calculate new topLeft based on fixed corner during resize\n let newTopLeft = [...startTopLeft] as [number, number];\n\n if ([\"n\", \"w\", \"nw\"].includes(transformHandle)) {\n newTopLeft = [\n startBottomRight[0] - Math.abs(newBoundsWidth),\n startBottomRight[1] - Math.abs(newBoundsHeight),\n ];\n }\n if (transformHandle === \"ne\") {\n const bottomLeft = [startTopLeft[0], startBottomRight[1]];\n newTopLeft = [bottomLeft[0], bottomLeft[1] - Math.abs(newBoundsHeight)];\n }\n if (transformHandle === \"sw\") {\n const topRight = [startBottomRight[0], startTopLeft[1]];\n newTopLeft = [topRight[0] - Math.abs(newBoundsWidth), topRight[1]];\n }\n\n if (shouldMaintainAspectRatio) {\n if ([\"s\", \"n\"].includes(transformHandle)) {\n newTopLeft[0] = startCenter[0] - newBoundsWidth / 2;\n }\n if ([\"e\", \"w\"].includes(transformHandle)) {\n newTopLeft[1] = startCenter[1] - newBoundsHeight / 2;\n }\n }\n\n // adjust topLeft to new rotation point\n const angle = stateAtCropStart.angle;\n const rotatedTopLeft = pointRotateRads(newTopLeft, startCenter, angle);\n const newCenter: Point = [\n newTopLeft[0] + Math.abs(newBoundsWidth) / 2,\n newTopLeft[1] + Math.abs(newBoundsHeight) / 2,\n ];\n const rotatedNewCenter = pointRotateRads(newCenter, startCenter, angle);\n newTopLeft = pointRotateRads(\n rotatedTopLeft,\n rotatedNewCenter,\n -angle as Radians,\n );\n\n const newOrigin = [...newTopLeft];\n newOrigin[0] += stateAtCropStart.x - newBoundsX1;\n newOrigin[1] += stateAtCropStart.y - newBoundsY1;\n\n return newOrigin;\n};\n\n// refer to https://link.excalidraw.com/l/6rfy1007QOo/6stx5PmRn0k\nexport const getUncroppedImageElement = (\n element: ExcalidrawImageElement,\n elementsMap: ElementsMap,\n) => {\n if (element.crop) {\n const { width, height } = getUncroppedWidthAndHeight(element);\n\n const [x1, y1, x2, y2, cx, cy] = getElementAbsoluteCoords(\n element,\n elementsMap,\n );\n\n const topLeftVector = vectorFromPoint(\n pointRotateRads(pointFrom(x1, y1), pointFrom(cx, cy), element.angle),\n );\n const topRightVector = vectorFromPoint(\n pointRotateRads(pointFrom(x2, y1), pointFrom(cx, cy), element.angle),\n );\n const topEdgeNormalized = vectorNormalize(\n vectorSubtract(topRightVector, topLeftVector),\n );\n const bottomLeftVector = vectorFromPoint(\n pointRotateRads(pointFrom(x1, y2), pointFrom(cx, cy), element.angle),\n );\n const leftEdgeVector = vectorSubtract(bottomLeftVector, topLeftVector);\n const leftEdgeNormalized = vectorNormalize(leftEdgeVector);\n\n const { cropX, cropY } = adjustCropPosition(element.crop, element.scale);\n\n const rotatedTopLeft = vectorAdd(\n vectorAdd(\n topLeftVector,\n vectorScale(\n topEdgeNormalized,\n (-cropX * width) / element.crop.naturalWidth,\n ),\n ),\n vectorScale(\n leftEdgeNormalized,\n (-cropY * height) / element.crop.naturalHeight,\n ),\n );\n\n const center = pointFromVector(\n vectorAdd(\n vectorAdd(rotatedTopLeft, vectorScale(topEdgeNormalized, width / 2)),\n vectorScale(leftEdgeNormalized, height / 2),\n ),\n );\n\n const unrotatedTopLeft = pointRotateRads(\n pointFromVector(rotatedTopLeft),\n center,\n -element.angle as Radians,\n );\n\n const uncroppedElement: ExcalidrawImageElement = {\n ...element,\n x: unrotatedTopLeft[0],\n y: unrotatedTopLeft[1],\n width,\n height,\n crop: null,\n };\n\n return uncroppedElement;\n }\n\n return element;\n};\n\nexport const getUncroppedWidthAndHeight = (element: ExcalidrawImageElement) => {\n if (element.crop) {\n const width =\n element.width / (element.crop.width / element.crop.naturalWidth);\n const height =\n element.height / (element.crop.height / element.crop.naturalHeight);\n\n return {\n width,\n height,\n };\n }\n\n return {\n width: element.width,\n height: element.height,\n };\n};\n\nconst adjustCropPosition = (\n crop: ImageCrop,\n scale: ExcalidrawImageElement[\"scale\"],\n) => {\n let cropX = crop.x;\n let cropY = crop.y;\n\n const flipX = scale[0] === -1;\n const flipY = scale[1] === -1;\n\n if (flipX) {\n cropX = crop.naturalWidth - Math.abs(cropX) - crop.width;\n }\n\n if (flipY) {\n cropY = crop.naturalHeight - Math.abs(cropY) - crop.height;\n }\n\n return {\n cropX,\n cropY,\n };\n};\n\nexport const getFlipAdjustedCropPosition = (\n element: ExcalidrawImageElement,\n natural = false,\n) => {\n const crop = element.crop;\n if (!crop) {\n return null;\n }\n\n const isFlippedByX = element.scale[0] === -1;\n const isFlippedByY = element.scale[1] === -1;\n\n let cropX = crop.x;\n let cropY = crop.y;\n\n if (isFlippedByX) {\n cropX = crop.naturalWidth - crop.width - crop.x;\n }\n\n if (isFlippedByY) {\n cropY = crop.naturalHeight - crop.height - crop.y;\n }\n\n if (natural) {\n return {\n x: cropX,\n y: cropY,\n };\n }\n\n const { width, height } = getUncroppedWidthAndHeight(element);\n\n return {\n x: cropX / (crop.naturalWidth / width),\n y: cropY / (crop.naturalHeight / height),\n };\n};\n", "import type { Point as RoughPoint } from \"roughjs/bin/geometry\";\nimport type { Drawable, Options } from \"roughjs/bin/core\";\nimport type { RoughGenerator } from \"roughjs/bin/generator\";\nimport { getDiamondPoints, getArrowheadPoints } from \"../element\";\nimport type { ElementShapes } from \"./types\";\nimport type {\n ExcalidrawElement,\n NonDeletedExcalidrawElement,\n ExcalidrawSelectionElement,\n ExcalidrawLinearElement,\n Arrowhead,\n} from \"../element/types\";\nimport { generateFreeDrawShape } from \"../renderer/renderElement\";\nimport { isTransparent, assertNever } from \"../utils\";\nimport { simplify } from \"points-on-curve\";\nimport { ROUGHNESS } from \"../constants\";\nimport {\n isElbowArrow,\n isEmbeddableElement,\n isIframeElement,\n isIframeLikeElement,\n isLinearElement,\n} from \"../element/typeChecks\";\nimport { canChangeRoundness } from \"./comparisons\";\nimport type { EmbedsValidationStatus } from \"../types\";\nimport { pointFrom, pointDistance, type LocalPoint } from \"@excalidraw/math\";\nimport { getCornerRadius, isPathALoop } from \"../shapes\";\nimport { headingForPointIsHorizontal } from \"../element/heading\";\n\nconst getDashArrayDashed = (strokeWidth: number) => [8, 8 + strokeWidth];\n\nconst getDashArrayDotted = (strokeWidth: number) => [1.5, 6 + strokeWidth];\n\nfunction adjustRoughness(element: ExcalidrawElement): number {\n const roughness = element.roughness;\n\n const maxSize = Math.max(element.width, element.height);\n const minSize = Math.min(element.width, element.height);\n\n // don't reduce roughness if\n if (\n // both sides relatively big\n (minSize >= 20 && maxSize >= 50) ||\n // is round & both sides above 15px\n (minSize >= 15 &&\n !!element.roundness &&\n canChangeRoundness(element.type)) ||\n // relatively long linear element\n (isLinearElement(element) && maxSize >= 50)\n ) {\n return roughness;\n }\n\n return Math.min(roughness / (maxSize < 10 ? 3 : 2), 2.5);\n}\n\nexport const generateRoughOptions = (\n element: ExcalidrawElement,\n continuousPath = false,\n): Options => {\n const options: Options = {\n seed: element.seed,\n strokeLineDash:\n element.strokeStyle === \"dashed\"\n ? getDashArrayDashed(element.strokeWidth)\n : element.strokeStyle === \"dotted\"\n ? getDashArrayDotted(element.strokeWidth)\n : undefined,\n // for non-solid strokes, disable multiStroke because it tends to make\n // dashes/dots overlay each other\n disableMultiStroke: element.strokeStyle !== \"solid\",\n // for non-solid strokes, increase the width a bit to make it visually\n // similar to solid strokes, because we're also disabling multiStroke\n strokeWidth:\n element.strokeStyle !== \"solid\"\n ? element.strokeWidth + 0.5\n : element.strokeWidth,\n // when increasing strokeWidth, we must explicitly set fillWeight and\n // hachureGap because if not specified, roughjs uses strokeWidth to\n // calculate them (and we don't want the fills to be modified)\n fillWeight: element.strokeWidth / 2,\n hachureGap: element.strokeWidth * 4,\n roughness: adjustRoughness(element),\n stroke: element.strokeColor,\n preserveVertices:\n continuousPath || element.roughness < ROUGHNESS.cartoonist,\n };\n\n switch (element.type) {\n case \"rectangle\":\n case \"iframe\":\n case \"embeddable\":\n case \"diamond\":\n case \"ellipse\": {\n options.fillStyle = element.fillStyle;\n options.fill = isTransparent(element.backgroundColor)\n ? undefined\n : element.backgroundColor;\n if (element.type === \"ellipse\") {\n options.curveFitting = 1;\n }\n return options;\n }\n case \"line\":\n case \"freedraw\": {\n if (isPathALoop(element.points)) {\n options.fillStyle = element.fillStyle;\n options.fill =\n element.backgroundColor === \"transparent\"\n ? undefined\n : element.backgroundColor;\n }\n return options;\n }\n case \"arrow\":\n return options;\n default: {\n throw new Error(`Unimplemented type ${element.type}`);\n }\n }\n};\n\nconst modifyIframeLikeForRoughOptions = (\n element: NonDeletedExcalidrawElement,\n isExporting: boolean,\n embedsValidationStatus: EmbedsValidationStatus | null,\n) => {\n if (\n isIframeLikeElement(element) &&\n (isExporting ||\n (isEmbeddableElement(element) &&\n embedsValidationStatus?.get(element.id) !== true)) &&\n isTransparent(element.backgroundColor) &&\n isTransparent(element.strokeColor)\n ) {\n return {\n ...element,\n roughness: 0,\n backgroundColor: \"#d3d3d3\",\n fillStyle: \"solid\",\n } as const;\n } else if (isIframeElement(element)) {\n return {\n ...element,\n strokeColor: isTransparent(element.strokeColor)\n ? \"#000000\"\n : element.strokeColor,\n backgroundColor: isTransparent(element.backgroundColor)\n ? \"#f4f4f6\"\n : element.backgroundColor,\n };\n }\n return element;\n};\n\nconst getArrowheadShapes = (\n element: ExcalidrawLinearElement,\n shape: Drawable[],\n position: \"start\" | \"end\",\n arrowhead: Arrowhead,\n generator: RoughGenerator,\n options: Options,\n canvasBackgroundColor: string | null,\n) => {\n canvasBackgroundColor = canvasBackgroundColor || \"transparent\";\n\n const arrowheadPoints = getArrowheadPoints(\n element,\n shape,\n position,\n arrowhead,\n );\n\n if (arrowheadPoints === null) {\n return [];\n }\n\n const generateCrowfootOne = (\n arrowheadPoints: number[] | null,\n options: Options,\n ) => {\n if (arrowheadPoints === null) {\n return [];\n }\n\n const [, , x3, y3, x4, y4] = arrowheadPoints;\n\n return [generator.line(x3, y3, x4, y4, options)];\n };\n\n switch (arrowhead) {\n case \"dot\":\n case \"circle\":\n case \"circle_outline\": {\n const [x, y, diameter] = arrowheadPoints;\n\n // always use solid stroke for arrowhead\n delete options.strokeLineDash;\n\n return [\n generator.circle(x, y, diameter, {\n ...options,\n fill:\n arrowhead === \"circle_outline\"\n ? canvasBackgroundColor\n : element.strokeColor,\n\n fillStyle: \"solid\",\n stroke: element.strokeColor,\n roughness: Math.min(0.5, options.roughness || 0),\n }),\n ];\n }\n case \"triangle\":\n case \"triangle_outline\": {\n const [x, y, x2, y2, x3, y3] = arrowheadPoints;\n\n // always use solid stroke for arrowhead\n delete options.strokeLineDash;\n\n return [\n generator.polygon(\n [\n [x, y],\n [x2, y2],\n [x3, y3],\n [x, y],\n ],\n {\n ...options,\n fill:\n arrowhead === \"triangle_outline\"\n ? canvasBackgroundColor\n : element.strokeColor,\n fillStyle: \"solid\",\n roughness: Math.min(1, options.roughness || 0),\n },\n ),\n ];\n }\n case \"diamond\":\n case \"diamond_outline\": {\n const [x, y, x2, y2, x3, y3, x4, y4] = arrowheadPoints;\n\n // always use solid stroke for arrowhead\n delete options.strokeLineDash;\n\n return [\n generator.polygon(\n [\n [x, y],\n [x2, y2],\n [x3, y3],\n [x4, y4],\n [x, y],\n ],\n {\n ...options,\n fill:\n arrowhead === \"diamond_outline\"\n ? canvasBackgroundColor\n : element.strokeColor,\n fillStyle: \"solid\",\n roughness: Math.min(1, options.roughness || 0),\n },\n ),\n ];\n }\n case \"crowfoot_one\":\n return generateCrowfootOne(arrowheadPoints, options);\n case \"bar\":\n case \"arrow\":\n case \"crowfoot_many\":\n case \"crowfoot_one_or_many\":\n default: {\n const [x2, y2, x3, y3, x4, y4] = arrowheadPoints;\n\n if (element.strokeStyle === \"dotted\") {\n // for dotted arrows caps, reduce gap to make it more legible\n const dash = getDashArrayDotted(element.strokeWidth - 1);\n options.strokeLineDash = [dash[0], dash[1] - 1];\n } else {\n // for solid/dashed, keep solid arrow cap\n delete options.strokeLineDash;\n }\n options.roughness = Math.min(1, options.roughness || 0);\n return [\n generator.line(x3, y3, x2, y2, options),\n generator.line(x4, y4, x2, y2, options),\n ...(arrowhead === \"crowfoot_one_or_many\"\n ? generateCrowfootOne(\n getArrowheadPoints(element, shape, position, \"crowfoot_one\"),\n options,\n )\n : []),\n ];\n }\n }\n};\n\n/**\n * Generates the roughjs shape for given element.\n *\n * Low-level. Use `ShapeCache.generateElementShape` instead.\n *\n * @private\n */\nexport const _generateElementShape = (\n element: Exclude<NonDeletedExcalidrawElement, ExcalidrawSelectionElement>,\n generator: RoughGenerator,\n {\n isExporting,\n canvasBackgroundColor,\n embedsValidationStatus,\n }: {\n isExporting: boolean;\n canvasBackgroundColor: string | null;\n embedsValidationStatus: EmbedsValidationStatus | null;\n },\n): Drawable | Drawable[] | null => {\n switch (element.type) {\n case \"rectangle\":\n case \"iframe\":\n case \"embeddable\": {\n let shape: ElementShapes[typeof element.type];\n // this is for rendering the stroke/bg of the embeddable, especially\n // when the src url is not set\n\n if (element.roundness) {\n const w = element.width;\n const h = element.height;\n const r = getCornerRadius(Math.min(w, h), element);\n shape = generator.path(\n `M ${r} 0 L ${w - r} 0 Q ${w} 0, ${w} ${r} L ${w} ${\n h - r\n } Q ${w} ${h}, ${w - r} ${h} L ${r} ${h} Q 0 ${h}, 0 ${\n h - r\n } L 0 ${r} Q 0 0, ${r} 0`,\n generateRoughOptions(\n modifyIframeLikeForRoughOptions(\n element,\n isExporting,\n embedsValidationStatus,\n ),\n true,\n ),\n );\n } else {\n shape = generator.rectangle(\n 0,\n 0,\n element.width,\n element.height,\n generateRoughOptions(\n modifyIframeLikeForRoughOptions(\n element,\n isExporting,\n embedsValidationStatus,\n ),\n false,\n ),\n );\n }\n return shape;\n }\n case \"diamond\": {\n let shape: ElementShapes[typeof element.type];\n\n const [topX, topY, rightX, rightY, bottomX, bottomY, leftX, leftY] =\n getDiamondPoints(element);\n if (element.roundness) {\n const verticalRadius = getCornerRadius(Math.abs(topX - leftX), element);\n\n const horizontalRadius = getCornerRadius(\n Math.abs(rightY - topY),\n element,\n );\n\n shape = generator.path(\n `M ${topX + verticalRadius} ${topY + horizontalRadius} L ${\n rightX - verticalRadius\n } ${rightY - horizontalRadius}\n C ${rightX} ${rightY}, ${rightX} ${rightY}, ${\n rightX - verticalRadius\n } ${rightY + horizontalRadius}\n L ${bottomX + verticalRadius} ${bottomY - horizontalRadius}\n C ${bottomX} ${bottomY}, ${bottomX} ${bottomY}, ${\n bottomX - verticalRadius\n } ${bottomY - horizontalRadius}\n L ${leftX + verticalRadius} ${leftY + horizontalRadius}\n C ${leftX} ${leftY}, ${leftX} ${leftY}, ${leftX + verticalRadius} ${\n leftY - horizontalRadius\n }\n L ${topX - verticalRadius} ${topY + horizontalRadius}\n C ${topX} ${topY}, ${topX} ${topY}, ${topX + verticalRadius} ${\n topY + horizontalRadius\n }`,\n generateRoughOptions(element, true),\n );\n } else {\n shape = generator.polygon(\n [\n [topX, topY],\n [rightX, rightY],\n [bottomX, bottomY],\n [leftX, leftY],\n ],\n generateRoughOptions(element),\n );\n }\n return shape;\n }\n case \"ellipse\": {\n const shape: ElementShapes[typeof element.type] = generator.ellipse(\n element.width / 2,\n element.height / 2,\n element.width,\n element.height,\n generateRoughOptions(element),\n );\n return shape;\n }\n case \"line\":\n case \"arrow\": {\n let shape: ElementShapes[typeof element.type];\n const options = generateRoughOptions(element);\n\n // points array can be empty in the beginning, so it is important to add\n // initial position to it\n const points = element.points.length\n ? element.points\n : [pointFrom<LocalPoint>(0, 0)];\n\n if (isElbowArrow(element)) {\n shape = [\n generator.path(\n generateElbowArrowShape(points, 16),\n generateRoughOptions(element, true),\n ),\n ];\n } else if (!element.roundness) {\n // curve is always the first element\n // this simplifies finding the curve for an element\n if (options.fill) {\n shape = [\n generator.polygon(points as unknown as RoughPoint[], options),\n ];\n } else {\n shape = [\n generator.linearPath(points as unknown as RoughPoint[], options),\n ];\n }\n } else {\n shape = [generator.curve(points as unknown as RoughPoint[], options)];\n }\n\n // add lines only in arrow\n if (element.type === \"arrow\") {\n const { startArrowhead = null, endArrowhead = \"arrow\" } = element;\n\n if (startArrowhead !== null) {\n const shapes = getArrowheadShapes(\n element,\n shape,\n \"start\",\n startArrowhead,\n generator,\n options,\n canvasBackgroundColor,\n );\n shape.push(...shapes);\n }\n\n if (endArrowhead !== null) {\n if (endArrowhead === undefined) {\n // Hey, we have an old arrow here!\n }\n\n const shapes = getArrowheadShapes(\n element,\n shape,\n \"end\",\n endArrowhead,\n generator,\n options,\n canvasBackgroundColor,\n );\n shape.push(...shapes);\n }\n }\n return shape;\n }\n case \"freedraw\": {\n let shape: ElementShapes[typeof element.type];\n generateFreeDrawShape(element);\n\n if (isPathALoop(element.points)) {\n // generate rough polygon to fill freedraw shape\n const simplifiedPoints = simplify(element.points, 0.75);\n shape = generator.curve(simplifiedPoints as [number, number][], {\n ...generateRoughOptions(element),\n stroke: \"none\",\n });\n } else {\n shape = null;\n }\n return shape;\n }\n case \"frame\":\n case \"magicframe\":\n case \"text\":\n case \"image\": {\n const shape: ElementShapes[typeof element.type] = null;\n // we return (and cache) `null` to make sure we don't regenerate\n // `element.canvas` on rerenders\n return shape;\n }\n default: {\n assertNever(\n element,\n `generateElementShape(): Unimplemented type ${(element as any)?.type}`,\n );\n return null;\n }\n }\n};\n\nconst generateElbowArrowShape = (\n points: readonly LocalPoint[],\n radius: number,\n) => {\n const subpoints = [] as [number, number][];\n for (let i = 1; i < points.length - 1; i += 1) {\n const prev = points[i - 1];\n const next = points[i + 1];\n const point = points[i];\n const prevIsHorizontal = headingForPointIsHorizontal(point, prev);\n const nextIsHorizontal = headingForPointIsHorizontal(next, point);\n const corner = Math.min(\n radius,\n pointDistance(points[i], next) / 2,\n pointDistance(points[i], prev) / 2,\n );\n\n if (prevIsHorizontal) {\n if (prev[0] < point[0]) {\n // LEFT\n subpoints.push([points[i][0] - corner, points[i][1]]);\n } else {\n // RIGHT\n subpoints.push([points[i][0] + corner, points[i][1]]);\n }\n } else if (prev[1] < point[1]) {\n // UP\n subpoints.push([points[i][0], points[i][1] - corner]);\n } else {\n subpoints.push([points[i][0], points[i][1] + corner]);\n }\n\n subpoints.push(points[i] as [number, number]);\n\n if (nextIsHorizontal) {\n if (next[0] < point[0]) {\n // LEFT\n subpoints.push([points[i][0] - corner, points[i][1]]);\n } else {\n // RIGHT\n subpoints.push([points[i][0] + corner, points[i][1]]);\n }\n } else if (next[1] < point[1]) {\n // UP\n subpoints.push([points[i][0], points[i][1] - corner]);\n } else {\n // DOWN\n subpoints.push([points[i][0], points[i][1] + corner]);\n }\n }\n\n const d = [`M ${points[0][0]} ${points[0][1]}`];\n for (let i = 0; i < subpoints.length; i += 3) {\n d.push(`L ${subpoints[i][0]} ${subpoints[i][1]}`);\n d.push(\n `Q ${subpoints[i + 1][0]} ${subpoints[i + 1][1]}, ${\n subpoints[i + 2][0]\n } ${subpoints[i + 2][1]}`,\n );\n }\n d.push(`L ${points[points.length - 1][0]} ${points[points.length - 1][1]}`);\n\n return d.join(\" \");\n};\n", "import type { ElementOrToolType } from \"../types\";\n\nexport const hasBackground = (type: ElementOrToolType) =>\n type === \"rectangle\" ||\n type === \"iframe\" ||\n type === \"embeddable\" ||\n type === \"ellipse\" ||\n type === \"diamond\" ||\n type === \"line\" ||\n type === \"freedraw\";\n\nexport const hasStrokeColor = (type: ElementOrToolType) =>\n type !== \"image\" && type !== \"frame\" && type !== \"magicframe\";\n\nexport const hasStrokeWidth = (type: ElementOrToolType) =>\n type === \"rectangle\" ||\n type === \"iframe\" ||\n type === \"embeddable\" ||\n type === \"ellipse\" ||\n type === \"diamond\" ||\n type === \"freedraw\" ||\n type === \"arrow\" ||\n type === \"line\";\n\nexport const hasStrokeStyle = (type: ElementOrToolType) =>\n type === \"rectangle\" ||\n type === \"iframe\" ||\n type === \"embeddable\" ||\n type === \"ellipse\" ||\n type === \"diamond\" ||\n type === \"arrow\" ||\n type === \"line\";\n\nexport const canChangeRoundness = (type: ElementOrToolType) =>\n type === \"rectangle\" ||\n type === \"iframe\" ||\n type === \"embeddable\" ||\n type === \"line\" ||\n type === \"diamond\" ||\n type === \"image\";\n\nexport const toolIsArrow = (type: ElementOrToolType) => type === \"arrow\";\n\nexport const canHaveArrowheads = (type: ElementOrToolType) => type === \"arrow\";\n", "import type {\n LocalPoint,\n GlobalPoint,\n Triangle,\n Vector,\n Radians,\n} from \"@excalidraw/math\";\nimport {\n pointFrom,\n pointRotateRads,\n pointScaleFromOrigin,\n radiansToDegrees,\n triangleIncludesPoint,\n vectorFromPoint,\n} from \"@excalidraw/math\";\nimport { getCenterForBounds, type Bounds } from \"./bounds\";\nimport type { ExcalidrawBindableElement } from \"./types\";\n\nexport const HEADING_RIGHT = [1, 0] as Heading;\nexport const HEADING_DOWN = [0, 1] as Heading;\nexport const HEADING_LEFT = [-1, 0] as Heading;\nexport const HEADING_UP = [0, -1] as Heading;\nexport type Heading = [1, 0] | [0, 1] | [-1, 0] | [0, -1];\n\nexport const headingForDiamond = <Point extends GlobalPoint | LocalPoint>(\n a: Point,\n b: Point,\n) => {\n const angle = radiansToDegrees(\n Math.atan2(b[1] - a[1], b[0] - a[0]) as Radians,\n );\n if (angle >= 315 || angle < 45) {\n return HEADING_UP;\n } else if (angle >= 45 && angle < 135) {\n return HEADING_RIGHT;\n } else if (angle >= 135 && angle < 225) {\n return HEADING_DOWN;\n }\n return HEADING_LEFT;\n};\n\nexport const vectorToHeading = (vec: Vector): Heading => {\n const [x, y] = vec;\n const absX = Math.abs(x);\n const absY = Math.abs(y);\n if (x > absY) {\n return HEADING_RIGHT;\n } else if (x <= -absY) {\n return HEADING_LEFT;\n } else if (y > absX) {\n return HEADING_DOWN;\n }\n return HEADING_UP;\n};\n\nexport const headingForPoint = <P extends GlobalPoint | LocalPoint>(\n p: P,\n o: P,\n) => vectorToHeading(vectorFromPoint<P>(p, o));\n\nexport const headingForPointIsHorizontal = <P extends GlobalPoint | LocalPoint>(\n p: P,\n o: P,\n) => headingIsHorizontal(headingForPoint<P>(p, o));\n\nexport const compareHeading = (a: Heading, b: Heading) =>\n a[0] === b[0] && a[1] === b[1];\n\nexport const headingIsHorizontal = (a: Heading) =>\n compareHeading(a, HEADING_RIGHT) || compareHeading(a, HEADING_LEFT);\n\nexport const headingIsVertical = (a: Heading) => !headingIsHorizontal(a);\n\n// Gets the heading for the point by creating a bounding box around the rotated\n// close fitting bounding box, then creating 4 search cones around the center of\n// the external bbox.\nexport const headingForPointFromElement = <\n Point extends GlobalPoint | LocalPoint,\n>(\n element: Readonly<ExcalidrawBindableElement>,\n aabb: Readonly<Bounds>,\n p: Readonly<Point>,\n): Heading => {\n const SEARCH_CONE_MULTIPLIER = 2;\n\n const midPoint = getCenterForBounds(aabb);\n\n if (element.type === \"diamond\") {\n if (p[0] < element.x) {\n return HEADING_LEFT;\n } else if (p[1] < element.y) {\n return HEADING_UP;\n } else if (p[0] > element.x + element.width) {\n return HEADING_RIGHT;\n } else if (p[1] > element.y + element.height) {\n return HEADING_DOWN;\n }\n\n const top = pointRotateRads(\n pointScaleFromOrigin(\n pointFrom(element.x + element.width / 2, element.y),\n midPoint,\n SEARCH_CONE_MULTIPLIER,\n ),\n midPoint,\n element.angle,\n );\n const right = pointRotateRads(\n pointScaleFromOrigin(\n pointFrom(element.x + element.width, element.y + element.height / 2),\n midPoint,\n SEARCH_CONE_MULTIPLIER,\n ),\n midPoint,\n element.angle,\n );\n const bottom = pointRotateRads(\n pointScaleFromOrigin(\n pointFrom(element.x + element.width / 2, element.y + element.height),\n midPoint,\n SEARCH_CONE_MULTIPLIER,\n ),\n midPoint,\n element.angle,\n );\n const left = pointRotateRads(\n pointScaleFromOrigin(\n pointFrom(element.x, element.y + element.height / 2),\n midPoint,\n SEARCH_CONE_MULTIPLIER,\n ),\n midPoint,\n element.angle,\n );\n\n if (\n triangleIncludesPoint<Point>([top, right, midPoint] as Triangle<Point>, p)\n ) {\n return headingForDiamond(top, right);\n } else if (\n triangleIncludesPoint<Point>(\n [right, bottom, midPoint] as Triangle<Point>,\n p,\n )\n ) {\n return headingForDiamond(right, bottom);\n } else if (\n triangleIncludesPoint<Point>(\n [bottom, left, midPoint] as Triangle<Point>,\n p,\n )\n ) {\n return headingForDiamond(bottom, left);\n }\n\n return headingForDiamond(left, top);\n }\n\n const topLeft = pointScaleFromOrigin(\n pointFrom(aabb[0], aabb[1]),\n midPoint,\n SEARCH_CONE_MULTIPLIER,\n ) as Point;\n const topRight = pointScaleFromOrigin(\n pointFrom(aabb[2], aabb[1]),\n midPoint,\n SEARCH_CONE_MULTIPLIER,\n ) as Point;\n const bottomLeft = pointScaleFromOrigin(\n pointFrom(aabb[0], aabb[3]),\n midPoint,\n SEARCH_CONE_MULTIPLIER,\n ) as Point;\n const bottomRight = pointScaleFromOrigin(\n pointFrom(aabb[2], aabb[3]),\n midPoint,\n SEARCH_CONE_MULTIPLIER,\n ) as Point;\n\n return triangleIncludesPoint<Point>(\n [topLeft, topRight, midPoint] as Triangle<Point>,\n p,\n )\n ? HEADING_UP\n : triangleIncludesPoint<Point>(\n [topRight, bottomRight, midPoint] as Triangle<Point>,\n p,\n )\n ? HEADING_RIGHT\n : triangleIncludesPoint<Point>(\n [bottomRight, bottomLeft, midPoint] as Triangle<Point>,\n p,\n )\n ? HEADING_DOWN\n : HEADING_LEFT;\n};\n\nexport const flipHeading = (h: Heading): Heading =>\n [\n h[0] === 0 ? 0 : h[0] > 0 ? -1 : 1,\n h[1] === 0 ? 0 : h[1] > 0 ? -1 : 1,\n ] as Heading;\n", "import {\n pointFromPair,\n type GlobalPoint,\n type LocalPoint,\n} from \"@excalidraw/math\";\n\nexport const getSizeFromPoints = (\n points: readonly (GlobalPoint | LocalPoint)[],\n) => {\n const xs = points.map((point) => point[0]);\n const ys = points.map((point) => point[1]);\n return {\n width: Math.max(...xs) - Math.min(...xs),\n height: Math.max(...ys) - Math.min(...ys),\n };\n};\n\n/** @arg dimension, 0 for rescaling only x, 1 for y */\nexport const rescalePoints = <Point extends GlobalPoint | LocalPoint>(\n dimension: 0 | 1,\n newSize: number,\n points: readonly Point[],\n normalize: boolean,\n): Point[] => {\n const coordinates = points.map((point) => point[dimension]);\n const maxCoordinate = Math.max(...coordinates);\n const minCoordinate = Math.min(...coordinates);\n const size = maxCoordinate - minCoordinate;\n const scale = size === 0 ? 1 : newSize / size;\n\n let nextMinCoordinate = Infinity;\n\n const scaledPoints = points.map((point): Point => {\n const newCoordinate = point[dimension] * scale;\n const newPoint = [...point];\n newPoint[dimension] = newCoordinate;\n if (newCoordinate < nextMinCoordinate) {\n nextMinCoordinate = newCoordinate;\n }\n return newPoint as Point;\n });\n\n if (!normalize) {\n return scaledPoints;\n }\n\n if (scaledPoints.length === 2) {\n // we don't translate two-point lines\n return scaledPoints;\n }\n\n const translation = minCoordinate - nextMinCoordinate;\n\n const nextPoints = scaledPoints.map((scaledPoint) =>\n pointFromPair<Point>(\n scaledPoint.map((value, currentDimension) => {\n return currentDimension === dimension ? value + translation : value;\n }) as [number, number],\n ),\n );\n\n return nextPoints;\n};\n", "import type { GlobalPoint, Radians } from \"@excalidraw/math\";\nimport {\n curvePointDistance,\n distanceToLineSegment,\n pointFrom,\n pointRotateRads,\n} from \"@excalidraw/math\";\nimport { ellipse, ellipseDistanceFromPoint } from \"@excalidraw/math/ellipse\";\nimport type {\n ExcalidrawBindableElement,\n ExcalidrawDiamondElement,\n ExcalidrawEllipseElement,\n ExcalidrawRectanguloidElement,\n} from \"./types\";\nimport {\n deconstructDiamondElement,\n deconstructRectanguloidElement,\n} from \"./utils\";\n\nexport const distanceToBindableElement = (\n element: ExcalidrawBindableElement,\n p: GlobalPoint,\n): number => {\n switch (element.type) {\n case \"rectangle\":\n case \"image\":\n case \"text\":\n case \"iframe\":\n case \"embeddable\":\n case \"frame\":\n case \"magicframe\":\n return distanceToRectanguloidElement(element, p);\n case \"diamond\":\n return distanceToDiamondElement(element, p);\n case \"ellipse\":\n return distanceToEllipseElement(element, p);\n }\n};\n\n/**\n * Returns the distance of a point and the provided rectangular-shaped element,\n * accounting for roundness and rotation\n *\n * @param element The rectanguloid element\n * @param p The point to consider\n * @returns The eucledian distance to the outline of the rectanguloid element\n */\nconst distanceToRectanguloidElement = (\n element: ExcalidrawRectanguloidElement,\n p: GlobalPoint,\n) => {\n const center = pointFrom<GlobalPoint>(\n element.x + element.width / 2,\n element.y + element.height / 2,\n );\n // To emulate a rotated rectangle we rotate the point in the inverse angle\n // instead. It's all the same distance-wise.\n const rotatedPoint = pointRotateRads(p, center, -element.angle as Radians);\n\n // Get the element's building components we can test against\n const [sides, corners] = deconstructRectanguloidElement(element);\n\n return Math.min(\n ...sides.map((s) => distanceToLineSegment(rotatedPoint, s)),\n ...corners\n .map((a) => curvePointDistance(a, rotatedPoint))\n .filter((d): d is number => d !== null),\n );\n};\n\n/**\n * Returns the distance of a point and the provided diamond element, accounting\n * for roundness and rotation\n *\n * @param element The diamond element\n * @param p The point to consider\n * @returns The eucledian distance to the outline of the diamond\n */\nconst distanceToDiamondElement = (\n element: ExcalidrawDiamondElement,\n p: GlobalPoint,\n): number => {\n const center = pointFrom<GlobalPoint>(\n element.x + element.width / 2,\n element.y + element.height / 2,\n );\n\n // Rotate the point to the inverse direction to simulate the rotated diamond\n // points. It's all the same distance-wise.\n const rotatedPoint = pointRotateRads(p, center, -element.angle as Radians);\n\n const [sides, curves] = deconstructDiamondElement(element);\n\n return Math.min(\n ...sides.map((s) => distanceToLineSegment(rotatedPoint, s)),\n ...curves\n .map((a) => curvePointDistance(a, rotatedPoint))\n .filter((d): d is number => d !== null),\n );\n};\n\n/**\n * Returns the distance of a point and the provided ellipse element, accounting\n * for roundness and rotation\n *\n * @param element The ellipse element\n * @param p The point to consider\n * @returns The eucledian distance to the outline of the ellipse\n */\nconst distanceToEllipseElement = (\n element: ExcalidrawEllipseElement,\n p: GlobalPoint,\n): number => {\n const center = pointFrom(\n element.x + element.width / 2,\n element.y + element.height / 2,\n );\n return ellipseDistanceFromPoint(\n // Instead of rotating the ellipse, rotate the point to the inverse angle\n pointRotateRads(p, center, -element.angle as Radians),\n ellipse(center, element.width / 2, element.height / 2),\n );\n};\n", "import type {\n ExcalidrawBindableElement,\n ExcalidrawElement,\n NonDeleted,\n ExcalidrawLinearElement,\n PointBinding,\n NonDeletedExcalidrawElement,\n ElementsMap,\n NonDeletedSceneElementsMap,\n ExcalidrawTextElement,\n ExcalidrawArrowElement,\n OrderedExcalidrawElement,\n ExcalidrawElbowArrowElement,\n FixedPoint,\n SceneElementsMap,\n FixedPointBinding,\n} from \"./types\";\n\nimport type { Bounds } from \"./bounds\";\nimport { getCenterForBounds } from \"./bounds\";\nimport type { AppState } from \"../types\";\nimport { isPointOnShape } from \"@excalidraw/utils/collision\";\nimport {\n isArrowElement,\n isBindableElement,\n isBindingElement,\n isBoundToContainer,\n isElbowArrow,\n isFixedPointBinding,\n isFrameLikeElement,\n isLinearElement,\n isRectanguloidElement,\n isTextElement,\n} from \"./typeChecks\";\nimport type { ElementUpdate } from \"./mutateElement\";\nimport { mutateElement } from \"./mutateElement\";\nimport type Scene from \"../scene/Scene\";\nimport { LinearElementEditor } from \"./linearElementEditor\";\nimport {\n arrayToMap,\n isBindingFallthroughEnabled,\n tupleToCoors,\n} from \"../utils\";\nimport { KEYS } from \"../keys\";\nimport { getBoundTextElement, handleBindTextResize } from \"./textElement\";\nimport { aabbForElement, getElementShape, pointInsideBounds } from \"../shapes\";\nimport {\n compareHeading,\n HEADING_DOWN,\n HEADING_RIGHT,\n HEADING_UP,\n headingForPointFromElement,\n vectorToHeading,\n type Heading,\n} from \"./heading\";\nimport type { LocalPoint, Radians } from \"@excalidraw/math\";\nimport {\n lineSegment,\n pointFrom,\n pointRotateRads,\n type GlobalPoint,\n vectorFromPoint,\n pointDistanceSq,\n clamp,\n pointDistance,\n pointFromVector,\n vectorScale,\n vectorNormalize,\n vectorCross,\n pointsEqual,\n lineSegmentIntersectionPoints,\n} from \"@excalidraw/math\";\nimport { intersectElementWithLineSegment } from \"./collision\";\nimport { distanceToBindableElement } from \"./distance\";\n\nexport type SuggestedBinding =\n | NonDeleted<ExcalidrawBindableElement>\n | SuggestedPointBinding;\n\nexport type SuggestedPointBinding = [\n NonDeleted<ExcalidrawLinearElement>,\n \"start\" | \"end\" | \"both\",\n NonDeleted<ExcalidrawBindableElement>,\n];\n\nexport const shouldEnableBindingForPointerEvent = (\n event: React.PointerEvent<HTMLElement>,\n) => {\n return !event[KEYS.CTRL_OR_CMD];\n};\n\nexport const isBindingEnabled = (appState: AppState): boolean => {\n return appState.isBindingEnabled;\n};\n\nexport const FIXED_BINDING_DISTANCE = 5;\nexport const BINDING_HIGHLIGHT_THICKNESS = 10;\nexport const BINDING_HIGHLIGHT_OFFSET = 4;\n\nconst getNonDeletedElements = (\n scene: Scene,\n ids: readonly ExcalidrawElement[\"id\"][],\n): NonDeleted<ExcalidrawElement>[] => {\n const result: NonDeleted<ExcalidrawElement>[] = [];\n ids.forEach((id) => {\n const element = scene.getNonDeletedElement(id);\n if (element != null) {\n result.push(element);\n }\n });\n return result;\n};\n\nexport const bindOrUnbindLinearElement = (\n linearElement: NonDeleted<ExcalidrawLinearElement>,\n startBindingElement: ExcalidrawBindableElement | null | \"keep\",\n endBindingElement: ExcalidrawBindableElement | null | \"keep\",\n elementsMap: NonDeletedSceneElementsMap,\n scene: Scene,\n): void => {\n const boundToElementIds: Set<ExcalidrawBindableElement[\"id\"]> = new Set();\n const unboundFromElementIds: Set<ExcalidrawBindableElement[\"id\"]> = new Set();\n bindOrUnbindLinearElementEdge(\n linearElement,\n startBindingElement,\n endBindingElement,\n \"start\",\n boundToElementIds,\n unboundFromElementIds,\n elementsMap,\n );\n bindOrUnbindLinearElementEdge(\n linearElement,\n endBindingElement,\n startBindingElement,\n \"end\",\n boundToElementIds,\n unboundFromElementIds,\n elementsMap,\n );\n\n const onlyUnbound = Array.from(unboundFromElementIds).filter(\n (id) => !boundToElementIds.has(id),\n );\n\n getNonDeletedElements(scene, onlyUnbound).forEach((element) => {\n mutateElement(element, {\n boundElements: element.boundElements?.filter(\n (element) =>\n element.type !== \"arrow\" || element.id !== linearElement.id,\n ),\n });\n });\n};\n\nconst bindOrUnbindLinearElementEdge = (\n linearElement: NonDeleted<ExcalidrawLinearElement>,\n bindableElement: ExcalidrawBindableElement | null | \"keep\",\n otherEdgeBindableElement: ExcalidrawBindableElement | null | \"keep\",\n startOrEnd: \"start\" | \"end\",\n // Is mutated\n boundToElementIds: Set<ExcalidrawBindableElement[\"id\"]>,\n // Is mutated\n unboundFromElementIds: Set<ExcalidrawBindableElement[\"id\"]>,\n elementsMap: NonDeletedSceneElementsMap,\n): void => {\n // \"keep\" is for method chaining convenience, a \"no-op\", so just bail out\n if (bindableElement === \"keep\") {\n return;\n }\n\n // null means break the bind, so nothing to consider here\n if (bindableElement === null) {\n const unbound = unbindLinearElement(linearElement, startOrEnd);\n if (unbound != null) {\n unboundFromElementIds.add(unbound);\n }\n return;\n }\n\n // While complext arrows can do anything, simple arrow with both ends trying\n // to bind to the same bindable should not be allowed, start binding takes\n // precedence\n if (isLinearElementSimple(linearElement)) {\n if (\n otherEdgeBindableElement == null ||\n (otherEdgeBindableElement === \"keep\"\n ? // TODO: Refactor - Needlessly complex\n !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(\n linearElement,\n bindableElement,\n startOrEnd,\n )\n : startOrEnd === \"start\" ||\n otherEdgeBindableElement.id !== bindableElement.id)\n ) {\n bindLinearElement(\n linearElement,\n bindableElement,\n startOrEnd,\n elementsMap,\n );\n boundToElementIds.add(bindableElement.id);\n }\n } else {\n bindLinearElement(linearElement, bindableElement, startOrEnd, elementsMap);\n boundToElementIds.add(bindableElement.id);\n }\n};\n\nconst getOriginalBindingIfStillCloseOfLinearElementEdge = (\n linearElement: NonDeleted<ExcalidrawLinearElement>,\n edge: \"start\" | \"end\",\n elementsMap: NonDeletedSceneElementsMap,\n zoom?: AppState[\"zoom\"],\n): NonDeleted<ExcalidrawElement> | null => {\n const coors = getLinearElementEdgeCoors(linearElement, edge, elementsMap);\n const elementId =\n edge === \"start\"\n ? linearElement.startBinding?.elementId\n : linearElement.endBinding?.elementId;\n if (elementId) {\n const element = elementsMap.get(elementId);\n if (\n isBindableElement(element) &&\n bindingBorderTest(element, coors, elementsMap, zoom)\n ) {\n return element;\n }\n }\n\n return null;\n};\n\nconst getOriginalBindingsIfStillCloseToArrowEnds = (\n linearElement: NonDeleted<ExcalidrawLinearElement>,\n elementsMap: NonDeletedSceneElementsMap,\n zoom?: AppState[\"zoom\"],\n): (NonDeleted<ExcalidrawElement> | null)[] =>\n [\"start\", \"end\"].map((edge) =>\n getOriginalBindingIfStillCloseOfLinearElementEdge(\n linearElement,\n edge as \"start\" | \"end\",\n elementsMap,\n zoom,\n ),\n );\n\nconst getBindingStrategyForDraggingArrowEndpoints = (\n selectedElement: NonDeleted<ExcalidrawLinearElement>,\n isBindingEnabled: boolean,\n draggingPoints: readonly number[],\n elementsMap: NonDeletedSceneElementsMap,\n elements: readonly NonDeletedExcalidrawElement[],\n zoom?: AppState[\"zoom\"],\n): (NonDeleted<ExcalidrawBindableElement> | null | \"keep\")[] => {\n const startIdx = 0;\n const endIdx = selectedElement.points.length - 1;\n const startDragged = draggingPoints.findIndex((i) => i === startIdx) > -1;\n const endDragged = draggingPoints.findIndex((i) => i === endIdx) > -1;\n const start = startDragged\n ? isBindingEnabled\n ? getElligibleElementForBindingElement(\n selectedElement,\n \"start\",\n elementsMap,\n elements,\n zoom,\n )\n : null // If binding is disabled and start is dragged, break all binds\n : // We have to update the focus and gap of the binding, so let's rebind\n getElligibleElementForBindingElement(\n selectedElement,\n \"start\",\n elementsMap,\n elements,\n zoom,\n );\n const end = endDragged\n ? isBindingEnabled\n ? getElligibleElementForBindingElement(\n selectedElement,\n \"end\",\n elementsMap,\n elements,\n zoom,\n )\n : null // If binding is disabled and end is dragged, break all binds\n : // We have to update the focus and gap of the binding, so let's rebind\n getElligibleElementForBindingElement(\n selectedElement,\n \"end\",\n elementsMap,\n elements,\n zoom,\n );\n\n return [start, end];\n};\n\nconst getBindingStrategyForDraggingArrowOrJoints = (\n selectedElement: NonDeleted<ExcalidrawLinearElement>,\n elementsMap: NonDeletedSceneElementsMap,\n elements: readonly NonDeletedExcalidrawElement[],\n isBindingEnabled: boolean,\n zoom?: AppState[\"zoom\"],\n): (NonDeleted<ExcalidrawBindableElement> | null | \"keep\")[] => {\n const [startIsClose, endIsClose] = getOriginalBindingsIfStillCloseToArrowEnds(\n selectedElement,\n elementsMap,\n zoom,\n );\n const start = startIsClose\n ? isBindingEnabled\n ? getElligibleElementForBindingElement(\n selectedElement,\n \"start\",\n elementsMap,\n elements,\n zoom,\n )\n : null\n : null;\n const end = endIsClose\n ? isBindingEnabled\n ? getElligibleElementForBindingElement(\n selectedElement,\n \"end\",\n elementsMap,\n elements,\n zoom,\n )\n : null\n : null;\n\n return [start, end];\n};\n\nexport const bindOrUnbindLinearElements = (\n selectedElements: NonDeleted<ExcalidrawLinearElement>[],\n elementsMap: NonDeletedSceneElementsMap,\n elements: readonly NonDeletedExcalidrawElement[],\n scene: Scene,\n isBindingEnabled: boolean,\n draggingPoints: readonly number[] | null,\n zoom?: AppState[\"zoom\"],\n): void => {\n selectedElements.forEach((selectedElement) => {\n const [start, end] = draggingPoints?.length\n ? // The arrow edge points are dragged (i.e. start, end)\n getBindingStrategyForDraggingArrowEndpoints(\n selectedElement,\n isBindingEnabled,\n draggingPoints ?? [],\n elementsMap,\n elements,\n zoom,\n )\n : // The arrow itself (the shaft) or the inner joins are dragged\n getBindingStrategyForDraggingArrowOrJoints(\n selectedElement,\n elementsMap,\n elements,\n isBindingEnabled,\n zoom,\n );\n\n bindOrUnbindLinearElement(selectedElement, start, end, elementsMap, scene);\n });\n};\n\nexport const getSuggestedBindingsForArrows = (\n selectedElements: NonDeleted<ExcalidrawElement>[],\n elementsMap: NonDeletedSceneElementsMap,\n zoom: AppState[\"zoom\"],\n): SuggestedBinding[] => {\n // HOT PATH: Bail out if selected elements list is too large\n if (selectedElements.length > 50) {\n return [];\n }\n\n return (\n selectedElements\n .filter(isLinearElement)\n .flatMap((element) =>\n getOriginalBindingsIfStillCloseToArrowEnds(element, elementsMap, zoom),\n )\n .filter(\n (element): element is NonDeleted<ExcalidrawBindableElement> =>\n element !== null,\n )\n // Filter out bind candidates which are in the\n // same selection / group with the arrow\n //\n // TODO: Is it worth turning the list into a set to avoid dupes?\n .filter(\n (element) =>\n selectedElements.filter((selected) => selected.id === element?.id)\n .length === 0,\n )\n );\n};\n\nexport const maybeBindLinearElement = (\n linearElement: NonDeleted<ExcalidrawLinearElement>,\n appState: AppState,\n pointerCoords: { x: number; y: number },\n elementsMap: NonDeletedSceneElementsMap,\n elements: readonly NonDeletedExcalidrawElement[],\n): void => {\n if (appState.startBoundElement != null) {\n bindLinearElement(\n linearElement,\n appState.startBoundElement,\n \"start\",\n elementsMap,\n );\n }\n\n const hoveredElement = getHoveredElementForBinding(\n pointerCoords,\n elements,\n elementsMap,\n appState.zoom,\n isElbowArrow(linearElement),\n isElbowArrow(linearElement),\n );\n\n if (hoveredElement !== null) {\n if (\n !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(\n linearElement,\n hoveredElement,\n \"end\",\n )\n ) {\n bindLinearElement(linearElement, hoveredElement, \"end\", elementsMap);\n }\n }\n};\n\nconst normalizePointBinding = (\n binding: { focus: number; gap: number },\n hoveredElement: ExcalidrawBindableElement,\n) => {\n let gap = binding.gap;\n const maxGap = maxBindingGap(\n hoveredElement,\n hoveredElement.width,\n hoveredElement.height,\n );\n\n if (gap > maxGap) {\n gap = BINDING_HIGHLIGHT_THICKNESS + BINDING_HIGHLIGHT_OFFSET;\n }\n return {\n ...binding,\n gap,\n };\n};\n\nexport const bindLinearElement = (\n linearElement: NonDeleted<ExcalidrawLinearElement>,\n hoveredElement: ExcalidrawBindableElement,\n startOrEnd: \"start\" | \"end\",\n elementsMap: NonDeletedSceneElementsMap,\n): void => {\n if (!isArrowElement(linearElement)) {\n return;\n }\n\n const binding: PointBinding | FixedPointBinding = {\n elementId: hoveredElement.id,\n ...(isElbowArrow(linearElement)\n ? {\n ...calculateFixedPointForElbowArrowBinding(\n linearElement,\n hoveredElement,\n startOrEnd,\n elementsMap,\n ),\n focus: 0,\n gap: 0,\n }\n : {\n ...normalizePointBinding(\n calculateFocusAndGap(\n linearElement,\n hoveredElement,\n startOrEnd,\n elementsMap,\n ),\n hoveredElement,\n ),\n }),\n };\n\n mutateElement(linearElement, {\n [startOrEnd === \"start\" ? \"startBinding\" : \"endBinding\"]: binding,\n });\n\n const boundElementsMap = arrayToMap(hoveredElement.boundElements || []);\n if (!boundElementsMap.has(linearElement.id)) {\n mutateElement(hoveredElement, {\n boundElements: (hoveredElement.boundElements || []).concat({\n id: linearElement.id,\n type: \"arrow\",\n }),\n });\n }\n};\n\n// Don't bind both ends of a simple segment\nconst isLinearElementSimpleAndAlreadyBoundOnOppositeEdge = (\n linearElement: NonDeleted<ExcalidrawLinearElement>,\n bindableElement: ExcalidrawBindableElement,\n startOrEnd: \"start\" | \"end\",\n): boolean => {\n const otherBinding =\n linearElement[startOrEnd === \"start\" ? \"endBinding\" : \"startBinding\"];\n return isLinearElementSimpleAndAlreadyBound(\n linearElement,\n otherBinding?.elementId,\n bindableElement,\n );\n};\n\nexport const isLinearElementSimpleAndAlreadyBound = (\n linearElement: NonDeleted<ExcalidrawLinearElement>,\n alreadyBoundToId: ExcalidrawBindableElement[\"id\"] | undefined,\n bindableElement: ExcalidrawBindableElement,\n): boolean => {\n return (\n alreadyBoundToId === bindableElement.id &&\n isLinearElementSimple(linearElement)\n );\n};\n\nconst isLinearElementSimple = (\n linearElement: NonDeleted<ExcalidrawLinearElement>,\n): boolean => linearElement.points.length < 3;\n\nconst unbindLinearElement = (\n linearElement: NonDeleted<ExcalidrawLinearElement>,\n startOrEnd: \"start\" | \"end\",\n): ExcalidrawBindableElement[\"id\"] | null => {\n const field = startOrEnd === \"start\" ? \"startBinding\" : \"endBinding\";\n const binding = linearElement[field];\n if (binding == null) {\n return null;\n }\n mutateElement(linearElement, { [field]: null });\n return binding.elementId;\n};\n\nexport const getHoveredElementForBinding = (\n pointerCoords: {\n x: number;\n y: number;\n },\n elements: readonly NonDeletedExcalidrawElement[],\n elementsMap: NonDeletedSceneElementsMap,\n zoom?: AppState[\"zoom\"],\n fullShape?: boolean,\n considerAllElements?: boolean,\n): NonDeleted<ExcalidrawBindableElement> | null => {\n if (considerAllElements) {\n let cullRest = false;\n const candidateElements = getAllElementsAtPositionForBinding(\n elements,\n (element) =>\n isBindableElement(element, false) &&\n bindingBorderTest(\n element,\n pointerCoords,\n elementsMap,\n zoom,\n (fullShape ||\n !isBindingFallthroughEnabled(\n element as ExcalidrawBindableElement,\n )) &&\n // disable fullshape snapping for frame elements so we\n // can bind to frame children\n !isFrameLikeElement(element),\n ),\n ).filter((element) => {\n if (cullRest) {\n return false;\n }\n\n if (!isBindingFallthroughEnabled(element as ExcalidrawBindableElement)) {\n cullRest = true;\n }\n\n return true;\n }) as NonDeleted<ExcalidrawBindableElement>[] | null;\n\n // Return early if there are no candidates or just one candidate\n if (!candidateElements || candidateElements.length === 0) {\n return null;\n }\n\n if (candidateElements.length === 1) {\n return candidateElements[0] as NonDeleted<ExcalidrawBindableElement>;\n }\n\n // Prefer the shape with the border being tested (if any)\n const borderTestElements = candidateElements.filter((element) =>\n bindingBorderTest(element, pointerCoords, elementsMap, zoom, false),\n );\n if (borderTestElements.length === 1) {\n return borderTestElements[0];\n }\n\n // Prefer smaller shapes\n return candidateElements\n .sort(\n (a, b) => b.width ** 2 + b.height ** 2 - (a.width ** 2 + a.height ** 2),\n )\n .pop() as NonDeleted<ExcalidrawBindableElement>;\n }\n\n const hoveredElement = getElementAtPositionForBinding(\n elements,\n (element) =>\n isBindableElement(element, false) &&\n bindingBorderTest(\n element,\n pointerCoords,\n elementsMap,\n zoom,\n // disable fullshape snapping for frame elements so we\n // can bind to frame children\n (fullShape || !isBindingFallthroughEnabled(element)) &&\n !isFrameLikeElement(element),\n ),\n );\n\n return hoveredElement as NonDeleted<ExcalidrawBindableElement> | null;\n};\n\nconst getElementAtPositionForBinding = (\n elements: readonly NonDeletedExcalidrawElement[],\n isAtPositionFn: (element: NonDeletedExcalidrawElement) => boolean,\n) => {\n let hitElement = null;\n // We need to to hit testing from front (end of the array) to back (beginning of the array)\n // because array is ordered from lower z-index to highest and we want element z-index\n // with higher z-index\n for (let index = elements.length - 1; index >= 0; --index) {\n const element = elements[index];\n if (element.isDeleted) {\n continue;\n }\n if (isAtPositionFn(element)) {\n hitElement = element;\n break;\n }\n }\n\n return hitElement;\n};\n\nconst getAllElementsAtPositionForBinding = (\n elements: readonly NonDeletedExcalidrawElement[],\n isAtPositionFn: (element: NonDeletedExcalidrawElement) => boolean,\n) => {\n const elementsAtPosition: NonDeletedExcalidrawElement[] = [];\n // We need to to hit testing from front (end of the array) to back (beginning of the array)\n // because array is ordered from lower z-index to highest and we want element z-index\n // with higher z-index\n for (let index = elements.length - 1; index >= 0; --index) {\n const element = elements[index];\n if (element.isDeleted) {\n continue;\n }\n\n if (isAtPositionFn(element)) {\n elementsAtPosition.push(element);\n }\n }\n\n return elementsAtPosition;\n};\n\nconst calculateFocusAndGap = (\n linearElement: NonDeleted<ExcalidrawLinearElement>,\n hoveredElement: ExcalidrawBindableElement,\n startOrEnd: \"start\" | \"end\",\n elementsMap: NonDeletedSceneElementsMap,\n): { focus: number; gap: number } => {\n const direction = startOrEnd === \"start\" ? -1 : 1;\n const edgePointIndex = direction === -1 ? 0 : linearElement.points.length - 1;\n const adjacentPointIndex = edgePointIndex - direction;\n\n const edgePoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(\n linearElement,\n edgePointIndex,\n elementsMap,\n );\n const adjacentPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(\n linearElement,\n adjacentPointIndex,\n elementsMap,\n );\n\n return {\n focus: determineFocusDistance(hoveredElement, adjacentPoint, edgePoint),\n gap: Math.max(1, distanceToBindableElement(hoveredElement, edgePoint)),\n };\n};\n\n// Supports translating, rotating and scaling `changedElement` with bound\n// linear elements.\n// Because scaling involves moving the focus points as well, it is\n// done before the `changedElement` is updated, and the `newSize` is passed\n// in explicitly.\nexport const updateBoundElements = (\n changedElement: NonDeletedExcalidrawElement,\n elementsMap: NonDeletedSceneElementsMap | SceneElementsMap,\n options?: {\n simultaneouslyUpdated?: readonly ExcalidrawElement[];\n newSize?: { width: number; height: number };\n changedElements?: Map<string, OrderedExcalidrawElement>;\n },\n) => {\n const { newSize, simultaneouslyUpdated } = options ?? {};\n const simultaneouslyUpdatedElementIds = getSimultaneouslyUpdatedElementIds(\n simultaneouslyUpdated,\n );\n\n if (!isBindableElement(changedElement)) {\n return;\n }\n\n boundElementsVisitor(elementsMap, changedElement, (element) => {\n if (!isLinearElement(element) || element.isDeleted) {\n return;\n }\n\n // In case the boundElements are stale\n if (!doesNeedUpdate(element, changedElement)) {\n return;\n }\n\n const bindings = {\n startBinding: maybeCalculateNewGapWhenScaling(\n changedElement,\n element.startBinding,\n newSize,\n ),\n endBinding: maybeCalculateNewGapWhenScaling(\n changedElement,\n element.endBinding,\n newSize,\n ),\n };\n\n // `linearElement` is being moved/scaled already, just update the binding\n if (simultaneouslyUpdatedElementIds.has(element.id)) {\n mutateElement(element, bindings, true);\n return;\n }\n\n const updates = bindableElementsVisitor(\n elementsMap,\n element,\n (bindableElement, bindingProp) => {\n if (\n bindableElement &&\n isBindableElement(bindableElement) &&\n (bindingProp === \"startBinding\" || bindingProp === \"endBinding\") &&\n changedElement.id === element[bindingProp]?.elementId\n ) {\n const point = updateBoundPoint(\n element,\n bindingProp,\n bindings[bindingProp],\n bindableElement,\n elementsMap,\n );\n if (point) {\n return {\n index:\n bindingProp === \"startBinding\" ? 0 : element.points.length - 1,\n point,\n };\n }\n }\n\n return null;\n },\n ).filter(\n (\n update,\n ): update is NonNullable<{\n index: number;\n point: LocalPoint;\n isDragging?: boolean;\n }> => update !== null,\n );\n\n LinearElementEditor.movePoints(element, updates, {\n ...(changedElement.id === element.startBinding?.elementId\n ? { startBinding: bindings.startBinding }\n : {}),\n ...(changedElement.id === element.endBinding?.elementId\n ? { endBinding: bindings.endBinding }\n : {}),\n });\n\n const boundText = getBoundTextElement(element, elementsMap);\n if (boundText && !boundText.isDeleted) {\n handleBindTextResize(element, elementsMap, false);\n }\n });\n};\n\nconst doesNeedUpdate = (\n boundElement: NonDeleted<ExcalidrawLinearElement>,\n changedElement: ExcalidrawBindableElement,\n) => {\n return (\n boundElement.startBinding?.elementId === changedElement.id ||\n boundElement.endBinding?.elementId === changedElement.id\n );\n};\n\nconst getSimultaneouslyUpdatedElementIds = (\n simultaneouslyUpdated: readonly ExcalidrawElement[] | undefined,\n): Set<ExcalidrawElement[\"id\"]> => {\n return new Set((simultaneouslyUpdated || []).map((element) => element.id));\n};\n\nexport const getHeadingForElbowArrowSnap = (\n p: Readonly<GlobalPoint>,\n otherPoint: Readonly<GlobalPoint>,\n bindableElement: ExcalidrawBindableElement | undefined | null,\n aabb: Bounds | undefined | null,\n elementsMap: ElementsMap,\n origPoint: GlobalPoint,\n zoom?: AppState[\"zoom\"],\n): Heading => {\n const otherPointHeading = vectorToHeading(vectorFromPoint(otherPoint, p));\n\n if (!bindableElement || !aabb) {\n return otherPointHeading;\n }\n\n const distance = getDistanceForBinding(\n origPoint,\n bindableElement,\n elementsMap,\n zoom,\n );\n\n if (!distance) {\n return vectorToHeading(\n vectorFromPoint(\n p,\n pointFrom<GlobalPoint>(\n bindableElement.x + bindableElement.width / 2,\n bindableElement.y + bindableElement.height / 2,\n ),\n ),\n );\n }\n\n return headingForPointFromElement(bindableElement, aabb, p);\n};\n\nconst getDistanceForBinding = (\n point: Readonly<GlobalPoint>,\n bindableElement: ExcalidrawBindableElement,\n elementsMap: ElementsMap,\n zoom?: AppState[\"zoom\"],\n) => {\n const distance = distanceToBindableElement(bindableElement, point);\n const bindDistance = maxBindingGap(\n bindableElement,\n bindableElement.width,\n bindableElement.height,\n zoom,\n );\n\n return distance > bindDistance ? null : distance;\n};\n\nexport const bindPointToSnapToElementOutline = (\n arrow: ExcalidrawElbowArrowElement,\n bindableElement: ExcalidrawBindableElement | undefined,\n startOrEnd: \"start\" | \"end\",\n): GlobalPoint => {\n const aabb = bindableElement && aabbForElement(bindableElement);\n const localP =\n arrow.points[startOrEnd === \"start\" ? 0 : arrow.points.length - 1];\n const globalP = pointFrom<GlobalPoint>(\n arrow.x + localP[0],\n arrow.y + localP[1],\n );\n const p = isRectanguloidElement(bindableElement)\n ? avoidRectangularCorner(bindableElement, globalP)\n : globalP;\n\n if (bindableElement && aabb) {\n const center = getCenterForBounds(aabb);\n\n const intersection = intersectElementWithLineSegment(\n bindableElement,\n lineSegment(\n center,\n pointFromVector(\n vectorScale(\n vectorNormalize(vectorFromPoint(p, center)),\n Math.max(bindableElement.width, bindableElement.height),\n ),\n center,\n ),\n ),\n )[0];\n const currentDistance = pointDistance(p, center);\n const fullDistance = pointDistance(intersection, center);\n const ratio = currentDistance / fullDistance;\n\n switch (true) {\n case ratio > 0.9:\n if (currentDistance - fullDistance > FIXED_BINDING_DISTANCE) {\n return p;\n }\n\n return pointFromVector(\n vectorScale(\n vectorNormalize(vectorFromPoint(p, intersection)),\n ratio > 1 ? FIXED_BINDING_DISTANCE : -FIXED_BINDING_DISTANCE,\n ),\n intersection,\n );\n\n default:\n return headingToMidBindPoint(p, bindableElement, aabb);\n }\n }\n\n return p;\n};\n\nconst headingToMidBindPoint = (\n p: GlobalPoint,\n bindableElement: ExcalidrawBindableElement,\n aabb: Bounds,\n): GlobalPoint => {\n const center = getCenterForBounds(aabb);\n const heading = vectorToHeading(vectorFromPoint(p, center));\n\n switch (true) {\n case compareHeading(heading, HEADING_UP):\n return pointRotateRads(\n pointFrom((aabb[0] + aabb[2]) / 2 + 0.1, aabb[1]),\n center,\n bindableElement.angle,\n );\n case compareHeading(heading, HEADING_RIGHT):\n return pointRotateRads(\n pointFrom(aabb[2], (aabb[1] + aabb[3]) / 2 + 0.1),\n center,\n bindableElement.angle,\n );\n case compareHeading(heading, HEADING_DOWN):\n return pointRotateRads(\n pointFrom((aabb[0] + aabb[2]) / 2 - 0.1, aabb[3]),\n center,\n bindableElement.angle,\n );\n default:\n return pointRotateRads(\n pointFrom(aabb[0], (aabb[1] + aabb[3]) / 2 - 0.1),\n center,\n bindableElement.angle,\n );\n }\n};\n\nexport const avoidRectangularCorner = (\n element: ExcalidrawBindableElement,\n p: GlobalPoint,\n): GlobalPoint => {\n const center = pointFrom<GlobalPoint>(\n element.x + element.width / 2,\n element.y + element.height / 2,\n );\n const nonRotatedPoint = pointRotateRads(p, center, -element.angle as Radians);\n\n if (nonRotatedPoint[0] < element.x && nonRotatedPoint[1] < element.y) {\n // Top left\n if (nonRotatedPoint[1] - element.y > -FIXED_BINDING_DISTANCE) {\n return pointRotateRads<GlobalPoint>(\n pointFrom(element.x - FIXED_BINDING_DISTANCE, element.y),\n center,\n element.angle,\n );\n }\n return pointRotateRads(\n pointFrom(element.x, element.y - FIXED_BINDING_DISTANCE),\n center,\n element.angle,\n );\n } else if (\n nonRotatedPoint[0] < element.x &&\n nonRotatedPoint[1] > element.y + element.height\n ) {\n // Bottom left\n if (nonRotatedPoint[0] - element.x > -FIXED_BINDING_DISTANCE) {\n return pointRotateRads(\n pointFrom(\n element.x,\n element.y + element.height + FIXED_BINDING_DISTANCE,\n ),\n center,\n element.angle,\n );\n }\n return pointRotateRads(\n pointFrom(element.x - FIXED_BINDING_DISTANCE, element.y + element.height),\n center,\n element.angle,\n );\n } else if (\n nonRotatedPoint[0] > element.x + element.width &&\n nonRotatedPoint[1] > element.y + element.height\n ) {\n // Bottom right\n if (\n nonRotatedPoint[0] - element.x <\n element.width + FIXED_BINDING_DISTANCE\n ) {\n return pointRotateRads(\n pointFrom(\n element.x + element.width,\n element.y + element.height + FIXED_BINDING_DISTANCE,\n ),\n center,\n element.angle,\n );\n }\n return pointRotateRads(\n pointFrom(\n element.x + element.width + FIXED_BINDING_DISTANCE,\n element.y + element.height,\n ),\n center,\n element.angle,\n );\n } else if (\n nonRotatedPoint[0] > element.x + element.width &&\n nonRotatedPoint[1] < element.y\n ) {\n // Top right\n if (\n nonRotatedPoint[0] - element.x <\n element.width + FIXED_BINDING_DISTANCE\n ) {\n return pointRotateRads(\n pointFrom(\n element.x + element.width,\n element.y - FIXED_BINDING_DISTANCE,\n ),\n center,\n element.angle,\n );\n }\n return pointRotateRads(\n pointFrom(element.x + element.width + FIXED_BINDING_DISTANCE, element.y),\n center,\n element.angle,\n );\n }\n\n return p;\n};\n\nexport const snapToMid = (\n element: ExcalidrawBindableElement,\n p: GlobalPoint,\n tolerance: number = 0.05,\n): GlobalPoint => {\n const { x, y, width, height, angle } = element;\n const center = pointFrom<GlobalPoint>(\n x + width / 2 - 0.1,\n y + height / 2 - 0.1,\n );\n const nonRotated = pointRotateRads(p, center, -angle as Radians);\n\n // snap-to-center point is adaptive to element size, but we don't want to go\n // above and below certain px distance\n const verticalThrehsold = clamp(tolerance * height, 5, 80);\n const horizontalThrehsold = clamp(tolerance * width, 5, 80);\n\n if (\n nonRotated[0] <= x + width / 2 &&\n nonRotated[1] > center[1] - verticalThrehsold &&\n nonRotated[1] < center[1] + verticalThrehsold\n ) {\n // LEFT\n return pointRotateRads(\n pointFrom(x - FIXED_BINDING_DISTANCE, center[1]),\n center,\n angle,\n );\n } else if (\n nonRotated[1] <= y + height / 2 &&\n nonRotated[0] > center[0] - horizontalThrehsold &&\n nonRotated[0] < center[0] + horizontalThrehsold\n ) {\n // TOP\n return pointRotateRads(\n pointFrom(center[0], y - FIXED_BINDING_DISTANCE),\n center,\n angle,\n );\n } else if (\n nonRotated[0] >= x + width / 2 &&\n nonRotated[1] > center[1] - verticalThrehsold &&\n nonRotated[1] < center[1] + verticalThrehsold\n ) {\n // RIGHT\n return pointRotateRads(\n pointFrom(x + width + FIXED_BINDING_DISTANCE, center[1]),\n center,\n angle,\n );\n } else if (\n nonRotated[1] >= y + height / 2 &&\n nonRotated[0] > center[0] - horizontalThrehsold &&\n nonRotated[0] < center[0] + horizontalThrehsold\n ) {\n // DOWN\n return pointRotateRads(\n pointFrom(center[0], y + height + FIXED_BINDING_DISTANCE),\n center,\n angle,\n );\n }\n\n return p;\n};\n\nconst updateBoundPoint = (\n linearElement: NonDeleted<ExcalidrawLinearElement>,\n startOrEnd: \"startBinding\" | \"endBinding\",\n binding: PointBinding | null | undefined,\n bindableElement: ExcalidrawBindableElement,\n elementsMap: ElementsMap,\n): LocalPoint | null => {\n if (\n binding == null ||\n // We only need to update the other end if this is a 2 point line element\n (binding.elementId !== bindableElement.id &&\n linearElement.points.length > 2)\n ) {\n return null;\n }\n\n const direction = startOrEnd === \"startBinding\" ? -1 : 1;\n const edgePointIndex = direction === -1 ? 0 : linearElement.points.length - 1;\n\n if (isElbowArrow(linearElement) && isFixedPointBinding(binding)) {\n const fixedPoint =\n normalizeFixedPoint(binding.fixedPoint) ??\n calculateFixedPointForElbowArrowBinding(\n linearElement,\n bindableElement,\n startOrEnd === \"startBinding\" ? \"start\" : \"end\",\n elementsMap,\n ).fixedPoint;\n const globalMidPoint = pointFrom<GlobalPoint>(\n bindableElement.x + bindableElement.width / 2,\n bindableElement.y + bindableElement.height / 2,\n );\n const global = pointFrom<GlobalPoint>(\n bindableElement.x + fixedPoint[0] * bindableElement.width,\n bindableElement.y + fixedPoint[1] * bindableElement.height,\n );\n const rotatedGlobal = pointRotateRads(\n global,\n globalMidPoint,\n bindableElement.angle,\n );\n\n return LinearElementEditor.pointFromAbsoluteCoords(\n linearElement,\n rotatedGlobal,\n elementsMap,\n );\n }\n\n const adjacentPointIndex = edgePointIndex - direction;\n const adjacentPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(\n linearElement,\n adjacentPointIndex,\n elementsMap,\n );\n const focusPointAbsolute = determineFocusPoint(\n bindableElement,\n binding.focus,\n adjacentPoint,\n );\n\n let newEdgePoint: GlobalPoint;\n\n // The linear element was not originally pointing inside the bound shape,\n // we can point directly at the focus point\n if (binding.gap === 0) {\n newEdgePoint = focusPointAbsolute;\n } else {\n const edgePointAbsolute =\n LinearElementEditor.getPointAtIndexGlobalCoordinates(\n linearElement,\n edgePointIndex,\n elementsMap,\n );\n\n const center = pointFrom<GlobalPoint>(\n bindableElement.x + bindableElement.width / 2,\n bindableElement.y + bindableElement.height / 2,\n );\n const interceptorLength =\n pointDistance(adjacentPoint, edgePointAbsolute) +\n pointDistance(adjacentPoint, center) +\n Math.max(bindableElement.width, bindableElement.height) * 2;\n const intersections = intersectElementWithLineSegment(\n bindableElement,\n lineSegment<GlobalPoint>(\n adjacentPoint,\n pointFromVector(\n vectorScale(\n vectorNormalize(vectorFromPoint(focusPointAbsolute, adjacentPoint)),\n interceptorLength,\n ),\n adjacentPoint,\n ),\n ),\n binding.gap,\n ).sort(\n (g, h) =>\n pointDistanceSq(g, adjacentPoint) - pointDistanceSq(h, adjacentPoint),\n );\n\n // debugClear();\n // debugDrawPoint(intersections[0], { color: \"red\", permanent: true });\n // debugDrawLine(\n // lineSegment<GlobalPoint>(\n // adjacentPoint,\n // pointFromVector(\n // vectorScale(\n // vectorNormalize(vectorFromPoint(focusPointAbsolute, adjacentPoint)),\n // interceptorLength,\n // ),\n // adjacentPoint,\n // ),\n // ),\n // { permanent: true, color: \"green\" },\n // );\n\n if (intersections.length > 1) {\n // The adjacent point is outside the shape (+ gap)\n newEdgePoint = intersections[0];\n } else if (intersections.length === 1) {\n // The adjacent point is inside the shape (+ gap)\n newEdgePoint = focusPointAbsolute;\n } else {\n // Shouldn't happend, but just in case\n newEdgePoint = edgePointAbsolute;\n }\n }\n\n return LinearElementEditor.pointFromAbsoluteCoords(\n linearElement,\n newEdgePoint,\n elementsMap,\n );\n};\n\nexport const calculateFixedPointForElbowArrowBinding = (\n linearElement: NonDeleted<ExcalidrawElbowArrowElement>,\n hoveredElement: ExcalidrawBindableElement,\n startOrEnd: \"start\" | \"end\",\n elementsMap: ElementsMap,\n): { fixedPoint: FixedPoint } => {\n const bounds = [\n hoveredElement.x,\n hoveredElement.y,\n hoveredElement.x + hoveredElement.width,\n hoveredElement.y + hoveredElement.height,\n ] as Bounds;\n const snappedPoint = bindPointToSnapToElementOutline(\n linearElement,\n hoveredElement,\n startOrEnd,\n );\n const globalMidPoint = pointFrom(\n bounds[0] + (bounds[2] - bounds[0]) / 2,\n bounds[1] + (bounds[3] - bounds[1]) / 2,\n );\n const nonRotatedSnappedGlobalPoint = pointRotateRads(\n snappedPoint,\n globalMidPoint,\n -hoveredElement.angle as Radians,\n );\n\n return {\n fixedPoint: normalizeFixedPoint([\n (nonRotatedSnappedGlobalPoint[0] - hoveredElement.x) /\n hoveredElement.width,\n (nonRotatedSnappedGlobalPoint[1] - hoveredElement.y) /\n hoveredElement.height,\n ]),\n };\n};\n\nconst maybeCalculateNewGapWhenScaling = (\n changedElement: ExcalidrawBindableElement,\n currentBinding: PointBinding | null | undefined,\n newSize: { width: number; height: number } | undefined,\n): PointBinding | null | undefined => {\n if (currentBinding == null || newSize == null) {\n return currentBinding;\n }\n const { width: newWidth, height: newHeight } = newSize;\n const { width, height } = changedElement;\n const newGap = Math.max(\n 1,\n Math.min(\n maxBindingGap(changedElement, newWidth, newHeight),\n currentBinding.gap *\n (newWidth < newHeight ? newWidth / width : newHeight / height),\n ),\n );\n\n return { ...currentBinding, gap: newGap };\n};\n\nconst getElligibleElementForBindingElement = (\n linearElement: NonDeleted<ExcalidrawLinearElement>,\n startOrEnd: \"start\" | \"end\",\n elementsMap: NonDeletedSceneElementsMap,\n elements: readonly NonDeletedExcalidrawElement[],\n zoom?: AppState[\"zoom\"],\n): NonDeleted<ExcalidrawBindableElement> | null => {\n return getHoveredElementForBinding(\n getLinearElementEdgeCoors(linearElement, startOrEnd, elementsMap),\n elements,\n elementsMap,\n zoom,\n isElbowArrow(linearElement),\n isElbowArrow(linearElement),\n );\n};\n\nconst getLinearElementEdgeCoors = (\n linearElement: NonDeleted<ExcalidrawLinearElement>,\n startOrEnd: \"start\" | \"end\",\n elementsMap: NonDeletedSceneElementsMap,\n): { x: number; y: number } => {\n const index = startOrEnd === \"start\" ? 0 : -1;\n return tupleToCoors(\n LinearElementEditor.getPointAtIndexGlobalCoordinates(\n linearElement,\n index,\n elementsMap,\n ),\n );\n};\n\n// We need to:\n// 1: Update elements not selected to point to duplicated elements\n// 2: Update duplicated elements to point to other duplicated elements\nexport const fixBindingsAfterDuplication = (\n sceneElements: readonly ExcalidrawElement[],\n oldElements: readonly ExcalidrawElement[],\n oldIdToDuplicatedId: Map<ExcalidrawElement[\"id\"], ExcalidrawElement[\"id\"]>,\n // There are three copying mechanisms: Copy-paste, duplication and alt-drag.\n // Only when alt-dragging the new \"duplicates\" act as the \"old\", while\n // the \"old\" elements act as the \"new copy\" - essentially working reverse\n // to the other two.\n duplicatesServeAsOld?: \"duplicatesServeAsOld\" | undefined,\n): void => {\n // First collect all the binding/bindable elements, so we only update\n // each once, regardless of whether they were duplicated or not.\n const allBoundElementIds: Set<ExcalidrawElement[\"id\"]> = new Set();\n const allBindableElementIds: Set<ExcalidrawElement[\"id\"]> = new Set();\n const shouldReverseRoles = duplicatesServeAsOld === \"duplicatesServeAsOld\";\n const duplicateIdToOldId = new Map(\n [...oldIdToDuplicatedId].map(([key, value]) => [value, key]),\n );\n oldElements.forEach((oldElement) => {\n const { boundElements } = oldElement;\n if (boundElements != null && boundElements.length > 0) {\n boundElements.forEach((boundElement) => {\n if (shouldReverseRoles && !oldIdToDuplicatedId.has(boundElement.id)) {\n allBoundElementIds.add(boundElement.id);\n }\n });\n allBindableElementIds.add(oldIdToDuplicatedId.get(oldElement.id)!);\n }\n if (isBindingElement(oldElement)) {\n if (oldElement.startBinding != null) {\n const { elementId } = oldElement.startBinding;\n if (shouldReverseRoles && !oldIdToDuplicatedId.has(elementId)) {\n allBindableElementIds.add(elementId);\n }\n }\n if (oldElement.endBinding != null) {\n const { elementId } = oldElement.endBinding;\n if (shouldReverseRoles && !oldIdToDuplicatedId.has(elementId)) {\n allBindableElementIds.add(elementId);\n }\n }\n if (oldElement.startBinding != null || oldElement.endBinding != null) {\n allBoundElementIds.add(oldIdToDuplicatedId.get(oldElement.id)!);\n }\n }\n });\n\n // Update the linear elements\n (\n sceneElements.filter(({ id }) =>\n allBoundElementIds.has(id),\n ) as ExcalidrawLinearElement[]\n ).forEach((element) => {\n const { startBinding, endBinding } = element;\n mutateElement(element, {\n startBinding: newBindingAfterDuplication(\n startBinding,\n oldIdToDuplicatedId,\n ),\n endBinding: newBindingAfterDuplication(endBinding, oldIdToDuplicatedId),\n });\n });\n\n // Update the bindable shapes\n sceneElements\n .filter(({ id }) => allBindableElementIds.has(id))\n .forEach((bindableElement) => {\n const oldElementId = duplicateIdToOldId.get(bindableElement.id);\n const boundElements = sceneElements.find(\n ({ id }) => id === oldElementId,\n )?.boundElements;\n\n if (boundElements && boundElements.length > 0) {\n mutateElement(bindableElement, {\n boundElements: boundElements.map((boundElement) =>\n oldIdToDuplicatedId.has(boundElement.id)\n ? {\n id: oldIdToDuplicatedId.get(boundElement.id)!,\n type: boundElement.type,\n }\n : boundElement,\n ),\n });\n }\n });\n};\n\nconst newBindingAfterDuplication = (\n binding: PointBinding | null,\n oldIdToDuplicatedId: Map<ExcalidrawElement[\"id\"], ExcalidrawElement[\"id\"]>,\n): PointBinding | null => {\n if (binding == null) {\n return null;\n }\n return {\n ...binding,\n elementId: oldIdToDuplicatedId.get(binding.elementId) ?? binding.elementId,\n };\n};\n\nexport const fixBindingsAfterDeletion = (\n sceneElements: readonly ExcalidrawElement[],\n deletedElements: readonly ExcalidrawElement[],\n): void => {\n const elements = arrayToMap(sceneElements);\n\n for (const element of deletedElements) {\n BoundElement.unbindAffected(elements, element, mutateElement);\n BindableElement.unbindAffected(elements, element, mutateElement);\n }\n};\n\nconst newBoundElements = (\n boundElements: ExcalidrawElement[\"boundElements\"],\n idsToRemove: Set<ExcalidrawElement[\"id\"]>,\n elementsToAdd: Array<ExcalidrawElement> = [],\n) => {\n if (!boundElements) {\n return null;\n }\n\n const nextBoundElements = boundElements.filter(\n (boundElement) => !idsToRemove.has(boundElement.id),\n );\n\n nextBoundElements.push(\n ...elementsToAdd.map(\n (x) =>\n ({ id: x.id, type: x.type } as\n | ExcalidrawArrowElement\n | ExcalidrawTextElement),\n ),\n );\n\n return nextBoundElements;\n};\n\nexport const bindingBorderTest = (\n element: NonDeleted<ExcalidrawBindableElement>,\n { x, y }: { x: number; y: number },\n elementsMap: NonDeletedSceneElementsMap,\n zoom?: AppState[\"zoom\"],\n fullShape?: boolean,\n): boolean => {\n const threshold = maxBindingGap(element, element.width, element.height, zoom);\n\n const shape = getElementShape(element, elementsMap);\n return (\n isPointOnShape(pointFrom(x, y), shape, threshold) ||\n (fullShape === true &&\n pointInsideBounds(pointFrom(x, y), aabbForElement(element)))\n );\n};\n\nexport const maxBindingGap = (\n element: ExcalidrawElement,\n elementWidth: number,\n elementHeight: number,\n zoom?: AppState[\"zoom\"],\n): number => {\n const zoomValue = zoom?.value && zoom.value < 1 ? zoom.value : 1;\n\n // Aligns diamonds with rectangles\n const shapeRatio = element.type === \"diamond\" ? 1 / Math.sqrt(2) : 1;\n const smallerDimension = shapeRatio * Math.min(elementWidth, elementHeight);\n\n return Math.max(\n 16,\n // bigger bindable boundary for bigger elements\n Math.min(0.25 * smallerDimension, 32),\n // keep in sync with the zoomed highlight\n BINDING_HIGHLIGHT_THICKNESS / zoomValue + BINDING_HIGHLIGHT_OFFSET,\n );\n};\n\n// The focus distance is the oriented ratio between the size of\n// the `element` and the \"focus image\" of the element on which\n// all focus points lie, so it's a number between -1 and 1.\n// The line going through `a` and `b` is a tangent to the \"focus image\"\n// of the element.\nconst determineFocusDistance = (\n element: ExcalidrawBindableElement,\n // Point on the line, in absolute coordinates\n a: GlobalPoint,\n // Another point on the line, in absolute coordinates (closer to element)\n b: GlobalPoint,\n): number => {\n const center = pointFrom<GlobalPoint>(\n element.x + element.width / 2,\n element.y + element.height / 2,\n );\n\n if (pointsEqual(a, b)) {\n return 0;\n }\n\n const rotatedA = pointRotateRads(a, center, -element.angle as Radians);\n const rotatedB = pointRotateRads(b, center, -element.angle as Radians);\n const sign =\n Math.sign(\n vectorCross(\n vectorFromPoint(rotatedB, a),\n vectorFromPoint(rotatedB, center),\n ),\n ) * -1;\n const rotatedInterceptor = lineSegment(\n rotatedB,\n pointFromVector(\n vectorScale(\n vectorNormalize(vectorFromPoint(rotatedB, rotatedA)),\n Math.max(element.width * 2, element.height * 2),\n ),\n rotatedB,\n ),\n );\n const axes =\n element.type === \"diamond\"\n ? [\n lineSegment(\n pointFrom<GlobalPoint>(element.x + element.width / 2, element.y),\n pointFrom<GlobalPoint>(\n element.x + element.width / 2,\n element.y + element.height,\n ),\n ),\n lineSegment(\n pointFrom<GlobalPoint>(element.x, element.y + element.height / 2),\n pointFrom<GlobalPoint>(\n element.x + element.width,\n element.y + element.height / 2,\n ),\n ),\n ]\n : [\n lineSegment(\n pointFrom<GlobalPoint>(element.x, element.y),\n pointFrom<GlobalPoint>(\n element.x + element.width,\n element.y + element.height,\n ),\n ),\n lineSegment(\n pointFrom<GlobalPoint>(element.x + element.width, element.y),\n pointFrom<GlobalPoint>(element.x, element.y + element.height),\n ),\n ];\n const interceptees =\n element.type === \"diamond\"\n ? [\n lineSegment(\n pointFrom<GlobalPoint>(\n element.x + element.width / 2,\n element.y - element.height,\n ),\n pointFrom<GlobalPoint>(\n element.x + element.width / 2,\n element.y + element.height * 2,\n ),\n ),\n lineSegment(\n pointFrom<GlobalPoint>(\n element.x - element.width,\n element.y + element.height / 2,\n ),\n pointFrom<GlobalPoint>(\n element.x + element.width * 2,\n element.y + element.height / 2,\n ),\n ),\n ]\n : [\n lineSegment(\n pointFrom<GlobalPoint>(\n element.x - element.width,\n element.y - element.height,\n ),\n pointFrom<GlobalPoint>(\n element.x + element.width * 2,\n element.y + element.height * 2,\n ),\n ),\n lineSegment(\n pointFrom<GlobalPoint>(\n element.x + element.width * 2,\n element.y - element.height,\n ),\n pointFrom<GlobalPoint>(\n element.x - element.width,\n element.y + element.height * 2,\n ),\n ),\n ];\n\n const ordered = [\n lineSegmentIntersectionPoints(rotatedInterceptor, interceptees[0]),\n lineSegmentIntersectionPoints(rotatedInterceptor, interceptees[1]),\n ]\n .filter((p): p is GlobalPoint => p !== null)\n .sort((g, h) => pointDistanceSq(g, b) - pointDistanceSq(h, b))\n .map(\n (p, idx): number =>\n (sign * pointDistance(center, p)) /\n (element.type === \"diamond\"\n ? pointDistance(axes[idx][0], axes[idx][1]) / 2\n : Math.sqrt(element.width ** 2 + element.height ** 2) / 2),\n )\n .sort((g, h) => Math.abs(g) - Math.abs(h));\n\n // debugClear();\n // [\n // lineSegmentIntersectionPoints(rotatedInterceptor, interceptees[0]),\n // lineSegmentIntersectionPoints(rotatedInterceptor, interceptees[1]),\n // ]\n // .filter((p): p is GlobalPoint => p !== null)\n // .forEach((p) => debugDrawPoint(p, { color: \"black\", permanent: true }));\n // debugDrawPoint(determineFocusPoint(element, ordered[0] ?? 0, rotatedA), {\n // color: \"red\",\n // permanent: true,\n // });\n // debugDrawLine(rotatedInterceptor, { color: \"green\", permanent: true });\n // debugDrawLine(interceptees[0], { color: \"red\", permanent: true });\n // debugDrawLine(interceptees[1], { color: \"red\", permanent: true });\n\n const signedDistanceRatio = ordered[0] ?? 0;\n\n return signedDistanceRatio;\n};\n\nconst determineFocusPoint = (\n element: ExcalidrawBindableElement,\n // The oriented, relative distance from the center of `element` of the\n // returned focusPoint\n focus: number,\n adjacentPoint: GlobalPoint,\n): GlobalPoint => {\n const center = pointFrom<GlobalPoint>(\n element.x + element.width / 2,\n element.y + element.height / 2,\n );\n\n if (focus === 0) {\n return center;\n }\n\n const candidates = (\n element.type === \"diamond\"\n ? [\n pointFrom<GlobalPoint>(element.x, element.y + element.height / 2),\n pointFrom<GlobalPoint>(element.x + element.width / 2, element.y),\n pointFrom<GlobalPoint>(\n element.x + element.width,\n element.y + element.height / 2,\n ),\n pointFrom<GlobalPoint>(\n element.x + element.width / 2,\n element.y + element.height,\n ),\n ]\n : [\n pointFrom<GlobalPoint>(element.x, element.y),\n pointFrom<GlobalPoint>(element.x + element.width, element.y),\n pointFrom<GlobalPoint>(\n element.x + element.width,\n element.y + element.height,\n ),\n pointFrom<GlobalPoint>(element.x, element.y + element.height),\n ]\n )\n .map((p) =>\n pointFromVector(\n vectorScale(vectorFromPoint(p, center), Math.abs(focus)),\n center,\n ),\n )\n .map((p) => pointRotateRads(p, center, element.angle as Radians));\n\n const selected = [\n vectorCross(\n vectorFromPoint(adjacentPoint, candidates[0]),\n vectorFromPoint(candidates[1], candidates[0]),\n ) > 0 && // TOP\n (focus > 0\n ? vectorCross(\n vectorFromPoint(adjacentPoint, candidates[1]),\n vectorFromPoint(candidates[2], candidates[1]),\n ) < 0\n : vectorCross(\n vectorFromPoint(adjacentPoint, candidates[3]),\n vectorFromPoint(candidates[0], candidates[3]),\n ) < 0),\n vectorCross(\n vectorFromPoint(adjacentPoint, candidates[1]),\n vectorFromPoint(candidates[2], candidates[1]),\n ) > 0 && // RIGHT\n (focus > 0\n ? vectorCross(\n vectorFromPoint(adjacentPoint, candidates[2]),\n vectorFromPoint(candidates[3], candidates[2]),\n ) < 0\n : vectorCross(\n vectorFromPoint(adjacentPoint, candidates[0]),\n vectorFromPoint(candidates[1], candidates[0]),\n ) < 0),\n vectorCross(\n vectorFromPoint(adjacentPoint, candidates[2]),\n vectorFromPoint(candidates[3], candidates[2]),\n ) > 0 && // BOTTOM\n (focus > 0\n ? vectorCross(\n vectorFromPoint(adjacentPoint, candidates[3]),\n vectorFromPoint(candidates[0], candidates[3]),\n ) < 0\n : vectorCross(\n vectorFromPoint(adjacentPoint, candidates[1]),\n vectorFromPoint(candidates[2], candidates[1]),\n ) < 0),\n vectorCross(\n vectorFromPoint(adjacentPoint, candidates[3]),\n vectorFromPoint(candidates[0], candidates[3]),\n ) > 0 && // LEFT\n (focus > 0\n ? vectorCross(\n vectorFromPoint(adjacentPoint, candidates[0]),\n vectorFromPoint(candidates[1], candidates[0]),\n ) < 0\n : vectorCross(\n vectorFromPoint(adjacentPoint, candidates[2]),\n vectorFromPoint(candidates[3], candidates[2]),\n ) < 0),\n ];\n\n const focusPoint = selected[0]\n ? focus > 0\n ? candidates[1]\n : candidates[0]\n : selected[1]\n ? focus > 0\n ? candidates[2]\n : candidates[1]\n : selected[2]\n ? focus > 0\n ? candidates[3]\n : candidates[2]\n : focus > 0\n ? candidates[0]\n : candidates[3];\n\n return focusPoint;\n};\n\nexport const bindingProperties: Set<BindableProp | BindingProp> = new Set([\n \"boundElements\",\n \"frameId\",\n \"containerId\",\n \"startBinding\",\n \"endBinding\",\n]);\n\nexport type BindableProp = \"boundElements\";\n\nexport type BindingProp =\n | \"frameId\"\n | \"containerId\"\n | \"startBinding\"\n | \"endBinding\";\n\ntype BoundElementsVisitingFunc = (\n boundElement: ExcalidrawElement | undefined,\n bindingProp: BindableProp,\n bindingId: string,\n) => void;\n\ntype BindableElementVisitingFunc<T> = (\n bindableElement: ExcalidrawElement | undefined,\n bindingProp: BindingProp,\n bindingId: string,\n) => T;\n\n/**\n * Tries to visit each bound element (does not have to be found).\n */\nconst boundElementsVisitor = (\n elements: ElementsMap,\n element: ExcalidrawElement,\n visit: BoundElementsVisitingFunc,\n) => {\n if (isBindableElement(element)) {\n // create new instance so that possible mutations won't play a role in visiting order\n const boundElements = element.boundElements?.slice() ?? [];\n\n // last added text should be the one we keep (~previous are duplicates)\n boundElements.forEach(({ id }) => {\n visit(elements.get(id), \"boundElements\", id);\n });\n }\n};\n\n/**\n * Tries to visit each bindable element (does not have to be found).\n */\nconst bindableElementsVisitor = <T>(\n elements: ElementsMap,\n element: ExcalidrawElement,\n visit: BindableElementVisitingFunc<T>,\n): T[] => {\n const result: T[] = [];\n\n if (element.frameId) {\n const id = element.frameId;\n result.push(visit(elements.get(id), \"frameId\", id));\n }\n\n if (isBoundToContainer(element)) {\n const id = element.containerId;\n result.push(visit(elements.get(id), \"containerId\", id));\n }\n\n if (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\n/**\n * Bound element containing bindings to `frameId`, `containerId`, `startBinding` or `endBinding`.\n */\nexport class BoundElement {\n /**\n * Unbind the affected non deleted bindable elements (removing element from `boundElements`).\n * - iterates non deleted bindable elements (`containerId` | `startBinding.elementId` | `endBinding.elementId`) of the current element\n * - prepares updates to unbind each bindable element's `boundElements` from the current element\n */\n public static unbindAffected(\n elements: ElementsMap,\n boundElement: ExcalidrawElement | undefined,\n updateElementWith: (\n affected: ExcalidrawElement,\n updates: ElementUpdate<ExcalidrawElement>,\n ) => void,\n ) {\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(\n elements,\n bindableElement,\n (_, __, boundElementId) => {\n if (boundElementId === boundElement.id) {\n updateElementWith(bindableElement, {\n boundElements: newBoundElements(\n bindableElement.boundElements,\n new Set([boundElementId]),\n ),\n });\n }\n },\n );\n });\n }\n\n /**\n * Rebind the next affected non deleted bindable elements (adding element to `boundElements`).\n * - iterates non deleted bindable elements (`containerId` | `startBinding.elementId` | `endBinding.elementId`) of the current element\n * - prepares updates to rebind each bindable element's `boundElements` to the current element\n *\n * NOTE: rebind expects that affected elements were previously unbound with `BoundElement.unbindAffected`\n */\n public static rebindAffected = (\n elements: ElementsMap,\n boundElement: ExcalidrawElement | undefined,\n updateElementWith: (\n affected: ExcalidrawElement,\n updates: ElementUpdate<ExcalidrawElement>,\n ) => void,\n ) => {\n // don't try to rebind element that is deleted\n if (!boundElement || boundElement.isDeleted) {\n return;\n }\n\n bindableElementsVisitor(\n elements,\n boundElement,\n (bindableElement, bindingProp) => {\n // unbind from bindable elements, as bindings from non deleted elements into deleted elements are incorrect\n if (!bindableElement || bindableElement.isDeleted) {\n updateElementWith(boundElement, { [bindingProp]: null });\n return;\n }\n\n // frame bindings are unidirectional, there is nothing to rebind\n if (bindingProp === \"frameId\") {\n return;\n }\n\n if (\n bindableElement.boundElements?.find((x) => x.id === boundElement.id)\n ) {\n return;\n }\n\n if (isArrowElement(boundElement)) {\n // rebind if not found!\n updateElementWith(bindableElement, {\n boundElements: newBoundElements(\n bindableElement.boundElements,\n new Set(),\n new Array(boundElement),\n ),\n });\n }\n\n if (isTextElement(boundElement)) {\n if (!bindableElement.boundElements?.find((x) => x.type === \"text\")) {\n // rebind only if there is no other text bound already\n updateElementWith(bindableElement, {\n boundElements: newBoundElements(\n bindableElement.boundElements,\n new Set(),\n new Array(boundElement),\n ),\n });\n } else {\n // unbind otherwise\n updateElementWith(boundElement, { [bindingProp]: null });\n }\n }\n },\n );\n };\n}\n\n/**\n * Bindable element containing bindings to `boundElements`.\n */\nexport class BindableElement {\n /**\n * Unbind the affected non deleted bound elements (resetting `containerId`, `startBinding`, `endBinding` to `null`).\n * - iterates through non deleted `boundElements` of the current element\n * - prepares updates to unbind each bound element from the current element\n */\n public static unbindAffected(\n elements: ElementsMap,\n bindableElement: ExcalidrawElement | undefined,\n updateElementWith: (\n affected: ExcalidrawElement,\n updates: ElementUpdate<ExcalidrawElement>,\n ) => void,\n ) {\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(\n elements,\n boundElement,\n (_, bindingProp, bindableElementId) => {\n // making sure there is an element to be unbound\n if (bindableElementId === bindableElement.id) {\n updateElementWith(boundElement, { [bindingProp]: null });\n }\n },\n );\n });\n }\n\n /**\n * Rebind the affected non deleted bound elements (for now setting only `containerId`, as we cannot rebind arrows atm).\n * - iterates through non deleted `boundElements` of the current element\n * - prepares updates to rebind each bound element to the current element or unbind it from `boundElements` in case of conflicts\n *\n * NOTE: rebind expects that affected elements were previously unbound with `BindaleElement.unbindAffected`\n */\n public static rebindAffected = (\n elements: ElementsMap,\n bindableElement: ExcalidrawElement | undefined,\n updateElementWith: (\n affected: ExcalidrawElement,\n updates: ElementUpdate<ExcalidrawElement>,\n ) => void,\n ) => {\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(\n elements,\n bindableElement,\n (boundElement, _, boundElementId) => {\n // unbind from bindable elements, as bindings from non deleted elements into deleted elements are incorrect\n if (!boundElement || boundElement.isDeleted) {\n updateElementWith(bindableElement, {\n boundElements: newBoundElements(\n bindableElement.boundElements,\n new Set([boundElementId]),\n ),\n });\n return;\n }\n\n if (isTextElement(boundElement)) {\n const boundElements = bindableElement.boundElements?.slice() ?? [];\n // check if this is the last element in the array, if not, there is an previously bound text which should be unbound\n if (\n boundElements.reverse().find((x) => x.type === \"text\")?.id ===\n boundElement.id\n ) {\n if (boundElement.containerId !== bindableElement.id) {\n // rebind if not bound already!\n updateElementWith(boundElement, {\n containerId: bindableElement.id,\n } as ElementUpdate<ExcalidrawTextElement>);\n }\n } else {\n if (boundElement.containerId !== null) {\n // unbind if not unbound already\n updateElementWith(boundElement, {\n containerId: null,\n } as ElementUpdate<ExcalidrawTextElement>);\n }\n\n // unbind from boundElements as the element got bound to some other element in the meantime\n updateElementWith(bindableElement, {\n boundElements: newBoundElements(\n bindableElement.boundElements,\n new Set([boundElement.id]),\n ),\n });\n }\n }\n },\n );\n };\n}\n\nexport const getGlobalFixedPointForBindableElement = (\n fixedPointRatio: [number, number],\n element: ExcalidrawBindableElement,\n): GlobalPoint => {\n const [fixedX, fixedY] = normalizeFixedPoint(fixedPointRatio);\n\n return pointRotateRads(\n pointFrom(\n element.x + element.width * fixedX,\n element.y + element.height * fixedY,\n ),\n pointFrom<GlobalPoint>(\n element.x + element.width / 2,\n element.y + element.height / 2,\n ),\n element.angle,\n );\n};\n\nexport const getGlobalFixedPoints = (\n arrow: ExcalidrawElbowArrowElement,\n elementsMap: ElementsMap,\n): [GlobalPoint, GlobalPoint] => {\n const startElement =\n arrow.startBinding &&\n (elementsMap.get(arrow.startBinding.elementId) as\n | ExcalidrawBindableElement\n | undefined);\n const endElement =\n arrow.endBinding &&\n (elementsMap.get(arrow.endBinding.elementId) as\n | ExcalidrawBindableElement\n | undefined);\n const startPoint =\n startElement && arrow.startBinding\n ? getGlobalFixedPointForBindableElement(\n arrow.startBinding.fixedPoint,\n startElement as ExcalidrawBindableElement,\n )\n : pointFrom<GlobalPoint>(\n arrow.x + arrow.points[0][0],\n arrow.y + arrow.points[0][1],\n );\n const endPoint =\n endElement && arrow.endBinding\n ? getGlobalFixedPointForBindableElement(\n arrow.endBinding.fixedPoint,\n endElement as ExcalidrawBindableElement,\n )\n : pointFrom<GlobalPoint>(\n arrow.x + arrow.points[arrow.points.length - 1][0],\n arrow.y + arrow.points[arrow.points.length - 1][1],\n );\n\n return [startPoint, endPoint];\n};\n\nexport const getArrowLocalFixedPoints = (\n arrow: ExcalidrawElbowArrowElement,\n elementsMap: ElementsMap,\n) => {\n const [startPoint, endPoint] = getGlobalFixedPoints(arrow, elementsMap);\n\n return [\n LinearElementEditor.pointFromAbsoluteCoords(arrow, startPoint, elementsMap),\n LinearElementEditor.pointFromAbsoluteCoords(arrow, endPoint, elementsMap),\n ];\n};\n\nexport const normalizeFixedPoint = <T extends FixedPoint | null>(\n fixedPoint: T,\n): T extends null ? null : 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 && (fixedPoint[0] === 0.5 || fixedPoint[1] === 0.5)) {\n return fixedPoint.map((ratio) =>\n ratio === 0.5 ? 0.5001 : ratio,\n ) as T extends null ? null : FixedPoint;\n }\n return fixedPoint as any as T extends null ? null : FixedPoint;\n};\n", "import type { AppState, Offsets, PointerCoords, Zoom } from \"../types\";\nimport type { ExcalidrawElement } from \"../element/types\";\nimport {\n getCommonBounds,\n getClosestElementBounds,\n getVisibleElements,\n} from \"../element\";\n\nimport {\n sceneCoordsToViewportCoords,\n viewportCoordsToSceneCoords,\n} from \"../utils\";\n\nconst isOutsideViewPort = (appState: AppState, cords: Array<number>) => {\n const [x1, y1, x2, y2] = cords;\n const { x: viewportX1, y: viewportY1 } = sceneCoordsToViewportCoords(\n { sceneX: x1, sceneY: y1 },\n appState,\n );\n const { x: viewportX2, y: viewportY2 } = sceneCoordsToViewportCoords(\n { sceneX: x2, sceneY: y2 },\n appState,\n );\n return (\n viewportX2 - viewportX1 > appState.width ||\n viewportY2 - viewportY1 > appState.height\n );\n};\n\nexport const centerScrollOn = ({\n scenePoint,\n viewportDimensions,\n zoom,\n offsets,\n}: {\n scenePoint: PointerCoords;\n viewportDimensions: { height: number; width: number };\n zoom: Zoom;\n offsets?: Offsets;\n}) => {\n let scrollX =\n (viewportDimensions.width - (offsets?.right ?? 0)) / 2 / zoom.value -\n scenePoint.x;\n\n scrollX += (offsets?.left ?? 0) / 2 / zoom.value;\n\n let scrollY =\n (viewportDimensions.height - (offsets?.bottom ?? 0)) / 2 / zoom.value -\n scenePoint.y;\n\n scrollY += (offsets?.top ?? 0) / 2 / zoom.value;\n\n return {\n scrollX,\n scrollY,\n };\n};\n\nexport const calculateScrollCenter = (\n elements: readonly ExcalidrawElement[],\n appState: AppState,\n): { scrollX: number; scrollY: number } => {\n elements = getVisibleElements(elements);\n\n if (!elements.length) {\n return {\n scrollX: 0,\n scrollY: 0,\n };\n }\n let [x1, y1, x2, y2] = getCommonBounds(elements);\n\n if (isOutsideViewPort(appState, [x1, y1, x2, y2])) {\n [x1, y1, x2, y2] = getClosestElementBounds(\n elements,\n viewportCoordsToSceneCoords(\n { clientX: appState.scrollX, clientY: appState.scrollY },\n appState,\n ),\n );\n }\n\n const centerX = (x1 + x2) / 2;\n const centerY = (y1 + y2) / 2;\n\n return centerScrollOn({\n scenePoint: { x: centerX, y: centerY },\n viewportDimensions: { width: appState.width, height: appState.height },\n zoom: appState.zoom,\n });\n};\n", "import { clamp, round } from \"@excalidraw/math\";\nimport { MAX_ZOOM, MIN_ZOOM } from \"../constants\";\nimport type { NormalizedZoomValue } from \"../types\";\n\nexport const getNormalizedZoom = (zoom: number): NormalizedZoomValue => {\n return clamp(round(zoom, 6), MIN_ZOOM, MAX_ZOOM) as NormalizedZoomValue;\n};\n\nexport const getNormalizedGridSize = (gridStep: number) => {\n return clamp(Math.round(gridStep), 1, 100);\n};\n\nexport const getNormalizedGridStep = (gridStep: number) => {\n return clamp(Math.round(gridStep), 1, 100);\n};\n", "import type {\n GroupId,\n ExcalidrawElement,\n NonDeleted,\n NonDeletedExcalidrawElement,\n ElementsMapOrArray,\n ElementsMap,\n} from \"./element/types\";\nimport type {\n AppClassProperties,\n AppState,\n InteractiveCanvasAppState,\n} from \"./types\";\nimport { getSelectedElements } from \"./scene\";\nimport { getBoundTextElement } from \"./element/textElement\";\nimport { makeNextSelectedElementIds } from \"./scene/selection\";\nimport type { Mutable } from \"./utility-types\";\n\nexport const selectGroup = (\n groupId: GroupId,\n appState: InteractiveCanvasAppState,\n elements: readonly NonDeleted<ExcalidrawElement>[],\n): Pick<\n InteractiveCanvasAppState,\n \"selectedGroupIds\" | \"selectedElementIds\" | \"editingGroupId\"\n> => {\n const elementsInGroup = elements.reduce(\n (acc: Record<string, true>, element) => {\n if (element.groupIds.includes(groupId)) {\n acc[element.id] = true;\n }\n return acc;\n },\n {},\n );\n\n if (Object.keys(elementsInGroup).length < 2) {\n if (\n appState.selectedGroupIds[groupId] ||\n appState.editingGroupId === groupId\n ) {\n return {\n selectedElementIds: appState.selectedElementIds,\n selectedGroupIds: { ...appState.selectedGroupIds, [groupId]: false },\n editingGroupId: null,\n };\n }\n return appState;\n }\n\n return {\n editingGroupId: appState.editingGroupId,\n selectedGroupIds: { ...appState.selectedGroupIds, [groupId]: true },\n selectedElementIds: {\n ...appState.selectedElementIds,\n ...elementsInGroup,\n },\n };\n};\n\nexport const selectGroupsForSelectedElements = (function () {\n type SelectGroupsReturnType = Pick<\n InteractiveCanvasAppState,\n \"selectedGroupIds\" | \"editingGroupId\" | \"selectedElementIds\"\n >;\n\n let lastSelectedElements: readonly NonDeleted<ExcalidrawElement>[] | null =\n null;\n let lastElements: readonly NonDeleted<ExcalidrawElement>[] | null = null;\n let lastReturnValue: SelectGroupsReturnType | null = null;\n\n const _selectGroups = (\n selectedElements: readonly NonDeleted<ExcalidrawElement>[],\n elements: readonly NonDeleted<ExcalidrawElement>[],\n appState: Pick<AppState, \"selectedElementIds\" | \"editingGroupId\">,\n prevAppState: InteractiveCanvasAppState,\n ): SelectGroupsReturnType => {\n if (\n lastReturnValue !== undefined &&\n elements === lastElements &&\n selectedElements === lastSelectedElements &&\n appState.editingGroupId === lastReturnValue?.editingGroupId\n ) {\n return lastReturnValue;\n }\n\n const selectedGroupIds: Record<GroupId, boolean> = {};\n // Gather all the groups withing selected elements\n for (const selectedElement of selectedElements) {\n let groupIds = selectedElement.groupIds;\n if (appState.editingGroupId) {\n // handle the case where a group is nested within a group\n const indexOfEditingGroup = groupIds.indexOf(appState.editingGroupId);\n if (indexOfEditingGroup > -1) {\n groupIds = groupIds.slice(0, indexOfEditingGroup);\n }\n }\n if (groupIds.length > 0) {\n const lastSelectedGroup = groupIds[groupIds.length - 1];\n selectedGroupIds[lastSelectedGroup] = true;\n }\n }\n\n // Gather all the elements within selected groups\n const groupElementsIndex: Record<GroupId, string[]> = {};\n const selectedElementIdsInGroups = elements.reduce(\n (acc: Record<string, true>, element) => {\n if (element.isDeleted) {\n return acc;\n }\n\n const groupId = element.groupIds.find((id) => selectedGroupIds[id]);\n\n if (groupId) {\n acc[element.id] = true;\n\n // Populate the index\n if (!Array.isArray(groupElementsIndex[groupId])) {\n groupElementsIndex[groupId] = [element.id];\n } else {\n groupElementsIndex[groupId].push(element.id);\n }\n }\n return acc;\n },\n {},\n );\n\n for (const groupId of Object.keys(groupElementsIndex)) {\n // If there is one element in the group, and the group is selected or it's being edited, it's not a group\n if (groupElementsIndex[groupId].length < 2) {\n if (selectedGroupIds[groupId]) {\n selectedGroupIds[groupId] = false;\n }\n }\n }\n\n lastElements = elements;\n lastSelectedElements = selectedElements;\n\n lastReturnValue = {\n editingGroupId: appState.editingGroupId,\n selectedGroupIds,\n selectedElementIds: makeNextSelectedElementIds(\n {\n ...appState.selectedElementIds,\n ...selectedElementIdsInGroups,\n },\n prevAppState,\n ),\n };\n\n return lastReturnValue;\n };\n\n /**\n * When you select an element, you often want to actually select the whole group it's in, unless\n * you're currently editing that group.\n */\n const selectGroupsForSelectedElements = (\n appState: Pick<AppState, \"selectedElementIds\" | \"editingGroupId\">,\n elements: readonly NonDeletedExcalidrawElement[],\n prevAppState: InteractiveCanvasAppState,\n /**\n * supply null in cases where you don't have access to App instance and\n * you don't care about optimizing selectElements retrieval\n */\n app: AppClassProperties | null,\n ): Mutable<\n Pick<\n InteractiveCanvasAppState,\n \"selectedGroupIds\" | \"editingGroupId\" | \"selectedElementIds\"\n >\n > => {\n const selectedElements = app\n ? app.scene.getSelectedElements({\n selectedElementIds: appState.selectedElementIds,\n // supplying elements explicitly in case we're passed non-state elements\n elements,\n })\n : getSelectedElements(elements, appState);\n\n if (!selectedElements.length) {\n return {\n selectedGroupIds: {},\n editingGroupId: null,\n selectedElementIds: makeNextSelectedElementIds(\n appState.selectedElementIds,\n prevAppState,\n ),\n };\n }\n\n return _selectGroups(selectedElements, elements, appState, prevAppState);\n };\n\n selectGroupsForSelectedElements.clearCache = () => {\n lastElements = null;\n lastSelectedElements = null;\n lastReturnValue = null;\n };\n\n return selectGroupsForSelectedElements;\n})();\n\n/**\n * If the element's group is selected, don't render an individual\n * selection border around it.\n */\nexport const isSelectedViaGroup = (\n appState: InteractiveCanvasAppState,\n element: ExcalidrawElement,\n) => getSelectedGroupForElement(appState, element) != null;\n\nexport const getSelectedGroupForElement = (\n appState: InteractiveCanvasAppState,\n element: ExcalidrawElement,\n) =>\n element.groupIds\n .filter((groupId) => groupId !== appState.editingGroupId)\n .find((groupId) => appState.selectedGroupIds[groupId]);\n\nexport const getSelectedGroupIds = (\n appState: InteractiveCanvasAppState,\n): GroupId[] =>\n Object.entries(appState.selectedGroupIds)\n .filter(([groupId, isSelected]) => isSelected)\n .map(([groupId, isSelected]) => groupId);\n\n// given a list of elements, return the the actual group ids that should be selected\n// or used to update the elements\nexport const selectGroupsFromGivenElements = (\n elements: readonly NonDeleted<ExcalidrawElement>[],\n appState: InteractiveCanvasAppState,\n) => {\n let nextAppState: InteractiveCanvasAppState = {\n ...appState,\n selectedGroupIds: {},\n };\n\n for (const element of elements) {\n let groupIds = element.groupIds;\n if (appState.editingGroupId) {\n const indexOfEditingGroup = groupIds.indexOf(appState.editingGroupId);\n if (indexOfEditingGroup > -1) {\n groupIds = groupIds.slice(0, indexOfEditingGroup);\n }\n }\n if (groupIds.length > 0) {\n const groupId = groupIds[groupIds.length - 1];\n nextAppState = {\n ...nextAppState,\n ...selectGroup(groupId, nextAppState, elements),\n };\n }\n }\n\n return nextAppState.selectedGroupIds;\n};\n\nexport const editGroupForSelectedElement = (\n appState: AppState,\n element: NonDeleted<ExcalidrawElement>,\n): AppState => {\n return {\n ...appState,\n editingGroupId: element.groupIds.length ? element.groupIds[0] : null,\n selectedGroupIds: {},\n selectedElementIds: {\n [element.id]: true,\n },\n };\n};\n\nexport const isElementInGroup = (element: ExcalidrawElement, groupId: string) =>\n element.groupIds.includes(groupId);\n\nexport const getElementsInGroup = (\n elements: ElementsMapOrArray,\n groupId: string,\n) => {\n const elementsInGroup: ExcalidrawElement[] = [];\n for (const element of elements.values()) {\n if (isElementInGroup(element, groupId)) {\n elementsInGroup.push(element);\n }\n }\n return elementsInGroup;\n};\n\nexport const getSelectedGroupIdForElement = (\n element: ExcalidrawElement,\n selectedGroupIds: { [groupId: string]: boolean },\n) => element.groupIds.find((groupId) => selectedGroupIds[groupId]);\n\nexport const getNewGroupIdsForDuplication = (\n groupIds: ExcalidrawElement[\"groupIds\"],\n editingGroupId: AppState[\"editingGroupId\"],\n mapper: (groupId: GroupId) => GroupId,\n) => {\n const copy = [...groupIds];\n const positionOfEditingGroupId = editingGroupId\n ? groupIds.indexOf(editingGroupId)\n : -1;\n const endIndex =\n positionOfEditingGroupId > -1 ? positionOfEditingGroupId : groupIds.length;\n for (let index = 0; index < endIndex; index++) {\n copy[index] = mapper(copy[index]);\n }\n\n return copy;\n};\n\nexport const addToGroup = (\n prevGroupIds: ExcalidrawElement[\"groupIds\"],\n newGroupId: GroupId,\n editingGroupId: AppState[\"editingGroupId\"],\n) => {\n // insert before the editingGroupId, or push to the end.\n const groupIds = [...prevGroupIds];\n const positionOfEditingGroupId = editingGroupId\n ? groupIds.indexOf(editingGroupId)\n : -1;\n const positionToInsert =\n positionOfEditingGroupId > -1 ? positionOfEditingGroupId : groupIds.length;\n groupIds.splice(positionToInsert, 0, newGroupId);\n return groupIds;\n};\n\nexport const removeFromSelectedGroups = (\n groupIds: ExcalidrawElement[\"groupIds\"],\n selectedGroupIds: { [groupId: string]: boolean },\n) => groupIds.filter((groupId) => !selectedGroupIds[groupId]);\n\nexport const getMaximumGroups = (\n elements: ExcalidrawElement[],\n elementsMap: ElementsMap,\n): ExcalidrawElement[][] => {\n const groups: Map<String, ExcalidrawElement[]> = new Map<\n String,\n ExcalidrawElement[]\n >();\n elements.forEach((element: ExcalidrawElement) => {\n const groupId =\n element.groupIds.length === 0\n ? element.id\n : element.groupIds[element.groupIds.length - 1];\n\n const currentGroupMembers = groups.get(groupId) || [];\n\n // Include bound text if present when grouping\n const boundTextElement = getBoundTextElement(element, elementsMap);\n if (boundTextElement) {\n currentGroupMembers.push(boundTextElement);\n }\n groups.set(groupId, [...currentGroupMembers, element]);\n });\n\n return Array.from(groups.values());\n};\n\nexport const getNonDeletedGroupIds = (elements: ElementsMap) => {\n const nonDeletedGroupIds = new Set<string>();\n\n for (const [, element] of elements) {\n // defensive check\n if (element.isDeleted) {\n continue;\n }\n\n // defensive fallback\n for (const groupId of element.groupIds ?? []) {\n nonDeletedGroupIds.add(groupId);\n }\n }\n\n return nonDeletedGroupIds;\n};\n\nexport const elementsAreInSameGroup = (\n elements: readonly ExcalidrawElement[],\n) => {\n const allGroups = elements.flatMap((element) => element.groupIds);\n const groupCount = new Map<string, number>();\n let maxGroup = 0;\n\n for (const group of allGroups) {\n groupCount.set(group, (groupCount.get(group) ?? 0) + 1);\n if (groupCount.get(group)! > maxGroup) {\n maxGroup = groupCount.get(group)!;\n }\n }\n\n return maxGroup === elements.length;\n};\n\nexport const isInGroup = (element: NonDeletedExcalidrawElement) => {\n return element.groupIds.length > 0;\n};\n", "import type { InclusiveRange } from \"@excalidraw/math\";\nimport {\n pointFrom,\n pointRotateRads,\n rangeInclusive,\n rangeIntersection,\n rangesOverlap,\n type GlobalPoint,\n} from \"@excalidraw/math\";\nimport { TOOL_TYPE } from \"./constants\";\nimport type { Bounds } from \"./element/bounds\";\nimport {\n getCommonBounds,\n getDraggedElementsBounds,\n getElementAbsoluteCoords,\n} from \"./element/bounds\";\nimport type { MaybeTransformHandleType } from \"./element/transformHandles\";\nimport { isBoundToContainer, isFrameLikeElement } from \"./element/typeChecks\";\nimport type {\n ElementsMap,\n ExcalidrawElement,\n NonDeletedExcalidrawElement,\n} from \"./element/types\";\nimport { getMaximumGroups } from \"./groups\";\nimport { KEYS } from \"./keys\";\nimport {\n getSelectedElements,\n getVisibleAndNonSelectedElements,\n} from \"./scene/selection\";\nimport type {\n AppClassProperties,\n AppState,\n KeyboardModifiersObject,\n NullableGridSize,\n} from \"./types\";\n\nconst SNAP_DISTANCE = 8;\n\n// do not comput more gaps per axis than this limit\n// TODO increase or remove once we optimize\nconst VISIBLE_GAPS_LIMIT_PER_AXIS = 99999;\n\n// snap distance with zoom value taken into consideration\nexport const getSnapDistance = (zoomValue: number) => {\n return SNAP_DISTANCE / zoomValue;\n};\n\ntype Vector2D = {\n x: number;\n y: number;\n};\n\ntype PointPair = [GlobalPoint, GlobalPoint];\n\nexport type PointSnap = {\n type: \"point\";\n points: PointPair;\n offset: number;\n};\n\nexport type Gap = {\n // start side \u2193 length\n // \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\u25C4\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25BA\n // \u2502 \u2502-----------------\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n // \u2502 start \u2502 \u2191 \u2502 \u2502\n // \u2502 element \u2502 overlap \u2502 end \u2502\n // \u2502 \u2502 \u2193 \u2502 element \u2502\n // \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518-----------------\u2502 \u2502\n // \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n // \u2191 end side\n startBounds: Bounds;\n endBounds: Bounds;\n startSide: [GlobalPoint, GlobalPoint];\n endSide: [GlobalPoint, GlobalPoint];\n overlap: InclusiveRange;\n length: number;\n};\n\nexport type GapSnap = {\n type: \"gap\";\n direction:\n | \"center_horizontal\"\n | \"center_vertical\"\n | \"side_left\"\n | \"side_right\"\n | \"side_top\"\n | \"side_bottom\";\n gap: Gap;\n offset: number;\n};\n\nexport type GapSnaps = GapSnap[];\n\nexport type Snap = GapSnap | PointSnap;\nexport type Snaps = Snap[];\n\nexport type PointSnapLine = {\n type: \"points\";\n points: GlobalPoint[];\n};\n\nexport type PointerSnapLine = {\n type: \"pointer\";\n points: PointPair;\n direction: \"horizontal\" | \"vertical\";\n};\n\nexport type GapSnapLine = {\n type: \"gap\";\n direction: \"horizontal\" | \"vertical\";\n points: PointPair;\n};\n\nexport type SnapLine = PointSnapLine | GapSnapLine | PointerSnapLine;\n\n// -----------------------------------------------------------------------------\n\nexport class SnapCache {\n private static referenceSnapPoints: GlobalPoint[] | null = null;\n\n private static visibleGaps: {\n verticalGaps: Gap[];\n horizontalGaps: Gap[];\n } | null = null;\n\n public static setReferenceSnapPoints = (snapPoints: GlobalPoint[] | null) => {\n SnapCache.referenceSnapPoints = snapPoints;\n };\n\n public static getReferenceSnapPoints = () => {\n return SnapCache.referenceSnapPoints;\n };\n\n public static setVisibleGaps = (\n gaps: {\n verticalGaps: Gap[];\n horizontalGaps: Gap[];\n } | null,\n ) => {\n SnapCache.visibleGaps = gaps;\n };\n\n public static getVisibleGaps = () => {\n return SnapCache.visibleGaps;\n };\n\n public static destroy = () => {\n SnapCache.referenceSnapPoints = null;\n SnapCache.visibleGaps = null;\n };\n}\n\n// -----------------------------------------------------------------------------\n\nexport const isGridModeEnabled = (app: AppClassProperties): boolean =>\n app.props.gridModeEnabled ?? app.state.gridModeEnabled;\n\nexport const isSnappingEnabled = ({\n event,\n app,\n selectedElements,\n}: {\n app: AppClassProperties;\n event: KeyboardModifiersObject;\n selectedElements: NonDeletedExcalidrawElement[];\n}) => {\n if (event) {\n return (\n (app.state.objectsSnapModeEnabled && !event[KEYS.CTRL_OR_CMD]) ||\n (!app.state.objectsSnapModeEnabled &&\n event[KEYS.CTRL_OR_CMD] &&\n !isGridModeEnabled(app))\n );\n }\n\n // do not suggest snaps for an arrow to give way to binding\n if (selectedElements.length === 1 && selectedElements[0].type === \"arrow\") {\n return false;\n }\n return app.state.objectsSnapModeEnabled;\n};\n\nexport const areRoughlyEqual = (a: number, b: number, precision = 0.01) => {\n return Math.abs(a - b) <= precision;\n};\n\nexport const getElementsCorners = (\n elements: ExcalidrawElement[],\n elementsMap: ElementsMap,\n {\n omitCenter,\n boundingBoxCorners,\n dragOffset,\n }: {\n omitCenter?: boolean;\n boundingBoxCorners?: boolean;\n dragOffset?: Vector2D;\n } = {\n omitCenter: false,\n boundingBoxCorners: false,\n },\n): GlobalPoint[] => {\n let result: GlobalPoint[] = [];\n\n if (elements.length === 1) {\n const element = elements[0];\n\n let [x1, y1, x2, y2, cx, cy] = getElementAbsoluteCoords(\n element,\n elementsMap,\n );\n\n if (dragOffset) {\n x1 += dragOffset.x;\n x2 += dragOffset.x;\n cx += dragOffset.x;\n\n y1 += dragOffset.y;\n y2 += dragOffset.y;\n cy += dragOffset.y;\n }\n\n const halfWidth = (x2 - x1) / 2;\n const halfHeight = (y2 - y1) / 2;\n\n if (\n (element.type === \"diamond\" || element.type === \"ellipse\") &&\n !boundingBoxCorners\n ) {\n const leftMid = pointRotateRads<GlobalPoint>(\n pointFrom(x1, y1 + halfHeight),\n pointFrom(cx, cy),\n element.angle,\n );\n const topMid = pointRotateRads<GlobalPoint>(\n pointFrom(x1 + halfWidth, y1),\n pointFrom(cx, cy),\n element.angle,\n );\n const rightMid = pointRotateRads<GlobalPoint>(\n pointFrom(x2, y1 + halfHeight),\n pointFrom(cx, cy),\n element.angle,\n );\n const bottomMid = pointRotateRads<GlobalPoint>(\n pointFrom(x1 + halfWidth, y2),\n pointFrom(cx, cy),\n element.angle,\n );\n const center = pointFrom<GlobalPoint>(cx, cy);\n\n result = omitCenter\n ? [leftMid, topMid, rightMid, bottomMid]\n : [leftMid, topMid, rightMid, bottomMid, center];\n } else {\n const topLeft = pointRotateRads<GlobalPoint>(\n pointFrom(x1, y1),\n pointFrom(cx, cy),\n element.angle,\n );\n const topRight = pointRotateRads<GlobalPoint>(\n pointFrom(x2, y1),\n pointFrom(cx, cy),\n element.angle,\n );\n const bottomLeft = pointRotateRads<GlobalPoint>(\n pointFrom(x1, y2),\n pointFrom(cx, cy),\n element.angle,\n );\n const bottomRight = pointRotateRads<GlobalPoint>(\n pointFrom(x2, y2),\n pointFrom(cx, cy),\n element.angle,\n );\n const center = pointFrom<GlobalPoint>(cx, cy);\n\n result = omitCenter\n ? [topLeft, topRight, bottomLeft, bottomRight]\n : [topLeft, topRight, bottomLeft, bottomRight, center];\n }\n } else if (elements.length > 1) {\n const [minX, minY, maxX, maxY] = getDraggedElementsBounds(\n elements,\n dragOffset ?? { x: 0, y: 0 },\n );\n const width = maxX - minX;\n const height = maxY - minY;\n\n const topLeft = pointFrom<GlobalPoint>(minX, minY);\n const topRight = pointFrom<GlobalPoint>(maxX, minY);\n const bottomLeft = pointFrom<GlobalPoint>(minX, maxY);\n const bottomRight = pointFrom<GlobalPoint>(maxX, maxY);\n const center = pointFrom<GlobalPoint>(minX + width / 2, minY + height / 2);\n\n result = omitCenter\n ? [topLeft, topRight, bottomLeft, bottomRight]\n : [topLeft, topRight, bottomLeft, bottomRight, center];\n }\n\n return result.map((p) => pointFrom(round(p[0]), round(p[1])));\n};\n\nconst getReferenceElements = (\n elements: readonly NonDeletedExcalidrawElement[],\n selectedElements: NonDeletedExcalidrawElement[],\n appState: AppState,\n elementsMap: ElementsMap,\n) => {\n const selectedFrames = selectedElements\n .filter((element) => isFrameLikeElement(element))\n .map((frame) => frame.id);\n\n return getVisibleAndNonSelectedElements(\n elements,\n selectedElements,\n appState,\n elementsMap,\n ).filter(\n (element) => !(element.frameId && selectedFrames.includes(element.frameId)),\n );\n};\n\nexport const getVisibleGaps = (\n elements: readonly NonDeletedExcalidrawElement[],\n selectedElements: ExcalidrawElement[],\n appState: AppState,\n elementsMap: ElementsMap,\n) => {\n const referenceElements: ExcalidrawElement[] = getReferenceElements(\n elements,\n selectedElements,\n appState,\n elementsMap,\n );\n\n const referenceBounds = getMaximumGroups(referenceElements, elementsMap)\n .filter(\n (elementsGroup) =>\n !(elementsGroup.length === 1 && isBoundToContainer(elementsGroup[0])),\n )\n .map(\n (group) =>\n getCommonBounds(group).map((bound) =>\n round(bound),\n ) as unknown as Bounds,\n );\n\n const horizontallySorted = referenceBounds.sort((a, b) => a[0] - b[0]);\n\n const horizontalGaps: Gap[] = [];\n\n let c = 0;\n\n horizontal: for (let i = 0; i < horizontallySorted.length; i++) {\n const startBounds = horizontallySorted[i];\n\n for (let j = i + 1; j < horizontallySorted.length; j++) {\n if (++c > VISIBLE_GAPS_LIMIT_PER_AXIS) {\n break horizontal;\n }\n\n const endBounds = horizontallySorted[j];\n\n const [, startMinY, startMaxX, startMaxY] = startBounds;\n const [endMinX, endMinY, , endMaxY] = endBounds;\n\n if (\n startMaxX < endMinX &&\n rangesOverlap(\n rangeInclusive(startMinY, startMaxY),\n rangeInclusive(endMinY, endMaxY),\n )\n ) {\n horizontalGaps.push({\n startBounds,\n endBounds,\n startSide: [\n pointFrom(startMaxX, startMinY),\n pointFrom(startMaxX, startMaxY),\n ],\n endSide: [pointFrom(endMinX, endMinY), pointFrom(endMinX, endMaxY)],\n length: endMinX - startMaxX,\n overlap: rangeIntersection(\n rangeInclusive(startMinY, startMaxY),\n rangeInclusive(endMinY, endMaxY),\n )!,\n });\n }\n }\n }\n\n const verticallySorted = referenceBounds.sort((a, b) => a[1] - b[1]);\n\n const verticalGaps: Gap[] = [];\n\n c = 0;\n\n vertical: for (let i = 0; i < verticallySorted.length; i++) {\n const startBounds = verticallySorted[i];\n\n for (let j = i + 1; j < verticallySorted.length; j++) {\n if (++c > VISIBLE_GAPS_LIMIT_PER_AXIS) {\n break vertical;\n }\n const endBounds = verticallySorted[j];\n\n const [startMinX, , startMaxX, startMaxY] = startBounds;\n const [endMinX, endMinY, endMaxX] = endBounds;\n\n if (\n startMaxY < endMinY &&\n rangesOverlap(\n rangeInclusive(startMinX, startMaxX),\n rangeInclusive(endMinX, endMaxX),\n )\n ) {\n verticalGaps.push({\n startBounds,\n endBounds,\n startSide: [\n pointFrom(startMinX, startMaxY),\n pointFrom(startMaxX, startMaxY),\n ],\n endSide: [pointFrom(endMinX, endMinY), pointFrom(endMaxX, endMinY)],\n length: endMinY - startMaxY,\n overlap: rangeIntersection(\n rangeInclusive(startMinX, startMaxX),\n rangeInclusive(endMinX, endMaxX),\n )!,\n });\n }\n }\n }\n\n return {\n horizontalGaps,\n verticalGaps,\n };\n};\n\nconst getGapSnaps = (\n selectedElements: ExcalidrawElement[],\n dragOffset: Vector2D,\n app: AppClassProperties,\n event: KeyboardModifiersObject,\n nearestSnapsX: Snaps,\n nearestSnapsY: Snaps,\n minOffset: Vector2D,\n) => {\n if (!isSnappingEnabled({ app, event, selectedElements })) {\n return [];\n }\n\n if (selectedElements.length === 0) {\n return [];\n }\n\n const visibleGaps = SnapCache.getVisibleGaps();\n\n if (visibleGaps) {\n const { horizontalGaps, verticalGaps } = visibleGaps;\n\n const [minX, minY, maxX, maxY] = getDraggedElementsBounds(\n selectedElements,\n dragOffset,\n ).map((bound) => round(bound));\n const centerX = (minX + maxX) / 2;\n const centerY = (minY + maxY) / 2;\n\n for (const gap of horizontalGaps) {\n if (!rangesOverlap(rangeInclusive(minY, maxY), gap.overlap)) {\n continue;\n }\n\n // center gap\n const gapMidX = gap.startSide[0][0] + gap.length / 2;\n const centerOffset = round(gapMidX - centerX);\n const gapIsLargerThanSelection = gap.length > maxX - minX;\n\n if (gapIsLargerThanSelection && Math.abs(centerOffset) <= minOffset.x) {\n if (Math.abs(centerOffset) < minOffset.x) {\n nearestSnapsX.length = 0;\n }\n minOffset.x = Math.abs(centerOffset);\n\n const snap: GapSnap = {\n type: \"gap\",\n direction: \"center_horizontal\",\n gap,\n offset: centerOffset,\n };\n\n nearestSnapsX.push(snap);\n continue;\n }\n\n // side gap, from the right\n const [, , endMaxX] = gap.endBounds;\n const distanceToEndElementX = minX - endMaxX;\n const sideOffsetRight = round(gap.length - distanceToEndElementX);\n\n if (Math.abs(sideOffsetRight) <= minOffset.x) {\n if (Math.abs(sideOffsetRight) < minOffset.x) {\n nearestSnapsX.length = 0;\n }\n minOffset.x = Math.abs(sideOffsetRight);\n\n const snap: GapSnap = {\n type: \"gap\",\n direction: \"side_right\",\n gap,\n offset: sideOffsetRight,\n };\n nearestSnapsX.push(snap);\n continue;\n }\n\n // side gap, from the left\n const [startMinX, , ,] = gap.startBounds;\n const distanceToStartElementX = startMinX - maxX;\n const sideOffsetLeft = round(distanceToStartElementX - gap.length);\n\n if (Math.abs(sideOffsetLeft) <= minOffset.x) {\n if (Math.abs(sideOffsetLeft) < minOffset.x) {\n nearestSnapsX.length = 0;\n }\n minOffset.x = Math.abs(sideOffsetLeft);\n\n const snap: GapSnap = {\n type: \"gap\",\n direction: \"side_left\",\n gap,\n offset: sideOffsetLeft,\n };\n nearestSnapsX.push(snap);\n continue;\n }\n }\n for (const gap of verticalGaps) {\n if (!rangesOverlap(rangeInclusive(minX, maxX), gap.overlap)) {\n continue;\n }\n\n // center gap\n const gapMidY = gap.startSide[0][1] + gap.length / 2;\n const centerOffset = round(gapMidY - centerY);\n const gapIsLargerThanSelection = gap.length > maxY - minY;\n\n if (gapIsLargerThanSelection && Math.abs(centerOffset) <= minOffset.y) {\n if (Math.abs(centerOffset) < minOffset.y) {\n nearestSnapsY.length = 0;\n }\n minOffset.y = Math.abs(centerOffset);\n\n const snap: GapSnap = {\n type: \"gap\",\n direction: \"center_vertical\",\n gap,\n offset: centerOffset,\n };\n\n nearestSnapsY.push(snap);\n continue;\n }\n\n // side gap, from the top\n const [, startMinY, ,] = gap.startBounds;\n const distanceToStartElementY = startMinY - maxY;\n const sideOffsetTop = round(distanceToStartElementY - gap.length);\n\n if (Math.abs(sideOffsetTop) <= minOffset.y) {\n if (Math.abs(sideOffsetTop) < minOffset.y) {\n nearestSnapsY.length = 0;\n }\n minOffset.y = Math.abs(sideOffsetTop);\n\n const snap: GapSnap = {\n type: \"gap\",\n direction: \"side_top\",\n gap,\n offset: sideOffsetTop,\n };\n nearestSnapsY.push(snap);\n continue;\n }\n\n // side gap, from the bottom\n const [, , , endMaxY] = gap.endBounds;\n const distanceToEndElementY = round(minY - endMaxY);\n const sideOffsetBottom = gap.length - distanceToEndElementY;\n\n if (Math.abs(sideOffsetBottom) <= minOffset.y) {\n if (Math.abs(sideOffsetBottom) < minOffset.y) {\n nearestSnapsY.length = 0;\n }\n minOffset.y = Math.abs(sideOffsetBottom);\n\n const snap: GapSnap = {\n type: \"gap\",\n direction: \"side_bottom\",\n gap,\n offset: sideOffsetBottom,\n };\n nearestSnapsY.push(snap);\n continue;\n }\n }\n }\n};\n\nexport const getReferenceSnapPoints = (\n elements: readonly NonDeletedExcalidrawElement[],\n selectedElements: ExcalidrawElement[],\n appState: AppState,\n elementsMap: ElementsMap,\n) => {\n const referenceElements = getReferenceElements(\n elements,\n selectedElements,\n appState,\n elementsMap,\n );\n return getMaximumGroups(referenceElements, elementsMap)\n .filter(\n (elementsGroup) =>\n !(elementsGroup.length === 1 && isBoundToContainer(elementsGroup[0])),\n )\n .flatMap((elementGroup) => getElementsCorners(elementGroup, elementsMap));\n};\n\nconst getPointSnaps = (\n selectedElements: ExcalidrawElement[],\n selectionSnapPoints: GlobalPoint[],\n app: AppClassProperties,\n event: KeyboardModifiersObject,\n nearestSnapsX: Snaps,\n nearestSnapsY: Snaps,\n minOffset: Vector2D,\n) => {\n if (\n !isSnappingEnabled({ app, event, selectedElements }) ||\n (selectedElements.length === 0 && selectionSnapPoints.length === 0)\n ) {\n return [];\n }\n\n const referenceSnapPoints = SnapCache.getReferenceSnapPoints();\n\n if (referenceSnapPoints) {\n for (const thisSnapPoint of selectionSnapPoints) {\n for (const otherSnapPoint of referenceSnapPoints) {\n const offsetX = otherSnapPoint[0] - thisSnapPoint[0];\n const offsetY = otherSnapPoint[1] - thisSnapPoint[1];\n\n if (Math.abs(offsetX) <= minOffset.x) {\n if (Math.abs(offsetX) < minOffset.x) {\n nearestSnapsX.length = 0;\n }\n\n nearestSnapsX.push({\n type: \"point\",\n points: [thisSnapPoint, otherSnapPoint],\n offset: offsetX,\n });\n\n minOffset.x = Math.abs(offsetX);\n }\n\n if (Math.abs(offsetY) <= minOffset.y) {\n if (Math.abs(offsetY) < minOffset.y) {\n nearestSnapsY.length = 0;\n }\n\n nearestSnapsY.push({\n type: \"point\",\n points: [thisSnapPoint, otherSnapPoint],\n offset: offsetY,\n });\n\n minOffset.y = Math.abs(offsetY);\n }\n }\n }\n }\n};\n\nexport const snapDraggedElements = (\n elements: ExcalidrawElement[],\n dragOffset: Vector2D,\n app: AppClassProperties,\n event: KeyboardModifiersObject,\n elementsMap: ElementsMap,\n) => {\n const appState = app.state;\n const selectedElements = getSelectedElements(elements, appState);\n if (\n !isSnappingEnabled({ app, event, selectedElements }) ||\n selectedElements.length === 0\n ) {\n return {\n snapOffset: {\n x: 0,\n y: 0,\n },\n snapLines: [],\n };\n }\n dragOffset.x = round(dragOffset.x);\n dragOffset.y = round(dragOffset.y);\n const nearestSnapsX: Snaps = [];\n const nearestSnapsY: Snaps = [];\n const snapDistance = getSnapDistance(appState.zoom.value);\n const minOffset = {\n x: snapDistance,\n y: snapDistance,\n };\n\n const selectionPoints = getElementsCorners(selectedElements, elementsMap, {\n dragOffset,\n });\n\n // get the nearest horizontal and vertical point and gap snaps\n getPointSnaps(\n selectedElements,\n selectionPoints,\n app,\n event,\n nearestSnapsX,\n nearestSnapsY,\n minOffset,\n );\n\n getGapSnaps(\n selectedElements,\n dragOffset,\n app,\n event,\n nearestSnapsX,\n nearestSnapsY,\n minOffset,\n );\n\n // using the nearest snaps to figure out how\n // much the elements need to be offset to be snapped\n // to some reference elements\n const snapOffset = {\n x: nearestSnapsX[0]?.offset ?? 0,\n y: nearestSnapsY[0]?.offset ?? 0,\n };\n\n // once the elements are snapped\n // and moved to the snapped position\n // we want to use the element's snapped position\n // to update nearest snaps so that we can create\n // point and gap snap lines correctly without any shifting\n\n minOffset.x = 0;\n minOffset.y = 0;\n nearestSnapsX.length = 0;\n nearestSnapsY.length = 0;\n const newDragOffset = {\n x: round(dragOffset.x + snapOffset.x),\n y: round(dragOffset.y + snapOffset.y),\n };\n\n getPointSnaps(\n selectedElements,\n getElementsCorners(selectedElements, elementsMap, {\n dragOffset: newDragOffset,\n }),\n app,\n event,\n nearestSnapsX,\n nearestSnapsY,\n minOffset,\n );\n\n getGapSnaps(\n selectedElements,\n newDragOffset,\n app,\n event,\n nearestSnapsX,\n nearestSnapsY,\n minOffset,\n );\n\n const pointSnapLines = createPointSnapLines(nearestSnapsX, nearestSnapsY);\n\n const gapSnapLines = createGapSnapLines(\n selectedElements,\n newDragOffset,\n [...nearestSnapsX, ...nearestSnapsY].filter(\n (snap) => snap.type === \"gap\",\n ) as GapSnap[],\n );\n\n return {\n snapOffset,\n snapLines: [...pointSnapLines, ...gapSnapLines],\n };\n};\n\nconst round = (x: number) => {\n const decimalPlaces = 6;\n return Math.round(x * 10 ** decimalPlaces) / 10 ** decimalPlaces;\n};\n\nconst dedupePoints = (points: GlobalPoint[]): GlobalPoint[] => {\n const map = new Map<string, GlobalPoint>();\n\n for (const point of points) {\n const key = point.join(\",\");\n\n if (!map.has(key)) {\n map.set(key, point);\n }\n }\n\n return Array.from(map.values());\n};\n\nconst createPointSnapLines = (\n nearestSnapsX: Snaps,\n nearestSnapsY: Snaps,\n): PointSnapLine[] => {\n const snapsX = {} as { [key: string]: GlobalPoint[] };\n const snapsY = {} as { [key: string]: GlobalPoint[] };\n\n if (nearestSnapsX.length > 0) {\n for (const snap of nearestSnapsX) {\n if (snap.type === \"point\") {\n // key = thisPoint.x\n const key = round(snap.points[0][0]);\n if (!snapsX[key]) {\n snapsX[key] = [];\n }\n snapsX[key].push(\n ...snap.points.map((p) =>\n pointFrom<GlobalPoint>(round(p[0]), round(p[1])),\n ),\n );\n }\n }\n }\n\n if (nearestSnapsY.length > 0) {\n for (const snap of nearestSnapsY) {\n if (snap.type === \"point\") {\n // key = thisPoint.y\n const key = round(snap.points[0][1]);\n if (!snapsY[key]) {\n snapsY[key] = [];\n }\n snapsY[key].push(\n ...snap.points.map((p) =>\n pointFrom<GlobalPoint>(round(p[0]), round(p[1])),\n ),\n );\n }\n }\n }\n\n return Object.entries(snapsX)\n .map(([key, points]) => {\n return {\n type: \"points\",\n points: dedupePoints(\n points\n .map((p) => {\n return pointFrom<GlobalPoint>(Number(key), p[1]);\n })\n .sort((a, b) => a[1] - b[1]),\n ),\n } as PointSnapLine;\n })\n .concat(\n Object.entries(snapsY).map(([key, points]) => {\n return {\n type: \"points\",\n points: dedupePoints(\n points\n .map((p) => {\n return pointFrom<GlobalPoint>(p[0], Number(key));\n })\n .sort((a, b) => a[0] - b[0]),\n ),\n } as PointSnapLine;\n }),\n );\n};\n\nconst dedupeGapSnapLines = (gapSnapLines: GapSnapLine[]) => {\n const map = new Map<string, GapSnapLine>();\n\n for (const gapSnapLine of gapSnapLines) {\n const key = gapSnapLine.points\n .flat()\n .map((point) => [round(point)])\n .join(\",\");\n\n if (!map.has(key)) {\n map.set(key, gapSnapLine);\n }\n }\n\n return Array.from(map.values());\n};\n\nconst createGapSnapLines = (\n selectedElements: ExcalidrawElement[],\n dragOffset: Vector2D,\n gapSnaps: GapSnap[],\n): GapSnapLine[] => {\n const [minX, minY, maxX, maxY] = getDraggedElementsBounds(\n selectedElements,\n dragOffset,\n );\n\n const gapSnapLines: GapSnapLine[] = [];\n\n for (const gapSnap of gapSnaps) {\n const [startMinX, startMinY, startMaxX, startMaxY] =\n gapSnap.gap.startBounds;\n const [endMinX, endMinY, endMaxX, endMaxY] = gapSnap.gap.endBounds;\n\n const verticalIntersection = rangeIntersection(\n rangeInclusive(minY, maxY),\n gapSnap.gap.overlap,\n );\n\n const horizontalGapIntersection = rangeIntersection(\n rangeInclusive(minX, maxX),\n gapSnap.gap.overlap,\n );\n\n switch (gapSnap.direction) {\n case \"center_horizontal\": {\n if (verticalIntersection) {\n const gapLineY =\n (verticalIntersection[0] + verticalIntersection[1]) / 2;\n\n gapSnapLines.push(\n {\n type: \"gap\",\n direction: \"horizontal\",\n points: [\n pointFrom(gapSnap.gap.startSide[0][0], gapLineY),\n pointFrom(minX, gapLineY),\n ],\n },\n {\n type: \"gap\",\n direction: \"horizontal\",\n points: [\n pointFrom(maxX, gapLineY),\n pointFrom(gapSnap.gap.endSide[0][0], gapLineY),\n ],\n },\n );\n }\n break;\n }\n case \"center_vertical\": {\n if (horizontalGapIntersection) {\n const gapLineX =\n (horizontalGapIntersection[0] + horizontalGapIntersection[1]) / 2;\n\n gapSnapLines.push(\n {\n type: \"gap\",\n direction: \"vertical\",\n points: [\n pointFrom(gapLineX, gapSnap.gap.startSide[0][1]),\n pointFrom(gapLineX, minY),\n ],\n },\n {\n type: \"gap\",\n direction: \"vertical\",\n points: [\n pointFrom(gapLineX, maxY),\n pointFrom(gapLineX, gapSnap.gap.endSide[0][1]),\n ],\n },\n );\n }\n break;\n }\n case \"side_right\": {\n if (verticalIntersection) {\n const gapLineY =\n (verticalIntersection[0] + verticalIntersection[1]) / 2;\n\n gapSnapLines.push(\n {\n type: \"gap\",\n direction: \"horizontal\",\n points: [\n pointFrom(startMaxX, gapLineY),\n pointFrom(endMinX, gapLineY),\n ],\n },\n {\n type: \"gap\",\n direction: \"horizontal\",\n points: [pointFrom(endMaxX, gapLineY), pointFrom(minX, gapLineY)],\n },\n );\n }\n break;\n }\n case \"side_left\": {\n if (verticalIntersection) {\n const gapLineY =\n (verticalIntersection[0] + verticalIntersection[1]) / 2;\n\n gapSnapLines.push(\n {\n type: \"gap\",\n direction: \"horizontal\",\n points: [\n pointFrom(maxX, gapLineY),\n pointFrom(startMinX, gapLineY),\n ],\n },\n {\n type: \"gap\",\n direction: \"horizontal\",\n points: [\n pointFrom(startMaxX, gapLineY),\n pointFrom(endMinX, gapLineY),\n ],\n },\n );\n }\n break;\n }\n case \"side_top\": {\n if (horizontalGapIntersection) {\n const gapLineX =\n (horizontalGapIntersection[0] + horizontalGapIntersection[1]) / 2;\n\n gapSnapLines.push(\n {\n type: \"gap\",\n direction: \"vertical\",\n points: [\n pointFrom(gapLineX, maxY),\n pointFrom(gapLineX, startMinY),\n ],\n },\n {\n type: \"gap\",\n direction: \"vertical\",\n points: [\n pointFrom(gapLineX, startMaxY),\n pointFrom(gapLineX, endMinY),\n ],\n },\n );\n }\n break;\n }\n case \"side_bottom\": {\n if (horizontalGapIntersection) {\n const gapLineX =\n (horizontalGapIntersection[0] + horizontalGapIntersection[1]) / 2;\n\n gapSnapLines.push(\n {\n type: \"gap\",\n direction: \"vertical\",\n points: [\n pointFrom(gapLineX, startMaxY),\n pointFrom(gapLineX, endMinY),\n ],\n },\n {\n type: \"gap\",\n direction: \"vertical\",\n points: [pointFrom(gapLineX, endMaxY), pointFrom(gapLineX, minY)],\n },\n );\n }\n break;\n }\n }\n }\n\n return dedupeGapSnapLines(\n gapSnapLines.map((gapSnapLine) => {\n return {\n ...gapSnapLine,\n points: gapSnapLine.points.map((p) =>\n pointFrom(round(p[0]), round(p[1])),\n ) as PointPair,\n };\n }),\n );\n};\n\nexport const snapResizingElements = (\n // use the latest elements to create snap lines\n selectedElements: ExcalidrawElement[],\n // while using the original elements to appy dragOffset to calculate snaps\n selectedOriginalElements: ExcalidrawElement[],\n app: AppClassProperties,\n event: KeyboardModifiersObject,\n dragOffset: Vector2D,\n transformHandle: MaybeTransformHandleType,\n) => {\n if (\n !isSnappingEnabled({ event, selectedElements, app }) ||\n selectedElements.length === 0 ||\n (selectedElements.length === 1 &&\n !areRoughlyEqual(selectedElements[0].angle, 0))\n ) {\n return {\n snapOffset: { x: 0, y: 0 },\n snapLines: [],\n };\n }\n\n let [minX, minY, maxX, maxY] = getCommonBounds(selectedOriginalElements);\n\n if (transformHandle) {\n if (transformHandle.includes(\"e\")) {\n maxX += dragOffset.x;\n } else if (transformHandle.includes(\"w\")) {\n minX += dragOffset.x;\n }\n\n if (transformHandle.includes(\"n\")) {\n minY += dragOffset.y;\n } else if (transformHandle.includes(\"s\")) {\n maxY += dragOffset.y;\n }\n }\n\n const selectionSnapPoints: GlobalPoint[] = [];\n\n if (transformHandle) {\n switch (transformHandle) {\n case \"e\": {\n selectionSnapPoints.push(pointFrom(maxX, minY), pointFrom(maxX, maxY));\n break;\n }\n case \"w\": {\n selectionSnapPoints.push(pointFrom(minX, minY), pointFrom(minX, maxY));\n break;\n }\n case \"n\": {\n selectionSnapPoints.push(pointFrom(minX, minY), pointFrom(maxX, minY));\n break;\n }\n case \"s\": {\n selectionSnapPoints.push(pointFrom(minX, maxY), pointFrom(maxX, maxY));\n break;\n }\n case \"ne\": {\n selectionSnapPoints.push(pointFrom(maxX, minY));\n break;\n }\n case \"nw\": {\n selectionSnapPoints.push(pointFrom(minX, minY));\n break;\n }\n case \"se\": {\n selectionSnapPoints.push(pointFrom(maxX, maxY));\n break;\n }\n case \"sw\": {\n selectionSnapPoints.push(pointFrom(minX, maxY));\n break;\n }\n }\n }\n\n const snapDistance = getSnapDistance(app.state.zoom.value);\n\n const minOffset = {\n x: snapDistance,\n y: snapDistance,\n };\n\n const nearestSnapsX: Snaps = [];\n const nearestSnapsY: Snaps = [];\n\n getPointSnaps(\n selectedOriginalElements,\n selectionSnapPoints,\n app,\n event,\n nearestSnapsX,\n nearestSnapsY,\n minOffset,\n );\n\n const snapOffset = {\n x: nearestSnapsX[0]?.offset ?? 0,\n y: nearestSnapsY[0]?.offset ?? 0,\n };\n\n // again, once snap offset is calculated\n // reset to recompute for creating snap lines to be rendered\n minOffset.x = 0;\n minOffset.y = 0;\n nearestSnapsX.length = 0;\n nearestSnapsY.length = 0;\n\n const [x1, y1, x2, y2] = getCommonBounds(selectedElements).map((bound) =>\n round(bound),\n );\n\n const corners: GlobalPoint[] = [\n pointFrom(x1, y1),\n pointFrom(x1, y2),\n pointFrom(x2, y1),\n pointFrom(x2, y2),\n ];\n\n getPointSnaps(\n selectedElements,\n corners,\n app,\n event,\n nearestSnapsX,\n nearestSnapsY,\n minOffset,\n );\n\n const pointSnapLines = createPointSnapLines(nearestSnapsX, nearestSnapsY);\n\n return {\n snapOffset,\n snapLines: pointSnapLines,\n };\n};\n\nexport const snapNewElement = (\n newElement: ExcalidrawElement,\n app: AppClassProperties,\n event: KeyboardModifiersObject,\n origin: Vector2D,\n dragOffset: Vector2D,\n elementsMap: ElementsMap,\n) => {\n if (!isSnappingEnabled({ event, selectedElements: [newElement], app })) {\n return {\n snapOffset: { x: 0, y: 0 },\n snapLines: [],\n };\n }\n\n const selectionSnapPoints: GlobalPoint[] = [\n pointFrom(origin.x + dragOffset.x, origin.y + dragOffset.y),\n ];\n\n const snapDistance = getSnapDistance(app.state.zoom.value);\n\n const minOffset = {\n x: snapDistance,\n y: snapDistance,\n };\n\n const nearestSnapsX: Snaps = [];\n const nearestSnapsY: Snaps = [];\n\n getPointSnaps(\n [newElement],\n selectionSnapPoints,\n app,\n event,\n nearestSnapsX,\n nearestSnapsY,\n minOffset,\n );\n\n const snapOffset = {\n x: nearestSnapsX[0]?.offset ?? 0,\n y: nearestSnapsY[0]?.offset ?? 0,\n };\n\n minOffset.x = 0;\n minOffset.y = 0;\n nearestSnapsX.length = 0;\n nearestSnapsY.length = 0;\n\n const corners = getElementsCorners([newElement], elementsMap, {\n boundingBoxCorners: true,\n omitCenter: true,\n });\n\n getPointSnaps(\n [newElement],\n corners,\n app,\n event,\n nearestSnapsX,\n nearestSnapsY,\n minOffset,\n );\n\n const pointSnapLines = createPointSnapLines(nearestSnapsX, nearestSnapsY);\n\n return {\n snapOffset,\n snapLines: pointSnapLines,\n };\n};\n\nexport const getSnapLinesAtPointer = (\n elements: readonly ExcalidrawElement[],\n app: AppClassProperties,\n pointer: Vector2D,\n event: KeyboardModifiersObject,\n elementsMap: ElementsMap,\n) => {\n if (!isSnappingEnabled({ event, selectedElements: [], app })) {\n return {\n originOffset: { x: 0, y: 0 },\n snapLines: [],\n };\n }\n\n const referenceElements = getVisibleAndNonSelectedElements(\n elements,\n [],\n app.state,\n elementsMap,\n );\n\n const snapDistance = getSnapDistance(app.state.zoom.value);\n\n const minOffset = {\n x: snapDistance,\n y: snapDistance,\n };\n\n const horizontalSnapLines: PointerSnapLine[] = [];\n const verticalSnapLines: PointerSnapLine[] = [];\n\n for (const referenceElement of referenceElements) {\n const corners = getElementsCorners([referenceElement], elementsMap);\n\n for (const corner of corners) {\n const offsetX = corner[0] - pointer.x;\n\n if (Math.abs(offsetX) <= Math.abs(minOffset.x)) {\n if (Math.abs(offsetX) < Math.abs(minOffset.x)) {\n verticalSnapLines.length = 0;\n }\n\n verticalSnapLines.push({\n type: \"pointer\",\n points: [corner, pointFrom(corner[0], pointer.y)],\n direction: \"vertical\",\n });\n\n minOffset.x = offsetX;\n }\n\n const offsetY = corner[1] - pointer.y;\n\n if (Math.abs(offsetY) <= Math.abs(minOffset.y)) {\n if (Math.abs(offsetY) < Math.abs(minOffset.y)) {\n horizontalSnapLines.length = 0;\n }\n\n horizontalSnapLines.push({\n type: \"pointer\",\n points: [corner, pointFrom(pointer.x, corner[1])],\n direction: \"horizontal\",\n });\n\n minOffset.y = offsetY;\n }\n }\n }\n\n return {\n originOffset: {\n x:\n verticalSnapLines.length > 0\n ? verticalSnapLines[0].points[0][0] - pointer.x\n : 0,\n y:\n horizontalSnapLines.length > 0\n ? horizontalSnapLines[0].points[0][1] - pointer.y\n : 0,\n },\n snapLines: [...verticalSnapLines, ...horizontalSnapLines],\n };\n};\n\nexport const isActiveToolNonLinearSnappable = (\n activeToolType: AppState[\"activeTool\"][\"type\"],\n) => {\n return (\n activeToolType === TOOL_TYPE.rectangle ||\n activeToolType === TOOL_TYPE.ellipse ||\n activeToolType === TOOL_TYPE.diamond ||\n activeToolType === TOOL_TYPE.frame ||\n activeToolType === TOOL_TYPE.magicframe ||\n activeToolType === TOOL_TYPE.image ||\n activeToolType === TOOL_TYPE.text\n );\n};\n\n// TODO: Rounding this point causes some shake when free drawing\nexport const getGridPoint = (\n x: number,\n y: number,\n gridSize: NullableGridSize,\n): [number, number] => {\n if (gridSize) {\n return [\n Math.round(x / gridSize) * gridSize,\n Math.round(y / gridSize) * gridSize,\n ];\n }\n return [x, y];\n};\n", "import type {\n NonDeleted,\n ExcalidrawLinearElement,\n ExcalidrawElement,\n PointBinding,\n ExcalidrawBindableElement,\n ExcalidrawTextElementWithContainer,\n ElementsMap,\n NonDeletedSceneElementsMap,\n FixedPointBinding,\n SceneElementsMap,\n FixedSegment,\n ExcalidrawElbowArrowElement,\n} from \"./types\";\nimport { getElementAbsoluteCoords, getLockedLinearCursorAlignSize } from \".\";\nimport type { Bounds } from \"./bounds\";\nimport {\n getCurvePathOps,\n getElementPointsCoords,\n getMinMaxXYFromCurvePathOps,\n} from \"./bounds\";\nimport type {\n AppState,\n PointerCoords,\n InteractiveCanvasAppState,\n AppClassProperties,\n NullableGridSize,\n Zoom,\n} from \"../types\";\nimport { mutateElement } from \"./mutateElement\";\n\nimport {\n bindOrUnbindLinearElement,\n getHoveredElementForBinding,\n isBindingEnabled,\n} from \"./binding\";\nimport { invariant, tupleToCoors } from \"../utils\";\nimport {\n isBindingElement,\n isElbowArrow,\n isFixedPointBinding,\n} from \"./typeChecks\";\nimport { KEYS, shouldRotateWithDiscreteAngle } from \"../keys\";\nimport { getBoundTextElement, handleBindTextResize } from \"./textElement\";\nimport { DRAGGING_THRESHOLD } from \"../constants\";\nimport type { Mutable } from \"../utility-types\";\nimport { ShapeCache } from \"../scene/ShapeCache\";\nimport type { Store } from \"../store\";\nimport type Scene from \"../scene/Scene\";\nimport type { Radians } from \"@excalidraw/math\";\nimport {\n pointCenter,\n pointFrom,\n pointRotateRads,\n pointsEqual,\n vector,\n type GlobalPoint,\n type LocalPoint,\n pointDistance,\n pointTranslate,\n vectorFromPoint,\n} from \"@excalidraw/math\";\nimport {\n getBezierCurveLength,\n getBezierXY,\n getControlPointsForBezierCurve,\n isPathALoop,\n mapIntervalToBezierT,\n} from \"../shapes\";\nimport { getGridPoint } from \"../snapping\";\nimport { headingIsHorizontal, vectorToHeading } from \"./heading\";\n\nconst editorMidPointsCache: {\n version: number | null;\n points: (GlobalPoint | null)[];\n zoom: number | null;\n} = { version: null, points: [], zoom: null };\nexport class LinearElementEditor {\n public readonly elementId: ExcalidrawElement[\"id\"] & {\n _brand: \"excalidrawLinearElementId\";\n };\n /** indices */\n public readonly selectedPointsIndices: readonly number[] | null;\n\n public readonly pointerDownState: Readonly<{\n prevSelectedPointsIndices: readonly number[] | null;\n /** index */\n lastClickedPoint: number;\n lastClickedIsEndPoint: boolean;\n origin: Readonly<{ x: number; y: number }> | null;\n segmentMidpoint: {\n value: GlobalPoint | null;\n index: number | null;\n added: boolean;\n };\n }>;\n\n /** whether you're dragging a point */\n public readonly isDragging: boolean;\n public readonly lastUncommittedPoint: LocalPoint | null;\n public readonly pointerOffset: Readonly<{ x: number; y: number }>;\n public readonly startBindingElement:\n | ExcalidrawBindableElement\n | null\n | \"keep\";\n public readonly endBindingElement: ExcalidrawBindableElement | null | \"keep\";\n public readonly hoverPointIndex: number;\n public readonly segmentMidPointHoveredCoords: GlobalPoint | null;\n public readonly elbowed: boolean;\n\n constructor(element: NonDeleted<ExcalidrawLinearElement>) {\n this.elementId = element.id as string & {\n _brand: \"excalidrawLinearElementId\";\n };\n if (!pointsEqual(element.points[0], pointFrom(0, 0))) {\n console.error(\"Linear element is not normalized\", Error().stack);\n }\n\n this.selectedPointsIndices = null;\n this.lastUncommittedPoint = null;\n this.isDragging = false;\n this.pointerOffset = { x: 0, y: 0 };\n this.startBindingElement = \"keep\";\n this.endBindingElement = \"keep\";\n this.pointerDownState = {\n prevSelectedPointsIndices: null,\n lastClickedPoint: -1,\n lastClickedIsEndPoint: false,\n origin: null,\n\n segmentMidpoint: {\n value: null,\n index: null,\n added: false,\n },\n };\n this.hoverPointIndex = -1;\n this.segmentMidPointHoveredCoords = null;\n this.elbowed = isElbowArrow(element) && element.elbowed;\n }\n\n // ---------------------------------------------------------------------------\n // static methods\n // ---------------------------------------------------------------------------\n\n static POINT_HANDLE_SIZE = 10;\n /**\n * @param id the `elementId` from the instance of this class (so that we can\n * statically guarantee this method returns an ExcalidrawLinearElement)\n */\n static getElement<T extends ExcalidrawLinearElement>(\n id: InstanceType<typeof LinearElementEditor>[\"elementId\"],\n elementsMap: ElementsMap,\n ): T | null {\n const element = elementsMap.get(id);\n if (element) {\n return element as NonDeleted<T>;\n }\n return null;\n }\n\n static handleBoxSelection(\n event: PointerEvent,\n appState: AppState,\n setState: React.Component<any, AppState>[\"setState\"],\n elementsMap: NonDeletedSceneElementsMap,\n ) {\n if (!appState.editingLinearElement || !appState.selectionElement) {\n return false;\n }\n const { editingLinearElement } = appState;\n const { selectedPointsIndices, elementId } = editingLinearElement;\n\n const element = LinearElementEditor.getElement(elementId, elementsMap);\n if (!element) {\n return false;\n }\n\n const [selectionX1, selectionY1, selectionX2, selectionY2] =\n getElementAbsoluteCoords(appState.selectionElement, elementsMap);\n\n const pointsSceneCoords = LinearElementEditor.getPointsGlobalCoordinates(\n element,\n elementsMap,\n );\n\n const nextSelectedPoints = pointsSceneCoords\n .reduce((acc: number[], point, index) => {\n if (\n (point[0] >= selectionX1 &&\n point[0] <= selectionX2 &&\n point[1] >= selectionY1 &&\n point[1] <= selectionY2) ||\n (event.shiftKey && selectedPointsIndices?.includes(index))\n ) {\n acc.push(index);\n }\n\n return acc;\n }, [])\n .filter((index) => {\n if (\n isElbowArrow(element) &&\n index !== 0 &&\n index !== element.points.length - 1\n ) {\n return false;\n }\n return true;\n });\n\n setState({\n editingLinearElement: {\n ...editingLinearElement,\n selectedPointsIndices: nextSelectedPoints.length\n ? nextSelectedPoints\n : null,\n },\n });\n }\n\n /** @returns whether point was dragged */\n static handlePointDragging(\n event: PointerEvent,\n app: AppClassProperties,\n scenePointerX: number,\n scenePointerY: number,\n maybeSuggestBinding: (\n element: NonDeleted<ExcalidrawLinearElement>,\n pointSceneCoords: { x: number; y: number }[],\n ) => void,\n linearElementEditor: LinearElementEditor,\n scene: Scene,\n ): boolean {\n if (!linearElementEditor) {\n return false;\n }\n const { elementId } = linearElementEditor;\n const elementsMap = scene.getNonDeletedElementsMap();\n const element = LinearElementEditor.getElement(elementId, elementsMap);\n if (!element) {\n return false;\n }\n\n if (\n isElbowArrow(element) &&\n !linearElementEditor.pointerDownState.lastClickedIsEndPoint &&\n linearElementEditor.pointerDownState.lastClickedPoint !== 0\n ) {\n return false;\n }\n\n const selectedPointsIndices = isElbowArrow(element)\n ? linearElementEditor.selectedPointsIndices\n ?.reduce(\n (startEnd, index) =>\n (index === 0\n ? [0, startEnd[1]]\n : [startEnd[0], element.points.length - 1]) as [\n boolean | number,\n boolean | number,\n ],\n [false, false] as [number | boolean, number | boolean],\n )\n .filter(\n (idx: number | boolean): idx is number => typeof idx === \"number\",\n )\n : linearElementEditor.selectedPointsIndices;\n const lastClickedPoint = isElbowArrow(element)\n ? linearElementEditor.pointerDownState.lastClickedPoint > 0\n ? element.points.length - 1\n : 0\n : linearElementEditor.pointerDownState.lastClickedPoint;\n\n // point that's being dragged (out of all selected points)\n const draggingPoint = element.points[lastClickedPoint] as\n | [number, number]\n | undefined;\n\n if (selectedPointsIndices && draggingPoint) {\n if (\n shouldRotateWithDiscreteAngle(event) &&\n selectedPointsIndices.length === 1 &&\n element.points.length > 1\n ) {\n const selectedIndex = selectedPointsIndices[0];\n const referencePoint =\n element.points[selectedIndex === 0 ? 1 : selectedIndex - 1];\n\n const [width, height] = LinearElementEditor._getShiftLockedDelta(\n element,\n elementsMap,\n referencePoint,\n pointFrom(scenePointerX, scenePointerY),\n event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(),\n );\n\n LinearElementEditor.movePoints(element, [\n {\n index: selectedIndex,\n point: pointFrom(\n width + referencePoint[0],\n height + referencePoint[1],\n ),\n isDragging: selectedIndex === lastClickedPoint,\n },\n ]);\n } else {\n const newDraggingPointPosition = LinearElementEditor.createPointAt(\n element,\n elementsMap,\n scenePointerX - linearElementEditor.pointerOffset.x,\n scenePointerY - linearElementEditor.pointerOffset.y,\n event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(),\n );\n\n const deltaX = newDraggingPointPosition[0] - draggingPoint[0];\n const deltaY = newDraggingPointPosition[1] - draggingPoint[1];\n\n LinearElementEditor.movePoints(\n element,\n selectedPointsIndices.map((pointIndex) => {\n const newPointPosition: LocalPoint =\n pointIndex === lastClickedPoint\n ? LinearElementEditor.createPointAt(\n element,\n elementsMap,\n scenePointerX - linearElementEditor.pointerOffset.x,\n scenePointerY - linearElementEditor.pointerOffset.y,\n event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(),\n )\n : pointFrom(\n element.points[pointIndex][0] + deltaX,\n element.points[pointIndex][1] + deltaY,\n );\n return {\n index: pointIndex,\n point: newPointPosition,\n isDragging: pointIndex === lastClickedPoint,\n };\n }),\n );\n }\n\n const boundTextElement = getBoundTextElement(element, elementsMap);\n if (boundTextElement) {\n handleBindTextResize(element, elementsMap, false);\n }\n\n // suggest bindings for first and last point if selected\n if (isBindingElement(element, false)) {\n const coords: { x: number; y: number }[] = [];\n\n const firstSelectedIndex = selectedPointsIndices[0];\n if (firstSelectedIndex === 0) {\n coords.push(\n tupleToCoors(\n LinearElementEditor.getPointGlobalCoordinates(\n element,\n element.points[0],\n elementsMap,\n ),\n ),\n );\n }\n\n const lastSelectedIndex =\n selectedPointsIndices[selectedPointsIndices.length - 1];\n if (lastSelectedIndex === element.points.length - 1) {\n coords.push(\n tupleToCoors(\n LinearElementEditor.getPointGlobalCoordinates(\n element,\n element.points[lastSelectedIndex],\n elementsMap,\n ),\n ),\n );\n }\n\n if (coords.length) {\n maybeSuggestBinding(element, coords);\n }\n }\n\n return true;\n }\n\n return false;\n }\n\n static handlePointerUp(\n event: PointerEvent,\n editingLinearElement: LinearElementEditor,\n appState: AppState,\n scene: Scene,\n ): LinearElementEditor {\n const elementsMap = scene.getNonDeletedElementsMap();\n const elements = scene.getNonDeletedElements();\n\n const { elementId, selectedPointsIndices, isDragging, pointerDownState } =\n editingLinearElement;\n const element = LinearElementEditor.getElement(elementId, elementsMap);\n if (!element) {\n return editingLinearElement;\n }\n\n const bindings: Mutable<\n Partial<\n Pick<\n InstanceType<typeof LinearElementEditor>,\n \"startBindingElement\" | \"endBindingElement\"\n >\n >\n > = {};\n\n if (isDragging && selectedPointsIndices) {\n for (const selectedPoint of selectedPointsIndices) {\n if (\n selectedPoint === 0 ||\n selectedPoint === element.points.length - 1\n ) {\n if (isPathALoop(element.points, appState.zoom.value)) {\n LinearElementEditor.movePoints(element, [\n {\n index: selectedPoint,\n point:\n selectedPoint === 0\n ? element.points[element.points.length - 1]\n : element.points[0],\n },\n ]);\n }\n\n const bindingElement = isBindingEnabled(appState)\n ? getHoveredElementForBinding(\n tupleToCoors(\n LinearElementEditor.getPointAtIndexGlobalCoordinates(\n element,\n selectedPoint!,\n elementsMap,\n ),\n ),\n elements,\n elementsMap,\n appState.zoom,\n isElbowArrow(element),\n isElbowArrow(element),\n )\n : null;\n\n bindings[\n selectedPoint === 0 ? \"startBindingElement\" : \"endBindingElement\"\n ] = bindingElement;\n }\n }\n }\n\n return {\n ...editingLinearElement,\n ...bindings,\n // if clicking without previously dragging a point(s), and not holding\n // shift, deselect all points except the one clicked. If holding shift,\n // toggle the point.\n selectedPointsIndices:\n isDragging || event.shiftKey\n ? !isDragging &&\n event.shiftKey &&\n pointerDownState.prevSelectedPointsIndices?.includes(\n pointerDownState.lastClickedPoint,\n )\n ? selectedPointsIndices &&\n selectedPointsIndices.filter(\n (pointIndex) =>\n pointIndex !== pointerDownState.lastClickedPoint,\n )\n : selectedPointsIndices\n : selectedPointsIndices?.includes(pointerDownState.lastClickedPoint)\n ? [pointerDownState.lastClickedPoint]\n : selectedPointsIndices,\n isDragging: false,\n pointerOffset: { x: 0, y: 0 },\n };\n }\n\n static getEditorMidPoints = (\n element: NonDeleted<ExcalidrawLinearElement>,\n elementsMap: ElementsMap,\n appState: InteractiveCanvasAppState,\n ): typeof editorMidPointsCache[\"points\"] => {\n const boundText = getBoundTextElement(element, elementsMap);\n\n // Since its not needed outside editor unless 2 pointer lines or bound text\n if (\n !isElbowArrow(element) &&\n !appState.editingLinearElement &&\n element.points.length > 2 &&\n !boundText\n ) {\n return [];\n }\n if (\n editorMidPointsCache.version === element.version &&\n editorMidPointsCache.zoom === appState.zoom.value\n ) {\n return editorMidPointsCache.points;\n }\n LinearElementEditor.updateEditorMidPointsCache(\n element,\n elementsMap,\n appState,\n );\n return editorMidPointsCache.points!;\n };\n\n static updateEditorMidPointsCache = (\n element: NonDeleted<ExcalidrawLinearElement>,\n elementsMap: ElementsMap,\n appState: InteractiveCanvasAppState,\n ) => {\n const points = LinearElementEditor.getPointsGlobalCoordinates(\n element,\n elementsMap,\n );\n\n let index = 0;\n const midpoints: (GlobalPoint | null)[] = [];\n while (index < points.length - 1) {\n if (\n LinearElementEditor.isSegmentTooShort(\n element,\n element.points[index],\n element.points[index + 1],\n index,\n appState.zoom,\n )\n ) {\n midpoints.push(null);\n index++;\n continue;\n }\n const segmentMidPoint = LinearElementEditor.getSegmentMidPoint(\n element,\n points[index],\n points[index + 1],\n index + 1,\n elementsMap,\n );\n midpoints.push(segmentMidPoint);\n index++;\n }\n editorMidPointsCache.points = midpoints;\n editorMidPointsCache.version = element.version;\n editorMidPointsCache.zoom = appState.zoom.value;\n };\n\n static getSegmentMidpointHitCoords = (\n linearElementEditor: LinearElementEditor,\n scenePointer: { x: number; y: number },\n appState: AppState,\n elementsMap: ElementsMap,\n ): GlobalPoint | null => {\n const { elementId } = linearElementEditor;\n const element = LinearElementEditor.getElement(elementId, elementsMap);\n if (!element) {\n return null;\n }\n const clickedPointIndex = LinearElementEditor.getPointIndexUnderCursor(\n element,\n elementsMap,\n appState.zoom,\n scenePointer.x,\n scenePointer.y,\n );\n if (!isElbowArrow(element) && clickedPointIndex >= 0) {\n return null;\n }\n const points = LinearElementEditor.getPointsGlobalCoordinates(\n element,\n elementsMap,\n );\n if (\n points.length >= 3 &&\n !appState.editingLinearElement &&\n !isElbowArrow(element)\n ) {\n return null;\n }\n\n const threshold =\n (LinearElementEditor.POINT_HANDLE_SIZE + 1) / appState.zoom.value;\n\n const existingSegmentMidpointHitCoords =\n linearElementEditor.segmentMidPointHoveredCoords;\n if (existingSegmentMidpointHitCoords) {\n const distance = pointDistance(\n pointFrom(\n existingSegmentMidpointHitCoords[0],\n existingSegmentMidpointHitCoords[1],\n ),\n pointFrom(scenePointer.x, scenePointer.y),\n );\n if (distance <= threshold) {\n return existingSegmentMidpointHitCoords;\n }\n }\n let index = 0;\n const midPoints: typeof editorMidPointsCache[\"points\"] =\n LinearElementEditor.getEditorMidPoints(element, elementsMap, appState);\n\n while (index < midPoints.length) {\n if (midPoints[index] !== null) {\n const distance = pointDistance(\n midPoints[index]!,\n pointFrom(scenePointer.x, scenePointer.y),\n );\n if (distance <= threshold) {\n return midPoints[index];\n }\n }\n\n index++;\n }\n return null;\n };\n\n static isSegmentTooShort<P extends GlobalPoint | LocalPoint>(\n element: NonDeleted<ExcalidrawLinearElement>,\n startPoint: P,\n endPoint: P,\n index: number,\n zoom: Zoom,\n ) {\n if (isElbowArrow(element)) {\n if (index >= 0 && index < element.points.length) {\n return (\n pointDistance(startPoint, endPoint) * zoom.value <\n LinearElementEditor.POINT_HANDLE_SIZE / 2\n );\n }\n\n return false;\n }\n\n let distance = pointDistance(startPoint, endPoint);\n if (element.points.length > 2 && element.roundness) {\n distance = getBezierCurveLength(element, endPoint);\n }\n\n return distance * zoom.value < LinearElementEditor.POINT_HANDLE_SIZE * 4;\n }\n\n static getSegmentMidPoint(\n element: NonDeleted<ExcalidrawLinearElement>,\n startPoint: GlobalPoint,\n endPoint: GlobalPoint,\n endPointIndex: number,\n elementsMap: ElementsMap,\n ): GlobalPoint {\n let segmentMidPoint = pointCenter(startPoint, endPoint);\n if (element.points.length > 2 && element.roundness) {\n const controlPoints = getControlPointsForBezierCurve(\n element,\n element.points[endPointIndex],\n );\n if (controlPoints) {\n const t = mapIntervalToBezierT(\n element,\n element.points[endPointIndex],\n 0.5,\n );\n\n segmentMidPoint = LinearElementEditor.getPointGlobalCoordinates(\n element,\n getBezierXY(\n controlPoints[0],\n controlPoints[1],\n controlPoints[2],\n controlPoints[3],\n t,\n ),\n elementsMap,\n );\n }\n }\n\n return segmentMidPoint;\n }\n\n static getSegmentMidPointIndex(\n linearElementEditor: LinearElementEditor,\n appState: AppState,\n midPoint: GlobalPoint,\n elementsMap: ElementsMap,\n ) {\n const element = LinearElementEditor.getElement(\n linearElementEditor.elementId,\n elementsMap,\n );\n if (!element) {\n return -1;\n }\n const midPoints = LinearElementEditor.getEditorMidPoints(\n element,\n elementsMap,\n appState,\n );\n let index = 0;\n while (index < midPoints.length) {\n if (LinearElementEditor.arePointsEqual(midPoint, midPoints[index])) {\n return index + 1;\n }\n index++;\n }\n return -1;\n }\n\n static handlePointerDown(\n event: React.PointerEvent<HTMLElement>,\n app: AppClassProperties,\n store: Store,\n scenePointer: { x: number; y: number },\n linearElementEditor: LinearElementEditor,\n scene: Scene,\n ): {\n didAddPoint: boolean;\n hitElement: NonDeleted<ExcalidrawElement> | null;\n linearElementEditor: LinearElementEditor | null;\n } {\n const appState = app.state;\n const elementsMap = scene.getNonDeletedElementsMap();\n const elements = scene.getNonDeletedElements();\n\n const ret: ReturnType<typeof LinearElementEditor[\"handlePointerDown\"]> = {\n didAddPoint: false,\n hitElement: null,\n linearElementEditor: null,\n };\n\n if (!linearElementEditor) {\n return ret;\n }\n\n const { elementId } = linearElementEditor;\n const element = LinearElementEditor.getElement(elementId, elementsMap);\n\n if (!element) {\n return ret;\n }\n const segmentMidpoint = LinearElementEditor.getSegmentMidpointHitCoords(\n linearElementEditor,\n scenePointer,\n appState,\n elementsMap,\n );\n let segmentMidpointIndex = null;\n if (segmentMidpoint) {\n segmentMidpointIndex = LinearElementEditor.getSegmentMidPointIndex(\n linearElementEditor,\n appState,\n segmentMidpoint,\n elementsMap,\n );\n } else if (event.altKey && appState.editingLinearElement) {\n if (linearElementEditor.lastUncommittedPoint == null) {\n mutateElement(element, {\n points: [\n ...element.points,\n LinearElementEditor.createPointAt(\n element,\n elementsMap,\n scenePointer.x,\n scenePointer.y,\n event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(),\n ),\n ],\n });\n ret.didAddPoint = true;\n }\n store.shouldCaptureIncrement();\n ret.linearElementEditor = {\n ...linearElementEditor,\n pointerDownState: {\n prevSelectedPointsIndices: linearElementEditor.selectedPointsIndices,\n lastClickedPoint: -1,\n lastClickedIsEndPoint: false,\n origin: { x: scenePointer.x, y: scenePointer.y },\n segmentMidpoint: {\n value: segmentMidpoint,\n index: segmentMidpointIndex,\n added: false,\n },\n },\n selectedPointsIndices: [element.points.length - 1],\n lastUncommittedPoint: null,\n endBindingElement: getHoveredElementForBinding(\n scenePointer,\n elements,\n elementsMap,\n app.state.zoom,\n linearElementEditor.elbowed,\n ),\n };\n\n ret.didAddPoint = true;\n return ret;\n }\n\n const clickedPointIndex = LinearElementEditor.getPointIndexUnderCursor(\n element,\n elementsMap,\n appState.zoom,\n scenePointer.x,\n scenePointer.y,\n );\n // if we clicked on a point, set the element as hitElement otherwise\n // it would get deselected if the point is outside the hitbox area\n if (clickedPointIndex >= 0 || segmentMidpoint) {\n ret.hitElement = element;\n } else {\n // You might be wandering why we are storing the binding elements on\n // LinearElementEditor and passing them in, instead of calculating them\n // from the end points of the `linearElement` - this is to allow disabling\n // binding (which needs to happen at the point the user finishes moving\n // the point).\n const { startBindingElement, endBindingElement } = linearElementEditor;\n if (isBindingEnabled(appState) && isBindingElement(element)) {\n bindOrUnbindLinearElement(\n element,\n startBindingElement,\n endBindingElement,\n elementsMap,\n scene,\n );\n }\n }\n\n const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n const targetPoint =\n clickedPointIndex > -1 &&\n pointRotateRads(\n pointFrom(\n element.x + element.points[clickedPointIndex][0],\n element.y + element.points[clickedPointIndex][1],\n ),\n pointFrom(cx, cy),\n element.angle,\n );\n\n const nextSelectedPointsIndices =\n clickedPointIndex > -1 || event.shiftKey\n ? event.shiftKey ||\n linearElementEditor.selectedPointsIndices?.includes(clickedPointIndex)\n ? normalizeSelectedPoints([\n ...(linearElementEditor.selectedPointsIndices || []),\n clickedPointIndex,\n ])\n : [clickedPointIndex]\n : null;\n ret.linearElementEditor = {\n ...linearElementEditor,\n pointerDownState: {\n prevSelectedPointsIndices: linearElementEditor.selectedPointsIndices,\n lastClickedPoint: clickedPointIndex,\n lastClickedIsEndPoint: clickedPointIndex === element.points.length - 1,\n origin: { x: scenePointer.x, y: scenePointer.y },\n segmentMidpoint: {\n value: segmentMidpoint,\n index: segmentMidpointIndex,\n added: false,\n },\n },\n selectedPointsIndices: nextSelectedPointsIndices,\n pointerOffset: targetPoint\n ? {\n x: scenePointer.x - targetPoint[0],\n y: scenePointer.y - targetPoint[1],\n }\n : { x: 0, y: 0 },\n };\n\n return ret;\n }\n\n static arePointsEqual<Point extends LocalPoint | GlobalPoint>(\n point1: Point | null,\n point2: Point | null,\n ) {\n if (!point1 && !point2) {\n return true;\n }\n if (!point1 || !point2) {\n return false;\n }\n return pointsEqual(point1, point2);\n }\n\n static handlePointerMove(\n event: React.PointerEvent<HTMLCanvasElement>,\n scenePointerX: number,\n scenePointerY: number,\n app: AppClassProperties,\n elementsMap: NonDeletedSceneElementsMap | SceneElementsMap,\n ): LinearElementEditor | null {\n const appState = app.state;\n if (!appState.editingLinearElement) {\n return null;\n }\n const { elementId, lastUncommittedPoint } = appState.editingLinearElement;\n const element = LinearElementEditor.getElement(elementId, elementsMap);\n if (!element) {\n return appState.editingLinearElement;\n }\n\n const { points } = element;\n const lastPoint = points[points.length - 1];\n\n if (!event.altKey) {\n if (lastPoint === lastUncommittedPoint) {\n LinearElementEditor.deletePoints(element, [points.length - 1]);\n }\n return {\n ...appState.editingLinearElement,\n lastUncommittedPoint: null,\n };\n }\n\n let newPoint: LocalPoint;\n\n if (shouldRotateWithDiscreteAngle(event) && points.length >= 2) {\n const lastCommittedPoint = points[points.length - 2];\n\n const [width, height] = LinearElementEditor._getShiftLockedDelta(\n element,\n elementsMap,\n lastCommittedPoint,\n pointFrom(scenePointerX, scenePointerY),\n event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(),\n );\n\n newPoint = pointFrom(\n width + lastCommittedPoint[0],\n height + lastCommittedPoint[1],\n );\n } else {\n newPoint = LinearElementEditor.createPointAt(\n element,\n elementsMap,\n scenePointerX - appState.editingLinearElement.pointerOffset.x,\n scenePointerY - appState.editingLinearElement.pointerOffset.y,\n event[KEYS.CTRL_OR_CMD] || isElbowArrow(element)\n ? null\n : app.getEffectiveGridSize(),\n );\n }\n\n if (lastPoint === lastUncommittedPoint) {\n LinearElementEditor.movePoints(element, [\n {\n index: element.points.length - 1,\n point: newPoint,\n },\n ]);\n } else {\n LinearElementEditor.addPoints(element, [{ point: newPoint }]);\n }\n return {\n ...appState.editingLinearElement,\n lastUncommittedPoint: element.points[element.points.length - 1],\n };\n }\n\n /** scene coords */\n static getPointGlobalCoordinates(\n element: NonDeleted<ExcalidrawLinearElement>,\n p: LocalPoint,\n elementsMap: ElementsMap,\n ): GlobalPoint {\n const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n\n const { x, y } = element;\n return pointRotateRads(\n pointFrom(x + p[0], y + p[1]),\n pointFrom(cx, cy),\n element.angle,\n );\n }\n\n /** scene coords */\n static getPointsGlobalCoordinates(\n element: NonDeleted<ExcalidrawLinearElement>,\n elementsMap: ElementsMap,\n ): GlobalPoint[] {\n const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n return element.points.map((p) => {\n const { x, y } = element;\n return pointRotateRads(\n pointFrom(x + p[0], y + p[1]),\n pointFrom(cx, cy),\n element.angle,\n );\n });\n }\n\n static getPointAtIndexGlobalCoordinates(\n element: NonDeleted<ExcalidrawLinearElement>,\n\n indexMaybeFromEnd: number, // -1 for last element\n elementsMap: ElementsMap,\n ): GlobalPoint {\n const index =\n indexMaybeFromEnd < 0\n ? element.points.length + indexMaybeFromEnd\n : indexMaybeFromEnd;\n const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n const p = element.points[index];\n const { x, y } = element;\n\n return p\n ? pointRotateRads(\n pointFrom(x + p[0], y + p[1]),\n pointFrom(cx, cy),\n element.angle,\n )\n : pointRotateRads(pointFrom(x, y), pointFrom(cx, cy), element.angle);\n }\n\n static pointFromAbsoluteCoords(\n element: NonDeleted<ExcalidrawLinearElement>,\n absoluteCoords: GlobalPoint,\n elementsMap: ElementsMap,\n ): LocalPoint {\n if (isElbowArrow(element)) {\n // No rotation for elbow arrows\n return pointFrom(\n absoluteCoords[0] - element.x,\n absoluteCoords[1] - element.y,\n );\n }\n\n const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n const [x, y] = pointRotateRads(\n pointFrom(absoluteCoords[0], absoluteCoords[1]),\n pointFrom(cx, cy),\n -element.angle as Radians,\n );\n return pointFrom(x - element.x, y - element.y);\n }\n\n static getPointIndexUnderCursor(\n element: NonDeleted<ExcalidrawLinearElement>,\n elementsMap: ElementsMap,\n zoom: AppState[\"zoom\"],\n x: number,\n y: number,\n ) {\n const pointHandles = LinearElementEditor.getPointsGlobalCoordinates(\n element,\n elementsMap,\n );\n let idx = pointHandles.length;\n // loop from right to left because points on the right are rendered over\n // points on the left, thus should take precedence when clicking, if they\n // overlap\n while (--idx > -1) {\n const p = pointHandles[idx];\n if (\n pointDistance(pointFrom(x, y), pointFrom(p[0], p[1])) * zoom.value <\n // +1px to account for outline stroke\n LinearElementEditor.POINT_HANDLE_SIZE + 1\n ) {\n return idx;\n }\n }\n return -1;\n }\n\n static createPointAt(\n element: NonDeleted<ExcalidrawLinearElement>,\n elementsMap: ElementsMap,\n scenePointerX: number,\n scenePointerY: number,\n gridSize: NullableGridSize,\n ): LocalPoint {\n const pointerOnGrid = getGridPoint(scenePointerX, scenePointerY, gridSize);\n const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n const [rotatedX, rotatedY] = pointRotateRads(\n pointFrom(pointerOnGrid[0], pointerOnGrid[1]),\n pointFrom(cx, cy),\n -element.angle as Radians,\n );\n\n return pointFrom(rotatedX - element.x, rotatedY - element.y);\n }\n\n /**\n * Normalizes line points so that the start point is at [0,0]. This is\n * expected in various parts of the codebase. Also returns new x/y to account\n * for the potential normalization.\n */\n static getNormalizedPoints(element: ExcalidrawLinearElement): {\n points: LocalPoint[];\n x: number;\n y: number;\n } {\n const { points } = element;\n\n const offsetX = points[0][0];\n const offsetY = points[0][1];\n\n return {\n points: points.map((p) => {\n return pointFrom(p[0] - offsetX, p[1] - offsetY);\n }),\n x: element.x + offsetX,\n y: element.y + offsetY,\n };\n }\n\n // element-mutating methods\n // ---------------------------------------------------------------------------\n\n static normalizePoints(element: NonDeleted<ExcalidrawLinearElement>) {\n mutateElement(element, LinearElementEditor.getNormalizedPoints(element));\n }\n\n static duplicateSelectedPoints(\n appState: AppState,\n elementsMap: NonDeletedSceneElementsMap | SceneElementsMap,\n ): AppState {\n invariant(\n appState.editingLinearElement,\n \"Not currently editing a linear element\",\n );\n\n const { selectedPointsIndices, elementId } = appState.editingLinearElement;\n const element = LinearElementEditor.getElement(elementId, elementsMap);\n\n invariant(\n element,\n \"The linear element does not exist in the provided Scene\",\n );\n invariant(\n selectedPointsIndices != null,\n \"There are no selected points to duplicate\",\n );\n\n const { points } = element;\n\n const nextSelectedIndices: number[] = [];\n\n let pointAddedToEnd = false;\n let indexCursor = -1;\n const nextPoints = points.reduce((acc: LocalPoint[], p, index) => {\n ++indexCursor;\n acc.push(p);\n\n const isSelected = selectedPointsIndices.includes(index);\n if (isSelected) {\n const nextPoint = points[index + 1];\n\n if (!nextPoint) {\n pointAddedToEnd = true;\n }\n acc.push(\n nextPoint\n ? pointFrom((p[0] + nextPoint[0]) / 2, (p[1] + nextPoint[1]) / 2)\n : pointFrom(p[0], p[1]),\n );\n\n nextSelectedIndices.push(indexCursor + 1);\n ++indexCursor;\n }\n\n return acc;\n }, []);\n\n mutateElement(element, { points: nextPoints });\n\n // temp hack to ensure the line doesn't move when adding point to the end,\n // potentially expanding the bounding box\n if (pointAddedToEnd) {\n const lastPoint = element.points[element.points.length - 1];\n LinearElementEditor.movePoints(element, [\n {\n index: element.points.length - 1,\n point: pointFrom(lastPoint[0] + 30, lastPoint[1] + 30),\n },\n ]);\n }\n\n return {\n ...appState,\n editingLinearElement: {\n ...appState.editingLinearElement,\n selectedPointsIndices: nextSelectedIndices,\n },\n };\n }\n\n static deletePoints(\n element: NonDeleted<ExcalidrawLinearElement>,\n pointIndices: readonly number[],\n ) {\n let offsetX = 0;\n let offsetY = 0;\n\n const isDeletingOriginPoint = pointIndices.includes(0);\n\n // if deleting first point, make the next to be [0,0] and recalculate\n // positions of the rest with respect to it\n if (isDeletingOriginPoint) {\n const firstNonDeletedPoint = element.points.find((point, idx) => {\n return !pointIndices.includes(idx);\n });\n if (firstNonDeletedPoint) {\n offsetX = firstNonDeletedPoint[0];\n offsetY = firstNonDeletedPoint[1];\n }\n }\n\n const nextPoints = element.points.reduce((acc: LocalPoint[], p, idx) => {\n if (!pointIndices.includes(idx)) {\n acc.push(\n !acc.length\n ? pointFrom(0, 0)\n : pointFrom(p[0] - offsetX, p[1] - offsetY),\n );\n }\n return acc;\n }, []);\n\n LinearElementEditor._updatePoints(element, nextPoints, offsetX, offsetY);\n }\n\n static addPoints(\n element: NonDeleted<ExcalidrawLinearElement>,\n targetPoints: { point: LocalPoint }[],\n ) {\n const offsetX = 0;\n const offsetY = 0;\n\n const nextPoints = [...element.points, ...targetPoints.map((x) => x.point)];\n LinearElementEditor._updatePoints(element, nextPoints, offsetX, offsetY);\n }\n\n static movePoints(\n element: NonDeleted<ExcalidrawLinearElement>,\n targetPoints: { index: number; point: LocalPoint; isDragging?: boolean }[],\n otherUpdates?: {\n startBinding?: PointBinding | null;\n endBinding?: PointBinding | null;\n },\n ) {\n const { points } = element;\n\n // in case we're moving start point, instead of modifying its position\n // which would break the invariant of it being at [0,0], we move\n // all the other points in the opposite direction by delta to\n // offset it. We do the same with actual element.x/y position, so\n // this hacks are completely transparent to the user.\n let offsetX = 0;\n let offsetY = 0;\n\n const selectedOriginPoint = targetPoints.find(({ index }) => index === 0);\n\n if (selectedOriginPoint) {\n offsetX =\n selectedOriginPoint.point[0] + points[selectedOriginPoint.index][0];\n offsetY =\n selectedOriginPoint.point[1] + points[selectedOriginPoint.index][1];\n }\n\n const nextPoints: LocalPoint[] = points.map((p, idx) => {\n const selectedPointData = targetPoints.find((t) => t.index === idx);\n if (selectedPointData) {\n if (selectedPointData.index === 0) {\n return p;\n }\n\n const deltaX =\n selectedPointData.point[0] - points[selectedPointData.index][0];\n const deltaY =\n selectedPointData.point[1] - points[selectedPointData.index][1];\n\n return pointFrom(p[0] + deltaX - offsetX, p[1] + deltaY - offsetY);\n }\n return offsetX || offsetY ? pointFrom(p[0] - offsetX, p[1] - offsetY) : p;\n });\n\n LinearElementEditor._updatePoints(\n element,\n nextPoints,\n offsetX,\n offsetY,\n otherUpdates,\n {\n isDragging: targetPoints.reduce(\n (dragging, targetPoint): boolean =>\n dragging || targetPoint.isDragging === true,\n false,\n ),\n },\n );\n }\n\n static shouldAddMidpoint(\n linearElementEditor: LinearElementEditor,\n pointerCoords: PointerCoords,\n appState: AppState,\n elementsMap: ElementsMap,\n ) {\n const element = LinearElementEditor.getElement(\n linearElementEditor.elementId,\n elementsMap,\n );\n\n // Elbow arrows don't allow midpoints\n if (element && isElbowArrow(element)) {\n return false;\n }\n\n if (!element) {\n return false;\n }\n\n const { segmentMidpoint } = linearElementEditor.pointerDownState;\n\n if (\n segmentMidpoint.added ||\n segmentMidpoint.value === null ||\n segmentMidpoint.index === null ||\n linearElementEditor.pointerDownState.origin === null\n ) {\n return false;\n }\n\n const origin = linearElementEditor.pointerDownState.origin!;\n const dist = pointDistance(\n pointFrom(origin.x, origin.y),\n pointFrom(pointerCoords.x, pointerCoords.y),\n );\n if (\n !appState.editingLinearElement &&\n dist < DRAGGING_THRESHOLD / appState.zoom.value\n ) {\n return false;\n }\n return true;\n }\n\n static addMidpoint(\n linearElementEditor: LinearElementEditor,\n pointerCoords: PointerCoords,\n app: AppClassProperties,\n snapToGrid: boolean,\n elementsMap: ElementsMap,\n ) {\n const element = LinearElementEditor.getElement(\n linearElementEditor.elementId,\n elementsMap,\n );\n if (!element) {\n return;\n }\n const { segmentMidpoint } = linearElementEditor.pointerDownState;\n const ret: {\n pointerDownState: LinearElementEditor[\"pointerDownState\"];\n selectedPointsIndices: LinearElementEditor[\"selectedPointsIndices\"];\n } = {\n pointerDownState: linearElementEditor.pointerDownState,\n selectedPointsIndices: linearElementEditor.selectedPointsIndices,\n };\n\n const midpoint = LinearElementEditor.createPointAt(\n element,\n elementsMap,\n pointerCoords.x,\n pointerCoords.y,\n snapToGrid && !isElbowArrow(element) ? app.getEffectiveGridSize() : null,\n );\n const points = [\n ...element.points.slice(0, segmentMidpoint.index!),\n midpoint,\n ...element.points.slice(segmentMidpoint.index!),\n ];\n\n mutateElement(element, {\n points,\n });\n\n ret.pointerDownState = {\n ...linearElementEditor.pointerDownState,\n segmentMidpoint: {\n ...linearElementEditor.pointerDownState.segmentMidpoint,\n added: true,\n },\n lastClickedPoint: segmentMidpoint.index!,\n };\n ret.selectedPointsIndices = [segmentMidpoint.index!];\n return ret;\n }\n\n private static _updatePoints(\n element: NonDeleted<ExcalidrawLinearElement>,\n nextPoints: readonly LocalPoint[],\n offsetX: number,\n offsetY: number,\n otherUpdates?: {\n startBinding?: PointBinding | null;\n endBinding?: PointBinding | null;\n },\n options?: {\n isDragging?: boolean;\n zoom?: AppState[\"zoom\"];\n },\n ) {\n if (isElbowArrow(element)) {\n const updates: {\n startBinding?: FixedPointBinding | null;\n endBinding?: FixedPointBinding | null;\n points?: LocalPoint[];\n } = {};\n if (otherUpdates?.startBinding !== undefined) {\n updates.startBinding =\n otherUpdates.startBinding !== null &&\n isFixedPointBinding(otherUpdates.startBinding)\n ? otherUpdates.startBinding\n : null;\n }\n if (otherUpdates?.endBinding !== undefined) {\n updates.endBinding =\n otherUpdates.endBinding !== null &&\n isFixedPointBinding(otherUpdates.endBinding)\n ? otherUpdates.endBinding\n : null;\n }\n\n updates.points = Array.from(nextPoints);\n updates.points[0] = pointTranslate(\n updates.points[0],\n vector(offsetX, offsetY),\n );\n updates.points[updates.points.length - 1] = pointTranslate(\n updates.points[updates.points.length - 1],\n vector(offsetX, offsetY),\n );\n\n mutateElement(element, updates, true, {\n isDragging: options?.isDragging,\n });\n } else {\n const nextCoords = getElementPointsCoords(element, nextPoints);\n const prevCoords = getElementPointsCoords(element, element.points);\n const nextCenterX = (nextCoords[0] + nextCoords[2]) / 2;\n const nextCenterY = (nextCoords[1] + nextCoords[3]) / 2;\n const prevCenterX = (prevCoords[0] + prevCoords[2]) / 2;\n const prevCenterY = (prevCoords[1] + prevCoords[3]) / 2;\n const dX = prevCenterX - nextCenterX;\n const dY = prevCenterY - nextCenterY;\n const rotated = pointRotateRads(\n pointFrom(offsetX, offsetY),\n pointFrom(dX, dY),\n element.angle,\n );\n mutateElement(element, {\n ...otherUpdates,\n points: nextPoints,\n x: element.x + rotated[0],\n y: element.y + rotated[1],\n });\n }\n }\n\n private static _getShiftLockedDelta(\n element: NonDeleted<ExcalidrawLinearElement>,\n elementsMap: ElementsMap,\n referencePoint: LocalPoint,\n scenePointer: GlobalPoint,\n gridSize: NullableGridSize,\n ) {\n const referencePointCoords = LinearElementEditor.getPointGlobalCoordinates(\n element,\n referencePoint,\n elementsMap,\n );\n\n if (isElbowArrow(element)) {\n return [\n scenePointer[0] - referencePointCoords[0],\n scenePointer[1] - referencePointCoords[1],\n ];\n }\n\n const [gridX, gridY] = getGridPoint(\n scenePointer[0],\n scenePointer[1],\n gridSize,\n );\n\n const { width, height } = getLockedLinearCursorAlignSize(\n referencePointCoords[0],\n referencePointCoords[1],\n gridX,\n gridY,\n );\n\n return pointRotateRads(\n pointFrom(width, height),\n pointFrom(0, 0),\n -element.angle as Radians,\n );\n }\n\n static getBoundTextElementPosition = (\n element: ExcalidrawLinearElement,\n boundTextElement: ExcalidrawTextElementWithContainer,\n elementsMap: ElementsMap,\n ): { x: number; y: number } => {\n const points = LinearElementEditor.getPointsGlobalCoordinates(\n element,\n elementsMap,\n );\n if (points.length < 2) {\n mutateElement(boundTextElement, { isDeleted: true });\n }\n let x = 0;\n let y = 0;\n if (element.points.length % 2 === 1) {\n const index = Math.floor(element.points.length / 2);\n const midPoint = LinearElementEditor.getPointGlobalCoordinates(\n element,\n element.points[index],\n elementsMap,\n );\n x = midPoint[0] - boundTextElement.width / 2;\n y = midPoint[1] - boundTextElement.height / 2;\n } else {\n const index = element.points.length / 2 - 1;\n\n let midSegmentMidpoint = editorMidPointsCache.points[index];\n if (element.points.length === 2) {\n midSegmentMidpoint = pointCenter(points[0], points[1]);\n }\n if (\n !midSegmentMidpoint ||\n editorMidPointsCache.version !== element.version\n ) {\n midSegmentMidpoint = LinearElementEditor.getSegmentMidPoint(\n element,\n points[index],\n points[index + 1],\n index + 1,\n elementsMap,\n );\n }\n x = midSegmentMidpoint[0] - boundTextElement.width / 2;\n y = midSegmentMidpoint[1] - boundTextElement.height / 2;\n }\n return { x, y };\n };\n\n static getMinMaxXYWithBoundText = (\n element: ExcalidrawLinearElement,\n elementsMap: ElementsMap,\n elementBounds: Bounds,\n boundTextElement: ExcalidrawTextElementWithContainer,\n ): [number, number, number, number, number, number] => {\n let [x1, y1, x2, y2] = elementBounds;\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n const { x: boundTextX1, y: boundTextY1 } =\n LinearElementEditor.getBoundTextElementPosition(\n element,\n boundTextElement,\n elementsMap,\n );\n const boundTextX2 = boundTextX1 + boundTextElement.width;\n const boundTextY2 = boundTextY1 + boundTextElement.height;\n const centerPoint = pointFrom(cx, cy);\n\n const topLeftRotatedPoint = pointRotateRads(\n pointFrom(x1, y1),\n centerPoint,\n element.angle,\n );\n const topRightRotatedPoint = pointRotateRads(\n pointFrom(x2, y1),\n centerPoint,\n element.angle,\n );\n\n const counterRotateBoundTextTopLeft = pointRotateRads(\n pointFrom(boundTextX1, boundTextY1),\n centerPoint,\n -element.angle as Radians,\n );\n const counterRotateBoundTextTopRight = pointRotateRads(\n pointFrom(boundTextX2, boundTextY1),\n centerPoint,\n -element.angle as Radians,\n );\n const counterRotateBoundTextBottomLeft = pointRotateRads(\n pointFrom(boundTextX1, boundTextY2),\n centerPoint,\n -element.angle as Radians,\n );\n const counterRotateBoundTextBottomRight = pointRotateRads(\n pointFrom(boundTextX2, boundTextY2),\n centerPoint,\n -element.angle as Radians,\n );\n\n if (\n topLeftRotatedPoint[0] < topRightRotatedPoint[0] &&\n topLeftRotatedPoint[1] >= topRightRotatedPoint[1]\n ) {\n x1 = Math.min(x1, counterRotateBoundTextBottomLeft[0]);\n x2 = Math.max(\n x2,\n Math.max(\n counterRotateBoundTextTopRight[0],\n counterRotateBoundTextBottomRight[0],\n ),\n );\n y1 = Math.min(y1, counterRotateBoundTextTopLeft[1]);\n\n y2 = Math.max(y2, counterRotateBoundTextBottomRight[1]);\n } else if (\n topLeftRotatedPoint[0] >= topRightRotatedPoint[0] &&\n topLeftRotatedPoint[1] > topRightRotatedPoint[1]\n ) {\n x1 = Math.min(x1, counterRotateBoundTextBottomRight[0]);\n x2 = Math.max(\n x2,\n Math.max(\n counterRotateBoundTextTopLeft[0],\n counterRotateBoundTextTopRight[0],\n ),\n );\n y1 = Math.min(y1, counterRotateBoundTextBottomLeft[1]);\n\n y2 = Math.max(y2, counterRotateBoundTextTopRight[1]);\n } else if (topLeftRotatedPoint[0] >= topRightRotatedPoint[0]) {\n x1 = Math.min(x1, counterRotateBoundTextTopRight[0]);\n x2 = Math.max(x2, counterRotateBoundTextBottomLeft[0]);\n y1 = Math.min(y1, counterRotateBoundTextBottomRight[1]);\n\n y2 = Math.max(y2, counterRotateBoundTextTopLeft[1]);\n } else if (topLeftRotatedPoint[1] <= topRightRotatedPoint[1]) {\n x1 = Math.min(\n x1,\n Math.min(\n counterRotateBoundTextTopRight[0],\n counterRotateBoundTextTopLeft[0],\n ),\n );\n\n x2 = Math.max(x2, counterRotateBoundTextBottomRight[0]);\n y1 = Math.min(y1, counterRotateBoundTextTopRight[1]);\n y2 = Math.max(y2, counterRotateBoundTextBottomLeft[1]);\n }\n\n return [x1, y1, x2, y2, cx, cy];\n };\n\n static getElementAbsoluteCoords = (\n element: ExcalidrawLinearElement,\n elementsMap: ElementsMap,\n includeBoundText: boolean = false,\n ): [number, number, number, number, number, number] => {\n let coords: [number, number, number, number, number, number];\n let x1;\n let y1;\n let x2;\n let y2;\n if (element.points.length < 2 || !ShapeCache.get(element)) {\n // XXX this is just a poor estimate and not very useful\n const { minX, minY, maxX, maxY } = element.points.reduce(\n (limits, [x, y]) => {\n limits.minY = Math.min(limits.minY, y);\n limits.minX = Math.min(limits.minX, x);\n\n limits.maxX = Math.max(limits.maxX, x);\n limits.maxY = Math.max(limits.maxY, y);\n\n return limits;\n },\n { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity },\n );\n x1 = minX + element.x;\n y1 = minY + element.y;\n x2 = maxX + element.x;\n y2 = maxY + element.y;\n } else {\n const shape = ShapeCache.generateElementShape(element, null);\n\n // first element is always the curve\n const ops = getCurvePathOps(shape[0]);\n\n const [minX, minY, maxX, maxY] = getMinMaxXYFromCurvePathOps(ops);\n x1 = minX + element.x;\n y1 = minY + element.y;\n x2 = maxX + element.x;\n y2 = maxY + element.y;\n }\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n coords = [x1, y1, x2, y2, cx, cy];\n\n if (!includeBoundText) {\n return coords;\n }\n const boundTextElement = getBoundTextElement(element, elementsMap);\n if (boundTextElement) {\n coords = LinearElementEditor.getMinMaxXYWithBoundText(\n element,\n elementsMap,\n [x1, y1, x2, y2],\n boundTextElement,\n );\n }\n\n return coords;\n };\n\n static moveFixedSegment(\n linearElement: LinearElementEditor,\n index: number,\n x: number,\n y: number,\n elementsMap: ElementsMap,\n ): LinearElementEditor {\n const element = LinearElementEditor.getElement(\n linearElement.elementId,\n elementsMap,\n );\n\n if (!element || !isElbowArrow(element)) {\n return linearElement;\n }\n\n if (index && index > 0 && index < element.points.length) {\n const isHorizontal = headingIsHorizontal(\n vectorToHeading(\n vectorFromPoint(element.points[index], element.points[index - 1]),\n ),\n );\n\n const fixedSegments = (element.fixedSegments ?? []).reduce(\n (segments, s) => {\n segments[s.index] = s;\n return segments;\n },\n {} as Record<number, FixedSegment>,\n );\n fixedSegments[index] = {\n index,\n start: pointFrom<LocalPoint>(\n !isHorizontal ? x - element.x : element.points[index - 1][0],\n isHorizontal ? y - element.y : element.points[index - 1][1],\n ),\n end: pointFrom<LocalPoint>(\n !isHorizontal ? x - element.x : element.points[index][0],\n isHorizontal ? y - element.y : element.points[index][1],\n ),\n };\n const nextFixedSegments = Object.values(fixedSegments).sort(\n (a, b) => a.index - b.index,\n );\n\n const offset = nextFixedSegments\n .map((segment) => segment.index)\n .reduce((count, idx) => (idx < index ? count + 1 : count), 0);\n\n mutateElement(element, {\n fixedSegments: nextFixedSegments,\n });\n\n const point = pointFrom<GlobalPoint>(\n element.x +\n (element.fixedSegments![offset].start[0] +\n element.fixedSegments![offset].end[0]) /\n 2,\n element.y +\n (element.fixedSegments![offset].start[1] +\n element.fixedSegments![offset].end[1]) /\n 2,\n );\n\n return {\n ...linearElement,\n segmentMidPointHoveredCoords: point,\n pointerDownState: {\n ...linearElement.pointerDownState,\n segmentMidpoint: {\n added: false,\n index: element.fixedSegments![offset].index,\n value: point,\n },\n },\n };\n }\n\n return linearElement;\n }\n\n static deleteFixedSegment(\n element: ExcalidrawElbowArrowElement,\n index: number,\n ): void {\n mutateElement(element, {\n fixedSegments: element.fixedSegments?.filter(\n (segment) => segment.index !== index,\n ),\n });\n mutateElement(element, {}, true);\n }\n}\n\nconst normalizeSelectedPoints = (\n points: (number | null)[],\n): number[] | null => {\n let nextPoints = [\n ...new Set(points.filter((p) => p !== null && p !== -1)),\n ] as number[];\n nextPoints = nextPoints.sort((a, b) => a - b);\n return nextPoints.length ? nextPoints : null;\n};\n", "import type { ExcalidrawTextContainer } from \"./types\";\n\nexport const originalContainerCache: {\n [id: ExcalidrawTextContainer[\"id\"]]:\n | {\n height: ExcalidrawTextContainer[\"height\"];\n }\n | undefined;\n} = {};\n\nexport const updateOriginalContainerCache = (\n id: ExcalidrawTextContainer[\"id\"],\n height: ExcalidrawTextContainer[\"height\"],\n) => {\n const data =\n originalContainerCache[id] || (originalContainerCache[id] = { height });\n data.height = height;\n return data;\n};\n\nexport const resetOriginalContainerCache = (\n id: ExcalidrawTextContainer[\"id\"],\n) => {\n if (originalContainerCache[id]) {\n delete originalContainerCache[id];\n }\n};\n\nexport const getOriginalContainerHeightFromCache = (\n id: ExcalidrawTextContainer[\"id\"],\n) => {\n return originalContainerCache[id]?.height ?? null;\n};\n", "import { getFontString, arrayToMap } from \"../utils\";\nimport type {\n ElementsMap,\n ExcalidrawElement,\n ExcalidrawElementType,\n ExcalidrawTextContainer,\n ExcalidrawTextElement,\n ExcalidrawTextElementWithContainer,\n NonDeletedExcalidrawElement,\n} from \"./types\";\nimport { mutateElement } from \"./mutateElement\";\nimport {\n ARROW_LABEL_FONT_SIZE_TO_MIN_WIDTH_RATIO,\n ARROW_LABEL_WIDTH_FRACTION,\n BOUND_TEXT_PADDING,\n DEFAULT_FONT_SIZE,\n TEXT_ALIGN,\n VERTICAL_ALIGN,\n} from \"../constants\";\nimport type { MaybeTransformHandleType } from \"./transformHandles\";\nimport { isTextElement } from \".\";\nimport { wrapText } from \"./textWrapping\";\nimport { isBoundToContainer, isArrowElement } from \"./typeChecks\";\nimport { LinearElementEditor } from \"./linearElementEditor\";\nimport type { AppState } from \"../types\";\nimport {\n resetOriginalContainerCache,\n updateOriginalContainerCache,\n} from \"./containerCache\";\nimport type { ExtractSetType } from \"../utility-types\";\nimport { measureText } from \"./textMeasurements\";\n\nexport const redrawTextBoundingBox = (\n textElement: ExcalidrawTextElement,\n container: ExcalidrawElement | null,\n elementsMap: ElementsMap,\n informMutation = true,\n) => {\n let maxWidth = undefined;\n const boundTextUpdates = {\n x: textElement.x,\n y: textElement.y,\n text: textElement.text,\n width: textElement.width,\n height: textElement.height,\n angle: container?.angle ?? textElement.angle,\n };\n\n boundTextUpdates.text = textElement.text;\n\n if (container || !textElement.autoResize) {\n maxWidth = container\n ? getBoundTextMaxWidth(container, textElement)\n : textElement.width;\n boundTextUpdates.text = wrapText(\n textElement.originalText,\n getFontString(textElement),\n maxWidth,\n );\n }\n\n const metrics = measureText(\n boundTextUpdates.text,\n getFontString(textElement),\n textElement.lineHeight,\n );\n\n // Note: only update width for unwrapped text and bound texts (which always have autoResize set to true)\n if (textElement.autoResize) {\n boundTextUpdates.width = metrics.width;\n }\n boundTextUpdates.height = metrics.height;\n\n if (container) {\n const maxContainerHeight = getBoundTextMaxHeight(\n container,\n textElement as ExcalidrawTextElementWithContainer,\n );\n const maxContainerWidth = getBoundTextMaxWidth(container, textElement);\n\n if (!isArrowElement(container) && metrics.height > maxContainerHeight) {\n const nextHeight = computeContainerDimensionForBoundText(\n metrics.height,\n container.type,\n );\n mutateElement(container, { height: nextHeight }, informMutation);\n updateOriginalContainerCache(container.id, nextHeight);\n }\n if (metrics.width > maxContainerWidth) {\n const nextWidth = computeContainerDimensionForBoundText(\n metrics.width,\n container.type,\n );\n mutateElement(container, { width: nextWidth }, informMutation);\n }\n const updatedTextElement = {\n ...textElement,\n ...boundTextUpdates,\n } as ExcalidrawTextElementWithContainer;\n const { x, y } = computeBoundTextPosition(\n container,\n updatedTextElement,\n elementsMap,\n );\n boundTextUpdates.x = x;\n boundTextUpdates.y = y;\n }\n\n mutateElement(textElement, boundTextUpdates, informMutation);\n};\n\nexport const bindTextToShapeAfterDuplication = (\n newElements: ExcalidrawElement[],\n oldElements: ExcalidrawElement[],\n oldIdToDuplicatedId: Map<ExcalidrawElement[\"id\"], ExcalidrawElement[\"id\"]>,\n): void => {\n const newElementsMap = arrayToMap(newElements) as Map<\n ExcalidrawElement[\"id\"],\n ExcalidrawElement\n >;\n oldElements.forEach((element) => {\n const newElementId = oldIdToDuplicatedId.get(element.id) as string;\n const boundTextElementId = getBoundTextElementId(element);\n\n if (boundTextElementId) {\n const newTextElementId = oldIdToDuplicatedId.get(boundTextElementId);\n if (newTextElementId) {\n const newContainer = newElementsMap.get(newElementId);\n if (newContainer) {\n mutateElement(newContainer, {\n boundElements: (element.boundElements || [])\n .filter(\n (boundElement) =>\n boundElement.id !== newTextElementId &&\n boundElement.id !== boundTextElementId,\n )\n .concat({\n type: \"text\",\n id: newTextElementId,\n }),\n });\n }\n const newTextElement = newElementsMap.get(newTextElementId);\n if (newTextElement && isTextElement(newTextElement)) {\n mutateElement(newTextElement, {\n containerId: newContainer ? newElementId : null,\n });\n }\n }\n }\n });\n};\n\nexport const handleBindTextResize = (\n container: NonDeletedExcalidrawElement,\n elementsMap: ElementsMap,\n transformHandleType: MaybeTransformHandleType,\n shouldMaintainAspectRatio = false,\n) => {\n const boundTextElementId = getBoundTextElementId(container);\n if (!boundTextElementId) {\n return;\n }\n resetOriginalContainerCache(container.id);\n const textElement = getBoundTextElement(container, elementsMap);\n if (textElement && textElement.text) {\n if (!container) {\n return;\n }\n\n let text = textElement.text;\n let nextHeight = textElement.height;\n let nextWidth = textElement.width;\n const maxWidth = getBoundTextMaxWidth(container, textElement);\n const maxHeight = getBoundTextMaxHeight(container, textElement);\n let containerHeight = container.height;\n if (\n shouldMaintainAspectRatio ||\n (transformHandleType !== \"n\" && transformHandleType !== \"s\")\n ) {\n if (text) {\n text = wrapText(\n textElement.originalText,\n getFontString(textElement),\n maxWidth,\n );\n }\n const metrics = measureText(\n text,\n getFontString(textElement),\n textElement.lineHeight,\n );\n nextHeight = metrics.height;\n nextWidth = metrics.width;\n }\n // increase height in case text element height exceeds\n if (nextHeight > maxHeight) {\n containerHeight = computeContainerDimensionForBoundText(\n nextHeight,\n container.type,\n );\n\n const diff = containerHeight - container.height;\n // fix the y coord when resizing from ne/nw/n\n const updatedY =\n !isArrowElement(container) &&\n (transformHandleType === \"ne\" ||\n transformHandleType === \"nw\" ||\n transformHandleType === \"n\")\n ? container.y - diff\n : container.y;\n mutateElement(container, {\n height: containerHeight,\n y: updatedY,\n });\n }\n\n mutateElement(textElement, {\n text,\n width: nextWidth,\n height: nextHeight,\n });\n\n if (!isArrowElement(container)) {\n mutateElement(\n textElement,\n computeBoundTextPosition(container, textElement, elementsMap),\n );\n }\n }\n};\n\nexport const computeBoundTextPosition = (\n container: ExcalidrawElement,\n boundTextElement: ExcalidrawTextElementWithContainer,\n elementsMap: ElementsMap,\n) => {\n if (isArrowElement(container)) {\n return LinearElementEditor.getBoundTextElementPosition(\n container,\n boundTextElement,\n elementsMap,\n );\n }\n const containerCoords = getContainerCoords(container);\n const maxContainerHeight = getBoundTextMaxHeight(container, boundTextElement);\n const maxContainerWidth = getBoundTextMaxWidth(container, boundTextElement);\n\n let x;\n let y;\n if (boundTextElement.verticalAlign === VERTICAL_ALIGN.TOP) {\n y = containerCoords.y;\n } else if (boundTextElement.verticalAlign === VERTICAL_ALIGN.BOTTOM) {\n y = containerCoords.y + (maxContainerHeight - boundTextElement.height);\n } else {\n y =\n containerCoords.y +\n (maxContainerHeight / 2 - boundTextElement.height / 2);\n }\n if (boundTextElement.textAlign === TEXT_ALIGN.LEFT) {\n x = containerCoords.x;\n } else if (boundTextElement.textAlign === TEXT_ALIGN.RIGHT) {\n x = containerCoords.x + (maxContainerWidth - boundTextElement.width);\n } else {\n x =\n containerCoords.x + (maxContainerWidth / 2 - boundTextElement.width / 2);\n }\n return { x, y };\n};\n\nexport const getBoundTextElementId = (container: ExcalidrawElement | null) => {\n return container?.boundElements?.length\n ? container?.boundElements?.find((ele) => ele.type === \"text\")?.id || null\n : null;\n};\n\nexport const getBoundTextElement = (\n element: ExcalidrawElement | null,\n elementsMap: ElementsMap,\n) => {\n if (!element) {\n return null;\n }\n const boundTextElementId = getBoundTextElementId(element);\n\n if (boundTextElementId) {\n return (elementsMap.get(boundTextElementId) ||\n null) as ExcalidrawTextElementWithContainer | null;\n }\n return null;\n};\n\nexport const getContainerElement = (\n element: ExcalidrawTextElement | null,\n elementsMap: ElementsMap,\n): ExcalidrawTextContainer | null => {\n if (!element) {\n return null;\n }\n if (element.containerId) {\n return (elementsMap.get(element.containerId) ||\n null) as ExcalidrawTextContainer | null;\n }\n return null;\n};\n\nexport const getContainerCenter = (\n container: ExcalidrawElement,\n appState: AppState,\n elementsMap: ElementsMap,\n) => {\n if (!isArrowElement(container)) {\n return {\n x: container.x + container.width / 2,\n y: container.y + container.height / 2,\n };\n }\n const points = LinearElementEditor.getPointsGlobalCoordinates(\n container,\n elementsMap,\n );\n if (points.length % 2 === 1) {\n const index = Math.floor(container.points.length / 2);\n const midPoint = LinearElementEditor.getPointGlobalCoordinates(\n container,\n container.points[index],\n elementsMap,\n );\n return { x: midPoint[0], y: midPoint[1] };\n }\n const index = container.points.length / 2 - 1;\n let midSegmentMidpoint = LinearElementEditor.getEditorMidPoints(\n container,\n elementsMap,\n appState,\n )[index];\n if (!midSegmentMidpoint) {\n midSegmentMidpoint = LinearElementEditor.getSegmentMidPoint(\n container,\n points[index],\n points[index + 1],\n index + 1,\n elementsMap,\n );\n }\n return { x: midSegmentMidpoint[0], y: midSegmentMidpoint[1] };\n};\n\nexport const getContainerCoords = (container: NonDeletedExcalidrawElement) => {\n let offsetX = BOUND_TEXT_PADDING;\n let offsetY = BOUND_TEXT_PADDING;\n\n if (container.type === \"ellipse\") {\n // The derivation of coordinates is explained in https://github.com/excalidraw/excalidraw/pull/6172\n offsetX += (container.width / 2) * (1 - Math.sqrt(2) / 2);\n offsetY += (container.height / 2) * (1 - Math.sqrt(2) / 2);\n }\n // The derivation of coordinates is explained in https://github.com/excalidraw/excalidraw/pull/6265\n if (container.type === \"diamond\") {\n offsetX += container.width / 4;\n offsetY += container.height / 4;\n }\n return {\n x: container.x + offsetX,\n y: container.y + offsetY,\n };\n};\n\nexport const getTextElementAngle = (\n textElement: ExcalidrawTextElement,\n container: ExcalidrawTextContainer | null,\n) => {\n if (!container || isArrowElement(container)) {\n return textElement.angle;\n }\n return container.angle;\n};\n\nexport const getBoundTextElementPosition = (\n container: ExcalidrawElement,\n boundTextElement: ExcalidrawTextElementWithContainer,\n elementsMap: ElementsMap,\n) => {\n if (isArrowElement(container)) {\n return LinearElementEditor.getBoundTextElementPosition(\n container,\n boundTextElement,\n elementsMap,\n );\n }\n};\n\nexport const shouldAllowVerticalAlign = (\n selectedElements: NonDeletedExcalidrawElement[],\n elementsMap: ElementsMap,\n) => {\n return selectedElements.some((element) => {\n if (isBoundToContainer(element)) {\n const container = getContainerElement(element, elementsMap);\n if (isArrowElement(container)) {\n return false;\n }\n return true;\n }\n return false;\n });\n};\n\nexport const suppportsHorizontalAlign = (\n selectedElements: NonDeletedExcalidrawElement[],\n elementsMap: ElementsMap,\n) => {\n return selectedElements.some((element) => {\n if (isBoundToContainer(element)) {\n const container = getContainerElement(element, elementsMap);\n if (isArrowElement(container)) {\n return false;\n }\n return true;\n }\n\n return isTextElement(element);\n });\n};\n\nconst VALID_CONTAINER_TYPES = new Set([\n \"rectangle\",\n \"ellipse\",\n \"diamond\",\n \"arrow\",\n]);\n\nexport const isValidTextContainer = (element: {\n type: ExcalidrawElementType;\n}) => VALID_CONTAINER_TYPES.has(element.type);\n\nexport const computeContainerDimensionForBoundText = (\n dimension: number,\n containerType: ExtractSetType<typeof VALID_CONTAINER_TYPES>,\n) => {\n dimension = Math.ceil(dimension);\n const padding = BOUND_TEXT_PADDING * 2;\n\n if (containerType === \"ellipse\") {\n return Math.round(((dimension + padding) / Math.sqrt(2)) * 2);\n }\n if (containerType === \"arrow\") {\n return dimension + padding * 8;\n }\n if (containerType === \"diamond\") {\n return 2 * (dimension + padding);\n }\n return dimension + padding;\n};\n\nexport const getBoundTextMaxWidth = (\n container: ExcalidrawElement,\n boundTextElement: ExcalidrawTextElement | null,\n) => {\n const { width } = container;\n if (isArrowElement(container)) {\n const minWidth =\n (boundTextElement?.fontSize ?? DEFAULT_FONT_SIZE) *\n ARROW_LABEL_FONT_SIZE_TO_MIN_WIDTH_RATIO;\n return Math.max(ARROW_LABEL_WIDTH_FRACTION * width, minWidth);\n }\n if (container.type === \"ellipse\") {\n // The width of the largest rectangle inscribed inside an ellipse is\n // Math.round((ellipse.width / 2) * Math.sqrt(2)) which is derived from\n // equation of an ellipse -https://github.com/excalidraw/excalidraw/pull/6172\n return Math.round((width / 2) * Math.sqrt(2)) - BOUND_TEXT_PADDING * 2;\n }\n if (container.type === \"diamond\") {\n // The width of the largest rectangle inscribed inside a rhombus is\n // Math.round(width / 2) - https://github.com/excalidraw/excalidraw/pull/6265\n return Math.round(width / 2) - BOUND_TEXT_PADDING * 2;\n }\n return width - BOUND_TEXT_PADDING * 2;\n};\n\nexport const getBoundTextMaxHeight = (\n container: ExcalidrawElement,\n boundTextElement: ExcalidrawTextElementWithContainer,\n) => {\n const { height } = container;\n if (isArrowElement(container)) {\n const containerHeight = height - BOUND_TEXT_PADDING * 8 * 2;\n if (containerHeight <= 0) {\n return boundTextElement.height;\n }\n return height;\n }\n if (container.type === \"ellipse\") {\n // The height of the largest rectangle inscribed inside an ellipse is\n // Math.round((ellipse.height / 2) * Math.sqrt(2)) which is derived from\n // equation of an ellipse - https://github.com/excalidraw/excalidraw/pull/6172\n return Math.round((height / 2) * Math.sqrt(2)) - BOUND_TEXT_PADDING * 2;\n }\n if (container.type === \"diamond\") {\n // The height of the largest rectangle inscribed inside a rhombus is\n // Math.round(height / 2) - https://github.com/excalidraw/excalidraw/pull/6265\n return Math.round(height / 2) - BOUND_TEXT_PADDING * 2;\n }\n return height - BOUND_TEXT_PADDING * 2;\n};\n\n/** retrieves text from text elements and concatenates to a single string */\nexport const getTextFromElements = (\n elements: readonly ExcalidrawElement[],\n separator = \"\\n\\n\",\n) => {\n const text = elements\n .reduce((acc: string[], element) => {\n if (isTextElement(element)) {\n acc.push(element.text);\n }\n return acc;\n }, [])\n .join(separator);\n return text;\n};\n", "import rough from \"roughjs/bin/rough\";\nimport type {\n ExcalidrawElement,\n ExcalidrawFrameLikeElement,\n ExcalidrawTextElement,\n NonDeletedExcalidrawElement,\n NonDeletedSceneElementsMap,\n Theme,\n} from \"../element/types\";\nimport type { Bounds } from \"../element/bounds\";\nimport { getCommonBounds, getElementAbsoluteCoords } from \"../element/bounds\";\nimport { renderSceneToSvg } from \"../renderer/staticSvgScene\";\nimport { arrayToMap, distance, getFontString, toBrandedType } from \"../utils\";\nimport type { AppState, BinaryFiles } from \"../types\";\nimport {\n COLOR_WHITE,\n DEFAULT_EXPORT_PADDING,\n DEFAULT_ZOOM_VALUE,\n FRAME_STYLE,\n FONT_FAMILY,\n SVG_NS,\n THEME,\n THEME_FILTER,\n MIME_TYPES,\n EXPORT_DATA_TYPES,\n} from \"../constants\";\nimport { getDefaultAppState } from \"../appState\";\nimport { serializeAsJSON } from \"../data/json\";\nimport {\n getInitializedImageElements,\n updateImageCache,\n} from \"../element/image\";\nimport { restoreAppState } from \"../data/restore\";\nimport {\n getElementsOverlappingFrame,\n getFrameLikeElements,\n getFrameLikeTitle,\n getRootElements,\n} from \"../frame\";\nimport { newTextElement } from \"../element\";\nimport { type Mutable } from \"../utility-types\";\nimport { newElementWith } from \"../element/mutateElement\";\nimport { isFrameLikeElement } from \"../element/typeChecks\";\nimport type { RenderableElementsMap } from \"./types\";\nimport { syncInvalidIndices } from \"../fractionalIndex\";\nimport { renderStaticScene } from \"../renderer/staticScene\";\nimport { Fonts } from \"../fonts\";\nimport { base64ToString, decode, encode, stringToBase64 } from \"../data/encode\";\n\nconst truncateText = (element: ExcalidrawTextElement, maxWidth: number) => {\n if (element.width <= maxWidth) {\n return element;\n }\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\")!;\n ctx.font = getFontString({\n fontFamily: element.fontFamily,\n fontSize: element.fontSize,\n });\n\n let text = element.text;\n\n const metrics = ctx.measureText(text);\n\n if (metrics.width > maxWidth) {\n // we iterate from the right, removing characters one by one instead\n // of bulding the string up. This assumes that it's more likely\n // your frame names will overflow by not that many characters\n // (if ever), so it sohuld be faster this way.\n for (let i = text.length; i > 0; i--) {\n const newText = `${text.slice(0, i)}...`;\n if (ctx.measureText(newText).width <= maxWidth) {\n text = newText;\n break;\n }\n }\n }\n return newElementWith(element, { text, width: maxWidth });\n};\n\n/**\n * When exporting frames, we need to render frame labels which are currently\n * being rendered in DOM when editing. Adding the labels as regular text\n * elements seems like a simple hack. In the future we'll want to move to\n * proper canvas rendering, even within editor (instead of DOM).\n */\nconst addFrameLabelsAsTextElements = (\n elements: readonly NonDeletedExcalidrawElement[],\n opts: Pick<AppState, \"exportWithDarkMode\">,\n) => {\n const nextElements: NonDeletedExcalidrawElement[] = [];\n for (const element of elements) {\n if (isFrameLikeElement(element)) {\n let textElement: Mutable<ExcalidrawTextElement> = newTextElement({\n x: element.x,\n y: element.y - FRAME_STYLE.nameOffsetY,\n fontFamily: FONT_FAMILY.Helvetica,\n fontSize: FRAME_STYLE.nameFontSize,\n lineHeight:\n FRAME_STYLE.nameLineHeight as ExcalidrawTextElement[\"lineHeight\"],\n strokeColor: opts.exportWithDarkMode\n ? FRAME_STYLE.nameColorDarkTheme\n : FRAME_STYLE.nameColorLightTheme,\n text: getFrameLikeTitle(element),\n });\n textElement.y -= textElement.height;\n\n textElement = truncateText(textElement, element.width);\n\n nextElements.push(textElement);\n }\n nextElements.push(element);\n }\n\n return nextElements;\n};\n\nconst getFrameRenderingConfig = (\n exportingFrame: ExcalidrawFrameLikeElement | null,\n frameRendering: AppState[\"frameRendering\"] | null,\n): AppState[\"frameRendering\"] => {\n frameRendering = frameRendering || getDefaultAppState().frameRendering;\n return {\n enabled: exportingFrame ? true : frameRendering.enabled,\n outline: exportingFrame ? false : frameRendering.outline,\n name: exportingFrame ? false : frameRendering.name,\n clip: exportingFrame ? true : frameRendering.clip,\n };\n};\n\nconst prepareElementsForRender = ({\n elements,\n exportingFrame,\n frameRendering,\n exportWithDarkMode,\n}: {\n elements: readonly ExcalidrawElement[];\n exportingFrame: ExcalidrawFrameLikeElement | null | undefined;\n frameRendering: AppState[\"frameRendering\"];\n exportWithDarkMode: AppState[\"exportWithDarkMode\"];\n}) => {\n let nextElements: readonly ExcalidrawElement[];\n\n if (exportingFrame) {\n nextElements = getElementsOverlappingFrame(elements, exportingFrame);\n } else if (frameRendering.enabled && frameRendering.name) {\n nextElements = addFrameLabelsAsTextElements(elements, {\n exportWithDarkMode,\n });\n } else {\n nextElements = elements;\n }\n\n return nextElements;\n};\n\nexport type ExportToCanvasData = {\n elements: readonly NonDeletedExcalidrawElement[];\n appState?: Partial<Omit<AppState, \"offsetTop\" | \"offsetLeft\">>;\n files: BinaryFiles | null;\n};\n\nexport type ExportToCanvasConfig = {\n theme?: Theme;\n /**\n * Canvas background. Valid values are:\n *\n * - `undefined` - the background of \"appState.viewBackgroundColor\" is used.\n * - `false` - no background is used (set to \"transparent\").\n * - `string` - should be a valid CSS color.\n *\n * @default undefined\n */\n canvasBackgroundColor?: string | false;\n /**\n * Canvas padding in pixels. Affected by `scale`.\n *\n * When `fit` is set to `none`, padding is added to the content bounding box\n * (including if you set `width` or `height` or `maxWidthOrHeight` or\n * `widthOrHeight`).\n *\n * When `fit` set to `contain`, padding is subtracted from the content\n * bounding box (ensuring the size doesn't exceed the supplied values, with\n * the exeception of using alongside `scale` as noted above), and the padding\n * serves as a minimum distance between the content and the canvas edges, as\n * it may exceed the supplied padding value from one side or the other in\n * order to maintain the aspect ratio. It is recommended to set `position`\n * to `center` when using `fit=contain`.\n *\n * When `fit` is set to `cover`, padding is disabled (set to 0).\n *\n * When `fit` is set to `none` and either `width` or `height` or\n * `maxWidthOrHeight` is set, padding is simply adding to the bounding box\n * and the content may overflow the canvas, thus right or bottom padding\n * may be ignored.\n *\n * @default 0\n */\n padding?: number;\n // -------------------------------------------------------------------------\n /**\n * Makes sure the canvas content fits into a frame of width/height no larger\n * than this value, while maintaining the aspect ratio.\n *\n * Final dimensions can get smaller/larger if used in conjunction with\n * `scale`.\n */\n maxWidthOrHeight?: number;\n /**\n * Scale the canvas content to be excatly this many pixels wide/tall,\n * maintaining the aspect ratio.\n *\n * Cannot be used in conjunction with `maxWidthOrHeight`.\n *\n * Final dimensions can get smaller/larger if used in conjunction with\n * `scale`.\n */\n widthOrHeight?: number;\n // -------------------------------------------------------------------------\n /**\n * Width of the frame. Supply `x` or `y` if you want to ofsset the canvas\n * content.\n *\n * If `width` omitted but `height` supplied, `width` is calculated from the\n * the content's bounding box to preserve the aspect ratio.\n *\n * Defaults to the content bounding box width when both `width` and `height`\n * are omitted.\n */\n width?: number;\n /**\n * Height of the frame.\n *\n * If `height` omitted but `width` supplied, `height` is calculated from the\n * content's bounding box to preserve the aspect ratio.\n *\n * Defaults to the content bounding box height when both `width` and `height`\n * are omitted.\n */\n height?: number;\n /**\n * Left canvas offset. By default the coordinate is relative to the canvas.\n * You can switch to content coordinates by setting `origin` to `content`.\n *\n * Defaults to the `x` postion of the content bounding box.\n */\n x?: number;\n /**\n * Top canvas offset. By default the coordinate is relative to the canvas.\n * You can switch to content coordinates by setting `origin` to `content`.\n *\n * Defaults to the `y` postion of the content bounding box.\n */\n y?: number;\n /**\n * Indicates the coordinate system of the `x` and `y` values.\n *\n * - `canvas` - `x` and `y` are relative to the canvas [0, 0] position.\n * - `content` - `x` and `y` are relative to the content bounding box.\n *\n * @default \"canvas\"\n */\n origin?: \"canvas\" | \"content\";\n /**\n * If dimensions specified and `x` and `y` are not specified, this indicates\n * how the canvas should be scaled.\n *\n * Behavior aligns with the `object-fit` CSS property.\n *\n * - `none` - no scaling.\n * - `contain` - scale to fit the frame. Includes `padding`.\n * - `cover` - scale to fill the frame while maintaining aspect ratio. If\n * content overflows, it will be cropped.\n *\n * If `maxWidthOrHeight` or `widthOrHeight` is set, `fit` is ignored.\n *\n * @default \"contain\" unless `width`, `height`, `maxWidthOrHeight`, or\n * `widthOrHeight` is specified in which case `none` is the default (can be\n * changed). If `x` or `y` are specified, `none` is forced.\n */\n fit?: \"none\" | \"contain\" | \"cover\";\n /**\n * When either `x` or `y` are not specified, indicates how the canvas should\n * be aligned on the respective axis.\n *\n * - `none` - canvas aligned to top left.\n * - `center` - canvas is centered on the axis which is not specified\n * (or both).\n *\n * If `maxWidthOrHeight` or `widthOrHeight` is set, `position` is ignored.\n *\n * @default \"center\"\n */\n position?: \"center\" | \"topLeft\";\n // -------------------------------------------------------------------------\n /**\n * A multiplier to increase/decrease the frame dimensions\n * (content resolution).\n *\n * For example, if your canvas is 300x150 and you set scale to 2, the\n * resulting size will be 600x300.\n *\n * @default 1\n */\n scale?: number;\n /**\n * If you need to suply your own canvas, e.g. in test environments or in\n * Node.js.\n *\n * Do not set `canvas.width/height` or modify the canvas context as that's\n * handled by Excalidraw.\n *\n * Defaults to `document.createElement(\"canvas\")`.\n */\n createCanvas?: () => HTMLCanvasElement;\n /**\n * If you want to supply `width`/`height` dynamically (or derive from the\n * content bounding box), you can use this function.\n *\n * Ignored if `maxWidthOrHeight`, `width`, or `height` is set.\n */\n getDimensions?: (\n width: number,\n height: number,\n ) => { width: number; height: number; scale?: number };\n\n exportingFrame?: ExcalidrawFrameLikeElement | null;\n\n loadFonts?: () => Promise<void>;\n};\n\n/**\n * This API is usually used as a precursor to searializing to Blob or PNG,\n * but can also be used to create a canvas for other purposes.\n */\nexport const exportToCanvas = async ({\n data,\n config,\n}: {\n data: ExportToCanvasData;\n config?: ExportToCanvasConfig;\n}) => {\n // clone\n const cfg = Object.assign({}, config);\n\n const { files } = data;\n const { exportingFrame } = cfg;\n\n const elements = data.elements;\n\n // initialize defaults\n // ---------------------------------------------------------------------------\n\n const appState = restoreAppState(data.appState, null);\n\n const frameRendering = getFrameRenderingConfig(\n exportingFrame ?? null,\n appState.frameRendering ?? null,\n );\n // for canvas export, don't clip if exporting a specific frame as it would\n // clip the corners of the content\n if (exportingFrame) {\n frameRendering.clip = false;\n }\n\n const elementsForRender = prepareElementsForRender({\n elements,\n exportingFrame,\n exportWithDarkMode: appState.exportWithDarkMode,\n frameRendering,\n });\n\n if (exportingFrame) {\n cfg.padding = 0;\n }\n\n cfg.fit =\n cfg.fit ??\n (cfg.width != null ||\n cfg.height != null ||\n cfg.maxWidthOrHeight != null ||\n cfg.widthOrHeight != null\n ? \"contain\"\n : \"none\");\n\n const containPadding = cfg.fit === \"contain\";\n\n if (cfg.x != null || cfg.x != null) {\n cfg.fit = \"none\";\n }\n\n if (cfg.fit === \"cover\") {\n if (cfg.padding && !import.meta.env.PROD) {\n console.warn(\"`padding` is ignored when `fit` is set to `cover`\");\n }\n cfg.padding = 0;\n }\n\n cfg.padding = cfg.padding ?? 0;\n cfg.scale = cfg.scale ?? 1;\n\n cfg.origin = cfg.origin ?? \"canvas\";\n cfg.position = cfg.position ?? \"center\";\n\n if (cfg.maxWidthOrHeight != null && cfg.widthOrHeight != null) {\n if (!import.meta.env.PROD) {\n console.warn(\"`maxWidthOrHeight` is ignored when `widthOrHeight` is set\");\n }\n cfg.maxWidthOrHeight = undefined;\n }\n\n if (\n (cfg.maxWidthOrHeight != null || cfg.width != null || cfg.height != null) &&\n cfg.getDimensions\n ) {\n if (!import.meta.env.PROD) {\n console.warn(\n \"`getDimensions` is ignored when `width`, `height`, or `maxWidthOrHeight` is set\",\n );\n }\n cfg.getDimensions = undefined;\n }\n // ---------------------------------------------------------------------------\n\n // load font faces before continuing, by default leverages browsers' [FontFace API](https://developer.mozilla.org/en-US/docs/Web/API/FontFace)\n if (cfg.loadFonts) {\n await cfg.loadFonts();\n } else {\n await Fonts.loadElementsFonts(elements);\n }\n\n // value used to scale the canvas context. By default, we use this to\n // make the canvas fit into the frame (e.g. for `cfg.fit` set to `contain`).\n // If `cfg.scale` is set, we multiply the resulting canvasScale by it to\n // scale the output further.\n let canvasScale = 1;\n\n const origCanvasSize = getCanvasSize(\n exportingFrame ? [exportingFrame] : getRootElements(elementsForRender),\n );\n\n // cfg.x = undefined;\n // cfg.y = undefined;\n\n // variables for original content bounding box\n const [origX, origY, origWidth, origHeight] = origCanvasSize;\n // variables for target bounding box\n let [x, y, width, height] = origCanvasSize;\n\n if (cfg.width != null) {\n width = cfg.width;\n\n if (cfg.padding && containPadding) {\n width -= cfg.padding * 2;\n }\n\n if (cfg.height) {\n height = cfg.height;\n if (cfg.padding && containPadding) {\n height -= cfg.padding * 2;\n }\n } else {\n // if height not specified, scale the original height to match the new\n // width while maintaining aspect ratio\n height *= width / origWidth;\n }\n } else if (cfg.height != null) {\n height = cfg.height;\n\n if (cfg.padding && containPadding) {\n height -= cfg.padding * 2;\n }\n // width not specified, so scale the original width to match the new\n // height while maintaining aspect ratio\n width *= height / origHeight;\n }\n\n if (cfg.maxWidthOrHeight != null || cfg.widthOrHeight != null) {\n if (containPadding && cfg.padding) {\n if (cfg.maxWidthOrHeight != null) {\n cfg.maxWidthOrHeight -= cfg.padding * 2;\n } else if (cfg.widthOrHeight != null) {\n cfg.widthOrHeight -= cfg.padding * 2;\n }\n }\n\n const max = Math.max(width, height);\n if (cfg.widthOrHeight != null) {\n // calculate by how much do we need to scale the canvas to fit into the\n // target dimension (e.g. target: max 50px, actual: 70x100px => scale: 0.5)\n canvasScale = cfg.widthOrHeight / max;\n } else if (cfg.maxWidthOrHeight != null) {\n canvasScale = cfg.maxWidthOrHeight < max ? cfg.maxWidthOrHeight / max : 1;\n }\n\n width *= canvasScale;\n height *= canvasScale;\n } else if (cfg.getDimensions) {\n const ret = cfg.getDimensions(width, height);\n\n width = ret.width;\n height = ret.height;\n cfg.scale = ret.scale ?? cfg.scale;\n } else if (\n containPadding &&\n cfg.padding &&\n cfg.width == null &&\n cfg.height == null\n ) {\n const whRatio = width / height;\n width -= cfg.padding * 2;\n height -= (cfg.padding * 2) / whRatio;\n }\n\n if (\n (cfg.fit === \"contain\" && !cfg.maxWidthOrHeight) ||\n (containPadding && cfg.padding)\n ) {\n if (cfg.fit === \"contain\") {\n const wRatio = width / origWidth;\n const hRatio = height / origHeight;\n // scale the orig canvas to fit in the target frame\n canvasScale = Math.min(wRatio, hRatio);\n } else {\n const wRatio = (width - cfg.padding * 2) / width;\n const hRatio = (height - cfg.padding * 2) / height;\n canvasScale = Math.min(wRatio, hRatio);\n }\n } else if (cfg.fit === \"cover\") {\n const wRatio = width / origWidth;\n const hRatio = height / origHeight;\n // scale the orig canvas to fill the the target frame\n // (opposite of \"contain\")\n canvasScale = Math.max(wRatio, hRatio);\n }\n\n x = cfg.x ?? origX;\n y = cfg.y ?? origY;\n\n // if we switch to \"content\" coords, we need to offset cfg-supplied\n // coords by the x/y of content bounding box\n if (cfg.origin === \"content\") {\n if (cfg.x != null) {\n x += origX;\n }\n if (cfg.y != null) {\n y += origY;\n }\n }\n\n // Centering the content to the frame.\n // We divide width/height by canvasScale so that we calculate in the original\n // aspect ratio dimensions.\n if (cfg.position === \"center\") {\n x -=\n width / canvasScale / 2 -\n (cfg.x == null ? origWidth : width + cfg.padding * 2) / 2;\n y -=\n height / canvasScale / 2 -\n (cfg.y == null ? origHeight : height + cfg.padding * 2) / 2;\n }\n\n const canvas = cfg.createCanvas\n ? cfg.createCanvas()\n : document.createElement(\"canvas\");\n\n // rescale padding based on current canvasScale factor so that the resulting\n // padding is kept the same as supplied by user (with the exception of\n // `cfg.scale` being set, which also scales the padding)\n const normalizedPadding = cfg.padding / canvasScale;\n\n // scale the whole frame by cfg.scale (on top of whatever canvasScale we\n // calculated above)\n canvasScale *= cfg.scale;\n\n width *= cfg.scale;\n height *= cfg.scale;\n\n canvas.width = width + cfg.padding * 2 * cfg.scale;\n canvas.height = height + cfg.padding * 2 * cfg.scale;\n\n const { imageCache } = await updateImageCache({\n imageCache: new Map(),\n fileIds: getInitializedImageElements(elementsForRender).map(\n (element) => element.fileId,\n ),\n files: files || {},\n });\n\n renderStaticScene({\n canvas,\n rc: rough.canvas(canvas),\n elementsMap: toBrandedType<RenderableElementsMap>(\n arrayToMap(elementsForRender),\n ),\n allElementsMap: toBrandedType<NonDeletedSceneElementsMap>(\n arrayToMap(syncInvalidIndices(elements)),\n ),\n visibleElements: elementsForRender,\n appState: {\n ...appState,\n frameRendering,\n width,\n height,\n offsetLeft: 0,\n offsetTop: 0,\n scrollX: -x + normalizedPadding,\n scrollY: -y + normalizedPadding,\n zoom: { value: DEFAULT_ZOOM_VALUE },\n\n shouldCacheIgnoreZoom: false,\n theme: cfg.theme || THEME.LIGHT,\n },\n scale: canvasScale,\n renderConfig: {\n canvasBackgroundColor:\n cfg.canvasBackgroundColor === false\n ? // null indicates transparent background\n null\n : cfg.canvasBackgroundColor ||\n appState.viewBackgroundColor ||\n COLOR_WHITE,\n imageCache,\n renderGrid: false,\n isExporting: true,\n // empty disables embeddable rendering\n embedsValidationStatus: new Map(),\n elementsPendingErasure: new Set(),\n pendingFlowchartNodes: null,\n },\n });\n\n return canvas;\n};\n\nconst createHTMLComment = (text: string) => {\n // surrounding with spaces to maintain prettified consistency with previous\n // iterations\n // <!-- comment -->\n return document.createComment(` ${text} `);\n};\n\nexport const exportToSvg = async ({\n data,\n config,\n}: {\n data: {\n elements: readonly NonDeletedExcalidrawElement[];\n appState: {\n exportBackground: boolean;\n exportPadding?: number;\n exportScale?: number;\n viewBackgroundColor: string;\n exportWithDarkMode?: boolean;\n exportEmbedScene?: boolean;\n frameRendering?: AppState[\"frameRendering\"];\n };\n files: BinaryFiles | null;\n };\n config?: {\n /**\n * if true, all embeddables passed in will be rendered when possible.\n */\n renderEmbeddables?: boolean;\n exportingFrame?: ExcalidrawFrameLikeElement | null;\n skipInliningFonts?: true;\n reuseImages?: boolean;\n };\n}): Promise<SVGSVGElement> => {\n // clone\n const cfg = Object.assign({}, config);\n\n cfg.exportingFrame = cfg.exportingFrame ?? null;\n\n const elements = data.elements;\n\n const frameRendering = getFrameRenderingConfig(\n cfg?.exportingFrame ?? null,\n data.appState.frameRendering ?? null,\n );\n\n let {\n exportPadding = DEFAULT_EXPORT_PADDING,\n exportWithDarkMode = false,\n viewBackgroundColor,\n exportScale = 1,\n exportEmbedScene,\n } = data.appState;\n\n const elementsForRender = prepareElementsForRender({\n elements,\n exportingFrame: cfg.exportingFrame,\n exportWithDarkMode,\n frameRendering,\n });\n\n if (cfg.exportingFrame) {\n exportPadding = 0;\n }\n\n let [minX, minY, width, height] = getCanvasSize(\n cfg.exportingFrame\n ? [cfg.exportingFrame]\n : getRootElements(elementsForRender),\n );\n\n const offsetX = -minX + exportPadding;\n const offsetY = -minY + exportPadding;\n\n width += exportPadding * 2;\n height += exportPadding * 2;\n\n // ---------------------------------------------------------------------------\n // initialize SVG root element\n // ---------------------------------------------------------------------------\n\n const svgRoot = document.createElementNS(SVG_NS, \"svg\");\n\n svgRoot.setAttribute(\"version\", \"1.1\");\n svgRoot.setAttribute(\"xmlns\", SVG_NS);\n svgRoot.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n svgRoot.setAttribute(\"width\", `${width * exportScale}`);\n svgRoot.setAttribute(\"height\", `${height * exportScale}`);\n if (exportWithDarkMode) {\n svgRoot.setAttribute(\"filter\", THEME_FILTER);\n }\n\n const defsElement = svgRoot.ownerDocument.createElementNS(SVG_NS, \"defs\");\n\n const metadataElement = svgRoot.ownerDocument.createElementNS(\n SVG_NS,\n \"metadata\",\n );\n\n svgRoot.appendChild(createHTMLComment(\"svg-source:excalidraw\"));\n svgRoot.appendChild(metadataElement);\n svgRoot.appendChild(defsElement);\n\n // ---------------------------------------------------------------------------\n // scene embed\n // ---------------------------------------------------------------------------\n\n // we need to serialize the \"original\" elements before we put them through\n // the tempScene hack which duplicates and regenerates ids\n if (exportEmbedScene) {\n try {\n encodeSvgBase64Payload({\n metadataElement,\n // when embedding scene, we want to embed the origionally supplied\n // elements which don't contain the temp frame labels.\n // But it also requires that the exportToSvg is being supplied with\n // only the elements that we're exporting, and no extra.\n payload: serializeAsJSON(\n elements,\n data.appState,\n data.files || {},\n \"local\",\n ),\n });\n } catch (error: any) {\n console.error(error);\n }\n }\n\n // ---------------------------------------------------------------------------\n // frame clip paths\n // ---------------------------------------------------------------------------\n\n const frameElements = getFrameLikeElements(elements);\n\n if (frameElements.length) {\n const elementsMap = arrayToMap(elements);\n\n for (const frame of frameElements) {\n const clipPath = svgRoot.ownerDocument.createElementNS(\n SVG_NS,\n \"clipPath\",\n );\n\n clipPath.setAttribute(\"id\", frame.id);\n\n const [x1, y1, x2, y2] = getElementAbsoluteCoords(frame, elementsMap);\n const cx = (x2 - x1) / 2 - (frame.x - x1);\n const cy = (y2 - y1) / 2 - (frame.y - y1);\n\n const rect = svgRoot.ownerDocument.createElementNS(SVG_NS, \"rect\");\n rect.setAttribute(\n \"transform\",\n `translate(${frame.x + offsetX} ${frame.y + offsetY}) rotate(${\n frame.angle\n } ${cx} ${cy})`,\n );\n rect.setAttribute(\"width\", `${frame.width}`);\n rect.setAttribute(\"height\", `${frame.height}`);\n\n if (!cfg.exportingFrame) {\n rect.setAttribute(\"rx\", `${FRAME_STYLE.radius}`);\n rect.setAttribute(\"ry\", `${FRAME_STYLE.radius}`);\n }\n\n clipPath.appendChild(rect);\n\n defsElement.appendChild(clipPath);\n }\n }\n\n // ---------------------------------------------------------------------------\n // inline font faces\n // ---------------------------------------------------------------------------\n\n const fontFaces = !cfg?.skipInliningFonts\n ? await Fonts.generateFontFaceDeclarations(elements)\n : [];\n\n const delimiter = \"\\n \"; // 6 spaces\n\n const style = svgRoot.ownerDocument.createElementNS(SVG_NS, \"style\");\n style.classList.add(\"style-fonts\");\n style.appendChild(\n document.createTextNode(`${delimiter}${fontFaces.join(delimiter)}`),\n );\n\n defsElement.appendChild(style);\n\n // ---------------------------------------------------------------------------\n // background\n // ---------------------------------------------------------------------------\n\n // render background rect\n if (data.appState.exportBackground && viewBackgroundColor) {\n const rect = svgRoot.ownerDocument.createElementNS(SVG_NS, \"rect\");\n rect.setAttribute(\"x\", \"0\");\n rect.setAttribute(\"y\", \"0\");\n rect.setAttribute(\"width\", `${width}`);\n rect.setAttribute(\"height\", `${height}`);\n rect.setAttribute(\"fill\", viewBackgroundColor);\n svgRoot.appendChild(rect);\n }\n\n // ---------------------------------------------------------------------------\n // render elements\n // ---------------------------------------------------------------------------\n\n const rsvg = rough.svg(svgRoot);\n\n const renderEmbeddables = cfg.renderEmbeddables ?? false;\n\n renderSceneToSvg(\n elementsForRender,\n toBrandedType<RenderableElementsMap>(arrayToMap(elementsForRender)),\n rsvg,\n svgRoot,\n data.files || {},\n {\n offsetX,\n offsetY,\n isExporting: true,\n exportWithDarkMode,\n renderEmbeddables,\n frameRendering,\n canvasBackgroundColor: viewBackgroundColor,\n embedsValidationStatus: renderEmbeddables\n ? new Map(\n elementsForRender\n .filter((element) => isFrameLikeElement(element))\n .map((element) => [element.id, true]),\n )\n : new Map(),\n reuseImages: cfg?.reuseImages ?? true,\n },\n );\n\n // ---------------------------------------------------------------------------\n\n return svgRoot;\n};\n\nexport const encodeSvgBase64Payload = ({\n payload,\n metadataElement,\n}: {\n payload: string;\n metadataElement: SVGMetadataElement;\n}) => {\n const base64 = stringToBase64(\n JSON.stringify(encode({ text: payload })),\n true /* is already byte string */,\n );\n\n metadataElement.appendChild(\n createHTMLComment(`payload-type:${MIME_TYPES.excalidraw}`),\n );\n metadataElement.appendChild(createHTMLComment(\"payload-version:2\"));\n metadataElement.appendChild(createHTMLComment(\"payload-start\"));\n metadataElement.appendChild(document.createTextNode(base64));\n metadataElement.appendChild(createHTMLComment(\"payload-end\"));\n};\n\nexport const decodeSvgBase64Payload = ({ svg }: { svg: string }) => {\n if (svg.includes(`payload-type:${MIME_TYPES.excalidraw}`)) {\n const match = svg.match(\n /<!-- payload-start -->\\s*(.+?)\\s*<!-- payload-end -->/,\n );\n if (!match) {\n throw new Error(\"INVALID\");\n }\n const versionMatch = svg.match(/<!-- payload-version:(\\d+) -->/);\n const version = versionMatch?.[1] || \"1\";\n const isByteString = version !== \"1\";\n\n try {\n const json = base64ToString(match[1], isByteString);\n const encodedData = JSON.parse(json);\n if (!(\"encoded\" in encodedData)) {\n // legacy, un-encoded scene JSON\n if (\n \"type\" in encodedData &&\n encodedData.type === EXPORT_DATA_TYPES.excalidraw\n ) {\n return json;\n }\n throw new Error(\"FAILED\");\n }\n return decode(encodedData);\n } catch (error: any) {\n console.error(error);\n throw new Error(\"FAILED\");\n }\n }\n throw new Error(\"INVALID\");\n};\n\n// calculate smallest area to fit the contents in\nexport const getCanvasSize = (\n elements: readonly NonDeletedExcalidrawElement[],\n): Bounds => {\n const [minX, minY, maxX, maxY] = getCommonBounds(elements);\n const width = distance(minX, maxX);\n const height = distance(minY, maxY);\n\n return [minX, minY, width, height];\n};\n\nexport const getExportSize = (\n elements: readonly NonDeletedExcalidrawElement[],\n exportPadding: number,\n scale: number,\n): [number, number] => {\n const [, , width, height] = getCanvasSize(elements).map((dimension) =>\n Math.trunc(dimension * scale),\n );\n\n return [width, height];\n};\n", "import { sanitizeUrl } from \"@braintree/sanitize-url\";\nimport { escapeDoubleQuotes } from \"../utils\";\n\nexport const normalizeLink = (link: string) => {\n link = link.trim();\n if (!link) {\n return link;\n }\n return sanitizeUrl(escapeDoubleQuotes(link));\n};\n\nexport const isLocalLink = (link: string | null) => {\n return !!(link?.includes(location.origin) || link?.startsWith(\"/\"));\n};\n\n/**\n * Returns URL sanitized and safe for usage in places such as\n * iframe's src attribute or <a> href attributes.\n */\nexport const toValidURL = (link: string) => {\n link = normalizeLink(link);\n\n // make relative links into fully-qualified urls\n if (link.startsWith(\"/\")) {\n return `${location.origin}${link}`;\n }\n\n try {\n new URL(link);\n } catch {\n // if link does not parse as URL, assume invalid and return blank page\n return \"about:blank\";\n }\n\n return link;\n};\n", "import type { Action } from \"./types\";\n\nexport let actions: readonly Action[] = [];\n\nexport const register = <T extends Action>(action: T) => {\n actions = actions.concat(action);\n return action as T & {\n keyTest?: unknown extends T[\"keyTest\"] ? never : T[\"keyTest\"];\n };\n};\n", "import { CURSOR_TYPE, MIME_TYPES, THEME } from \"./constants\";\nimport OpenColor from \"open-color\";\nimport type { AppState, DataURL } from \"./types\";\nimport { isHandToolActive, isEraserActive } from \"./appState\";\n\nconst laserPointerCursorSVG_tag = `<svg viewBox=\"0 0 24 24\" stroke-width=\"1\" width=\"28\" height=\"28\" xmlns=\"http://www.w3.org/2000/svg\">`;\nconst laserPointerCursorBackgroundSVG = `<path d=\"M6.164 11.755a5.314 5.314 0 0 1-4.932-5.298 5.314 5.314 0 0 1 5.311-5.311 5.314 5.314 0 0 1 5.307 5.113l8.773 8.773a3.322 3.322 0 0 1 0 4.696l-.895.895a3.322 3.322 0 0 1-4.696 0l-8.868-8.868Z\" style=\"fill:#fff\"/>`;\nconst laserPointerCursorIconSVG = `<path stroke=\"#1b1b1f\" fill=\"#fff\" d=\"m7.868 11.113 7.773 7.774a2.359 2.359 0 0 0 1.667.691 2.368 2.368 0 0 0 2.357-2.358c0-.625-.248-1.225-.69-1.667L11.201 7.78 9.558 9.469l-1.69 1.643v.001Zm10.273 3.606-3.333 3.333m-3.25-6.583 2 2m-7-7 3 3M3.664 3.625l1 1M2.529 6.922l1.407-.144m5.735-2.932-1.118.866M4.285 9.823l.758-1.194m1.863-6.207-.13 1.408\"/>`;\n\nconst laserPointerCursorDataURL_lightMode = `data:${\n MIME_TYPES.svg\n},${encodeURIComponent(\n `${laserPointerCursorSVG_tag}${laserPointerCursorIconSVG}</svg>`,\n)}`;\nconst laserPointerCursorDataURL_darkMode = `data:${\n MIME_TYPES.svg\n},${encodeURIComponent(\n `${laserPointerCursorSVG_tag}${laserPointerCursorBackgroundSVG}${laserPointerCursorIconSVG}</svg>`,\n)}`;\n\nexport const resetCursor = (interactiveCanvas: HTMLCanvasElement | null) => {\n if (interactiveCanvas) {\n interactiveCanvas.style.cursor = \"\";\n }\n};\n\nexport const setCursor = (\n interactiveCanvas: HTMLCanvasElement | null,\n cursor: string,\n) => {\n if (interactiveCanvas) {\n interactiveCanvas.style.cursor = cursor;\n }\n};\n\nlet eraserCanvasCache: any;\nlet previewDataURL: string;\nexport const setEraserCursor = (\n interactiveCanvas: HTMLCanvasElement | null,\n theme: AppState[\"theme\"],\n) => {\n const cursorImageSizePx = 20;\n\n const drawCanvas = () => {\n const isDarkTheme = theme === THEME.DARK;\n eraserCanvasCache = document.createElement(\"canvas\");\n eraserCanvasCache.theme = theme;\n eraserCanvasCache.height = cursorImageSizePx;\n eraserCanvasCache.width = cursorImageSizePx;\n const context = eraserCanvasCache.getContext(\"2d\")!;\n context.lineWidth = 1;\n context.beginPath();\n context.arc(\n eraserCanvasCache.width / 2,\n eraserCanvasCache.height / 2,\n 5,\n 0,\n 2 * Math.PI,\n );\n context.fillStyle = isDarkTheme ? OpenColor.black : OpenColor.white;\n context.fill();\n context.strokeStyle = isDarkTheme ? OpenColor.white : OpenColor.black;\n context.stroke();\n previewDataURL = eraserCanvasCache.toDataURL(MIME_TYPES.svg) as DataURL;\n };\n if (!eraserCanvasCache || eraserCanvasCache.theme !== theme) {\n drawCanvas();\n }\n\n setCursor(\n interactiveCanvas,\n `url(${previewDataURL}) ${cursorImageSizePx / 2} ${\n cursorImageSizePx / 2\n }, auto`,\n );\n};\n\nexport const setCursorForShape = (\n interactiveCanvas: HTMLCanvasElement | null,\n appState: Pick<AppState, \"activeTool\" | \"theme\">,\n) => {\n if (!interactiveCanvas) {\n return;\n }\n if (appState.activeTool.type === \"selection\") {\n resetCursor(interactiveCanvas);\n } else if (isHandToolActive(appState)) {\n interactiveCanvas.style.cursor = CURSOR_TYPE.GRAB;\n } else if (isEraserActive(appState)) {\n setEraserCursor(interactiveCanvas, appState.theme);\n // do nothing if image tool is selected which suggests there's\n // a image-preview set as the cursor\n // Ignore custom type as well and let host decide\n } else if (appState.activeTool.type === \"laser\") {\n const url =\n appState.theme === THEME.LIGHT\n ? laserPointerCursorDataURL_lightMode\n : laserPointerCursorDataURL_darkMode;\n interactiveCanvas.style.cursor = `url(${url}), auto`;\n } else if (![\"image\", \"custom\"].includes(appState.activeTool.type)) {\n interactiveCanvas.style.cursor = CURSOR_TYPE.CROSSHAIR;\n } else if (\n appState.activeTool.type === \"custom\" &&\n appState.activeTool.customType === \"comment\"\n ) {\n const cursorIconUrl = `data:${MIME_TYPES.svg},${encodeURIComponent(`\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M5.25 18A3.25 3.25 0 0 1 2 14.75v-8.5A3.25 3.25 0 0 1 5.25 3h13.5A3.25 3.25 0 0 1 22 6.25v8.5A3.25 3.25 0 0 1 18.75 18h-5.738L8 21.75a1.25 1.25 0 0 1-1.999-1V18h-.75Zm7.264-1.5h6.236a1.75 1.75 0 0 0 1.75-1.75v-8.5a1.75 1.75 0 0 0-1.75-1.75H5.25A1.75 1.75 0 0 0 3.5 6.25v8.5c0 .966.784 1.75 1.75 1.75h2.249v3.75l5.015-3.75Z\"\n fill=\"${appState.theme === THEME.LIGHT ? \"#000\" : \"#fff\"}\"\n />\n </svg>\n `)}`;\n interactiveCanvas.style.cursor = `url(${cursorIconUrl}) 5 20, auto`;\n } else if (appState.activeTool.type !== \"image\") {\n interactiveCanvas.style.cursor = CURSOR_TYPE.AUTO;\n }\n};\n", "import { Random } from \"roughjs/bin/math\";\nimport { nanoid } from \"nanoid\";\nimport { isTestEnv } from \"./utils\";\n\nlet random = new Random(Date.now());\nlet testIdBase = 0;\n\nexport const randomInteger = () => Math.floor(random.next() * 2 ** 31);\n\nexport const reseed = (seed: number) => {\n random = new Random(seed);\n testIdBase = 0;\n};\n\nexport const randomId = () => (isTestEnv() ? `id${testIdBase++}` : nanoid());\n", "import type {\n ExcalidrawElement,\n ExcalidrawImageElement,\n ExcalidrawTextElement,\n ExcalidrawLinearElement,\n ExcalidrawGenericElement,\n NonDeleted,\n TextAlign,\n GroupId,\n VerticalAlign,\n Arrowhead,\n ExcalidrawFreeDrawElement,\n FontFamilyValues,\n ExcalidrawTextContainer,\n ExcalidrawFrameElement,\n ExcalidrawEmbeddableElement,\n ExcalidrawMagicFrameElement,\n ExcalidrawIframeElement,\n ElementsMap,\n ExcalidrawArrowElement,\n FixedSegment,\n ExcalidrawElbowArrowElement,\n} from \"./types\";\nimport {\n arrayToMap,\n getFontString,\n getUpdatedTimestamp,\n isTestEnv,\n} from \"../utils\";\nimport { randomInteger, randomId } from \"../random\";\nimport { bumpVersion, newElementWith } from \"./mutateElement\";\nimport { getNewGroupIdsForDuplication } from \"../groups\";\nimport type { AppState } from \"../types\";\nimport { getElementAbsoluteCoords } from \".\";\nimport { getResizedElementAbsoluteCoords } from \"./bounds\";\nimport { getBoundTextMaxWidth } from \"./textElement\";\nimport { wrapText } from \"./textWrapping\";\nimport {\n DEFAULT_ELEMENT_PROPS,\n DEFAULT_FONT_FAMILY,\n DEFAULT_FONT_SIZE,\n DEFAULT_TEXT_ALIGN,\n DEFAULT_VERTICAL_ALIGN,\n ORIG_ID,\n VERTICAL_ALIGN,\n} from \"../constants\";\nimport type { MarkOptional, Merge, Mutable } from \"../utility-types\";\nimport { getLineHeight } from \"../fonts\";\nimport type { Radians } from \"@excalidraw/math\";\nimport { normalizeText, measureText } from \"./textMeasurements\";\n\nexport type ElementConstructorOpts = MarkOptional<\n Omit<ExcalidrawGenericElement, \"id\" | \"type\" | \"isDeleted\" | \"updated\">,\n | \"width\"\n | \"height\"\n | \"angle\"\n | \"groupIds\"\n | \"frameId\"\n | \"index\"\n | \"boundElements\"\n | \"seed\"\n | \"version\"\n | \"versionNonce\"\n | \"link\"\n | \"strokeStyle\"\n | \"fillStyle\"\n | \"strokeColor\"\n | \"backgroundColor\"\n | \"roughness\"\n | \"strokeWidth\"\n | \"roundness\"\n | \"locked\"\n | \"opacity\"\n | \"customData\"\n>;\n\nconst _newElementBase = <T extends ExcalidrawElement>(\n type: T[\"type\"],\n {\n x,\n y,\n strokeColor = DEFAULT_ELEMENT_PROPS.strokeColor,\n backgroundColor = DEFAULT_ELEMENT_PROPS.backgroundColor,\n fillStyle = DEFAULT_ELEMENT_PROPS.fillStyle,\n strokeWidth = DEFAULT_ELEMENT_PROPS.strokeWidth,\n strokeStyle = DEFAULT_ELEMENT_PROPS.strokeStyle,\n roughness = DEFAULT_ELEMENT_PROPS.roughness,\n opacity = DEFAULT_ELEMENT_PROPS.opacity,\n width = 0,\n height = 0,\n angle = 0 as Radians,\n groupIds = [],\n frameId = null,\n index = null,\n roundness = null,\n boundElements = null,\n link = null,\n locked = DEFAULT_ELEMENT_PROPS.locked,\n ...rest\n }: ElementConstructorOpts & Omit<Partial<ExcalidrawGenericElement>, \"type\">,\n) => {\n // NOTE (mtolmacs): This is a temporary check to detect extremely large\n // element position or sizing\n if (\n x < -1e6 ||\n x > 1e6 ||\n y < -1e6 ||\n y > 1e6 ||\n width < -1e6 ||\n width > 1e6 ||\n height < -1e6 ||\n height > 1e6\n ) {\n console.error(\"New element size or position is too large\", {\n x,\n y,\n width,\n height,\n // @ts-ignore\n points: rest.points,\n });\n }\n\n // assign type to guard against excess properties\n const element: Merge<ExcalidrawGenericElement, { type: T[\"type\"] }> = {\n id: rest.id || randomId(),\n type,\n x,\n y,\n width,\n height,\n angle,\n strokeColor,\n backgroundColor,\n fillStyle,\n strokeWidth,\n strokeStyle,\n roughness,\n opacity,\n groupIds,\n frameId,\n index,\n roundness,\n seed: rest.seed ?? randomInteger(),\n version: rest.version || 1,\n versionNonce: rest.versionNonce ?? 0,\n isDeleted: false as false,\n boundElements,\n updated: getUpdatedTimestamp(),\n link,\n locked,\n customData: rest.customData,\n };\n return element;\n};\n\nexport const newElement = (\n opts: {\n type: ExcalidrawGenericElement[\"type\"];\n } & ElementConstructorOpts,\n): NonDeleted<ExcalidrawGenericElement> =>\n _newElementBase<ExcalidrawGenericElement>(opts.type, opts);\n\nexport const newEmbeddableElement = (\n opts: {\n type: \"embeddable\";\n } & ElementConstructorOpts,\n): NonDeleted<ExcalidrawEmbeddableElement> => {\n return _newElementBase<ExcalidrawEmbeddableElement>(\"embeddable\", opts);\n};\n\nexport const newIframeElement = (\n opts: {\n type: \"iframe\";\n } & ElementConstructorOpts,\n): NonDeleted<ExcalidrawIframeElement> => {\n return {\n ..._newElementBase<ExcalidrawIframeElement>(\"iframe\", opts),\n };\n};\n\nexport const newFrameElement = (\n opts: {\n name?: string;\n } & ElementConstructorOpts,\n): NonDeleted<ExcalidrawFrameElement> => {\n const frameElement = newElementWith(\n {\n ..._newElementBase<ExcalidrawFrameElement>(\"frame\", opts),\n type: \"frame\",\n name: opts?.name || null,\n },\n {},\n );\n\n return frameElement;\n};\n\nexport const newMagicFrameElement = (\n opts: {\n name?: string;\n } & ElementConstructorOpts,\n): NonDeleted<ExcalidrawMagicFrameElement> => {\n const frameElement = newElementWith(\n {\n ..._newElementBase<ExcalidrawMagicFrameElement>(\"magicframe\", opts),\n type: \"magicframe\",\n name: opts?.name || null,\n },\n {},\n );\n\n return frameElement;\n};\n\n/** computes element x/y offset based on textAlign/verticalAlign */\nconst getTextElementPositionOffsets = (\n opts: {\n textAlign: ExcalidrawTextElement[\"textAlign\"];\n verticalAlign: ExcalidrawTextElement[\"verticalAlign\"];\n },\n metrics: {\n width: number;\n height: number;\n },\n) => {\n return {\n x:\n opts.textAlign === \"center\"\n ? metrics.width / 2\n : opts.textAlign === \"right\"\n ? metrics.width\n : 0,\n y: opts.verticalAlign === \"middle\" ? metrics.height / 2 : 0,\n };\n};\n\nexport const newTextElement = (\n opts: {\n text: string;\n originalText?: string;\n fontSize?: number;\n fontFamily?: FontFamilyValues;\n textAlign?: TextAlign;\n verticalAlign?: VerticalAlign;\n containerId?: ExcalidrawTextContainer[\"id\"] | null;\n lineHeight?: ExcalidrawTextElement[\"lineHeight\"];\n autoResize?: ExcalidrawTextElement[\"autoResize\"];\n } & ElementConstructorOpts,\n): NonDeleted<ExcalidrawTextElement> => {\n const fontFamily = opts.fontFamily || DEFAULT_FONT_FAMILY;\n const fontSize = opts.fontSize || DEFAULT_FONT_SIZE;\n const lineHeight = opts.lineHeight || getLineHeight(fontFamily);\n const text = normalizeText(opts.text);\n const metrics = measureText(\n text,\n getFontString({ fontFamily, fontSize }),\n lineHeight,\n );\n const textAlign = opts.textAlign || DEFAULT_TEXT_ALIGN;\n const verticalAlign = opts.verticalAlign || DEFAULT_VERTICAL_ALIGN;\n const offsets = getTextElementPositionOffsets(\n { textAlign, verticalAlign },\n metrics,\n );\n\n const textElementProps: ExcalidrawTextElement = {\n ..._newElementBase<ExcalidrawTextElement>(\"text\", opts),\n text,\n fontSize,\n fontFamily,\n textAlign,\n verticalAlign,\n x: opts.x - offsets.x,\n y: opts.y - offsets.y,\n width: metrics.width,\n height: metrics.height,\n containerId: opts.containerId || null,\n originalText: opts.originalText ?? text,\n autoResize: opts.autoResize ?? true,\n lineHeight,\n };\n\n const textElement: ExcalidrawTextElement = newElementWith(\n textElementProps,\n {},\n );\n\n return textElement;\n};\n\nconst getAdjustedDimensions = (\n element: ExcalidrawTextElement,\n elementsMap: ElementsMap,\n nextText: string,\n): {\n x: number;\n y: number;\n width: number;\n height: number;\n} => {\n let { width: nextWidth, height: nextHeight } = measureText(\n nextText,\n getFontString(element),\n element.lineHeight,\n );\n\n // wrapped text\n if (!element.autoResize) {\n nextWidth = element.width;\n }\n\n const { textAlign, verticalAlign } = element;\n let x: number;\n let y: number;\n if (\n textAlign === \"center\" &&\n verticalAlign === VERTICAL_ALIGN.MIDDLE &&\n !element.containerId &&\n element.autoResize\n ) {\n const prevMetrics = measureText(\n element.text,\n getFontString(element),\n element.lineHeight,\n );\n const offsets = getTextElementPositionOffsets(element, {\n width: nextWidth - prevMetrics.width,\n height: nextHeight - prevMetrics.height,\n });\n\n x = element.x - offsets.x;\n y = element.y - offsets.y;\n } else {\n const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);\n\n const [nextX1, nextY1, nextX2, nextY2] = getResizedElementAbsoluteCoords(\n element,\n nextWidth,\n nextHeight,\n false,\n );\n const deltaX1 = (x1 - nextX1) / 2;\n const deltaY1 = (y1 - nextY1) / 2;\n const deltaX2 = (x2 - nextX2) / 2;\n const deltaY2 = (y2 - nextY2) / 2;\n\n [x, y] = adjustXYWithRotation(\n {\n s: true,\n e: textAlign === \"center\" || textAlign === \"left\",\n w: textAlign === \"center\" || textAlign === \"right\",\n },\n element.x,\n element.y,\n element.angle,\n deltaX1,\n deltaY1,\n deltaX2,\n deltaY2,\n );\n }\n\n return {\n width: nextWidth,\n height: nextHeight,\n x: Number.isFinite(x) ? x : element.x,\n y: Number.isFinite(y) ? y : element.y,\n };\n};\n\nconst adjustXYWithRotation = (\n sides: {\n n?: boolean;\n e?: boolean;\n s?: boolean;\n w?: boolean;\n },\n x: number,\n y: number,\n angle: number,\n deltaX1: number,\n deltaY1: number,\n deltaX2: number,\n deltaY2: number,\n): [number, number] => {\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n if (sides.e && sides.w) {\n x += deltaX1 + deltaX2;\n } else if (sides.e) {\n x += deltaX1 * (1 + cos);\n y += deltaX1 * sin;\n x += deltaX2 * (1 - cos);\n y += deltaX2 * -sin;\n } else if (sides.w) {\n x += deltaX1 * (1 - cos);\n y += deltaX1 * -sin;\n x += deltaX2 * (1 + cos);\n y += deltaX2 * sin;\n }\n\n if (sides.n && sides.s) {\n y += deltaY1 + deltaY2;\n } else if (sides.n) {\n x += deltaY1 * sin;\n y += deltaY1 * (1 - cos);\n x += deltaY2 * -sin;\n y += deltaY2 * (1 + cos);\n } else if (sides.s) {\n x += deltaY1 * -sin;\n y += deltaY1 * (1 + cos);\n x += deltaY2 * sin;\n y += deltaY2 * (1 - cos);\n }\n return [x, y];\n};\n\nexport const refreshTextDimensions = (\n textElement: ExcalidrawTextElement,\n container: ExcalidrawTextContainer | null,\n elementsMap: ElementsMap,\n text = textElement.text,\n) => {\n if (textElement.isDeleted) {\n return;\n }\n if (container || !textElement.autoResize) {\n text = wrapText(\n text,\n getFontString(textElement),\n container\n ? getBoundTextMaxWidth(container, textElement)\n : textElement.width,\n );\n }\n const dimensions = getAdjustedDimensions(textElement, elementsMap, text);\n return { text, ...dimensions };\n};\n\nexport const newFreeDrawElement = (\n opts: {\n type: \"freedraw\";\n points?: ExcalidrawFreeDrawElement[\"points\"];\n simulatePressure: boolean;\n pressures?: ExcalidrawFreeDrawElement[\"pressures\"];\n } & ElementConstructorOpts,\n): NonDeleted<ExcalidrawFreeDrawElement> => {\n return {\n ..._newElementBase<ExcalidrawFreeDrawElement>(opts.type, opts),\n points: opts.points || [],\n pressures: opts.pressures || [],\n simulatePressure: opts.simulatePressure,\n lastCommittedPoint: null,\n };\n};\n\nexport const newLinearElement = (\n opts: {\n type: ExcalidrawLinearElement[\"type\"];\n points?: ExcalidrawLinearElement[\"points\"];\n } & ElementConstructorOpts,\n): NonDeleted<ExcalidrawLinearElement> => {\n return {\n ..._newElementBase<ExcalidrawLinearElement>(opts.type, opts),\n points: opts.points || [],\n lastCommittedPoint: null,\n startBinding: null,\n endBinding: null,\n startArrowhead: null,\n endArrowhead: null,\n };\n};\n\nexport const newArrowElement = <T extends boolean>(\n opts: {\n type: ExcalidrawArrowElement[\"type\"];\n startArrowhead?: Arrowhead | null;\n endArrowhead?: Arrowhead | null;\n points?: ExcalidrawArrowElement[\"points\"];\n elbowed?: T;\n fixedSegments?: FixedSegment[] | null;\n } & ElementConstructorOpts,\n): T extends true\n ? NonDeleted<ExcalidrawElbowArrowElement>\n : NonDeleted<ExcalidrawArrowElement> => {\n if (opts.elbowed) {\n return {\n ..._newElementBase<ExcalidrawElbowArrowElement>(opts.type, opts),\n points: opts.points || [],\n lastCommittedPoint: null,\n startBinding: null,\n endBinding: null,\n startArrowhead: opts.startArrowhead || null,\n endArrowhead: opts.endArrowhead || null,\n elbowed: true,\n fixedSegments: opts.fixedSegments || [],\n startIsSpecial: false,\n endIsSpecial: false,\n } as NonDeleted<ExcalidrawElbowArrowElement>;\n }\n\n return {\n ..._newElementBase<ExcalidrawArrowElement>(opts.type, opts),\n points: opts.points || [],\n lastCommittedPoint: null,\n startBinding: null,\n endBinding: null,\n startArrowhead: opts.startArrowhead || null,\n endArrowhead: opts.endArrowhead || null,\n elbowed: false,\n } as T extends true\n ? NonDeleted<ExcalidrawElbowArrowElement>\n : NonDeleted<ExcalidrawArrowElement>;\n};\n\nexport const newImageElement = (\n opts: {\n type: ExcalidrawImageElement[\"type\"];\n status?: ExcalidrawImageElement[\"status\"];\n fileId?: ExcalidrawImageElement[\"fileId\"];\n scale?: ExcalidrawImageElement[\"scale\"];\n crop?: ExcalidrawImageElement[\"crop\"];\n } & ElementConstructorOpts,\n): NonDeleted<ExcalidrawImageElement> => {\n return {\n ..._newElementBase<ExcalidrawImageElement>(\"image\", opts),\n // in the future we'll support changing stroke color for some SVG elements,\n // and `transparent` will likely mean \"use original colors of the image\"\n strokeColor: \"transparent\",\n status: opts.status ?? \"pending\",\n fileId: opts.fileId ?? null,\n scale: opts.scale ?? [1, 1],\n crop: opts.crop ?? null,\n };\n};\n\n// Simplified deep clone for the purpose of cloning ExcalidrawElement.\n//\n// Only clones plain objects and arrays. Doesn't clone Date, RegExp, Map, Set,\n// Typed arrays and other non-null objects.\n//\n// Adapted from https://github.com/lukeed/klona\n//\n// The reason for `deepCopyElement()` wrapper is type safety (only allow\n// passing ExcalidrawElement as the top-level argument).\nconst _deepCopyElement = (val: any, depth: number = 0) => {\n // only clone non-primitives\n if (val == null || typeof val !== \"object\") {\n return val;\n }\n\n const objectType = Object.prototype.toString.call(val);\n\n if (objectType === \"[object Object]\") {\n const tmp =\n typeof val.constructor === \"function\"\n ? Object.create(Object.getPrototypeOf(val))\n : {};\n for (const key in val) {\n if (val.hasOwnProperty(key)) {\n // don't copy non-serializable objects like these caches. They'll be\n // populated when the element is rendered.\n if (depth === 0 && (key === \"shape\" || key === \"canvas\")) {\n continue;\n }\n tmp[key] = _deepCopyElement(val[key], depth + 1);\n }\n }\n return tmp;\n }\n\n if (Array.isArray(val)) {\n let k = val.length;\n const arr = new Array(k);\n while (k--) {\n arr[k] = _deepCopyElement(val[k], depth + 1);\n }\n return arr;\n }\n\n // we're not cloning non-array & non-plain-object objects because we\n // don't support them on excalidraw elements yet. If we do, we need to make\n // sure we start cloning them, so let's warn about it.\n if (import.meta.env.DEV) {\n if (\n objectType !== \"[object Object]\" &&\n objectType !== \"[object Array]\" &&\n objectType.startsWith(\"[object \")\n ) {\n console.warn(\n `_deepCloneElement: unexpected object type ${objectType}. This value will not be cloned!`,\n );\n }\n }\n\n return val;\n};\n\n/**\n * Clones ExcalidrawElement data structure. Does not regenerate id, nonce, or\n * any value. The purpose is to to break object references for immutability\n * reasons, whenever we want to keep the original element, but ensure it's not\n * mutated.\n *\n * Only clones plain objects and arrays. Doesn't clone Date, RegExp, Map, Set,\n * Typed arrays and other non-null objects.\n */\nexport const deepCopyElement = <T extends ExcalidrawElement>(\n val: T,\n): Mutable<T> => {\n return _deepCopyElement(val);\n};\n\nconst __test__defineOrigId = (clonedObj: object, origId: string) => {\n Object.defineProperty(clonedObj, ORIG_ID, {\n value: origId,\n writable: false,\n enumerable: false,\n });\n};\n\n/**\n * utility wrapper to generate new id.\n */\nconst regenerateId = () => {\n return randomId();\n};\n\n/**\n * Duplicate an element, often used in the alt-drag operation.\n * Note that this method has gotten a bit complicated since the\n * introduction of gruoping/ungrouping elements.\n * @param editingGroupId The current group being edited. The new\n * element will inherit this group and its\n * parents.\n * @param groupIdMapForOperation A Map that maps old group IDs to\n * duplicated ones. If you are duplicating\n * multiple elements at once, share this map\n * amongst all of them\n * @param element Element to duplicate\n * @param overrides Any element properties to override\n */\nexport const duplicateElement = <TElement extends ExcalidrawElement>(\n editingGroupId: AppState[\"editingGroupId\"],\n groupIdMapForOperation: Map<GroupId, GroupId>,\n element: TElement,\n overrides?: Partial<TElement>,\n): Readonly<TElement> => {\n let copy = deepCopyElement(element);\n\n if (isTestEnv()) {\n __test__defineOrigId(copy, element.id);\n }\n\n copy.id = regenerateId();\n copy.boundElements = null;\n copy.updated = getUpdatedTimestamp();\n copy.seed = randomInteger();\n copy.groupIds = getNewGroupIdsForDuplication(\n copy.groupIds,\n editingGroupId,\n (groupId) => {\n if (!groupIdMapForOperation.has(groupId)) {\n groupIdMapForOperation.set(groupId, regenerateId());\n }\n return groupIdMapForOperation.get(groupId)!;\n },\n );\n if (overrides) {\n copy = Object.assign(copy, overrides);\n }\n return copy;\n};\n\n/**\n * Clones elements, regenerating their ids (including bindings) and group ids.\n *\n * If bindings don't exist in the elements array, they are removed. Therefore,\n * it's advised to supply the whole elements array, or sets of elements that\n * are encapsulated (such as library items), if the purpose is to retain\n * bindings to the cloned elements intact.\n *\n * NOTE by default does not randomize or regenerate anything except the id.\n */\nexport const duplicateElements = (\n elements: readonly ExcalidrawElement[],\n opts?: {\n /** NOTE also updates version flags and `updated` */\n randomizeSeed: boolean;\n },\n) => {\n const clonedElements: ExcalidrawElement[] = [];\n\n const origElementsMap = arrayToMap(elements);\n\n // used for for migrating old ids to new ids\n const elementNewIdsMap = new Map<\n /* orig */ ExcalidrawElement[\"id\"],\n /* new */ ExcalidrawElement[\"id\"]\n >();\n\n const maybeGetNewId = (id: ExcalidrawElement[\"id\"]) => {\n // if we've already migrated the element id, return the new one directly\n if (elementNewIdsMap.has(id)) {\n return elementNewIdsMap.get(id)!;\n }\n // if we haven't migrated the element id, but an old element with the same\n // id exists, generate a new id for it and return it\n if (origElementsMap.has(id)) {\n const newId = regenerateId();\n elementNewIdsMap.set(id, newId);\n return newId;\n }\n // if old element doesn't exist, return null to mark it for removal\n return null;\n };\n\n const groupNewIdsMap = new Map</* orig */ GroupId, /* new */ GroupId>();\n\n for (const element of elements) {\n const clonedElement: Mutable<ExcalidrawElement> = _deepCopyElement(element);\n\n clonedElement.id = maybeGetNewId(element.id)!;\n if (isTestEnv()) {\n __test__defineOrigId(clonedElement, element.id);\n }\n\n if (opts?.randomizeSeed) {\n clonedElement.seed = randomInteger();\n bumpVersion(clonedElement);\n }\n\n if (clonedElement.groupIds) {\n clonedElement.groupIds = clonedElement.groupIds.map((groupId) => {\n if (!groupNewIdsMap.has(groupId)) {\n groupNewIdsMap.set(groupId, regenerateId());\n }\n return groupNewIdsMap.get(groupId)!;\n });\n }\n\n if (\"containerId\" in clonedElement && clonedElement.containerId) {\n const newContainerId = maybeGetNewId(clonedElement.containerId);\n clonedElement.containerId = newContainerId;\n }\n\n if (\"boundElements\" in clonedElement && clonedElement.boundElements) {\n clonedElement.boundElements = clonedElement.boundElements.reduce(\n (\n acc: Mutable<NonNullable<ExcalidrawElement[\"boundElements\"]>>,\n binding,\n ) => {\n const newBindingId = maybeGetNewId(binding.id);\n if (newBindingId) {\n acc.push({ ...binding, id: newBindingId });\n }\n return acc;\n },\n [],\n );\n }\n\n if (\"endBinding\" in clonedElement && clonedElement.endBinding) {\n const newEndBindingId = maybeGetNewId(clonedElement.endBinding.elementId);\n clonedElement.endBinding = newEndBindingId\n ? {\n ...clonedElement.endBinding,\n elementId: newEndBindingId,\n }\n : null;\n }\n if (\"startBinding\" in clonedElement && clonedElement.startBinding) {\n const newEndBindingId = maybeGetNewId(\n clonedElement.startBinding.elementId,\n );\n clonedElement.startBinding = newEndBindingId\n ? {\n ...clonedElement.startBinding,\n elementId: newEndBindingId,\n }\n : null;\n }\n\n if (clonedElement.frameId) {\n clonedElement.frameId = maybeGetNewId(clonedElement.frameId);\n }\n\n clonedElements.push(clonedElement);\n }\n\n return clonedElements;\n};\n", "import { generateNKeysBetween } from \"fractional-indexing\";\nimport { mutateElement } from \"./element/mutateElement\";\nimport type {\n ExcalidrawElement,\n FractionalIndex,\n OrderedExcalidrawElement,\n} from \"./element/types\";\nimport { InvalidFractionalIndexError } from \"./errors\";\nimport { hasBoundTextElement } from \"./element/typeChecks\";\nimport { getBoundTextElement } from \"./element/textElement\";\nimport { arrayToMap } from \"./utils\";\n\n/**\n * Envisioned relation between array order and fractional indices:\n *\n * 1) Array (or array-like ordered data structure) should be used as a cache of elements order, hiding the internal fractional indices implementation.\n * - it's undesirable to perform reorder for each related operation, therefore it's necessary to cache the order defined by fractional indices into an ordered data structure\n * - it's easy enough to define the order of the elements from the outside (boundaries), without worrying about the underlying structure of fractional indices (especially for the host apps)\n * - it's necessary to always keep the array support for backwards compatibility (restore) - old scenes, old libraries, supporting multiple excalidraw versions etc.\n * - it's necessary to always keep the fractional indices in sync with the array order\n * - elements with invalid indices should be detected and synced, without altering the already valid indices\n *\n * 2) Fractional indices should be used to reorder the elements, whenever the cached order is expected to be invalidated.\n * - as the fractional indices are encoded as part of the elements, it opens up possibilities for incremental-like APIs\n * - re-order based on fractional indices should be part of (multiplayer) operations such as reconciliation & undo/redo\n * - technically all the z-index actions could perform also re-order based on fractional indices,but in current state it would not bring much benefits,\n * as it's faster & more efficient to perform re-order based on array manipulation and later synchronisation of moved indices with the array order\n */\n\n/**\n * Ensure that all elements have valid fractional indices.\n *\n * @throws `InvalidFractionalIndexError` if invalid index is detected.\n */\nexport const validateFractionalIndices = (\n elements: readonly ExcalidrawElement[],\n {\n shouldThrow = false,\n includeBoundTextValidation = false,\n ignoreLogs,\n reconciliationContext,\n }: {\n shouldThrow: boolean;\n includeBoundTextValidation: boolean;\n ignoreLogs?: true;\n reconciliationContext?: {\n localElements: ReadonlyArray<ExcalidrawElement>;\n remoteElements: ReadonlyArray<ExcalidrawElement>;\n };\n },\n) => {\n const errorMessages = [];\n const stringifyElement = (element: ExcalidrawElement | void) =>\n `${element?.index}:${element?.id}:${element?.type}:${element?.isDeleted}:${element?.version}:${element?.versionNonce}`;\n\n const indices = elements.map((x) => x.index);\n for (const [i, index] of indices.entries()) {\n const predecessorIndex = indices[i - 1];\n const successorIndex = indices[i + 1];\n\n if (!isValidFractionalIndex(index, predecessorIndex, successorIndex)) {\n errorMessages.push(\n `Fractional indices invariant has been compromised: \"${stringifyElement(\n elements[i - 1],\n )}\", \"${stringifyElement(elements[i])}\", \"${stringifyElement(\n elements[i + 1],\n )}\"`,\n );\n }\n\n // disabled by default, as we don't fix it\n if (includeBoundTextValidation && hasBoundTextElement(elements[i])) {\n const container = elements[i];\n const text = getBoundTextElement(container, arrayToMap(elements));\n\n if (text && text.index! <= container.index!) {\n errorMessages.push(\n `Fractional indices invariant for bound elements has been compromised: \"${stringifyElement(\n text,\n )}\", \"${stringifyElement(container)}\"`,\n );\n }\n }\n }\n\n if (errorMessages.length) {\n const error = new InvalidFractionalIndexError();\n const additionalContext = [];\n\n if (reconciliationContext) {\n additionalContext.push(\"Additional reconciliation context:\");\n additionalContext.push(\n reconciliationContext.localElements.map((x) => stringifyElement(x)),\n );\n additionalContext.push(\n reconciliationContext.remoteElements.map((x) => stringifyElement(x)),\n );\n }\n\n if (!ignoreLogs) {\n // report just once and with the stacktrace\n console.error(\n errorMessages.join(\"\\n\\n\"),\n error.stack,\n elements.map((x) => stringifyElement(x)),\n ...additionalContext,\n );\n }\n\n if (shouldThrow) {\n // if enabled, gather all the errors first, throw once\n throw error;\n }\n }\n};\n\n/**\n * Order the elements based on the fractional indices.\n * - when fractional indices are identical, break the tie based on the element id\n * - when there is no fractional index in one of the elements, respect the order of the array\n */\nexport const orderByFractionalIndex = (\n elements: OrderedExcalidrawElement[],\n) => {\n return elements.sort((a, b) => {\n // in case the indices are not the defined at runtime\n if (isOrderedElement(a) && isOrderedElement(b)) {\n if (a.index < b.index) {\n return -1;\n } else if (a.index > b.index) {\n return 1;\n }\n\n // break ties based on the element id\n return a.id < b.id ? -1 : 1;\n }\n\n // defensively keep the array order\n return 1;\n });\n};\n\n/**\n * Synchronizes invalid fractional indices of moved elements with the array order by mutating passed elements.\n * If the synchronization fails or the result is invalid, it fallbacks to `syncInvalidIndices`.\n */\nexport const syncMovedIndices = (\n elements: readonly ExcalidrawElement[],\n movedElements: Map<string, ExcalidrawElement>,\n): OrderedExcalidrawElement[] => {\n try {\n const indicesGroups = getMovedIndicesGroups(elements, movedElements);\n\n // try generatating indices, throws on invalid movedElements\n const elementsUpdates = generateIndices(elements, indicesGroups);\n const elementsCandidates = elements.map((x) =>\n elementsUpdates.has(x) ? { ...x, ...elementsUpdates.get(x) } : x,\n );\n\n // ensure next indices are valid before mutation, throws on invalid ones\n validateFractionalIndices(\n elementsCandidates,\n // we don't autofix invalid bound text indices, hence don't include it in the validation\n {\n includeBoundTextValidation: false,\n shouldThrow: true,\n ignoreLogs: true,\n },\n );\n\n // split mutation so we don't end up in an incosistent state\n for (const [element, update] of elementsUpdates) {\n mutateElement(element, update, false);\n }\n } catch (e) {\n // fallback to default sync\n syncInvalidIndices(elements);\n }\n\n return elements as OrderedExcalidrawElement[];\n};\n\n/**\n * Synchronizes all invalid fractional indices with the array order by mutating passed elements.\n *\n * WARN: in edge cases it could modify the elements which were not moved, as it's impossible to guess the actually moved elements from the elements array itself.\n */\nexport const syncInvalidIndices = (\n elements: readonly ExcalidrawElement[],\n): OrderedExcalidrawElement[] => {\n const indicesGroups = getInvalidIndicesGroups(elements);\n const elementsUpdates = generateIndices(elements, indicesGroups);\n for (const [element, update] of elementsUpdates) {\n mutateElement(element, update, false);\n }\n\n return elements as OrderedExcalidrawElement[];\n};\n\n/**\n * Get contiguous groups of indices of passed moved elements.\n *\n * NOTE: First and last elements within the groups are indices of lower and upper bounds.\n */\nconst getMovedIndicesGroups = (\n elements: readonly ExcalidrawElement[],\n movedElements: Map<string, ExcalidrawElement>,\n) => {\n const indicesGroups: number[][] = [];\n\n let i = 0;\n\n while (i < elements.length) {\n if (movedElements.has(elements[i].id)) {\n const indicesGroup = [i - 1, i]; // push the lower bound index as the first item\n\n while (++i < elements.length) {\n if (!movedElements.has(elements[i].id)) {\n break;\n }\n\n indicesGroup.push(i);\n }\n\n indicesGroup.push(i); // push the upper bound index as the last item\n indicesGroups.push(indicesGroup);\n } else {\n i++;\n }\n }\n\n return indicesGroups;\n};\n\n/**\n * Gets contiguous groups of all invalid indices automatically detected inside the elements array.\n *\n * WARN: First and last items within the groups do NOT have to be contiguous, those are the found lower and upper bounds!\n */\nconst getInvalidIndicesGroups = (elements: readonly ExcalidrawElement[]) => {\n const indicesGroups: number[][] = [];\n\n // once we find lowerBound / upperBound, it cannot be lower than that, so we cache it for better perf.\n let lowerBound: ExcalidrawElement[\"index\"] | undefined = undefined;\n let upperBound: ExcalidrawElement[\"index\"] | undefined = undefined;\n let lowerBoundIndex: number = -1;\n let upperBoundIndex: number = 0;\n\n /** @returns maybe valid lowerBound */\n const getLowerBound = (\n index: number,\n ): [ExcalidrawElement[\"index\"] | undefined, number] => {\n const lowerBound = elements[lowerBoundIndex]\n ? elements[lowerBoundIndex].index\n : undefined;\n\n // we are already iterating left to right, therefore there is no need for additional looping\n const candidate = elements[index - 1]?.index;\n\n if (\n (!lowerBound && candidate) || // first lowerBound\n (lowerBound && candidate && candidate > lowerBound) // next lowerBound\n ) {\n // WARN: candidate's index could be higher or same as the current element's index\n return [candidate, index - 1];\n }\n\n // cache hit! take the last lower bound\n return [lowerBound, lowerBoundIndex];\n };\n\n /** @returns always valid upperBound */\n const getUpperBound = (\n index: number,\n ): [ExcalidrawElement[\"index\"] | undefined, number] => {\n const upperBound = elements[upperBoundIndex]\n ? elements[upperBoundIndex].index\n : undefined;\n\n // cache hit! don't let it find the upper bound again\n if (upperBound && index < upperBoundIndex) {\n return [upperBound, upperBoundIndex];\n }\n\n // set the current upperBoundIndex as the starting point\n let i = upperBoundIndex;\n while (++i < elements.length) {\n const candidate = elements[i]?.index;\n\n if (\n (!upperBound && candidate) || // first upperBound\n (upperBound && candidate && candidate > upperBound) // next upperBound\n ) {\n return [candidate, i];\n }\n }\n\n // we reached the end, sky is the limit\n return [undefined, i];\n };\n\n let i = 0;\n\n while (i < elements.length) {\n const current = elements[i].index;\n [lowerBound, lowerBoundIndex] = getLowerBound(i);\n [upperBound, upperBoundIndex] = getUpperBound(i);\n\n if (!isValidFractionalIndex(current, lowerBound, upperBound)) {\n // push the lower bound index as the first item\n const indicesGroup = [lowerBoundIndex, i];\n\n while (++i < elements.length) {\n const current = elements[i].index;\n const [nextLowerBound, nextLowerBoundIndex] = getLowerBound(i);\n const [nextUpperBound, nextUpperBoundIndex] = getUpperBound(i);\n\n if (isValidFractionalIndex(current, nextLowerBound, nextUpperBound)) {\n break;\n }\n\n // assign bounds only for the moved elements\n [lowerBound, lowerBoundIndex] = [nextLowerBound, nextLowerBoundIndex];\n [upperBound, upperBoundIndex] = [nextUpperBound, nextUpperBoundIndex];\n\n indicesGroup.push(i);\n }\n\n // push the upper bound index as the last item\n indicesGroup.push(upperBoundIndex);\n indicesGroups.push(indicesGroup);\n } else {\n i++;\n }\n }\n\n return indicesGroups;\n};\n\nconst isValidFractionalIndex = (\n index: ExcalidrawElement[\"index\"] | undefined,\n predecessor: ExcalidrawElement[\"index\"] | undefined,\n successor: ExcalidrawElement[\"index\"] | undefined,\n) => {\n if (!index) {\n return false;\n }\n\n if (predecessor && successor) {\n return predecessor < index && index < successor;\n }\n\n if (!predecessor && successor) {\n // first element\n return index < successor;\n }\n\n if (predecessor && !successor) {\n // last element\n return predecessor < index;\n }\n\n // only element in the array\n return !!index;\n};\n\nconst generateIndices = (\n elements: readonly ExcalidrawElement[],\n indicesGroups: number[][],\n) => {\n const elementsUpdates = new Map<\n ExcalidrawElement,\n { index: FractionalIndex }\n >();\n\n for (const indices of indicesGroups) {\n const lowerBoundIndex = indices.shift()!;\n const upperBoundIndex = indices.pop()!;\n\n const fractionalIndices = generateNKeysBetween(\n elements[lowerBoundIndex]?.index,\n elements[upperBoundIndex]?.index,\n indices.length,\n ) as FractionalIndex[];\n\n for (let i = 0; i < indices.length; i++) {\n const element = elements[indices[i]];\n\n elementsUpdates.set(element, {\n index: fractionalIndices[i],\n });\n }\n }\n\n return elementsUpdates;\n};\n\nconst isOrderedElement = (\n element: ExcalidrawElement,\n): element is OrderedExcalidrawElement => {\n // for now it's sufficient whether the index is there\n // meaning, the element was already ordered in the past\n // meaning, it is not a newly inserted element, not an unrestored element, etc.\n // it does not have to mean that the index itself is valid\n if (element.index) {\n return true;\n }\n\n return false;\n};\n", "import { ENV } from \"./constants\";\nimport type { BindableProp, BindingProp } from \"./element/binding\";\nimport {\n BoundElement,\n BindableElement,\n bindingProperties,\n updateBoundElements,\n} from \"./element/binding\";\nimport { LinearElementEditor } from \"./element/linearElementEditor\";\nimport type { ElementUpdate } from \"./element/mutateElement\";\nimport { mutateElement, newElementWith } from \"./element/mutateElement\";\nimport {\n getBoundTextElementId,\n redrawTextBoundingBox,\n} from \"./element/textElement\";\nimport {\n hasBoundTextElement,\n isBindableElement,\n isBoundToContainer,\n isImageElement,\n isTextElement,\n} from \"./element/typeChecks\";\nimport type {\n ExcalidrawElement,\n ExcalidrawImageElement,\n ExcalidrawLinearElement,\n ExcalidrawTextElement,\n NonDeleted,\n Ordered,\n OrderedExcalidrawElement,\n SceneElementsMap,\n} from \"./element/types\";\nimport { orderByFractionalIndex, syncMovedIndices } from \"./fractionalIndex\";\nimport { getNonDeletedGroupIds } from \"./groups\";\nimport { getObservedAppState } from \"./store\";\nimport type {\n AppState,\n ObservedAppState,\n ObservedElementsAppState,\n ObservedStandaloneAppState,\n} from \"./types\";\nimport type { SubtypeOf, ValueOf } from \"./utility-types\";\nimport {\n arrayToMap,\n arrayToObject,\n assertNever,\n isShallowEqual,\n toBrandedType,\n} from \"./utils\";\n\n/**\n * Represents the difference between two objects of the same type.\n *\n * Both `deleted` and `inserted` partials represent the same set of added, removed or updated properties, where:\n * - `deleted` is a set of all the deleted values\n * - `inserted` is a set of all the inserted (added, updated) values\n *\n * Keeping it as pure object (without transient state, side-effects, etc.), so we won't have to instantiate it on load.\n */\nclass Delta<T> {\n private constructor(\n public readonly deleted: Partial<T>,\n public readonly inserted: Partial<T>,\n ) {}\n\n public static create<T>(\n deleted: Partial<T>,\n inserted: Partial<T>,\n modifier?: (delta: Partial<T>) => Partial<T>,\n modifierOptions?: \"deleted\" | \"inserted\",\n ) {\n const modifiedDeleted =\n modifier && modifierOptions !== \"inserted\" ? modifier(deleted) : deleted;\n const modifiedInserted =\n modifier && modifierOptions !== \"deleted\" ? modifier(inserted) : inserted;\n\n return new Delta(modifiedDeleted, modifiedInserted);\n }\n\n /**\n * Calculates the delta between two objects.\n *\n * @param prevObject - The previous state of the object.\n * @param nextObject - The next state of the object.\n *\n * @returns new delta instance.\n */\n public static calculate<T extends { [key: string]: any }>(\n prevObject: T,\n nextObject: T,\n modifier?: (partial: Partial<T>) => Partial<T>,\n postProcess?: (\n deleted: Partial<T>,\n inserted: Partial<T>,\n ) => [Partial<T>, Partial<T>],\n ): Delta<T> {\n if (prevObject === nextObject) {\n return Delta.empty();\n }\n\n const deleted = {} as Partial<T>;\n const inserted = {} as Partial<T>;\n\n // O(n^3) here for elements, but it's not as bad as it looks:\n // - we do this only on store recordings, not on every frame (not for ephemerals)\n // - we do this only on previously detected changed elements\n // - we do shallow compare only on the first level of properties (not going any deeper)\n // - # of properties is reasonably small\n for (const key of this.distinctKeysIterator(\n \"full\",\n prevObject,\n nextObject,\n )) {\n deleted[key as keyof T] = prevObject[key];\n inserted[key as keyof T] = nextObject[key];\n }\n\n const [processedDeleted, processedInserted] = postProcess\n ? postProcess(deleted, inserted)\n : [deleted, inserted];\n\n return Delta.create(processedDeleted, processedInserted, modifier);\n }\n\n public static empty() {\n return new Delta({}, {});\n }\n\n public static isEmpty<T>(delta: Delta<T>): boolean {\n return (\n !Object.keys(delta.deleted).length && !Object.keys(delta.inserted).length\n );\n }\n\n /**\n * Merges deleted and inserted object partials.\n */\n public static mergeObjects<T extends { [key: string]: unknown }>(\n prev: T,\n added: T,\n removed: T,\n ) {\n const cloned = { ...prev };\n\n for (const key of Object.keys(removed)) {\n delete cloned[key];\n }\n\n return { ...cloned, ...added };\n }\n\n /**\n * Merges deleted and inserted array partials.\n */\n public static mergeArrays<T>(\n prev: readonly T[] | null,\n added: readonly T[] | null | undefined,\n removed: readonly T[] | null | undefined,\n predicate?: (value: T) => string,\n ) {\n return Object.values(\n Delta.mergeObjects(\n arrayToObject(prev ?? [], predicate),\n arrayToObject(added ?? [], predicate),\n arrayToObject(removed ?? [], predicate),\n ),\n );\n }\n\n /**\n * Diff object partials as part of the `postProcess`.\n */\n public static diffObjects<T, K extends keyof T, V extends ValueOf<T[K]>>(\n deleted: Partial<T>,\n inserted: Partial<T>,\n property: K,\n setValue: (prevValue: V | undefined) => V,\n ) {\n if (!deleted[property] && !inserted[property]) {\n return;\n }\n\n if (\n typeof deleted[property] === \"object\" ||\n typeof inserted[property] === \"object\"\n ) {\n type RecordLike = Record<string, V | undefined>;\n\n const deletedObject: RecordLike = deleted[property] ?? {};\n const insertedObject: RecordLike = inserted[property] ?? {};\n\n const deletedDifferences = Delta.getLeftDifferences(\n deletedObject,\n insertedObject,\n ).reduce((acc, curr) => {\n acc[curr] = setValue(deletedObject[curr]);\n return acc;\n }, {} as RecordLike);\n\n const insertedDifferences = Delta.getRightDifferences(\n deletedObject,\n insertedObject,\n ).reduce((acc, curr) => {\n acc[curr] = setValue(insertedObject[curr]);\n return acc;\n }, {} as RecordLike);\n\n if (\n Object.keys(deletedDifferences).length ||\n Object.keys(insertedDifferences).length\n ) {\n Reflect.set(deleted, property, deletedDifferences);\n Reflect.set(inserted, property, insertedDifferences);\n } else {\n Reflect.deleteProperty(deleted, property);\n Reflect.deleteProperty(inserted, property);\n }\n }\n }\n\n /**\n * Diff array partials as part of the `postProcess`.\n */\n public static diffArrays<T, K extends keyof T, V extends T[K]>(\n deleted: Partial<T>,\n inserted: Partial<T>,\n property: K,\n groupBy: (value: V extends ArrayLike<infer T> ? T : never) => string,\n ) {\n if (!deleted[property] && !inserted[property]) {\n return;\n }\n\n if (Array.isArray(deleted[property]) || Array.isArray(inserted[property])) {\n const deletedArray = (\n Array.isArray(deleted[property]) ? deleted[property] : []\n ) as [];\n const insertedArray = (\n Array.isArray(inserted[property]) ? inserted[property] : []\n ) as [];\n\n const deletedDifferences = arrayToObject(\n Delta.getLeftDifferences(\n arrayToObject(deletedArray, groupBy),\n arrayToObject(insertedArray, groupBy),\n ),\n );\n const insertedDifferences = arrayToObject(\n Delta.getRightDifferences(\n arrayToObject(deletedArray, groupBy),\n arrayToObject(insertedArray, groupBy),\n ),\n );\n\n if (\n Object.keys(deletedDifferences).length ||\n Object.keys(insertedDifferences).length\n ) {\n const deletedValue = deletedArray.filter(\n (x) => deletedDifferences[groupBy ? groupBy(x) : String(x)],\n );\n const insertedValue = insertedArray.filter(\n (x) => insertedDifferences[groupBy ? groupBy(x) : String(x)],\n );\n\n Reflect.set(deleted, property, deletedValue);\n Reflect.set(inserted, property, insertedValue);\n } else {\n Reflect.deleteProperty(deleted, property);\n Reflect.deleteProperty(inserted, property);\n }\n }\n }\n\n /**\n * Compares if object1 contains any different value compared to the object2.\n */\n public static isLeftDifferent<T extends {}>(\n object1: T,\n object2: T,\n skipShallowCompare = false,\n ): boolean {\n const anyDistinctKey = this.distinctKeysIterator(\n \"left\",\n object1,\n object2,\n skipShallowCompare,\n ).next().value;\n\n return !!anyDistinctKey;\n }\n\n /**\n * Compares if object2 contains any different value compared to the object1.\n */\n public static isRightDifferent<T extends {}>(\n object1: T,\n object2: T,\n skipShallowCompare = false,\n ): boolean {\n const anyDistinctKey = this.distinctKeysIterator(\n \"right\",\n object1,\n object2,\n skipShallowCompare,\n ).next().value;\n\n return !!anyDistinctKey;\n }\n\n /**\n * Returns all the object1 keys that have distinct values.\n */\n public static getLeftDifferences<T extends {}>(\n object1: T,\n object2: T,\n skipShallowCompare = false,\n ) {\n return Array.from(\n this.distinctKeysIterator(\"left\", object1, object2, skipShallowCompare),\n );\n }\n\n /**\n * Returns all the object2 keys that have distinct values.\n */\n public static getRightDifferences<T extends {}>(\n object1: T,\n object2: T,\n skipShallowCompare = false,\n ) {\n return Array.from(\n this.distinctKeysIterator(\"right\", object1, object2, skipShallowCompare),\n );\n }\n\n /**\n * Iterator comparing values of object properties based on the passed joining strategy.\n *\n * @yields keys of properties with different values\n *\n * WARN: it's based on shallow compare performed only on the first level and doesn't go deeper than that.\n */\n private static *distinctKeysIterator<T extends {}>(\n join: \"left\" | \"right\" | \"full\",\n object1: T,\n object2: T,\n skipShallowCompare = false,\n ) {\n if (object1 === object2) {\n return;\n }\n\n let keys: string[] = [];\n\n if (join === \"left\") {\n keys = Object.keys(object1);\n } else if (join === \"right\") {\n keys = Object.keys(object2);\n } else if (join === \"full\") {\n keys = Array.from(\n new Set([...Object.keys(object1), ...Object.keys(object2)]),\n );\n } else {\n assertNever(\n join,\n `Unknown distinctKeysIterator's join param \"${join}\"`,\n true,\n );\n }\n\n for (const key of keys) {\n const object1Value = object1[key as keyof T];\n const object2Value = object2[key as keyof T];\n\n if (object1Value !== object2Value) {\n if (\n !skipShallowCompare &&\n typeof object1Value === \"object\" &&\n typeof object2Value === \"object\" &&\n object1Value !== null &&\n object2Value !== null &&\n isShallowEqual(object1Value, object2Value)\n ) {\n continue;\n }\n\n yield key;\n }\n }\n }\n}\n\n/**\n * Encapsulates the modifications captured as `Delta`/s.\n */\ninterface Change<T> {\n /**\n * Inverses the `Delta`s inside while creating a new `Change`.\n */\n inverse(): Change<T>;\n\n /**\n * Applies the `Change` to the previous object.\n *\n * @returns a tuple of the next object `T` with applied change, and `boolean`, indicating whether the applied change resulted in a visible change.\n */\n applyTo(previous: T, ...options: unknown[]): [T, boolean];\n\n /**\n * Checks whether there are actually `Delta`s.\n */\n isEmpty(): boolean;\n}\n\nexport class AppStateChange implements Change<AppState> {\n private constructor(private readonly delta: Delta<ObservedAppState>) {}\n\n public static calculate<T extends ObservedAppState>(\n prevAppState: T,\n nextAppState: T,\n ): AppStateChange {\n const delta = Delta.calculate(\n prevAppState,\n nextAppState,\n undefined,\n AppStateChange.postProcess,\n );\n\n return new AppStateChange(delta);\n }\n\n public static empty() {\n return new AppStateChange(Delta.create({}, {}));\n }\n\n public inverse(): AppStateChange {\n const inversedDelta = Delta.create(this.delta.inserted, this.delta.deleted);\n return new AppStateChange(inversedDelta);\n }\n\n public applyTo(\n appState: AppState,\n nextElements: SceneElementsMap,\n ): [AppState, boolean] {\n try {\n const {\n selectedElementIds: removedSelectedElementIds = {},\n selectedGroupIds: removedSelectedGroupIds = {},\n } = this.delta.deleted;\n\n const {\n selectedElementIds: addedSelectedElementIds = {},\n selectedGroupIds: addedSelectedGroupIds = {},\n selectedLinearElementId,\n editingLinearElementId,\n ...directlyApplicablePartial\n } = this.delta.inserted;\n\n const mergedSelectedElementIds = Delta.mergeObjects(\n appState.selectedElementIds,\n addedSelectedElementIds,\n removedSelectedElementIds,\n );\n\n const mergedSelectedGroupIds = Delta.mergeObjects(\n appState.selectedGroupIds,\n addedSelectedGroupIds,\n removedSelectedGroupIds,\n );\n\n const selectedLinearElement =\n selectedLinearElementId && nextElements.has(selectedLinearElementId)\n ? new LinearElementEditor(\n nextElements.get(\n selectedLinearElementId,\n ) as NonDeleted<ExcalidrawLinearElement>,\n )\n : null;\n\n const editingLinearElement =\n editingLinearElementId && nextElements.has(editingLinearElementId)\n ? new LinearElementEditor(\n nextElements.get(\n editingLinearElementId,\n ) as NonDeleted<ExcalidrawLinearElement>,\n )\n : null;\n\n const nextAppState = {\n ...appState,\n ...directlyApplicablePartial,\n selectedElementIds: mergedSelectedElementIds,\n selectedGroupIds: mergedSelectedGroupIds,\n selectedLinearElement:\n typeof selectedLinearElementId !== \"undefined\"\n ? selectedLinearElement // element was either inserted or deleted\n : appState.selectedLinearElement, // otherwise assign what we had before\n editingLinearElement:\n typeof editingLinearElementId !== \"undefined\"\n ? editingLinearElement // element was either inserted or deleted\n : appState.editingLinearElement, // otherwise assign what we had before\n };\n\n const constainsVisibleChanges = this.filterInvisibleChanges(\n appState,\n nextAppState,\n nextElements,\n );\n\n return [nextAppState, constainsVisibleChanges];\n } catch (e) {\n // shouldn't really happen, but just in case\n console.error(`Couldn't apply appstate change`, e);\n\n if (import.meta.env.DEV || import.meta.env.MODE === ENV.TEST) {\n throw e;\n }\n\n return [appState, false];\n }\n }\n\n public isEmpty(): boolean {\n return Delta.isEmpty(this.delta);\n }\n\n /**\n * It is necessary to post process the partials in case of reference values,\n * for which we need to calculate the real diff between `deleted` and `inserted`.\n */\n private static postProcess<T extends ObservedAppState>(\n deleted: Partial<T>,\n inserted: Partial<T>,\n ): [Partial<T>, Partial<T>] {\n try {\n Delta.diffObjects(\n deleted,\n inserted,\n \"selectedElementIds\",\n // ts language server has a bit trouble resolving this, so we are giving it a little push\n (_) => true as ValueOf<T[\"selectedElementIds\"]>,\n );\n Delta.diffObjects(\n deleted,\n inserted,\n \"selectedGroupIds\",\n (prevValue) => (prevValue ?? false) as ValueOf<T[\"selectedGroupIds\"]>,\n );\n } catch (e) {\n // if postprocessing fails it does not make sense to bubble up, but let's make sure we know about it\n console.error(`Couldn't postprocess appstate change deltas.`);\n\n if (import.meta.env.DEV || import.meta.env.MODE === ENV.TEST) {\n throw e;\n }\n } finally {\n return [deleted, inserted];\n }\n }\n\n /**\n * Mutates `nextAppState` be filtering out state related to deleted elements.\n *\n * @returns `true` if a visible change is found, `false` otherwise.\n */\n private filterInvisibleChanges(\n prevAppState: AppState,\n nextAppState: AppState,\n nextElements: SceneElementsMap,\n ): boolean {\n // TODO: #7348 we could still get an empty undo/redo, as we assume that previous appstate does not contain references to deleted elements\n // which is not always true - i.e. now we do cleanup appstate during history, but we do not do it during remote updates\n const prevObservedAppState = getObservedAppState(prevAppState);\n const nextObservedAppState = getObservedAppState(nextAppState);\n\n const containsStandaloneDifference = Delta.isRightDifferent(\n AppStateChange.stripElementsProps(prevObservedAppState),\n AppStateChange.stripElementsProps(nextObservedAppState),\n );\n\n const containsElementsDifference = Delta.isRightDifferent(\n AppStateChange.stripStandaloneProps(prevObservedAppState),\n AppStateChange.stripStandaloneProps(nextObservedAppState),\n );\n\n if (!containsStandaloneDifference && !containsElementsDifference) {\n // no change in appstate was detected\n return false;\n }\n\n const visibleDifferenceFlag = {\n value: containsStandaloneDifference,\n };\n\n if (containsElementsDifference) {\n // filter invisible changes on each iteration\n const changedElementsProps = Delta.getRightDifferences(\n AppStateChange.stripStandaloneProps(prevObservedAppState),\n AppStateChange.stripStandaloneProps(nextObservedAppState),\n ) as Array<keyof ObservedElementsAppState>;\n\n let nonDeletedGroupIds = new Set<string>();\n\n if (\n changedElementsProps.includes(\"editingGroupId\") ||\n changedElementsProps.includes(\"selectedGroupIds\")\n ) {\n // this one iterates through all the non deleted elements, so make sure it's not done twice\n nonDeletedGroupIds = getNonDeletedGroupIds(nextElements);\n }\n\n // check whether delta properties are related to the existing non-deleted elements\n for (const key of changedElementsProps) {\n switch (key) {\n case \"selectedElementIds\":\n nextAppState[key] = AppStateChange.filterSelectedElements(\n nextAppState[key],\n nextElements,\n visibleDifferenceFlag,\n );\n\n break;\n case \"selectedGroupIds\":\n nextAppState[key] = AppStateChange.filterSelectedGroups(\n nextAppState[key],\n nonDeletedGroupIds,\n visibleDifferenceFlag,\n );\n\n break;\n case \"croppingElementId\": {\n const croppingElementId = nextAppState[key];\n const element =\n croppingElementId && nextElements.get(croppingElementId);\n\n if (element && !element.isDeleted) {\n visibleDifferenceFlag.value = true;\n } else {\n nextAppState[key] = null;\n }\n break;\n }\n case \"editingGroupId\":\n const editingGroupId = nextAppState[key];\n\n if (!editingGroupId) {\n // previously there was an editingGroup (assuming visible), now there is none\n visibleDifferenceFlag.value = true;\n } else if (nonDeletedGroupIds.has(editingGroupId)) {\n // previously there wasn't an editingGroup, now there is one which is visible\n visibleDifferenceFlag.value = true;\n } else {\n // there was assigned an editingGroup now, but it's related to deleted element\n nextAppState[key] = null;\n }\n\n break;\n case \"selectedLinearElementId\":\n case \"editingLinearElementId\":\n const appStateKey = AppStateChange.convertToAppStateKey(key);\n const linearElement = nextAppState[appStateKey];\n\n if (!linearElement) {\n // previously there was a linear element (assuming visible), now there is none\n visibleDifferenceFlag.value = true;\n } else {\n const element = nextElements.get(linearElement.elementId);\n\n if (element && !element.isDeleted) {\n // previously there wasn't a linear element, now there is one which is visible\n visibleDifferenceFlag.value = true;\n } else {\n // there was assigned a linear element now, but it's deleted\n nextAppState[appStateKey] = null;\n }\n }\n\n break;\n default: {\n assertNever(\n key,\n `Unknown ObservedElementsAppState's key \"${key}\"`,\n true,\n );\n }\n }\n }\n }\n\n return visibleDifferenceFlag.value;\n }\n\n private static convertToAppStateKey(\n key: keyof Pick<\n ObservedElementsAppState,\n \"selectedLinearElementId\" | \"editingLinearElementId\"\n >,\n ): keyof Pick<AppState, \"selectedLinearElement\" | \"editingLinearElement\"> {\n switch (key) {\n case \"selectedLinearElementId\":\n return \"selectedLinearElement\";\n case \"editingLinearElementId\":\n return \"editingLinearElement\";\n }\n }\n\n private static filterSelectedElements(\n selectedElementIds: AppState[\"selectedElementIds\"],\n elements: SceneElementsMap,\n visibleDifferenceFlag: { value: boolean },\n ) {\n const ids = Object.keys(selectedElementIds);\n\n if (!ids.length) {\n // previously there were ids (assuming related to visible elements), now there are none\n visibleDifferenceFlag.value = true;\n return selectedElementIds;\n }\n\n const nextSelectedElementIds = { ...selectedElementIds };\n\n for (const id of ids) {\n const element = elements.get(id);\n\n if (element && !element.isDeleted) {\n // there is a selected element id related to a visible element\n visibleDifferenceFlag.value = true;\n } else {\n delete nextSelectedElementIds[id];\n }\n }\n\n return nextSelectedElementIds;\n }\n\n private static filterSelectedGroups(\n selectedGroupIds: AppState[\"selectedGroupIds\"],\n nonDeletedGroupIds: Set<string>,\n visibleDifferenceFlag: { value: boolean },\n ) {\n const ids = Object.keys(selectedGroupIds);\n\n if (!ids.length) {\n // previously there were ids (assuming related to visible groups), now there are none\n visibleDifferenceFlag.value = true;\n return selectedGroupIds;\n }\n\n const nextSelectedGroupIds = { ...selectedGroupIds };\n\n for (const id of Object.keys(nextSelectedGroupIds)) {\n if (nonDeletedGroupIds.has(id)) {\n // there is a selected group id related to a visible group\n visibleDifferenceFlag.value = true;\n } else {\n delete nextSelectedGroupIds[id];\n }\n }\n\n return nextSelectedGroupIds;\n }\n\n private static stripElementsProps(\n delta: Partial<ObservedAppState>,\n ): Partial<ObservedStandaloneAppState> {\n // WARN: Do not remove the type-casts as they here to ensure proper type checks\n const {\n editingGroupId,\n selectedGroupIds,\n selectedElementIds,\n editingLinearElementId,\n selectedLinearElementId,\n croppingElementId,\n ...standaloneProps\n } = delta as ObservedAppState;\n\n return standaloneProps as SubtypeOf<\n typeof standaloneProps,\n ObservedStandaloneAppState\n >;\n }\n\n private static stripStandaloneProps(\n delta: Partial<ObservedAppState>,\n ): Partial<ObservedElementsAppState> {\n // WARN: Do not remove the type-casts as they here to ensure proper type checks\n const { name, viewBackgroundColor, ...elementsProps } =\n delta as ObservedAppState;\n\n return elementsProps as SubtypeOf<\n typeof elementsProps,\n ObservedElementsAppState\n >;\n }\n}\n\ntype ElementPartial<T extends ExcalidrawElement = ExcalidrawElement> = Omit<\n ElementUpdate<Ordered<T>>,\n \"seed\"\n>;\n\n/**\n * Elements change is a low level primitive to capture a change between two sets of elements.\n * It does so by encapsulating forward and backward `Delta`s, allowing to time-travel in both directions.\n */\nexport class ElementsChange implements Change<SceneElementsMap> {\n private constructor(\n private readonly added: Map<string, Delta<ElementPartial>>,\n private readonly removed: Map<string, Delta<ElementPartial>>,\n private readonly updated: Map<string, Delta<ElementPartial>>,\n ) {}\n\n public static create(\n added: Map<string, Delta<ElementPartial>>,\n removed: Map<string, Delta<ElementPartial>>,\n updated: Map<string, Delta<ElementPartial>>,\n options = { shouldRedistribute: false },\n ) {\n let change: ElementsChange;\n\n if (options.shouldRedistribute) {\n const nextAdded = new Map<string, Delta<ElementPartial>>();\n const nextRemoved = new Map<string, Delta<ElementPartial>>();\n const nextUpdated = new Map<string, Delta<ElementPartial>>();\n\n const deltas = [...added, ...removed, ...updated];\n\n for (const [id, delta] of deltas) {\n if (this.satisfiesAddition(delta)) {\n nextAdded.set(id, delta);\n } else if (this.satisfiesRemoval(delta)) {\n nextRemoved.set(id, delta);\n } else {\n nextUpdated.set(id, delta);\n }\n }\n\n change = new ElementsChange(nextAdded, nextRemoved, nextUpdated);\n } else {\n change = new ElementsChange(added, removed, updated);\n }\n\n if (import.meta.env.DEV || import.meta.env.MODE === ENV.TEST) {\n ElementsChange.validate(change, \"added\", this.satisfiesAddition);\n ElementsChange.validate(change, \"removed\", this.satisfiesRemoval);\n ElementsChange.validate(change, \"updated\", this.satisfiesUpdate);\n }\n\n return change;\n }\n\n private static satisfiesAddition = ({\n deleted,\n inserted,\n }: Delta<ElementPartial>) =>\n // dissallowing added as \"deleted\", which could cause issues when resolving conflicts\n deleted.isDeleted === true && !inserted.isDeleted;\n\n private static satisfiesRemoval = ({\n deleted,\n inserted,\n }: Delta<ElementPartial>) =>\n !deleted.isDeleted && inserted.isDeleted === true;\n\n private static satisfiesUpdate = ({\n deleted,\n inserted,\n }: Delta<ElementPartial>) => !!deleted.isDeleted === !!inserted.isDeleted;\n\n private static validate(\n change: ElementsChange,\n type: \"added\" | \"removed\" | \"updated\",\n satifies: (delta: Delta<ElementPartial>) => boolean,\n ) {\n for (const [id, delta] of change[type].entries()) {\n if (!satifies(delta)) {\n console.error(\n `Broken invariant for \"${type}\" delta, element \"${id}\", delta:`,\n delta,\n );\n throw new Error(`ElementsChange invariant broken for element \"${id}\".`);\n }\n }\n }\n\n /**\n * Calculates the `Delta`s between the previous and next set of elements.\n *\n * @param prevElements - Map representing the previous state of elements.\n * @param nextElements - Map representing the next state of elements.\n *\n * @returns `ElementsChange` instance representing the `Delta` changes between the two sets of elements.\n */\n public static calculate<T extends OrderedExcalidrawElement>(\n prevElements: Map<string, T>,\n nextElements: Map<string, T>,\n ): ElementsChange {\n if (prevElements === nextElements) {\n return ElementsChange.empty();\n }\n\n const added = new Map<string, Delta<ElementPartial>>();\n const removed = new Map<string, Delta<ElementPartial>>();\n const updated = new Map<string, Delta<ElementPartial>>();\n\n // this might be needed only in same edge cases, like during collab, when `isDeleted` elements get removed or when we (un)intentionally remove the elements\n for (const prevElement of prevElements.values()) {\n const nextElement = nextElements.get(prevElement.id);\n\n if (!nextElement) {\n const deleted = { ...prevElement, isDeleted: false } as ElementPartial;\n const inserted = { isDeleted: true } as ElementPartial;\n\n const delta = Delta.create(\n deleted,\n inserted,\n ElementsChange.stripIrrelevantProps,\n );\n\n removed.set(prevElement.id, delta);\n }\n }\n\n for (const nextElement of nextElements.values()) {\n const prevElement = prevElements.get(nextElement.id);\n\n if (!prevElement) {\n const deleted = { isDeleted: true } as ElementPartial;\n const inserted = {\n ...nextElement,\n isDeleted: false,\n } as ElementPartial;\n\n const delta = Delta.create(\n deleted,\n inserted,\n ElementsChange.stripIrrelevantProps,\n );\n\n added.set(nextElement.id, delta);\n\n continue;\n }\n\n if (prevElement.versionNonce !== nextElement.versionNonce) {\n const delta = Delta.calculate<ElementPartial>(\n prevElement,\n nextElement,\n ElementsChange.stripIrrelevantProps,\n ElementsChange.postProcess,\n );\n\n if (\n // making sure we don't get here some non-boolean values (i.e. undefined, null, etc.)\n typeof prevElement.isDeleted === \"boolean\" &&\n typeof nextElement.isDeleted === \"boolean\" &&\n prevElement.isDeleted !== nextElement.isDeleted\n ) {\n // notice that other props could have been updated as well\n if (prevElement.isDeleted && !nextElement.isDeleted) {\n added.set(nextElement.id, delta);\n } else {\n removed.set(nextElement.id, delta);\n }\n\n continue;\n }\n\n // making sure there are at least some changes\n if (!Delta.isEmpty(delta)) {\n updated.set(nextElement.id, delta);\n }\n }\n }\n\n return ElementsChange.create(added, removed, updated);\n }\n\n public static empty() {\n return ElementsChange.create(new Map(), new Map(), new Map());\n }\n\n public inverse(): ElementsChange {\n const inverseInternal = (deltas: Map<string, Delta<ElementPartial>>) => {\n const inversedDeltas = new Map<string, Delta<ElementPartial>>();\n\n for (const [id, delta] of deltas.entries()) {\n inversedDeltas.set(id, Delta.create(delta.inserted, delta.deleted));\n }\n\n return inversedDeltas;\n };\n\n const added = inverseInternal(this.added);\n const removed = inverseInternal(this.removed);\n const updated = inverseInternal(this.updated);\n\n // notice we inverse removed with added not to break the invariants\n return ElementsChange.create(removed, added, updated);\n }\n\n public isEmpty(): boolean {\n return (\n this.added.size === 0 &&\n this.removed.size === 0 &&\n this.updated.size === 0\n );\n }\n\n /**\n * Update delta/s based on the existing elements.\n *\n * @param elements current elements\n * @param modifierOptions defines which of the delta (`deleted` or `inserted`) will be updated\n * @returns new instance with modified delta/s\n */\n public applyLatestChanges(elements: SceneElementsMap): ElementsChange {\n const modifier =\n (element: OrderedExcalidrawElement) => (partial: ElementPartial) => {\n const latestPartial: { [key: string]: unknown } = {};\n\n for (const key of Object.keys(partial) as Array<keyof typeof partial>) {\n // do not update following props:\n // - `boundElements`, as it is a reference value which is postprocessed to contain only deleted/inserted keys\n switch (key) {\n case \"boundElements\":\n latestPartial[key] = partial[key];\n break;\n default:\n latestPartial[key] = element[key];\n }\n }\n\n return latestPartial;\n };\n\n const applyLatestChangesInternal = (\n deltas: Map<string, Delta<ElementPartial>>,\n ) => {\n const modifiedDeltas = new Map<string, Delta<ElementPartial>>();\n\n for (const [id, delta] of deltas.entries()) {\n const existingElement = elements.get(id);\n\n if (existingElement) {\n const modifiedDelta = Delta.create(\n delta.deleted,\n delta.inserted,\n modifier(existingElement),\n \"inserted\",\n );\n\n modifiedDeltas.set(id, modifiedDelta);\n } else {\n modifiedDeltas.set(id, delta);\n }\n }\n\n return modifiedDeltas;\n };\n\n const added = applyLatestChangesInternal(this.added);\n const removed = applyLatestChangesInternal(this.removed);\n const updated = applyLatestChangesInternal(this.updated);\n\n return ElementsChange.create(added, removed, updated, {\n shouldRedistribute: true, // redistribute the deltas as `isDeleted` could have been updated\n });\n }\n\n public applyTo(\n elements: SceneElementsMap,\n snapshot: Map<string, OrderedExcalidrawElement>,\n ): [SceneElementsMap, boolean] {\n let nextElements = toBrandedType<SceneElementsMap>(new Map(elements));\n let changedElements: Map<string, OrderedExcalidrawElement>;\n\n const flags = {\n containsVisibleDifference: false,\n containsZindexDifference: false,\n };\n\n // mimic a transaction by applying deltas into `nextElements` (always new instance, no mutation)\n try {\n const applyDeltas = ElementsChange.createApplier(\n nextElements,\n snapshot,\n flags,\n );\n\n const addedElements = applyDeltas(this.added);\n const removedElements = applyDeltas(this.removed);\n const updatedElements = applyDeltas(this.updated);\n\n const affectedElements = this.resolveConflicts(elements, nextElements);\n\n // TODO: #7348 validate elements semantically and syntactically the changed elements, in case they would result data integrity issues\n changedElements = new Map([\n ...addedElements,\n ...removedElements,\n ...updatedElements,\n ...affectedElements,\n ]);\n } catch (e) {\n console.error(`Couldn't apply elements change`, e);\n\n if (import.meta.env.DEV || import.meta.env.MODE === ENV.TEST) {\n throw e;\n }\n\n // should not really happen, but just in case we cannot apply deltas, let's return the previous elements with visible change set to `true`\n // even though there is obviously no visible change, returning `false` could be dangerous, as i.e.:\n // in the worst case, it could lead into iterating through the whole stack with no possibility to redo\n // instead, the worst case when returning `true` is an empty undo / redo\n return [elements, true];\n }\n\n try {\n // TODO: #7348 refactor away mutations below, so that we couldn't end up in an incosistent state\n ElementsChange.redrawTextBoundingBoxes(nextElements, changedElements);\n\n // the following reorder performs also mutations, but only on new instances of changed elements\n // (unless something goes really bad and it fallbacks to fixing all invalid indices)\n nextElements = ElementsChange.reorderElements(\n nextElements,\n changedElements,\n flags,\n );\n\n // Need ordered nextElements to avoid z-index binding issues\n ElementsChange.redrawBoundArrows(nextElements, changedElements);\n } catch (e) {\n console.error(\n `Couldn't mutate elements after applying elements change`,\n e,\n );\n\n if (import.meta.env.DEV || import.meta.env.MODE === ENV.TEST) {\n throw e;\n }\n } finally {\n return [nextElements, flags.containsVisibleDifference];\n }\n }\n\n private static createApplier = (\n nextElements: SceneElementsMap,\n snapshot: Map<string, OrderedExcalidrawElement>,\n flags: {\n containsVisibleDifference: boolean;\n containsZindexDifference: boolean;\n },\n ) => {\n const getElement = ElementsChange.createGetter(\n nextElements,\n snapshot,\n flags,\n );\n\n return (deltas: Map<string, Delta<ElementPartial>>) =>\n Array.from(deltas.entries()).reduce((acc, [id, delta]) => {\n const element = getElement(id, delta.inserted);\n\n if (element) {\n const newElement = ElementsChange.applyDelta(element, delta, flags);\n nextElements.set(newElement.id, newElement);\n acc.set(newElement.id, newElement);\n }\n\n return acc;\n }, new Map<string, OrderedExcalidrawElement>());\n };\n\n private static createGetter =\n (\n elements: SceneElementsMap,\n snapshot: Map<string, OrderedExcalidrawElement>,\n flags: {\n containsVisibleDifference: boolean;\n containsZindexDifference: boolean;\n },\n ) =>\n (id: string, partial: ElementPartial) => {\n let element = elements.get(id);\n\n if (!element) {\n // always fallback to the local snapshot, in cases when we cannot find the element in the elements array\n element = snapshot.get(id);\n\n if (element) {\n // as the element was brought from the snapshot, it automatically results in a possible zindex difference\n flags.containsZindexDifference = true;\n\n // as the element was force deleted, we need to check if adding it back results in a visible change\n if (\n partial.isDeleted === false ||\n (partial.isDeleted !== true && element.isDeleted === false)\n ) {\n flags.containsVisibleDifference = true;\n }\n }\n }\n\n return element;\n };\n\n private static applyDelta(\n element: OrderedExcalidrawElement,\n delta: Delta<ElementPartial>,\n flags: {\n containsVisibleDifference: boolean;\n containsZindexDifference: boolean;\n } = {\n // by default we don't care about about the flags\n containsVisibleDifference: true,\n containsZindexDifference: true,\n },\n ) {\n const { boundElements, ...directlyApplicablePartial } = delta.inserted;\n\n if (\n delta.deleted.boundElements?.length ||\n delta.inserted.boundElements?.length\n ) {\n const mergedBoundElements = Delta.mergeArrays(\n element.boundElements,\n delta.inserted.boundElements,\n delta.deleted.boundElements,\n (x) => x.id,\n );\n\n Object.assign(directlyApplicablePartial, {\n boundElements: mergedBoundElements,\n });\n }\n\n if (isImageElement(element)) {\n const _delta = delta as Delta<ElementPartial<ExcalidrawImageElement>>;\n // we want to override `crop` only if modified so that we don't reset\n // when undoing/redoing unrelated change\n if (_delta.deleted.crop || _delta.inserted.crop) {\n Object.assign(directlyApplicablePartial, {\n // apply change verbatim\n crop: _delta.inserted.crop ?? null,\n });\n }\n }\n\n if (!flags.containsVisibleDifference) {\n // strip away fractional as even if it would be different, it doesn't have to result in visible change\n const { index, ...rest } = directlyApplicablePartial;\n const containsVisibleDifference =\n ElementsChange.checkForVisibleDifference(element, rest);\n\n flags.containsVisibleDifference = containsVisibleDifference;\n }\n\n if (!flags.containsZindexDifference) {\n flags.containsZindexDifference =\n delta.deleted.index !== delta.inserted.index;\n }\n\n return newElementWith(element, directlyApplicablePartial);\n }\n\n /**\n * Check for visible changes regardless of whether they were removed, added or updated.\n */\n private static checkForVisibleDifference(\n element: OrderedExcalidrawElement,\n partial: ElementPartial,\n ) {\n if (element.isDeleted && partial.isDeleted !== false) {\n // when it's deleted and partial is not false, it cannot end up with a visible change\n return false;\n }\n\n if (element.isDeleted && partial.isDeleted === false) {\n // when we add an element, it results in a visible change\n return true;\n }\n\n if (element.isDeleted === false && partial.isDeleted) {\n // when we remove an element, it results in a visible change\n return true;\n }\n\n // check for any difference on a visible element\n return Delta.isRightDifferent(element, partial);\n }\n\n /**\n * Resolves conflicts for all previously added, removed and updated elements.\n * Updates the previous deltas with all the changes after conflict resolution.\n *\n * @returns all elements affected by the conflict resolution\n */\n private resolveConflicts(\n prevElements: SceneElementsMap,\n nextElements: SceneElementsMap,\n ) {\n const nextAffectedElements = new Map<string, OrderedExcalidrawElement>();\n const updater = (\n element: ExcalidrawElement,\n updates: ElementUpdate<ExcalidrawElement>,\n ) => {\n const nextElement = nextElements.get(element.id); // only ever modify next element!\n if (!nextElement) {\n return;\n }\n\n let affectedElement: OrderedExcalidrawElement;\n\n if (prevElements.get(element.id) === nextElement) {\n // create the new element instance in case we didn't modify the element yet\n // so that we won't end up in an incosistent state in case we would fail in the middle of mutations\n affectedElement = newElementWith(\n nextElement,\n updates as ElementUpdate<OrderedExcalidrawElement>,\n );\n } else {\n affectedElement = mutateElement(\n nextElement,\n updates as ElementUpdate<OrderedExcalidrawElement>,\n );\n }\n\n nextAffectedElements.set(affectedElement.id, affectedElement);\n nextElements.set(affectedElement.id, affectedElement);\n };\n\n // removed delta is affecting the bindings always, as all the affected elements of the removed elements need to be unbound\n for (const [id] of this.removed) {\n ElementsChange.unbindAffected(prevElements, nextElements, id, updater);\n }\n\n // added delta is affecting the bindings always, all the affected elements of the added elements need to be rebound\n for (const [id] of this.added) {\n ElementsChange.rebindAffected(prevElements, nextElements, id, updater);\n }\n\n // updated delta is affecting the binding only in case it contains changed binding or bindable property\n for (const [id] of Array.from(this.updated).filter(([_, delta]) =>\n Object.keys({ ...delta.deleted, ...delta.inserted }).find((prop) =>\n bindingProperties.has(prop as BindingProp | BindableProp),\n ),\n )) {\n const updatedElement = nextElements.get(id);\n if (!updatedElement || updatedElement.isDeleted) {\n // skip fixing bindings for updates on deleted elements\n continue;\n }\n\n ElementsChange.rebindAffected(prevElements, nextElements, id, updater);\n }\n\n // filter only previous elements, which were now affected\n const prevAffectedElements = new Map(\n Array.from(prevElements).filter(([id]) => nextAffectedElements.has(id)),\n );\n\n // calculate complete deltas for affected elements, and assign them back to all the deltas\n // technically we could do better here if perf. would become an issue\n const { added, removed, updated } = ElementsChange.calculate(\n prevAffectedElements,\n nextAffectedElements,\n );\n\n for (const [id, delta] of added) {\n this.added.set(id, delta);\n }\n\n for (const [id, delta] of removed) {\n this.removed.set(id, delta);\n }\n\n for (const [id, delta] of updated) {\n this.updated.set(id, delta);\n }\n\n return nextAffectedElements;\n }\n\n /**\n * Non deleted affected elements of removed elements (before and after applying delta),\n * should be unbound ~ bindings should not point from non deleted into the deleted element/s.\n */\n private static unbindAffected(\n prevElements: SceneElementsMap,\n nextElements: SceneElementsMap,\n id: string,\n updater: (\n element: ExcalidrawElement,\n updates: ElementUpdate<ExcalidrawElement>,\n ) => void,\n ) {\n // the instance could have been updated, so make sure we are passing the latest element to each function below\n const prevElement = () => prevElements.get(id); // element before removal\n const nextElement = () => nextElements.get(id); // element after removal\n\n BoundElement.unbindAffected(nextElements, prevElement(), updater);\n BoundElement.unbindAffected(nextElements, nextElement(), updater);\n\n BindableElement.unbindAffected(nextElements, prevElement(), updater);\n BindableElement.unbindAffected(nextElements, nextElement(), updater);\n }\n\n /**\n * Non deleted affected elements of added or updated element/s (before and after applying delta),\n * should be rebound (if possible) with the current element ~ bindings should be bidirectional.\n */\n private static rebindAffected(\n prevElements: SceneElementsMap,\n nextElements: SceneElementsMap,\n id: string,\n updater: (\n element: ExcalidrawElement,\n updates: ElementUpdate<ExcalidrawElement>,\n ) => void,\n ) {\n // the instance could have been updated, so make sure we are passing the latest element to each function below\n const prevElement = () => prevElements.get(id); // element before addition / update\n const nextElement = () => nextElements.get(id); // element after addition / update\n\n BoundElement.unbindAffected(nextElements, prevElement(), updater);\n BoundElement.rebindAffected(nextElements, nextElement(), updater);\n\n BindableElement.unbindAffected(\n nextElements,\n prevElement(),\n (element, updates) => {\n // we cannot rebind arrows with bindable element so we don't unbind them at all during rebind (we still need to unbind them on removal)\n // TODO: #7348 add startBinding / endBinding to the `BoundElement` context so that we could rebind arrows and remove this condition\n if (isTextElement(element)) {\n updater(element, updates);\n }\n },\n );\n BindableElement.rebindAffected(nextElements, nextElement(), updater);\n }\n\n private static redrawTextBoundingBoxes(\n elements: SceneElementsMap,\n changed: Map<string, OrderedExcalidrawElement>,\n ) {\n const boxesToRedraw = new Map<\n string,\n { container: OrderedExcalidrawElement; boundText: ExcalidrawTextElement }\n >();\n\n for (const element of changed.values()) {\n if (isBoundToContainer(element)) {\n const { containerId } = element as ExcalidrawTextElement;\n const container = containerId ? elements.get(containerId) : undefined;\n\n if (container) {\n boxesToRedraw.set(container.id, {\n container,\n boundText: element as ExcalidrawTextElement,\n });\n }\n }\n\n if (hasBoundTextElement(element)) {\n const boundTextElementId = getBoundTextElementId(element);\n const boundText = boundTextElementId\n ? elements.get(boundTextElementId)\n : undefined;\n\n if (boundText) {\n boxesToRedraw.set(element.id, {\n container: element,\n boundText: boundText as ExcalidrawTextElement,\n });\n }\n }\n }\n\n for (const { container, boundText } of boxesToRedraw.values()) {\n if (container.isDeleted || boundText.isDeleted) {\n // skip redraw if one of them is deleted, as it would not result in a meaningful redraw\n continue;\n }\n\n redrawTextBoundingBox(boundText, container, elements, false);\n }\n }\n\n private static redrawBoundArrows(\n elements: SceneElementsMap,\n changed: Map<string, OrderedExcalidrawElement>,\n ) {\n for (const element of changed.values()) {\n if (!element.isDeleted && isBindableElement(element)) {\n updateBoundElements(element, elements, {\n changedElements: changed,\n });\n }\n }\n }\n\n private static reorderElements(\n elements: SceneElementsMap,\n changed: Map<string, OrderedExcalidrawElement>,\n flags: {\n containsVisibleDifference: boolean;\n containsZindexDifference: boolean;\n },\n ) {\n if (!flags.containsZindexDifference) {\n return elements;\n }\n\n const unordered = Array.from(elements.values());\n const ordered = orderByFractionalIndex([...unordered]);\n const moved = Delta.getRightDifferences(unordered, ordered, true).reduce(\n (acc, arrayIndex) => {\n const candidate = unordered[Number(arrayIndex)];\n if (candidate && changed.has(candidate.id)) {\n acc.set(candidate.id, candidate);\n }\n\n return acc;\n },\n new Map(),\n );\n\n if (!flags.containsVisibleDifference && moved.size) {\n // we found a difference in order!\n flags.containsVisibleDifference = true;\n }\n\n // synchronize all elements that were actually moved\n // could fallback to synchronizing all invalid indices\n return arrayToMap(syncMovedIndices(ordered, moved)) as typeof elements;\n }\n\n /**\n * It is necessary to post process the partials in case of reference values,\n * for which we need to calculate the real diff between `deleted` and `inserted`.\n */\n private static postProcess(\n deleted: ElementPartial,\n inserted: ElementPartial,\n ): [ElementPartial, ElementPartial] {\n try {\n Delta.diffArrays(deleted, inserted, \"boundElements\", (x) => x.id);\n } catch (e) {\n // if postprocessing fails, it does not make sense to bubble up, but let's make sure we know about it\n console.error(`Couldn't postprocess elements change deltas.`);\n\n if (import.meta.env.DEV || import.meta.env.MODE === ENV.TEST) {\n throw e;\n }\n } finally {\n return [deleted, inserted];\n }\n }\n\n private static stripIrrelevantProps(\n partial: Partial<OrderedExcalidrawElement>,\n ): ElementPartial {\n const { id, updated, version, versionNonce, seed, ...strippedPartial } =\n partial;\n\n return strippedPartial;\n }\n}\n", "import type { UnsubscribeCallback } from \"./types\";\n\ntype Subscriber<T extends any[]> = (...payload: T) => void;\n\nexport class Emitter<T extends any[] = []> {\n public subscribers: Subscriber<T>[] = [];\n\n /**\n * Attaches subscriber\n *\n * @returns unsubscribe function\n */\n on(...handlers: Subscriber<T>[] | Subscriber<T>[][]): UnsubscribeCallback {\n const _handlers = handlers\n .flat()\n .filter((item) => typeof item === \"function\");\n\n this.subscribers.push(..._handlers);\n\n return () => this.off(_handlers);\n }\n\n once(...handlers: Subscriber<T>[] | Subscriber<T>[][]): UnsubscribeCallback {\n const _handlers = handlers\n .flat()\n .filter((item) => typeof item === \"function\");\n\n _handlers.push(() => detach());\n\n const detach = this.on(..._handlers);\n return detach;\n }\n\n off(...handlers: Subscriber<T>[] | Subscriber<T>[][]) {\n const _handlers = handlers.flat();\n this.subscribers = this.subscribers.filter(\n (handler) => !_handlers.includes(handler),\n );\n }\n\n trigger(...payload: T) {\n for (const handler of this.subscribers) {\n handler(...payload);\n }\n return this;\n }\n\n clear() {\n this.subscribers = [];\n }\n}\n", "import { getDefaultAppState } from \"./appState\";\nimport { AppStateChange, ElementsChange } from \"./change\";\nimport { ENV } from \"./constants\";\nimport { newElementWith } from \"./element/mutateElement\";\nimport { deepCopyElement } from \"./element/newElement\";\nimport type { OrderedExcalidrawElement } from \"./element/types\";\nimport { Emitter } from \"./emitter\";\nimport type { AppState, ObservedAppState } from \"./types\";\nimport type { ValueOf } from \"./utility-types\";\nimport { isShallowEqual } from \"./utils\";\n\n// hidden non-enumerable property for runtime checks\nconst hiddenObservedAppStateProp = \"__observedAppState\";\n\nexport const getObservedAppState = (appState: AppState): ObservedAppState => {\n const observedAppState = {\n name: appState.name,\n editingGroupId: appState.editingGroupId,\n viewBackgroundColor: appState.viewBackgroundColor,\n selectedElementIds: appState.selectedElementIds,\n selectedGroupIds: appState.selectedGroupIds,\n editingLinearElementId: appState.editingLinearElement?.elementId || null,\n selectedLinearElementId: appState.selectedLinearElement?.elementId || null,\n croppingElementId: appState.croppingElementId,\n };\n\n Reflect.defineProperty(observedAppState, hiddenObservedAppStateProp, {\n value: true,\n enumerable: false,\n });\n\n return observedAppState;\n};\n\nconst isObservedAppState = (\n appState: AppState | ObservedAppState,\n): appState is ObservedAppState =>\n !!Reflect.get(appState, hiddenObservedAppStateProp);\n\nexport const StoreAction = {\n /**\n * Immediately undoable.\n *\n * Use for updates which should be captured.\n * Should be used for most of the local updates.\n *\n * These updates will _immediately_ make it to the local undo / redo stacks.\n */\n CAPTURE: \"capture\",\n /**\n * Never undoable.\n *\n * Use for updates which should never be recorded, such as remote updates\n * or scene initialization.\n *\n * These updates will _never_ make it to the local undo / redo stacks.\n */\n UPDATE: \"update\",\n /**\n * Eventually undoable.\n *\n * Use for updates which should not be captured immediately - likely\n * exceptions which are part of some async multi-step process. Otherwise, all\n * such updates would end up being captured with the next\n * `StoreAction.CAPTURE` - triggered either by the next `updateScene`\n * or internally by the editor.\n *\n * These updates will _eventually_ make it to the local undo / redo stacks.\n */\n NONE: \"none\",\n} as const;\n\nexport type StoreActionType = ValueOf<typeof StoreAction>;\n\n/**\n * Represent an increment to the Store.\n */\nclass StoreIncrementEvent {\n constructor(\n public readonly elementsChange: ElementsChange,\n public readonly appStateChange: AppStateChange,\n ) {}\n}\n\n/**\n * Store which captures the observed changes and emits them as `StoreIncrementEvent` events.\n *\n * @experimental this interface is experimental and subject to change.\n */\nexport interface IStore {\n onStoreIncrementEmitter: Emitter<[StoreIncrementEvent]>;\n get snapshot(): Snapshot;\n set snapshot(snapshot: Snapshot);\n\n /**\n * Use to schedule update of the snapshot, useful on updates for which we don't need to calculate increments (i.e. remote updates).\n */\n shouldUpdateSnapshot(): void;\n\n /**\n * Use to schedule calculation of a store increment.\n */\n shouldCaptureIncrement(): void;\n\n /**\n * Based on the scheduled operation, either only updates store snapshot or also calculates increment and emits the result as a `StoreIncrementEvent`.\n *\n * @emits StoreIncrementEvent when increment is calculated.\n */\n commit(\n elements: Map<string, OrderedExcalidrawElement> | undefined,\n appState: AppState | ObservedAppState | undefined,\n ): void;\n\n /**\n * Clears the store instance.\n */\n clear(): void;\n\n /**\n * Filters out yet uncomitted elements from `nextElements`, which are part of in-progress local async actions (ephemerals) and thus were not yet commited to the snapshot.\n *\n * This is necessary in updates in which we receive reconciled elements, already containing elements which were not yet captured by the local store (i.e. collab).\n */\n filterUncomittedElements(\n prevElements: Map<string, OrderedExcalidrawElement>,\n nextElements: Map<string, OrderedExcalidrawElement>,\n ): Map<string, OrderedExcalidrawElement>;\n}\n\nexport class Store implements IStore {\n public readonly onStoreIncrementEmitter = new Emitter<\n [StoreIncrementEvent]\n >();\n\n private scheduledActions: Set<StoreActionType> = new Set();\n private _snapshot = Snapshot.empty();\n\n public get snapshot() {\n return this._snapshot;\n }\n\n public set snapshot(snapshot: Snapshot) {\n this._snapshot = snapshot;\n }\n\n // TODO: Suspicious that this is called so many places. Seems error-prone.\n public shouldCaptureIncrement = () => {\n this.scheduleAction(StoreAction.CAPTURE);\n };\n\n public shouldUpdateSnapshot = () => {\n this.scheduleAction(StoreAction.UPDATE);\n };\n\n private scheduleAction = (action: StoreActionType) => {\n this.scheduledActions.add(action);\n this.satisfiesScheduledActionsInvariant();\n };\n\n public commit = (\n elements: Map<string, OrderedExcalidrawElement> | undefined,\n appState: AppState | ObservedAppState | undefined,\n ): void => {\n try {\n // Capture has precedence since it also performs update\n if (this.scheduledActions.has(StoreAction.CAPTURE)) {\n this.captureIncrement(elements, appState);\n } else if (this.scheduledActions.has(StoreAction.UPDATE)) {\n this.updateSnapshot(elements, appState);\n }\n } finally {\n this.satisfiesScheduledActionsInvariant();\n // Defensively reset all scheduled actions, potentially cleans up other runtime garbage\n this.scheduledActions = new Set();\n }\n };\n\n public captureIncrement = (\n elements: Map<string, OrderedExcalidrawElement> | undefined,\n appState: AppState | ObservedAppState | undefined,\n ) => {\n const prevSnapshot = this.snapshot;\n const nextSnapshot = this.snapshot.maybeClone(elements, appState);\n\n // Optimisation, don't continue if nothing has changed\n if (prevSnapshot !== nextSnapshot) {\n // Calculate and record the changes based on the previous and next snapshot\n const elementsChange = nextSnapshot.meta.didElementsChange\n ? ElementsChange.calculate(prevSnapshot.elements, nextSnapshot.elements)\n : ElementsChange.empty();\n\n const appStateChange = nextSnapshot.meta.didAppStateChange\n ? AppStateChange.calculate(prevSnapshot.appState, nextSnapshot.appState)\n : AppStateChange.empty();\n\n if (!elementsChange.isEmpty() || !appStateChange.isEmpty()) {\n // Notify listeners with the increment\n this.onStoreIncrementEmitter.trigger(\n new StoreIncrementEvent(elementsChange, appStateChange),\n );\n }\n\n // Update snapshot\n this.snapshot = nextSnapshot;\n }\n };\n\n public updateSnapshot = (\n elements: Map<string, OrderedExcalidrawElement> | undefined,\n appState: AppState | ObservedAppState | undefined,\n ) => {\n const nextSnapshot = this.snapshot.maybeClone(elements, appState);\n\n if (this.snapshot !== nextSnapshot) {\n // Update snapshot\n this.snapshot = nextSnapshot;\n }\n };\n\n public filterUncomittedElements = (\n prevElements: Map<string, OrderedExcalidrawElement>,\n nextElements: Map<string, OrderedExcalidrawElement>,\n ) => {\n for (const [id, prevElement] of prevElements.entries()) {\n const nextElement = nextElements.get(id);\n\n if (!nextElement) {\n // Nothing to care about here, elements were forcefully deleted\n continue;\n }\n\n const elementSnapshot = this.snapshot.elements.get(id);\n\n // Checks for in progress async user action\n if (!elementSnapshot) {\n // Detected yet uncomitted local element\n nextElements.delete(id);\n } else if (elementSnapshot.version < prevElement.version) {\n // Element was already commited, but the snapshot version is lower than current current local version\n nextElements.set(id, elementSnapshot);\n }\n }\n\n return nextElements;\n };\n\n public clear = (): void => {\n this.snapshot = Snapshot.empty();\n this.scheduledActions = new Set();\n };\n\n private satisfiesScheduledActionsInvariant = () => {\n if (!(this.scheduledActions.size >= 0 && this.scheduledActions.size <= 3)) {\n const message = `There can be at most three store actions scheduled at the same time, but there are \"${this.scheduledActions.size}\".`;\n console.error(message, this.scheduledActions.values());\n\n if (import.meta.env.DEV || import.meta.env.MODE === ENV.TEST) {\n throw new Error(message);\n }\n }\n };\n}\n\nexport class Snapshot {\n private constructor(\n public readonly elements: Map<string, OrderedExcalidrawElement>,\n public readonly appState: ObservedAppState,\n public readonly meta: {\n didElementsChange: boolean;\n didAppStateChange: boolean;\n isEmpty?: boolean;\n } = {\n didElementsChange: false,\n didAppStateChange: false,\n isEmpty: false,\n },\n ) {}\n\n public static empty() {\n return new Snapshot(\n new Map(),\n getObservedAppState(getDefaultAppState() as AppState),\n { didElementsChange: false, didAppStateChange: false, isEmpty: true },\n );\n }\n\n public isEmpty() {\n return this.meta.isEmpty;\n }\n\n /**\n * Efficiently clone the existing snapshot, only if we detected changes.\n *\n * @returns same instance if there are no changes detected, new instance otherwise.\n */\n public maybeClone(\n elements: Map<string, OrderedExcalidrawElement> | undefined,\n appState: AppState | ObservedAppState | undefined,\n ) {\n const nextElementsSnapshot = this.maybeCreateElementsSnapshot(elements);\n const nextAppStateSnapshot = this.maybeCreateAppStateSnapshot(appState);\n\n let didElementsChange = false;\n let didAppStateChange = false;\n\n if (this.elements !== nextElementsSnapshot) {\n didElementsChange = true;\n }\n\n if (this.appState !== nextAppStateSnapshot) {\n didAppStateChange = true;\n }\n\n if (!didElementsChange && !didAppStateChange) {\n return this;\n }\n\n const snapshot = new Snapshot(nextElementsSnapshot, nextAppStateSnapshot, {\n didElementsChange,\n didAppStateChange,\n });\n\n return snapshot;\n }\n\n private maybeCreateAppStateSnapshot(\n appState: AppState | ObservedAppState | undefined,\n ) {\n if (!appState) {\n return this.appState;\n }\n\n // Not watching over everything from the app state, just the relevant props\n const nextAppStateSnapshot = !isObservedAppState(appState)\n ? getObservedAppState(appState)\n : appState;\n\n const didAppStateChange = this.detectChangedAppState(nextAppStateSnapshot);\n\n if (!didAppStateChange) {\n return this.appState;\n }\n\n return nextAppStateSnapshot;\n }\n\n private detectChangedAppState(nextObservedAppState: ObservedAppState) {\n return !isShallowEqual(this.appState, nextObservedAppState, {\n selectedElementIds: isShallowEqual,\n selectedGroupIds: isShallowEqual,\n });\n }\n\n private maybeCreateElementsSnapshot(\n elements: Map<string, OrderedExcalidrawElement> | undefined,\n ) {\n if (!elements) {\n return this.elements;\n }\n\n const didElementsChange = this.detectChangedElements(elements);\n\n if (!didElementsChange) {\n return this.elements;\n }\n\n const elementsSnapshot = this.createElementsSnapshot(elements);\n return elementsSnapshot;\n }\n\n /**\n * Detect if there any changed elements.\n *\n * NOTE: we shouldn't just use `sceneVersionNonce` instead, as we need to call this before the scene updates.\n */\n private detectChangedElements(\n nextElements: Map<string, OrderedExcalidrawElement>,\n ) {\n if (this.elements === nextElements) {\n return false;\n }\n\n if (this.elements.size !== nextElements.size) {\n return true;\n }\n\n // loop from right to left as changes are likelier to happen on new elements\n const keys = Array.from(nextElements.keys());\n\n for (let i = keys.length - 1; i >= 0; i--) {\n const prev = this.elements.get(keys[i]);\n const next = nextElements.get(keys[i]);\n if (\n !prev ||\n !next ||\n prev.id !== next.id ||\n prev.versionNonce !== next.versionNonce\n ) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Perform structural clone, cloning only elements that changed.\n */\n private createElementsSnapshot(\n nextElements: Map<string, OrderedExcalidrawElement>,\n ) {\n const clonedElements = new Map();\n\n for (const [id, prevElement] of this.elements.entries()) {\n // Clone previous elements, never delete, in case nextElements would be just a subset of previous elements\n // i.e. during collab, persist or whenenever isDeleted elements get cleared\n if (!nextElements.get(id)) {\n // When we cannot find the prev element in the next elements, we mark it as deleted\n clonedElements.set(\n id,\n newElementWith(prevElement, { isDeleted: true }),\n );\n } else {\n clonedElements.set(id, prevElement);\n }\n }\n\n for (const [id, nextElement] of nextElements.entries()) {\n const prevElement = clonedElements.get(id);\n\n // At this point our elements are reconcilled already, meaning the next element is always newer\n if (\n !prevElement || // element was added\n (prevElement && prevElement.versionNonce !== nextElement.versionNonce) // element was updated\n ) {\n clonedElements.set(id, deepCopyElement(nextElement));\n }\n }\n\n return clonedElements;\n }\n}\n", "import { register } from \"../actions/register\";\nimport { FONT_FAMILY, VERTICAL_ALIGN } from \"../constants\";\nimport type { ExcalidrawProps } from \"../types\";\nimport { escapeDoubleQuotes, getFontString, updateActiveTool } from \"../utils\";\nimport { setCursorForShape } from \"../cursor\";\nimport { newTextElement } from \"./newElement\";\nimport { wrapText } from \"./textWrapping\";\nimport { isIframeElement } from \"./typeChecks\";\nimport type {\n ExcalidrawElement,\n ExcalidrawIframeLikeElement,\n IframeData,\n} from \"./types\";\nimport type { MarkRequired } from \"../utility-types\";\nimport { StoreAction } from \"../store\";\n\ntype IframeDataWithSandbox = MarkRequired<IframeData, \"sandbox\">;\n\nconst embeddedLinkCache = new Map<string, IframeDataWithSandbox>();\n\nconst RE_YOUTUBE =\n /^(?:http(?:s)?:\\/\\/)?(?:www\\.)?youtu(?:be\\.com|\\.be)\\/(embed\\/|watch\\?v=|shorts\\/|playlist\\?list=|embed\\/videoseries\\?list=)?([a-zA-Z0-9_-]+)(?:\\?t=|&t=|\\?start=|&start=)?([a-zA-Z0-9_-]+)?[^\\s]*$/;\n\nconst RE_VIMEO =\n /^(?:http(?:s)?:\\/\\/)?(?:(?:w){3}\\.)?(?:player\\.)?vimeo\\.com\\/(?:video\\/)?([^?\\s]+)(?:\\?.*)?$/;\nconst RE_FIGMA = /^https:\\/\\/(?:www\\.)?figma\\.com/;\n\nconst RE_GH_GIST = /^https:\\/\\/gist\\.github\\.com\\/([\\w_-]+)\\/([\\w_-]+)/;\nconst RE_GH_GIST_EMBED =\n /^<script[\\s\\S]*?\\ssrc=[\"'](https:\\/\\/gist\\.github\\.com\\/.*?)\\.js[\"']/i;\n\n// not anchored to start to allow <blockquote> twitter embeds\nconst RE_TWITTER =\n /(?:https?:\\/\\/)?(?:(?:w){3}\\.)?(?:twitter|x)\\.com\\/[^/]+\\/status\\/(\\d+)/;\nconst RE_TWITTER_EMBED =\n /^<blockquote[\\s\\S]*?\\shref=[\"'](https?:\\/\\/(?:twitter|x)\\.com\\/[^\"']*)/i;\n\nconst RE_VALTOWN =\n /^https:\\/\\/(?:www\\.)?val\\.town\\/(v|embed)\\/[a-zA-Z_$][0-9a-zA-Z_$]+\\.[a-zA-Z_$][0-9a-zA-Z_$]+/;\n\nconst RE_GENERIC_EMBED =\n /^<(?:iframe|blockquote)[\\s\\S]*?\\s(?:src|href)=[\"']([^\"']*)[\"'][\\s\\S]*?>$/i;\n\nconst RE_GIPHY =\n /giphy.com\\/(?:clips|embed|gifs)\\/[a-zA-Z0-9]*?-?([a-zA-Z0-9]+)(?:[^a-zA-Z0-9]|$)/;\n\nconst RE_REDDIT =\n /^(?:http(?:s)?:\\/\\/)?(?:www\\.)?reddit\\.com\\/r\\/([a-zA-Z0-9_]+)\\/comments\\/([a-zA-Z0-9_]+)\\/([a-zA-Z0-9_]+)\\/?(?:\\?[^#\\s]*)?(?:#[^\\s]*)?$/;\n\nconst RE_REDDIT_EMBED =\n /^<blockquote[\\s\\S]*?\\shref=[\"'](https?:\\/\\/(?:www\\.)?reddit\\.com\\/[^\"']*)/i;\n\nconst ALLOWED_DOMAINS = new Set([\n \"youtube.com\",\n \"youtu.be\",\n \"vimeo.com\",\n \"player.vimeo.com\",\n \"figma.com\",\n \"link.excalidraw.com\",\n \"gist.github.com\",\n \"twitter.com\",\n \"x.com\",\n \"*.simplepdf.eu\",\n \"stackblitz.com\",\n \"val.town\",\n \"giphy.com\",\n \"reddit.com\",\n]);\n\nconst ALLOW_SAME_ORIGIN = new Set([\n \"youtube.com\",\n \"youtu.be\",\n \"vimeo.com\",\n \"player.vimeo.com\",\n \"figma.com\",\n \"twitter.com\",\n \"x.com\",\n \"*.simplepdf.eu\",\n \"stackblitz.com\",\n \"reddit.com\",\n]);\n\nexport const createSrcDoc = (body: string) => {\n return `<html><body>${body}</body></html>`;\n};\n\nexport const getEmbedLink = (\n link: string | null | undefined,\n): IframeDataWithSandbox | null => {\n if (!link) {\n return null;\n }\n\n if (embeddedLinkCache.has(link)) {\n return embeddedLinkCache.get(link)!;\n }\n\n const originalLink = link;\n\n const allowSameOrigin = ALLOW_SAME_ORIGIN.has(\n matchHostname(link, ALLOW_SAME_ORIGIN) || \"\",\n );\n\n let type: \"video\" | \"generic\" = \"generic\";\n let aspectRatio = { w: 560, h: 840 };\n const ytLink = link.match(RE_YOUTUBE);\n if (ytLink?.[2]) {\n const time = ytLink[3] ? `&start=${ytLink[3]}` : ``;\n const isPortrait = link.includes(\"shorts\");\n type = \"video\";\n switch (ytLink[1]) {\n case \"embed/\":\n case \"watch?v=\":\n case \"shorts/\":\n link = `https://www.youtube.com/embed/${ytLink[2]}?enablejsapi=1${time}`;\n break;\n case \"playlist?list=\":\n case \"embed/videoseries?list=\":\n link = `https://www.youtube.com/embed/videoseries?list=${ytLink[2]}&enablejsapi=1${time}`;\n break;\n default:\n link = `https://www.youtube.com/embed/${ytLink[2]}?enablejsapi=1${time}`;\n break;\n }\n aspectRatio = isPortrait ? { w: 315, h: 560 } : { w: 560, h: 315 };\n embeddedLinkCache.set(originalLink, {\n link,\n intrinsicSize: aspectRatio,\n type,\n sandbox: { allowSameOrigin },\n });\n return {\n link,\n intrinsicSize: aspectRatio,\n type,\n sandbox: { allowSameOrigin },\n };\n }\n\n const vimeoLink = link.match(RE_VIMEO);\n if (vimeoLink?.[1]) {\n const target = vimeoLink?.[1];\n const error = !/^\\d+$/.test(target)\n ? new URIError(\"Invalid embed link format\")\n : undefined;\n type = \"video\";\n link = `https://player.vimeo.com/video/${target}?api=1`;\n aspectRatio = { w: 560, h: 315 };\n //warning deliberately ommited so it is displayed only once per link\n //same link next time will be served from cache\n embeddedLinkCache.set(originalLink, {\n link,\n intrinsicSize: aspectRatio,\n type,\n sandbox: { allowSameOrigin },\n });\n return {\n link,\n intrinsicSize: aspectRatio,\n type,\n error,\n sandbox: { allowSameOrigin },\n };\n }\n\n const figmaLink = link.match(RE_FIGMA);\n if (figmaLink) {\n type = \"generic\";\n link = `https://www.figma.com/embed?embed_host=share&url=${encodeURIComponent(\n link,\n )}`;\n aspectRatio = { w: 550, h: 550 };\n embeddedLinkCache.set(originalLink, {\n link,\n intrinsicSize: aspectRatio,\n type,\n sandbox: { allowSameOrigin },\n });\n return {\n link,\n intrinsicSize: aspectRatio,\n type,\n sandbox: { allowSameOrigin },\n };\n }\n\n const valLink = link.match(RE_VALTOWN);\n if (valLink) {\n link =\n valLink[1] === \"embed\" ? valLink[0] : valLink[0].replace(\"/v\", \"/embed\");\n embeddedLinkCache.set(originalLink, {\n link,\n intrinsicSize: aspectRatio,\n type,\n sandbox: { allowSameOrigin },\n });\n return {\n link,\n intrinsicSize: aspectRatio,\n type,\n sandbox: { allowSameOrigin },\n };\n }\n\n if (RE_TWITTER.test(link)) {\n const postId = link.match(RE_TWITTER)![1];\n // the embed srcdoc still supports twitter.com domain only.\n // Note that we don't attempt to parse the username as it can consist of\n // non-latin1 characters, and the username in the url can be set to anything\n // without affecting the embed.\n const safeURL = escapeDoubleQuotes(\n `https://twitter.com/x/status/${postId}`,\n );\n\n const ret: IframeDataWithSandbox = {\n type: \"document\",\n srcdoc: (theme: string) =>\n createSrcDoc(\n `<blockquote class=\"twitter-tweet\" data-dnt=\"true\" data-theme=\"${theme}\"><a href=\"${safeURL}\"></a></blockquote> <script async src=\"https://platform.twitter.com/widgets.js\" charset=\"utf-8\"></script>`,\n ),\n intrinsicSize: { w: 480, h: 480 },\n sandbox: { allowSameOrigin },\n };\n embeddedLinkCache.set(originalLink, ret);\n return ret;\n }\n\n if (RE_REDDIT.test(link)) {\n const [, page, postId, title] = link.match(RE_REDDIT)!;\n const safeURL = escapeDoubleQuotes(\n `https://reddit.com/r/${page}/comments/${postId}/${title}`,\n );\n const ret: IframeDataWithSandbox = {\n type: \"document\",\n srcdoc: (theme: string) =>\n createSrcDoc(\n `<blockquote class=\"reddit-embed-bq\" data-embed-theme=\"${theme}\"><a href=\"${safeURL}\"></a><br></blockquote><script async=\"\" src=\"https://embed.reddit.com/widgets.js\" charset=\"UTF-8\"></script>`,\n ),\n intrinsicSize: { w: 480, h: 480 },\n sandbox: { allowSameOrigin },\n };\n embeddedLinkCache.set(originalLink, ret);\n return ret;\n }\n\n if (RE_GH_GIST.test(link)) {\n const [, user, gistId] = link.match(RE_GH_GIST)!;\n const safeURL = escapeDoubleQuotes(\n `https://gist.github.com/${user}/${gistId}`,\n );\n const ret: IframeDataWithSandbox = {\n type: \"document\",\n srcdoc: () =>\n createSrcDoc(`\n <script src=\"${safeURL}.js\"></script>\n <style type=\"text/css\">\n * { margin: 0px; }\n table, .gist { height: 100%; }\n .gist .gist-file { height: calc(100vh - 2px); padding: 0px; display: grid; grid-template-rows: 1fr auto; }\n </style>\n `),\n intrinsicSize: { w: 550, h: 720 },\n sandbox: { allowSameOrigin },\n };\n embeddedLinkCache.set(link, ret);\n return ret;\n }\n\n embeddedLinkCache.set(link, {\n link,\n intrinsicSize: aspectRatio,\n type,\n sandbox: { allowSameOrigin },\n });\n return {\n link,\n intrinsicSize: aspectRatio,\n type,\n sandbox: { allowSameOrigin },\n };\n};\n\nexport const createPlaceholderEmbeddableLabel = (\n element: ExcalidrawIframeLikeElement,\n): ExcalidrawElement => {\n let text: string;\n if (isIframeElement(element)) {\n text = \"IFrame element\";\n } else {\n text =\n !element.link || element?.link === \"\" ? \"Empty Web-Embed\" : element.link;\n }\n\n const fontSize = Math.max(\n Math.min(element.width / 2, element.width / text.length),\n element.width / 30,\n );\n const fontFamily = FONT_FAMILY.Helvetica;\n\n const fontString = getFontString({\n fontSize,\n fontFamily,\n });\n\n return newTextElement({\n x: element.x + element.width / 2,\n y: element.y + element.height / 2,\n strokeColor:\n element.strokeColor !== \"transparent\" ? element.strokeColor : \"black\",\n backgroundColor: \"transparent\",\n fontFamily,\n fontSize,\n text: wrapText(text, fontString, element.width - 20),\n textAlign: \"center\",\n verticalAlign: VERTICAL_ALIGN.MIDDLE,\n angle: element.angle ?? 0,\n });\n};\n\nexport const actionSetEmbeddableAsActiveTool = register({\n name: \"setEmbeddableAsActiveTool\",\n trackEvent: { category: \"toolbar\" },\n target: \"Tool\",\n label: \"toolBar.embeddable\",\n perform: (elements, appState, _, app) => {\n const nextActiveTool = updateActiveTool(appState, {\n type: \"embeddable\",\n });\n\n setCursorForShape(app.canvas, {\n ...appState,\n activeTool: nextActiveTool,\n });\n\n return {\n elements,\n appState: {\n ...appState,\n activeTool: updateActiveTool(appState, {\n type: \"embeddable\",\n }),\n },\n storeAction: StoreAction.NONE,\n };\n },\n});\n\nconst matchHostname = (\n url: string,\n /** using a Set assumes it already contains normalized bare domains */\n allowedHostnames: Set<string> | string,\n): string | null => {\n try {\n const { hostname } = new URL(url);\n\n const bareDomain = hostname.replace(/^www\\./, \"\");\n\n if (allowedHostnames instanceof Set) {\n if (ALLOWED_DOMAINS.has(bareDomain)) {\n return bareDomain;\n }\n\n const bareDomainWithFirstSubdomainWildcarded = bareDomain.replace(\n /^([^.]+)/,\n \"*\",\n );\n if (ALLOWED_DOMAINS.has(bareDomainWithFirstSubdomainWildcarded)) {\n return bareDomainWithFirstSubdomainWildcarded;\n }\n return null;\n }\n\n const bareAllowedHostname = allowedHostnames.replace(/^www\\./, \"\");\n if (bareDomain === bareAllowedHostname) {\n return bareAllowedHostname;\n }\n } catch (error) {\n // ignore\n }\n return null;\n};\n\nexport const maybeParseEmbedSrc = (str: string): string => {\n const twitterMatch = str.match(RE_TWITTER_EMBED);\n if (twitterMatch && twitterMatch.length === 2) {\n return twitterMatch[1];\n }\n\n const redditMatch = str.match(RE_REDDIT_EMBED);\n if (redditMatch && redditMatch.length === 2) {\n return redditMatch[1];\n }\n\n const gistMatch = str.match(RE_GH_GIST_EMBED);\n if (gistMatch && gistMatch.length === 2) {\n return gistMatch[1];\n }\n\n if (RE_GIPHY.test(str)) {\n return `https://giphy.com/embed/${RE_GIPHY.exec(str)![1]}`;\n }\n\n const match = str.match(RE_GENERIC_EMBED);\n if (match && match.length === 2) {\n return match[1];\n }\n\n return str;\n};\n\nexport const embeddableURLValidator = (\n url: string | null | undefined,\n validateEmbeddable: ExcalidrawProps[\"validateEmbeddable\"],\n): boolean => {\n if (!url) {\n return false;\n }\n if (validateEmbeddable != null) {\n if (typeof validateEmbeddable === \"function\") {\n const ret = validateEmbeddable(url);\n // if return value is undefined, leave validation to default\n if (typeof ret === \"boolean\") {\n return ret;\n }\n } else if (typeof validateEmbeddable === \"boolean\") {\n return validateEmbeddable;\n } else if (validateEmbeddable instanceof RegExp) {\n return validateEmbeddable.test(url);\n } else if (Array.isArray(validateEmbeddable)) {\n for (const domain of validateEmbeddable) {\n if (domain instanceof RegExp) {\n if (url.match(domain)) {\n return true;\n }\n } else if (matchHostname(url, domain)) {\n return true;\n }\n }\n return false;\n }\n }\n\n return !!matchHostname(url, ALLOWED_DOMAINS);\n};\n", "import type { Drawable } from \"roughjs/bin/core\";\nimport type { RoughSVG } from \"roughjs/bin/svg\";\nimport {\n FRAME_STYLE,\n MAX_DECIMALS_FOR_SVG_EXPORT,\n MIME_TYPES,\n SVG_NS,\n} from \"../constants\";\nimport { normalizeLink, toValidURL } from \"../data/url\";\nimport { getElementAbsoluteCoords, hashString } from \"../element\";\nimport {\n createPlaceholderEmbeddableLabel,\n getEmbedLink,\n} from \"../element/embeddable\";\nimport { LinearElementEditor } from \"../element/linearElementEditor\";\nimport {\n getBoundTextElement,\n getContainerElement,\n} from \"../element/textElement\";\nimport {\n isArrowElement,\n isIframeLikeElement,\n isInitializedImageElement,\n isTextElement,\n} from \"../element/typeChecks\";\nimport type {\n ExcalidrawElement,\n ExcalidrawTextElementWithContainer,\n NonDeletedExcalidrawElement,\n} from \"../element/types\";\nimport { getContainingFrame } from \"../frame\";\nimport { ShapeCache } from \"../scene/ShapeCache\";\nimport type { RenderableElementsMap, SVGRenderConfig } from \"../scene/types\";\nimport type { AppState, BinaryFiles } from \"../types\";\nimport { getFontFamilyString, isRTL, isTestEnv } from \"../utils\";\nimport { getFreeDrawSvgPath, IMAGE_INVERT_FILTER } from \"./renderElement\";\nimport { getVerticalOffset } from \"../fonts\";\nimport { getCornerRadius, isPathALoop } from \"../shapes\";\nimport { getUncroppedWidthAndHeight } from \"../element/cropElement\";\nimport { getLineHeightInPx } from \"../element/textMeasurements\";\n\nconst roughSVGDrawWithPrecision = (\n rsvg: RoughSVG,\n drawable: Drawable,\n precision?: number,\n) => {\n if (typeof precision === \"undefined\") {\n return rsvg.draw(drawable);\n }\n const pshape: Drawable = {\n sets: drawable.sets,\n shape: drawable.shape,\n options: { ...drawable.options, fixedDecimalPlaceDigits: precision },\n };\n return rsvg.draw(pshape);\n};\n\nconst maybeWrapNodesInFrameClipPath = (\n element: NonDeletedExcalidrawElement,\n root: SVGElement,\n nodes: SVGElement[],\n frameRendering: AppState[\"frameRendering\"],\n elementsMap: RenderableElementsMap,\n) => {\n if (!frameRendering.enabled || !frameRendering.clip) {\n return null;\n }\n const frame = getContainingFrame(element, elementsMap);\n if (frame) {\n const g = root.ownerDocument!.createElementNS(SVG_NS, \"g\");\n g.setAttributeNS(SVG_NS, \"clip-path\", `url(#${frame.id})`);\n nodes.forEach((node) => g.appendChild(node));\n return g;\n }\n\n return null;\n};\n\nconst renderElementToSvg = (\n element: NonDeletedExcalidrawElement,\n elementsMap: RenderableElementsMap,\n rsvg: RoughSVG,\n svgRoot: SVGElement,\n files: BinaryFiles,\n offsetX: number,\n offsetY: number,\n renderConfig: SVGRenderConfig,\n) => {\n const offset = { x: offsetX, y: offsetY };\n const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);\n let cx = (x2 - x1) / 2 - (element.x - x1);\n let cy = (y2 - y1) / 2 - (element.y - y1);\n if (isTextElement(element)) {\n const container = getContainerElement(element, elementsMap);\n if (isArrowElement(container)) {\n const [x1, y1, x2, y2] = getElementAbsoluteCoords(container, elementsMap);\n\n const boundTextCoords = LinearElementEditor.getBoundTextElementPosition(\n container,\n element as ExcalidrawTextElementWithContainer,\n elementsMap,\n );\n cx = (x2 - x1) / 2 - (boundTextCoords.x - x1);\n cy = (y2 - y1) / 2 - (boundTextCoords.y - y1);\n offsetX = offsetX + boundTextCoords.x - element.x;\n offsetY = offsetY + boundTextCoords.y - element.y;\n }\n }\n const degree = (180 * element.angle) / Math.PI;\n\n // element to append node to, most of the time svgRoot\n let root = svgRoot;\n\n // if the element has a link, create an anchor tag and make that the new root\n if (element.link) {\n const anchorTag = svgRoot.ownerDocument!.createElementNS(SVG_NS, \"a\");\n anchorTag.setAttribute(\"href\", normalizeLink(element.link));\n root.appendChild(anchorTag);\n root = anchorTag;\n }\n\n const addToRoot = (node: SVGElement, element: ExcalidrawElement) => {\n if (isTestEnv()) {\n node.setAttribute(\"data-id\", element.id);\n }\n root.appendChild(node);\n };\n\n const opacity =\n ((getContainingFrame(element, elementsMap)?.opacity ?? 100) *\n element.opacity) /\n 10000;\n\n switch (element.type) {\n case \"selection\": {\n // Since this is used only during editing experience, which is canvas based,\n // this should not happen\n throw new Error(\"Selection rendering is not supported for SVG\");\n }\n case \"rectangle\":\n case \"diamond\":\n case \"ellipse\": {\n const shape = ShapeCache.generateElementShape(element, null);\n const node = roughSVGDrawWithPrecision(\n rsvg,\n shape,\n MAX_DECIMALS_FOR_SVG_EXPORT,\n );\n if (opacity !== 1) {\n node.setAttribute(\"stroke-opacity\", `${opacity}`);\n node.setAttribute(\"fill-opacity\", `${opacity}`);\n }\n node.setAttribute(\"stroke-linecap\", \"round\");\n node.setAttribute(\n \"transform\",\n `translate(${offsetX || 0} ${\n offsetY || 0\n }) rotate(${degree} ${cx} ${cy})`,\n );\n\n const g = maybeWrapNodesInFrameClipPath(\n element,\n root,\n [node],\n renderConfig.frameRendering,\n elementsMap,\n );\n\n addToRoot(g || node, element);\n break;\n }\n case \"iframe\":\n case \"embeddable\": {\n // render placeholder rectangle\n const shape = ShapeCache.generateElementShape(element, renderConfig);\n const node = roughSVGDrawWithPrecision(\n rsvg,\n shape,\n MAX_DECIMALS_FOR_SVG_EXPORT,\n );\n const opacity = element.opacity / 100;\n if (opacity !== 1) {\n node.setAttribute(\"stroke-opacity\", `${opacity}`);\n node.setAttribute(\"fill-opacity\", `${opacity}`);\n }\n node.setAttribute(\"stroke-linecap\", \"round\");\n node.setAttribute(\n \"transform\",\n `translate(${offsetX || 0} ${\n offsetY || 0\n }) rotate(${degree} ${cx} ${cy})`,\n );\n addToRoot(node, element);\n\n const label: ExcalidrawElement =\n createPlaceholderEmbeddableLabel(element);\n renderElementToSvg(\n label,\n elementsMap,\n rsvg,\n root,\n files,\n label.x + offset.x - element.x,\n label.y + offset.y - element.y,\n renderConfig,\n );\n\n // render embeddable element + iframe\n const embeddableNode = roughSVGDrawWithPrecision(\n rsvg,\n shape,\n MAX_DECIMALS_FOR_SVG_EXPORT,\n );\n embeddableNode.setAttribute(\"stroke-linecap\", \"round\");\n embeddableNode.setAttribute(\n \"transform\",\n `translate(${offsetX || 0} ${\n offsetY || 0\n }) rotate(${degree} ${cx} ${cy})`,\n );\n while (embeddableNode.firstChild) {\n embeddableNode.removeChild(embeddableNode.firstChild);\n }\n const radius = getCornerRadius(\n Math.min(element.width, element.height),\n element,\n );\n\n const embedLink = getEmbedLink(toValidURL(element.link || \"\"));\n\n // if rendering embeddables explicitly disabled or\n // embedding documents via srcdoc (which doesn't seem to work for SVGs)\n // replace with a link instead\n if (\n renderConfig.renderEmbeddables === false ||\n embedLink?.type === \"document\"\n ) {\n const anchorTag = svgRoot.ownerDocument!.createElementNS(SVG_NS, \"a\");\n anchorTag.setAttribute(\"href\", normalizeLink(element.link || \"\"));\n anchorTag.setAttribute(\"target\", \"_blank\");\n anchorTag.setAttribute(\"rel\", \"noopener noreferrer\");\n anchorTag.style.borderRadius = `${radius}px`;\n\n embeddableNode.appendChild(anchorTag);\n } else {\n const foreignObject = svgRoot.ownerDocument!.createElementNS(\n SVG_NS,\n \"foreignObject\",\n );\n foreignObject.style.width = `${element.width}px`;\n foreignObject.style.height = `${element.height}px`;\n foreignObject.style.border = \"none\";\n const div = foreignObject.ownerDocument!.createElementNS(SVG_NS, \"div\");\n div.setAttribute(\"xmlns\", \"http://www.w3.org/1999/xhtml\");\n div.style.width = \"100%\";\n div.style.height = \"100%\";\n const iframe = div.ownerDocument!.createElement(\"iframe\");\n iframe.src = embedLink?.link ?? \"\";\n iframe.style.width = \"100%\";\n iframe.style.height = \"100%\";\n iframe.style.border = \"none\";\n iframe.style.borderRadius = `${radius}px`;\n iframe.style.top = \"0\";\n iframe.style.left = \"0\";\n iframe.allowFullscreen = true;\n div.appendChild(iframe);\n foreignObject.appendChild(div);\n\n embeddableNode.appendChild(foreignObject);\n }\n addToRoot(embeddableNode, element);\n break;\n }\n case \"line\":\n case \"arrow\": {\n const boundText = getBoundTextElement(element, elementsMap);\n const maskPath = svgRoot.ownerDocument!.createElementNS(SVG_NS, \"mask\");\n if (boundText) {\n maskPath.setAttribute(\"id\", `mask-${element.id}`);\n const maskRectVisible = svgRoot.ownerDocument!.createElementNS(\n SVG_NS,\n \"rect\",\n );\n offsetX = offsetX || 0;\n offsetY = offsetY || 0;\n maskRectVisible.setAttribute(\"x\", \"0\");\n maskRectVisible.setAttribute(\"y\", \"0\");\n maskRectVisible.setAttribute(\"fill\", \"#fff\");\n maskRectVisible.setAttribute(\n \"width\",\n `${element.width + 100 + offsetX}`,\n );\n maskRectVisible.setAttribute(\n \"height\",\n `${element.height + 100 + offsetY}`,\n );\n\n maskPath.appendChild(maskRectVisible);\n const maskRectInvisible = svgRoot.ownerDocument!.createElementNS(\n SVG_NS,\n \"rect\",\n );\n const boundTextCoords = LinearElementEditor.getBoundTextElementPosition(\n element,\n boundText,\n elementsMap,\n );\n\n const maskX = offsetX + boundTextCoords.x - element.x;\n const maskY = offsetY + boundTextCoords.y - element.y;\n\n maskRectInvisible.setAttribute(\"x\", maskX.toString());\n maskRectInvisible.setAttribute(\"y\", maskY.toString());\n maskRectInvisible.setAttribute(\"fill\", \"#000\");\n maskRectInvisible.setAttribute(\"width\", `${boundText.width}`);\n maskRectInvisible.setAttribute(\"height\", `${boundText.height}`);\n maskRectInvisible.setAttribute(\"opacity\", \"1\");\n maskPath.appendChild(maskRectInvisible);\n }\n const group = svgRoot.ownerDocument!.createElementNS(SVG_NS, \"g\");\n if (boundText) {\n group.setAttribute(\"mask\", `url(#mask-${element.id})`);\n }\n group.setAttribute(\"stroke-linecap\", \"round\");\n\n const shapes = ShapeCache.generateElementShape(element, renderConfig);\n shapes.forEach((shape) => {\n const node = roughSVGDrawWithPrecision(\n rsvg,\n shape,\n MAX_DECIMALS_FOR_SVG_EXPORT,\n );\n if (opacity !== 1) {\n node.setAttribute(\"stroke-opacity\", `${opacity}`);\n node.setAttribute(\"fill-opacity\", `${opacity}`);\n }\n node.setAttribute(\n \"transform\",\n `translate(${offsetX || 0} ${\n offsetY || 0\n }) rotate(${degree} ${cx} ${cy})`,\n );\n if (\n element.type === \"line\" &&\n isPathALoop(element.points) &&\n element.backgroundColor !== \"transparent\"\n ) {\n node.setAttribute(\"fill-rule\", \"evenodd\");\n }\n group.appendChild(node);\n });\n\n const g = maybeWrapNodesInFrameClipPath(\n element,\n root,\n [group, maskPath],\n renderConfig.frameRendering,\n elementsMap,\n );\n if (g) {\n addToRoot(g, element);\n root.appendChild(g);\n } else {\n addToRoot(group, element);\n root.append(maskPath);\n }\n break;\n }\n case \"freedraw\": {\n const backgroundFillShape = ShapeCache.generateElementShape(\n element,\n renderConfig,\n );\n const node = backgroundFillShape\n ? roughSVGDrawWithPrecision(\n rsvg,\n backgroundFillShape,\n MAX_DECIMALS_FOR_SVG_EXPORT,\n )\n : svgRoot.ownerDocument!.createElementNS(SVG_NS, \"g\");\n if (opacity !== 1) {\n node.setAttribute(\"stroke-opacity\", `${opacity}`);\n node.setAttribute(\"fill-opacity\", `${opacity}`);\n }\n node.setAttribute(\n \"transform\",\n `translate(${offsetX || 0} ${\n offsetY || 0\n }) rotate(${degree} ${cx} ${cy})`,\n );\n node.setAttribute(\"stroke\", \"none\");\n const path = svgRoot.ownerDocument!.createElementNS(SVG_NS, \"path\");\n path.setAttribute(\"fill\", element.strokeColor);\n path.setAttribute(\"d\", getFreeDrawSvgPath(element));\n node.appendChild(path);\n\n const g = maybeWrapNodesInFrameClipPath(\n element,\n root,\n [node],\n renderConfig.frameRendering,\n elementsMap,\n );\n\n addToRoot(g || node, element);\n break;\n }\n case \"image\": {\n const width = Math.round(element.width);\n const height = Math.round(element.height);\n const fileData =\n isInitializedImageElement(element) && files[element.fileId];\n if (fileData) {\n const { reuseImages = true } = renderConfig;\n\n let symbolId = `image-${fileData.id}`;\n\n let uncroppedWidth = element.width;\n let uncroppedHeight = element.height;\n if (element.crop) {\n ({ width: uncroppedWidth, height: uncroppedHeight } =\n getUncroppedWidthAndHeight(element));\n\n symbolId = `image-crop-${fileData.id}-${hashString(\n `${uncroppedWidth}x${uncroppedHeight}`,\n )}`;\n }\n\n if (!reuseImages) {\n symbolId = `image-${element.id}`;\n }\n\n let symbol = svgRoot.querySelector(`#${symbolId}`);\n if (!symbol) {\n symbol = svgRoot.ownerDocument!.createElementNS(SVG_NS, \"symbol\");\n symbol.id = symbolId;\n\n const image = svgRoot.ownerDocument!.createElementNS(SVG_NS, \"image\");\n image.setAttribute(\"href\", fileData.dataURL);\n image.setAttribute(\"preserveAspectRatio\", \"none\");\n\n if (element.crop || !reuseImages) {\n image.setAttribute(\"width\", `${uncroppedWidth}`);\n image.setAttribute(\"height\", `${uncroppedHeight}`);\n } else {\n image.setAttribute(\"width\", \"100%\");\n image.setAttribute(\"height\", \"100%\");\n }\n\n symbol.appendChild(image);\n\n (root.querySelector(\"defs\") || root).prepend(symbol);\n }\n\n const use = svgRoot.ownerDocument!.createElementNS(SVG_NS, \"use\");\n use.setAttribute(\"href\", `#${symbolId}`);\n\n // in dark theme, revert the image color filter\n if (\n renderConfig.exportWithDarkMode &&\n fileData.mimeType !== MIME_TYPES.svg\n ) {\n use.setAttribute(\"filter\", IMAGE_INVERT_FILTER);\n }\n\n let normalizedCropX = 0;\n let normalizedCropY = 0;\n\n if (element.crop) {\n const { width: uncroppedWidth, height: uncroppedHeight } =\n getUncroppedWidthAndHeight(element);\n normalizedCropX =\n element.crop.x / (element.crop.naturalWidth / uncroppedWidth);\n normalizedCropY =\n element.crop.y / (element.crop.naturalHeight / uncroppedHeight);\n }\n\n const adjustedCenterX = cx + normalizedCropX;\n const adjustedCenterY = cy + normalizedCropY;\n\n use.setAttribute(\"width\", `${width + normalizedCropX}`);\n use.setAttribute(\"height\", `${height + normalizedCropY}`);\n use.setAttribute(\"opacity\", `${opacity}`);\n\n // We first apply `scale` transforms (horizontal/vertical mirroring)\n // on the <use> element, then apply translation and rotation\n // on the <g> element which wraps the <use>.\n // Doing this separately is a quick hack to to work around compositing\n // the transformations correctly (the transform-origin was not being\n // applied correctly).\n if (element.scale[0] !== 1 || element.scale[1] !== 1) {\n use.setAttribute(\n \"transform\",\n `translate(${adjustedCenterX} ${adjustedCenterY}) scale(${\n element.scale[0]\n } ${\n element.scale[1]\n }) translate(${-adjustedCenterX} ${-adjustedCenterY})`,\n );\n }\n\n const g = svgRoot.ownerDocument!.createElementNS(SVG_NS, \"g\");\n\n if (element.crop) {\n const mask = svgRoot.ownerDocument!.createElementNS(SVG_NS, \"mask\");\n mask.setAttribute(\"id\", `mask-image-crop-${element.id}`);\n mask.setAttribute(\"fill\", \"#fff\");\n const maskRect = svgRoot.ownerDocument!.createElementNS(\n SVG_NS,\n \"rect\",\n );\n\n maskRect.setAttribute(\"x\", `${normalizedCropX}`);\n maskRect.setAttribute(\"y\", `${normalizedCropY}`);\n maskRect.setAttribute(\"width\", `${width}`);\n maskRect.setAttribute(\"height\", `${height}`);\n\n mask.appendChild(maskRect);\n root.appendChild(mask);\n g.setAttribute(\"mask\", `url(#${mask.id})`);\n }\n\n g.appendChild(use);\n g.setAttribute(\n \"transform\",\n `translate(${offsetX - normalizedCropX} ${\n offsetY - normalizedCropY\n }) rotate(${degree} ${adjustedCenterX} ${adjustedCenterY})`,\n );\n\n if (element.roundness) {\n const clipPath = svgRoot.ownerDocument!.createElementNS(\n SVG_NS,\n \"clipPath\",\n );\n clipPath.id = `image-clipPath-${element.id}`;\n\n const clipRect = svgRoot.ownerDocument!.createElementNS(\n SVG_NS,\n \"rect\",\n );\n const radius = getCornerRadius(\n Math.min(element.width, element.height),\n element,\n );\n clipRect.setAttribute(\"width\", `${element.width}`);\n clipRect.setAttribute(\"height\", `${element.height}`);\n clipRect.setAttribute(\"rx\", `${radius}`);\n clipRect.setAttribute(\"ry\", `${radius}`);\n clipPath.appendChild(clipRect);\n addToRoot(clipPath, element);\n\n g.setAttributeNS(SVG_NS, \"clip-path\", `url(#${clipPath.id})`);\n }\n\n const clipG = maybeWrapNodesInFrameClipPath(\n element,\n root,\n [g],\n renderConfig.frameRendering,\n elementsMap,\n );\n addToRoot(clipG || g, element);\n }\n break;\n }\n // frames are not rendered and only acts as a container\n case \"frame\":\n case \"magicframe\": {\n if (\n renderConfig.frameRendering.enabled &&\n renderConfig.frameRendering.outline\n ) {\n const rect = document.createElementNS(SVG_NS, \"rect\");\n\n rect.setAttribute(\n \"transform\",\n `translate(${offsetX || 0} ${\n offsetY || 0\n }) rotate(${degree} ${cx} ${cy})`,\n );\n\n rect.setAttribute(\"width\", `${element.width}px`);\n rect.setAttribute(\"height\", `${element.height}px`);\n // Rounded corners\n rect.setAttribute(\"rx\", FRAME_STYLE.radius.toString());\n rect.setAttribute(\"ry\", FRAME_STYLE.radius.toString());\n\n rect.setAttribute(\"fill\", \"none\");\n rect.setAttribute(\"stroke\", FRAME_STYLE.strokeColor);\n rect.setAttribute(\"stroke-width\", FRAME_STYLE.strokeWidth.toString());\n\n addToRoot(rect, element);\n }\n break;\n }\n default: {\n if (isTextElement(element)) {\n const node = svgRoot.ownerDocument!.createElementNS(SVG_NS, \"g\");\n if (opacity !== 1) {\n node.setAttribute(\"stroke-opacity\", `${opacity}`);\n node.setAttribute(\"fill-opacity\", `${opacity}`);\n }\n\n node.setAttribute(\n \"transform\",\n `translate(${offsetX || 0} ${\n offsetY || 0\n }) rotate(${degree} ${cx} ${cy})`,\n );\n const lines = element.text.replace(/\\r\\n?/g, \"\\n\").split(\"\\n\");\n const lineHeightPx = getLineHeightInPx(\n element.fontSize,\n element.lineHeight,\n );\n const horizontalOffset =\n element.textAlign === \"center\"\n ? element.width / 2\n : element.textAlign === \"right\"\n ? element.width\n : 0;\n const verticalOffset = getVerticalOffset(\n element.fontFamily,\n element.fontSize,\n lineHeightPx,\n );\n const direction = isRTL(element.text) ? \"rtl\" : \"ltr\";\n const textAnchor =\n element.textAlign === \"center\"\n ? \"middle\"\n : element.textAlign === \"right\" || direction === \"rtl\"\n ? \"end\"\n : \"start\";\n for (let i = 0; i < lines.length; i++) {\n const text = svgRoot.ownerDocument!.createElementNS(SVG_NS, \"text\");\n text.textContent = lines[i];\n text.setAttribute(\"x\", `${horizontalOffset}`);\n text.setAttribute(\"y\", `${i * lineHeightPx + verticalOffset}`);\n text.setAttribute(\"font-family\", getFontFamilyString(element));\n text.setAttribute(\"font-size\", `${element.fontSize}px`);\n text.setAttribute(\"fill\", element.strokeColor);\n text.setAttribute(\"text-anchor\", textAnchor);\n text.setAttribute(\"style\", \"white-space: pre;\");\n text.setAttribute(\"direction\", direction);\n text.setAttribute(\"dominant-baseline\", \"alphabetic\");\n node.appendChild(text);\n }\n\n const g = maybeWrapNodesInFrameClipPath(\n element,\n root,\n [node],\n renderConfig.frameRendering,\n elementsMap,\n );\n\n addToRoot(g || node, element);\n } else {\n // @ts-ignore\n throw new Error(`Unimplemented type ${element.type}`);\n }\n }\n }\n};\n\nexport const renderSceneToSvg = (\n elements: readonly NonDeletedExcalidrawElement[],\n elementsMap: RenderableElementsMap,\n rsvg: RoughSVG,\n svgRoot: SVGElement,\n files: BinaryFiles,\n renderConfig: SVGRenderConfig,\n) => {\n if (!svgRoot) {\n return;\n }\n\n // render elements\n elements\n .filter((el) => !isIframeLikeElement(el))\n .forEach((element) => {\n if (!element.isDeleted) {\n if (\n isTextElement(element) &&\n element.containerId &&\n elementsMap.has(element.containerId)\n ) {\n // will be rendered with the container\n return;\n }\n\n try {\n renderElementToSvg(\n element,\n elementsMap,\n rsvg,\n svgRoot,\n files,\n element.x + renderConfig.offsetX,\n element.y + renderConfig.offsetY,\n renderConfig,\n );\n\n const boundTextElement = getBoundTextElement(element, elementsMap);\n if (boundTextElement) {\n renderElementToSvg(\n boundTextElement,\n elementsMap,\n rsvg,\n svgRoot,\n files,\n boundTextElement.x + renderConfig.offsetX,\n boundTextElement.y + renderConfig.offsetY,\n renderConfig,\n );\n }\n } catch (error: any) {\n console.error(error);\n }\n }\n });\n\n // render embeddables on top\n elements\n .filter((el) => isIframeLikeElement(el))\n .forEach((element) => {\n if (!element.isDeleted) {\n try {\n renderElementToSvg(\n element,\n elementsMap,\n rsvg,\n svgRoot,\n files,\n element.x + renderConfig.offsetX,\n element.y + renderConfig.offsetY,\n renderConfig,\n );\n } catch (error: any) {\n console.error(error);\n }\n }\n });\n};\n", "import type { FileSystemHandle } from \"browser-fs-access\";\nimport {\n fileOpen as _fileOpen,\n fileSave as _fileSave,\n supported as nativeFileSystemSupported,\n} from \"browser-fs-access\";\nimport { EVENT, MIME_TYPES } from \"../constants\";\nimport { AbortError } from \"../errors\";\nimport { debounce } from \"../utils\";\n\ntype FILE_EXTENSION = Exclude<keyof typeof MIME_TYPES, \"binary\">;\n\nconst INPUT_CHANGE_INTERVAL_MS = 500;\n\nexport const fileOpen = <M extends boolean | undefined = false>(opts: {\n extensions?: FILE_EXTENSION[];\n description: string;\n multiple?: M;\n}): Promise<M extends false | undefined ? File : File[]> => {\n // an unsafe TS hack, alas not much we can do AFAIK\n type RetType = M extends false | undefined ? File : File[];\n\n const mimeTypes = opts.extensions?.reduce((mimeTypes, type) => {\n mimeTypes.push(MIME_TYPES[type]);\n\n return mimeTypes;\n }, [] as string[]);\n\n const extensions = opts.extensions?.reduce((acc, ext) => {\n if (ext === \"jpg\") {\n return acc.concat(\".jpg\", \".jpeg\");\n }\n return acc.concat(`.${ext}`);\n }, [] as string[]);\n\n return _fileOpen({\n description: opts.description,\n extensions,\n mimeTypes,\n multiple: opts.multiple ?? false,\n legacySetup: (resolve, reject, input) => {\n const scheduleRejection = debounce(reject, INPUT_CHANGE_INTERVAL_MS);\n const focusHandler = () => {\n checkForFile();\n document.addEventListener(EVENT.KEYUP, scheduleRejection);\n document.addEventListener(EVENT.POINTER_UP, scheduleRejection);\n scheduleRejection();\n };\n const checkForFile = () => {\n // this hack might not work when expecting multiple files\n if (input.files?.length) {\n const ret = opts.multiple ? [...input.files] : input.files[0];\n resolve(ret as RetType);\n }\n };\n requestAnimationFrame(() => {\n window.addEventListener(EVENT.FOCUS, focusHandler);\n });\n const interval = window.setInterval(() => {\n checkForFile();\n }, INPUT_CHANGE_INTERVAL_MS);\n return (rejectPromise) => {\n clearInterval(interval);\n scheduleRejection.cancel();\n window.removeEventListener(EVENT.FOCUS, focusHandler);\n document.removeEventListener(EVENT.KEYUP, scheduleRejection);\n document.removeEventListener(EVENT.POINTER_UP, scheduleRejection);\n if (rejectPromise) {\n // so that something is shown in console if we need to debug this\n console.warn(\"Opening the file was canceled (legacy-fs).\");\n rejectPromise(new AbortError());\n }\n };\n },\n }) as Promise<RetType>;\n};\n\nexport const fileSave = (\n blob: Blob | Promise<Blob>,\n opts: {\n /** supply without the extension */\n name: string;\n /** file extension */\n extension: FILE_EXTENSION;\n mimeTypes?: string[];\n description: string;\n /** existing FileSystemHandle */\n fileHandle?: FileSystemHandle | null;\n },\n) => {\n return _fileSave(\n blob,\n {\n fileName: `${opts.name}.${opts.extension}`,\n description: opts.description,\n extensions: [`.${opts.extension}`],\n mimeTypes: opts.mimeTypes,\n },\n opts.fileHandle,\n );\n};\n\nexport { nativeFileSystemSupported };\nexport type { FileSystemHandle };\n", "import { fileOpen, fileSave } from \"./filesystem\";\nimport { cleanAppStateForExport, clearAppStateForDatabase } from \"../appState\";\nimport {\n DEFAULT_FILENAME,\n EXPORT_DATA_TYPES,\n EXPORT_SOURCE,\n MIME_TYPES,\n VERSIONS,\n} from \"../constants\";\nimport { clearElementsForDatabase, clearElementsForExport } from \"../element\";\nimport type { ExcalidrawElement } from \"../element/types\";\nimport type { AppState, BinaryFiles, LibraryItems } from \"../types\";\nimport { isImageFileHandle, loadFromBlob, normalizeFile } from \"./blob\";\n\nimport type {\n ExportedDataState,\n ImportedDataState,\n ExportedLibraryData,\n ImportedLibraryData,\n} from \"./types\";\n\n/**\n * Strips out files which are only referenced by deleted elements\n */\nconst filterOutDeletedFiles = (\n elements: readonly ExcalidrawElement[],\n files: BinaryFiles,\n) => {\n const nextFiles: BinaryFiles = {};\n for (const element of elements) {\n if (\n !element.isDeleted &&\n \"fileId\" in element &&\n element.fileId &&\n files[element.fileId]\n ) {\n nextFiles[element.fileId] = files[element.fileId];\n }\n }\n return nextFiles;\n};\n\nexport const serializeAsJSON = (\n elements: readonly ExcalidrawElement[],\n appState: Partial<AppState>,\n files: BinaryFiles,\n type: \"local\" | \"database\",\n): string => {\n const data: ExportedDataState = {\n type: EXPORT_DATA_TYPES.excalidraw,\n version: VERSIONS.excalidraw,\n source: EXPORT_SOURCE,\n elements:\n type === \"local\"\n ? clearElementsForExport(elements)\n : clearElementsForDatabase(elements),\n appState:\n type === \"local\"\n ? cleanAppStateForExport(appState)\n : clearAppStateForDatabase(appState),\n files:\n type === \"local\"\n ? filterOutDeletedFiles(elements, files)\n : // will be stripped from JSON\n undefined,\n };\n\n return JSON.stringify(data, null, 2);\n};\n\nexport const saveAsJSON = async (\n elements: readonly ExcalidrawElement[],\n appState: AppState,\n files: BinaryFiles,\n /** filename */\n name: string = appState.name || DEFAULT_FILENAME,\n) => {\n const serialized = serializeAsJSON(elements, appState, files, \"local\");\n const blob = new Blob([serialized], {\n type: MIME_TYPES.excalidraw,\n });\n\n const fileHandle = await fileSave(blob, {\n name,\n extension: \"excalidraw\",\n description: \"Excalidraw file\",\n fileHandle: isImageFileHandle(appState.fileHandle)\n ? null\n : appState.fileHandle,\n });\n return { fileHandle };\n};\n\nexport const loadFromJSON = async (\n localAppState: AppState,\n localElements: readonly ExcalidrawElement[] | null,\n) => {\n const file = await fileOpen({\n description: \"Excalidraw files\",\n // ToDo: Be over-permissive until https://bugs.webkit.org/show_bug.cgi?id=34442\n // gets resolved. Else, iOS users cannot open `.excalidraw` files.\n // extensions: [\"json\", \"excalidraw\", \"png\", \"svg\"],\n });\n return loadFromBlob(\n await normalizeFile(file),\n localAppState,\n localElements,\n file.handle,\n );\n};\n\nexport const isValidExcalidrawData = (data?: {\n type?: any;\n elements?: any;\n appState?: any;\n}): data is ImportedDataState => {\n return (\n data?.type === EXPORT_DATA_TYPES.excalidraw &&\n (!data.elements ||\n (Array.isArray(data.elements) &&\n (!data.appState || typeof data.appState === \"object\")))\n );\n};\n\nexport const isValidLibrary = (json: any): json is ImportedLibraryData => {\n return (\n typeof json === \"object\" &&\n json &&\n json.type === EXPORT_DATA_TYPES.excalidrawLibrary &&\n (json.version === 1 || json.version === 2)\n );\n};\n\nexport const serializeLibraryAsJSON = (libraryItems: LibraryItems) => {\n const data: ExportedLibraryData = {\n type: EXPORT_DATA_TYPES.excalidrawLibrary,\n version: VERSIONS.excalidrawLibrary,\n source: EXPORT_SOURCE,\n libraryItems,\n };\n return JSON.stringify(data, null, 2);\n};\n\nexport const saveLibraryAsJSON = async (libraryItems: LibraryItems) => {\n const serialized = serializeLibraryAsJSON(libraryItems);\n await fileSave(\n new Blob([serialized], {\n type: MIME_TYPES.excalidrawlib,\n }),\n {\n name: \"library\",\n extension: \"excalidrawlib\",\n description: \"Excalidraw library file\",\n },\n );\n};\n", "// -----------------------------------------------------------------------------\n// ExcalidrawImageElement & related helpers\n// -----------------------------------------------------------------------------\n\nimport { MIME_TYPES, SVG_NS } from \"../constants\";\nimport type { AppClassProperties, DataURL, BinaryFiles } from \"../types\";\nimport { isInitializedImageElement } from \"./typeChecks\";\nimport type {\n ExcalidrawElement,\n FileId,\n InitializedExcalidrawImageElement,\n} from \"./types\";\n\nexport const loadHTMLImageElement = (dataURL: DataURL) => {\n return new Promise<HTMLImageElement>((resolve, reject) => {\n const image = new Image();\n image.onload = () => {\n resolve(image);\n };\n image.onerror = (error) => {\n reject(error);\n };\n image.src = dataURL;\n });\n};\n\n/** NOTE: updates cache even if already populated with given image. Thus,\n * you should filter out the images upstream if you want to optimize this. */\nexport const updateImageCache = async ({\n fileIds,\n files,\n imageCache,\n}: {\n fileIds: FileId[];\n files: BinaryFiles;\n imageCache: AppClassProperties[\"imageCache\"];\n}) => {\n const updatedFiles = new Map<FileId, true>();\n const erroredFiles = new Map<FileId, true>();\n\n await Promise.all(\n fileIds.reduce((promises, fileId) => {\n const fileData = files[fileId as string];\n if (fileData && !updatedFiles.has(fileId)) {\n updatedFiles.set(fileId, true);\n return promises.concat(\n (async () => {\n try {\n if (fileData.mimeType === MIME_TYPES.binary) {\n throw new Error(\"Only images can be added to ImageCache\");\n }\n\n const imagePromise = loadHTMLImageElement(fileData.dataURL);\n const data = {\n image: imagePromise,\n mimeType: fileData.mimeType,\n } as const;\n // store the promise immediately to indicate there's an in-progress\n // initialization\n imageCache.set(fileId, data);\n\n const image = await imagePromise;\n\n imageCache.set(fileId, { ...data, image });\n } catch (error: any) {\n erroredFiles.set(fileId, true);\n }\n })(),\n );\n }\n return promises;\n }, [] as Promise<any>[]),\n );\n\n return {\n imageCache,\n /** includes errored files because they cache was updated nonetheless */\n updatedFiles,\n /** files that failed when creating HTMLImageElement */\n erroredFiles,\n };\n};\n\nexport const getInitializedImageElements = (\n elements: readonly ExcalidrawElement[],\n) =>\n elements.filter((element) =>\n isInitializedImageElement(element),\n ) as InitializedExcalidrawImageElement[];\n\nexport const isHTMLSVGElement = (node: Node | null): node is SVGElement => {\n // lower-casing due to XML/HTML convention differences\n // https://johnresig.com/blog/nodename-case-sensitivity\n return node?.nodeName.toLowerCase() === \"svg\";\n};\n\nexport const normalizeSVG = (SVGString: string) => {\n const doc = new DOMParser().parseFromString(SVGString, MIME_TYPES.svg);\n const svg = doc.querySelector(\"svg\");\n const errorNode = doc.querySelector(\"parsererror\");\n if (errorNode || !isHTMLSVGElement(svg)) {\n throw new Error(\"Invalid SVG\");\n } else {\n if (!svg.hasAttribute(\"xmlns\")) {\n svg.setAttribute(\"xmlns\", SVG_NS);\n }\n\n let width = svg.getAttribute(\"width\");\n let height = svg.getAttribute(\"height\");\n\n // Do not use % or auto values for width/height\n // to avoid scaling issues when rendering at different sizes/zoom levels\n if (width?.includes(\"%\") || width === \"auto\") {\n width = null;\n }\n if (height?.includes(\"%\") || height === \"auto\") {\n height = null;\n }\n\n const viewBox = svg.getAttribute(\"viewBox\");\n\n if (!width || !height) {\n width = width || \"50\";\n height = height || \"50\";\n\n if (viewBox) {\n const match = viewBox.match(\n /\\d+ +\\d+ +(\\d+(?:\\.\\d+)?) +(\\d+(?:\\.\\d+)?)/,\n );\n if (match) {\n [, width, height] = match;\n }\n }\n\n svg.setAttribute(\"width\", width);\n svg.setAttribute(\"height\", height);\n }\n\n // Make sure viewBox is set\n if (!viewBox) {\n svg.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n }\n\n return svg.outerHTML;\n }\n};\n", "import type {\n ExcalidrawArrowElement,\n ExcalidrawElbowArrowElement,\n ExcalidrawElement,\n ExcalidrawElementType,\n ExcalidrawLinearElement,\n ExcalidrawSelectionElement,\n ExcalidrawTextElement,\n FixedPointBinding,\n FontFamilyValues,\n OrderedExcalidrawElement,\n PointBinding,\n StrokeRoundness,\n} from \"../element/types\";\nimport type { AppState, BinaryFiles, LibraryItem } from \"../types\";\nimport type { ImportedDataState, LegacyAppState } from \"./types\";\nimport {\n getNonDeletedElements,\n getNormalizedDimensions,\n isInvisiblySmallElement,\n refreshTextDimensions,\n} from \"../element\";\nimport {\n isArrowElement,\n isElbowArrow,\n isFixedPointBinding,\n isLinearElement,\n isTextElement,\n isUsingAdaptiveRadius,\n} from \"../element/typeChecks\";\nimport { randomId } from \"../random\";\nimport {\n DEFAULT_FONT_FAMILY,\n DEFAULT_TEXT_ALIGN,\n DEFAULT_VERTICAL_ALIGN,\n FONT_FAMILY,\n ROUNDNESS,\n DEFAULT_SIDEBAR,\n DEFAULT_ELEMENT_PROPS,\n DEFAULT_GRID_SIZE,\n DEFAULT_GRID_STEP,\n} from \"../constants\";\nimport { getDefaultAppState } from \"../appState\";\nimport { LinearElementEditor } from \"../element/linearElementEditor\";\nimport { bumpVersion } from \"../element/mutateElement\";\nimport { getUpdatedTimestamp, updateActiveTool } from \"../utils\";\nimport { arrayToMap } from \"../utils\";\nimport type { MarkOptional, Mutable } from \"../utility-types\";\nimport { getContainerElement } from \"../element/textElement\";\nimport { normalizeLink } from \"./url\";\nimport { syncInvalidIndices } from \"../fractionalIndex\";\nimport { getSizeFromPoints } from \"../points\";\nimport { getLineHeight } from \"../fonts\";\nimport { normalizeFixedPoint } from \"../element/binding\";\nimport {\n getNormalizedGridSize,\n getNormalizedGridStep,\n getNormalizedZoom,\n} from \"../scene\";\nimport type { LocalPoint, Radians } from \"@excalidraw/math\";\nimport { isFiniteNumber, pointFrom } from \"@excalidraw/math\";\nimport { detectLineHeight } from \"../element/textMeasurements\";\n\ntype RestoredAppState = Omit<\n AppState,\n \"offsetTop\" | \"offsetLeft\" | \"width\" | \"height\"\n>;\n\nexport const AllowedExcalidrawActiveTools: Record<\n AppState[\"activeTool\"][\"type\"],\n boolean\n> = {\n selection: true,\n text: true,\n rectangle: true,\n diamond: true,\n ellipse: true,\n line: true,\n image: true,\n arrow: true,\n freedraw: true,\n eraser: false,\n custom: true,\n frame: true,\n embeddable: true,\n hand: true,\n laser: false,\n magicframe: false,\n};\n\nexport type RestoredDataState = {\n elements: OrderedExcalidrawElement[];\n appState: RestoredAppState;\n files: BinaryFiles;\n};\n\nconst getFontFamilyByName = (fontFamilyName: string): FontFamilyValues => {\n if (Object.keys(FONT_FAMILY).includes(fontFamilyName)) {\n return FONT_FAMILY[\n fontFamilyName as keyof typeof FONT_FAMILY\n ] as FontFamilyValues;\n }\n return DEFAULT_FONT_FAMILY;\n};\n\nconst repairBinding = <T extends ExcalidrawLinearElement>(\n element: T,\n binding: PointBinding | FixedPointBinding | null,\n): T extends ExcalidrawElbowArrowElement\n ? FixedPointBinding | null\n : PointBinding | FixedPointBinding | null => {\n if (!binding) {\n return null;\n }\n\n const focus = binding.focus || 0;\n\n if (isElbowArrow(element)) {\n const fixedPointBinding:\n | ExcalidrawElbowArrowElement[\"startBinding\"]\n | ExcalidrawElbowArrowElement[\"endBinding\"] = isFixedPointBinding(binding)\n ? {\n ...binding,\n focus,\n fixedPoint: normalizeFixedPoint(binding.fixedPoint ?? [0, 0]),\n }\n : null;\n\n return fixedPointBinding;\n }\n\n return {\n ...binding,\n focus,\n } as T extends ExcalidrawElbowArrowElement\n ? FixedPointBinding | null\n : PointBinding | FixedPointBinding | null;\n};\n\nconst restoreElementWithProperties = <\n T extends Required<Omit<ExcalidrawElement, \"customData\">> & {\n customData?: ExcalidrawElement[\"customData\"];\n /** @deprecated */\n boundElementIds?: readonly ExcalidrawElement[\"id\"][];\n /** @deprecated */\n strokeSharpness?: StrokeRoundness;\n },\n K extends Pick<T, keyof Omit<Required<T>, keyof ExcalidrawElement>>,\n>(\n element: T,\n extra: Pick<\n T,\n // This extra Pick<T, keyof K> ensure no excess properties are passed.\n // @ts-ignore TS complains here but type checks the call sites fine.\n keyof K\n > &\n Partial<Pick<ExcalidrawElement, \"type\" | \"x\" | \"y\" | \"customData\">>,\n): T => {\n const base: Pick<T, keyof ExcalidrawElement> = {\n type: extra.type || element.type,\n // all elements must have version > 0 so getSceneVersion() will pick up\n // newly added elements\n version: element.version || 1,\n versionNonce: element.versionNonce ?? 0,\n index: element.index ?? null,\n isDeleted: element.isDeleted ?? false,\n id: element.id || randomId(),\n fillStyle: element.fillStyle || DEFAULT_ELEMENT_PROPS.fillStyle,\n strokeWidth: element.strokeWidth || DEFAULT_ELEMENT_PROPS.strokeWidth,\n strokeStyle: element.strokeStyle ?? DEFAULT_ELEMENT_PROPS.strokeStyle,\n roughness: element.roughness ?? DEFAULT_ELEMENT_PROPS.roughness,\n opacity:\n element.opacity == null ? DEFAULT_ELEMENT_PROPS.opacity : element.opacity,\n angle: element.angle || (0 as Radians),\n x: extra.x ?? element.x ?? 0,\n y: extra.y ?? element.y ?? 0,\n strokeColor: element.strokeColor || DEFAULT_ELEMENT_PROPS.strokeColor,\n backgroundColor:\n element.backgroundColor || DEFAULT_ELEMENT_PROPS.backgroundColor,\n width: element.width || 0,\n height: element.height || 0,\n seed: element.seed ?? 1,\n groupIds: element.groupIds ?? [],\n frameId: element.frameId ?? null,\n roundness: element.roundness\n ? element.roundness\n : element.strokeSharpness === \"round\"\n ? {\n // for old elements that would now use adaptive radius algo,\n // use legacy algo instead\n type: isUsingAdaptiveRadius(element.type)\n ? ROUNDNESS.LEGACY\n : ROUNDNESS.PROPORTIONAL_RADIUS,\n }\n : null,\n boundElements: element.boundElementIds\n ? element.boundElementIds.map((id) => ({ type: \"arrow\", id }))\n : element.boundElements ?? [],\n updated: element.updated ?? getUpdatedTimestamp(),\n link: element.link ? normalizeLink(element.link) : null,\n locked: element.locked ?? false,\n };\n\n if (\"customData\" in element || \"customData\" in extra) {\n base.customData =\n \"customData\" in extra ? extra.customData : element.customData;\n }\n\n // NOTE (mtolmacs): This is a temporary check to detect extremely large\n // element position or sizing\n if (\n element.x < -1e6 ||\n element.x > 1e6 ||\n element.y < -1e6 ||\n element.y > 1e6 ||\n element.width < -1e6 ||\n element.width > 1e6 ||\n element.height < -1e6 ||\n element.height > 1e6\n ) {\n console.error(\n \"Restore element with properties size or position is too large\",\n { element },\n );\n }\n\n return {\n // spread the original element properties to not lose unknown ones\n // for forward-compatibility\n ...element,\n // normalized properties\n ...base,\n ...getNormalizedDimensions(base),\n ...extra,\n } as unknown as T;\n};\n\nconst restoreElement = (\n element: Exclude<ExcalidrawElement, ExcalidrawSelectionElement>,\n): typeof element | null => {\n // NOTE (mtolmacs): This is a temporary check to detect extremely large\n // element position or sizing\n if (\n element.x < -1e6 ||\n element.x > 1e6 ||\n element.y < -1e6 ||\n element.y > 1e6 ||\n element.width < -1e6 ||\n element.width > 1e6 ||\n element.height < -1e6 ||\n element.height > 1e6\n ) {\n console.error(\"Restore element size or position is too large\", { element });\n }\n\n switch (element.type) {\n case \"text\":\n let fontSize = element.fontSize;\n let fontFamily = element.fontFamily;\n if (\"font\" in element) {\n const [fontPx, _fontFamily]: [string, string] = (\n element as any\n ).font.split(\" \");\n fontSize = parseFloat(fontPx);\n fontFamily = getFontFamilyByName(_fontFamily);\n }\n const text = (typeof element.text === \"string\" && element.text) || \"\";\n\n // line-height might not be specified either when creating elements\n // programmatically, or when importing old diagrams.\n // For the latter we want to detect the original line height which\n // will likely differ from our per-font fixed line height we now use,\n // to maintain backward compatibility.\n const lineHeight =\n element.lineHeight ||\n (element.height\n ? // detect line-height from current element height and font-size\n detectLineHeight(element)\n : // no element height likely means programmatic use, so default\n // to a fixed line height\n getLineHeight(element.fontFamily));\n element = restoreElementWithProperties(element, {\n fontSize,\n fontFamily,\n text,\n textAlign: element.textAlign || DEFAULT_TEXT_ALIGN,\n verticalAlign: element.verticalAlign || DEFAULT_VERTICAL_ALIGN,\n containerId: element.containerId ?? null,\n originalText: element.originalText || text,\n autoResize: element.autoResize ?? true,\n lineHeight,\n });\n\n // if empty text, mark as deleted. We keep in array\n // for data integrity purposes (collab etc.)\n if (!text && !element.isDeleted) {\n element = { ...element, originalText: text, isDeleted: true };\n element = bumpVersion(element);\n }\n\n return element;\n case \"freedraw\": {\n return restoreElementWithProperties(element, {\n points: element.points,\n lastCommittedPoint: null,\n simulatePressure: element.simulatePressure,\n pressures: element.pressures,\n });\n }\n case \"image\":\n return restoreElementWithProperties(element, {\n status: element.status || \"pending\",\n fileId: element.fileId,\n scale: element.scale || [1, 1],\n crop: element.crop ?? null,\n });\n case \"line\":\n // @ts-ignore LEGACY type\n // eslint-disable-next-line no-fallthrough\n case \"draw\":\n const { startArrowhead = null, endArrowhead = null } = element;\n let x = element.x;\n let y = element.y;\n let points = // migrate old arrow model to new one\n !Array.isArray(element.points) || element.points.length < 2\n ? [pointFrom(0, 0), pointFrom(element.width, element.height)]\n : element.points;\n\n if (points[0][0] !== 0 || points[0][1] !== 0) {\n ({ points, x, y } = LinearElementEditor.getNormalizedPoints(element));\n }\n\n return restoreElementWithProperties(element, {\n type:\n (element.type as ExcalidrawElementType | \"draw\") === \"draw\"\n ? \"line\"\n : element.type,\n startBinding: repairBinding(element, element.startBinding),\n endBinding: repairBinding(element, element.endBinding),\n lastCommittedPoint: null,\n startArrowhead,\n endArrowhead,\n points,\n x,\n y,\n ...getSizeFromPoints(points),\n });\n case \"arrow\": {\n const { startArrowhead = null, endArrowhead = \"arrow\" } = element;\n let x: number | undefined = element.x;\n let y: number | undefined = element.y;\n let points: readonly LocalPoint[] | undefined = // migrate old arrow model to new one\n !Array.isArray(element.points) || element.points.length < 2\n ? [pointFrom(0, 0), pointFrom(element.width, element.height)]\n : element.points;\n\n if (points[0][0] !== 0 || points[0][1] !== 0) {\n ({ points, x, y } = LinearElementEditor.getNormalizedPoints(element));\n }\n\n const base = {\n type: element.type,\n startBinding: repairBinding(element, element.startBinding),\n endBinding: repairBinding(element, element.endBinding),\n lastCommittedPoint: null,\n startArrowhead,\n endArrowhead,\n points,\n x,\n y,\n elbowed: (element as ExcalidrawArrowElement).elbowed,\n ...getSizeFromPoints(points),\n } as const;\n\n // TODO: Separate arrow from linear element\n return isElbowArrow(element)\n ? restoreElementWithProperties(element as ExcalidrawElbowArrowElement, {\n ...base,\n elbowed: true,\n startBinding: repairBinding(element, element.startBinding),\n endBinding: repairBinding(element, element.endBinding),\n fixedSegments: element.fixedSegments,\n startIsSpecial: element.startIsSpecial,\n endIsSpecial: element.endIsSpecial,\n })\n : restoreElementWithProperties(element as ExcalidrawArrowElement, base);\n }\n\n // generic elements\n case \"ellipse\":\n case \"rectangle\":\n case \"diamond\":\n case \"iframe\":\n case \"embeddable\":\n return restoreElementWithProperties(element, {});\n case \"magicframe\":\n case \"frame\":\n return restoreElementWithProperties(element, {\n name: element.name ?? null,\n });\n\n // Don't use default case so as to catch a missing an element type case.\n // We also don't want to throw, but instead return void so we filter\n // out these unsupported elements from the restored array.\n }\n return null;\n};\n\n/**\n * Repairs container element's boundElements array by removing duplicates and\n * fixing containerId of bound elements if not present. Also removes any\n * bound elements that do not exist in the elements array.\n *\n * NOTE mutates elements.\n */\nconst repairContainerElement = (\n container: Mutable<ExcalidrawElement>,\n elementsMap: Map<string, Mutable<ExcalidrawElement>>,\n) => {\n if (container.boundElements) {\n // copy because we're not cloning on restore, and we don't want to mutate upstream\n const boundElements = container.boundElements.slice();\n\n // dedupe bindings & fix boundElement.containerId if not set already\n const boundIds = new Set<ExcalidrawElement[\"id\"]>();\n container.boundElements = boundElements.reduce(\n (\n acc: Mutable<NonNullable<ExcalidrawElement[\"boundElements\"]>>,\n binding,\n ) => {\n const boundElement = elementsMap.get(binding.id);\n if (boundElement && !boundIds.has(binding.id)) {\n boundIds.add(binding.id);\n\n if (boundElement.isDeleted) {\n return acc;\n }\n\n acc.push(binding);\n\n if (\n isTextElement(boundElement) &&\n // being slightly conservative here, preserving existing containerId\n // if defined, lest boundElements is stale\n !boundElement.containerId\n ) {\n (boundElement as Mutable<ExcalidrawTextElement>).containerId =\n container.id;\n }\n }\n return acc;\n },\n [],\n );\n }\n};\n\n/**\n * Repairs target bound element's container's boundElements array,\n * or removes contaienrId if container does not exist.\n *\n * NOTE mutates elements.\n */\nconst repairBoundElement = (\n boundElement: Mutable<ExcalidrawTextElement>,\n elementsMap: Map<string, Mutable<ExcalidrawElement>>,\n) => {\n const container = boundElement.containerId\n ? elementsMap.get(boundElement.containerId)\n : null;\n\n if (!container) {\n boundElement.containerId = null;\n return;\n }\n\n if (boundElement.isDeleted) {\n return;\n }\n\n if (\n container.boundElements &&\n !container.boundElements.find((binding) => binding.id === boundElement.id)\n ) {\n // copy because we're not cloning on restore, and we don't want to mutate upstream\n const boundElements = (\n container.boundElements || (container.boundElements = [])\n ).slice();\n boundElements.push({ type: \"text\", id: boundElement.id });\n container.boundElements = boundElements;\n }\n};\n\n/**\n * Remove an element's frameId if its containing frame is non-existent\n *\n * NOTE mutates elements.\n */\nconst repairFrameMembership = (\n element: Mutable<ExcalidrawElement>,\n elementsMap: Map<string, Mutable<ExcalidrawElement>>,\n) => {\n if (element.frameId) {\n const containingFrame = elementsMap.get(element.frameId);\n\n if (!containingFrame) {\n element.frameId = null;\n }\n }\n};\n\nexport const restoreElements = (\n elements: ImportedDataState[\"elements\"],\n /** NOTE doesn't serve for reconciliation */\n localElements: readonly ExcalidrawElement[] | null | undefined,\n opts?: { refreshDimensions?: boolean; repairBindings?: boolean } | undefined,\n): OrderedExcalidrawElement[] => {\n // used to detect duplicate top-level element ids\n const existingIds = new Set<string>();\n const localElementsMap = localElements ? arrayToMap(localElements) : null;\n const restoredElements = syncInvalidIndices(\n (elements || []).reduce((elements, element) => {\n // filtering out selection, which is legacy, no longer kept in elements,\n // and causing issues if retained\n if (element.type !== \"selection\" && !isInvisiblySmallElement(element)) {\n let migratedElement: ExcalidrawElement | null = restoreElement(element);\n if (migratedElement) {\n const localElement = localElementsMap?.get(element.id);\n if (localElement && localElement.version > migratedElement.version) {\n migratedElement = bumpVersion(\n migratedElement,\n localElement.version,\n );\n }\n if (existingIds.has(migratedElement.id)) {\n migratedElement = { ...migratedElement, id: randomId() };\n }\n existingIds.add(migratedElement.id);\n\n elements.push(migratedElement);\n }\n }\n return elements;\n }, [] as ExcalidrawElement[]),\n );\n\n if (!opts?.repairBindings) {\n return restoredElements;\n }\n\n // repair binding. Mutates elements.\n const restoredElementsMap = arrayToMap(restoredElements);\n for (const element of restoredElements) {\n if (element.frameId) {\n repairFrameMembership(element, restoredElementsMap);\n }\n\n if (isTextElement(element) && element.containerId) {\n repairBoundElement(element, restoredElementsMap);\n } else if (element.boundElements) {\n repairContainerElement(element, restoredElementsMap);\n }\n\n if (opts.refreshDimensions && isTextElement(element)) {\n Object.assign(\n element,\n refreshTextDimensions(\n element,\n getContainerElement(element, restoredElementsMap),\n restoredElementsMap,\n ),\n );\n }\n\n if (isLinearElement(element)) {\n if (\n element.startBinding &&\n (!restoredElementsMap.has(element.startBinding.elementId) ||\n !isArrowElement(element))\n ) {\n (element as Mutable<ExcalidrawLinearElement>).startBinding = null;\n }\n if (\n element.endBinding &&\n (!restoredElementsMap.has(element.endBinding.elementId) ||\n !isArrowElement(element))\n ) {\n (element as Mutable<ExcalidrawLinearElement>).endBinding = null;\n }\n }\n }\n\n return restoredElements;\n};\n\nconst coalesceAppStateValue = <\n T extends keyof ReturnType<typeof getDefaultAppState>,\n>(\n key: T,\n appState: Exclude<ImportedDataState[\"appState\"], null | undefined>,\n defaultAppState: ReturnType<typeof getDefaultAppState>,\n) => {\n const value = appState[key];\n // NOTE the value! assertion is needed in TS 4.5.5 (fixed in newer versions)\n return value !== undefined ? value! : defaultAppState[key];\n};\n\nconst LegacyAppStateMigrations: {\n [K in keyof LegacyAppState]: (\n ImportedDataState: Exclude<ImportedDataState[\"appState\"], null | undefined>,\n defaultAppState: ReturnType<typeof getDefaultAppState>,\n ) => [LegacyAppState[K][1], AppState[LegacyAppState[K][1]]];\n} = {\n isSidebarDocked: (appState, defaultAppState) => {\n return [\n \"defaultSidebarDockedPreference\",\n appState.isSidebarDocked ??\n coalesceAppStateValue(\n \"defaultSidebarDockedPreference\",\n appState,\n defaultAppState,\n ),\n ];\n },\n};\n\nexport const restoreAppState = (\n appState: ImportedDataState[\"appState\"],\n localAppState: Partial<AppState> | null | undefined,\n): RestoredAppState => {\n appState = appState || {};\n const defaultAppState = getDefaultAppState();\n const nextAppState = {} as typeof defaultAppState;\n\n // first, migrate all legacy AppState properties to new ones. We do it\n // in one go before migrate the rest of the properties in case the new ones\n // depend on checking any other key (i.e. they are coupled)\n for (const legacyKey of Object.keys(\n LegacyAppStateMigrations,\n ) as (keyof typeof LegacyAppStateMigrations)[]) {\n if (legacyKey in appState) {\n const [nextKey, nextValue] = LegacyAppStateMigrations[legacyKey](\n appState,\n defaultAppState,\n );\n (nextAppState as any)[nextKey] = nextValue;\n }\n }\n\n for (const [key, defaultValue] of Object.entries(defaultAppState) as [\n keyof typeof defaultAppState,\n any,\n ][]) {\n // if AppState contains a legacy key, prefer that one and migrate its\n // value to the new one\n const suppliedValue = appState[key];\n\n const localValue = localAppState ? localAppState[key] : undefined;\n (nextAppState as any)[key] =\n suppliedValue !== undefined\n ? suppliedValue\n : localValue !== undefined\n ? localValue\n : defaultValue;\n }\n\n return {\n ...nextAppState,\n cursorButton: localAppState?.cursorButton || \"up\",\n // reset on fresh restore so as to hide the UI button if penMode not active\n penDetected:\n localAppState?.penDetected ??\n (appState.penMode ? appState.penDetected ?? false : false),\n activeTool: {\n ...updateActiveTool(\n defaultAppState,\n nextAppState.activeTool.type &&\n AllowedExcalidrawActiveTools[nextAppState.activeTool.type]\n ? nextAppState.activeTool\n : { type: \"selection\" },\n ),\n lastActiveTool: null,\n locked: nextAppState.activeTool.locked ?? false,\n },\n // Migrates from previous version where appState.zoom was a number\n zoom: {\n value: getNormalizedZoom(\n isFiniteNumber(appState.zoom)\n ? appState.zoom\n : appState.zoom?.value ?? defaultAppState.zoom.value,\n ),\n },\n openSidebar:\n // string (legacy)\n typeof (appState.openSidebar as any as string) === \"string\"\n ? { name: DEFAULT_SIDEBAR.name }\n : nextAppState.openSidebar,\n gridSize: getNormalizedGridSize(\n isFiniteNumber(appState.gridSize) ? appState.gridSize : DEFAULT_GRID_SIZE,\n ),\n gridStep: getNormalizedGridStep(\n isFiniteNumber(appState.gridStep) ? appState.gridStep : DEFAULT_GRID_STEP,\n ),\n editingFrame: null,\n };\n};\n\nexport const restore = (\n data: Pick<ImportedDataState, \"appState\" | \"elements\" | \"files\"> | null,\n /**\n * Local AppState (`this.state` or initial state from localStorage) so that we\n * don't overwrite local state with default values (when values not\n * explicitly specified).\n * Supply `null` if you can't get access to it.\n */\n localAppState: Partial<AppState> | null | undefined,\n localElements: readonly ExcalidrawElement[] | null | undefined,\n elementsConfig?: { refreshDimensions?: boolean; repairBindings?: boolean },\n): RestoredDataState => {\n return {\n elements: restoreElements(data?.elements, localElements, elementsConfig),\n appState: restoreAppState(data?.appState, localAppState || null),\n files: data?.files || {},\n };\n};\n\nconst restoreLibraryItem = (libraryItem: LibraryItem) => {\n const elements = restoreElements(\n getNonDeletedElements(libraryItem.elements),\n null,\n );\n return elements.length ? { ...libraryItem, elements } : null;\n};\n\nexport const restoreLibraryItems = (\n libraryItems: ImportedDataState[\"libraryItems\"] = [],\n defaultStatus: LibraryItem[\"status\"],\n) => {\n const restoredItems: LibraryItem[] = [];\n for (const item of libraryItems) {\n // migrate older libraries\n if (Array.isArray(item)) {\n const restoredItem = restoreLibraryItem({\n status: defaultStatus,\n elements: item,\n id: randomId(),\n created: Date.now(),\n });\n if (restoredItem) {\n restoredItems.push(restoredItem);\n }\n } else {\n const _item = item as MarkOptional<\n LibraryItem,\n \"id\" | \"status\" | \"created\"\n >;\n const restoredItem = restoreLibraryItem({\n ..._item,\n id: _item.id || randomId(),\n status: _item.status || defaultStatus,\n created: _item.created || Date.now(),\n });\n if (restoredItem) {\n restoredItems.push(restoredItem);\n }\n }\n }\n return restoredItems;\n};\n", "import type { GlobalPoint, Radians } from \"@excalidraw/math\";\nimport { pointFrom, pointRotateRads } from \"@excalidraw/math\";\nimport { MIME_TYPES } from \"../../constants\";\nimport type { Bounds } from \"../../element/bounds\";\nimport { getElementAbsoluteCoords } from \"../../element/bounds\";\nimport { hitElementBoundingBox } from \"../../element/collision\";\nimport type {\n ElementsMap,\n NonDeletedExcalidrawElement,\n} from \"../../element/types\";\nimport { DEFAULT_LINK_SIZE } from \"../../renderer/renderElement\";\nimport type { AppState, UIAppState } from \"../../types\";\n\nexport const EXTERNAL_LINK_IMG = document.createElement(\"img\");\nEXTERNAL_LINK_IMG.src = `data:${MIME_TYPES.svg}, ${encodeURIComponent(\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#1971c2\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-external-link\"><path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"></path><polyline points=\"15 3 21 3 21 9\"></polyline><line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"></line></svg>`,\n)}`;\n\nexport const ELEMENT_LINK_IMG = document.createElement(\"img\");\nELEMENT_LINK_IMG.src = `data:${MIME_TYPES.svg}, ${encodeURIComponent(\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#1971c2\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-arrow-big-right-line\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M12 9v-3.586a1 1 0 0 1 1.707 -.707l6.586 6.586a1 1 0 0 1 0 1.414l-6.586 6.586a1 1 0 0 1 -1.707 -.707v-3.586h-6v-6h6z\" /><path d=\"M3 9v6\" /></svg>`,\n)}`;\n\nexport const getLinkHandleFromCoords = (\n [x1, y1, x2, y2]: Bounds,\n angle: Radians,\n appState: Pick<UIAppState, \"zoom\">,\n): Bounds => {\n const size = DEFAULT_LINK_SIZE;\n const linkWidth = size / appState.zoom.value;\n const linkHeight = size / appState.zoom.value;\n const linkMarginY = size / appState.zoom.value;\n const centerX = (x1 + x2) / 2;\n const centerY = (y1 + y2) / 2;\n const centeringOffset = (size - 8) / (2 * appState.zoom.value);\n const dashedLineMargin = 4 / appState.zoom.value;\n\n // Same as `ne` resize handle\n const x = x2 + dashedLineMargin - centeringOffset;\n const y = y1 - dashedLineMargin - linkMarginY + centeringOffset;\n\n const [rotatedX, rotatedY] = pointRotateRads(\n pointFrom(x + linkWidth / 2, y + linkHeight / 2),\n pointFrom(centerX, centerY),\n angle,\n );\n return [\n rotatedX - linkWidth / 2,\n rotatedY - linkHeight / 2,\n linkWidth,\n linkHeight,\n ];\n};\n\nexport const isPointHittingLinkIcon = (\n element: NonDeletedExcalidrawElement,\n elementsMap: ElementsMap,\n appState: AppState,\n [x, y]: GlobalPoint,\n) => {\n const threshold = 4 / appState.zoom.value;\n const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);\n const [linkX, linkY, linkWidth, linkHeight] = getLinkHandleFromCoords(\n [x1, y1, x2, y2],\n element.angle,\n appState,\n );\n const hitLink =\n x > linkX - threshold &&\n x < linkX + threshold + linkWidth &&\n y > linkY - threshold &&\n y < linkY + linkHeight + threshold;\n return hitLink;\n};\n\nexport const isPointHittingLink = (\n element: NonDeletedExcalidrawElement,\n elementsMap: ElementsMap,\n appState: AppState,\n [x, y]: GlobalPoint,\n isMobile: boolean,\n) => {\n if (!element.link || appState.selectedElementIds[element.id]) {\n return false;\n }\n if (\n !isMobile &&\n appState.viewModeEnabled &&\n hitElementBoundingBox(x, y, element, elementsMap)\n ) {\n return true;\n }\n return isPointHittingLinkIcon(\n element,\n elementsMap,\n appState,\n pointFrom(x, y),\n );\n};\n", "import type { StaticCanvasAppState, AppState } from \"../types\";\n\nimport type { StaticCanvasRenderConfig } from \"../scene/types\";\n\nimport { THEME, THEME_FILTER } from \"../constants\";\n\nexport const fillCircle = (\n context: CanvasRenderingContext2D,\n cx: number,\n cy: number,\n radius: number,\n stroke = true,\n) => {\n context.beginPath();\n context.arc(cx, cy, radius, 0, Math.PI * 2);\n context.fill();\n if (stroke) {\n context.stroke();\n }\n};\n\nexport const getNormalizedCanvasDimensions = (\n canvas: HTMLCanvasElement,\n scale: number,\n): [number, number] => {\n // When doing calculations based on canvas width we should used normalized one\n return [canvas.width / scale, canvas.height / scale];\n};\n\nexport const bootstrapCanvas = ({\n canvas,\n scale,\n normalizedWidth,\n normalizedHeight,\n theme,\n isExporting,\n canvasBackgroundColor,\n}: {\n canvas: HTMLCanvasElement;\n scale: number;\n normalizedWidth: number;\n normalizedHeight: number;\n theme?: AppState[\"theme\"];\n // static canvas only\n isExporting?: StaticCanvasRenderConfig[\"isExporting\"];\n canvasBackgroundColor?: string | null;\n}): CanvasRenderingContext2D => {\n const context = canvas.getContext(\"2d\")!;\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n context.scale(scale, scale);\n\n if (isExporting && theme === THEME.DARK) {\n context.filter = THEME_FILTER;\n }\n\n // Paint background\n if (typeof canvasBackgroundColor === \"string\") {\n const hasTransparence =\n canvasBackgroundColor === \"transparent\" ||\n canvasBackgroundColor.length === 5 || // #RGBA\n canvasBackgroundColor.length === 9 || // #RRGGBBA\n /(hsla|rgba)\\(/.test(canvasBackgroundColor);\n if (hasTransparence) {\n context.clearRect(0, 0, normalizedWidth, normalizedHeight);\n }\n context.save();\n context.fillStyle = canvasBackgroundColor;\n context.fillRect(0, 0, normalizedWidth, normalizedHeight);\n context.restore();\n } else {\n context.clearRect(0, 0, normalizedWidth, normalizedHeight);\n }\n\n return context;\n};\n", "/**\n * Create and link between shapes.\n */\n\nimport { ELEMENT_LINK_KEY } from \"../constants\";\nimport { normalizeLink } from \"../data/url\";\nimport { elementsAreInSameGroup } from \"../groups\";\nimport type { AppProps, AppState } from \"../types\";\nimport type { ExcalidrawElement } from \"./types\";\n\nexport const defaultGetElementLinkFromSelection: Exclude<\n AppProps[\"generateLinkForSelection\"],\n undefined\n> = (id, type) => {\n const url = window.location.href;\n\n try {\n const link = new URL(url);\n link.searchParams.set(ELEMENT_LINK_KEY, id);\n\n return normalizeLink(link.toString());\n } catch (error) {\n console.error(error);\n }\n\n return normalizeLink(url);\n};\n\nexport const getLinkIdAndTypeFromSelection = (\n selectedElements: ExcalidrawElement[],\n appState: AppState,\n): {\n id: string;\n type: \"element\" | \"group\";\n} | null => {\n if (\n selectedElements.length > 0 &&\n canCreateLinkFromElements(selectedElements)\n ) {\n if (selectedElements.length === 1) {\n return {\n id: selectedElements[0].id,\n type: \"element\",\n };\n }\n\n if (selectedElements.length > 1) {\n const selectedGroupId = Object.keys(appState.selectedGroupIds)[0];\n\n if (selectedGroupId) {\n return {\n id: selectedGroupId,\n type: \"group\",\n };\n }\n return {\n id: selectedElements[0].groupIds[0],\n type: \"group\",\n };\n }\n }\n\n return null;\n};\n\nexport const canCreateLinkFromElements = (\n selectedElements: ExcalidrawElement[],\n) => {\n if (selectedElements.length === 1) {\n return true;\n }\n\n if (selectedElements.length > 1 && elementsAreInSameGroup(selectedElements)) {\n return true;\n }\n\n return false;\n};\n\nexport const isElementLink = (url: string) => {\n try {\n const _url = new URL(url);\n return (\n _url.searchParams.has(ELEMENT_LINK_KEY) &&\n _url.host === window.location.host\n );\n } catch (error) {\n return false;\n }\n};\n\nexport const parseElementLinkFromURL = (url: string) => {\n try {\n const { searchParams } = new URL(url);\n if (searchParams.has(ELEMENT_LINK_KEY)) {\n const id = searchParams.get(ELEMENT_LINK_KEY);\n return id;\n }\n } catch {}\n\n return null;\n};\n", "import { FRAME_STYLE } from \"../constants\";\nimport { getElementAbsoluteCoords } from \"../element\";\n\nimport {\n elementOverlapsWithFrame,\n getTargetFrame,\n shouldApplyFrameClip,\n} from \"../frame\";\nimport {\n isEmbeddableElement,\n isIframeLikeElement,\n isTextElement,\n} from \"../element/typeChecks\";\nimport { renderElement } from \"../renderer/renderElement\";\nimport { createPlaceholderEmbeddableLabel } from \"../element/embeddable\";\nimport type { StaticCanvasAppState, Zoom } from \"../types\";\nimport type {\n ElementsMap,\n ExcalidrawFrameLikeElement,\n NonDeletedExcalidrawElement,\n} from \"../element/types\";\nimport type {\n StaticCanvasRenderConfig,\n StaticSceneRenderConfig,\n} from \"../scene/types\";\nimport {\n EXTERNAL_LINK_IMG,\n ELEMENT_LINK_IMG,\n getLinkHandleFromCoords,\n} from \"../components/hyperlink/helpers\";\nimport { bootstrapCanvas, getNormalizedCanvasDimensions } from \"./helpers\";\nimport { throttleRAF } from \"../utils\";\nimport { getBoundTextElement } from \"../element/textElement\";\nimport { isElementLink } from \"../element/elementLink\";\n\nconst GridLineColor = {\n Bold: \"#dddddd\",\n Regular: \"#e5e5e5\",\n} as const;\n\nconst strokeGrid = (\n context: CanvasRenderingContext2D,\n /** grid cell pixel size */\n gridSize: number,\n /** setting to 1 will disble bold lines */\n gridStep: number,\n scrollX: number,\n scrollY: number,\n zoom: Zoom,\n width: number,\n height: number,\n) => {\n const offsetX = (scrollX % gridSize) - gridSize;\n const offsetY = (scrollY % gridSize) - gridSize;\n\n const actualGridSize = gridSize * zoom.value;\n\n const spaceWidth = 1 / zoom.value;\n\n context.save();\n\n // Offset rendering by 0.5 to ensure that 1px wide lines are crisp.\n // We only do this when zoomed to 100% because otherwise the offset is\n // fractional, and also visibly offsets the elements.\n // We also do this per-axis, as each axis may already be offset by 0.5.\n if (zoom.value === 1) {\n context.translate(offsetX % 1 ? 0 : 0.5, offsetY % 1 ? 0 : 0.5);\n }\n\n // vertical lines\n for (let x = offsetX; x < offsetX + width + gridSize * 2; x += gridSize) {\n const isBold =\n gridStep > 1 && Math.round(x - scrollX) % (gridStep * gridSize) === 0;\n // don't render regular lines when zoomed out and they're barely visible\n if (!isBold && actualGridSize < 10) {\n continue;\n }\n\n const lineWidth = Math.min(1 / zoom.value, isBold ? 4 : 1);\n context.lineWidth = lineWidth;\n const lineDash = [lineWidth * 3, spaceWidth + (lineWidth + spaceWidth)];\n\n context.beginPath();\n context.setLineDash(isBold ? [] : lineDash);\n context.strokeStyle = isBold ? GridLineColor.Bold : GridLineColor.Regular;\n context.moveTo(x, offsetY - gridSize);\n context.lineTo(x, Math.ceil(offsetY + height + gridSize * 2));\n context.stroke();\n }\n\n for (let y = offsetY; y < offsetY + height + gridSize * 2; y += gridSize) {\n const isBold =\n gridStep > 1 && Math.round(y - scrollY) % (gridStep * gridSize) === 0;\n if (!isBold && actualGridSize < 10) {\n continue;\n }\n\n const lineWidth = Math.min(1 / zoom.value, isBold ? 4 : 1);\n context.lineWidth = lineWidth;\n const lineDash = [lineWidth * 3, spaceWidth + (lineWidth + spaceWidth)];\n\n context.beginPath();\n context.setLineDash(isBold ? [] : lineDash);\n context.strokeStyle = isBold ? GridLineColor.Bold : GridLineColor.Regular;\n context.moveTo(offsetX - gridSize, y);\n context.lineTo(Math.ceil(offsetX + width + gridSize * 2), y);\n context.stroke();\n }\n context.restore();\n};\n\nconst frameClip = (\n frame: ExcalidrawFrameLikeElement,\n context: CanvasRenderingContext2D,\n renderConfig: StaticCanvasRenderConfig,\n appState: StaticCanvasAppState,\n) => {\n context.translate(frame.x + appState.scrollX, frame.y + appState.scrollY);\n context.beginPath();\n if (context.roundRect) {\n context.roundRect(\n 0,\n 0,\n frame.width,\n frame.height,\n FRAME_STYLE.radius / appState.zoom.value,\n );\n } else {\n context.rect(0, 0, frame.width, frame.height);\n }\n context.clip();\n context.translate(\n -(frame.x + appState.scrollX),\n -(frame.y + appState.scrollY),\n );\n};\n\ntype LinkIconCanvas = HTMLCanvasElement & { zoom: number };\n\nconst linkIconCanvasCache: {\n regularLink: LinkIconCanvas | null;\n elementLink: LinkIconCanvas | null;\n} = {\n regularLink: null,\n elementLink: null,\n};\n\nconst renderLinkIcon = (\n element: NonDeletedExcalidrawElement,\n context: CanvasRenderingContext2D,\n appState: StaticCanvasAppState,\n elementsMap: ElementsMap,\n) => {\n if (element.link && !appState.selectedElementIds[element.id]) {\n const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);\n const [x, y, width, height] = getLinkHandleFromCoords(\n [x1, y1, x2, y2],\n element.angle,\n appState,\n );\n const centerX = x + width / 2;\n const centerY = y + height / 2;\n context.save();\n context.translate(appState.scrollX + centerX, appState.scrollY + centerY);\n context.rotate(element.angle);\n\n const canvasKey = isElementLink(element.link)\n ? \"elementLink\"\n : \"regularLink\";\n\n let linkCanvas = linkIconCanvasCache[canvasKey];\n\n if (!linkCanvas || linkCanvas.zoom !== appState.zoom.value) {\n linkCanvas = Object.assign(document.createElement(\"canvas\"), {\n zoom: appState.zoom.value,\n });\n linkCanvas.width = width * window.devicePixelRatio * appState.zoom.value;\n linkCanvas.height =\n height * window.devicePixelRatio * appState.zoom.value;\n linkIconCanvasCache[canvasKey] = linkCanvas;\n\n const linkCanvasCacheContext = linkCanvas.getContext(\"2d\")!;\n linkCanvasCacheContext.scale(\n window.devicePixelRatio * appState.zoom.value,\n window.devicePixelRatio * appState.zoom.value,\n );\n linkCanvasCacheContext.fillStyle = \"#fff\";\n linkCanvasCacheContext.fillRect(0, 0, width, height);\n\n if (canvasKey === \"elementLink\") {\n linkCanvasCacheContext.drawImage(ELEMENT_LINK_IMG, 0, 0, width, height);\n } else {\n linkCanvasCacheContext.drawImage(\n EXTERNAL_LINK_IMG,\n 0,\n 0,\n width,\n height,\n );\n }\n\n linkCanvasCacheContext.restore();\n }\n context.drawImage(linkCanvas, x - centerX, y - centerY, width, height);\n context.restore();\n }\n};\nconst _renderStaticScene = ({\n canvas,\n rc,\n elementsMap,\n allElementsMap,\n visibleElements,\n scale,\n appState,\n renderConfig,\n}: StaticSceneRenderConfig) => {\n if (canvas === null) {\n return;\n }\n\n const { renderGrid = true, isExporting } = renderConfig;\n\n const [normalizedWidth, normalizedHeight] = getNormalizedCanvasDimensions(\n canvas,\n scale,\n );\n\n const context = bootstrapCanvas({\n canvas,\n scale,\n normalizedWidth,\n normalizedHeight,\n theme: appState.theme,\n isExporting,\n canvasBackgroundColor: renderConfig.canvasBackgroundColor,\n });\n\n // Apply zoom\n context.scale(appState.zoom.value, appState.zoom.value);\n\n // Grid\n if (renderGrid) {\n strokeGrid(\n context,\n appState.gridSize,\n appState.gridStep,\n appState.scrollX,\n appState.scrollY,\n appState.zoom,\n normalizedWidth / appState.zoom.value,\n normalizedHeight / appState.zoom.value,\n );\n }\n\n const groupsToBeAddedToFrame = new Set<string>();\n\n visibleElements.forEach((element) => {\n if (\n element.groupIds.length > 0 &&\n appState.frameToHighlight &&\n appState.selectedElementIds[element.id] &&\n (elementOverlapsWithFrame(\n element,\n appState.frameToHighlight,\n elementsMap,\n ) ||\n element.groupIds.find((groupId) => groupsToBeAddedToFrame.has(groupId)))\n ) {\n element.groupIds.forEach((groupId) =>\n groupsToBeAddedToFrame.add(groupId),\n );\n }\n });\n\n const inFrameGroupsMap = new Map<string, boolean>();\n\n // Paint visible elements\n visibleElements\n .filter((el) => !isIframeLikeElement(el))\n .forEach((element) => {\n try {\n const frameId = element.frameId || appState.frameToHighlight?.id;\n\n if (\n isTextElement(element) &&\n element.containerId &&\n elementsMap.has(element.containerId)\n ) {\n // will be rendered with the container\n return;\n }\n\n context.save();\n\n if (\n frameId &&\n appState.frameRendering.enabled &&\n appState.frameRendering.clip\n ) {\n const frame = getTargetFrame(element, elementsMap, appState);\n if (\n frame &&\n shouldApplyFrameClip(\n element,\n frame,\n appState,\n elementsMap,\n inFrameGroupsMap,\n )\n ) {\n frameClip(frame, context, renderConfig, appState);\n }\n renderElement(\n element,\n elementsMap,\n allElementsMap,\n rc,\n context,\n renderConfig,\n appState,\n );\n } else {\n renderElement(\n element,\n elementsMap,\n allElementsMap,\n rc,\n context,\n renderConfig,\n appState,\n );\n }\n\n const boundTextElement = getBoundTextElement(element, elementsMap);\n if (boundTextElement) {\n renderElement(\n boundTextElement,\n elementsMap,\n allElementsMap,\n rc,\n context,\n renderConfig,\n appState,\n );\n }\n\n context.restore();\n\n if (!isExporting) {\n renderLinkIcon(element, context, appState, elementsMap);\n }\n } catch (error: any) {\n console.error(error);\n }\n });\n\n // render embeddables on top\n visibleElements\n .filter((el) => isIframeLikeElement(el))\n .forEach((element) => {\n try {\n const render = () => {\n renderElement(\n element,\n elementsMap,\n allElementsMap,\n rc,\n context,\n renderConfig,\n appState,\n );\n\n if (\n isIframeLikeElement(element) &&\n (isExporting ||\n (isEmbeddableElement(element) &&\n renderConfig.embedsValidationStatus.get(element.id) !==\n true)) &&\n element.width &&\n element.height\n ) {\n const label = createPlaceholderEmbeddableLabel(element);\n renderElement(\n label,\n elementsMap,\n allElementsMap,\n rc,\n context,\n renderConfig,\n appState,\n );\n }\n if (!isExporting) {\n renderLinkIcon(element, context, appState, elementsMap);\n }\n };\n // - when exporting the whole canvas, we DO NOT apply clipping\n // - when we are exporting a particular frame, apply clipping\n // if the containing frame is not selected, apply clipping\n const frameId = element.frameId || appState.frameToHighlight?.id;\n\n if (\n frameId &&\n appState.frameRendering.enabled &&\n appState.frameRendering.clip\n ) {\n context.save();\n\n const frame = getTargetFrame(element, elementsMap, appState);\n\n if (\n frame &&\n shouldApplyFrameClip(\n element,\n frame,\n appState,\n elementsMap,\n inFrameGroupsMap,\n )\n ) {\n frameClip(frame, context, renderConfig, appState);\n }\n render();\n context.restore();\n } else {\n render();\n }\n } catch (error: any) {\n console.error(error);\n }\n });\n\n // render pending nodes for flowcharts\n renderConfig.pendingFlowchartNodes?.forEach((element) => {\n try {\n renderElement(\n element,\n elementsMap,\n allElementsMap,\n rc,\n context,\n renderConfig,\n appState,\n );\n } catch (error) {\n console.error(error);\n }\n });\n};\n\n/** throttled to animation framerate */\nexport const renderStaticSceneThrottled = throttleRAF(\n (config: StaticSceneRenderConfig) => {\n _renderStaticScene(config);\n },\n { trailing: true },\n);\n\n/**\n * Static scene is the non-ui canvas where we render elements.\n */\nexport const renderStaticScene = (\n renderConfig: StaticSceneRenderConfig,\n throttle?: boolean,\n) => {\n if (throttle) {\n renderStaticSceneThrottled(renderConfig);\n return;\n }\n\n _renderStaticScene(renderConfig);\n};\n", "import type { Radians } from \"@excalidraw/math\";\nimport { pointFrom } from \"@excalidraw/math\";\nimport { DEFAULT_CHART_COLOR_INDEX, getAllColorsSpecificShade } from \"./colors\";\nimport {\n COLOR_CHARCOAL_BLACK,\n DEFAULT_FONT_FAMILY,\n DEFAULT_FONT_SIZE,\n VERTICAL_ALIGN,\n} from \"./constants\";\nimport { newElement, newLinearElement, newTextElement } from \"./element\";\nimport type { NonDeletedExcalidrawElement } from \"./element/types\";\nimport { randomId } from \"./random\";\n\nexport type ChartElements = readonly NonDeletedExcalidrawElement[];\n\nconst BAR_WIDTH = 32;\nconst BAR_GAP = 12;\nconst BAR_HEIGHT = 256;\nconst GRID_OPACITY = 50;\n\nexport interface Spreadsheet {\n title: string | null;\n labels: string[] | null;\n values: number[];\n}\n\nexport const NOT_SPREADSHEET = \"NOT_SPREADSHEET\";\nexport const VALID_SPREADSHEET = \"VALID_SPREADSHEET\";\n\ntype ParseSpreadsheetResult =\n | { type: typeof NOT_SPREADSHEET; reason: string }\n | { type: typeof VALID_SPREADSHEET; spreadsheet: Spreadsheet };\n\n/**\n * @private exported for testing\n */\nexport const tryParseNumber = (s: string): number | null => {\n const match = /^([-+]?)[$\u20AC\u00A3\u00A5\u20A9]?([-+]?)([\\d.,]+)[%]?$/.exec(s);\n if (!match) {\n return null;\n }\n return parseFloat(`${(match[1] || match[2]) + match[3]}`.replace(/,/g, \"\"));\n};\n\nconst isNumericColumn = (lines: string[][], columnIndex: number) =>\n lines.slice(1).every((line) => tryParseNumber(line[columnIndex]) !== null);\n\n/**\n * @private exported for testing\n */\nexport const tryParseCells = (cells: string[][]): ParseSpreadsheetResult => {\n const numCols = cells[0].length;\n\n if (numCols > 2) {\n return { type: NOT_SPREADSHEET, reason: \"More than 2 columns\" };\n }\n\n if (numCols === 1) {\n if (!isNumericColumn(cells, 0)) {\n return { type: NOT_SPREADSHEET, reason: \"Value is not numeric\" };\n }\n\n const hasHeader = tryParseNumber(cells[0][0]) === null;\n const values = (hasHeader ? cells.slice(1) : cells).map((line) =>\n tryParseNumber(line[0]),\n );\n\n if (values.length < 2) {\n return { type: NOT_SPREADSHEET, reason: \"Less than two rows\" };\n }\n\n return {\n type: VALID_SPREADSHEET,\n spreadsheet: {\n title: hasHeader ? cells[0][0] : null,\n labels: null,\n values: values as number[],\n },\n };\n }\n\n const labelColumnNumeric = isNumericColumn(cells, 0);\n const valueColumnNumeric = isNumericColumn(cells, 1);\n\n if (!labelColumnNumeric && !valueColumnNumeric) {\n return { type: NOT_SPREADSHEET, reason: \"Value is not numeric\" };\n }\n\n const [labelColumnIndex, valueColumnIndex] = valueColumnNumeric\n ? [0, 1]\n : [1, 0];\n const hasHeader = tryParseNumber(cells[0][valueColumnIndex]) === null;\n const rows = hasHeader ? cells.slice(1) : cells;\n\n if (rows.length < 2) {\n return { type: NOT_SPREADSHEET, reason: \"Less than 2 rows\" };\n }\n\n return {\n type: VALID_SPREADSHEET,\n spreadsheet: {\n title: hasHeader ? cells[0][valueColumnIndex] : null,\n labels: rows.map((row) => row[labelColumnIndex]),\n values: rows.map((row) => tryParseNumber(row[valueColumnIndex])!),\n },\n };\n};\n\nconst transposeCells = (cells: string[][]) => {\n const nextCells: string[][] = [];\n for (let col = 0; col < cells[0].length; col++) {\n const nextCellRow: string[] = [];\n for (let row = 0; row < cells.length; row++) {\n nextCellRow.push(cells[row][col]);\n }\n nextCells.push(nextCellRow);\n }\n return nextCells;\n};\n\nexport const tryParseSpreadsheet = (text: string): ParseSpreadsheetResult => {\n // Copy/paste from excel, spreadsheets, tsv, csv.\n // For now we only accept 2 columns with an optional header\n\n // Check for tab separated values\n let lines = text\n .trim()\n .split(\"\\n\")\n .map((line) => line.trim().split(\"\\t\"));\n\n // Check for comma separated files\n if (lines.length && lines[0].length !== 2) {\n lines = text\n .trim()\n .split(\"\\n\")\n .map((line) => line.trim().split(\",\"));\n }\n\n if (lines.length === 0) {\n return { type: NOT_SPREADSHEET, reason: \"No values\" };\n }\n\n const numColsFirstLine = lines[0].length;\n const isSpreadsheet = lines.every((line) => line.length === numColsFirstLine);\n\n if (!isSpreadsheet) {\n return {\n type: NOT_SPREADSHEET,\n reason: \"All rows don't have same number of columns\",\n };\n }\n\n const result = tryParseCells(lines);\n if (result.type !== VALID_SPREADSHEET) {\n const transposedResults = tryParseCells(transposeCells(lines));\n if (transposedResults.type === VALID_SPREADSHEET) {\n return transposedResults;\n }\n }\n return result;\n};\n\nconst bgColors = getAllColorsSpecificShade(DEFAULT_CHART_COLOR_INDEX);\n\n// Put all the common properties here so when the whole chart is selected\n// the properties dialog shows the correct selected values\nconst commonProps = {\n fillStyle: \"hachure\",\n fontFamily: DEFAULT_FONT_FAMILY,\n fontSize: DEFAULT_FONT_SIZE,\n opacity: 100,\n roughness: 1,\n strokeColor: COLOR_CHARCOAL_BLACK,\n roundness: null,\n strokeStyle: \"solid\",\n strokeWidth: 1,\n verticalAlign: VERTICAL_ALIGN.MIDDLE,\n locked: false,\n} as const;\n\nconst getChartDimensions = (spreadsheet: Spreadsheet) => {\n const chartWidth =\n (BAR_WIDTH + BAR_GAP) * spreadsheet.values.length + BAR_GAP;\n const chartHeight = BAR_HEIGHT + BAR_GAP * 2;\n return { chartWidth, chartHeight };\n};\n\nconst chartXLabels = (\n spreadsheet: Spreadsheet,\n x: number,\n y: number,\n groupId: string,\n backgroundColor: string,\n): ChartElements => {\n return (\n spreadsheet.labels?.map((label, index) => {\n return newTextElement({\n groupIds: [groupId],\n backgroundColor,\n ...commonProps,\n text: label.length > 8 ? `${label.slice(0, 5)}...` : label,\n x: x + index * (BAR_WIDTH + BAR_GAP) + BAR_GAP * 2,\n y: y + BAR_GAP / 2,\n width: BAR_WIDTH,\n angle: 5.87 as Radians,\n fontSize: 16,\n textAlign: \"center\",\n verticalAlign: \"top\",\n });\n }) || []\n );\n};\n\nconst chartYLabels = (\n spreadsheet: Spreadsheet,\n x: number,\n y: number,\n groupId: string,\n backgroundColor: string,\n): ChartElements => {\n const minYLabel = newTextElement({\n groupIds: [groupId],\n backgroundColor,\n ...commonProps,\n x: x - BAR_GAP,\n y: y - BAR_GAP,\n text: \"0\",\n textAlign: \"right\",\n });\n\n const maxYLabel = newTextElement({\n groupIds: [groupId],\n backgroundColor,\n ...commonProps,\n x: x - BAR_GAP,\n y: y - BAR_HEIGHT - minYLabel.height / 2,\n text: Math.max(...spreadsheet.values).toLocaleString(),\n textAlign: \"right\",\n });\n\n return [minYLabel, maxYLabel];\n};\n\nconst chartLines = (\n spreadsheet: Spreadsheet,\n x: number,\n y: number,\n groupId: string,\n backgroundColor: string,\n): ChartElements => {\n const { chartWidth, chartHeight } = getChartDimensions(spreadsheet);\n const xLine = newLinearElement({\n backgroundColor,\n groupIds: [groupId],\n ...commonProps,\n type: \"line\",\n x,\n y,\n width: chartWidth,\n points: [pointFrom(0, 0), pointFrom(chartWidth, 0)],\n });\n\n const yLine = newLinearElement({\n backgroundColor,\n groupIds: [groupId],\n ...commonProps,\n type: \"line\",\n x,\n y,\n height: chartHeight,\n points: [pointFrom(0, 0), pointFrom(0, -chartHeight)],\n });\n\n const maxLine = newLinearElement({\n backgroundColor,\n groupIds: [groupId],\n ...commonProps,\n type: \"line\",\n x,\n y: y - BAR_HEIGHT - BAR_GAP,\n strokeStyle: \"dotted\",\n width: chartWidth,\n opacity: GRID_OPACITY,\n points: [pointFrom(0, 0), pointFrom(chartWidth, 0)],\n });\n\n return [xLine, yLine, maxLine];\n};\n\n// For the maths behind it https://excalidraw.com/#json=6320864370884608,O_5xfD-Agh32tytHpRJx1g\nconst chartBaseElements = (\n spreadsheet: Spreadsheet,\n x: number,\n y: number,\n groupId: string,\n backgroundColor: string,\n debug?: boolean,\n): ChartElements => {\n const { chartWidth, chartHeight } = getChartDimensions(spreadsheet);\n\n const title = spreadsheet.title\n ? newTextElement({\n backgroundColor,\n groupIds: [groupId],\n ...commonProps,\n text: spreadsheet.title,\n x: x + chartWidth / 2,\n y: y - BAR_HEIGHT - BAR_GAP * 2 - DEFAULT_FONT_SIZE,\n roundness: null,\n textAlign: \"center\",\n })\n : null;\n\n const debugRect = debug\n ? newElement({\n backgroundColor,\n groupIds: [groupId],\n ...commonProps,\n type: \"rectangle\",\n x,\n y: y - chartHeight,\n width: chartWidth,\n height: chartHeight,\n strokeColor: COLOR_CHARCOAL_BLACK,\n fillStyle: \"solid\",\n opacity: 6,\n })\n : null;\n\n return [\n ...(debugRect ? [debugRect] : []),\n ...(title ? [title] : []),\n ...chartXLabels(spreadsheet, x, y, groupId, backgroundColor),\n ...chartYLabels(spreadsheet, x, y, groupId, backgroundColor),\n ...chartLines(spreadsheet, x, y, groupId, backgroundColor),\n ];\n};\n\nconst chartTypeBar = (\n spreadsheet: Spreadsheet,\n x: number,\n y: number,\n): ChartElements => {\n const max = Math.max(...spreadsheet.values);\n const groupId = randomId();\n const backgroundColor = bgColors[Math.floor(Math.random() * bgColors.length)];\n\n const bars = spreadsheet.values.map((value, index) => {\n const barHeight = (value / max) * BAR_HEIGHT;\n return newElement({\n backgroundColor,\n groupIds: [groupId],\n ...commonProps,\n type: \"rectangle\",\n x: x + index * (BAR_WIDTH + BAR_GAP) + BAR_GAP,\n y: y - barHeight - BAR_GAP,\n width: BAR_WIDTH,\n height: barHeight,\n });\n });\n\n return [\n ...bars,\n ...chartBaseElements(\n spreadsheet,\n x,\n y,\n groupId,\n backgroundColor,\n import.meta.env.DEV,\n ),\n ];\n};\n\nconst chartTypeLine = (\n spreadsheet: Spreadsheet,\n x: number,\n y: number,\n): ChartElements => {\n const max = Math.max(...spreadsheet.values);\n const groupId = randomId();\n const backgroundColor = bgColors[Math.floor(Math.random() * bgColors.length)];\n\n let index = 0;\n const points = [];\n for (const value of spreadsheet.values) {\n const cx = index * (BAR_WIDTH + BAR_GAP);\n const cy = -(value / max) * BAR_HEIGHT;\n points.push([cx, cy]);\n index++;\n }\n\n const maxX = Math.max(...points.map((element) => element[0]));\n const maxY = Math.max(...points.map((element) => element[1]));\n const minX = Math.min(...points.map((element) => element[0]));\n const minY = Math.min(...points.map((element) => element[1]));\n\n const line = newLinearElement({\n backgroundColor,\n groupIds: [groupId],\n ...commonProps,\n type: \"line\",\n x: x + BAR_GAP + BAR_WIDTH / 2,\n y: y - BAR_GAP,\n height: maxY - minY,\n width: maxX - minX,\n strokeWidth: 2,\n points: points as any,\n });\n\n const dots = spreadsheet.values.map((value, index) => {\n const cx = index * (BAR_WIDTH + BAR_GAP) + BAR_GAP / 2;\n const cy = -(value / max) * BAR_HEIGHT + BAR_GAP / 2;\n return newElement({\n backgroundColor,\n groupIds: [groupId],\n ...commonProps,\n fillStyle: \"solid\",\n strokeWidth: 2,\n type: \"ellipse\",\n x: x + cx + BAR_WIDTH / 2,\n y: y + cy - BAR_GAP * 2,\n width: BAR_GAP,\n height: BAR_GAP,\n });\n });\n\n const lines = spreadsheet.values.map((value, index) => {\n const cx = index * (BAR_WIDTH + BAR_GAP) + BAR_GAP / 2;\n const cy = (value / max) * BAR_HEIGHT + BAR_GAP / 2 + BAR_GAP;\n return newLinearElement({\n backgroundColor,\n groupIds: [groupId],\n ...commonProps,\n type: \"line\",\n x: x + cx + BAR_WIDTH / 2 + BAR_GAP / 2,\n y: y - cy,\n height: cy,\n strokeStyle: \"dotted\",\n opacity: GRID_OPACITY,\n points: [pointFrom(0, 0), pointFrom(0, cy)],\n });\n });\n\n return [\n ...chartBaseElements(\n spreadsheet,\n x,\n y,\n groupId,\n backgroundColor,\n import.meta.env.DEV,\n ),\n line,\n ...lines,\n ...dots,\n ];\n};\n\nexport const renderSpreadsheet = (\n chartType: string,\n spreadsheet: Spreadsheet,\n x: number,\n y: number,\n): ChartElements => {\n if (chartType === \"line\") {\n return chartTypeLine(spreadsheet, x, y);\n }\n return chartTypeBar(spreadsheet, x, y);\n};\n", "import type {\n ExcalidrawElement,\n NonDeletedExcalidrawElement,\n} from \"./element/types\";\nimport type { BinaryFiles } from \"./types\";\nimport type { Spreadsheet } from \"./charts\";\nimport { tryParseSpreadsheet, VALID_SPREADSHEET } from \"./charts\";\nimport {\n ALLOWED_PASTE_MIME_TYPES,\n EXPORT_DATA_TYPES,\n MIME_TYPES,\n} from \"./constants\";\nimport {\n isFrameLikeElement,\n isInitializedImageElement,\n} from \"./element/typeChecks\";\nimport { deepCopyElement } from \"./element/newElement\";\nimport { mutateElement } from \"./element/mutateElement\";\nimport { getContainingFrame } from \"./frame\";\nimport { arrayToMap, isMemberOf, isPromiseLike } from \"./utils\";\nimport { createFile, isSupportedImageFileType } from \"./data/blob\";\nimport { ExcalidrawError } from \"./errors\";\n\ntype ElementsClipboard = {\n type: typeof EXPORT_DATA_TYPES.excalidrawClipboard;\n elements: readonly NonDeletedExcalidrawElement[];\n files: BinaryFiles | undefined;\n};\n\nexport type PastedMixedContent = { type: \"text\" | \"imageUrl\"; value: string }[];\n\nexport interface ClipboardData {\n spreadsheet?: Spreadsheet;\n elements?: readonly ExcalidrawElement[];\n files?: BinaryFiles;\n text?: string;\n mixedContent?: PastedMixedContent;\n errorMessage?: string;\n programmaticAPI?: boolean;\n}\n\ntype AllowedPasteMimeTypes = typeof ALLOWED_PASTE_MIME_TYPES[number];\n\ntype ParsedClipboardEventTextData =\n | { type: \"text\"; value: string }\n | { type: \"mixedContent\"; value: PastedMixedContent };\n\nexport const probablySupportsClipboardReadText =\n \"clipboard\" in navigator && \"readText\" in navigator.clipboard;\n\nexport const probablySupportsClipboardWriteText =\n \"clipboard\" in navigator && \"writeText\" in navigator.clipboard;\n\nexport const probablySupportsClipboardBlob =\n \"clipboard\" in navigator &&\n \"write\" in navigator.clipboard &&\n \"ClipboardItem\" in window &&\n \"toBlob\" in HTMLCanvasElement.prototype;\n\nconst clipboardContainsElements = (\n contents: any,\n): contents is { elements: ExcalidrawElement[]; files?: BinaryFiles } => {\n if (\n [\n EXPORT_DATA_TYPES.excalidraw,\n EXPORT_DATA_TYPES.excalidrawClipboard,\n EXPORT_DATA_TYPES.excalidrawClipboardWithAPI,\n ].includes(contents?.type) &&\n Array.isArray(contents.elements)\n ) {\n return true;\n }\n return false;\n};\n\nexport const createPasteEvent = ({\n types,\n files,\n}: {\n types?: { [key in AllowedPasteMimeTypes]?: string | File };\n files?: File[];\n}) => {\n if (!types && !files) {\n console.warn(\"createPasteEvent: no types or files provided\");\n }\n\n const event = new ClipboardEvent(\"paste\", {\n clipboardData: new DataTransfer(),\n });\n\n if (types) {\n for (const [type, value] of Object.entries(types)) {\n if (typeof value !== \"string\") {\n files = files || [];\n files.push(value);\n continue;\n }\n try {\n event.clipboardData?.setData(type, value);\n if (event.clipboardData?.getData(type) !== value) {\n throw new Error(`Failed to set \"${type}\" as clipboardData item`);\n }\n } catch (error: any) {\n throw new Error(error.message);\n }\n }\n }\n\n if (files) {\n let idx = -1;\n for (const file of files) {\n idx++;\n try {\n event.clipboardData?.items.add(file);\n if (event.clipboardData?.files[idx] !== file) {\n throw new Error(\n `Failed to set file \"${file.name}\" as clipboardData item`,\n );\n }\n } catch (error: any) {\n throw new Error(error.message);\n }\n }\n }\n\n return event;\n};\n\nexport const serializeAsClipboardJSON = ({\n elements,\n files,\n}: {\n elements: readonly NonDeletedExcalidrawElement[];\n files: BinaryFiles | null;\n}) => {\n const elementsMap = arrayToMap(elements);\n const framesToCopy = new Set(\n elements.filter((element) => isFrameLikeElement(element)),\n );\n let foundFile = false;\n\n const _files = elements.reduce((acc, element) => {\n if (isInitializedImageElement(element)) {\n foundFile = true;\n if (files && files[element.fileId]) {\n acc[element.fileId] = files[element.fileId];\n }\n }\n return acc;\n }, {} as BinaryFiles);\n\n if (foundFile && !files) {\n console.warn(\n \"copyToClipboard: attempting to file element(s) without providing associated `files` object.\",\n );\n }\n\n // select bound text elements when copying\n const contents: ElementsClipboard = {\n type: EXPORT_DATA_TYPES.excalidrawClipboard,\n elements: elements.map((element) => {\n if (\n getContainingFrame(element, elementsMap) &&\n !framesToCopy.has(getContainingFrame(element, elementsMap)!)\n ) {\n const copiedElement = deepCopyElement(element);\n mutateElement(copiedElement, {\n frameId: null,\n });\n return copiedElement;\n }\n\n return element;\n }),\n files: files ? _files : undefined,\n };\n\n return JSON.stringify(contents);\n};\n\nexport const copyToClipboard = async (\n elements: readonly NonDeletedExcalidrawElement[],\n files: BinaryFiles | null,\n /** supply if available to make the operation more certain to succeed */\n clipboardEvent?: ClipboardEvent | null,\n) => {\n await copyTextToSystemClipboard(\n serializeAsClipboardJSON({ elements, files }),\n clipboardEvent,\n );\n};\n\nconst parsePotentialSpreadsheet = (\n text: string,\n): { spreadsheet: Spreadsheet } | { errorMessage: string } | null => {\n const result = tryParseSpreadsheet(text);\n if (result.type === VALID_SPREADSHEET) {\n return { spreadsheet: result.spreadsheet };\n }\n return null;\n};\n\n/** internal, specific to parsing paste events. Do not reuse. */\nfunction parseHTMLTree(el: ChildNode) {\n let result: PastedMixedContent = [];\n for (const node of el.childNodes) {\n if (node.nodeType === 3) {\n const text = node.textContent?.trim();\n if (text) {\n result.push({ type: \"text\", value: text });\n }\n } else if (node instanceof HTMLImageElement) {\n const url = node.getAttribute(\"src\");\n if (url && url.startsWith(\"http\")) {\n result.push({ type: \"imageUrl\", value: url });\n }\n } else {\n result = result.concat(parseHTMLTree(node));\n }\n }\n return result;\n}\n\nconst maybeParseHTMLPaste = (\n event: ClipboardEvent,\n): { type: \"mixedContent\"; value: PastedMixedContent } | null => {\n const html = event.clipboardData?.getData(MIME_TYPES.html);\n\n if (!html) {\n return null;\n }\n\n try {\n const doc = new DOMParser().parseFromString(html, MIME_TYPES.html);\n\n const content = parseHTMLTree(doc.body);\n\n if (content.length) {\n return { type: \"mixedContent\", value: content };\n }\n } catch (error: any) {\n console.error(`error in parseHTMLFromPaste: ${error.message}`);\n }\n\n return null;\n};\n\n/**\n * Reads OS clipboard programmatically. May not work on all browsers.\n * Will prompt user for permission if not granted.\n */\nexport const readSystemClipboard = async () => {\n const types: { [key in AllowedPasteMimeTypes]?: string | File } = {};\n\n let clipboardItems: ClipboardItems;\n\n try {\n clipboardItems = await navigator.clipboard?.read();\n } catch (error: any) {\n try {\n if (navigator.clipboard?.readText) {\n console.warn(\n `navigator.clipboard.readText() failed (${error.message}). Failling back to navigator.clipboard.read()`,\n );\n const readText = await navigator.clipboard?.readText();\n if (readText) {\n return { [MIME_TYPES.text]: readText };\n }\n }\n } catch (error: any) {\n // @ts-ignore\n if (navigator.clipboard?.read) {\n console.warn(\n `navigator.clipboard.readText() failed (${error.message}). Failling back to navigator.clipboard.read()`,\n );\n } else {\n if (error.name === \"DataError\") {\n console.warn(\n `navigator.clipboard.read() error, clipboard is probably empty: ${error.message}`,\n );\n return types;\n }\n\n throw error;\n }\n }\n throw error;\n }\n\n for (const item of clipboardItems) {\n for (const type of item.types) {\n if (!isMemberOf(ALLOWED_PASTE_MIME_TYPES, type)) {\n continue;\n }\n try {\n if (type === MIME_TYPES.text || type === MIME_TYPES.html) {\n types[type] = await (await item.getType(type)).text();\n } else if (isSupportedImageFileType(type)) {\n const imageBlob = await item.getType(type);\n const file = createFile(imageBlob, type, undefined);\n types[type] = file;\n } else {\n throw new ExcalidrawError(`Unsupported clipboard type: ${type}`);\n }\n } catch (error: any) {\n console.warn(\n error instanceof ExcalidrawError\n ? error.message\n : `Cannot retrieve ${type} from clipboardItem: ${error.message}`,\n );\n }\n }\n }\n\n if (Object.keys(types).length === 0) {\n console.warn(\"No clipboard data found from clipboard.read().\");\n return types;\n }\n\n return types;\n};\n\n/**\n * Parses \"paste\" ClipboardEvent.\n */\nconst parseClipboardEventTextData = async (\n event: ClipboardEvent,\n isPlainPaste = false,\n): Promise<ParsedClipboardEventTextData> => {\n try {\n const mixedContent = !isPlainPaste && event && maybeParseHTMLPaste(event);\n\n if (mixedContent) {\n if (mixedContent.value.every((item) => item.type === \"text\")) {\n return {\n type: \"text\",\n value:\n event.clipboardData?.getData(MIME_TYPES.text) ||\n mixedContent.value\n .map((item) => item.value)\n .join(\"\\n\")\n .trim(),\n };\n }\n\n return mixedContent;\n }\n\n const text = event.clipboardData?.getData(MIME_TYPES.text);\n\n return { type: \"text\", value: (text || \"\").trim() };\n } catch {\n return { type: \"text\", value: \"\" };\n }\n};\n\n/**\n * Attempts to parse clipboard event.\n */\nexport const parseClipboard = async (\n event: ClipboardEvent,\n isPlainPaste = false,\n): Promise<ClipboardData> => {\n const parsedEventData = await parseClipboardEventTextData(\n event,\n isPlainPaste,\n );\n\n if (parsedEventData.type === \"mixedContent\") {\n return {\n mixedContent: parsedEventData.value,\n };\n }\n\n try {\n // if system clipboard contains spreadsheet, use it even though it's\n // technically possible it's staler than in-app clipboard\n const spreadsheetResult =\n !isPlainPaste && parsePotentialSpreadsheet(parsedEventData.value);\n\n if (spreadsheetResult) {\n return spreadsheetResult;\n }\n } catch (error: any) {\n console.error(error);\n }\n\n try {\n const systemClipboardData = JSON.parse(parsedEventData.value);\n const programmaticAPI =\n systemClipboardData.type === EXPORT_DATA_TYPES.excalidrawClipboardWithAPI;\n if (clipboardContainsElements(systemClipboardData)) {\n return {\n elements: systemClipboardData.elements,\n files: systemClipboardData.files,\n text: isPlainPaste\n ? JSON.stringify(systemClipboardData.elements, null, 2)\n : undefined,\n programmaticAPI,\n };\n }\n } catch {}\n\n return { text: parsedEventData.value };\n};\n\nexport const copyBlobToClipboardAsPng = async (blob: Blob | Promise<Blob>) => {\n try {\n // in Safari so far we need to construct the ClipboardItem synchronously\n // (i.e. in the same tick) otherwise browser will complain for lack of\n // user intent. Using a Promise ClipboardItem constructor solves this.\n // https://bugs.webkit.org/show_bug.cgi?id=222262\n //\n // Note that Firefox (and potentially others) seems to support Promise\n // ClipboardItem constructor, but throws on an unrelated MIME type error.\n // So we need to await this and fallback to awaiting the blob if applicable.\n await navigator.clipboard.write([\n new window.ClipboardItem({\n [MIME_TYPES.png]: blob,\n }),\n ]);\n } catch (error: any) {\n // if we're using a Promise ClipboardItem, let's try constructing\n // with resolution value instead\n if (isPromiseLike(blob)) {\n await navigator.clipboard.write([\n new window.ClipboardItem({\n [MIME_TYPES.png]: await blob,\n }),\n ]);\n } else {\n throw error;\n }\n }\n};\n\nexport const copyTextToSystemClipboard = async (\n text: string | null,\n clipboardEvent?: ClipboardEvent | null,\n) => {\n // (1) first try using Async Clipboard API\n if (probablySupportsClipboardWriteText) {\n try {\n // NOTE: doesn't work on FF on non-HTTPS domains, or when document\n // not focused\n await navigator.clipboard.writeText(text || \"\");\n return;\n } catch (error: any) {\n console.error(error);\n }\n }\n\n // (2) if fails and we have access to ClipboardEvent, use plain old setData()\n try {\n if (clipboardEvent) {\n clipboardEvent.clipboardData?.setData(MIME_TYPES.text, text || \"\");\n if (clipboardEvent.clipboardData?.getData(MIME_TYPES.text) !== text) {\n throw new Error(\"Failed to setData on clipboardEvent\");\n }\n return;\n }\n } catch (error: any) {\n console.error(error);\n }\n\n // (3) if that fails, use document.execCommand\n if (!copyTextViaExecCommand(text)) {\n throw new Error(\"Error copying to clipboard.\");\n }\n};\n\n// adapted from https://github.com/zenorocha/clipboard.js/blob/ce79f170aa655c408b6aab33c9472e8e4fa52e19/src/clipboard-action.js#L48\nconst copyTextViaExecCommand = (text: string | null) => {\n // execCommand doesn't allow copying empty strings, so if we're\n // clearing clipboard using this API, we must copy at least an empty char\n if (!text) {\n text = \" \";\n }\n\n const isRTL = document.documentElement.getAttribute(\"dir\") === \"rtl\";\n\n const textarea = document.createElement(\"textarea\");\n\n textarea.style.border = \"0\";\n textarea.style.padding = \"0\";\n textarea.style.margin = \"0\";\n textarea.style.position = \"absolute\";\n textarea.style[isRTL ? \"right\" : \"left\"] = \"-9999px\";\n const yPosition = window.pageYOffset || document.documentElement.scrollTop;\n textarea.style.top = `${yPosition}px`;\n // Prevent zooming on iOS\n textarea.style.fontSize = \"12pt\";\n\n textarea.setAttribute(\"readonly\", \"\");\n textarea.value = text;\n\n document.body.appendChild(textarea);\n\n let success = false;\n\n try {\n textarea.select();\n textarea.setSelectionRange(0, textarea.value.length);\n\n success = document.execCommand(\"copy\");\n } catch (error: any) {\n console.error(error);\n }\n\n textarea.remove();\n\n return success;\n};\n", "import {\n exportToCanvas as _exportToCanvas,\n exportToSvg as _exportToSvg,\n} from \"@excalidraw/excalidraw/scene/export\";\nimport type {\n ExportToCanvasConfig,\n ExportToCanvasData,\n} from \"@excalidraw/excalidraw/scene/export\";\nimport { restore } from \"@excalidraw/excalidraw/data/restore\";\nimport { COLOR_WHITE, MIME_TYPES } from \"@excalidraw/excalidraw/constants\";\nimport { encodePngMetadata } from \"@excalidraw/excalidraw/data/image\";\nimport { serializeAsJSON } from \"@excalidraw/excalidraw/data/json\";\nimport {\n copyBlobToClipboardAsPng,\n copyTextToSystemClipboard,\n copyToClipboard,\n} from \"@excalidraw/excalidraw/clipboard\";\nimport { getNonDeletedElements } from \"@excalidraw/excalidraw/element\";\n\nexport { MIME_TYPES };\n\ntype ExportToBlobConfig = ExportToCanvasConfig & {\n mimeType?: string;\n quality?: number;\n};\n\ntype ExportToSvgConfig = Pick<\n ExportToCanvasConfig,\n \"canvasBackgroundColor\" | \"padding\" | \"theme\" | \"exportingFrame\"\n> & {\n /**\n * if true, all embeddables passed in will be rendered when possible.\n */\n renderEmbeddables?: boolean;\n skipInliningFonts?: true;\n reuseImages?: boolean;\n};\n\nexport const exportToCanvas = async ({\n data,\n config,\n}: {\n data: ExportToCanvasData;\n config?: ExportToCanvasConfig;\n}) => {\n return _exportToCanvas({\n data,\n config,\n });\n};\n\nexport const exportToBlob = async ({\n data,\n config,\n}: {\n data: ExportToCanvasData;\n config?: ExportToBlobConfig;\n}): Promise<Blob> => {\n let { mimeType = MIME_TYPES.png, quality } = config || {};\n\n if (mimeType === MIME_TYPES.png && typeof quality === \"number\") {\n console.warn(`\"quality\" will be ignored for \"${MIME_TYPES.png}\" mimeType`);\n }\n\n // typo in MIME type (should be \"jpeg\")\n if (mimeType === \"image/jpg\") {\n mimeType = MIME_TYPES.jpg;\n }\n\n if (mimeType === MIME_TYPES.jpg && !config?.canvasBackgroundColor === false) {\n console.warn(\n `Defaulting \"exportBackground\" to \"true\" for \"${MIME_TYPES.jpg}\" mimeType`,\n );\n config = {\n ...config,\n canvasBackgroundColor: data.appState?.viewBackgroundColor || COLOR_WHITE,\n };\n }\n\n const canvas = await _exportToCanvas({ data, config });\n\n quality = quality ? quality : /image\\/jpe?g/.test(mimeType) ? 0.92 : 0.8;\n\n return new Promise((resolve, reject) => {\n canvas.toBlob(\n async (blob) => {\n if (!blob) {\n return reject(new Error(\"couldn't export to blob\"));\n }\n if (\n blob &&\n mimeType === MIME_TYPES.png &&\n data.appState?.exportEmbedScene\n ) {\n blob = await encodePngMetadata({\n blob,\n metadata: serializeAsJSON(\n // NOTE as long as we're using the Scene hack, we need to ensure\n // we pass the original, uncloned elements when serializing\n // so that we keep ids stable\n data.elements,\n data.appState,\n data.files || {},\n \"local\",\n ),\n });\n }\n resolve(blob);\n },\n mimeType,\n quality,\n );\n });\n};\n\nexport const exportToSvg = async ({\n data,\n config,\n}: {\n data: ExportToCanvasData;\n config?: ExportToSvgConfig;\n}): Promise<SVGSVGElement> => {\n const { elements: restoredElements, appState: restoredAppState } = restore(\n { ...data, files: data.files || {} },\n null,\n null,\n );\n\n const appState = { ...restoredAppState, exportPadding: config?.padding };\n const elements = getNonDeletedElements(restoredElements);\n const files = data.files || {};\n\n return _exportToSvg({\n data: { elements, appState, files },\n config: {\n exportingFrame: config?.exportingFrame,\n renderEmbeddables: config?.renderEmbeddables,\n skipInliningFonts: config?.skipInliningFonts,\n reuseImages: config?.reuseImages,\n },\n });\n};\n\nexport const exportToClipboard = async ({\n type,\n data,\n config,\n}: {\n data: ExportToCanvasData;\n} & (\n | { type: \"png\"; config?: ExportToBlobConfig }\n | { type: \"svg\"; config?: ExportToSvgConfig }\n | { type: \"json\"; config?: never }\n)) => {\n if (type === \"svg\") {\n const svg = await exportToSvg({ data, config });\n await copyTextToSystemClipboard(svg.outerHTML);\n } else if (type === \"png\") {\n await copyBlobToClipboardAsPng(exportToBlob({ data, config }));\n } else if (type === \"json\") {\n await copyToClipboard(data.elements, data.files);\n } else {\n throw new Error(\"Invalid export type\");\n }\n};\n", "import type {\n ExcalidrawElement,\n ExcalidrawFreeDrawElement,\n ExcalidrawLinearElement,\n NonDeletedExcalidrawElement,\n} from \"@excalidraw/excalidraw/element/types\";\nimport {\n isArrowElement,\n isExcalidrawElement,\n isFreeDrawElement,\n isLinearElement,\n isTextElement,\n} from \"@excalidraw/excalidraw/element/typeChecks\";\nimport type { Bounds } from \"@excalidraw/excalidraw/element/bounds\";\nimport { getElementBounds } from \"@excalidraw/excalidraw/element/bounds\";\nimport { arrayToMap } from \"@excalidraw/excalidraw/utils\";\nimport type { LocalPoint } from \"@excalidraw/math\";\nimport {\n rangeIncludesValue,\n pointFrom,\n pointRotateRads,\n rangeInclusive,\n} from \"@excalidraw/math\";\n\ntype Element = NonDeletedExcalidrawElement;\ntype Elements = readonly NonDeletedExcalidrawElement[];\n\ntype Points = readonly LocalPoint[];\n\n/** @returns vertices relative to element's top-left [0,0] position */\nconst getNonLinearElementRelativePoints = (\n element: Exclude<\n Element,\n ExcalidrawLinearElement | ExcalidrawFreeDrawElement\n >,\n): [\n TopLeft: LocalPoint,\n TopRight: LocalPoint,\n BottomRight: LocalPoint,\n BottomLeft: LocalPoint,\n] => {\n if (element.type === \"diamond\") {\n return [\n pointFrom(element.width / 2, 0),\n pointFrom(element.width, element.height / 2),\n pointFrom(element.width / 2, element.height),\n pointFrom(0, element.height / 2),\n ];\n }\n return [\n pointFrom(0, 0),\n pointFrom(0 + element.width, 0),\n pointFrom(0 + element.width, element.height),\n pointFrom(0, element.height),\n ];\n};\n\n/** @returns vertices relative to element's top-left [0,0] position */\nconst getElementRelativePoints = (element: ExcalidrawElement): Points => {\n if (isLinearElement(element) || isFreeDrawElement(element)) {\n return element.points;\n }\n return getNonLinearElementRelativePoints(element);\n};\n\nconst getMinMaxPoints = (points: Points) => {\n const ret = points.reduce(\n (limits, [x, y]) => {\n limits.minY = Math.min(limits.minY, y);\n limits.minX = Math.min(limits.minX, x);\n\n limits.maxX = Math.max(limits.maxX, x);\n limits.maxY = Math.max(limits.maxY, y);\n\n return limits;\n },\n {\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity,\n cx: 0,\n cy: 0,\n },\n );\n\n ret.cx = (ret.maxX + ret.minX) / 2;\n ret.cy = (ret.maxY + ret.minY) / 2;\n\n return ret;\n};\n\nconst getRotatedBBox = (element: Element): Bounds => {\n const points = getElementRelativePoints(element);\n\n const { cx, cy } = getMinMaxPoints(points);\n const centerPoint = pointFrom<LocalPoint>(cx, cy);\n\n const rotatedPoints = points.map((p) =>\n pointRotateRads(p, centerPoint, element.angle),\n );\n const { minX, minY, maxX, maxY } = getMinMaxPoints(rotatedPoints);\n\n return [\n minX + element.x,\n minY + element.y,\n maxX + element.x,\n maxY + element.y,\n ];\n};\n\nexport const isElementInsideBBox = (\n element: Element,\n bbox: Bounds,\n eitherDirection = false,\n): boolean => {\n const elementBBox = getRotatedBBox(element);\n\n const elementInsideBbox =\n bbox[0] <= elementBBox[0] &&\n bbox[2] >= elementBBox[2] &&\n bbox[1] <= elementBBox[1] &&\n bbox[3] >= elementBBox[3];\n\n if (!eitherDirection) {\n return elementInsideBbox;\n }\n\n if (elementInsideBbox) {\n return true;\n }\n\n return (\n elementBBox[0] <= bbox[0] &&\n elementBBox[2] >= bbox[2] &&\n elementBBox[1] <= bbox[1] &&\n elementBBox[3] >= bbox[3]\n );\n};\n\nexport const elementPartiallyOverlapsWithOrContainsBBox = (\n element: Element,\n bbox: Bounds,\n): boolean => {\n const elementBBox = getRotatedBBox(element);\n\n return (\n (rangeIncludesValue(elementBBox[0], rangeInclusive(bbox[0], bbox[2])) ||\n rangeIncludesValue(\n bbox[0],\n rangeInclusive(elementBBox[0], elementBBox[2]),\n )) &&\n (rangeIncludesValue(elementBBox[1], rangeInclusive(bbox[1], bbox[3])) ||\n rangeIncludesValue(\n bbox[1],\n rangeInclusive(elementBBox[1], elementBBox[3]),\n ))\n );\n};\n\nexport const elementsOverlappingBBox = ({\n elements,\n bounds,\n type,\n errorMargin = 0,\n}: {\n elements: Elements;\n bounds: Bounds | ExcalidrawElement;\n /** safety offset. Defaults to 0. */\n errorMargin?: number;\n /**\n * - overlap: elements overlapping or inside bounds\n * - contain: elements inside bounds or bounds inside elements\n * - inside: elements inside bounds\n **/\n type: \"overlap\" | \"contain\" | \"inside\";\n}) => {\n if (isExcalidrawElement(bounds)) {\n bounds = getElementBounds(bounds, arrayToMap(elements));\n }\n const adjustedBBox: Bounds = [\n bounds[0] - errorMargin,\n bounds[1] - errorMargin,\n bounds[2] + errorMargin,\n bounds[3] + errorMargin,\n ];\n\n const includedElementSet = new Set<string>();\n\n for (const element of elements) {\n if (includedElementSet.has(element.id)) {\n continue;\n }\n\n const isOverlaping =\n type === \"overlap\"\n ? elementPartiallyOverlapsWithOrContainsBBox(element, adjustedBBox)\n : type === \"inside\"\n ? isElementInsideBBox(element, adjustedBBox)\n : isElementInsideBBox(element, adjustedBBox, true);\n\n if (isOverlaping) {\n includedElementSet.add(element.id);\n\n if (element.boundElements) {\n for (const boundElement of element.boundElements) {\n includedElementSet.add(boundElement.id);\n }\n }\n\n if (isTextElement(element) && element.containerId) {\n includedElementSet.add(element.containerId);\n }\n\n if (isArrowElement(element)) {\n if (element.startBinding) {\n includedElementSet.add(element.startBinding.elementId);\n }\n\n if (element.endBinding) {\n includedElementSet.add(element.endBinding?.elementId);\n }\n }\n }\n }\n\n return elements.filter((element) => includedElementSet.has(element.id));\n};\n", "import {\n vectorCross,\n vectorFromPoint,\n type GlobalPoint,\n type LocalPoint,\n} from \"@excalidraw/math\";\nimport type { Bounds } from \"@excalidraw/excalidraw/element/bounds\";\n\nexport type LineSegment<P extends LocalPoint | GlobalPoint> = [P, P];\n\nexport function getBBox<P extends LocalPoint | GlobalPoint>(\n line: LineSegment<P>,\n): Bounds {\n return [\n Math.min(line[0][0], line[1][0]),\n Math.min(line[0][1], line[1][1]),\n Math.max(line[0][0], line[1][0]),\n Math.max(line[0][1], line[1][1]),\n ];\n}\n\nexport function doBBoxesIntersect(a: Bounds, b: Bounds) {\n return a[0] <= b[2] && a[2] >= b[0] && a[1] <= b[3] && a[3] >= b[1];\n}\n\nconst EPSILON = 0.000001;\n\nexport function isPointOnLine<P extends GlobalPoint | LocalPoint>(\n l: LineSegment<P>,\n p: P,\n) {\n const p1 = vectorFromPoint(l[1], l[0]);\n const p2 = vectorFromPoint(p, l[0]);\n\n const r = vectorCross(p1, p2);\n\n return Math.abs(r) < EPSILON;\n}\n\nexport function isPointRightOfLine<P extends GlobalPoint | LocalPoint>(\n l: LineSegment<P>,\n p: P,\n) {\n const p1 = vectorFromPoint(l[1], l[0]);\n const p2 = vectorFromPoint(p, l[0]);\n\n return vectorCross(p1, p2) < 0;\n}\n\nexport function isLineSegmentTouchingOrCrossingLine<\n P extends GlobalPoint | LocalPoint,\n>(a: LineSegment<P>, b: LineSegment<P>) {\n return (\n isPointOnLine(a, b[0]) ||\n isPointOnLine(a, b[1]) ||\n (isPointRightOfLine(a, b[0])\n ? !isPointRightOfLine(a, b[1])\n : isPointRightOfLine(a, b[1]))\n );\n}\n\n// https://martin-thoma.com/how-to-check-if-two-line-segments-intersect/\nexport function doLineSegmentsIntersect<P extends GlobalPoint | LocalPoint>(\n a: LineSegment<P>,\n b: LineSegment<P>,\n) {\n return (\n doBBoxesIntersect(getBBox(a), getBBox(b)) &&\n isLineSegmentTouchingOrCrossingLine(a, b) &&\n isLineSegmentTouchingOrCrossingLine(b, a)\n );\n}\n", "import {\n getCommonBounds,\n getElementAbsoluteCoords,\n isTextElement,\n} from \"./element\";\nimport type {\n ElementsMap,\n ElementsMapOrArray,\n ExcalidrawElement,\n ExcalidrawFrameLikeElement,\n NonDeleted,\n NonDeletedExcalidrawElement,\n} from \"./element/types\";\nimport {\n getBoundTextElement,\n getContainerElement,\n} from \"./element/textElement\";\nimport { arrayToMap } from \"./utils\";\nimport { mutateElement } from \"./element/mutateElement\";\nimport type {\n AppClassProperties,\n AppState,\n StaticCanvasAppState,\n} from \"./types\";\nimport { getElementsWithinSelection, getSelectedElements } from \"./scene\";\nimport { getElementsInGroup, selectGroupsFromGivenElements } from \"./groups\";\nimport type { ExcalidrawElementsIncludingDeleted } from \"./scene/Scene\";\nimport { getElementLineSegments } from \"./element/bounds\";\nimport {\n doLineSegmentsIntersect,\n elementsOverlappingBBox,\n} from \"@excalidraw/utils\";\nimport { isFrameElement, isFrameLikeElement } from \"./element/typeChecks\";\nimport type { ReadonlySetLike } from \"./utility-types\";\nimport { isPointWithinBounds, pointFrom } from \"@excalidraw/math\";\n\n// --------------------------- Frame State ------------------------------------\nexport const bindElementsToFramesAfterDuplication = (\n nextElements: readonly ExcalidrawElement[],\n oldElements: readonly ExcalidrawElement[],\n oldIdToDuplicatedId: Map<ExcalidrawElement[\"id\"], ExcalidrawElement[\"id\"]>,\n) => {\n const nextElementMap = arrayToMap(nextElements) as Map<\n ExcalidrawElement[\"id\"],\n ExcalidrawElement\n >;\n\n for (const element of oldElements) {\n if (element.frameId) {\n // use its frameId to get the new frameId\n const nextElementId = oldIdToDuplicatedId.get(element.id);\n const nextFrameId = oldIdToDuplicatedId.get(element.frameId);\n if (nextElementId) {\n const nextElement = nextElementMap.get(nextElementId);\n if (nextElement) {\n mutateElement(\n nextElement,\n {\n frameId: nextFrameId ?? element.frameId,\n },\n false,\n );\n }\n }\n }\n }\n};\n\nexport function isElementIntersectingFrame(\n element: ExcalidrawElement,\n frame: ExcalidrawFrameLikeElement,\n elementsMap: ElementsMap,\n) {\n const frameLineSegments = getElementLineSegments(frame, elementsMap);\n\n const elementLineSegments = getElementLineSegments(element, elementsMap);\n\n const intersecting = frameLineSegments.some((frameLineSegment) =>\n elementLineSegments.some((elementLineSegment) =>\n doLineSegmentsIntersect(frameLineSegment, elementLineSegment),\n ),\n );\n\n return intersecting;\n}\n\nexport const getElementsCompletelyInFrame = (\n elements: readonly ExcalidrawElement[],\n frame: ExcalidrawFrameLikeElement,\n elementsMap: ElementsMap,\n) =>\n omitGroupsContainingFrameLikes(\n getElementsWithinSelection(elements, frame, elementsMap, false),\n ).filter(\n (element) =>\n (!isFrameLikeElement(element) && !element.frameId) ||\n element.frameId === frame.id,\n );\n\nexport const isElementContainingFrame = (\n element: ExcalidrawElement,\n frame: ExcalidrawFrameLikeElement,\n elementsMap: ElementsMap,\n) => {\n return getElementsWithinSelection([frame], element, elementsMap).some(\n (e) => e.id === frame.id,\n );\n};\n\nexport const getElementsIntersectingFrame = (\n elements: readonly ExcalidrawElement[],\n frame: ExcalidrawFrameLikeElement,\n) => {\n const elementsMap = arrayToMap(elements);\n return elements.filter((element) =>\n isElementIntersectingFrame(element, frame, elementsMap),\n );\n};\n\nexport const elementsAreInFrameBounds = (\n elements: readonly ExcalidrawElement[],\n frame: ExcalidrawFrameLikeElement,\n elementsMap: ElementsMap,\n) => {\n const [frameX1, frameY1, frameX2, frameY2] = getElementAbsoluteCoords(\n frame,\n elementsMap,\n );\n\n const [elementX1, elementY1, elementX2, elementY2] =\n getCommonBounds(elements);\n\n return (\n frameX1 <= elementX1 &&\n frameY1 <= elementY1 &&\n frameX2 >= elementX2 &&\n frameY2 >= elementY2\n );\n};\n\nexport const elementOverlapsWithFrame = (\n element: ExcalidrawElement,\n frame: ExcalidrawFrameLikeElement,\n elementsMap: ElementsMap,\n) => {\n return (\n elementsAreInFrameBounds([element], frame, elementsMap) ||\n isElementIntersectingFrame(element, frame, elementsMap) ||\n isElementContainingFrame(element, frame, elementsMap)\n );\n};\n\nexport const isCursorInFrame = (\n cursorCoords: {\n x: number;\n y: number;\n },\n frame: NonDeleted<ExcalidrawFrameLikeElement>,\n elementsMap: ElementsMap,\n) => {\n const [fx1, fy1, fx2, fy2] = getElementAbsoluteCoords(frame, elementsMap);\n\n return isPointWithinBounds(\n pointFrom(fx1, fy1),\n pointFrom(cursorCoords.x, cursorCoords.y),\n pointFrom(fx2, fy2),\n );\n};\n\nexport const groupsAreAtLeastIntersectingTheFrame = (\n elements: readonly NonDeletedExcalidrawElement[],\n groupIds: readonly string[],\n frame: ExcalidrawFrameLikeElement,\n) => {\n const elementsMap = arrayToMap(elements);\n const elementsInGroup = groupIds.flatMap((groupId) =>\n getElementsInGroup(elements, groupId),\n );\n\n if (elementsInGroup.length === 0) {\n return true;\n }\n\n return !!elementsInGroup.find(\n (element) =>\n elementsAreInFrameBounds([element], frame, elementsMap) ||\n isElementIntersectingFrame(element, frame, elementsMap),\n );\n};\n\nexport const groupsAreCompletelyOutOfFrame = (\n elements: readonly NonDeletedExcalidrawElement[],\n groupIds: readonly string[],\n frame: ExcalidrawFrameLikeElement,\n) => {\n const elementsMap = arrayToMap(elements);\n const elementsInGroup = groupIds.flatMap((groupId) =>\n getElementsInGroup(elements, groupId),\n );\n\n if (elementsInGroup.length === 0) {\n return true;\n }\n\n return (\n elementsInGroup.find(\n (element) =>\n elementsAreInFrameBounds([element], frame, elementsMap) ||\n isElementIntersectingFrame(element, frame, elementsMap),\n ) === undefined\n );\n};\n\n// --------------------------- Frame Utils ------------------------------------\n\n/**\n * Returns a map of frameId to frame elements. Includes empty frames.\n */\nexport const groupByFrameLikes = (elements: readonly ExcalidrawElement[]) => {\n const frameElementsMap = new Map<\n ExcalidrawElement[\"id\"],\n ExcalidrawElement[]\n >();\n\n for (const element of elements) {\n const frameId = isFrameLikeElement(element) ? element.id : element.frameId;\n if (frameId && !frameElementsMap.has(frameId)) {\n frameElementsMap.set(frameId, getFrameChildren(elements, frameId));\n }\n }\n\n return frameElementsMap;\n};\n\nexport const getFrameChildren = (\n allElements: ElementsMapOrArray,\n frameId: string,\n) => {\n const frameChildren: ExcalidrawElement[] = [];\n for (const element of allElements.values()) {\n if (element.frameId === frameId) {\n frameChildren.push(element);\n }\n }\n return frameChildren;\n};\n\nexport const getFrameLikeElements = (\n allElements: ExcalidrawElementsIncludingDeleted,\n): ExcalidrawFrameLikeElement[] => {\n return allElements.filter((element): element is ExcalidrawFrameLikeElement =>\n isFrameLikeElement(element),\n );\n};\n\n/**\n * Returns ExcalidrawFrameElements and non-frame-children elements.\n *\n * Considers children as root elements if they point to a frame parent\n * non-existing in the elements set.\n *\n * Considers non-frame bound elements (container or arrow labels) as root.\n */\nexport const getRootElements = (\n allElements: ExcalidrawElementsIncludingDeleted,\n) => {\n const frameElements = arrayToMap(getFrameLikeElements(allElements));\n return allElements.filter(\n (element) =>\n frameElements.has(element.id) ||\n !element.frameId ||\n !frameElements.has(element.frameId),\n );\n};\n\nexport const getElementsInResizingFrame = (\n allElements: ExcalidrawElementsIncludingDeleted,\n frame: ExcalidrawFrameLikeElement,\n appState: AppState,\n elementsMap: ElementsMap,\n): ExcalidrawElement[] => {\n const prevElementsInFrame = getFrameChildren(allElements, frame.id);\n const nextElementsInFrame = new Set<ExcalidrawElement>(prevElementsInFrame);\n\n const elementsCompletelyInFrame = new Set([\n ...getElementsCompletelyInFrame(allElements, frame, elementsMap),\n ...prevElementsInFrame.filter((element) =>\n isElementContainingFrame(element, frame, elementsMap),\n ),\n ]);\n\n const elementsNotCompletelyInFrame = prevElementsInFrame.filter(\n (element) => !elementsCompletelyInFrame.has(element),\n );\n\n // for elements that are completely in the frame\n // if they are part of some groups, then those groups are still\n // considered to belong to the frame\n const groupsToKeep = new Set<string>(\n Array.from(elementsCompletelyInFrame).flatMap(\n (element) => element.groupIds,\n ),\n );\n\n for (const element of elementsNotCompletelyInFrame) {\n if (!isElementIntersectingFrame(element, frame, elementsMap)) {\n if (element.groupIds.length === 0) {\n nextElementsInFrame.delete(element);\n }\n } else if (element.groupIds.length > 0) {\n // group element intersects with the frame, we should keep the groups\n // that this element is part of\n for (const id of element.groupIds) {\n groupsToKeep.add(id);\n }\n }\n }\n\n for (const element of elementsNotCompletelyInFrame) {\n if (element.groupIds.length > 0) {\n let shouldRemoveElement = true;\n\n for (const id of element.groupIds) {\n if (groupsToKeep.has(id)) {\n shouldRemoveElement = false;\n }\n }\n\n if (shouldRemoveElement) {\n nextElementsInFrame.delete(element);\n }\n }\n }\n\n const individualElementsCompletelyInFrame = Array.from(\n elementsCompletelyInFrame,\n ).filter((element) => element.groupIds.length === 0);\n\n for (const element of individualElementsCompletelyInFrame) {\n nextElementsInFrame.add(element);\n }\n\n const newGroupElementsCompletelyInFrame = Array.from(\n elementsCompletelyInFrame,\n ).filter((element) => element.groupIds.length > 0);\n\n const groupIds = selectGroupsFromGivenElements(\n newGroupElementsCompletelyInFrame,\n appState,\n );\n\n // new group elements\n for (const [id, isSelected] of Object.entries(groupIds)) {\n if (isSelected) {\n const elementsInGroup = getElementsInGroup(allElements, id);\n\n if (elementsAreInFrameBounds(elementsInGroup, frame, elementsMap)) {\n for (const element of elementsInGroup) {\n nextElementsInFrame.add(element);\n }\n }\n }\n }\n\n return [...nextElementsInFrame].filter((element) => {\n return !(isTextElement(element) && element.containerId);\n });\n};\n\nexport const getElementsInNewFrame = (\n elements: ExcalidrawElementsIncludingDeleted,\n frame: ExcalidrawFrameLikeElement,\n elementsMap: ElementsMap,\n) => {\n return omitPartialGroups(\n omitGroupsContainingFrameLikes(\n elements,\n getElementsCompletelyInFrame(elements, frame, elementsMap),\n ),\n frame,\n elementsMap,\n );\n};\n\nexport const omitPartialGroups = (\n elements: ExcalidrawElement[],\n frame: ExcalidrawFrameLikeElement,\n allElementsMap: ElementsMap,\n) => {\n const elementsToReturn = [];\n const checkedGroups = new Map<string, boolean>();\n\n for (const element of elements) {\n let shouldOmit = false;\n if (element.groupIds.length > 0) {\n // if some partial group should be omitted, then all elements in that group should be omitted\n if (element.groupIds.some((gid) => checkedGroups.get(gid))) {\n shouldOmit = true;\n } else {\n const allElementsInGroup = new Set(\n element.groupIds.flatMap((gid) =>\n getElementsInGroup(allElementsMap, gid),\n ),\n );\n\n shouldOmit = !elementsAreInFrameBounds(\n Array.from(allElementsInGroup),\n frame,\n allElementsMap,\n );\n }\n\n element.groupIds.forEach((gid) => {\n checkedGroups.set(gid, shouldOmit);\n });\n }\n\n if (!shouldOmit) {\n elementsToReturn.push(element);\n }\n }\n\n return elementsToReturn;\n};\n\nexport const getContainingFrame = (\n element: ExcalidrawElement,\n elementsMap: ElementsMap,\n) => {\n if (!element.frameId) {\n return null;\n }\n return (elementsMap.get(element.frameId) ||\n null) as null | ExcalidrawFrameLikeElement;\n};\n\n// --------------------------- Frame Operations -------------------------------\n\n/** */\nexport const filterElementsEligibleAsFrameChildren = (\n elements: readonly ExcalidrawElement[],\n frame: ExcalidrawFrameLikeElement,\n) => {\n const otherFrames = new Set<ExcalidrawFrameLikeElement[\"id\"]>();\n const elementsMap = arrayToMap(elements);\n elements = omitGroupsContainingFrameLikes(elements);\n\n for (const element of elements) {\n if (isFrameLikeElement(element) && element.id !== frame.id) {\n otherFrames.add(element.id);\n }\n }\n\n const processedGroups = new Set<ExcalidrawElement[\"id\"]>();\n\n const eligibleElements: ExcalidrawElement[] = [];\n\n for (const element of elements) {\n // don't add frames or their children\n if (\n isFrameLikeElement(element) ||\n (element.frameId && otherFrames.has(element.frameId))\n ) {\n continue;\n }\n\n if (element.groupIds.length) {\n const shallowestGroupId = element.groupIds.at(-1)!;\n if (!processedGroups.has(shallowestGroupId)) {\n processedGroups.add(shallowestGroupId);\n const groupElements = getElementsInGroup(elements, shallowestGroupId);\n if (\n groupElements.some((el) =>\n elementOverlapsWithFrame(el, frame, elementsMap),\n )\n ) {\n for (const child of groupElements) {\n eligibleElements.push(child);\n }\n }\n }\n } else {\n const overlaps = elementOverlapsWithFrame(element, frame, elementsMap);\n if (overlaps) {\n eligibleElements.push(element);\n }\n }\n }\n\n return eligibleElements;\n};\n\n/**\n * Retains (or repairs for target frame) the ordering invriant where children\n * elements come right before the parent frame:\n * [el, el, child, child, frame, el]\n *\n * @returns mutated allElements (same data structure)\n */\nexport const addElementsToFrame = <T extends ElementsMapOrArray>(\n allElements: T,\n elementsToAdd: NonDeletedExcalidrawElement[],\n frame: ExcalidrawFrameLikeElement,\n appState: AppState,\n): T => {\n const elementsMap = arrayToMap(allElements);\n const currTargetFrameChildrenMap = new Map<ExcalidrawElement[\"id\"], true>();\n for (const element of allElements.values()) {\n if (element.frameId === frame.id) {\n currTargetFrameChildrenMap.set(element.id, true);\n }\n }\n\n const suppliedElementsToAddSet = new Set(elementsToAdd.map((el) => el.id));\n\n const finalElementsToAdd: ExcalidrawElement[] = [];\n\n const otherFrames = new Set<ExcalidrawFrameLikeElement[\"id\"]>();\n\n for (const element of elementsToAdd) {\n if (isFrameLikeElement(element) && element.id !== frame.id) {\n otherFrames.add(element.id);\n }\n }\n\n // - add bound text elements if not already in the array\n // - filter out elements that are already in the frame\n for (const element of omitGroupsContainingFrameLikes(\n allElements,\n elementsToAdd,\n )) {\n // don't add frames or their children\n if (\n isFrameLikeElement(element) ||\n (element.frameId && otherFrames.has(element.frameId))\n ) {\n continue;\n }\n\n // if the element is already in another frame (which is also in elementsToAdd),\n // it means that frame and children are selected at the same time\n // => keep original frame membership, do not add to the target frame\n if (\n element.frameId &&\n appState.selectedElementIds[element.id] &&\n appState.selectedElementIds[element.frameId]\n ) {\n continue;\n }\n\n if (!currTargetFrameChildrenMap.has(element.id)) {\n finalElementsToAdd.push(element);\n }\n\n const boundTextElement = getBoundTextElement(element, elementsMap);\n if (\n boundTextElement &&\n !suppliedElementsToAddSet.has(boundTextElement.id) &&\n !currTargetFrameChildrenMap.has(boundTextElement.id)\n ) {\n finalElementsToAdd.push(boundTextElement);\n }\n }\n\n for (const element of finalElementsToAdd) {\n mutateElement(\n element,\n {\n frameId: frame.id,\n },\n false,\n );\n }\n\n return allElements;\n};\n\nexport const removeElementsFromFrame = (\n elementsToRemove: ReadonlySetLike<NonDeletedExcalidrawElement>,\n elementsMap: ElementsMap,\n) => {\n const _elementsToRemove = new Map<\n ExcalidrawElement[\"id\"],\n ExcalidrawElement\n >();\n\n const toRemoveElementsByFrame = new Map<\n ExcalidrawFrameLikeElement[\"id\"],\n ExcalidrawElement[]\n >();\n\n for (const element of elementsToRemove) {\n if (element.frameId) {\n _elementsToRemove.set(element.id, element);\n\n const arr = toRemoveElementsByFrame.get(element.frameId) || [];\n arr.push(element);\n\n const boundTextElement = getBoundTextElement(element, elementsMap);\n if (boundTextElement) {\n _elementsToRemove.set(boundTextElement.id, boundTextElement);\n arr.push(boundTextElement);\n }\n\n toRemoveElementsByFrame.set(element.frameId, arr);\n }\n }\n\n for (const [, element] of _elementsToRemove) {\n mutateElement(\n element,\n {\n frameId: null,\n },\n false,\n );\n }\n};\n\nexport const removeAllElementsFromFrame = <T extends ExcalidrawElement>(\n allElements: readonly T[],\n frame: ExcalidrawFrameLikeElement,\n) => {\n const elementsInFrame = getFrameChildren(allElements, frame.id);\n removeElementsFromFrame(elementsInFrame, arrayToMap(allElements));\n return allElements;\n};\n\nexport const replaceAllElementsInFrame = <T extends ExcalidrawElement>(\n allElements: readonly T[],\n nextElementsInFrame: ExcalidrawElement[],\n frame: ExcalidrawFrameLikeElement,\n app: AppClassProperties,\n): T[] => {\n return addElementsToFrame(\n removeAllElementsFromFrame(allElements, frame),\n nextElementsInFrame,\n frame,\n app.state,\n ).slice();\n};\n\n/** does not mutate elements, but returns new ones */\nexport const updateFrameMembershipOfSelectedElements = <\n T extends ElementsMapOrArray,\n>(\n allElements: T,\n appState: AppState,\n app: AppClassProperties,\n) => {\n const selectedElements = app.scene.getSelectedElements({\n selectedElementIds: appState.selectedElementIds,\n // supplying elements explicitly in case we're passed non-state elements\n elements: allElements,\n });\n const elementsToFilter = new Set<ExcalidrawElement>(selectedElements);\n\n if (appState.editingGroupId) {\n for (const element of selectedElements) {\n if (element.groupIds.length === 0) {\n elementsToFilter.add(element);\n } else {\n element.groupIds\n .flatMap((gid) => getElementsInGroup(allElements, gid))\n .forEach((element) => elementsToFilter.add(element));\n }\n }\n }\n\n const elementsToRemove = new Set<ExcalidrawElement>();\n\n const elementsMap = arrayToMap(allElements);\n\n elementsToFilter.forEach((element) => {\n if (\n element.frameId &&\n !isFrameLikeElement(element) &&\n !isElementInFrame(element, elementsMap, appState)\n ) {\n elementsToRemove.add(element);\n }\n });\n\n if (elementsToRemove.size > 0) {\n removeElementsFromFrame(elementsToRemove, elementsMap);\n }\n return allElements;\n};\n\n/**\n * filters out elements that are inside groups that contain a frame element\n * anywhere in the group tree\n */\nexport const omitGroupsContainingFrameLikes = (\n allElements: ElementsMapOrArray,\n /** subset of elements you want to filter. Optional perf optimization so we\n * don't have to filter all elements unnecessarily\n */\n selectedElements?: readonly ExcalidrawElement[],\n) => {\n const uniqueGroupIds = new Set<string>();\n const elements = selectedElements || allElements;\n\n for (const el of elements.values()) {\n const topMostGroupId = el.groupIds[el.groupIds.length - 1];\n if (topMostGroupId) {\n uniqueGroupIds.add(topMostGroupId);\n }\n }\n\n const rejectedGroupIds = new Set<string>();\n for (const groupId of uniqueGroupIds) {\n if (\n getElementsInGroup(allElements, groupId).some((el) =>\n isFrameLikeElement(el),\n )\n ) {\n rejectedGroupIds.add(groupId);\n }\n }\n\n const ret: ExcalidrawElement[] = [];\n\n for (const element of elements.values()) {\n if (!rejectedGroupIds.has(element.groupIds[element.groupIds.length - 1])) {\n ret.push(element);\n }\n }\n\n return ret;\n};\n\n/**\n * depending on the appState, return target frame, which is the frame the given element\n * is going to be added to or remove from\n */\nexport const getTargetFrame = (\n element: ExcalidrawElement,\n elementsMap: ElementsMap,\n appState: StaticCanvasAppState,\n) => {\n const _element = isTextElement(element)\n ? getContainerElement(element, elementsMap) || element\n : element;\n\n // if the element and its containing frame are both selected, then\n // the containing frame is the target frame\n if (\n _element.frameId &&\n appState.selectedElementIds[_element.id] &&\n appState.selectedElementIds[_element.frameId]\n ) {\n return getContainingFrame(_element, elementsMap);\n }\n\n return appState.selectedElementIds[_element.id] &&\n appState.selectedElementsAreBeingDragged\n ? appState.frameToHighlight\n : getContainingFrame(_element, elementsMap);\n};\n\n// TODO: this a huge bottleneck for large scenes, optimise\n// given an element, return if the element is in some frame\nexport const isElementInFrame = (\n element: ExcalidrawElement,\n allElementsMap: ElementsMap,\n appState: StaticCanvasAppState,\n opts?: {\n targetFrame?: ExcalidrawFrameLikeElement;\n checkedGroups?: Map<string, boolean>;\n },\n) => {\n const frame =\n opts?.targetFrame ?? getTargetFrame(element, allElementsMap, appState);\n\n if (!frame) {\n return false;\n }\n\n const _element = isTextElement(element)\n ? getContainerElement(element, allElementsMap) || element\n : element;\n\n const setGroupsInFrame = (isInFrame: boolean) => {\n if (opts?.checkedGroups) {\n _element.groupIds.forEach((groupId) => {\n opts.checkedGroups?.set(groupId, isInFrame);\n });\n }\n };\n\n if (\n // if the element is not selected, or it is selected but not being dragged,\n // frame membership won't update, so return true\n !appState.selectedElementIds[_element.id] ||\n !appState.selectedElementsAreBeingDragged ||\n // if both frame and element are selected, won't update membership, so return true\n (appState.selectedElementIds[_element.id] &&\n appState.selectedElementIds[frame.id])\n ) {\n return true;\n }\n\n if (_element.groupIds.length === 0) {\n return elementOverlapsWithFrame(_element, frame, allElementsMap);\n }\n\n for (const gid of _element.groupIds) {\n if (opts?.checkedGroups?.has(gid)) {\n return opts.checkedGroups.get(gid)!!;\n }\n }\n\n const allElementsInGroup = new Set(\n _element.groupIds\n .filter((gid) => {\n if (opts?.checkedGroups) {\n return !opts.checkedGroups.has(gid);\n }\n return true;\n })\n .flatMap((gid) => getElementsInGroup(allElementsMap, gid)),\n );\n\n if (appState.editingGroupId && appState.selectedElementsAreBeingDragged) {\n const selectedElements = new Set(\n getSelectedElements(allElementsMap, appState),\n );\n\n const editingGroupOverlapsFrame = appState.frameToHighlight !== null;\n\n if (editingGroupOverlapsFrame) {\n return true;\n }\n\n selectedElements.forEach((selectedElement) => {\n allElementsInGroup.delete(selectedElement);\n });\n }\n\n for (const elementInGroup of allElementsInGroup) {\n if (isFrameLikeElement(elementInGroup)) {\n setGroupsInFrame(false);\n return false;\n }\n }\n\n for (const elementInGroup of allElementsInGroup) {\n if (elementOverlapsWithFrame(elementInGroup, frame, allElementsMap)) {\n setGroupsInFrame(true);\n return true;\n }\n }\n\n return false;\n};\n\nexport const shouldApplyFrameClip = (\n element: ExcalidrawElement,\n frame: ExcalidrawFrameLikeElement,\n appState: StaticCanvasAppState,\n elementsMap: ElementsMap,\n checkedGroups?: Map<string, boolean>,\n) => {\n if (!appState.frameRendering || !appState.frameRendering.clip) {\n return false;\n }\n\n // for individual elements, only clip when the element is\n // a. overlapping with the frame, or\n // b. containing the frame, for example when an element is used as a background\n // and is therefore bigger than the frame and completely contains the frame\n const shouldClipElementItself =\n isElementIntersectingFrame(element, frame, elementsMap) ||\n isElementContainingFrame(element, frame, elementsMap);\n\n if (shouldClipElementItself) {\n for (const groupId of element.groupIds) {\n checkedGroups?.set(groupId, true);\n }\n\n return true;\n }\n\n // if an element is outside the frame, but is part of a group that has some elements\n // \"in\" the frame, we should clip the element\n if (\n !shouldClipElementItself &&\n element.groupIds.length > 0 &&\n !elementsAreInFrameBounds([element], frame, elementsMap)\n ) {\n let shouldClip = false;\n\n // if no elements are being dragged, we can skip the geometry check\n // because we know if the element is in the given frame or not\n if (!appState.selectedElementsAreBeingDragged) {\n shouldClip = element.frameId === frame.id;\n for (const groupId of element.groupIds) {\n checkedGroups?.set(groupId, shouldClip);\n }\n } else {\n shouldClip = isElementInFrame(element, elementsMap, appState, {\n targetFrame: frame,\n checkedGroups,\n });\n }\n\n for (const groupId of element.groupIds) {\n checkedGroups?.set(groupId, shouldClip);\n }\n\n return shouldClip;\n }\n\n return false;\n};\n\nexport const getFrameLikeTitle = (element: ExcalidrawFrameLikeElement) => {\n // TODO name frames \"AI\" only if specific to AI frames\n return element.name === null\n ? isFrameElement(element)\n ? \"Frame\"\n : \"AI Frame\"\n : element.name;\n};\n\nexport const getElementsOverlappingFrame = (\n elements: readonly ExcalidrawElement[],\n frame: ExcalidrawFrameLikeElement,\n) => {\n return (\n elementsOverlappingBBox({\n elements,\n bounds: frame,\n type: \"overlap\",\n })\n // removes elements who are overlapping, but are in a different frame,\n // and thus invisible in target frame\n .filter((el) => !el.frameId || el.frameId === frame.id)\n );\n};\n\nexport const frameAndChildrenSelectedTogether = (\n selectedElements: readonly ExcalidrawElement[],\n) => {\n const selectedElementsMap = arrayToMap(selectedElements);\n\n return (\n selectedElements.length > 1 &&\n selectedElements.some(\n (element) => element.frameId && selectedElementsMap.has(element.frameId),\n )\n );\n};\n", "import type {\n ElementsMap,\n ElementsMapOrArray,\n ExcalidrawElement,\n NonDeletedExcalidrawElement,\n} from \"../element/types\";\nimport { getElementAbsoluteCoords, getElementBounds } from \"../element\";\nimport type { AppState, InteractiveCanvasAppState } from \"../types\";\nimport { isBoundToContainer, isFrameLikeElement } from \"../element/typeChecks\";\nimport {\n elementOverlapsWithFrame,\n getContainingFrame,\n getFrameChildren,\n} from \"../frame\";\nimport { isShallowEqual } from \"../utils\";\nimport { isElementInViewport } from \"../element/sizeHelpers\";\n\n/**\n * Frames and their containing elements are not to be selected at the same time.\n * Given an array of selected elements, if there are frames and their containing elements\n * we only keep the frames.\n * @param selectedElements\n */\nexport const excludeElementsInFramesFromSelection = <\n T extends ExcalidrawElement,\n>(\n selectedElements: readonly T[],\n) => {\n const framesInSelection = new Set<T[\"id\"]>();\n\n selectedElements.forEach((element) => {\n if (isFrameLikeElement(element)) {\n framesInSelection.add(element.id);\n }\n });\n\n return selectedElements.filter((element) => {\n if (element.frameId && framesInSelection.has(element.frameId)) {\n return false;\n }\n return true;\n });\n};\n\nexport const getElementsWithinSelection = (\n elements: readonly NonDeletedExcalidrawElement[],\n selection: NonDeletedExcalidrawElement,\n elementsMap: ElementsMap,\n excludeElementsInFrames: boolean = true,\n) => {\n const [selectionX1, selectionY1, selectionX2, selectionY2] =\n getElementAbsoluteCoords(selection, elementsMap);\n\n let elementsInSelection = elements.filter((element) => {\n let [elementX1, elementY1, elementX2, elementY2] = getElementBounds(\n element,\n elementsMap,\n );\n\n const containingFrame = getContainingFrame(element, elementsMap);\n if (containingFrame) {\n const [fx1, fy1, fx2, fy2] = getElementBounds(\n containingFrame,\n elementsMap,\n );\n\n elementX1 = Math.max(fx1, elementX1);\n elementY1 = Math.max(fy1, elementY1);\n elementX2 = Math.min(fx2, elementX2);\n elementY2 = Math.min(fy2, elementY2);\n }\n\n return (\n element.locked === false &&\n element.type !== \"selection\" &&\n !isBoundToContainer(element) &&\n selectionX1 <= elementX1 &&\n selectionY1 <= elementY1 &&\n selectionX2 >= elementX2 &&\n selectionY2 >= elementY2\n );\n });\n\n elementsInSelection = excludeElementsInFrames\n ? excludeElementsInFramesFromSelection(elementsInSelection)\n : elementsInSelection;\n\n elementsInSelection = elementsInSelection.filter((element) => {\n const containingFrame = getContainingFrame(element, elementsMap);\n\n if (containingFrame) {\n return elementOverlapsWithFrame(element, containingFrame, elementsMap);\n }\n\n return true;\n });\n\n return elementsInSelection;\n};\n\nexport const getVisibleAndNonSelectedElements = (\n elements: readonly NonDeletedExcalidrawElement[],\n selectedElements: readonly NonDeletedExcalidrawElement[],\n appState: AppState,\n elementsMap: ElementsMap,\n) => {\n const selectedElementsSet = new Set(\n selectedElements.map((element) => element.id),\n );\n return elements.filter((element) => {\n const isVisible = isElementInViewport(\n element,\n appState.width,\n appState.height,\n appState,\n elementsMap,\n );\n\n return !selectedElementsSet.has(element.id) && isVisible;\n });\n};\n\n// FIXME move this into the editor instance to keep utility methods stateless\nexport const isSomeElementSelected = (function () {\n let lastElements: readonly NonDeletedExcalidrawElement[] | null = null;\n let lastSelectedElementIds: AppState[\"selectedElementIds\"] | null = null;\n let isSelected: boolean | null = null;\n\n const ret = (\n elements: readonly NonDeletedExcalidrawElement[],\n appState: Pick<AppState, \"selectedElementIds\">,\n ): boolean => {\n if (\n isSelected != null &&\n elements === lastElements &&\n appState.selectedElementIds === lastSelectedElementIds\n ) {\n return isSelected;\n }\n\n isSelected = elements.some(\n (element) => appState.selectedElementIds[element.id],\n );\n lastElements = elements;\n lastSelectedElementIds = appState.selectedElementIds;\n\n return isSelected;\n };\n\n ret.clearCache = () => {\n lastElements = null;\n lastSelectedElementIds = null;\n isSelected = null;\n };\n\n return ret;\n})();\n\n/**\n * Returns common attribute (picked by `getAttribute` callback) of selected\n * elements. If elements don't share the same value, returns `null`.\n */\nexport const getCommonAttributeOfSelectedElements = <T>(\n elements: readonly NonDeletedExcalidrawElement[],\n appState: Pick<AppState, \"selectedElementIds\">,\n getAttribute: (element: ExcalidrawElement) => T,\n): T | null => {\n const attributes = Array.from(\n new Set(\n getSelectedElements(elements, appState).map((element) =>\n getAttribute(element),\n ),\n ),\n );\n return attributes.length === 1 ? attributes[0] : null;\n};\n\nexport const getSelectedElements = (\n elements: ElementsMapOrArray,\n appState: Pick<InteractiveCanvasAppState, \"selectedElementIds\">,\n opts?: {\n includeBoundTextElement?: boolean;\n includeElementsInFrames?: boolean;\n },\n) => {\n const addedElements = new Set<ExcalidrawElement[\"id\"]>();\n const selectedElements: ExcalidrawElement[] = [];\n for (const element of elements.values()) {\n if (appState.selectedElementIds[element.id]) {\n selectedElements.push(element);\n addedElements.add(element.id);\n continue;\n }\n if (\n opts?.includeBoundTextElement &&\n isBoundToContainer(element) &&\n appState.selectedElementIds[element?.containerId]\n ) {\n selectedElements.push(element);\n addedElements.add(element.id);\n continue;\n }\n }\n\n if (opts?.includeElementsInFrames) {\n const elementsToInclude: ExcalidrawElement[] = [];\n selectedElements.forEach((element) => {\n if (isFrameLikeElement(element)) {\n getFrameChildren(elements, element.id).forEach(\n (e) => !addedElements.has(e.id) && elementsToInclude.push(e),\n );\n }\n elementsToInclude.push(element);\n });\n\n return elementsToInclude;\n }\n\n return selectedElements;\n};\n\nexport const getTargetElements = (\n elements: ElementsMapOrArray,\n appState: Pick<\n AppState,\n \"selectedElementIds\" | \"editingTextElement\" | \"newElement\"\n >,\n) =>\n appState.editingTextElement\n ? [appState.editingTextElement]\n : appState.newElement\n ? [appState.newElement]\n : getSelectedElements(elements, appState, {\n includeBoundTextElement: true,\n });\n\n/**\n * returns prevState's selectedElementids if no change from previous, so as to\n * retain reference identity for memoization\n */\nexport const makeNextSelectedElementIds = (\n nextSelectedElementIds: AppState[\"selectedElementIds\"],\n prevState: Pick<AppState, \"selectedElementIds\">,\n) => {\n if (isShallowEqual(prevState.selectedElementIds, nextSelectedElementIds)) {\n return prevState.selectedElementIds;\n }\n\n return nextSelectedElementIds;\n};\n", "export default class BinaryHeap<T> {\n private content: T[] = [];\n\n constructor(private scoreFunction: (node: T) => number) {}\n\n sinkDown(idx: number) {\n const node = this.content[idx];\n while (idx > 0) {\n const parentN = ((idx + 1) >> 1) - 1;\n const parent = this.content[parentN];\n if (this.scoreFunction(node) < this.scoreFunction(parent)) {\n this.content[parentN] = node;\n this.content[idx] = parent;\n idx = parentN; // TODO: Optimize\n } else {\n break;\n }\n }\n }\n\n bubbleUp(idx: number) {\n const length = this.content.length;\n const node = this.content[idx];\n const score = this.scoreFunction(node);\n\n while (true) {\n const child2N = (idx + 1) << 1;\n const child1N = child2N - 1;\n let swap = null;\n let child1Score = 0;\n\n if (child1N < length) {\n const child1 = this.content[child1N];\n child1Score = this.scoreFunction(child1);\n if (child1Score < score) {\n swap = child1N;\n }\n }\n\n if (child2N < length) {\n const child2 = this.content[child2N];\n const child2Score = this.scoreFunction(child2);\n if (child2Score < (swap === null ? score : child1Score)) {\n swap = child2N;\n }\n }\n\n if (swap !== null) {\n this.content[idx] = this.content[swap];\n this.content[swap] = node;\n idx = swap; // TODO: Optimize\n } else {\n break;\n }\n }\n }\n\n push(node: T) {\n this.content.push(node);\n this.sinkDown(this.content.length - 1);\n }\n\n pop(): T | null {\n if (this.content.length === 0) {\n return null;\n }\n\n const result = this.content[0];\n const end = this.content.pop()!;\n\n if (this.content.length > 0) {\n this.content[0] = end;\n this.bubbleUp(0);\n }\n\n return result;\n }\n\n remove(node: T) {\n if (this.content.length === 0) {\n return;\n }\n\n const i = this.content.indexOf(node);\n const end = this.content.pop()!;\n\n if (i < this.content.length) {\n this.content[i] = end;\n\n if (this.scoreFunction(end) < this.scoreFunction(node)) {\n this.sinkDown(i);\n } else {\n this.bubbleUp(i);\n }\n }\n }\n\n size(): number {\n return this.content.length;\n }\n\n rescoreElement(node: T) {\n this.sinkDown(this.content.indexOf(node));\n }\n}\n", "import {\n clamp,\n pointDistance,\n pointFrom,\n pointScaleFromOrigin,\n pointsEqual,\n pointTranslate,\n vector,\n vectorCross,\n vectorFromPoint,\n vectorScale,\n type GlobalPoint,\n type LocalPoint,\n} from \"@excalidraw/math\";\nimport BinaryHeap from \"../binaryheap\";\nimport { getSizeFromPoints } from \"../points\";\nimport { aabbForElement, pointInsideBounds } from \"../shapes\";\nimport { invariant, isAnyTrue, toBrandedType, tupleToCoors } from \"../utils\";\nimport type { AppState } from \"../types\";\nimport {\n bindPointToSnapToElementOutline,\n FIXED_BINDING_DISTANCE,\n getHeadingForElbowArrowSnap,\n getGlobalFixedPointForBindableElement,\n snapToMid,\n getHoveredElementForBinding,\n} from \"./binding\";\nimport type { Bounds } from \"./bounds\";\nimport type { Heading } from \"./heading\";\nimport {\n compareHeading,\n flipHeading,\n HEADING_DOWN,\n HEADING_LEFT,\n HEADING_RIGHT,\n HEADING_UP,\n headingForPointIsHorizontal,\n headingIsHorizontal,\n vectorToHeading,\n headingForPoint,\n} from \"./heading\";\nimport { type ElementUpdate } from \"./mutateElement\";\nimport { isBindableElement } from \"./typeChecks\";\nimport {\n type ExcalidrawElbowArrowElement,\n type NonDeletedSceneElementsMap,\n type SceneElementsMap,\n} from \"./types\";\nimport type {\n Arrowhead,\n ElementsMap,\n ExcalidrawBindableElement,\n FixedPointBinding,\n FixedSegment,\n} from \"./types\";\nimport { distanceToBindableElement } from \"./distance\";\n\ntype GridAddress = [number, number] & { _brand: \"gridaddress\" };\n\ntype Node = {\n f: number;\n g: number;\n h: number;\n closed: boolean;\n visited: boolean;\n parent: Node | null;\n pos: GlobalPoint;\n addr: GridAddress;\n};\n\ntype Grid = {\n row: number;\n col: number;\n data: (Node | null)[];\n};\n\ntype ElbowArrowState = {\n x: number;\n y: number;\n startBinding: FixedPointBinding | null;\n endBinding: FixedPointBinding | null;\n startArrowhead: Arrowhead | null;\n endArrowhead: Arrowhead | null;\n};\n\ntype ElbowArrowData = {\n dynamicAABBs: Bounds[];\n startDonglePosition: GlobalPoint | null;\n startGlobalPoint: GlobalPoint;\n startHeading: Heading;\n endDonglePosition: GlobalPoint | null;\n endGlobalPoint: GlobalPoint;\n endHeading: Heading;\n commonBounds: Bounds;\n hoveredStartElement: ExcalidrawBindableElement | null;\n hoveredEndElement: ExcalidrawBindableElement | null;\n};\n\nconst DEDUP_TRESHOLD = 1;\nexport const BASE_PADDING = 40;\n\nconst handleSegmentRenormalization = (\n arrow: ExcalidrawElbowArrowElement,\n elementsMap: NonDeletedSceneElementsMap | SceneElementsMap,\n) => {\n const nextFixedSegments: FixedSegment[] | null = arrow.fixedSegments\n ? arrow.fixedSegments.slice()\n : null;\n\n if (nextFixedSegments) {\n const _nextPoints: GlobalPoint[] = [];\n\n arrow.points\n .map((p) => pointFrom<GlobalPoint>(arrow.x + p[0], arrow.y + p[1]))\n .forEach((p, i, points) => {\n if (i < 2) {\n return _nextPoints.push(p);\n }\n\n const currentSegmentIsHorizontal = headingForPoint(p, points[i - 1]);\n const prevSegmentIsHorizontal = headingForPoint(\n points[i - 1],\n points[i - 2],\n );\n\n if (\n // Check if previous two points are on the same line\n compareHeading(currentSegmentIsHorizontal, prevSegmentIsHorizontal)\n ) {\n const prevSegmentIdx =\n nextFixedSegments?.findIndex(\n (segment) => segment.index === i - 1,\n ) ?? -1;\n const segmentIdx =\n nextFixedSegments?.findIndex((segment) => segment.index === i) ??\n -1;\n\n // If the current segment is a fixed segment, update its start point\n if (segmentIdx !== -1) {\n nextFixedSegments[segmentIdx].start = pointFrom<LocalPoint>(\n points[i - 2][0] - arrow.x,\n points[i - 2][1] - arrow.y,\n );\n }\n\n // Remove the fixed segment status from the previous segment if it is\n // a fixed segment, because we are going to unify that segment with\n // the current one\n if (prevSegmentIdx !== -1) {\n nextFixedSegments.splice(prevSegmentIdx, 1);\n }\n\n // Remove the duplicate point\n _nextPoints.splice(-1, 1);\n\n // Update fixed point indices\n nextFixedSegments.forEach((segment) => {\n if (segment.index > i - 1) {\n segment.index -= 1;\n }\n });\n }\n\n return _nextPoints.push(p);\n });\n\n const nextPoints: GlobalPoint[] = [];\n\n _nextPoints.forEach((p, i, points) => {\n if (i < 3) {\n return nextPoints.push(p);\n }\n\n if (\n // Remove segments that are too short\n pointDistance(points[i - 2], points[i - 1]) < DEDUP_TRESHOLD\n ) {\n const prevPrevSegmentIdx =\n nextFixedSegments?.findIndex((segment) => segment.index === i - 2) ??\n -1;\n const prevSegmentIdx =\n nextFixedSegments?.findIndex((segment) => segment.index === i - 1) ??\n -1;\n\n // Remove the previous fixed segment if it exists (i.e. the segment\n // which will be removed due to being parallel or too short)\n if (prevSegmentIdx !== -1) {\n nextFixedSegments.splice(prevSegmentIdx, 1);\n }\n\n // Remove the fixed segment status from the segment 2 steps back\n // if it is a fixed segment, because we are going to unify that\n // segment with the current one\n if (prevPrevSegmentIdx !== -1) {\n nextFixedSegments.splice(prevPrevSegmentIdx, 1);\n }\n\n nextPoints.splice(-2, 2);\n\n // Since we have to remove two segments, update any fixed segment\n nextFixedSegments.forEach((segment) => {\n if (segment.index > i - 2) {\n segment.index -= 2;\n }\n });\n\n // Remove aligned segment points\n const isHorizontal = headingForPointIsHorizontal(p, points[i - 1]);\n\n return nextPoints.push(\n pointFrom<GlobalPoint>(\n !isHorizontal ? points[i - 2][0] : p[0],\n isHorizontal ? points[i - 2][1] : p[1],\n ),\n );\n }\n\n nextPoints.push(p);\n });\n\n const filteredNextFixedSegments = nextFixedSegments.filter(\n (segment) =>\n segment.index !== 1 && segment.index !== nextPoints.length - 1,\n );\n if (filteredNextFixedSegments.length === 0) {\n return normalizeArrowElementUpdate(\n getElbowArrowCornerPoints(\n removeElbowArrowShortSegments(\n routeElbowArrow(\n arrow,\n getElbowArrowData(\n arrow,\n elementsMap,\n nextPoints.map((p) =>\n pointFrom<LocalPoint>(p[0] - arrow.x, p[1] - arrow.y),\n ),\n ),\n ) ?? [],\n ),\n ),\n filteredNextFixedSegments,\n null,\n null,\n );\n }\n\n import.meta.env.DEV &&\n invariant(\n validateElbowPoints(nextPoints),\n \"Invalid elbow points with fixed segments\",\n );\n\n return normalizeArrowElementUpdate(\n nextPoints,\n filteredNextFixedSegments,\n arrow.startIsSpecial,\n arrow.endIsSpecial,\n );\n }\n\n return {\n x: arrow.x,\n y: arrow.y,\n points: arrow.points,\n fixedSegments: arrow.fixedSegments,\n startIsSpecial: arrow.startIsSpecial,\n endIsSpecial: arrow.endIsSpecial,\n };\n};\n\nconst handleSegmentRelease = (\n arrow: ExcalidrawElbowArrowElement,\n fixedSegments: readonly FixedSegment[],\n elementsMap: NonDeletedSceneElementsMap | SceneElementsMap,\n) => {\n const newFixedSegmentIndices = fixedSegments.map((segment) => segment.index);\n const oldFixedSegmentIndices =\n arrow.fixedSegments?.map((segment) => segment.index) ?? [];\n const deletedSegmentIdx = oldFixedSegmentIndices.findIndex(\n (idx) => !newFixedSegmentIndices.includes(idx),\n );\n\n if (deletedSegmentIdx === -1 || !arrow.fixedSegments?.[deletedSegmentIdx]) {\n return {\n points: arrow.points,\n };\n }\n\n const deletedIdx = arrow.fixedSegments[deletedSegmentIdx].index;\n\n // Find prev and next fixed segments\n const prevSegment = arrow.fixedSegments[deletedSegmentIdx - 1];\n const nextSegment = arrow.fixedSegments[deletedSegmentIdx + 1];\n\n // We need to render a sub-arrow path to restore deleted segments\n const x = arrow.x + (prevSegment ? prevSegment.end[0] : 0);\n const y = arrow.y + (prevSegment ? prevSegment.end[1] : 0);\n const {\n startHeading,\n endHeading,\n startGlobalPoint,\n endGlobalPoint,\n hoveredStartElement,\n hoveredEndElement,\n ...rest\n } = getElbowArrowData(\n {\n x,\n y,\n startBinding: prevSegment ? null : arrow.startBinding,\n endBinding: nextSegment ? null : arrow.endBinding,\n startArrowhead: null,\n endArrowhead: null,\n },\n elementsMap,\n [\n pointFrom<LocalPoint>(0, 0),\n pointFrom<LocalPoint>(\n arrow.x +\n (nextSegment?.start[0] ?? arrow.points[arrow.points.length - 1][0]) -\n x,\n arrow.y +\n (nextSegment?.start[1] ?? arrow.points[arrow.points.length - 1][1]) -\n y,\n ),\n ],\n { isDragging: false },\n );\n\n const { points: restoredPoints } = normalizeArrowElementUpdate(\n getElbowArrowCornerPoints(\n removeElbowArrowShortSegments(\n routeElbowArrow(arrow, {\n startHeading,\n endHeading,\n startGlobalPoint,\n endGlobalPoint,\n hoveredStartElement,\n hoveredEndElement,\n ...rest,\n }) ?? [],\n ),\n ),\n fixedSegments,\n null,\n null,\n );\n\n const nextPoints: GlobalPoint[] = [];\n\n // First part of the arrow are the old points\n if (prevSegment) {\n for (let i = 0; i < prevSegment.index; i++) {\n nextPoints.push(\n pointFrom<GlobalPoint>(\n arrow.x + arrow.points[i][0],\n arrow.y + arrow.points[i][1],\n ),\n );\n }\n }\n\n restoredPoints.forEach((p) => {\n nextPoints.push(\n pointFrom<GlobalPoint>(\n arrow.x + (prevSegment ? prevSegment.end[0] : 0) + p[0],\n arrow.y + (prevSegment ? prevSegment.end[1] : 0) + p[1],\n ),\n );\n });\n\n // Last part of the arrow are the old points too\n if (nextSegment) {\n for (let i = nextSegment.index; i < arrow.points.length; i++) {\n nextPoints.push(\n pointFrom<GlobalPoint>(\n arrow.x + arrow.points[i][0],\n arrow.y + arrow.points[i][1],\n ),\n );\n }\n }\n\n // Update nextFixedSegments\n const originalSegmentCountDiff =\n (nextSegment?.index ?? arrow.points.length) - (prevSegment?.index ?? 0) - 1;\n\n const nextFixedSegments = fixedSegments.map((segment) => {\n if (segment.index > deletedIdx) {\n return {\n ...segment,\n index:\n segment.index -\n originalSegmentCountDiff +\n (restoredPoints.length - 1),\n };\n }\n\n return segment;\n });\n\n const simplifiedPoints = nextPoints.flatMap((p, i) => {\n const prev = nextPoints[i - 1];\n const next = nextPoints[i + 1];\n\n if (prev && next) {\n const prevHeading = headingForPoint(p, prev);\n const nextHeading = headingForPoint(next, p);\n\n if (compareHeading(prevHeading, nextHeading)) {\n // Update subsequent fixed segment indices\n nextFixedSegments.forEach((segment) => {\n if (segment.index > i) {\n segment.index -= 1;\n }\n });\n\n return [];\n } else if (compareHeading(prevHeading, flipHeading(nextHeading))) {\n // Update subsequent fixed segment indices\n nextFixedSegments.forEach((segment) => {\n if (segment.index > i) {\n segment.index += 1;\n }\n });\n\n return [p, p];\n }\n }\n\n return [p];\n });\n\n return normalizeArrowElementUpdate(\n simplifiedPoints,\n nextFixedSegments,\n false,\n false,\n );\n};\n\n/**\n *\n */\nconst handleSegmentMove = (\n arrow: ExcalidrawElbowArrowElement,\n fixedSegments: readonly FixedSegment[],\n startHeading: Heading,\n endHeading: Heading,\n hoveredStartElement: ExcalidrawBindableElement | null,\n hoveredEndElement: ExcalidrawBindableElement | null,\n): ElementUpdate<ExcalidrawElbowArrowElement> => {\n const activelyModifiedSegmentIdx = fixedSegments\n .map((segment, i) => {\n if (\n arrow.fixedSegments == null ||\n arrow.fixedSegments[i] === undefined ||\n arrow.fixedSegments[i].index !== segment.index\n ) {\n return i;\n }\n\n return (segment.start[0] !== arrow.fixedSegments![i].start[0] &&\n segment.end[0] !== arrow.fixedSegments![i].end[0]) !==\n (segment.start[1] !== arrow.fixedSegments![i].start[1] &&\n segment.end[1] !== arrow.fixedSegments![i].end[1])\n ? i\n : null;\n })\n .filter((idx) => idx !== null)\n .shift();\n\n if (activelyModifiedSegmentIdx == null) {\n return { points: arrow.points };\n }\n\n const firstSegmentIdx =\n arrow.fixedSegments?.findIndex((segment) => segment.index === 1) ?? -1;\n const lastSegmentIdx =\n arrow.fixedSegments?.findIndex(\n (segment) => segment.index === arrow.points.length - 1,\n ) ?? -1;\n\n // Handle special case for first segment move\n const segmentLength = pointDistance(\n fixedSegments[activelyModifiedSegmentIdx].start,\n fixedSegments[activelyModifiedSegmentIdx].end,\n );\n const segmentIsTooShort = segmentLength < BASE_PADDING + 5;\n if (\n firstSegmentIdx === -1 &&\n fixedSegments[activelyModifiedSegmentIdx].index === 1 &&\n hoveredStartElement\n ) {\n const startIsHorizontal = headingIsHorizontal(startHeading);\n const startIsPositive = startIsHorizontal\n ? compareHeading(startHeading, HEADING_RIGHT)\n : compareHeading(startHeading, HEADING_DOWN);\n const padding = startIsPositive\n ? segmentIsTooShort\n ? segmentLength / 2\n : BASE_PADDING\n : segmentIsTooShort\n ? -segmentLength / 2\n : -BASE_PADDING;\n fixedSegments[activelyModifiedSegmentIdx].start = pointFrom<LocalPoint>(\n fixedSegments[activelyModifiedSegmentIdx].start[0] +\n (startIsHorizontal ? padding : 0),\n fixedSegments[activelyModifiedSegmentIdx].start[1] +\n (!startIsHorizontal ? padding : 0),\n );\n }\n\n // Handle special case for last segment move\n if (\n lastSegmentIdx === -1 &&\n fixedSegments[activelyModifiedSegmentIdx].index ===\n arrow.points.length - 1 &&\n hoveredEndElement\n ) {\n const endIsHorizontal = headingIsHorizontal(endHeading);\n const endIsPositive = endIsHorizontal\n ? compareHeading(endHeading, HEADING_RIGHT)\n : compareHeading(endHeading, HEADING_DOWN);\n const padding = endIsPositive\n ? segmentIsTooShort\n ? segmentLength / 2\n : BASE_PADDING\n : segmentIsTooShort\n ? -segmentLength / 2\n : -BASE_PADDING;\n fixedSegments[activelyModifiedSegmentIdx].end = pointFrom<LocalPoint>(\n fixedSegments[activelyModifiedSegmentIdx].end[0] +\n (endIsHorizontal ? padding : 0),\n fixedSegments[activelyModifiedSegmentIdx].end[1] +\n (!endIsHorizontal ? padding : 0),\n );\n }\n\n // Translate all fixed segments to global coordinates\n const nextFixedSegments = fixedSegments.map((segment) => ({\n ...segment,\n start: pointFrom<GlobalPoint>(\n arrow.x + segment.start[0],\n arrow.y + segment.start[1],\n ),\n end: pointFrom<GlobalPoint>(\n arrow.x + segment.end[0],\n arrow.y + segment.end[1],\n ),\n }));\n\n // For start, clone old arrow points\n const newPoints: GlobalPoint[] = arrow.points.map((p, i) =>\n pointFrom<GlobalPoint>(arrow.x + p[0], arrow.y + p[1]),\n );\n\n const startIdx = nextFixedSegments[activelyModifiedSegmentIdx].index - 1;\n const endIdx = nextFixedSegments[activelyModifiedSegmentIdx].index;\n const start = nextFixedSegments[activelyModifiedSegmentIdx].start;\n const end = nextFixedSegments[activelyModifiedSegmentIdx].end;\n const prevSegmentIsHorizontal =\n newPoints[startIdx - 1] &&\n !pointsEqual(newPoints[startIdx], newPoints[startIdx - 1])\n ? headingForPointIsHorizontal(\n newPoints[startIdx - 1],\n newPoints[startIdx],\n )\n : undefined;\n const nextSegmentIsHorizontal =\n newPoints[endIdx + 1] &&\n !pointsEqual(newPoints[endIdx], newPoints[endIdx + 1])\n ? headingForPointIsHorizontal(newPoints[endIdx + 1], newPoints[endIdx])\n : undefined;\n\n // Override the segment points with the actively moved fixed segment\n if (prevSegmentIsHorizontal !== undefined) {\n const dir = prevSegmentIsHorizontal ? 1 : 0;\n newPoints[startIdx - 1][dir] = start[dir];\n }\n newPoints[startIdx] = start;\n newPoints[endIdx] = end;\n if (nextSegmentIsHorizontal !== undefined) {\n const dir = nextSegmentIsHorizontal ? 1 : 0;\n newPoints[endIdx + 1][dir] = end[dir];\n }\n\n // Override neighboring fixedSegment start/end points, if any\n const prevSegmentIdx = nextFixedSegments.findIndex(\n (segment) => segment.index === startIdx,\n );\n if (prevSegmentIdx !== -1) {\n // Align the next segment points with the moved segment\n const dir = headingForPointIsHorizontal(\n nextFixedSegments[prevSegmentIdx].end,\n nextFixedSegments[prevSegmentIdx].start,\n )\n ? 1\n : 0;\n nextFixedSegments[prevSegmentIdx].start[dir] = start[dir];\n nextFixedSegments[prevSegmentIdx].end = start;\n }\n\n const nextSegmentIdx = nextFixedSegments.findIndex(\n (segment) => segment.index === endIdx + 1,\n );\n if (nextSegmentIdx !== -1) {\n // Align the next segment points with the moved segment\n const dir = headingForPointIsHorizontal(\n nextFixedSegments[nextSegmentIdx].end,\n nextFixedSegments[nextSegmentIdx].start,\n )\n ? 1\n : 0;\n nextFixedSegments[nextSegmentIdx].end[dir] = end[dir];\n nextFixedSegments[nextSegmentIdx].start = end;\n }\n\n // First segment move needs an additional segment\n if (firstSegmentIdx === -1 && startIdx === 0) {\n const startIsHorizontal = hoveredStartElement\n ? headingIsHorizontal(startHeading)\n : headingForPointIsHorizontal(newPoints[1], newPoints[0]);\n newPoints.unshift(\n pointFrom<GlobalPoint>(\n startIsHorizontal ? start[0] : arrow.x + arrow.points[0][0],\n !startIsHorizontal ? start[1] : arrow.y + arrow.points[0][1],\n ),\n );\n\n if (hoveredStartElement) {\n newPoints.unshift(\n pointFrom<GlobalPoint>(\n arrow.x + arrow.points[0][0],\n arrow.y + arrow.points[0][1],\n ),\n );\n }\n\n for (const segment of nextFixedSegments) {\n segment.index += hoveredStartElement ? 2 : 1;\n }\n }\n\n // Last segment move needs an additional segment\n if (lastSegmentIdx === -1 && endIdx === arrow.points.length - 1) {\n const endIsHorizontal = headingIsHorizontal(endHeading);\n newPoints.push(\n pointFrom<GlobalPoint>(\n endIsHorizontal\n ? end[0]\n : arrow.x + arrow.points[arrow.points.length - 1][0],\n !endIsHorizontal\n ? end[1]\n : arrow.y + arrow.points[arrow.points.length - 1][1],\n ),\n );\n if (hoveredEndElement) {\n newPoints.push(\n pointFrom<GlobalPoint>(\n arrow.x + arrow.points[arrow.points.length - 1][0],\n arrow.y + arrow.points[arrow.points.length - 1][1],\n ),\n );\n }\n }\n\n return normalizeArrowElementUpdate(\n newPoints,\n nextFixedSegments.map((segment) => ({\n ...segment,\n start: pointFrom<LocalPoint>(\n segment.start[0] - arrow.x,\n segment.start[1] - arrow.y,\n ),\n end: pointFrom<LocalPoint>(\n segment.end[0] - arrow.x,\n segment.end[1] - arrow.y,\n ),\n })),\n false, // If you move a segment, there is no special point anymore\n false, // If you move a segment, there is no special point anymore\n );\n};\n\nconst handleEndpointDrag = (\n arrow: ExcalidrawElbowArrowElement,\n updatedPoints: readonly LocalPoint[],\n fixedSegments: readonly FixedSegment[],\n startHeading: Heading,\n endHeading: Heading,\n startGlobalPoint: GlobalPoint,\n endGlobalPoint: GlobalPoint,\n hoveredStartElement: ExcalidrawBindableElement | null,\n hoveredEndElement: ExcalidrawBindableElement | null,\n) => {\n let startIsSpecial = arrow.startIsSpecial ?? null;\n let endIsSpecial = arrow.endIsSpecial ?? null;\n const globalUpdatedPoints = updatedPoints.map((p, i) =>\n i === 0\n ? pointFrom<GlobalPoint>(arrow.x + p[0], arrow.y + p[1])\n : i === updatedPoints.length - 1\n ? pointFrom<GlobalPoint>(arrow.x + p[0], arrow.y + p[1])\n : pointFrom<GlobalPoint>(\n arrow.x + arrow.points[i][0],\n arrow.y + arrow.points[i][1],\n ),\n );\n const nextFixedSegments = fixedSegments.map((segment) => ({\n ...segment,\n start: pointFrom<GlobalPoint>(\n arrow.x + (segment.start[0] - updatedPoints[0][0]),\n arrow.y + (segment.start[1] - updatedPoints[0][1]),\n ),\n end: pointFrom<GlobalPoint>(\n arrow.x + (segment.end[0] - updatedPoints[0][0]),\n arrow.y + (segment.end[1] - updatedPoints[0][1]),\n ),\n }));\n const newPoints: GlobalPoint[] = [];\n\n // Add the inside points\n const offset = 2 + (startIsSpecial ? 1 : 0);\n const endOffset = 2 + (endIsSpecial ? 1 : 0);\n while (newPoints.length + offset < globalUpdatedPoints.length - endOffset) {\n newPoints.push(globalUpdatedPoints[newPoints.length + offset]);\n }\n\n // Calculate the moving second point connection and add the start point\n {\n const secondPoint = globalUpdatedPoints[startIsSpecial ? 2 : 1];\n const thirdPoint = globalUpdatedPoints[startIsSpecial ? 3 : 2];\n const startIsHorizontal = headingIsHorizontal(startHeading);\n const secondIsHorizontal = headingIsHorizontal(\n vectorToHeading(vectorFromPoint(secondPoint, thirdPoint)),\n );\n\n if (hoveredStartElement && startIsHorizontal === secondIsHorizontal) {\n const positive = startIsHorizontal\n ? compareHeading(startHeading, HEADING_RIGHT)\n : compareHeading(startHeading, HEADING_DOWN);\n newPoints.unshift(\n pointFrom<GlobalPoint>(\n !secondIsHorizontal\n ? thirdPoint[0]\n : startGlobalPoint[0] + (positive ? BASE_PADDING : -BASE_PADDING),\n secondIsHorizontal\n ? thirdPoint[1]\n : startGlobalPoint[1] + (positive ? BASE_PADDING : -BASE_PADDING),\n ),\n );\n newPoints.unshift(\n pointFrom<GlobalPoint>(\n startIsHorizontal\n ? startGlobalPoint[0] + (positive ? BASE_PADDING : -BASE_PADDING)\n : startGlobalPoint[0],\n !startIsHorizontal\n ? startGlobalPoint[1] + (positive ? BASE_PADDING : -BASE_PADDING)\n : startGlobalPoint[1],\n ),\n );\n if (!startIsSpecial) {\n startIsSpecial = true;\n for (const segment of nextFixedSegments) {\n if (segment.index > 1) {\n segment.index += 1;\n }\n }\n }\n } else {\n newPoints.unshift(\n pointFrom<GlobalPoint>(\n !secondIsHorizontal ? secondPoint[0] : startGlobalPoint[0],\n secondIsHorizontal ? secondPoint[1] : startGlobalPoint[1],\n ),\n );\n if (startIsSpecial) {\n startIsSpecial = false;\n for (const segment of nextFixedSegments) {\n if (segment.index > 1) {\n segment.index -= 1;\n }\n }\n }\n }\n newPoints.unshift(startGlobalPoint);\n }\n\n // Calculate the moving second to last point connection\n {\n const secondToLastPoint =\n globalUpdatedPoints[globalUpdatedPoints.length - (endIsSpecial ? 3 : 2)];\n const thirdToLastPoint =\n globalUpdatedPoints[globalUpdatedPoints.length - (endIsSpecial ? 4 : 3)];\n const endIsHorizontal = headingIsHorizontal(endHeading);\n const secondIsHorizontal = headingForPointIsHorizontal(\n thirdToLastPoint,\n secondToLastPoint,\n );\n if (hoveredEndElement && endIsHorizontal === secondIsHorizontal) {\n const positive = endIsHorizontal\n ? compareHeading(endHeading, HEADING_RIGHT)\n : compareHeading(endHeading, HEADING_DOWN);\n newPoints.push(\n pointFrom<GlobalPoint>(\n !secondIsHorizontal\n ? thirdToLastPoint[0]\n : endGlobalPoint[0] + (positive ? BASE_PADDING : -BASE_PADDING),\n secondIsHorizontal\n ? thirdToLastPoint[1]\n : endGlobalPoint[1] + (positive ? BASE_PADDING : -BASE_PADDING),\n ),\n );\n newPoints.push(\n pointFrom<GlobalPoint>(\n endIsHorizontal\n ? endGlobalPoint[0] + (positive ? BASE_PADDING : -BASE_PADDING)\n : endGlobalPoint[0],\n !endIsHorizontal\n ? endGlobalPoint[1] + (positive ? BASE_PADDING : -BASE_PADDING)\n : endGlobalPoint[1],\n ),\n );\n if (!endIsSpecial) {\n endIsSpecial = true;\n }\n } else {\n newPoints.push(\n pointFrom<GlobalPoint>(\n !secondIsHorizontal ? secondToLastPoint[0] : endGlobalPoint[0],\n secondIsHorizontal ? secondToLastPoint[1] : endGlobalPoint[1],\n ),\n );\n if (endIsSpecial) {\n endIsSpecial = false;\n }\n }\n }\n\n newPoints.push(endGlobalPoint);\n\n return normalizeArrowElementUpdate(\n newPoints,\n nextFixedSegments\n .map(({ index }) => ({\n index,\n start: newPoints[index - 1],\n end: newPoints[index],\n }))\n .map((segment) => ({\n ...segment,\n start: pointFrom<LocalPoint>(\n segment.start[0] - startGlobalPoint[0],\n segment.start[1] - startGlobalPoint[1],\n ),\n end: pointFrom<LocalPoint>(\n segment.end[0] - startGlobalPoint[0],\n segment.end[1] - startGlobalPoint[1],\n ),\n })),\n startIsSpecial,\n endIsSpecial,\n );\n};\n\nconst MAX_POS = 1e6;\n\n/**\n *\n */\nexport const updateElbowArrowPoints = (\n arrow: Readonly<ExcalidrawElbowArrowElement>,\n elementsMap: NonDeletedSceneElementsMap | SceneElementsMap,\n updates: {\n points?: readonly LocalPoint[];\n fixedSegments?: FixedSegment[] | null;\n startBinding?: FixedPointBinding | null;\n endBinding?: FixedPointBinding | null;\n },\n options?: {\n isDragging?: boolean;\n },\n): ElementUpdate<ExcalidrawElbowArrowElement> => {\n if (arrow.points.length < 2) {\n return { points: updates.points ?? arrow.points };\n }\n\n // NOTE (mtolmacs): This is a temporary check to ensure that the incoming elbow\n // arrow size is valid. This check will be removed once the issue is identified\n if (\n arrow.x < -MAX_POS ||\n arrow.x > MAX_POS ||\n arrow.y < -MAX_POS ||\n arrow.y > MAX_POS ||\n arrow.x + (updates?.points?.[updates?.points?.length - 1]?.[0] ?? 0) <\n -MAX_POS ||\n arrow.x + (updates?.points?.[updates?.points?.length - 1]?.[0] ?? 0) >\n MAX_POS ||\n arrow.y + (updates?.points?.[updates?.points?.length - 1]?.[1] ?? 0) <\n -MAX_POS ||\n arrow.y + (updates?.points?.[updates?.points?.length - 1]?.[1] ?? 0) >\n MAX_POS ||\n arrow.x + (arrow?.points?.[arrow?.points?.length - 1]?.[0] ?? 0) <\n -MAX_POS ||\n arrow.x + (arrow?.points?.[arrow?.points?.length - 1]?.[0] ?? 0) >\n MAX_POS ||\n arrow.y + (arrow?.points?.[arrow?.points?.length - 1]?.[1] ?? 0) <\n -MAX_POS ||\n arrow.y + (arrow?.points?.[arrow?.points?.length - 1]?.[1] ?? 0) > MAX_POS\n ) {\n console.error(\n \"Elbow arrow (or update) is outside reasonable bounds (> 1e6)\",\n {\n arrow,\n updates,\n },\n );\n }\n // @ts-ignore See above note\n arrow.x = clamp(arrow.x, -MAX_POS, MAX_POS);\n // @ts-ignore See above note\n arrow.y = clamp(arrow.y, -MAX_POS, MAX_POS);\n if (updates.points) {\n updates.points = updates.points.map(([x, y]) =>\n pointFrom<LocalPoint>(\n clamp(x, -MAX_POS, MAX_POS),\n clamp(y, -MAX_POS, MAX_POS),\n ),\n );\n }\n\n if (!import.meta.env.PROD) {\n invariant(\n !updates.points || updates.points.length >= 2,\n \"Updated point array length must match the arrow point length, contain \" +\n \"exactly the new start and end points or not be specified at all (i.e. \" +\n \"you can't add new points between start and end manually to elbow arrows)\",\n );\n\n invariant(\n !arrow.fixedSegments ||\n arrow.fixedSegments\n .map((s) => s.start[0] === s.end[0] || s.start[1] === s.end[1])\n .every(Boolean),\n \"Fixed segments must be either horizontal or vertical\",\n );\n\n invariant(\n !updates.fixedSegments ||\n updates.fixedSegments\n .map((s) => s.start[0] === s.end[0] || s.start[1] === s.end[1])\n .every(Boolean),\n \"Updates to fixed segments must be either horizontal or vertical\",\n );\n\n invariant(\n arrow.points\n .slice(1)\n .map(\n (p, i) => p[0] === arrow.points[i][0] || p[1] === arrow.points[i][1],\n ),\n \"Elbow arrow segments must be either horizontal or vertical\",\n );\n }\n\n // 0. During all element replacement in the scene, we just need to renormalize\n // the arrow\n // TODO (dwelle,mtolmacs): Remove this once Scene.getScene() is removed\n if (\n elementsMap.size === 0 &&\n updates.points &&\n validateElbowPoints(updates.points)\n ) {\n return normalizeArrowElementUpdate(\n updates.points.map((p) =>\n pointFrom<GlobalPoint>(arrow.x + p[0], arrow.y + p[1]),\n ),\n arrow.fixedSegments,\n arrow.startIsSpecial,\n arrow.endIsSpecial,\n );\n }\n\n const updatedPoints: readonly LocalPoint[] = updates.points\n ? updates.points && updates.points.length === 2\n ? arrow.points.map((p, idx) =>\n idx === 0\n ? updates.points![0]\n : idx === arrow.points.length - 1\n ? updates.points![1]\n : p,\n )\n : updates.points.slice()\n : arrow.points.slice();\n\n const {\n startHeading,\n endHeading,\n startGlobalPoint,\n endGlobalPoint,\n hoveredStartElement,\n hoveredEndElement,\n ...rest\n } = getElbowArrowData(\n {\n x: arrow.x,\n y: arrow.y,\n startBinding:\n typeof updates.startBinding !== \"undefined\"\n ? updates.startBinding\n : arrow.startBinding,\n endBinding:\n typeof updates.endBinding !== \"undefined\"\n ? updates.endBinding\n : arrow.endBinding,\n startArrowhead: arrow.startArrowhead,\n endArrowhead: arrow.endArrowhead,\n },\n elementsMap,\n updatedPoints,\n options,\n );\n\n const fixedSegments = updates.fixedSegments ?? arrow.fixedSegments ?? [];\n\n ////\n // 1. Renormalize the arrow\n ////\n if (\n !updates.points &&\n !updates.fixedSegments &&\n !updates.startBinding &&\n !updates.endBinding\n ) {\n return handleSegmentRenormalization(arrow, elementsMap);\n }\n\n // Short circuit on no-op to avoid huge performance hit\n if (\n updates.startBinding === arrow.startBinding &&\n updates.endBinding === arrow.endBinding\n ) {\n return {};\n }\n\n ////\n // 2. Just normal elbow arrow things\n ////\n if (fixedSegments.length === 0) {\n return normalizeArrowElementUpdate(\n getElbowArrowCornerPoints(\n removeElbowArrowShortSegments(\n routeElbowArrow(arrow, {\n startHeading,\n endHeading,\n startGlobalPoint,\n endGlobalPoint,\n hoveredStartElement,\n hoveredEndElement,\n ...rest,\n }) ?? [],\n ),\n ),\n fixedSegments,\n null,\n null,\n );\n }\n\n ////\n // 3. Handle releasing a fixed segment\n if ((arrow.fixedSegments?.length ?? 0) > fixedSegments.length) {\n return handleSegmentRelease(arrow, fixedSegments, elementsMap);\n }\n\n ////\n // 4. Handle manual segment move\n ////\n if (!updates.points) {\n return handleSegmentMove(\n arrow,\n fixedSegments,\n startHeading,\n endHeading,\n hoveredStartElement,\n hoveredEndElement,\n );\n }\n\n ////\n // 5. Handle resize\n ////\n if (updates.points && updates.fixedSegments) {\n return updates;\n }\n\n ////\n // 6. One or more segments are fixed and endpoints are moved\n //\n // The key insights are:\n // - When segments are fixed, the arrow will keep the exact amount of segments\n // - Fixed segments are \"replacements\" for exactly one segment in the old arrow\n ////\n return handleEndpointDrag(\n arrow,\n updatedPoints,\n fixedSegments,\n startHeading,\n endHeading,\n startGlobalPoint,\n endGlobalPoint,\n hoveredStartElement,\n hoveredEndElement,\n );\n};\n\n/**\n * Retrieves data necessary for calculating the elbow arrow path.\n *\n * @param arrow - The arrow object containing its properties.\n * @param elementsMap - A map of elements in the scene.\n * @param nextPoints - The next set of points for the arrow.\n * @param options - Optional parameters for the calculation.\n * @param options.isDragging - Indicates if the arrow is being dragged.\n * @param options.startIsMidPoint - Indicates if the start point is a midpoint.\n * @param options.endIsMidPoint - Indicates if the end point is a midpoint.\n *\n * @returns An object containing various properties needed for elbow arrow calculations:\n * - dynamicAABBs: Dynamically generated axis-aligned bounding boxes.\n * - startDonglePosition: The position of the start dongle.\n * - startGlobalPoint: The global coordinates of the start point.\n * - startHeading: The heading direction from the start point.\n * - endDonglePosition: The position of the end dongle.\n * - endGlobalPoint: The global coordinates of the end point.\n * - endHeading: The heading direction from the end point.\n * - commonBounds: The common bounding box that encompasses both start and end points.\n * - hoveredStartElement: The element being hovered over at the start point.\n * - hoveredEndElement: The element being hovered over at the end point.\n */\nconst getElbowArrowData = (\n arrow: {\n x: number;\n y: number;\n startBinding: FixedPointBinding | null;\n endBinding: FixedPointBinding | null;\n startArrowhead: Arrowhead | null;\n endArrowhead: Arrowhead | null;\n },\n elementsMap: NonDeletedSceneElementsMap | SceneElementsMap,\n nextPoints: readonly LocalPoint[],\n options?: {\n isDragging?: boolean;\n zoom?: AppState[\"zoom\"];\n },\n) => {\n const origStartGlobalPoint: GlobalPoint = pointTranslate<\n LocalPoint,\n GlobalPoint\n >(nextPoints[0], vector(arrow.x, arrow.y));\n const origEndGlobalPoint: GlobalPoint = pointTranslate<\n LocalPoint,\n GlobalPoint\n >(nextPoints[nextPoints.length - 1], vector(arrow.x, arrow.y));\n const startElement =\n arrow.startBinding &&\n getBindableElementForId(arrow.startBinding.elementId, elementsMap);\n const endElement =\n arrow.endBinding &&\n getBindableElementForId(arrow.endBinding.elementId, elementsMap);\n const [hoveredStartElement, hoveredEndElement] = options?.isDragging\n ? getHoveredElements(\n origStartGlobalPoint,\n origEndGlobalPoint,\n elementsMap,\n options?.zoom,\n )\n : [startElement, endElement];\n const startGlobalPoint = getGlobalPoint(\n {\n ...arrow,\n elbowed: true,\n points: nextPoints,\n } as ExcalidrawElbowArrowElement,\n \"start\",\n arrow.startBinding?.fixedPoint,\n origStartGlobalPoint,\n startElement,\n hoveredStartElement,\n options?.isDragging,\n );\n const endGlobalPoint = getGlobalPoint(\n {\n ...arrow,\n elbowed: true,\n points: nextPoints,\n } as ExcalidrawElbowArrowElement,\n \"end\",\n arrow.endBinding?.fixedPoint,\n origEndGlobalPoint,\n endElement,\n hoveredEndElement,\n options?.isDragging,\n );\n const startHeading = getBindPointHeading(\n startGlobalPoint,\n endGlobalPoint,\n elementsMap,\n hoveredStartElement,\n origStartGlobalPoint,\n );\n const endHeading = getBindPointHeading(\n endGlobalPoint,\n startGlobalPoint,\n elementsMap,\n hoveredEndElement,\n origEndGlobalPoint,\n );\n const startPointBounds = [\n startGlobalPoint[0] - 2,\n startGlobalPoint[1] - 2,\n startGlobalPoint[0] + 2,\n startGlobalPoint[1] + 2,\n ] as Bounds;\n const endPointBounds = [\n endGlobalPoint[0] - 2,\n endGlobalPoint[1] - 2,\n endGlobalPoint[0] + 2,\n endGlobalPoint[1] + 2,\n ] as Bounds;\n const startElementBounds = hoveredStartElement\n ? aabbForElement(\n hoveredStartElement,\n offsetFromHeading(\n startHeading,\n arrow.startArrowhead\n ? FIXED_BINDING_DISTANCE * 6\n : FIXED_BINDING_DISTANCE * 2,\n 1,\n ),\n )\n : startPointBounds;\n const endElementBounds = hoveredEndElement\n ? aabbForElement(\n hoveredEndElement,\n offsetFromHeading(\n endHeading,\n arrow.endArrowhead\n ? FIXED_BINDING_DISTANCE * 6\n : FIXED_BINDING_DISTANCE * 2,\n 1,\n ),\n )\n : endPointBounds;\n const boundsOverlap =\n pointInsideBounds(\n startGlobalPoint,\n hoveredEndElement\n ? aabbForElement(\n hoveredEndElement,\n offsetFromHeading(endHeading, BASE_PADDING, BASE_PADDING),\n )\n : endPointBounds,\n ) ||\n pointInsideBounds(\n endGlobalPoint,\n hoveredStartElement\n ? aabbForElement(\n hoveredStartElement,\n offsetFromHeading(startHeading, BASE_PADDING, BASE_PADDING),\n )\n : startPointBounds,\n );\n const commonBounds = commonAABB(\n boundsOverlap\n ? [startPointBounds, endPointBounds]\n : [startElementBounds, endElementBounds],\n );\n const dynamicAABBs = generateDynamicAABBs(\n boundsOverlap ? startPointBounds : startElementBounds,\n boundsOverlap ? endPointBounds : endElementBounds,\n commonBounds,\n boundsOverlap\n ? offsetFromHeading(\n startHeading,\n !hoveredStartElement && !hoveredEndElement ? 0 : BASE_PADDING,\n 0,\n )\n : offsetFromHeading(\n startHeading,\n !hoveredStartElement && !hoveredEndElement\n ? 0\n : BASE_PADDING -\n (arrow.startArrowhead\n ? FIXED_BINDING_DISTANCE * 6\n : FIXED_BINDING_DISTANCE * 2),\n BASE_PADDING,\n ),\n boundsOverlap\n ? offsetFromHeading(\n endHeading,\n !hoveredStartElement && !hoveredEndElement ? 0 : BASE_PADDING,\n 0,\n )\n : offsetFromHeading(\n endHeading,\n !hoveredStartElement && !hoveredEndElement\n ? 0\n : BASE_PADDING -\n (arrow.endArrowhead\n ? FIXED_BINDING_DISTANCE * 6\n : FIXED_BINDING_DISTANCE * 2),\n BASE_PADDING,\n ),\n boundsOverlap,\n hoveredStartElement && aabbForElement(hoveredStartElement),\n hoveredEndElement && aabbForElement(hoveredEndElement),\n );\n const startDonglePosition = getDonglePosition(\n dynamicAABBs[0],\n startHeading,\n startGlobalPoint,\n );\n const endDonglePosition = getDonglePosition(\n dynamicAABBs[1],\n endHeading,\n endGlobalPoint,\n );\n\n return {\n dynamicAABBs,\n startDonglePosition,\n startGlobalPoint,\n startHeading,\n endDonglePosition,\n endGlobalPoint,\n endHeading,\n commonBounds,\n hoveredStartElement,\n hoveredEndElement,\n boundsOverlap,\n startElementBounds,\n endElementBounds,\n };\n};\n\n/**\n * Generate the elbow arrow segments\n *\n * @param arrow\n * @param elementsMap\n * @param nextPoints\n * @param options\n * @returns\n */\nconst routeElbowArrow = (\n arrow: ElbowArrowState,\n elbowArrowData: ElbowArrowData,\n): GlobalPoint[] | null => {\n const {\n dynamicAABBs,\n startDonglePosition,\n startGlobalPoint,\n startHeading,\n endDonglePosition,\n endGlobalPoint,\n endHeading,\n commonBounds,\n hoveredEndElement,\n } = elbowArrowData;\n\n // Canculate Grid positions\n const grid = calculateGrid(\n dynamicAABBs,\n startDonglePosition ? startDonglePosition : startGlobalPoint,\n startHeading,\n endDonglePosition ? endDonglePosition : endGlobalPoint,\n endHeading,\n commonBounds,\n );\n\n const startDongle =\n startDonglePosition && pointToGridNode(startDonglePosition, grid);\n const endDongle =\n endDonglePosition && pointToGridNode(endDonglePosition, grid);\n\n // Do not allow stepping on the true end or true start points\n const endNode = pointToGridNode(endGlobalPoint, grid);\n if (endNode && hoveredEndElement) {\n endNode.closed = true;\n }\n const startNode = pointToGridNode(startGlobalPoint, grid);\n if (startNode && arrow.startBinding) {\n startNode.closed = true;\n }\n const dongleOverlap =\n startDongle &&\n endDongle &&\n (pointInsideBounds(startDongle.pos, dynamicAABBs[1]) ||\n pointInsideBounds(endDongle.pos, dynamicAABBs[0]));\n\n // Create path to end dongle from start dongle\n const path = astar(\n startDongle ? startDongle : startNode!,\n endDongle ? endDongle : endNode!,\n grid,\n startHeading ? startHeading : HEADING_RIGHT,\n endHeading ? endHeading : HEADING_RIGHT,\n dongleOverlap ? [] : dynamicAABBs,\n );\n\n if (path) {\n const points = path.map((node) => [\n node.pos[0],\n node.pos[1],\n ]) as GlobalPoint[];\n startDongle && points.unshift(startGlobalPoint);\n endDongle && points.push(endGlobalPoint);\n\n return points;\n }\n\n return null;\n};\n\nconst offsetFromHeading = (\n heading: Heading,\n head: number,\n side: number,\n): [number, number, number, number] => {\n switch (heading) {\n case HEADING_UP:\n return [head, side, side, side];\n case HEADING_RIGHT:\n return [side, head, side, side];\n case HEADING_DOWN:\n return [side, side, head, side];\n }\n\n return [side, side, side, head];\n};\n\n/**\n * Routing algorithm based on the A* path search algorithm.\n * @see https://www.geeksforgeeks.org/a-search-algorithm/\n *\n * Binary heap is used to optimize node lookup.\n * See {@link calculateGrid} for the grid calculation details.\n *\n * Additional modifications added due to aesthetic route reasons:\n * 1) Arrow segment direction change is penalized by specific linear constant (bendMultiplier)\n * 2) Arrow segments are not allowed to go \"backwards\", overlapping with the previous segment\n */\nconst astar = (\n start: Node,\n end: Node,\n grid: Grid,\n startHeading: Heading,\n endHeading: Heading,\n aabbs: Bounds[],\n) => {\n const bendMultiplier = m_dist(start.pos, end.pos);\n const open = new BinaryHeap<Node>((node) => node.f);\n\n open.push(start);\n\n while (open.size() > 0) {\n // Grab the lowest f(x) to process next. Heap keeps this sorted for us.\n const current = open.pop();\n\n if (!current || current.closed) {\n // Current is not passable, continue with next element\n continue;\n }\n\n // End case -- result has been found, return the traced path.\n if (current === end) {\n return pathTo(start, current);\n }\n\n // Normal case -- move current from open to closed, process each of its neighbors.\n current.closed = true;\n\n // Find all neighbors for the current node.\n const neighbors = getNeighbors(current.addr, grid);\n\n for (let i = 0; i < 4; i++) {\n const neighbor = neighbors[i];\n\n if (!neighbor || neighbor.closed) {\n // Not a valid node to process, skip to next neighbor.\n continue;\n }\n\n // Intersect\n const neighborHalfPoint = pointScaleFromOrigin(\n neighbor.pos,\n current.pos,\n 0.5,\n );\n if (\n isAnyTrue(\n ...aabbs.map((aabb) => pointInsideBounds(neighborHalfPoint, aabb)),\n )\n ) {\n continue;\n }\n\n // The g score is the shortest distance from start to current node.\n // We need to check if the path we have arrived at this neighbor is the shortest one we have seen yet.\n const neighborHeading = neighborIndexToHeading(i as 0 | 1 | 2 | 3);\n const previousDirection = current.parent\n ? vectorToHeading(vectorFromPoint(current.pos, current.parent.pos))\n : startHeading;\n\n // Do not allow going in reverse\n const reverseHeading = flipHeading(previousDirection);\n const neighborIsReverseRoute =\n compareHeading(reverseHeading, neighborHeading) ||\n (gridAddressesEqual(start.addr, neighbor.addr) &&\n compareHeading(neighborHeading, startHeading)) ||\n (gridAddressesEqual(end.addr, neighbor.addr) &&\n compareHeading(neighborHeading, endHeading));\n if (neighborIsReverseRoute) {\n continue;\n }\n\n const directionChange = previousDirection !== neighborHeading;\n const gScore =\n current.g +\n m_dist(neighbor.pos, current.pos) +\n (directionChange ? Math.pow(bendMultiplier, 3) : 0);\n\n const beenVisited = neighbor.visited;\n\n if (!beenVisited || gScore < neighbor.g) {\n const estBendCount = estimateSegmentCount(\n neighbor,\n end,\n neighborHeading,\n endHeading,\n );\n // Found an optimal (so far) path to this node. Take score for node to see how good it is.\n neighbor.visited = true;\n neighbor.parent = current;\n neighbor.h =\n m_dist(end.pos, neighbor.pos) +\n estBendCount * Math.pow(bendMultiplier, 2);\n neighbor.g = gScore;\n neighbor.f = neighbor.g + neighbor.h;\n if (!beenVisited) {\n // Pushing to heap will put it in proper place based on the 'f' value.\n open.push(neighbor);\n } else {\n // Already seen the node, but since it has been rescored we need to reorder it in the heap\n open.rescoreElement(neighbor);\n }\n }\n }\n }\n\n return null;\n};\n\nconst pathTo = (start: Node, node: Node) => {\n let curr = node;\n const path = [];\n while (curr.parent) {\n path.unshift(curr);\n curr = curr.parent;\n }\n path.unshift(start);\n\n return path;\n};\n\nconst m_dist = (a: GlobalPoint | LocalPoint, b: GlobalPoint | LocalPoint) =>\n Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1]);\n\n/**\n * Create dynamically resizing, always touching\n * bounding boxes having a minimum extent represented\n * by the given static bounds.\n */\nconst generateDynamicAABBs = (\n a: Bounds,\n b: Bounds,\n common: Bounds,\n startDifference?: [number, number, number, number],\n endDifference?: [number, number, number, number],\n disableSideHack?: boolean,\n startElementBounds?: Bounds | null,\n endElementBounds?: Bounds | null,\n): Bounds[] => {\n const startEl = startElementBounds ?? a;\n const endEl = endElementBounds ?? b;\n const [startUp, startRight, startDown, startLeft] = startDifference ?? [\n 0, 0, 0, 0,\n ];\n const [endUp, endRight, endDown, endLeft] = endDifference ?? [0, 0, 0, 0];\n\n const first = [\n a[0] > b[2]\n ? a[1] > b[3] || a[3] < b[1]\n ? Math.min((startEl[0] + endEl[2]) / 2, a[0] - startLeft)\n : (startEl[0] + endEl[2]) / 2\n : a[0] > b[0]\n ? a[0] - startLeft\n : common[0] - startLeft,\n a[1] > b[3]\n ? a[0] > b[2] || a[2] < b[0]\n ? Math.min((startEl[1] + endEl[3]) / 2, a[1] - startUp)\n : (startEl[1] + endEl[3]) / 2\n : a[1] > b[1]\n ? a[1] - startUp\n : common[1] - startUp,\n a[2] < b[0]\n ? a[1] > b[3] || a[3] < b[1]\n ? Math.max((startEl[2] + endEl[0]) / 2, a[2] + startRight)\n : (startEl[2] + endEl[0]) / 2\n : a[2] < b[2]\n ? a[2] + startRight\n : common[2] + startRight,\n a[3] < b[1]\n ? a[0] > b[2] || a[2] < b[0]\n ? Math.max((startEl[3] + endEl[1]) / 2, a[3] + startDown)\n : (startEl[3] + endEl[1]) / 2\n : a[3] < b[3]\n ? a[3] + startDown\n : common[3] + startDown,\n ] as Bounds;\n const second = [\n b[0] > a[2]\n ? b[1] > a[3] || b[3] < a[1]\n ? Math.min((endEl[0] + startEl[2]) / 2, b[0] - endLeft)\n : (endEl[0] + startEl[2]) / 2\n : b[0] > a[0]\n ? b[0] - endLeft\n : common[0] - endLeft,\n b[1] > a[3]\n ? b[0] > a[2] || b[2] < a[0]\n ? Math.min((endEl[1] + startEl[3]) / 2, b[1] - endUp)\n : (endEl[1] + startEl[3]) / 2\n : b[1] > a[1]\n ? b[1] - endUp\n : common[1] - endUp,\n b[2] < a[0]\n ? b[1] > a[3] || b[3] < a[1]\n ? Math.max((endEl[2] + startEl[0]) / 2, b[2] + endRight)\n : (endEl[2] + startEl[0]) / 2\n : b[2] < a[2]\n ? b[2] + endRight\n : common[2] + endRight,\n b[3] < a[1]\n ? b[0] > a[2] || b[2] < a[0]\n ? Math.max((endEl[3] + startEl[1]) / 2, b[3] + endDown)\n : (endEl[3] + startEl[1]) / 2\n : b[3] < a[3]\n ? b[3] + endDown\n : common[3] + endDown,\n ] as Bounds;\n\n const c = commonAABB([first, second]);\n if (\n !disableSideHack &&\n first[2] - first[0] + second[2] - second[0] > c[2] - c[0] + 0.00000000001 &&\n first[3] - first[1] + second[3] - second[1] > c[3] - c[1] + 0.00000000001\n ) {\n const [endCenterX, endCenterY] = [\n (second[0] + second[2]) / 2,\n (second[1] + second[3]) / 2,\n ];\n if (b[0] > a[2] && a[1] > b[3]) {\n // BOTTOM LEFT\n const cX = first[2] + (second[0] - first[2]) / 2;\n const cY = second[3] + (first[1] - second[3]) / 2;\n\n if (\n vectorCross(\n vector(a[2] - endCenterX, a[1] - endCenterY),\n vector(a[0] - endCenterX, a[3] - endCenterY),\n ) > 0\n ) {\n return [\n [first[0], first[1], cX, first[3]],\n [cX, second[1], second[2], second[3]],\n ];\n }\n\n return [\n [first[0], cY, first[2], first[3]],\n [second[0], second[1], second[2], cY],\n ];\n } else if (a[2] < b[0] && a[3] < b[1]) {\n // TOP LEFT\n const cX = first[2] + (second[0] - first[2]) / 2;\n const cY = first[3] + (second[1] - first[3]) / 2;\n\n if (\n vectorCross(\n vector(a[0] - endCenterX, a[1] - endCenterY),\n vector(a[2] - endCenterX, a[3] - endCenterY),\n ) > 0\n ) {\n return [\n [first[0], first[1], first[2], cY],\n [second[0], cY, second[2], second[3]],\n ];\n }\n\n return [\n [first[0], first[1], cX, first[3]],\n [cX, second[1], second[2], second[3]],\n ];\n } else if (a[0] > b[2] && a[3] < b[1]) {\n // TOP RIGHT\n const cX = second[2] + (first[0] - second[2]) / 2;\n const cY = first[3] + (second[1] - first[3]) / 2;\n\n if (\n vectorCross(\n vector(a[2] - endCenterX, a[1] - endCenterY),\n vector(a[0] - endCenterX, a[3] - endCenterY),\n ) > 0\n ) {\n return [\n [cX, first[1], first[2], first[3]],\n [second[0], second[1], cX, second[3]],\n ];\n }\n\n return [\n [first[0], first[1], first[2], cY],\n [second[0], cY, second[2], second[3]],\n ];\n } else if (a[0] > b[2] && a[1] > b[3]) {\n // BOTTOM RIGHT\n const cX = second[2] + (first[0] - second[2]) / 2;\n const cY = second[3] + (first[1] - second[3]) / 2;\n\n if (\n vectorCross(\n vector(a[0] - endCenterX, a[1] - endCenterY),\n vector(a[2] - endCenterX, a[3] - endCenterY),\n ) > 0\n ) {\n return [\n [cX, first[1], first[2], first[3]],\n [second[0], second[1], cX, second[3]],\n ];\n }\n\n return [\n [first[0], cY, first[2], first[3]],\n [second[0], second[1], second[2], cY],\n ];\n }\n }\n\n return [first, second];\n};\n\n/**\n * Calculates the grid which is used as nodes at\n * the grid line intersections by the A* algorithm.\n *\n * NOTE: This is not a uniform grid. It is built at\n * various intersections of bounding boxes.\n */\nconst calculateGrid = (\n aabbs: Bounds[],\n start: GlobalPoint,\n startHeading: Heading,\n end: GlobalPoint,\n endHeading: Heading,\n common: Bounds,\n): Grid => {\n const horizontal = new Set<number>();\n const vertical = new Set<number>();\n\n if (startHeading === HEADING_LEFT || startHeading === HEADING_RIGHT) {\n vertical.add(start[1]);\n } else {\n horizontal.add(start[0]);\n }\n if (endHeading === HEADING_LEFT || endHeading === HEADING_RIGHT) {\n vertical.add(end[1]);\n } else {\n horizontal.add(end[0]);\n }\n\n aabbs.forEach((aabb) => {\n horizontal.add(aabb[0]);\n horizontal.add(aabb[2]);\n vertical.add(aabb[1]);\n vertical.add(aabb[3]);\n });\n\n horizontal.add(common[0]);\n horizontal.add(common[2]);\n vertical.add(common[1]);\n vertical.add(common[3]);\n\n const _vertical = Array.from(vertical).sort((a, b) => a - b);\n const _horizontal = Array.from(horizontal).sort((a, b) => a - b);\n\n return {\n row: _vertical.length,\n col: _horizontal.length,\n data: _vertical.flatMap((y, row) =>\n _horizontal.map(\n (x, col): Node => ({\n f: 0,\n g: 0,\n h: 0,\n closed: false,\n visited: false,\n parent: null,\n addr: [col, row] as GridAddress,\n pos: [x, y] as GlobalPoint,\n }),\n ),\n ),\n };\n};\n\nconst getDonglePosition = (\n bounds: Bounds,\n heading: Heading,\n p: GlobalPoint,\n): GlobalPoint => {\n switch (heading) {\n case HEADING_UP:\n return pointFrom(p[0], bounds[1]);\n case HEADING_RIGHT:\n return pointFrom(bounds[2], p[1]);\n case HEADING_DOWN:\n return pointFrom(p[0], bounds[3]);\n }\n return pointFrom(bounds[0], p[1]);\n};\n\nconst estimateSegmentCount = (\n start: Node,\n end: Node,\n startHeading: Heading,\n endHeading: Heading,\n) => {\n if (endHeading === HEADING_RIGHT) {\n switch (startHeading) {\n case HEADING_RIGHT: {\n if (start.pos[0] >= end.pos[0]) {\n return 4;\n }\n if (start.pos[1] === end.pos[1]) {\n return 0;\n }\n return 2;\n }\n case HEADING_UP:\n if (start.pos[1] > end.pos[1] && start.pos[0] < end.pos[0]) {\n return 1;\n }\n return 3;\n case HEADING_DOWN:\n if (start.pos[1] < end.pos[1] && start.pos[0] < end.pos[0]) {\n return 1;\n }\n return 3;\n case HEADING_LEFT:\n if (start.pos[1] === end.pos[1]) {\n return 4;\n }\n return 2;\n }\n } else if (endHeading === HEADING_LEFT) {\n switch (startHeading) {\n case HEADING_RIGHT:\n if (start.pos[1] === end.pos[1]) {\n return 4;\n }\n return 2;\n case HEADING_UP:\n if (start.pos[1] > end.pos[1] && start.pos[0] > end.pos[0]) {\n return 1;\n }\n return 3;\n case HEADING_DOWN:\n if (start.pos[1] < end.pos[1] && start.pos[0] > end.pos[0]) {\n return 1;\n }\n return 3;\n case HEADING_LEFT:\n if (start.pos[0] <= end.pos[0]) {\n return 4;\n }\n if (start.pos[1] === end.pos[1]) {\n return 0;\n }\n return 2;\n }\n } else if (endHeading === HEADING_UP) {\n switch (startHeading) {\n case HEADING_RIGHT:\n if (start.pos[1] > end.pos[1] && start.pos[0] < end.pos[0]) {\n return 1;\n }\n return 3;\n case HEADING_UP:\n if (start.pos[1] >= end.pos[1]) {\n return 4;\n }\n if (start.pos[0] === end.pos[0]) {\n return 0;\n }\n return 2;\n case HEADING_DOWN:\n if (start.pos[0] === end.pos[0]) {\n return 4;\n }\n return 2;\n case HEADING_LEFT:\n if (start.pos[1] > end.pos[1] && start.pos[0] > end.pos[0]) {\n return 1;\n }\n return 3;\n }\n } else if (endHeading === HEADING_DOWN) {\n switch (startHeading) {\n case HEADING_RIGHT:\n if (start.pos[1] < end.pos[1] && start.pos[0] < end.pos[0]) {\n return 1;\n }\n return 3;\n case HEADING_UP:\n if (start.pos[0] === end.pos[0]) {\n return 4;\n }\n return 2;\n case HEADING_DOWN:\n if (start.pos[1] <= end.pos[1]) {\n return 4;\n }\n if (start.pos[0] === end.pos[0]) {\n return 0;\n }\n return 2;\n case HEADING_LEFT:\n if (start.pos[1] < end.pos[1] && start.pos[0] > end.pos[0]) {\n return 1;\n }\n return 3;\n }\n }\n return 0;\n};\n\n/**\n * Get neighboring points for a gived grid address\n */\nconst getNeighbors = ([col, row]: [number, number], grid: Grid) =>\n [\n gridNodeFromAddr([col, row - 1], grid),\n gridNodeFromAddr([col + 1, row], grid),\n gridNodeFromAddr([col, row + 1], grid),\n gridNodeFromAddr([col - 1, row], grid),\n ] as [Node | null, Node | null, Node | null, Node | null];\n\nconst gridNodeFromAddr = (\n [col, row]: [col: number, row: number],\n grid: Grid,\n): Node | null => {\n if (col < 0 || col >= grid.col || row < 0 || row >= grid.row) {\n return null;\n }\n\n return grid.data[row * grid.col + col] ?? null;\n};\n\n/**\n * Get node for global point on canvas (if exists)\n */\nconst pointToGridNode = (point: GlobalPoint, grid: Grid): Node | null => {\n for (let col = 0; col < grid.col; col++) {\n for (let row = 0; row < grid.row; row++) {\n const candidate = gridNodeFromAddr([col, row], grid);\n if (\n candidate &&\n point[0] === candidate.pos[0] &&\n point[1] === candidate.pos[1]\n ) {\n return candidate;\n }\n }\n }\n\n return null;\n};\n\nconst commonAABB = (aabbs: Bounds[]): Bounds => [\n Math.min(...aabbs.map((aabb) => aabb[0])),\n Math.min(...aabbs.map((aabb) => aabb[1])),\n Math.max(...aabbs.map((aabb) => aabb[2])),\n Math.max(...aabbs.map((aabb) => aabb[3])),\n];\n\n/// #region Utils\n\nconst getBindableElementForId = (\n id: string,\n elementsMap: ElementsMap,\n): ExcalidrawBindableElement | null => {\n const element = elementsMap.get(id);\n if (element && isBindableElement(element)) {\n return element;\n }\n\n return null;\n};\n\nconst normalizeArrowElementUpdate = (\n global: GlobalPoint[],\n nextFixedSegments: readonly FixedSegment[] | null,\n startIsSpecial?: ExcalidrawElbowArrowElement[\"startIsSpecial\"],\n endIsSpecial?: ExcalidrawElbowArrowElement[\"startIsSpecial\"],\n): {\n points: LocalPoint[];\n x: number;\n y: number;\n width: number;\n height: number;\n fixedSegments: readonly FixedSegment[] | null;\n startIsSpecial?: ExcalidrawElbowArrowElement[\"startIsSpecial\"];\n endIsSpecial?: ExcalidrawElbowArrowElement[\"startIsSpecial\"];\n} => {\n const offsetX = global[0][0];\n const offsetY = global[0][1];\n\n let points = global.map((p) =>\n pointTranslate<GlobalPoint, LocalPoint>(\n p,\n vectorScale(vectorFromPoint(global[0]), -1),\n ),\n );\n\n // NOTE (mtolmacs): This is a temporary check to see if the normalization\n // creates an overly large arrow. This should be removed once we have an answer.\n if (\n offsetX < -MAX_POS ||\n offsetX > MAX_POS ||\n offsetY < -MAX_POS ||\n offsetY > MAX_POS ||\n offsetX + points[points.length - 1][0] < -MAX_POS ||\n offsetY + points[points.length - 1][0] > MAX_POS ||\n offsetX + points[points.length - 1][1] < -MAX_POS ||\n offsetY + points[points.length - 1][1] > MAX_POS\n ) {\n console.error(\n \"Elbow arrow normalization is outside reasonable bounds (> 1e6)\",\n {\n x: offsetX,\n y: offsetY,\n points,\n ...getSizeFromPoints(points),\n },\n );\n }\n\n points = points.map(([x, y]) =>\n pointFrom<LocalPoint>(clamp(x, -1e6, 1e6), clamp(y, -1e6, 1e6)),\n );\n\n return {\n points,\n x: clamp(offsetX, -1e6, 1e6),\n y: clamp(offsetY, -1e6, 1e6),\n fixedSegments:\n (nextFixedSegments?.length ?? 0) > 0 ? nextFixedSegments : null,\n ...getSizeFromPoints(points),\n startIsSpecial,\n endIsSpecial,\n };\n};\n\nconst getElbowArrowCornerPoints = (points: GlobalPoint[]): GlobalPoint[] => {\n if (points.length > 1) {\n let previousHorizontal =\n Math.abs(points[0][1] - points[1][1]) <\n Math.abs(points[0][0] - points[1][0]);\n\n return points.filter((p, idx) => {\n // The very first and last points are always kept\n if (idx === 0 || idx === points.length - 1) {\n return true;\n }\n\n const next = points[idx + 1];\n const nextHorizontal =\n Math.abs(p[1] - next[1]) < Math.abs(p[0] - next[0]);\n if (previousHorizontal === nextHorizontal) {\n previousHorizontal = nextHorizontal;\n return false;\n }\n\n previousHorizontal = nextHorizontal;\n return true;\n });\n }\n\n return points;\n};\n\nconst removeElbowArrowShortSegments = (\n points: GlobalPoint[],\n): GlobalPoint[] => {\n if (points.length >= 4) {\n return points.filter((p, idx) => {\n if (idx === 0 || idx === points.length - 1) {\n return true;\n }\n\n const prev = points[idx - 1];\n const prevDist = pointDistance(prev, p);\n return prevDist > DEDUP_TRESHOLD;\n });\n }\n\n return points;\n};\n\nconst neighborIndexToHeading = (idx: number): Heading => {\n switch (idx) {\n case 0:\n return HEADING_UP;\n case 1:\n return HEADING_RIGHT;\n case 2:\n return HEADING_DOWN;\n }\n return HEADING_LEFT;\n};\n\nconst getGlobalPoint = (\n arrow: ExcalidrawElbowArrowElement,\n startOrEnd: \"start\" | \"end\",\n fixedPointRatio: [number, number] | undefined | null,\n initialPoint: GlobalPoint,\n boundElement?: ExcalidrawBindableElement | null,\n hoveredElement?: ExcalidrawBindableElement | null,\n isDragging?: boolean,\n): GlobalPoint => {\n if (isDragging) {\n if (hoveredElement) {\n const snapPoint = bindPointToSnapToElementOutline(\n arrow,\n hoveredElement,\n startOrEnd,\n );\n\n return snapToMid(hoveredElement, snapPoint);\n }\n\n return initialPoint;\n }\n\n if (boundElement) {\n const fixedGlobalPoint = getGlobalFixedPointForBindableElement(\n fixedPointRatio || [0, 0],\n boundElement,\n );\n\n // NOTE: Resize scales the binding position point too, so we need to update it\n return Math.abs(\n distanceToBindableElement(boundElement, fixedGlobalPoint) -\n FIXED_BINDING_DISTANCE,\n ) > 0.01\n ? bindPointToSnapToElementOutline(arrow, boundElement, startOrEnd)\n : fixedGlobalPoint;\n }\n\n return initialPoint;\n};\n\nconst getBindPointHeading = (\n p: GlobalPoint,\n otherPoint: GlobalPoint,\n elementsMap: NonDeletedSceneElementsMap | SceneElementsMap,\n hoveredElement: ExcalidrawBindableElement | null | undefined,\n origPoint: GlobalPoint,\n): Heading =>\n getHeadingForElbowArrowSnap(\n p,\n otherPoint,\n hoveredElement,\n hoveredElement &&\n aabbForElement(\n hoveredElement,\n Array(4).fill(distanceToBindableElement(hoveredElement, p)) as [\n number,\n number,\n number,\n number,\n ],\n ),\n elementsMap,\n origPoint,\n );\n\nconst getHoveredElements = (\n origStartGlobalPoint: GlobalPoint,\n origEndGlobalPoint: GlobalPoint,\n elementsMap: NonDeletedSceneElementsMap | SceneElementsMap,\n zoom?: AppState[\"zoom\"],\n) => {\n // TODO: Might be a performance bottleneck and the Map type\n // remembers the insertion order anyway...\n const nonDeletedSceneElementsMap = toBrandedType<NonDeletedSceneElementsMap>(\n new Map([...elementsMap].filter((el) => !el[1].isDeleted)),\n );\n const elements = Array.from(elementsMap.values());\n return [\n getHoveredElementForBinding(\n tupleToCoors(origStartGlobalPoint),\n elements,\n nonDeletedSceneElementsMap,\n zoom,\n true,\n true,\n ),\n getHoveredElementForBinding(\n tupleToCoors(origEndGlobalPoint),\n elements,\n nonDeletedSceneElementsMap,\n zoom,\n true,\n true,\n ),\n ];\n};\n\nconst gridAddressesEqual = (a: GridAddress, b: GridAddress): boolean =>\n a[0] === b[0] && a[1] === b[1];\n\nconst validateElbowPoints = <P extends GlobalPoint | LocalPoint>(\n points: readonly P[],\n tolerance: number = DEDUP_TRESHOLD,\n) =>\n points\n .slice(1)\n .map(\n (p, i) =>\n Math.abs(p[0] - points[i][0]) < tolerance ||\n Math.abs(p[1] - points[i][1]) < tolerance,\n )\n .every(Boolean);\n", "import type { ExcalidrawElement, SceneElementsMap } from \"./types\";\nimport Scene from \"../scene/Scene\";\nimport { getSizeFromPoints } from \"../points\";\nimport { randomInteger } from \"../random\";\nimport { getUpdatedTimestamp, toBrandedType } from \"../utils\";\nimport type { Mutable } from \"../utility-types\";\nimport { ShapeCache } from \"../scene/ShapeCache\";\nimport { isElbowArrow } from \"./typeChecks\";\nimport { updateElbowArrowPoints } from \"./elbowArrow\";\nimport type { Radians } from \"@excalidraw/math\";\n\nexport type ElementUpdate<TElement extends ExcalidrawElement> = Omit<\n Partial<TElement>,\n \"id\" | \"version\" | \"versionNonce\" | \"updated\"\n>;\n\n// This function tracks updates of text elements for the purposes for collaboration.\n// The version is used to compare updates when more than one user is working in\n// the same drawing. Note: this will trigger the component to update. Make sure you\n// are calling it either from a React event handler or within unstable_batchedUpdates().\nexport const mutateElement = <TElement extends Mutable<ExcalidrawElement>>(\n element: TElement,\n updates: ElementUpdate<TElement>,\n informMutation = true,\n options?: {\n // Currently only for elbow arrows.\n // If true, the elbow arrow tries to bind to the nearest element. If false\n // it tries to keep the same bound element, if any.\n isDragging?: boolean;\n },\n): TElement => {\n let didChange = false;\n\n // casting to any because can't use `in` operator\n // (see https://github.com/microsoft/TypeScript/issues/21732)\n const { points, fixedSegments, fileId, startBinding, endBinding } =\n updates as any;\n\n if (\n isElbowArrow(element) &&\n (Object.keys(updates).length === 0 || // normalization case\n typeof points !== \"undefined\" || // repositioning\n typeof fixedSegments !== \"undefined\" || // segment fixing\n typeof startBinding !== \"undefined\" ||\n typeof endBinding !== \"undefined\") // manual binding to element\n ) {\n const elementsMap = toBrandedType<SceneElementsMap>(\n Scene.getScene(element)?.getNonDeletedElementsMap() ?? new Map(),\n );\n\n updates = {\n ...updates,\n angle: 0 as Radians,\n ...updateElbowArrowPoints(\n {\n ...element,\n x: updates.x || element.x,\n y: updates.y || element.y,\n },\n elementsMap,\n {\n fixedSegments,\n points,\n startBinding,\n endBinding,\n },\n {\n isDragging: options?.isDragging,\n },\n ),\n };\n } else if (typeof points !== \"undefined\") {\n updates = { ...getSizeFromPoints(points), ...updates };\n }\n\n for (const key in updates) {\n const value = (updates as any)[key];\n if (typeof value !== \"undefined\") {\n if (\n (element as any)[key] === value &&\n // if object, always update because its attrs could have changed\n // (except for specific keys we handle below)\n (typeof value !== \"object\" ||\n value === null ||\n key === \"groupIds\" ||\n key === \"scale\")\n ) {\n continue;\n }\n\n if (key === \"scale\") {\n const prevScale = (element as any)[key];\n const nextScale = value;\n if (prevScale[0] === nextScale[0] && prevScale[1] === nextScale[1]) {\n continue;\n }\n } else if (key === \"points\") {\n const prevPoints = (element as any)[key];\n const nextPoints = value;\n if (prevPoints.length === nextPoints.length) {\n let didChangePoints = false;\n let index = prevPoints.length;\n while (--index) {\n const prevPoint = prevPoints[index];\n const nextPoint = nextPoints[index];\n if (\n prevPoint[0] !== nextPoint[0] ||\n prevPoint[1] !== nextPoint[1]\n ) {\n didChangePoints = true;\n break;\n }\n }\n if (!didChangePoints) {\n continue;\n }\n }\n }\n\n (element as any)[key] = value;\n didChange = true;\n }\n }\n\n if (!didChange) {\n return element;\n }\n\n if (\n typeof updates.height !== \"undefined\" ||\n typeof updates.width !== \"undefined\" ||\n typeof fileId != \"undefined\" ||\n typeof points !== \"undefined\"\n ) {\n ShapeCache.delete(element);\n }\n\n element.version++;\n element.versionNonce = randomInteger();\n element.updated = getUpdatedTimestamp();\n\n if (informMutation) {\n Scene.getScene(element)?.triggerUpdate();\n }\n\n return element;\n};\n\nexport const newElementWith = <TElement extends ExcalidrawElement>(\n element: TElement,\n updates: ElementUpdate<TElement>,\n /** pass `true` to always regenerate */\n force = false,\n): TElement => {\n let didChange = false;\n for (const key in updates) {\n const value = (updates as any)[key];\n if (typeof value !== \"undefined\") {\n if (\n (element as any)[key] === value &&\n // if object, always update because its attrs could have changed\n (typeof value !== \"object\" || value === null)\n ) {\n continue;\n }\n didChange = true;\n }\n }\n\n if (!didChange && !force) {\n return element;\n }\n\n return {\n ...element,\n ...updates,\n updated: getUpdatedTimestamp(),\n version: element.version + 1,\n versionNonce: randomInteger(),\n };\n};\n\n/**\n * Mutates element, bumping `version`, `versionNonce`, and `updated`.\n *\n * NOTE: does not trigger re-render.\n */\nexport const bumpVersion = <T extends Mutable<ExcalidrawElement>>(\n element: T,\n version?: ExcalidrawElement[\"version\"],\n) => {\n element.version = (version ?? element.version) + 1;\n element.versionNonce = randomInteger();\n element.updated = getUpdatedTimestamp();\n return element;\n};\n", "import type { ElementsMap, ExcalidrawElement } from \"./types\";\nimport { mutateElement } from \"./mutateElement\";\nimport { isFreeDrawElement, isLinearElement } from \"./typeChecks\";\nimport { SHIFT_LOCKING_ANGLE } from \"../constants\";\nimport type { AppState, Offsets, Zoom } from \"../types\";\nimport { getCommonBounds, getElementBounds } from \"./bounds\";\nimport { viewportCoordsToSceneCoords } from \"../utils\";\n\n// TODO: remove invisible elements consistently actions, so that invisible elements are not recorded by the store, exported, broadcasted or persisted\n// - perhaps could be as part of a standalone 'cleanup' action, in addition to 'finalize'\n// - could also be part of `_clearElements`\nexport const isInvisiblySmallElement = (\n element: ExcalidrawElement,\n): boolean => {\n if (isLinearElement(element) || isFreeDrawElement(element)) {\n return element.points.length < 2;\n }\n return element.width === 0 && element.height === 0;\n};\n\nexport const isElementInViewport = (\n element: ExcalidrawElement,\n width: number,\n height: number,\n viewTransformations: {\n zoom: Zoom;\n offsetLeft: number;\n offsetTop: number;\n scrollX: number;\n scrollY: number;\n },\n elementsMap: ElementsMap,\n) => {\n const [x1, y1, x2, y2] = getElementBounds(element, elementsMap); // scene coordinates\n const topLeftSceneCoords = viewportCoordsToSceneCoords(\n {\n clientX: viewTransformations.offsetLeft,\n clientY: viewTransformations.offsetTop,\n },\n viewTransformations,\n );\n const bottomRightSceneCoords = viewportCoordsToSceneCoords(\n {\n clientX: viewTransformations.offsetLeft + width,\n clientY: viewTransformations.offsetTop + height,\n },\n viewTransformations,\n );\n\n return (\n topLeftSceneCoords.x <= x2 &&\n topLeftSceneCoords.y <= y2 &&\n bottomRightSceneCoords.x >= x1 &&\n bottomRightSceneCoords.y >= y1\n );\n};\n\nexport const isElementCompletelyInViewport = (\n elements: ExcalidrawElement[],\n width: number,\n height: number,\n viewTransformations: {\n zoom: Zoom;\n offsetLeft: number;\n offsetTop: number;\n scrollX: number;\n scrollY: number;\n },\n elementsMap: ElementsMap,\n padding?: Offsets,\n) => {\n const [x1, y1, x2, y2] = getCommonBounds(elements, elementsMap); // scene coordinates\n const topLeftSceneCoords = viewportCoordsToSceneCoords(\n {\n clientX: viewTransformations.offsetLeft + (padding?.left || 0),\n clientY: viewTransformations.offsetTop + (padding?.top || 0),\n },\n viewTransformations,\n );\n const bottomRightSceneCoords = viewportCoordsToSceneCoords(\n {\n clientX: viewTransformations.offsetLeft + width - (padding?.right || 0),\n clientY: viewTransformations.offsetTop + height - (padding?.bottom || 0),\n },\n viewTransformations,\n );\n\n return (\n x1 >= topLeftSceneCoords.x &&\n y1 >= topLeftSceneCoords.y &&\n x2 <= bottomRightSceneCoords.x &&\n y2 <= bottomRightSceneCoords.y\n );\n};\n\n/**\n * Makes a perfect shape or diagonal/horizontal/vertical line\n */\nexport const getPerfectElementSize = (\n elementType: AppState[\"activeTool\"][\"type\"],\n width: number,\n height: number,\n): { width: number; height: number } => {\n const absWidth = Math.abs(width);\n const absHeight = Math.abs(height);\n\n if (\n elementType === \"line\" ||\n elementType === \"arrow\" ||\n elementType === \"freedraw\"\n ) {\n const lockedAngle =\n Math.round(Math.atan(absHeight / absWidth) / SHIFT_LOCKING_ANGLE) *\n SHIFT_LOCKING_ANGLE;\n if (lockedAngle === 0) {\n height = 0;\n } else if (lockedAngle === Math.PI / 2) {\n width = 0;\n } else {\n height = absWidth * Math.tan(lockedAngle) * Math.sign(height) || height;\n }\n } else if (elementType !== \"selection\") {\n height = absWidth * Math.sign(height);\n }\n return { width, height };\n};\n\nexport const getLockedLinearCursorAlignSize = (\n originX: number,\n originY: number,\n x: number,\n y: number,\n) => {\n let width = x - originX;\n let height = y - originY;\n\n const lockedAngle =\n Math.round(Math.atan(height / width) / SHIFT_LOCKING_ANGLE) *\n SHIFT_LOCKING_ANGLE;\n\n if (lockedAngle === 0) {\n height = 0;\n } else if (lockedAngle === Math.PI / 2) {\n width = 0;\n } else {\n // locked angle line, y = mx + b => mx - y + b = 0\n const a1 = Math.tan(lockedAngle);\n const b1 = -1;\n const c1 = originY - a1 * originX;\n\n // line through cursor, perpendicular to locked angle line\n const a2 = -1 / a1;\n const b2 = -1;\n const c2 = y - a2 * x;\n\n // intersection of the two lines above\n const intersectX = (b1 * c2 - b2 * c1) / (a1 * b2 - a2 * b1);\n const intersectY = (c1 * a2 - c2 * a1) / (a1 * b2 - a2 * b1);\n\n // delta\n width = intersectX - originX;\n height = intersectY - originY;\n }\n\n return { width, height };\n};\n\nexport const resizePerfectLineForNWHandler = (\n element: ExcalidrawElement,\n x: number,\n y: number,\n) => {\n const anchorX = element.x + element.width;\n const anchorY = element.y + element.height;\n const distanceToAnchorX = x - anchorX;\n const distanceToAnchorY = y - anchorY;\n if (Math.abs(distanceToAnchorX) < Math.abs(distanceToAnchorY) / 2) {\n mutateElement(element, {\n x: anchorX,\n width: 0,\n y,\n height: -distanceToAnchorY,\n });\n } else if (Math.abs(distanceToAnchorY) < Math.abs(element.width) / 2) {\n mutateElement(element, {\n y: anchorY,\n height: 0,\n });\n } else {\n const nextHeight =\n Math.sign(distanceToAnchorY) *\n Math.sign(distanceToAnchorX) *\n element.width;\n mutateElement(element, {\n x,\n y: anchorY - nextHeight,\n width: -distanceToAnchorX,\n height: nextHeight,\n });\n }\n};\n\nexport const getNormalizedDimensions = (\n element: Pick<ExcalidrawElement, \"width\" | \"height\" | \"x\" | \"y\">,\n): {\n width: ExcalidrawElement[\"width\"];\n height: ExcalidrawElement[\"height\"];\n x: ExcalidrawElement[\"x\"];\n y: ExcalidrawElement[\"y\"];\n} => {\n const ret = {\n width: element.width,\n height: element.height,\n x: element.x,\n y: element.y,\n };\n\n if (element.width < 0) {\n const nextWidth = Math.abs(element.width);\n ret.width = nextWidth;\n ret.x = element.x - nextWidth;\n }\n\n if (element.height < 0) {\n const nextHeight = Math.abs(element.height);\n ret.height = nextHeight;\n ret.y = element.y - nextHeight;\n }\n\n return ret;\n};\n", "import type {\n ElementsMap,\n ExcalidrawElement,\n NonDeletedExcalidrawElement,\n PointerType,\n} from \"./types\";\n\nimport type { Bounds } from \"./bounds\";\nimport { getElementAbsoluteCoords } from \"./bounds\";\nimport type { Device, InteractiveCanvasAppState, Zoom } from \"../types\";\nimport {\n isElbowArrow,\n isFrameLikeElement,\n isImageElement,\n isLinearElement,\n} from \"./typeChecks\";\nimport {\n DEFAULT_TRANSFORM_HANDLE_SPACING,\n isAndroid,\n isIOS,\n} from \"../constants\";\nimport type { Radians } from \"@excalidraw/math\";\nimport { pointFrom, pointRotateRads } from \"@excalidraw/math\";\n\nexport type TransformHandleDirection =\n | \"n\"\n | \"s\"\n | \"w\"\n | \"e\"\n | \"nw\"\n | \"ne\"\n | \"sw\"\n | \"se\";\n\nexport type TransformHandleType = TransformHandleDirection | \"rotation\";\n\nexport type TransformHandle = Bounds;\nexport type TransformHandles = Partial<{\n [T in TransformHandleType]: TransformHandle;\n}>;\nexport type MaybeTransformHandleType = TransformHandleType | false;\n\nconst transformHandleSizes: { [k in PointerType]: number } = {\n mouse: 8,\n pen: 16,\n touch: 28,\n};\n\nconst ROTATION_RESIZE_HANDLE_GAP = 16;\n\nexport const DEFAULT_OMIT_SIDES = {\n e: true,\n s: true,\n n: true,\n w: true,\n};\n\nexport const OMIT_SIDES_FOR_MULTIPLE_ELEMENTS = {\n e: true,\n s: true,\n n: true,\n w: true,\n};\n\nexport const OMIT_SIDES_FOR_FRAME = {\n e: true,\n s: true,\n n: true,\n w: true,\n rotation: true,\n};\n\nconst OMIT_SIDES_FOR_LINE_SLASH = {\n e: true,\n s: true,\n n: true,\n w: true,\n nw: true,\n se: true,\n};\n\nconst OMIT_SIDES_FOR_LINE_BACKSLASH = {\n e: true,\n s: true,\n n: true,\n w: true,\n};\n\nconst generateTransformHandle = (\n x: number,\n y: number,\n width: number,\n height: number,\n cx: number,\n cy: number,\n angle: Radians,\n): TransformHandle => {\n const [xx, yy] = pointRotateRads(\n pointFrom(x + width / 2, y + height / 2),\n pointFrom(cx, cy),\n angle,\n );\n return [xx - width / 2, yy - height / 2, width, height];\n};\n\nexport const canResizeFromSides = (device: Device) => {\n if (device.viewport.isMobile) {\n return false;\n }\n\n if (device.isTouchScreen && (isAndroid || isIOS)) {\n return false;\n }\n\n return true;\n};\n\nexport const getOmitSidesForDevice = (device: Device) => {\n if (canResizeFromSides(device)) {\n return DEFAULT_OMIT_SIDES;\n }\n\n return {};\n};\n\nexport const getTransformHandlesFromCoords = (\n [x1, y1, x2, y2, cx, cy]: [number, number, number, number, number, number],\n angle: Radians,\n zoom: Zoom,\n pointerType: PointerType,\n omitSides: { [T in TransformHandleType]?: boolean } = {},\n margin = 4,\n spacing = DEFAULT_TRANSFORM_HANDLE_SPACING,\n): TransformHandles => {\n const size = transformHandleSizes[pointerType];\n const handleWidth = size / zoom.value;\n const handleHeight = size / zoom.value;\n\n const handleMarginX = size / zoom.value;\n const handleMarginY = size / zoom.value;\n\n const width = x2 - x1;\n const height = y2 - y1;\n const dashedLineMargin = margin / zoom.value;\n const centeringOffset = (size - spacing * 2) / (2 * zoom.value);\n\n const transformHandles: TransformHandles = {\n nw: omitSides.nw\n ? undefined\n : generateTransformHandle(\n x1 - dashedLineMargin - handleMarginX + centeringOffset,\n y1 - dashedLineMargin - handleMarginY + centeringOffset,\n handleWidth,\n handleHeight,\n cx,\n cy,\n angle,\n ),\n ne: omitSides.ne\n ? undefined\n : generateTransformHandle(\n x2 + dashedLineMargin - centeringOffset,\n y1 - dashedLineMargin - handleMarginY + centeringOffset,\n handleWidth,\n handleHeight,\n cx,\n cy,\n angle,\n ),\n sw: omitSides.sw\n ? undefined\n : generateTransformHandle(\n x1 - dashedLineMargin - handleMarginX + centeringOffset,\n y2 + dashedLineMargin - centeringOffset,\n handleWidth,\n handleHeight,\n cx,\n cy,\n angle,\n ),\n se: omitSides.se\n ? undefined\n : generateTransformHandle(\n x2 + dashedLineMargin - centeringOffset,\n y2 + dashedLineMargin - centeringOffset,\n handleWidth,\n handleHeight,\n cx,\n cy,\n angle,\n ),\n rotation: omitSides.rotation\n ? undefined\n : generateTransformHandle(\n x1 + width / 2 - handleWidth / 2,\n y1 -\n dashedLineMargin -\n handleMarginY +\n centeringOffset -\n ROTATION_RESIZE_HANDLE_GAP / zoom.value,\n handleWidth,\n handleHeight,\n cx,\n cy,\n angle,\n ),\n };\n\n // We only want to show height handles (all cardinal directions) above a certain size\n // Note: we render using \"mouse\" size so we should also use \"mouse\" size for this check\n const minimumSizeForEightHandles =\n (5 * transformHandleSizes.mouse) / zoom.value;\n if (Math.abs(width) > minimumSizeForEightHandles) {\n if (!omitSides.n) {\n transformHandles.n = generateTransformHandle(\n x1 + width / 2 - handleWidth / 2,\n y1 - dashedLineMargin - handleMarginY + centeringOffset,\n handleWidth,\n handleHeight,\n cx,\n cy,\n angle,\n );\n }\n if (!omitSides.s) {\n transformHandles.s = generateTransformHandle(\n x1 + width / 2 - handleWidth / 2,\n y2 + dashedLineMargin - centeringOffset,\n handleWidth,\n handleHeight,\n cx,\n cy,\n angle,\n );\n }\n }\n if (Math.abs(height) > minimumSizeForEightHandles) {\n if (!omitSides.w) {\n transformHandles.w = generateTransformHandle(\n x1 - dashedLineMargin - handleMarginX + centeringOffset,\n y1 + height / 2 - handleHeight / 2,\n handleWidth,\n handleHeight,\n cx,\n cy,\n angle,\n );\n }\n if (!omitSides.e) {\n transformHandles.e = generateTransformHandle(\n x2 + dashedLineMargin - centeringOffset,\n y1 + height / 2 - handleHeight / 2,\n handleWidth,\n handleHeight,\n cx,\n cy,\n angle,\n );\n }\n }\n\n return transformHandles;\n};\n\nexport const getTransformHandles = (\n element: ExcalidrawElement,\n zoom: Zoom,\n elementsMap: ElementsMap,\n pointerType: PointerType = \"mouse\",\n omitSides: { [T in TransformHandleType]?: boolean } = DEFAULT_OMIT_SIDES,\n): TransformHandles => {\n // so that when locked element is selected (especially when you toggle lock\n // via keyboard) the locked element is visually distinct, indicating\n // you can't move/resize\n if (\n element.locked ||\n // Elbow arrows cannot be rotated\n isElbowArrow(element)\n ) {\n return {};\n }\n\n if (element.type === \"freedraw\" || isLinearElement(element)) {\n if (element.points.length === 2) {\n // only check the last point because starting point is always (0,0)\n const [, p1] = element.points;\n if (p1[0] === 0 || p1[1] === 0) {\n omitSides = OMIT_SIDES_FOR_LINE_BACKSLASH;\n } else if (p1[0] > 0 && p1[1] < 0) {\n omitSides = OMIT_SIDES_FOR_LINE_SLASH;\n } else if (p1[0] > 0 && p1[1] > 0) {\n omitSides = OMIT_SIDES_FOR_LINE_BACKSLASH;\n } else if (p1[0] < 0 && p1[1] > 0) {\n omitSides = OMIT_SIDES_FOR_LINE_SLASH;\n } else if (p1[0] < 0 && p1[1] < 0) {\n omitSides = OMIT_SIDES_FOR_LINE_BACKSLASH;\n }\n }\n } else if (isFrameLikeElement(element)) {\n omitSides = {\n ...omitSides,\n rotation: true,\n };\n }\n const margin = isLinearElement(element)\n ? DEFAULT_TRANSFORM_HANDLE_SPACING + 8\n : isImageElement(element)\n ? 0\n : DEFAULT_TRANSFORM_HANDLE_SPACING;\n return getTransformHandlesFromCoords(\n getElementAbsoluteCoords(element, elementsMap, true),\n element.angle,\n zoom,\n pointerType,\n omitSides,\n margin,\n isImageElement(element) ? 0 : undefined,\n );\n};\n\nexport const shouldShowBoundingBox = (\n elements: readonly NonDeletedExcalidrawElement[],\n appState: InteractiveCanvasAppState,\n) => {\n if (appState.editingLinearElement) {\n return false;\n }\n if (elements.length > 1) {\n return true;\n }\n const element = elements[0];\n if (isElbowArrow(element)) {\n // Elbow arrows cannot be resized as single selected elements\n return false;\n }\n if (!isLinearElement(element)) {\n return true;\n }\n\n return element.points.length > 2;\n};\n", "import type {\n ExcalidrawElement,\n PointerType,\n NonDeletedExcalidrawElement,\n ElementsMap,\n} from \"./types\";\n\nimport type {\n TransformHandleType,\n TransformHandle,\n MaybeTransformHandleType,\n} from \"./transformHandles\";\nimport {\n getTransformHandlesFromCoords,\n getTransformHandles,\n getOmitSidesForDevice,\n canResizeFromSides,\n} from \"./transformHandles\";\nimport type { AppState, Device, Zoom } from \"../types\";\nimport type { Bounds } from \"./bounds\";\nimport { getElementAbsoluteCoords } from \"./bounds\";\nimport { SIDE_RESIZING_THRESHOLD } from \"../constants\";\nimport { isImageElement, isLinearElement } from \"./typeChecks\";\nimport type { GlobalPoint, LineSegment, LocalPoint } from \"@excalidraw/math\";\nimport {\n pointFrom,\n pointOnLineSegment,\n pointRotateRads,\n type Radians,\n} from \"@excalidraw/math\";\n\nconst isInsideTransformHandle = (\n transformHandle: TransformHandle,\n x: number,\n y: number,\n) =>\n x >= transformHandle[0] &&\n x <= transformHandle[0] + transformHandle[2] &&\n y >= transformHandle[1] &&\n y <= transformHandle[1] + transformHandle[3];\n\nexport const resizeTest = <Point extends GlobalPoint | LocalPoint>(\n element: NonDeletedExcalidrawElement,\n elementsMap: ElementsMap,\n appState: AppState,\n x: number,\n y: number,\n zoom: Zoom,\n pointerType: PointerType,\n device: Device,\n): MaybeTransformHandleType => {\n if (!appState.selectedElementIds[element.id]) {\n return false;\n }\n\n const { rotation: rotationTransformHandle, ...transformHandles } =\n getTransformHandles(\n element,\n zoom,\n elementsMap,\n pointerType,\n getOmitSidesForDevice(device),\n );\n\n if (\n rotationTransformHandle &&\n isInsideTransformHandle(rotationTransformHandle, x, y)\n ) {\n return \"rotation\" as TransformHandleType;\n }\n\n const filter = Object.keys(transformHandles).filter((key) => {\n const transformHandle =\n transformHandles[key as Exclude<TransformHandleType, \"rotation\">]!;\n if (!transformHandle) {\n return false;\n }\n return isInsideTransformHandle(transformHandle, x, y);\n });\n\n if (filter.length > 0) {\n return filter[0] as TransformHandleType;\n }\n\n if (canResizeFromSides(device)) {\n const [x1, y1, x2, y2, cx, cy] = getElementAbsoluteCoords(\n element,\n elementsMap,\n );\n\n // do not resize from the sides for linear elements with only two points\n if (!(isLinearElement(element) && element.points.length <= 2)) {\n const SPACING = isImageElement(element)\n ? 0\n : SIDE_RESIZING_THRESHOLD / zoom.value;\n const ZOOMED_SIDE_RESIZING_THRESHOLD =\n SIDE_RESIZING_THRESHOLD / zoom.value;\n const sides = getSelectionBorders(\n pointFrom(x1 - SPACING, y1 - SPACING),\n pointFrom(x2 + SPACING, y2 + SPACING),\n pointFrom(cx, cy),\n element.angle,\n );\n\n for (const [dir, side] of Object.entries(sides)) {\n // test to see if x, y are on the line segment\n if (\n pointOnLineSegment(\n pointFrom(x, y),\n side as LineSegment<Point>,\n ZOOMED_SIDE_RESIZING_THRESHOLD,\n )\n ) {\n return dir as TransformHandleType;\n }\n }\n }\n }\n\n return false;\n};\n\nexport const getElementWithTransformHandleType = (\n elements: readonly NonDeletedExcalidrawElement[],\n appState: AppState,\n scenePointerX: number,\n scenePointerY: number,\n zoom: Zoom,\n pointerType: PointerType,\n elementsMap: ElementsMap,\n device: Device,\n) => {\n return elements.reduce((result, element) => {\n if (result) {\n return result;\n }\n const transformHandleType = resizeTest(\n element,\n elementsMap,\n appState,\n scenePointerX,\n scenePointerY,\n zoom,\n pointerType,\n device,\n );\n return transformHandleType ? { element, transformHandleType } : null;\n }, null as { element: NonDeletedExcalidrawElement; transformHandleType: MaybeTransformHandleType } | null);\n};\n\nexport const getTransformHandleTypeFromCoords = <\n Point extends GlobalPoint | LocalPoint,\n>(\n [x1, y1, x2, y2]: Bounds,\n scenePointerX: number,\n scenePointerY: number,\n zoom: Zoom,\n pointerType: PointerType,\n device: Device,\n): MaybeTransformHandleType => {\n const transformHandles = getTransformHandlesFromCoords(\n [x1, y1, x2, y2, (x1 + x2) / 2, (y1 + y2) / 2],\n 0 as Radians,\n zoom,\n pointerType,\n getOmitSidesForDevice(device),\n );\n\n const found = Object.keys(transformHandles).find((key) => {\n const transformHandle =\n transformHandles[key as Exclude<TransformHandleType, \"rotation\">]!;\n return (\n transformHandle &&\n isInsideTransformHandle(transformHandle, scenePointerX, scenePointerY)\n );\n });\n\n if (found) {\n return found as MaybeTransformHandleType;\n }\n\n if (canResizeFromSides(device)) {\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n\n const SPACING = SIDE_RESIZING_THRESHOLD / zoom.value;\n\n const sides = getSelectionBorders(\n pointFrom(x1 - SPACING, y1 - SPACING),\n pointFrom(x2 + SPACING, y2 + SPACING),\n pointFrom(cx, cy),\n 0 as Radians,\n );\n\n for (const [dir, side] of Object.entries(sides)) {\n // test to see if x, y are on the line segment\n if (\n pointOnLineSegment(\n pointFrom(scenePointerX, scenePointerY),\n side as LineSegment<Point>,\n SPACING,\n )\n ) {\n return dir as TransformHandleType;\n }\n }\n }\n\n return false;\n};\n\nconst RESIZE_CURSORS = [\"ns\", \"nesw\", \"ew\", \"nwse\"];\nconst rotateResizeCursor = (cursor: string, angle: number) => {\n const index = RESIZE_CURSORS.indexOf(cursor);\n if (index >= 0) {\n const a = Math.round(angle / (Math.PI / 4));\n cursor = RESIZE_CURSORS[(index + a) % RESIZE_CURSORS.length];\n }\n return cursor;\n};\n\n/*\n * Returns bi-directional cursor for the element being resized\n */\nexport const getCursorForResizingElement = (resizingElement: {\n element?: ExcalidrawElement;\n transformHandleType: MaybeTransformHandleType;\n}): string => {\n const { element, transformHandleType } = resizingElement;\n const shouldSwapCursors =\n element && Math.sign(element.height) * Math.sign(element.width) === -1;\n let cursor = null;\n\n switch (transformHandleType) {\n case \"n\":\n case \"s\":\n cursor = \"ns\";\n break;\n case \"w\":\n case \"e\":\n cursor = \"ew\";\n break;\n case \"nw\":\n case \"se\":\n if (shouldSwapCursors) {\n cursor = \"nesw\";\n } else {\n cursor = \"nwse\";\n }\n break;\n case \"ne\":\n case \"sw\":\n if (shouldSwapCursors) {\n cursor = \"nwse\";\n } else {\n cursor = \"nesw\";\n }\n break;\n case \"rotation\":\n return \"grab\";\n }\n\n if (cursor && element) {\n cursor = rotateResizeCursor(cursor, element.angle);\n }\n\n return cursor ? `${cursor}-resize` : \"\";\n};\n\nconst getSelectionBorders = <Point extends LocalPoint | GlobalPoint>(\n [x1, y1]: Point,\n [x2, y2]: Point,\n center: Point,\n angle: Radians,\n) => {\n const topLeft = pointRotateRads(pointFrom(x1, y1), center, angle);\n const topRight = pointRotateRads(pointFrom(x2, y1), center, angle);\n const bottomLeft = pointRotateRads(pointFrom(x1, y2), center, angle);\n const bottomRight = pointRotateRads(pointFrom(x2, y2), center, angle);\n\n return {\n n: [topLeft, topRight],\n e: [topRight, bottomRight],\n s: [bottomRight, bottomLeft],\n w: [bottomLeft, topLeft],\n };\n};\n", "import { MIN_FONT_SIZE, SHIFT_LOCKING_ANGLE } from \"../constants\";\nimport { rescalePoints } from \"../points\";\nimport type {\n ExcalidrawLinearElement,\n ExcalidrawTextElement,\n NonDeletedExcalidrawElement,\n NonDeleted,\n ExcalidrawElement,\n ExcalidrawTextElementWithContainer,\n ExcalidrawImageElement,\n ElementsMap,\n SceneElementsMap,\n ExcalidrawElbowArrowElement,\n} from \"./types\";\nimport type { Mutable } from \"../utility-types\";\nimport {\n getElementAbsoluteCoords,\n getCommonBounds,\n getResizedElementAbsoluteCoords,\n getCommonBoundingBox,\n getElementBounds,\n} from \"./bounds\";\nimport type { BoundingBox } from \"./bounds\";\nimport {\n isArrowElement,\n isBoundToContainer,\n isElbowArrow,\n isFrameLikeElement,\n isFreeDrawElement,\n isImageElement,\n isLinearElement,\n isTextElement,\n} from \"./typeChecks\";\nimport { mutateElement } from \"./mutateElement\";\nimport { getFontString } from \"../utils\";\nimport { getArrowLocalFixedPoints, updateBoundElements } from \"./binding\";\nimport type {\n MaybeTransformHandleType,\n TransformHandleDirection,\n} from \"./transformHandles\";\nimport type { PointerDownState } from \"../types\";\nimport type Scene from \"../scene/Scene\";\nimport {\n getBoundTextElement,\n getBoundTextElementId,\n getContainerElement,\n handleBindTextResize,\n getBoundTextMaxWidth,\n} from \"./textElement\";\nimport { wrapText } from \"./textWrapping\";\nimport { LinearElementEditor } from \"./linearElementEditor\";\nimport { isInGroup } from \"../groups\";\nimport type { GlobalPoint } from \"@excalidraw/math\";\nimport {\n pointCenter,\n normalizeRadians,\n pointFrom,\n pointFromPair,\n pointRotateRads,\n type Radians,\n type LocalPoint,\n} from \"@excalidraw/math\";\nimport {\n getMinTextElementWidth,\n measureText,\n getApproxMinLineWidth,\n getApproxMinLineHeight,\n} from \"./textMeasurements\";\n\n// Returns true when transform (resizing/rotation) happened\nexport const transformElements = (\n originalElements: PointerDownState[\"originalElements\"],\n transformHandleType: MaybeTransformHandleType,\n selectedElements: readonly NonDeletedExcalidrawElement[],\n elementsMap: SceneElementsMap,\n scene: Scene,\n shouldRotateWithDiscreteAngle: boolean,\n shouldResizeFromCenter: boolean,\n shouldMaintainAspectRatio: boolean,\n pointerX: number,\n pointerY: number,\n centerX: number,\n centerY: number,\n): boolean => {\n if (selectedElements.length === 1) {\n const [element] = selectedElements;\n if (transformHandleType === \"rotation\") {\n if (!isElbowArrow(element)) {\n rotateSingleElement(\n element,\n elementsMap,\n scene,\n pointerX,\n pointerY,\n shouldRotateWithDiscreteAngle,\n );\n updateBoundElements(element, elementsMap);\n }\n } else if (isTextElement(element) && transformHandleType) {\n resizeSingleTextElement(\n originalElements,\n element,\n elementsMap,\n transformHandleType,\n shouldResizeFromCenter,\n pointerX,\n pointerY,\n );\n updateBoundElements(element, elementsMap);\n return true;\n } else if (transformHandleType) {\n const elementId = selectedElements[0].id;\n const latestElement = elementsMap.get(elementId);\n const origElement = originalElements.get(elementId);\n\n if (latestElement && origElement) {\n const { nextWidth, nextHeight } =\n getNextSingleWidthAndHeightFromPointer(\n latestElement,\n origElement,\n elementsMap,\n originalElements,\n transformHandleType,\n pointerX,\n pointerY,\n {\n shouldMaintainAspectRatio,\n shouldResizeFromCenter,\n },\n );\n\n resizeSingleElement(\n nextWidth,\n nextHeight,\n latestElement,\n origElement,\n elementsMap,\n originalElements,\n transformHandleType,\n {\n shouldMaintainAspectRatio,\n shouldResizeFromCenter,\n },\n );\n }\n }\n return true;\n } else if (selectedElements.length > 1) {\n if (transformHandleType === \"rotation\") {\n rotateMultipleElements(\n originalElements,\n selectedElements,\n elementsMap,\n scene,\n pointerX,\n pointerY,\n shouldRotateWithDiscreteAngle,\n centerX,\n centerY,\n );\n return true;\n } else if (transformHandleType) {\n const { nextWidth, nextHeight, flipByX, flipByY, originalBoundingBox } =\n getNextMultipleWidthAndHeightFromPointer(\n selectedElements,\n originalElements,\n elementsMap,\n transformHandleType,\n pointerX,\n pointerY,\n {\n shouldMaintainAspectRatio,\n shouldResizeFromCenter,\n },\n );\n\n resizeMultipleElements(\n selectedElements,\n elementsMap,\n transformHandleType,\n scene,\n originalElements,\n {\n shouldResizeFromCenter,\n shouldMaintainAspectRatio,\n flipByX,\n flipByY,\n nextWidth,\n nextHeight,\n originalBoundingBox,\n },\n );\n\n return true;\n }\n }\n return false;\n};\n\nconst rotateSingleElement = (\n element: NonDeletedExcalidrawElement,\n elementsMap: ElementsMap,\n scene: Scene,\n pointerX: number,\n pointerY: number,\n shouldRotateWithDiscreteAngle: boolean,\n) => {\n const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n let angle: Radians;\n if (isFrameLikeElement(element)) {\n angle = 0 as Radians;\n } else {\n angle = ((5 * Math.PI) / 2 +\n Math.atan2(pointerY - cy, pointerX - cx)) as Radians;\n if (shouldRotateWithDiscreteAngle) {\n angle = (angle + SHIFT_LOCKING_ANGLE / 2) as Radians;\n angle = (angle - (angle % SHIFT_LOCKING_ANGLE)) as Radians;\n }\n angle = normalizeRadians(angle as Radians);\n }\n const boundTextElementId = getBoundTextElementId(element);\n\n mutateElement(element, { angle });\n if (boundTextElementId) {\n const textElement =\n scene.getElement<ExcalidrawTextElementWithContainer>(boundTextElementId);\n\n if (textElement && !isArrowElement(element)) {\n mutateElement(textElement, { angle });\n }\n }\n};\n\nexport const rescalePointsInElement = (\n element: NonDeletedExcalidrawElement,\n width: number,\n height: number,\n normalizePoints: boolean,\n) =>\n isLinearElement(element) || isFreeDrawElement(element)\n ? {\n points: rescalePoints(\n 0,\n width,\n rescalePoints(1, height, element.points, normalizePoints),\n normalizePoints,\n ),\n }\n : {};\n\nexport const measureFontSizeFromWidth = (\n element: NonDeleted<ExcalidrawTextElement>,\n elementsMap: ElementsMap,\n nextWidth: number,\n): { size: number } | null => {\n // We only use width to scale font on resize\n let width = element.width;\n\n const hasContainer = isBoundToContainer(element);\n if (hasContainer) {\n const container = getContainerElement(element, elementsMap);\n if (container) {\n width = getBoundTextMaxWidth(container, element);\n }\n }\n const nextFontSize = element.fontSize * (nextWidth / width);\n if (nextFontSize < MIN_FONT_SIZE) {\n return null;\n }\n\n return {\n size: nextFontSize,\n };\n};\n\nconst resizeSingleTextElement = (\n originalElements: PointerDownState[\"originalElements\"],\n element: NonDeleted<ExcalidrawTextElement>,\n elementsMap: ElementsMap,\n transformHandleType: TransformHandleDirection,\n shouldResizeFromCenter: boolean,\n pointerX: number,\n pointerY: number,\n) => {\n const [x1, y1, x2, y2, cx, cy] = getElementAbsoluteCoords(\n element,\n elementsMap,\n );\n // rotation pointer with reverse angle\n const [rotatedX, rotatedY] = pointRotateRads(\n pointFrom(pointerX, pointerY),\n pointFrom(cx, cy),\n -element.angle as Radians,\n );\n let scaleX = 0;\n let scaleY = 0;\n\n if (transformHandleType !== \"e\" && transformHandleType !== \"w\") {\n if (transformHandleType.includes(\"e\")) {\n scaleX = (rotatedX - x1) / (x2 - x1);\n }\n if (transformHandleType.includes(\"w\")) {\n scaleX = (x2 - rotatedX) / (x2 - x1);\n }\n if (transformHandleType.includes(\"n\")) {\n scaleY = (y2 - rotatedY) / (y2 - y1);\n }\n if (transformHandleType.includes(\"s\")) {\n scaleY = (rotatedY - y1) / (y2 - y1);\n }\n }\n\n const scale = Math.max(scaleX, scaleY);\n\n if (scale > 0) {\n const nextWidth = element.width * scale;\n const nextHeight = element.height * scale;\n const metrics = measureFontSizeFromWidth(element, elementsMap, nextWidth);\n if (metrics === null) {\n return;\n }\n\n const startTopLeft = [x1, y1];\n const startBottomRight = [x2, y2];\n const startCenter = [cx, cy];\n\n let newTopLeft = pointFrom<GlobalPoint>(x1, y1);\n if ([\"n\", \"w\", \"nw\"].includes(transformHandleType)) {\n newTopLeft = pointFrom<GlobalPoint>(\n startBottomRight[0] - Math.abs(nextWidth),\n startBottomRight[1] - Math.abs(nextHeight),\n );\n }\n if (transformHandleType === \"ne\") {\n const bottomLeft = [startTopLeft[0], startBottomRight[1]];\n newTopLeft = pointFrom<GlobalPoint>(\n bottomLeft[0],\n bottomLeft[1] - Math.abs(nextHeight),\n );\n }\n if (transformHandleType === \"sw\") {\n const topRight = [startBottomRight[0], startTopLeft[1]];\n newTopLeft = pointFrom<GlobalPoint>(\n topRight[0] - Math.abs(nextWidth),\n topRight[1],\n );\n }\n\n if ([\"s\", \"n\"].includes(transformHandleType)) {\n newTopLeft[0] = startCenter[0] - nextWidth / 2;\n }\n if ([\"e\", \"w\"].includes(transformHandleType)) {\n newTopLeft[1] = startCenter[1] - nextHeight / 2;\n }\n\n if (shouldResizeFromCenter) {\n newTopLeft[0] = startCenter[0] - Math.abs(nextWidth) / 2;\n newTopLeft[1] = startCenter[1] - Math.abs(nextHeight) / 2;\n }\n\n const angle = element.angle;\n const rotatedTopLeft = pointRotateRads(\n newTopLeft,\n pointFrom(cx, cy),\n angle,\n );\n const newCenter = pointFrom<GlobalPoint>(\n newTopLeft[0] + Math.abs(nextWidth) / 2,\n newTopLeft[1] + Math.abs(nextHeight) / 2,\n );\n const rotatedNewCenter = pointRotateRads(\n newCenter,\n pointFrom(cx, cy),\n angle,\n );\n newTopLeft = pointRotateRads(\n rotatedTopLeft,\n rotatedNewCenter,\n -angle as Radians,\n );\n const [nextX, nextY] = newTopLeft;\n\n mutateElement(element, {\n fontSize: metrics.size,\n width: nextWidth,\n height: nextHeight,\n x: nextX,\n y: nextY,\n });\n }\n\n if (transformHandleType === \"e\" || transformHandleType === \"w\") {\n const stateAtResizeStart = originalElements.get(element.id)!;\n const [x1, y1, x2, y2] = getResizedElementAbsoluteCoords(\n stateAtResizeStart,\n stateAtResizeStart.width,\n stateAtResizeStart.height,\n true,\n );\n const startTopLeft = pointFrom<GlobalPoint>(x1, y1);\n const startBottomRight = pointFrom<GlobalPoint>(x2, y2);\n const startCenter = pointCenter(startTopLeft, startBottomRight);\n\n const rotatedPointer = pointRotateRads(\n pointFrom(pointerX, pointerY),\n startCenter,\n -stateAtResizeStart.angle as Radians,\n );\n\n const [esx1, , esx2] = getResizedElementAbsoluteCoords(\n element,\n element.width,\n element.height,\n true,\n );\n\n const boundsCurrentWidth = esx2 - esx1;\n\n const atStartBoundsWidth = startBottomRight[0] - startTopLeft[0];\n const minWidth = getMinTextElementWidth(\n getFontString({\n fontSize: element.fontSize,\n fontFamily: element.fontFamily,\n }),\n element.lineHeight,\n );\n\n let scaleX = atStartBoundsWidth / boundsCurrentWidth;\n\n if (transformHandleType.includes(\"e\")) {\n scaleX = (rotatedPointer[0] - startTopLeft[0]) / boundsCurrentWidth;\n }\n if (transformHandleType.includes(\"w\")) {\n scaleX = (startBottomRight[0] - rotatedPointer[0]) / boundsCurrentWidth;\n }\n\n const newWidth =\n element.width * scaleX < minWidth ? minWidth : element.width * scaleX;\n\n const text = wrapText(\n element.originalText,\n getFontString(element),\n Math.abs(newWidth),\n );\n const metrics = measureText(\n text,\n getFontString(element),\n element.lineHeight,\n );\n\n const eleNewHeight = metrics.height;\n\n const [newBoundsX1, newBoundsY1, newBoundsX2, newBoundsY2] =\n getResizedElementAbsoluteCoords(\n stateAtResizeStart,\n newWidth,\n eleNewHeight,\n true,\n );\n const newBoundsWidth = newBoundsX2 - newBoundsX1;\n const newBoundsHeight = newBoundsY2 - newBoundsY1;\n\n let newTopLeft = [...startTopLeft] as [number, number];\n if ([\"n\", \"w\", \"nw\"].includes(transformHandleType)) {\n newTopLeft = [\n startBottomRight[0] - Math.abs(newBoundsWidth),\n startTopLeft[1],\n ];\n }\n\n // adjust topLeft to new rotation point\n const angle = stateAtResizeStart.angle;\n const rotatedTopLeft = pointRotateRads(\n pointFromPair(newTopLeft),\n startCenter,\n angle,\n );\n const newCenter = pointFrom(\n newTopLeft[0] + Math.abs(newBoundsWidth) / 2,\n newTopLeft[1] + Math.abs(newBoundsHeight) / 2,\n );\n const rotatedNewCenter = pointRotateRads(newCenter, startCenter, angle);\n newTopLeft = pointRotateRads(\n rotatedTopLeft,\n rotatedNewCenter,\n -angle as Radians,\n );\n\n const resizedElement: Partial<ExcalidrawTextElement> = {\n width: Math.abs(newWidth),\n height: Math.abs(metrics.height),\n x: newTopLeft[0],\n y: newTopLeft[1],\n text,\n autoResize: false,\n };\n\n mutateElement(element, resizedElement);\n }\n};\n\nconst rotateMultipleElements = (\n originalElements: PointerDownState[\"originalElements\"],\n elements: readonly NonDeletedExcalidrawElement[],\n elementsMap: SceneElementsMap,\n scene: Scene,\n pointerX: number,\n pointerY: number,\n shouldRotateWithDiscreteAngle: boolean,\n centerX: number,\n centerY: number,\n) => {\n let centerAngle =\n (5 * Math.PI) / 2 + Math.atan2(pointerY - centerY, pointerX - centerX);\n if (shouldRotateWithDiscreteAngle) {\n centerAngle += SHIFT_LOCKING_ANGLE / 2;\n centerAngle -= centerAngle % SHIFT_LOCKING_ANGLE;\n }\n\n for (const element of elements) {\n if (!isFrameLikeElement(element)) {\n const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n const origAngle =\n originalElements.get(element.id)?.angle ?? element.angle;\n const [rotatedCX, rotatedCY] = pointRotateRads(\n pointFrom(cx, cy),\n pointFrom(centerX, centerY),\n (centerAngle + origAngle - element.angle) as Radians,\n );\n\n if (isElbowArrow(element)) {\n // Needed to re-route the arrow\n mutateElement(element, {\n points: getArrowLocalFixedPoints(element, elementsMap),\n });\n } else {\n mutateElement(\n element,\n {\n x: element.x + (rotatedCX - cx),\n y: element.y + (rotatedCY - cy),\n angle: normalizeRadians((centerAngle + origAngle) as Radians),\n },\n false,\n );\n }\n\n updateBoundElements(element, elementsMap, {\n simultaneouslyUpdated: elements,\n });\n\n const boundText = getBoundTextElement(element, elementsMap);\n if (boundText && !isArrowElement(element)) {\n mutateElement(\n boundText,\n {\n x: boundText.x + (rotatedCX - cx),\n y: boundText.y + (rotatedCY - cy),\n angle: normalizeRadians((centerAngle + origAngle) as Radians),\n },\n false,\n );\n }\n }\n }\n\n scene.triggerUpdate();\n};\n\nexport const getResizeOffsetXY = (\n transformHandleType: MaybeTransformHandleType,\n selectedElements: NonDeletedExcalidrawElement[],\n elementsMap: ElementsMap,\n x: number,\n y: number,\n): [number, number] => {\n const [x1, y1, x2, y2] =\n selectedElements.length === 1\n ? getElementAbsoluteCoords(selectedElements[0], elementsMap)\n : getCommonBounds(selectedElements);\n const cx = (x1 + x2) / 2;\n const cy = (y1 + y2) / 2;\n const angle = (\n selectedElements.length === 1 ? selectedElements[0].angle : 0\n ) as Radians;\n [x, y] = pointRotateRads(\n pointFrom(x, y),\n pointFrom(cx, cy),\n -angle as Radians,\n );\n switch (transformHandleType) {\n case \"n\":\n return pointRotateRads(\n pointFrom(x - (x1 + x2) / 2, y - y1),\n pointFrom(0, 0),\n angle,\n );\n case \"s\":\n return pointRotateRads(\n pointFrom(x - (x1 + x2) / 2, y - y2),\n pointFrom(0, 0),\n angle,\n );\n case \"w\":\n return pointRotateRads(\n pointFrom(x - x1, y - (y1 + y2) / 2),\n pointFrom(0, 0),\n angle,\n );\n case \"e\":\n return pointRotateRads(\n pointFrom(x - x2, y - (y1 + y2) / 2),\n pointFrom(0, 0),\n angle,\n );\n case \"nw\":\n return pointRotateRads(pointFrom(x - x1, y - y1), pointFrom(0, 0), angle);\n case \"ne\":\n return pointRotateRads(pointFrom(x - x2, y - y1), pointFrom(0, 0), angle);\n case \"sw\":\n return pointRotateRads(pointFrom(x - x1, y - y2), pointFrom(0, 0), angle);\n case \"se\":\n return pointRotateRads(pointFrom(x - x2, y - y2), pointFrom(0, 0), angle);\n default:\n return [0, 0];\n }\n};\n\nexport const getResizeArrowDirection = (\n transformHandleType: MaybeTransformHandleType,\n element: NonDeleted<ExcalidrawLinearElement>,\n): \"origin\" | \"end\" => {\n const [, [px, py]] = element.points;\n const isResizeEnd =\n (transformHandleType === \"nw\" && (px < 0 || py < 0)) ||\n (transformHandleType === \"ne\" && px >= 0) ||\n (transformHandleType === \"sw\" && px <= 0) ||\n (transformHandleType === \"se\" && (px > 0 || py > 0));\n return isResizeEnd ? \"end\" : \"origin\";\n};\n\ntype ResizeAnchor =\n | \"top-left\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-right\"\n | \"west-side\"\n | \"north-side\"\n | \"east-side\"\n | \"south-side\"\n | \"center\";\n\nconst getResizeAnchor = (\n handleDirection: TransformHandleDirection,\n shouldMaintainAspectRatio: boolean,\n shouldResizeFromCenter: boolean,\n): ResizeAnchor => {\n if (shouldResizeFromCenter) {\n return \"center\";\n }\n\n if (shouldMaintainAspectRatio) {\n switch (handleDirection) {\n case \"n\":\n return \"south-side\";\n case \"e\": {\n return \"west-side\";\n }\n case \"s\":\n return \"north-side\";\n case \"w\":\n return \"east-side\";\n case \"ne\":\n return \"bottom-left\";\n case \"nw\":\n return \"bottom-right\";\n case \"se\":\n return \"top-left\";\n case \"sw\":\n return \"top-right\";\n }\n }\n\n if ([\"e\", \"se\", \"s\"].includes(handleDirection)) {\n return \"top-left\";\n } else if ([\"n\", \"nw\", \"w\"].includes(handleDirection)) {\n return \"bottom-right\";\n } else if (handleDirection === \"ne\") {\n return \"bottom-left\";\n }\n return \"top-right\";\n};\n\nconst getResizedOrigin = (\n prevOrigin: GlobalPoint,\n prevWidth: number,\n prevHeight: number,\n newWidth: number,\n newHeight: number,\n angle: number,\n handleDirection: TransformHandleDirection,\n shouldMaintainAspectRatio: boolean,\n shouldResizeFromCenter: boolean,\n): { x: number; y: number } => {\n const anchor = getResizeAnchor(\n handleDirection,\n shouldMaintainAspectRatio,\n shouldResizeFromCenter,\n );\n\n const [x, y] = prevOrigin;\n\n switch (anchor) {\n case \"top-left\":\n return {\n x:\n x +\n (prevWidth - newWidth) / 2 +\n ((newWidth - prevWidth) / 2) * Math.cos(angle) +\n ((prevHeight - newHeight) / 2) * Math.sin(angle),\n y:\n y +\n (prevHeight - newHeight) / 2 +\n ((newWidth - prevWidth) / 2) * Math.sin(angle) +\n ((newHeight - prevHeight) / 2) * Math.cos(angle),\n };\n case \"top-right\":\n return {\n x:\n x +\n ((prevWidth - newWidth) / 2) * (Math.cos(angle) + 1) +\n ((prevHeight - newHeight) / 2) * Math.sin(angle),\n y:\n y +\n (prevHeight - newHeight) / 2 +\n ((prevWidth - newWidth) / 2) * Math.sin(angle) +\n ((newHeight - prevHeight) / 2) * Math.cos(angle),\n };\n\n case \"bottom-left\":\n return {\n x:\n x +\n ((prevWidth - newWidth) / 2) * (1 - Math.cos(angle)) +\n ((newHeight - prevHeight) / 2) * Math.sin(angle),\n y:\n y +\n ((prevHeight - newHeight) / 2) * (Math.cos(angle) + 1) +\n ((newWidth - prevWidth) / 2) * Math.sin(angle),\n };\n case \"bottom-right\":\n return {\n x:\n x +\n ((prevWidth - newWidth) / 2) * (Math.cos(angle) + 1) +\n ((newHeight - prevHeight) / 2) * Math.sin(angle),\n y:\n y +\n ((prevHeight - newHeight) / 2) * (Math.cos(angle) + 1) +\n ((prevWidth - newWidth) / 2) * Math.sin(angle),\n };\n case \"center\":\n return {\n x: x - (newWidth - prevWidth) / 2,\n y: y - (newHeight - prevHeight) / 2,\n };\n case \"east-side\":\n // NOTE (mtolmacs): Reverting this for a short period to test if it is\n // the cause of the megasized elbow arrows showing up.\n if (\n Math.abs(\n y +\n ((prevWidth - newWidth) / 2) * Math.sin(angle) +\n (prevHeight - newHeight) / 2,\n ) > 1e6\n ) {\n console.error(\n \"getResizedOrigin() new calculation creates extremely large (> 1e6) y value where the old calculation resulted in\",\n {\n result:\n y +\n (newHeight - prevHeight) / 2 +\n ((prevWidth - newWidth) / 2) * Math.sin(angle),\n },\n );\n }\n\n return {\n x: x + ((prevWidth - newWidth) / 2) * (Math.cos(angle) + 1),\n y:\n y +\n (newHeight - prevHeight) / 2 +\n ((prevWidth - newWidth) / 2) * Math.sin(angle),\n };\n case \"west-side\":\n return {\n x: x + ((prevWidth - newWidth) / 2) * (1 - Math.cos(angle)),\n y:\n y +\n ((newWidth - prevWidth) / 2) * Math.sin(angle) +\n (prevHeight - newHeight) / 2,\n };\n case \"north-side\":\n return {\n x:\n x +\n (prevWidth - newWidth) / 2 +\n ((prevHeight - newHeight) / 2) * Math.sin(angle),\n y: y + ((newHeight - prevHeight) / 2) * (Math.cos(angle) - 1),\n };\n case \"south-side\":\n return {\n x:\n x +\n (prevWidth - newWidth) / 2 +\n ((newHeight - prevHeight) / 2) * Math.sin(angle),\n y: y + ((prevHeight - newHeight) / 2) * (Math.cos(angle) + 1),\n };\n }\n};\n\nexport const resizeSingleElement = (\n nextWidth: number,\n nextHeight: number,\n latestElement: ExcalidrawElement,\n origElement: ExcalidrawElement,\n elementsMap: ElementsMap,\n originalElementsMap: ElementsMap,\n handleDirection: TransformHandleDirection,\n {\n shouldInformMutation = true,\n shouldMaintainAspectRatio = false,\n shouldResizeFromCenter = false,\n }: {\n shouldMaintainAspectRatio?: boolean;\n shouldResizeFromCenter?: boolean;\n shouldInformMutation?: boolean;\n } = {},\n) => {\n let boundTextFont: { fontSize?: number } = {};\n const boundTextElement = getBoundTextElement(latestElement, elementsMap);\n\n if (boundTextElement) {\n const stateOfBoundTextElementAtResize = originalElementsMap.get(\n boundTextElement.id,\n ) as typeof boundTextElement | undefined;\n if (stateOfBoundTextElementAtResize) {\n boundTextFont = {\n fontSize: stateOfBoundTextElementAtResize.fontSize,\n };\n }\n if (shouldMaintainAspectRatio) {\n const updatedElement = {\n ...latestElement,\n width: nextWidth,\n height: nextHeight,\n };\n\n const nextFont = measureFontSizeFromWidth(\n boundTextElement,\n elementsMap,\n getBoundTextMaxWidth(updatedElement, boundTextElement),\n );\n if (nextFont === null) {\n return;\n }\n boundTextFont = {\n fontSize: nextFont.size,\n };\n } else {\n const minWidth = getApproxMinLineWidth(\n getFontString(boundTextElement),\n boundTextElement.lineHeight,\n );\n const minHeight = getApproxMinLineHeight(\n boundTextElement.fontSize,\n boundTextElement.lineHeight,\n );\n nextWidth = Math.max(nextWidth, minWidth);\n nextHeight = Math.max(nextHeight, minHeight);\n }\n }\n\n const rescaledPoints = rescalePointsInElement(\n origElement,\n nextWidth,\n nextHeight,\n true,\n );\n\n let previousOrigin = pointFrom<GlobalPoint>(origElement.x, origElement.y);\n\n if (isLinearElement(origElement)) {\n const [x1, y1] = getElementBounds(origElement, originalElementsMap);\n previousOrigin = pointFrom<GlobalPoint>(x1, y1);\n }\n\n const newOrigin: {\n x: number;\n y: number;\n } = getResizedOrigin(\n previousOrigin,\n origElement.width,\n origElement.height,\n nextWidth,\n nextHeight,\n origElement.angle,\n handleDirection,\n shouldMaintainAspectRatio!!,\n shouldResizeFromCenter!!,\n );\n\n if (isLinearElement(origElement) && rescaledPoints.points) {\n const offsetX = origElement.x - previousOrigin[0];\n const offsetY = origElement.y - previousOrigin[1];\n\n newOrigin.x += offsetX;\n newOrigin.y += offsetY;\n\n const scaledX = rescaledPoints.points[0][0];\n const scaledY = rescaledPoints.points[0][1];\n\n newOrigin.x += scaledX;\n newOrigin.y += scaledY;\n\n rescaledPoints.points = rescaledPoints.points.map((p) =>\n pointFrom<LocalPoint>(p[0] - scaledX, p[1] - scaledY),\n );\n }\n\n // flipping\n if (nextWidth < 0) {\n newOrigin.x = newOrigin.x + nextWidth;\n }\n if (nextHeight < 0) {\n newOrigin.y = newOrigin.y + nextHeight;\n }\n\n if (\"scale\" in latestElement && \"scale\" in origElement) {\n mutateElement(latestElement, {\n scale: [\n // defaulting because scaleX/Y can be 0/-0\n (Math.sign(nextWidth) || origElement.scale[0]) * origElement.scale[0],\n (Math.sign(nextHeight) || origElement.scale[1]) * origElement.scale[1],\n ],\n });\n }\n\n if (\n isArrowElement(latestElement) &&\n boundTextElement &&\n shouldMaintainAspectRatio\n ) {\n const fontSize =\n (nextWidth / latestElement.width) * boundTextElement.fontSize;\n if (fontSize < MIN_FONT_SIZE) {\n return;\n }\n boundTextFont.fontSize = fontSize;\n }\n\n if (\n nextWidth !== 0 &&\n nextHeight !== 0 &&\n Number.isFinite(newOrigin.x) &&\n Number.isFinite(newOrigin.y)\n ) {\n const updates = {\n ...newOrigin,\n width: Math.abs(nextWidth),\n height: Math.abs(nextHeight),\n ...rescaledPoints,\n };\n\n mutateElement(latestElement, updates, shouldInformMutation);\n\n updateBoundElements(latestElement, elementsMap as SceneElementsMap, {\n // TODO: confirm with MARK if this actually makes sense\n newSize: { width: nextWidth, height: nextHeight },\n });\n\n if (boundTextElement && boundTextFont != null) {\n mutateElement(boundTextElement, {\n fontSize: boundTextFont.fontSize,\n });\n }\n handleBindTextResize(\n latestElement,\n elementsMap,\n handleDirection,\n shouldMaintainAspectRatio,\n );\n }\n};\n\nconst getNextSingleWidthAndHeightFromPointer = (\n latestElement: ExcalidrawElement,\n origElement: ExcalidrawElement,\n elementsMap: ElementsMap,\n originalElementsMap: ElementsMap,\n handleDirection: TransformHandleDirection,\n pointerX: number,\n pointerY: number,\n {\n shouldMaintainAspectRatio = false,\n shouldResizeFromCenter = false,\n }: {\n shouldMaintainAspectRatio?: boolean;\n shouldResizeFromCenter?: boolean;\n } = {},\n) => {\n // Gets bounds corners\n const [x1, y1, x2, y2] = getResizedElementAbsoluteCoords(\n origElement,\n origElement.width,\n origElement.height,\n true,\n );\n const startTopLeft = pointFrom(x1, y1);\n const startBottomRight = pointFrom(x2, y2);\n const startCenter = pointCenter(startTopLeft, startBottomRight);\n\n // Calculate new dimensions based on cursor position\n const rotatedPointer = pointRotateRads(\n pointFrom(pointerX, pointerY),\n startCenter,\n -origElement.angle as Radians,\n );\n\n // Get bounds corners rendered on screen\n const [esx1, esy1, esx2, esy2] = getResizedElementAbsoluteCoords(\n latestElement,\n latestElement.width,\n latestElement.height,\n true,\n );\n\n const boundsCurrentWidth = esx2 - esx1;\n const boundsCurrentHeight = esy2 - esy1;\n\n // It's important we set the initial scale value based on the width and height at resize start,\n // otherwise previous dimensions affected by modifiers will be taken into account.\n const atStartBoundsWidth = startBottomRight[0] - startTopLeft[0];\n const atStartBoundsHeight = startBottomRight[1] - startTopLeft[1];\n let scaleX = atStartBoundsWidth / boundsCurrentWidth;\n let scaleY = atStartBoundsHeight / boundsCurrentHeight;\n\n if (handleDirection.includes(\"e\")) {\n scaleX = (rotatedPointer[0] - startTopLeft[0]) / boundsCurrentWidth;\n }\n if (handleDirection.includes(\"s\")) {\n scaleY = (rotatedPointer[1] - startTopLeft[1]) / boundsCurrentHeight;\n }\n if (handleDirection.includes(\"w\")) {\n scaleX = (startBottomRight[0] - rotatedPointer[0]) / boundsCurrentWidth;\n }\n if (handleDirection.includes(\"n\")) {\n scaleY = (startBottomRight[1] - rotatedPointer[1]) / boundsCurrentHeight;\n }\n\n // We have to use dimensions of element on screen, otherwise the scaling of the\n // dimensions won't match the cursor for linear elements.\n let nextWidth = latestElement.width * scaleX;\n let nextHeight = latestElement.height * scaleY;\n\n if (shouldResizeFromCenter) {\n nextWidth = 2 * nextWidth - origElement.width;\n nextHeight = 2 * nextHeight - origElement.height;\n }\n\n // adjust dimensions to keep sides ratio\n if (shouldMaintainAspectRatio) {\n const widthRatio = Math.abs(nextWidth) / origElement.width;\n const heightRatio = Math.abs(nextHeight) / origElement.height;\n if (handleDirection.length === 1) {\n nextHeight *= widthRatio;\n nextWidth *= heightRatio;\n }\n if (handleDirection.length === 2) {\n const ratio = Math.max(widthRatio, heightRatio);\n nextWidth = origElement.width * ratio * Math.sign(nextWidth);\n nextHeight = origElement.height * ratio * Math.sign(nextHeight);\n }\n }\n\n return {\n nextWidth,\n nextHeight,\n };\n};\n\nconst getNextMultipleWidthAndHeightFromPointer = (\n selectedElements: readonly NonDeletedExcalidrawElement[],\n originalElementsMap: ElementsMap,\n elementsMap: ElementsMap,\n handleDirection: TransformHandleDirection,\n pointerX: number,\n pointerY: number,\n {\n shouldMaintainAspectRatio = false,\n shouldResizeFromCenter = false,\n }: {\n shouldResizeFromCenter?: boolean;\n shouldMaintainAspectRatio?: boolean;\n } = {},\n) => {\n const originalElementsArray = selectedElements.map(\n (el) => originalElementsMap.get(el.id)!,\n );\n\n // getCommonBoundingBox() uses getBoundTextElement() which returns null for\n // original elements from pointerDownState, so we have to find and add these\n // bound text elements manually. Additionally, the coordinates of bound text\n // elements aren't always up to date.\n const boundTextElements = originalElementsArray.reduce((acc, orig) => {\n if (!isLinearElement(orig)) {\n return acc;\n }\n const textId = getBoundTextElementId(orig);\n if (!textId) {\n return acc;\n }\n const text = originalElementsMap.get(textId) ?? null;\n if (!isBoundToContainer(text)) {\n return acc;\n }\n return [\n ...acc,\n {\n ...text,\n ...LinearElementEditor.getBoundTextElementPosition(\n orig,\n text,\n elementsMap,\n ),\n },\n ];\n }, [] as ExcalidrawTextElementWithContainer[]);\n\n const originalBoundingBox = getCommonBoundingBox(\n originalElementsArray.map((orig) => orig).concat(boundTextElements),\n );\n\n const { minX, minY, maxX, maxY, midX, midY } = originalBoundingBox;\n const width = maxX - minX;\n const height = maxY - minY;\n\n const anchorsMap = {\n ne: [minX, maxY],\n se: [minX, minY],\n sw: [maxX, minY],\n nw: [maxX, maxY],\n e: [minX, minY + height / 2],\n w: [maxX, minY + height / 2],\n n: [minX + width / 2, maxY],\n s: [minX + width / 2, minY],\n } as Record<TransformHandleDirection, GlobalPoint>;\n\n // anchor point must be on the opposite side of the dragged selection handle\n // or be the center of the selection if shouldResizeFromCenter\n const [anchorX, anchorY] = shouldResizeFromCenter\n ? [midX, midY]\n : anchorsMap[handleDirection];\n\n const resizeFromCenterScale = shouldResizeFromCenter ? 2 : 1;\n\n const scale =\n Math.max(\n Math.abs(pointerX - anchorX) / width || 0,\n Math.abs(pointerY - anchorY) / height || 0,\n ) * resizeFromCenterScale;\n\n let nextWidth =\n handleDirection.includes(\"e\") || handleDirection.includes(\"w\")\n ? Math.abs(pointerX - anchorX) * resizeFromCenterScale\n : width;\n let nextHeight =\n handleDirection.includes(\"n\") || handleDirection.includes(\"s\")\n ? Math.abs(pointerY - anchorY) * resizeFromCenterScale\n : height;\n\n if (shouldMaintainAspectRatio) {\n nextWidth = width * scale * Math.sign(pointerX - anchorX);\n nextHeight = height * scale * Math.sign(pointerY - anchorY);\n }\n\n const flipConditionsMap: Record<\n TransformHandleDirection,\n // Condition for which we should flip or not flip the selected elements\n // - when evaluated to `true`, we flip\n // - therefore, setting it to always `false` means we do not flip (in that direction) at all\n [x: boolean, y: boolean]\n > = {\n ne: [pointerX < anchorX, pointerY > anchorY],\n se: [pointerX < anchorX, pointerY < anchorY],\n sw: [pointerX > anchorX, pointerY < anchorY],\n nw: [pointerX > anchorX, pointerY > anchorY],\n // e.g. when resizing from the \"e\" side, we do not need to consider changes in the `y` direction\n // and therefore, we do not need to flip in the `y` direction at all\n e: [pointerX < anchorX, false],\n w: [pointerX > anchorX, false],\n n: [false, pointerY > anchorY],\n s: [false, pointerY < anchorY],\n };\n\n const [flipByX, flipByY] = flipConditionsMap[handleDirection].map(\n (condition) => condition,\n );\n\n return {\n originalBoundingBox,\n nextWidth,\n nextHeight,\n flipByX,\n flipByY,\n };\n};\n\nexport const resizeMultipleElements = (\n selectedElements: readonly NonDeletedExcalidrawElement[],\n elementsMap: ElementsMap,\n handleDirection: TransformHandleDirection,\n scene: Scene,\n originalElementsMap: ElementsMap,\n {\n shouldMaintainAspectRatio = false,\n shouldResizeFromCenter = false,\n flipByX = false,\n flipByY = false,\n nextHeight,\n nextWidth,\n originalBoundingBox,\n }: {\n nextWidth?: number;\n nextHeight?: number;\n shouldMaintainAspectRatio?: boolean;\n shouldResizeFromCenter?: boolean;\n flipByX?: boolean;\n flipByY?: boolean;\n // added to improve performance\n originalBoundingBox?: BoundingBox;\n } = {},\n) => {\n // in the case of just flipping, there is no need to specify the next width and height\n if (\n nextWidth === undefined &&\n nextHeight === undefined &&\n flipByX === undefined &&\n flipByY === undefined\n ) {\n return;\n }\n\n // do not allow next width or height to be 0\n if (nextHeight === 0 || nextWidth === 0) {\n return;\n }\n\n if (!originalElementsMap) {\n originalElementsMap = elementsMap;\n }\n\n const targetElements = selectedElements.reduce(\n (\n acc: {\n /** element at resize start */\n orig: NonDeletedExcalidrawElement;\n /** latest element */\n latest: NonDeletedExcalidrawElement;\n }[],\n element,\n ) => {\n const origElement = originalElementsMap!.get(element.id);\n if (origElement) {\n acc.push({ orig: origElement, latest: element });\n }\n return acc;\n },\n [],\n );\n\n let boundingBox: BoundingBox;\n\n if (originalBoundingBox) {\n boundingBox = originalBoundingBox;\n } else {\n const boundTextElements = targetElements.reduce((acc, { orig }) => {\n if (!isLinearElement(orig)) {\n return acc;\n }\n const textId = getBoundTextElementId(orig);\n if (!textId) {\n return acc;\n }\n const text = originalElementsMap!.get(textId) ?? null;\n if (!isBoundToContainer(text)) {\n return acc;\n }\n return [\n ...acc,\n {\n ...text,\n ...LinearElementEditor.getBoundTextElementPosition(\n orig,\n text,\n elementsMap,\n ),\n },\n ];\n }, [] as ExcalidrawTextElementWithContainer[]);\n\n boundingBox = getCommonBoundingBox(\n targetElements.map(({ orig }) => orig).concat(boundTextElements),\n );\n }\n const { minX, minY, maxX, maxY, midX, midY } = boundingBox;\n const width = maxX - minX;\n const height = maxY - minY;\n\n if (nextWidth === undefined && nextHeight === undefined) {\n nextWidth = width;\n nextHeight = height;\n }\n\n if (shouldMaintainAspectRatio) {\n if (nextWidth === undefined) {\n nextWidth = nextHeight! * (width / height);\n } else if (nextHeight === undefined) {\n nextHeight = nextWidth! * (height / width);\n } else if (Math.abs(nextWidth / nextHeight - width / height) > 0.001) {\n nextWidth = nextHeight * (width / height);\n }\n }\n\n if (nextWidth && nextHeight) {\n let scaleX =\n handleDirection.includes(\"e\") || handleDirection.includes(\"w\")\n ? Math.abs(nextWidth) / width\n : 1;\n let scaleY =\n handleDirection.includes(\"n\") || handleDirection.includes(\"s\")\n ? Math.abs(nextHeight) / height\n : 1;\n\n let scale: number;\n\n if (handleDirection.length === 1) {\n scale =\n handleDirection.includes(\"e\") || handleDirection.includes(\"w\")\n ? scaleX\n : scaleY;\n } else {\n scale = Math.max(\n Math.abs(nextWidth) / width || 0,\n Math.abs(nextHeight) / height || 0,\n );\n }\n\n const anchorsMap = {\n ne: [minX, maxY],\n se: [minX, minY],\n sw: [maxX, minY],\n nw: [maxX, maxY],\n e: [minX, minY + height / 2],\n w: [maxX, minY + height / 2],\n n: [minX + width / 2, maxY],\n s: [minX + width / 2, minY],\n } as Record<TransformHandleDirection, GlobalPoint>;\n\n // anchor point must be on the opposite side of the dragged selection handle\n // or be the center of the selection if shouldResizeFromCenter\n const [anchorX, anchorY] = shouldResizeFromCenter\n ? [midX, midY]\n : anchorsMap[handleDirection];\n\n const keepAspectRatio =\n shouldMaintainAspectRatio ||\n targetElements.some(\n (item) =>\n item.latest.angle !== 0 ||\n isTextElement(item.latest) ||\n isInGroup(item.latest),\n );\n\n if (keepAspectRatio) {\n scaleX = scale;\n scaleY = scale;\n }\n\n /**\n * to flip an element:\n * 1. determine over which axis is the element being flipped\n * (could be x, y, or both) indicated by `flipFactorX` & `flipFactorY`\n * 2. shift element's position by the amount of width or height (or both) or\n * mirror points in the case of linear & freedraw elemenets\n * 3. adjust element angle\n */\n const [flipFactorX, flipFactorY] = [flipByX ? -1 : 1, flipByY ? -1 : 1];\n\n const elementsAndUpdates: {\n element: NonDeletedExcalidrawElement;\n update: Mutable<\n Pick<ExcalidrawElement, \"x\" | \"y\" | \"width\" | \"height\" | \"angle\">\n > & {\n points?: ExcalidrawLinearElement[\"points\"];\n fontSize?: ExcalidrawTextElement[\"fontSize\"];\n scale?: ExcalidrawImageElement[\"scale\"];\n boundTextFontSize?: ExcalidrawTextElement[\"fontSize\"];\n startBinding?: ExcalidrawElbowArrowElement[\"startBinding\"];\n endBinding?: ExcalidrawElbowArrowElement[\"endBinding\"];\n fixedSegments?: ExcalidrawElbowArrowElement[\"fixedSegments\"];\n };\n }[] = [];\n\n for (const { orig, latest } of targetElements) {\n // bounded text elements are updated along with their container elements\n if (isTextElement(orig) && isBoundToContainer(orig)) {\n continue;\n }\n\n const width = orig.width * scaleX;\n const height = orig.height * scaleY;\n const angle = normalizeRadians(\n (orig.angle * flipFactorX * flipFactorY) as Radians,\n );\n\n const isLinearOrFreeDraw =\n isLinearElement(orig) || isFreeDrawElement(orig);\n const offsetX = orig.x - anchorX;\n const offsetY = orig.y - anchorY;\n const shiftX = flipByX && !isLinearOrFreeDraw ? width : 0;\n const shiftY = flipByY && !isLinearOrFreeDraw ? height : 0;\n const x = anchorX + flipFactorX * (offsetX * scaleX + shiftX);\n const y = anchorY + flipFactorY * (offsetY * scaleY + shiftY);\n\n const rescaledPoints = rescalePointsInElement(\n orig,\n width * flipFactorX,\n height * flipFactorY,\n false,\n );\n\n const update: typeof elementsAndUpdates[0][\"update\"] = {\n x,\n y,\n width,\n height,\n angle,\n ...rescaledPoints,\n };\n\n if (isElbowArrow(orig)) {\n // Mirror fixed point binding for elbow arrows\n // when resize goes into the negative direction\n if (orig.startBinding) {\n update.startBinding = {\n ...orig.startBinding,\n fixedPoint: [\n flipByX\n ? -orig.startBinding.fixedPoint[0] + 1\n : orig.startBinding.fixedPoint[0],\n flipByY\n ? -orig.startBinding.fixedPoint[1] + 1\n : orig.startBinding.fixedPoint[1],\n ],\n };\n }\n if (orig.endBinding) {\n update.endBinding = {\n ...orig.endBinding,\n fixedPoint: [\n flipByX\n ? -orig.endBinding.fixedPoint[0] + 1\n : orig.endBinding.fixedPoint[0],\n flipByY\n ? -orig.endBinding.fixedPoint[1] + 1\n : orig.endBinding.fixedPoint[1],\n ],\n };\n }\n if (orig.fixedSegments && rescaledPoints.points) {\n update.fixedSegments = orig.fixedSegments.map((segment) => ({\n ...segment,\n start: rescaledPoints.points[segment.index - 1],\n end: rescaledPoints.points[segment.index],\n }));\n }\n }\n\n if (isImageElement(orig)) {\n update.scale = [\n orig.scale[0] * flipFactorX,\n orig.scale[1] * flipFactorY,\n ];\n }\n\n if (isTextElement(orig)) {\n const metrics = measureFontSizeFromWidth(orig, elementsMap, width);\n if (!metrics) {\n return;\n }\n update.fontSize = metrics.size;\n }\n\n const boundTextElement = originalElementsMap.get(\n getBoundTextElementId(orig) ?? \"\",\n ) as ExcalidrawTextElementWithContainer | undefined;\n\n if (boundTextElement) {\n if (keepAspectRatio) {\n const newFontSize = boundTextElement.fontSize * scale;\n if (newFontSize < MIN_FONT_SIZE) {\n return;\n }\n update.boundTextFontSize = newFontSize;\n } else {\n update.boundTextFontSize = boundTextElement.fontSize;\n }\n }\n\n elementsAndUpdates.push({\n element: latest,\n update,\n });\n }\n\n const elementsToUpdate = elementsAndUpdates.map(({ element }) => element);\n\n for (const {\n element,\n update: { boundTextFontSize, ...update },\n } of elementsAndUpdates) {\n const { width, height, angle } = update;\n\n mutateElement(element, update, false, {\n // needed for the fixed binding point udpate to take effect\n isDragging: true,\n });\n\n updateBoundElements(element, elementsMap as SceneElementsMap, {\n simultaneouslyUpdated: elementsToUpdate,\n newSize: { width, height },\n });\n\n const boundTextElement = getBoundTextElement(element, elementsMap);\n if (boundTextElement && boundTextFontSize) {\n mutateElement(\n boundTextElement,\n {\n fontSize: boundTextFontSize,\n angle: isLinearElement(element) ? undefined : angle,\n },\n false,\n );\n handleBindTextResize(element, elementsMap, handleDirection, true);\n }\n }\n\n scene.triggerUpdate();\n }\n};\n", "import { updateBoundElements } from \"./binding\";\nimport type { Bounds } from \"./bounds\";\nimport { getCommonBounds } from \"./bounds\";\nimport { mutateElement } from \"./mutateElement\";\nimport { getPerfectElementSize } from \"./sizeHelpers\";\nimport type { NonDeletedExcalidrawElement } from \"./types\";\nimport type {\n AppState,\n NormalizedZoomValue,\n NullableGridSize,\n PointerDownState,\n} from \"../types\";\nimport { getBoundTextElement } from \"./textElement\";\nimport type Scene from \"../scene/Scene\";\nimport {\n isArrowElement,\n isElbowArrow,\n isFrameLikeElement,\n isImageElement,\n isTextElement,\n} from \"./typeChecks\";\nimport { getFontString } from \"../utils\";\nimport { TEXT_AUTOWRAP_THRESHOLD } from \"../constants\";\nimport { getGridPoint } from \"../snapping\";\nimport { getMinTextElementWidth } from \"./textMeasurements\";\n\nexport const dragSelectedElements = (\n pointerDownState: PointerDownState,\n _selectedElements: NonDeletedExcalidrawElement[],\n offset: { x: number; y: number },\n scene: Scene,\n snapOffset: {\n x: number;\n y: number;\n },\n gridSize: NullableGridSize,\n) => {\n if (\n _selectedElements.length === 1 &&\n isElbowArrow(_selectedElements[0]) &&\n (_selectedElements[0].startBinding || _selectedElements[0].endBinding)\n ) {\n return;\n }\n\n const selectedElements = _selectedElements.filter((element) => {\n if (isElbowArrow(element) && element.startBinding && element.endBinding) {\n const startElement = _selectedElements.find(\n (el) => el.id === element.startBinding?.elementId,\n );\n const endElement = _selectedElements.find(\n (el) => el.id === element.endBinding?.elementId,\n );\n\n return startElement && endElement;\n }\n\n return true;\n });\n\n // we do not want a frame and its elements to be selected at the same time\n // but when it happens (due to some bug), we want to avoid updating element\n // in the frame twice, hence the use of set\n const elementsToUpdate = new Set<NonDeletedExcalidrawElement>(\n selectedElements,\n );\n const frames = selectedElements\n .filter((e) => isFrameLikeElement(e))\n .map((f) => f.id);\n\n if (frames.length > 0) {\n for (const element of scene.getNonDeletedElements()) {\n if (element.frameId !== null && frames.includes(element.frameId)) {\n elementsToUpdate.add(element);\n }\n }\n }\n\n const commonBounds = getCommonBounds(\n Array.from(elementsToUpdate).map(\n (el) => pointerDownState.originalElements.get(el.id) ?? el,\n ),\n );\n const adjustedOffset = calculateOffset(\n commonBounds,\n offset,\n snapOffset,\n gridSize,\n );\n\n elementsToUpdate.forEach((element) => {\n updateElementCoords(pointerDownState, element, adjustedOffset);\n if (!isArrowElement(element)) {\n // skip arrow labels since we calculate its position during render\n const textElement = getBoundTextElement(\n element,\n scene.getNonDeletedElementsMap(),\n );\n if (textElement) {\n updateElementCoords(pointerDownState, textElement, adjustedOffset);\n }\n updateBoundElements(element, scene.getElementsMapIncludingDeleted(), {\n simultaneouslyUpdated: Array.from(elementsToUpdate),\n });\n }\n });\n};\n\nconst calculateOffset = (\n commonBounds: Bounds,\n dragOffset: { x: number; y: number },\n snapOffset: { x: number; y: number },\n gridSize: NullableGridSize,\n): { x: number; y: number } => {\n const [x, y] = commonBounds;\n let nextX = x + dragOffset.x + snapOffset.x;\n let nextY = y + dragOffset.y + snapOffset.y;\n\n if (snapOffset.x === 0 || snapOffset.y === 0) {\n const [nextGridX, nextGridY] = getGridPoint(\n x + dragOffset.x,\n y + dragOffset.y,\n gridSize,\n );\n\n if (snapOffset.x === 0) {\n nextX = nextGridX;\n }\n\n if (snapOffset.y === 0) {\n nextY = nextGridY;\n }\n }\n return {\n x: nextX - x,\n y: nextY - y,\n };\n};\n\nconst updateElementCoords = (\n pointerDownState: PointerDownState,\n element: NonDeletedExcalidrawElement,\n dragOffset: { x: number; y: number },\n) => {\n const originalElement =\n pointerDownState.originalElements.get(element.id) ?? element;\n\n const nextX = originalElement.x + dragOffset.x;\n const nextY = originalElement.y + dragOffset.y;\n\n mutateElement(element, {\n x: nextX,\n y: nextY,\n });\n};\n\nexport const getDragOffsetXY = (\n selectedElements: NonDeletedExcalidrawElement[],\n x: number,\n y: number,\n): [number, number] => {\n const [x1, y1] = getCommonBounds(selectedElements);\n return [x - x1, y - y1];\n};\n\nexport const dragNewElement = ({\n newElement,\n elementType,\n originX,\n originY,\n x,\n y,\n width,\n height,\n shouldMaintainAspectRatio,\n shouldResizeFromCenter,\n zoom,\n widthAspectRatio = null,\n originOffset = null,\n informMutation = true,\n}: {\n newElement: NonDeletedExcalidrawElement;\n elementType: AppState[\"activeTool\"][\"type\"];\n originX: number;\n originY: number;\n x: number;\n y: number;\n width: number;\n height: number;\n shouldMaintainAspectRatio: boolean;\n shouldResizeFromCenter: boolean;\n zoom: NormalizedZoomValue;\n /** whether to keep given aspect ratio when `isResizeWithSidesSameLength` is\n true */\n widthAspectRatio?: number | null;\n originOffset?: {\n x: number;\n y: number;\n } | null;\n informMutation?: boolean;\n}) => {\n if (shouldMaintainAspectRatio && newElement.type !== \"selection\") {\n if (widthAspectRatio) {\n height = width / widthAspectRatio;\n } else {\n // Depending on where the cursor is at (x, y) relative to where the starting point is\n // (originX, originY), we use ONLY width or height to control size increase.\n // This allows the cursor to always \"stick\" to one of the sides of the bounding box.\n if (Math.abs(y - originY) > Math.abs(x - originX)) {\n ({ width, height } = getPerfectElementSize(\n elementType,\n height,\n x < originX ? -width : width,\n ));\n } else {\n ({ width, height } = getPerfectElementSize(\n elementType,\n width,\n y < originY ? -height : height,\n ));\n }\n\n if (height < 0) {\n height = -height;\n }\n }\n }\n\n let newX = x < originX ? originX - width : originX;\n let newY = y < originY ? originY - height : originY;\n\n if (shouldResizeFromCenter) {\n width += width;\n height += height;\n newX = originX - width / 2;\n newY = originY - height / 2;\n }\n\n let textAutoResize = null;\n\n if (isTextElement(newElement)) {\n height = newElement.height;\n const minWidth = getMinTextElementWidth(\n getFontString({\n fontSize: newElement.fontSize,\n fontFamily: newElement.fontFamily,\n }),\n newElement.lineHeight,\n );\n width = Math.max(width, minWidth);\n\n if (Math.abs(x - originX) > TEXT_AUTOWRAP_THRESHOLD / zoom) {\n textAutoResize = {\n autoResize: false,\n };\n }\n\n newY = originY;\n if (shouldResizeFromCenter) {\n newX = originX - width / 2;\n }\n }\n\n if (width !== 0 && height !== 0) {\n let imageInitialDimension = null;\n if (isImageElement(newElement)) {\n imageInitialDimension = {\n initialWidth: width,\n initialHeight: height,\n };\n }\n\n mutateElement(\n newElement,\n {\n x: newX + (originOffset?.x ?? 0),\n y: newY + (originOffset?.y ?? 0),\n width,\n height,\n ...textAutoResize,\n ...imageInitialDimension,\n },\n informMutation,\n );\n }\n};\n", "import type { NonDeletedExcalidrawElement } from \"./types\";\nimport { getSelectedElements } from \"../scene\";\nimport type { UIAppState } from \"../types\";\n\nexport const showSelectedShapeActions = (\n appState: UIAppState,\n elements: readonly NonDeletedExcalidrawElement[],\n) =>\n Boolean(\n !appState.viewModeEnabled &&\n appState.openDialog?.name !== \"elementLinkSelector\" &&\n ((appState.activeTool.type !== \"custom\" &&\n (appState.editingTextElement ||\n (appState.activeTool.type !== \"selection\" &&\n appState.activeTool.type !== \"eraser\" &&\n appState.activeTool.type !== \"hand\" &&\n appState.activeTool.type !== \"laser\"))) ||\n getSelectedElements(elements, appState).length),\n );\n", "import type {\n ExcalidrawElement,\n NonDeletedExcalidrawElement,\n NonDeleted,\n} from \"./types\";\nimport { isInvisiblySmallElement } from \"./sizeHelpers\";\nimport { isLinearElementType } from \"./typeChecks\";\n\nexport {\n newElement,\n newTextElement,\n refreshTextDimensions,\n newLinearElement,\n newArrowElement,\n newImageElement,\n duplicateElement,\n} from \"./newElement\";\nexport {\n getElementAbsoluteCoords,\n getElementBounds,\n getCommonBounds,\n getDiamondPoints,\n getArrowheadPoints,\n getClosestElementBounds,\n} from \"./bounds\";\n\nexport {\n OMIT_SIDES_FOR_MULTIPLE_ELEMENTS,\n getTransformHandlesFromCoords,\n getTransformHandles,\n} from \"./transformHandles\";\nexport {\n resizeTest,\n getCursorForResizingElement,\n getElementWithTransformHandleType,\n getTransformHandleTypeFromCoords,\n} from \"./resizeTest\";\nexport {\n transformElements,\n getResizeOffsetXY,\n getResizeArrowDirection,\n} from \"./resizeElements\";\nexport {\n dragSelectedElements,\n getDragOffsetXY,\n dragNewElement,\n} from \"./dragElements\";\nexport { isTextElement, isExcalidrawElement } from \"./typeChecks\";\nexport { redrawTextBoundingBox, getTextFromElements } from \"./textElement\";\nexport {\n getPerfectElementSize,\n getLockedLinearCursorAlignSize,\n isInvisiblySmallElement,\n resizePerfectLineForNWHandler,\n getNormalizedDimensions,\n} from \"./sizeHelpers\";\nexport { showSelectedShapeActions } from \"./showSelectedShapeActions\";\n\n/**\n * @deprecated unsafe, use hashElementsVersion instead\n */\nexport const getSceneVersion = (elements: readonly ExcalidrawElement[]) =>\n elements.reduce((acc, el) => acc + el.version, 0);\n\n/**\n * Hashes elements' versionNonce (using djb2 algo). Order of elements matters.\n */\nexport const hashElementsVersion = (\n elements: readonly ExcalidrawElement[],\n): number => {\n let hash = 5381;\n for (let i = 0; i < elements.length; i++) {\n hash = (hash << 5) + hash + elements[i].versionNonce;\n }\n return hash >>> 0; // Ensure unsigned 32-bit integer\n};\n\n// string hash function (using djb2). Not cryptographically secure, use only\n// for versioning and such.\nexport const hashString = (s: string): number => {\n let hash: number = 5381;\n for (let i = 0; i < s.length; i++) {\n const char: number = s.charCodeAt(i);\n hash = (hash << 5) + hash + char;\n }\n return hash >>> 0; // Ensure unsigned 32-bit integer\n};\n\nexport const getVisibleElements = (elements: readonly ExcalidrawElement[]) =>\n elements.filter(\n (el) => !el.isDeleted && !isInvisiblySmallElement(el),\n ) as readonly NonDeletedExcalidrawElement[];\n\nexport const getNonDeletedElements = <T extends ExcalidrawElement>(\n elements: readonly T[],\n) =>\n elements.filter((element) => !element.isDeleted) as readonly NonDeleted<T>[];\n\nexport const isNonDeletedElement = <T extends ExcalidrawElement>(\n element: T,\n): element is NonDeleted<T> => !element.isDeleted;\n\nconst _clearElements = (\n elements: readonly ExcalidrawElement[],\n): ExcalidrawElement[] =>\n getNonDeletedElements(elements).map((element) =>\n isLinearElementType(element.type)\n ? { ...element, lastCommittedPoint: null }\n : element,\n );\n\nexport const clearElementsForDatabase = (\n elements: readonly ExcalidrawElement[],\n) => _clearElements(elements);\n\nexport const clearElementsForExport = (\n elements: readonly ExcalidrawElement[],\n) => _clearElements(elements);\n\nexport const clearElementsForLocalStorage = (\n elements: readonly ExcalidrawElement[],\n) => _clearElements(elements);\n"],
5
+ "mappings": ";;;;;;;;;AAAA,OAAO,eAAe;AACtB,OAAO,UAAU;AACjB,OAAO,eAAe;;;ACFtB,SAAS,SAAS,eAAe;;;ACG1B,IAAM,WAAW,uBAAuB,KAAK,UAAU,QAAQ;AAC/D,IAAM,YAAY,OAAO,KAAK,UAAU,QAAQ;AAChD,IAAM,YAAY,iBAAiB,KAAK,UAAU,SAAS;AAC3D,IAAM,YACX,cAAc,UACd,UAAU,UAAU,QAAQ,KAAK,IAAI,KACrC,UAAU,UAAU,QAAQ,OAAO,IAAI;AAClC,IAAM,WAAW,UAAU,UAAU,QAAQ,QAAQ,MAAM;AAC3D,IAAM,WACX,CAAC,YAAY,UAAU,UAAU,QAAQ,QAAQ,MAAM;AAClD,IAAM,QACX,cAAc,KAAK,UAAU,QAAQ;AAEpC,UAAU,UAAU,SAAS,KAAK,KAAK,gBAAgB;AAEnD,IAAM,UAAU,MACpB,UAAkB,OAAO,SAAS,SAAS;AAEvC,IAAM,yBACX,OAAO,WAAW,eAAe,oBAAoB;AAEhD,IAAM,WAAW;AAMjB,IAAM,0BAA0B;AAChC,IAAM,qBAAqB;AAC3B,IAAM,yBAAyB;AAC/B,IAAM,iCAAiC;AACvC,IAAM,2BAA2B;AACjC,IAAM,gCAAgC;AACtC,IAAM,sBAAsB,KAAK,KAAK;AACtC,IAAM,sBAAsB;AAC5B,IAAM,cAAc;AAAA,EACzB,MAAM;AAAA,EACN,WAAW;AAAA,EACX,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AACR;AACO,IAAM,iBAAiB;AAAA,EAC5B,MAAM;AAAA,EACN,OAAO;AAAA,EACP,WAAW;AAAA,EACX,OAAO;AAAA,EACP,QAAQ;AACV;AAEO,IAAM,iBAAiB;AAAA,EAC5B,SAAS;AAAA,EACT,UAAU;AAAA;AAAA;AAAA,EAGV,eAAe;AACjB;AAoCO,IAAM,iBAAiB;AAAA,EAC5B,WAAW;AAAA,EACX,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,MAAM;AACR;AAEO,IAAM,MAAM;AAAA,EACjB,MAAM;AACR;AAEO,IAAM,UAAU;AAAA,EACrB,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,2BAA2B;AAC7B;AAEO,IAAM,+BAA+B;AACrC,IAAM,8BAA8B;AAUpC,IAAM,cAAc;AAAA,EACzB,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,UAAU;AAAA;AAAA,EAEV,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,mBAAmB;AACrB;AAEO,IAAM,wBAAwB;AAAA,EACnC,CAAC,4BAA4B,GAAG;AAAA,EAChC,CAAC,2BAA2B,GAAG;AACjC;AAEO,IAAM,yBAAyB,CACpC,eAC8C;AAC9C,UAAQ,YAAY;AAAA,IAClB,KAAK,YAAY;AACf,aAAO,CAAC,8BAA8B,2BAA2B;AAAA,IACnE;AACE,aAAO,CAAC,2BAA2B;AAAA,EACvC;AACF;AAEO,IAAM,QAAQ;AAAA,EACnB,OAAO;AAAA,EACP,MAAM;AACR;AAEO,IAAM,cAAc;AAAA,EACzB,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,gBAAgB;AAClB;AAEO,IAAM,gBAAgB;AACtB,IAAM,oBAAoB;AAC1B,IAAM,sBAAwC,YAAY;AAC1D,IAAM,qBAAqB;AAC3B,IAAM,yBAAyB;AAE/B,IAAM,mCAAmC;AACzC,IAAM,qBAAqB;AAI3B,IAAM,cAAc;AACpB,IAAM,uBAAuB;AAC7B,IAAM,oBAAoB;AAG1B,IAAM,0BAA0B,IAAI;AAGpC,IAAM,UAAU;AAChB,IAAM,8BACX,IAAI,0BAA0B;AAGzB,IAAM,mBAAmB;AAIzB,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AAE1B,IAAM,mBAAmB;AAAA,EAC9B,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AACR;AAEO,IAAM,aAAa;AAAA,EACxB,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA;AAAA,EAEN,YAAY;AAAA,EACZ,eAAe;AAAA;AAAA,EAEf,kBAAkB;AAAA,EAClB,kBAAkB;AAAA;AAAA,EAElB,QAAQ;AAAA;AAAA,EAER,GAAG;AACL;AAEO,IAAM,2BAA2B;AAAA,EACtC,WAAW;AAAA,EACX,WAAW;AAAA,EACX,GAAG,OAAO,OAAO,gBAAgB;AACnC;AAEO,IAAM,qBAAqB;AAAA,EAChC,KAAK;AAAA,EACL,KAAK;AAAA,EACL,WAAW;AACb;AAEO,IAAM,oBAAoB;AAAA,EAC/B,YAAY;AAAA,EACZ,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,4BAA4B;AAC9B;AAEO,IAAM,gBACX,OAAO,4BAA4B,OAAO,SAAS;AAG9C,IAAM,uBAAuB;AAC7B,IAAM,oBAAoB;AAC1B,IAAM,yBAAyB;AAG/B,IAAM,iBAAiB;AACvB,IAAM,YAAY;AAClB,IAAM,WAAW;AACjB,IAAM,WAAW;AACjB,IAAM,0BAA0B;AAQhC,IAAM,eAAe;AAErB,IAAM,iBAAiB;AAAA,EAC5B,YAAY;AACd;AAEO,IAAM,gBAAgB;AAAA,EAC3B,YAAY;AACd;AAEO,IAAM,qBAA4C;AAAA,EACvD,eAAe;AAAA,IACb,2BAA2B;AAAA,IAC3B,aAAa;AAAA,IACb,QAAQ,EAAE,gBAAgB,KAAK;AAAA,IAC/B,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,aAAa;AAAA,IACb,aAAa;AAAA,EACf;AAAA,EACA,OAAO;AAAA,IACL,OAAO;AAAA,EACT;AACF;AAKO,IAAM,wBAAwB;AAC9B,IAAM,yBAAyB;AAC/B,IAAM,0BAA0B;AAEhC,IAAM,6BAA6B;AAKnC,IAAM,8BAA8B;AAEpC,IAAM,gBAAgB,CAAC,GAAG,GAAG,CAAC;AAC9B,IAAM,yBAAyB;AAE/B,IAAM,oCAAoC;AAE1C,IAAM,yBAAyB,IAAI,OAAO;AAE1C,IAAM,SAAS;AAIf,IAAM,WAAW;AAAA,EACtB,YAAY;AAAA,EACZ,mBAAmB;AACrB;AAEO,IAAM,qBAAqB;AAC3B,IAAM,6BAA6B;AACnC,IAAM,2CAA2C;AAEjD,IAAM,iBAAiB;AAAA,EAC5B,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,QAAQ;AACV;AAEO,IAAM,aAAa;AAAA,EACxB,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AACT;AAEO,IAAM,iCAAiC;AAKvC,IAAM,8BAA8B;AAEpC,IAAM,0BAA0B;AAEhC,IAAM,YAAY;AAAA;AAAA;AAAA;AAAA,EAIvB,QAAQ;AAAA;AAAA,EAGR,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASrB,iBAAiB;AACnB;AAEO,IAAM,YAAY;AAAA,EACvB,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,YAAY;AACd;AAEO,IAAM,eAAe;AAAA,EAC1B,MAAM;AAAA,EACN,MAAM;AAAA,EACN,WAAW;AACb;AAEO,IAAM,wBAST;AAAA,EACF,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,aAAa;AAAA,EACb,aAAa;AAAA,EACb,WAAW,UAAU;AAAA,EACrB,SAAS;AAAA,EACT,QAAQ;AACV;AAEO,IAAM,sBAAsB;AAC5B,IAAM,oBAAoB;AAE1B,IAAM,kBAAkB;AAAA,EAC7B,MAAM;AAAA,EACN,YAAY;AACd;AAEO,IAAM,yBAAyB,oBAAI,IAAI;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AACF,CAAU;AAGH,IAAM,YAAY;AAAA,EACvB,WAAW;AAAA,EACX,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,OAAO;AACT;AAEO,IAAM,iBAAiB;AAAA,EAC5B,aAAa;AAAA;AAAA,EAEb,uBAAuB;AAAA,EACvB,iBAAiB;AACnB;AAMO,IAAM,mBAAmB;AAEzB,IAAM,eAAe,EAAE,cAAc,GAAG,mBAAmB,EAAE;AAE7D,IAAM,sBAAsB;AAE5B,IAAM,aAA6D;AAAA,EACxE,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACT;AAEO,IAAM,+BAA+B;AACrC,IAAM,mBAAmB;AAGzB,IAAM,UAAU,OAAO,IAAI,sBAAsB;AAEjD,IAAK,gBAAL,kBAAKA,mBAAL;AACL,EAAAA,eAAA,YAAS;AACT,EAAAA,eAAA,UAAO;AACP,EAAAA,eAAA,UAAO;AAHG,SAAAA;AAAA,GAAA;;;ACpdZ,SAAS,UAAAC,eAAc;;;ACgBvB,IAAM,qBAAqB,cAAc,SAAS,gBAAgB,IAC9D,mBACA;AAEG,IAAM,qBAAqB,MAG7B;AACH,SAAO;AAAA,IACL,mBAAmB;AAAA,IACnB,OAAO,MAAM;AAAA,IACb,eAAe,oBAAI,IAAI;AAAA,IACvB,kBAAkB;AAAA,IAClB,4BAA4B,sBAAsB;AAAA,IAClD,yBAAyB;AAAA,IACzB,sBAAsB,sBAAsB;AAAA,IAC5C,uBAAuB;AAAA,IACvB,qBAAqB;AAAA,IACrB,oBAAoB,sBAAsB;AAAA,IAC1C,sBAAsB,sBAAsB;AAAA,IAC5C,2BAA2B;AAAA,IAC3B,wBAAwB,sBAAsB;AAAA,IAC9C,sBAAsB;AAAA,IACtB,sBAAsB,WAAW;AAAA,IACjC,wBAAwB,sBAAsB;AAAA,IAC9C,wBAAwB,sBAAsB;AAAA,IAC9C,sBAAsB;AAAA,IACtB,0BAA0B;AAAA,IAC1B,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ,oBAAoB;AAAA,IACpB,gBAAgB;AAAA,IAChB,sBAAsB;AAAA,IACtB,YAAY;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,QAAQ,sBAAsB;AAAA,MAC9B,gBAAgB;AAAA,IAClB;AAAA,IACA,SAAS;AAAA,IACT,aAAa;AAAA,IACb,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,aAAa;AAAA,IACb,kBAAkB;AAAA,IAClB,oBAAoB;AAAA,IACpB,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,UAAU;AAAA,IACV,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,gCAAgC;AAAA,IAChC,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,qBAAqB;AAAA,IACrB,cAAc;AAAA,IACd,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,IACV,WAAW;AAAA,IACX,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,aAAa,EAAE,OAAO,OAAO,MAAM,KAAK;AAAA,IACxC,4BAA4B,CAAC;AAAA,IAC7B,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,SAAS;AAAA,IACT,SAAS;AAAA,IACT,oBAAoB,CAAC;AAAA,IACrB,mBAAmB,CAAC;AAAA,IACpB,kBAAkB,CAAC;AAAA,IACnB,iCAAiC;AAAA,IACjC,kBAAkB;AAAA,IAClB,uBAAuB;AAAA,IACvB,OAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,aAAa,eAAe,aAAa;AAAA,IACnD;AAAA,IACA,mBAAmB;AAAA,IACnB,mBAAmB,CAAC;AAAA,IACpB,gBAAgB,EAAE,SAAS,MAAM,MAAM,MAAM,MAAM,MAAM,SAAS,KAAK;AAAA,IACvE,kBAAkB;AAAA,IAClB,cAAc;AAAA,IACd,qBAAqB;AAAA,IACrB,OAAO;AAAA,IACP,qBAAqB;AAAA,IACrB,gBAAgB;AAAA,IAChB,MAAM;AAAA,MACJ,OAAO;AAAA,IACT;AAAA,IACA,iBAAiB;AAAA,IACjB,uBAAuB;AAAA,IACvB,oBAAoB;AAAA,IACpB,uBAAuB;AAAA,IACvB,WAAW,CAAC;AAAA,IACZ,kBAAkB;AAAA,MAChB,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,IACA,wBAAwB;AAAA,IACxB,cAAc;AAAA,IACd,YAAY,oBAAI,IAAI;AAAA,IACpB,YAAY;AAAA,IACZ,mBAAmB;AAAA,IACnB,eAAe,CAAC;AAAA,EAClB;AACF;AAMA,IAAM,yBAA0B,kBAU9B,WACA,QAAQ;AAAA,EACR,mBAAmB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACjE,OAAO,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACrD,eAAe,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC9D,kBAAkB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAChE,4BAA4B,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC1E,yBAAyB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACvE,sBAAsB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACpE,uBAAuB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACrE,qBAAqB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACnE,sBAAsB;AAAA,IACpB,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AAAA,EACA,sBAAsB;AAAA,IACpB,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AAAA,EACA,oBAAoB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAClE,sBAAsB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACpE,2BAA2B,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACzE,wBAAwB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACtE,wBAAwB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACtE,wBAAwB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACtE,sBAAsB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACpE,0BAA0B,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACzE,cAAc,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC5D,kBAAkB,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACjE,YAAY,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC3D,oBAAoB,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACnE,gBAAgB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC9D,sBAAsB,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACrE,YAAY,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC1D,SAAS,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACvD,aAAa,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC3D,cAAc,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC7D,kBAAkB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAChE,kBAAkB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAChE,aAAa,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC3D,oBAAoB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAClE,YAAY,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC3D,UAAU,EAAE,SAAS,MAAM,QAAQ,MAAM,QAAQ,KAAK;AAAA,EACtD,UAAU,EAAE,SAAS,MAAM,QAAQ,MAAM,QAAQ,KAAK;AAAA,EACtD,iBAAiB,EAAE,SAAS,MAAM,QAAQ,MAAM,QAAQ,KAAK;AAAA,EAC7D,QAAQ,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACvD,kBAAkB,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACjE,gCAAgC;AAAA,IAC9B,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AAAA,EACA,WAAW,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC1D,YAAY,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC3D,YAAY,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC3D,qBAAqB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACnE,cAAc,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC7D,MAAM,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACpD,YAAY,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC3D,WAAW,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC1D,aAAa,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC5D,UAAU,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACxD,WAAW,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC1D,aAAa,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC3D,YAAY,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC3D,aAAa,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC5D,4BAA4B,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC1E,iBAAiB,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAChE,iBAAiB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC/D,SAAS,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACvD,SAAS,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACvD,oBAAoB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAClE,mBAAmB,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAClE,kBAAkB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAChE,iCAAiC;AAAA,IAC/B,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AAAA,EACA,kBAAkB,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACjE,uBAAuB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACrE,OAAO,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACrD,mBAAmB,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAClE,mBAAmB,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAClE,gBAAgB,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC/D,kBAAkB,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACjE,cAAc,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC7D,qBAAqB,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACpE,OAAO,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACtD,qBAAqB,EAAE,SAAS,MAAM,QAAQ,MAAM,QAAQ,KAAK;AAAA,EACjE,OAAO,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACtD,gBAAgB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC9D,MAAM,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACpD,iBAAiB,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAChE,uBAAuB,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACtE,oBAAoB,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACnE,uBAAuB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACrE,WAAW,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC1D,kBAAkB,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACjE,wBAAwB,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACtE,cAAc,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC7D,YAAY,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC3D,YAAY,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAC3D,mBAAmB,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAAA,EAClE,eAAe,EAAE,SAAS,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAChE,CAAC;AAED,IAAM,2BAA2B,CAG/B,UACA,eACG;AAMH,QAAM,iBAAiB,CAAC;AACxB,aAAW,OAAO,OAAO,KAAK,QAAQ,GAAgC;AACpE,UAAM,aAAa,uBAAuB,GAAG;AAC7C,QAAI,aAAa,UAAU,GAAG;AAC5B,YAAM,YAAY,SAAS,GAAG;AAG9B,MAAC,eAAuB,GAAG,IAAI;AAAA,IACjC;AAAA,EACF;AACA,SAAO;AACT;AAEO,IAAM,+BAA+B,CAAC,aAAgC;AAC3E,SAAO,yBAAyB,UAAU,SAAS;AACrD;AAEO,IAAM,yBAAyB,CAAC,aAAgC;AACrE,SAAO,yBAAyB,UAAU,QAAQ;AACpD;AAEO,IAAM,2BAA2B,CAAC,aAAgC;AACvE,SAAO,yBAAyB,UAAU,QAAQ;AACpD;AAEO,IAAM,iBAAiB,CAAC;AAAA,EAC7B;AACF,MAEM,WAAW,SAAS;AAEnB,IAAM,mBAAmB,CAAC;AAAA,EAC/B;AACF,MAEM;AACJ,SAAO,WAAW,SAAS;AAC7B;;;ACzSA,OAAO,cAAc;;;ACArB,OAAO,UAAU;;;ACAV,IAAM,YAAY;AAElB,IAAM,QAAQ,CAAC,OAAe,KAAa,QAAgB;AAChE,SAAO,KAAK,IAAI,KAAK,IAAI,OAAO,GAAG,GAAG,GAAG;AAC3C;AAEO,IAAM,QAAQ,CACnB,OACA,WACA,OAAmC,YAChC;AACH,QAAM,aAAa,KAAK,IAAI,IAAI,SAAS;AAEzC,SAAO,KAAK,IAAI,GAAG,QAAQ,OAAO,WAAW,UAAU,IAAI;AAC7D;AAEO,IAAM,cAAc,CACzB,OACA,MACA,OAAmC,YACxB;AACX,QAAM,SAAS,IAAI;AACnB,SAAO,KAAK,IAAI,EAAE,QAAQ,MAAM,IAAI;AACtC;AAEO,IAAM,UAAU,CAAC,GAAW,OAAe,IAAI,KAAK;AAEpD,IAAM,iBAAiB,CAAC,UAAgC;AAC7D,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AAC3D;AAEO,IAAM,YAAY,CAAC,GAAW,GAAW,YAAY,cAC1D,KAAK,IAAI,IAAI,CAAC,IAAI;;;ACtBb,IAAM,mBAAmB,CAAC,UAA4B;AAC3D,MAAI,QAAQ,GAAG;AACb,WAAQ,QAAQ,IAAI,KAAK;AAAA,EAC3B;AACA,MAAI,SAAS,IAAI,KAAK,IAAI;AACxB,WAAQ,QAAQ,IAAI,KAAK;AAAA,EAC3B;AACA,SAAO;AACT;AAeO,SAAS,iBAAiB,SAA2B;AAC1D,SAAS,UAAU,KAAK,KAAM;AAChC;AAEO,SAAS,iBAAiB,SAA2B;AAC1D,SAAS,UAAU,MAAO,KAAK;AACjC;AAQO,SAAS,iBAAiB,MAAwB;AACvD,SAAO,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI;AACxC;;;ACxCO,SAAS,OACd,GACA,GACA,UAAkB,GAClB,UAAkB,GACV;AACR,SAAO,CAAC,IAAI,SAAS,IAAI,OAAO;AAClC;AASO,SAAS,gBACd,GACA,SAAgB,CAAC,GAAG,CAAC,GACb;AACR,SAAO,OAAO,EAAE,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC;AAClD;AAUO,SAAS,YAAY,GAAW,GAAmB;AACxD,SAAO,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AACjC;AAUO,SAAS,UAAU,GAAW,GAAW;AAC9C,SAAO,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AACjC;AA0BO,SAAS,UAAU,GAAqB,GAA6B;AAC1E,SAAO,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAClC;AASO,SAAS,eACdC,QACA,KACQ;AACR,SAAO,CAACA,OAAM,CAAC,IAAI,IAAI,CAAC,GAAGA,OAAM,CAAC,IAAI,IAAI,CAAC,CAAC;AAC9C;AASO,SAAS,YAAY,GAAW,QAAwB;AAC7D,SAAO,OAAO,EAAE,CAAC,IAAI,QAAQ,EAAE,CAAC,IAAI,MAAM;AAC5C;AASO,SAAS,kBAAkB,GAAW;AAC3C,SAAO,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AACjC;AAQO,SAAS,gBAAgB,GAAW;AACzC,SAAO,KAAK,KAAK,kBAAkB,CAAC,CAAC;AACvC;AAQO,IAAM,kBAAkB,CAAC,MAAsB;AACpD,QAAM,IAAI,gBAAgB,CAAC;AAE3B,MAAI,MAAM,GAAG;AACX,WAAO,OAAO,GAAG,CAAC;AAAA,EACpB;AAEA,SAAO,OAAO,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC;AAClC;;;AC9HO,SAAS,UACd,GACA,GACO;AACP,SAAO,CAAC,GAAG,CAAC;AACd;AAQO,SAAS,eACd,aACmB;AACnB,SAAO,YAAY,WAAW,IAC1B,UAAiB,YAAY,CAAC,GAAG,YAAY,CAAC,CAAC,IAC/C;AACN;AAQO,SAAS,cACd,MACO;AACP,SAAO;AACT;AAQO,SAAS,gBACd,GACA,SAAY,UAAU,GAAG,CAAC,GACvB;AACH,SAAO,UAAa,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AACxD;AAQO,SAAS,QAAQ,GAA2C;AACjE,SACE,MAAM,QAAQ,CAAC,KACf,EAAE,WAAW,KACb,OAAO,EAAE,CAAC,MAAM,YAChB,CAAC,MAAM,EAAE,CAAC,CAAC,KACX,OAAO,EAAE,CAAC,MAAM,YAChB,CAAC,MAAM,EAAE,CAAC,CAAC;AAEf;AAUO,SAAS,YACd,GACA,GACS;AACT,QAAM,MAAM,KAAK;AACjB,SAAO,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,aAAa,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI;AAC5D;AAUO,SAAS,gBACd,CAAC,GAAG,CAAC,GACL,CAAC,IAAI,EAAE,GACP,OACO;AACP,SAAO;AAAA,KACJ,IAAI,MAAM,KAAK,IAAI,KAAK,KAAK,IAAI,MAAM,KAAK,IAAI,KAAK,IAAI;AAAA,KACzD,IAAI,MAAM,KAAK,IAAI,KAAK,KAAK,IAAI,MAAM,KAAK,IAAI,KAAK,IAAI;AAAA,EAC5D;AACF;AA+BO,SAAS,eAGd,GAAS,IAAY,CAAC,GAAG,CAAC,GAAiB;AAC3C,SAAO,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3C;AASO,SAAS,YAAgD,GAAM,GAAS;AAC7E,SAAO,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;AACvD;AASO,SAAS,cACd,GACA,GACQ;AACR,SAAO,KAAK,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAC5C;AAWO,SAAS,gBACd,GACA,GACQ;AACR,QAAM,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;AACxB,QAAM,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;AAExB,SAAO,QAAQ,QAAQ,QAAQ;AACjC;AAUO,IAAM,uBAAuB,CAClC,GACA,KACA,eACG,eAAe,KAAK,YAAY,gBAAgB,GAAG,GAAG,GAAG,UAAU,CAAC;AAWlE,IAAM,sBAAsB,CACjC,GACA,GACA,MACG;AACH,SACE,EAAE,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,KAC3B,EAAE,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,KAC3B,EAAE,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,KAC3B,EAAE,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;AAE/B;;;AC7NO,SAAS,KAAyC,GAAM,GAAe;AAC5E,SAAO,CAAC,GAAG,CAAC;AACd;AAUO,SAAS,iBACd,GACA,GACc;AACd,QAAM,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;AAC3B,QAAM,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;AAC3B,QAAM,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;AAC3B,QAAM,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;AAC3B,QAAM,IAAI,KAAK,KAAK,KAAK;AACzB,MAAI,MAAM,GAAG;AACX,UAAM,KAAK,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,CAAC;AACrC,UAAM,KAAK,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,CAAC;AACrC,WAAO,WAAkB,KAAK,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,KAAK,MAAM,CAAC;AAAA,EAC1E;AAEA,SAAO;AACT;;;ACdO,SAAS,YACd,GACA,GACgB;AAChB,SAAO,CAAC,GAAG,CAAC;AACd;AAwEO,IAAM,qBAAqB,CAChC,OACAC,OACA,YAAY,cACT;AACH,QAAMC,YAAW,sBAAsB,OAAOD,KAAI;AAElD,MAAIC,cAAa,GAAG;AAClB,WAAO;AAAA,EACT;AAEA,SAAOA,YAAW;AACpB;AAEO,IAAM,wBAAwB,CACnC,OACAD,UACG;AACH,QAAM,CAAC,GAAG,CAAC,IAAI;AACf,QAAM,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,IAAIA;AAE7B,QAAM,IAAI,IAAI;AACd,QAAM,IAAI,IAAI;AACd,QAAM,IAAI,KAAK;AACf,QAAM,IAAI,KAAK;AAEf,QAAM,MAAM,IAAI,IAAI,IAAI;AACxB,QAAM,SAAS,IAAI,IAAI,IAAI;AAC3B,MAAI,QAAQ;AACZ,MAAI,WAAW,GAAG;AAChB,YAAQ,MAAM;AAAA,EAChB;AAEA,MAAI;AACJ,MAAI;AAEJ,MAAI,QAAQ,GAAG;AACb,SAAK;AACL,SAAK;AAAA,EACP,WAAW,QAAQ,GAAG;AACpB,SAAK;AACL,SAAK;AAAA,EACP,OAAO;AACL,SAAK,KAAK,QAAQ;AAClB,SAAK,KAAK,QAAQ;AAAA,EACpB;AAEA,QAAM,KAAK,IAAI;AACf,QAAM,KAAK,IAAI;AACf,SAAO,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AACpC;AASO,SAAS,8BAEd,GAAuB,GAAqC;AAC5D,QAAM,YAAY,iBAAiB,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AAErE,MACE,CAAC,aACD,CAAC,mBAAmB,WAAW,CAAC,KAChC,CAAC,mBAAmB,WAAW,CAAC,GAChC;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;ACzKO,SAAS,UACd,SACA,aACc;AACd,SAAO,CAAC,SAAS,WAAW;AAC9B;AAEO,SAAS,8BAEd,GAAqB,GAAgC;AACrD,SAAO;AAAA,IACL,YAAY,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAAA,IAC7C,YAAY,UAAU,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;AAAA,IAC7C,YAAY,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAAA,IAC7C,YAAY,UAAU,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;AAAA,EAC/C,EACG,IAAI,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC,EAC9C,OAAO,CAAC,MAAkB,CAAC,CAAC,CAAC;AAClC;;;ACTO,SAAS,MACd,GACA,GACA,GACA,GACA;AACA,SAAO,CAAC,GAAG,GAAG,GAAG,CAAC;AACpB;AAEA,SAAS,SACP,GACA,IACA,IACA,QAAgB,MACN;AACV,SAAO;AAAA,KACJ,EAAE,KAAK,OAAO,EAAE,IAAI,EAAE,KAAK,OAAO,EAAE,MAAM,IAAI;AAAA,KAC9C,EAAE,IAAI,KAAK,KAAK,IAAI,EAAE,IAAI,KAAK,KAAK,MAAM,IAAI;AAAA,EACjD;AACF;AAEA,SAAS,MACP,GACA,IACA,IACA,YAAoB,MACpB,YAAoB,IACH;AACjB,MAAI,QAAQ;AACZ,MAAI,OAAO;AAEX,SAAO,SAAS,WAAW;AACzB,QAAI,QAAQ,WAAW;AACrB,aAAO;AAAA,IACT;AAEA,UAAM,KAAK,EAAE,IAAI,EAAE;AACnB,UAAM,WAAW;AAAA,MACf,SAAS,CAAC,GAAG,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE;AAAA,MACrC,SAAS,CAAC,GAAG,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE;AAAA,IACvC;AACA,UAAM,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7B,UAAM,MACJ,SAAS,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC,EAAE,CAAC;AAElE,QAAI,QAAQ,GAAG;AACb,aAAO;AAAA,IACT;AAEA,UAAM,KAAK;AAAA,MACT,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,GAAG;AAAA,MAC5C,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,CAAC,IAAI,GAAG;AAAA,IAC9C;AACA,UAAM,IAAI;AAAA,MACR,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;AAAA,MACxC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;AAAA,IAC1C;AAEA,SAAK,KAAK,EAAE,CAAC,EAAE,CAAC;AAChB,SAAK,KAAK,EAAE,CAAC,EAAE,CAAC;AAEhB,UAAM,CAAC,MAAM,IAAI,IAAI,EAAE,IAAI,EAAE;AAC7B,YAAQ,KAAK,IAAI,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC;AAC/C,YAAQ;AAAA,EACV;AAEA,SAAO,CAAC,IAAI,EAAE;AAChB;AAEA,IAAM,iBAAiB,CACrB,GACA,MAEA;AAAA,GACG,IAAI,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC,IACnB,KAAK,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC,IAC7B,KAAK,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC,IAC7B,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;AAAA,GAChB,IAAI,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC,IACnB,KAAK,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC,IAC7B,KAAK,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC,IAC7B,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;AACnB;AAKK,SAAS,0BAEd,GAAiB,GAAgC;AAEjD,QAAM,SAAS,YAAY,CAAC;AAC5B,MACE;AAAA,IACE;AAAA,MACE,UAAU,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,MAC9B,UAAU,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,IAChC;AAAA,IACA;AAAA,EACF,EAAE,WAAW,GACb;AACA,WAAO,CAAC;AAAA,EACV;AAEA,QAAME,QAAO,CAAC,MACZ;AAAA,IACE,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;AAAA,IAC/B,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;AAAA,EACjC;AAEF,QAAM,kBAAsC;AAAA,IAC1C,CAAC,KAAK,CAAC;AAAA,IACP,CAAC,KAAK,CAAC;AAAA,IACP,CAAC,KAAK,CAAC;AAAA,EACT;AAEA,QAAM,YAAY,CAAC,CAAC,IAAI,EAAE,MAAwB;AAChD,UAAMC,YAAW;AAAA,MACf,CAACC,IAAWC,OAAc;AACxB,cAAM,eAAe,eAAe,GAAGD,EAAC;AACxC,cAAM,aAAaF,MAAKG,EAAC;AAEzB,eAAO;AAAA,UACL,aAAa,CAAC,IAAI,WAAW,CAAC;AAAA,UAC9B,aAAa,CAAC,IAAI,WAAW,CAAC;AAAA,QAChC;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI,CAACF,WAAU;AACb,aAAO;AAAA,IACT;AAEA,UAAM,CAAC,GAAG,CAAC,IAAIA;AAEf,QAAI,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,GAAG;AACpC,aAAO;AAAA,IACT;AAEA,WAAO,eAAe,GAAG,CAAC;AAAA,EAC5B;AAEA,MAAI,WAAW,UAAU,gBAAgB,CAAC,CAAC;AAC3C,MAAI,UAAU;AACZ,WAAO,CAAC,QAAQ;AAAA,EAClB;AAEA,aAAW,UAAU,gBAAgB,CAAC,CAAC;AACvC,MAAI,UAAU;AACZ,WAAO,CAAC,QAAQ;AAAA,EAClB;AAEA,aAAW,UAAU,gBAAgB,CAAC,CAAC;AACvC,MAAI,UAAU;AACZ,WAAO,CAAC,QAAQ;AAAA,EAClB;AAEA,SAAO,CAAC;AACV;AAeO,SAAS,kBACd,GACA,GACA,YAAoB,MACN;AACd,QAAM,eAAe,CACnB,KACA,KACA,GACA,IAAY,cACT;AACH,QAAI,IAAI;AACR,QAAI,IAAI;AACR,QAAI;AAEJ,WAAO,IAAI,IAAI,GAAG;AAChB,WAAK,IAAI,KAAK;AACd,UAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG;AACvB,YAAI;AAAA,MACN,OAAO;AACL,YAAI;AAAA,MACN;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,WAAW;AACjB,MAAI,cAAc;AAClB,WAAS,MAAM,UAAU,OAAO,GAAG,OAAO,UAAU,QAAQ;AAC1D,UAAM,IAAI,cAAc,GAAG,eAAe,GAAG,OAAO,QAAQ,CAAC;AAC7D,QAAI,IAAI,KAAK;AACX,YAAM;AACN,oBAAc;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,KAAK,KAAK,KAAK,cAAc,KAAK,UAAU,CAAC;AACnD,QAAM,KAAK,KAAK,KAAK,cAAc,KAAK,UAAU,CAAC;AACnD,QAAM,WAAW;AAAA,IAAa;AAAA,IAAI;AAAA,IAAI,CAAC,MACrC,cAAc,GAAG,eAAe,GAAG,CAAC,CAAC;AAAA,EACvC;AAEA,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAEA,SAAO,eAAe,GAAG,QAAQ;AACnC;AASO,SAAS,mBACd,GACA,GACA;AACA,QAAM,UAAU,kBAAkB,GAAG,CAAC;AAEtC,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,SAAO,cAAc,GAAG,OAAO;AACjC;AAkBA,SAAS,YACP,GACQ;AACR,QAAM,CAAC,IAAI,IAAI,IAAI,EAAE,IAAI;AACzB,QAAM,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AACrC,QAAM,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AACrC,SAAO,CAAC,KAAK,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC;AACxE;;;ACpRO,SAAS,WACX,QACH;AACA,SAAO,aAAa,MAAM;AAC5B;AAEO,SAAS,kBACd,QACA;AACA,SAAO,aAAa,MAAM;AAC5B;AAEO,IAAM,uBAAuB,CAClC,OACAG,aACG;AACH,QAAM,IAAI,MAAM,CAAC;AACjB,QAAM,IAAI,MAAM,CAAC;AACjB,MAAI,SAAS;AAEb,WAAS,IAAI,GAAG,IAAIA,SAAQ,SAAS,GAAG,IAAIA,SAAQ,QAAQ,IAAI,KAAK;AACnE,UAAM,KAAKA,SAAQ,CAAC,EAAE,CAAC;AACvB,UAAM,KAAKA,SAAQ,CAAC,EAAE,CAAC;AACvB,UAAM,KAAKA,SAAQ,CAAC,EAAE,CAAC;AACvB,UAAM,KAAKA,SAAQ,CAAC,EAAE,CAAC;AAEvB,SACI,KAAK,KAAK,MAAM,KAAO,MAAM,KAAK,KAAK,MACzC,KAAM,KAAK,OAAO,IAAI,OAAQ,KAAK,MAAM,IACzC;AACA,eAAS,CAAC;AAAA,IACZ;AAAA,EACF;AAEA,SAAO;AACT;AAEO,IAAM,iBAAiB,CAC5B,GACA,MACA,YAAY,cACT;AACH,MAAI,KAAK;AAET,WAAS,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,IAAI,GAAG,KAAK;AAC/C,QAAI,mBAAmB,GAAG,YAAY,KAAK,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,GAAG,SAAS,GAAG;AACvE,WAAK;AACL;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,aACPA,UACA;AACA,SAAO,gBAAgBA,QAAO,IAC1BA,WACC,CAAC,GAAGA,UAASA,SAAQ,CAAC,CAAC;AAC9B;AAEA,SAAS,gBACPA,UACA;AACA,SAAO,YAAYA,SAAQ,CAAC,GAAGA,SAAQA,SAAQ,SAAS,CAAC,CAAC;AAC5D;;;AC7DO,SAAS,eAAeC,QAAe,KAA6B;AACzE,SAAO,cAA8B,CAACA,QAAO,GAAG,CAAC;AACnD;AAoBO,IAAM,gBAAgB,CAC3B,CAAC,IAAI,EAAE,GACP,CAAC,IAAI,EAAE,MACK;AACZ,MAAI,MAAM,IAAI;AACZ,WAAO,MAAM;AAAA,EACf;AAEA,MAAI,MAAM,IAAI;AACZ,WAAO,MAAM;AAAA,EACf;AAEA,SAAO;AACT;AAUO,IAAM,oBAAoB,CAC/B,CAAC,IAAI,EAAE,GACP,CAAC,IAAI,EAAE,MACmB;AAC1B,QAAM,aAAa,KAAK,IAAI,IAAI,EAAE;AAClC,QAAM,WAAW,KAAK,IAAI,IAAI,EAAE;AAEhC,MAAI,cAAc,UAAU;AAC1B,WAAO,cAA8B,CAAC,YAAY,QAAQ,CAAC;AAAA,EAC7D;AAEA,SAAO;AACT;AASO,IAAM,qBAAqB,CAChC,OACA,CAAC,KAAK,GAAG,MACG;AACZ,SAAO,SAAS,OAAO,SAAS;AAClC;;;ACpEO,SAAS,sBACd,CAAC,GAAG,GAAG,CAAC,GACR,GACS;AACT,QAAM,eAAe,CAAC,IAAO,IAAO,QACjC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC;AACrE,QAAM,KAAK,aAAa,GAAG,GAAG,CAAC;AAC/B,QAAM,KAAK,aAAa,GAAG,GAAG,CAAC;AAC/B,QAAM,KAAK,aAAa,GAAG,GAAG,CAAC;AAE/B,QAAM,UAAU,KAAK,KAAK,KAAK,KAAK,KAAK;AACzC,QAAM,UAAU,KAAK,KAAK,KAAK,KAAK,KAAK;AAEzC,SAAO,EAAE,WAAW;AACtB;;;AXFA,IAAI,eAA8B;AAM3B,IAAM,cAAc,MAAM;AAC/B,MAAI,cAAc;AAChB,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,oBAAI,KAAK;AACtB,QAAM,OAAO,KAAK,YAAY;AAC9B,QAAM,QAAQ,GAAG,KAAK,SAAS,IAAI,CAAC,GAAG,SAAS,GAAG,GAAG;AACtD,QAAM,MAAM,GAAG,KAAK,QAAQ,CAAC,GAAG,SAAS,GAAG,GAAG;AAC/C,QAAM,KAAK,GAAG,KAAK,SAAS,CAAC,GAAG,SAAS,GAAG,GAAG;AAC/C,QAAM,MAAM,GAAG,KAAK,WAAW,CAAC,GAAG,SAAS,GAAG,GAAG;AAElD,SAAO,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,EAAE,GAAG,GAAG;AAC5C;AAEO,IAAM,mBAAmB,CAAC,QAC/B,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAEpC,IAAM,aAAa,CACxB,WAEA,kBAAkB,eAAe,OAAO,UAAU,SAAS,UAAU;AAEhE,IAAM,cAAc,CACzB,WAOC,kBAAkB,eAAe,OAAO,QAAQ,SAAS,aAC1D,kBAAkB;AAClB,kBAAkB,oBAClB,kBAAkB,uBAClB,kBAAkB;AAEb,IAAM,gBAAgB,CAAC,WAAyC;AACrE,SACE,YAAY,MAAM,KACjB,kBAAkB,WAAW,CAAC,CAAC,OAAO,QAAQ,eAAe;AAElE;AAEO,IAAM,oBAAoB,CAC/B,WAMC,kBAAkB,eAAe,OAAO,QAAQ,SAAS,aAC1D,kBAAkB;AAClB,kBAAkB,uBACjB,kBAAkB,qBAChB,OAAO,SAAS,UACf,OAAO,SAAS,YAChB,OAAO,SAAS;AAEf,IAAM,sBAAsB,CAAC;AAAA,EAClC;AACF,MAEM;AACJ,aAAW,CAAC,kBAAkB,EAAE,KAAK,OAAO,QAAQ,WAAW,GAAG;AAChE,QAAI,OAAO,YAAY;AAErB,aAAO,GAAG,gBAAgB,GAAG,uBAAuB,EAAE,EACnD,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EACnB,KAAK,EAAE,CAAC;AAAA,IACb;AAAA,EACF;AACA,SAAO;AACT;AAGO,IAAM,gBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA;AACF,MAGM;AACJ,SAAO,GAAG,QAAQ,MAAM,oBAAoB,EAAE,WAAW,CAAC,CAAC;AAC7D;AAEO,IAAM,WAAW,CACtB,IACA,YACG;AACH,MAAI,SAAS;AACb,MAAI,WAAqB;AACzB,QAAM,MAAM,IAAI,SAAY;AAC1B,eAAW;AACX,iBAAa,MAAM;AACnB,aAAS,OAAO,WAAW,MAAM;AAC/B,iBAAW;AACX,SAAG,GAAG,IAAI;AAAA,IACZ,GAAG,OAAO;AAAA,EACZ;AACA,MAAI,QAAQ,MAAM;AAChB,iBAAa,MAAM;AACnB,QAAI,UAAU;AACZ,YAAM,YAAY;AAClB,iBAAW;AACX,SAAG,GAAG,SAAS;AAAA,IACjB;AAAA,EACF;AACA,MAAI,SAAS,MAAM;AACjB,eAAW;AACX,iBAAa,MAAM;AAAA,EACrB;AACA,SAAO;AACT;AAGO,IAAM,cAAc,CACzB,IACA,SACG;AACH,MAAI,UAAyB;AAC7B,MAAI,WAAqB;AACzB,MAAI,mBAA6B;AAEjC,QAAM,eAAe,CAAC,SAAY;AAChC,cAAU,OAAO,sBAAsB,MAAM;AAC3C,gBAAU;AACV,SAAG,GAAG,IAAI;AACV,iBAAW;AACX,UAAI,kBAAkB;AACpB,mBAAW;AACX,2BAAmB;AACnB,qBAAa,QAAQ;AAAA,MACvB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,MAAM,IAAI,SAAY;AAC1B,QAAI,+BAAgB,SAAS,QAAQ;AACnC,SAAG,GAAG,IAAI;AACV;AAAA,IACF;AACA,eAAW;AACX,QAAI,YAAY,MAAM;AACpB,mBAAa,QAAQ;AAAA,IACvB,WAAW,MAAM,UAAU;AACzB,yBAAmB;AAAA,IACrB;AAAA,EACF;AACA,MAAI,QAAQ,MAAM;AAChB,QAAI,YAAY,MAAM;AACpB,2BAAqB,OAAO;AAC5B,gBAAU;AAAA,IACZ;AACA,QAAI,UAAU;AACZ,SAAG,GAAI,oBAAoB,QAAS;AACpC,iBAAW,mBAAmB;AAAA,IAChC;AAAA,EACF;AACA,MAAI,SAAS,MAAM;AACjB,eAAW,mBAAmB;AAC9B,QAAI,YAAY,MAAM;AACpB,2BAAqB,OAAO;AAC5B,gBAAU;AAAA,IACZ;AAAA,EACF;AACA,SAAO;AACT;AAQO,IAAM,UAAU,CAAC,MAAc;AACpC,SAAO,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC;AAC9B;AAEA,IAAM,qBAAqB,CAAC,MAAc,IAAY,aAAqB;AACzE,UAAQ,KAAK,QAAQ,QAAQ,QAAQ,IAAI;AAC3C;AA4BO,IAAM,kBAAkB,CAG7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAmBM;AACJ,MAAI,WAAW;AACf,MAAI,UAAU;AACd,MAAI;AAEJ,WAAS,KAAK,WAAmB;AAC/B,QAAI,UAAU;AACZ;AAAA,IACF;AACA,QAAI,cAAc,QAAW;AAC3B,kBAAY;AACZ,gBAAU;AAAA,IACZ;AAEA,UAAM,UAAU,KAAK,IAAI,YAAY,WAAW,QAAQ;AACxD,UAAM,SAAS,QAAQ,UAAU,QAAQ;AAEzC,UAAM,YAAY,CAAC;AAEnB,WAAO,KAAK,UAAU,EAAE,QAAQ,CAAC,QAAQ;AACvC,YAAM,OAAO;AACb,YAAM,UAAW,SAAS,IAAI,IAAI,WAAW,IAAI,KAAK,SACpD,WAAW,IAAI;AACjB,gBAAU,IAAI,IAAI;AAAA,IACpB,CAAC;AAED,WAAO,SAAS;AAEhB,QAAI,UAAU,UAAU;AACtB,YAAM,WAAW,UAAU;AAE3B,YAAMC,aAAY,CAAC;AAEnB,aAAO,KAAK,UAAU,EAAE,QAAQ,CAAC,QAAQ;AACvC,cAAM,OAAO;AACb,cAAM,aAAa,WAAW,IAAI;AAClC,cAAM,WAAW,SAAS,IAAI;AAE9B,YAAI;AAEJ,iBAAS,mBACL,iBAAiB,YAAY,UAAU,UAAU,IAAI,IACrD,mBAAmB,YAAY,UAAU,QAAQ;AAErD,YAAI,UAAU,MAAM;AAClB,mBAAS,mBAAmB,YAAY,UAAU,QAAQ;AAAA,QAC5D;AAEA,QAAAA,WAAU,IAAI,IAAI;AAAA,MACpB,CAAC;AACD,aAAOA,UAAS;AAEhB,gBAAU,OAAO,sBAAsB,IAAI;AAAA,IAC7C,OAAO;AACL,aAAO,QAAQ;AACf,cAAQ;AAAA,IACV;AAAA,EACF;AAEA,YAAU,OAAO,sBAAsB,IAAI;AAE3C,SAAO,MAAM;AACX,eAAW;AACX,eAAW;AACX,WAAO,qBAAqB,OAAO;AAAA,EACrC;AACF;AAGO,IAAM,QAAQ,CACnB,OACA,SACU;AACV,MAAI,CAAC,MAAM,UAAU,OAAO,GAAG;AAC7B,WAAO,CAAC;AAAA,EACV;AACA,MAAI,QAAQ;AACZ,MAAI,WAAW;AACf,QAAM,SAAS,MAAM,KAAK,KAAK,MAAM,SAAS,IAAI,CAAC;AACnD,SAAO,QAAQ,MAAM,QAAQ;AAC3B,WAAO,UAAU,IAAI,MAAM,MAAM,OAAQ,SAAS,IAAK;AAAA,EACzD;AACA,SAAO;AACT;AAmBO,IAAM,WAAW,CAAC,GAAW,MAAc,KAAK,IAAI,IAAI,CAAC;AAEzD,IAAM,mBAAmB,CAC9B,UACA,SAQ2B;AAC3B,MAAI,KAAK,SAAS,UAAU;AAC1B,WAAO;AAAA,MACL,GAAG,SAAS;AAAA,MACZ,MAAM;AAAA,MACN,YAAY,KAAK;AAAA,MACjB,QAAQ,KAAK,UAAU,SAAS,WAAW;AAAA,IAC7C;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAG,SAAS;AAAA,IACZ,gBACE,KAAK,+BAA+B,SAChC,SAAS,WAAW,iBACpB,KAAK;AAAA,IACX,MAAM,KAAK;AAAA,IACX,YAAY;AAAA,IACZ,QAAQ,KAAK,UAAU,SAAS,WAAW;AAAA,EAC7C;AACF;AAUO,IAAM,iBAAiB,CAAC,aAA6B;AAC1D,aAAW,SACR,QAAQ,YAAY,KAAK,EACzB,QAAQ,cAAc,OAAO,EAC7B,QAAQ,uBAAuB,OAAO;AACzC,MAAI,UAAU;AACZ,WAAO,SACJ,QAAQ,mBAAmB,KAAK,EAChC,QAAQ,YAAY,QAAQ;AAAA,EACjC;AACA,SAAO,SAAS,QAAQ,mBAAmB,MAAM;AACnD;AAEO,IAAM,8BAA8B,CACzC,EAAE,SAAS,QAAQ,GACnB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAOG;AACH,QAAM,KAAK,UAAU,cAAc,KAAK,QAAQ;AAChD,QAAM,KAAK,UAAU,aAAa,KAAK,QAAQ;AAE/C,SAAO,EAAE,GAAG,EAAE;AAChB;AAEO,IAAM,8BAA8B,CACzC,EAAE,QAAQ,OAAO,GACjB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAOG;AACH,QAAM,KAAK,SAAS,WAAW,KAAK,QAAQ;AAC5C,QAAM,KAAK,SAAS,WAAW,KAAK,QAAQ;AAC5C,SAAO,EAAE,GAAG,EAAE;AAChB;AAEO,IAAM,uBAAuB,CAAC,SACnC,iBAAiB,SAAS,eAAe,EAAE,iBAAiB,KAAK,IAAI,EAAE;AAEzE,IAAM,eACJ;AAEF,IAAM,eAAe;AACrB,IAAM,eAAe,IAAI,OAAO,MAAM,YAAY,MAAM,YAAY,GAAG;AAOhE,IAAM,QAAQ,CAAC,SAAiB,aAAa,KAAK,IAAI;AAEtD,IAAM,eAAe,CAC1B,YAC6B;AAC7B,QAAM,CAAC,GAAG,CAAC,IAAI;AACf,SAAO,EAAE,GAAG,EAAE;AAChB;AAGO,IAAM,mBAAmB,CAAC,UAAkB;AACjD,MAAI,OAAO,SAAS,cAAc;AAChC,YAAQ,KAAK,KAAK;AAClB;AAAA,EACF;AACA,QAAM;AACR;AAEO,IAAM,YAAY,CACvB,OACA,IACA,YAAoB,MACjB;AACH,MAAI,YAAY,GAAG;AACjB,gBAAY,MAAM,SAAS;AAAA,EAC7B;AACA,cAAY,KAAK,IAAI,MAAM,QAAQ,KAAK,IAAI,WAAW,CAAC,CAAC;AACzD,MAAI,QAAQ,YAAY;AACxB,SAAO,EAAE,QAAQ,MAAM,QAAQ;AAC7B,QAAI,GAAG,MAAM,KAAK,GAAG,OAAO,KAAK,GAAG;AAClC,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEO,IAAM,gBAAgB,CAC3B,OACA,IACA,YAAoB,MAAM,SAAS,MAChC;AACH,MAAI,YAAY,GAAG;AACjB,gBAAY,MAAM,SAAS;AAAA,EAC7B;AACA,cAAY,KAAK,IAAI,MAAM,SAAS,GAAG,KAAK,IAAI,WAAW,CAAC,CAAC;AAC7D,MAAI,QAAQ,YAAY;AACxB,SAAO,EAAE,QAAQ,IAAI;AACnB,QAAI,GAAG,MAAM,KAAK,GAAG,OAAO,KAAK,GAAG;AAClC,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEO,IAAM,gBAAgB,CAAC,UAAkB;AAC9C,QAAM,mBAAmB,MAAM,WAAW,KAAK,MAAM,OAAO,GAAG,CAAC,MAAM;AACtE,QAAM,sBAAsB,MAAM,WAAW,KAAK,MAAM,OAAO,GAAG,CAAC,MAAM;AACzE,SAAO,oBAAoB,uBAAuB,UAAU;AAC9D;AAEO,IAAM,8BAA8B,CAAC,OAC1C,GAAG,cAAc,WAAW,cAAc,GAAG,eAAe;AAQvD,IAAM,oBAAoB,MAAS;AACxC,MAAI;AACJ,MAAI;AACJ,QAAM,UAAU,IAAI,QAAQ,CAAC,UAAU,YAAY;AACjD,cAAU;AACV,aAAS;AAAA,EACX,CAAC;AACD,EAAC,QAAgB,UAAU;AAC3B,EAAC,QAAgB,SAAS;AAC1B,SAAO;AACT;AA8CO,IAAM,gCAAgC,CAC3C,YAC2B;AAC3B,MAAI,SAAS,QAAQ;AACrB,SAAO,QAAQ;AACb,QAAI,WAAW,SAAS,MAAM;AAC5B,aAAO;AAAA,IACT;AACA,UAAM,EAAE,UAAU,IAAI,OAAO,iBAAiB,MAAM;AACpD,UAAM,uBAAuB,OAAO,eAAe,OAAO;AAC1D,QACE,yBACC,cAAc,UACb,cAAc,YACd,cAAc,YAChB;AACA,aAAO;AAAA,IACT;AACA,aAAS,OAAO;AAAA,EAClB;AACA,SAAO;AACT;AAEO,IAAM,qBAAqB,CAAC,YAA8B;AAC/D,MAAI,SAAS,QAAQ;AACrB,SAAO,QAAQ;AACb,QAAI,OAAO,WAAW,IAAI;AACxB,aAAO,MAAM;AACb;AAAA,IACF;AACA,aAAS,OAAO;AAAA,EAClB;AACF;AAEO,IAAM,gBAAgB,CAAC,UAA6B;AACzD,QAAM,eAAe;AAErB,QAAM,cAAc;AACtB;AAEO,IAAM,mBAAmB,CAAC,UAAsB;AACrD,SAAO,MAAM,KAAK,KAAK,EACpB,IAAI,CAAC,SAAS,IAAI,KAAK,SAAS,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAC/C,KAAK,EAAE;AACZ;AAEO,IAAM,sBAAsB,MAAO,UAAU,IAAI,IAAI,KAAK,IAAI;AAM9D,IAAM,aAAa,CACxB,UACG;AACH,MAAI,iBAAiB,KAAK;AACxB,WAAO;AAAA,EACT;AACA,SAAO,MAAM,OAAO,CAAC,KAAqB,YAAY;AACpD,QAAI,IAAI,OAAO,YAAY,WAAW,UAAU,QAAQ,IAAI,OAAO;AACnE,WAAO;AAAA,EACT,GAAG,oBAAI,IAAI,CAAC;AACd;AAEO,IAAM,sBAAsB,CACjC,aAEA,SAAS,OAAO,CAAC,KAAK,SAAY,QAAQ;AACxC,MAAI,IAAI,QAAQ,IAAI,CAAC,SAAS,GAAG,CAAC;AAClC,SAAO;AACT,GAAG,oBAAI,IAAyC,CAAC;AAK5C,IAAM,gBAAgB,CAC3B,OACA,YAEA,MAAM,OAAO,CAAC,KAAK,UAAU;AAC3B,MAAI,UAAU,QAAQ,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI;AAChD,SAAO;AACT,GAAG,CAAC,CAAyB;AAWxB,IAAM,cAAc,CAAI,UAC7B,MAAM,OAAO,CAAC,KAAK,MAAM,UAAU;AACjC,QAAM,OAAgB,EAAE,GAAG,MAAM,MAAM,MAAM,MAAM,KAAK;AAGxD,MAAI,UAAU,GAAG;AACf,UAAM,WAAW,IAAI,QAAQ,CAAC;AAC9B,SAAK,OAAO;AACZ,aAAS,OAAO;AAEhB,QAAI,UAAU,MAAM,SAAS,GAAG;AAE9B,YAAM,YAAY,IAAI,CAAC;AACvB,WAAK,OAAO;AACZ,gBAAU,OAAO;AAAA,IACnB;AAAA,EACF;AAEA,MAAI,KAAK,IAAI;AAEb,SAAO;AACT,GAAG,CAAC,CAAc;AAEb,IAAM,YAAY,MAAM,+BAAgB,SAAS;AAEjD,IAAM,WAAW,MAAM,+BAAgB,SAAS;AAEhD,IAAM,cAAc,MACzB,OAAO,YAAY,eAAe;AAE7B,IAAM,YAAY,CAAkB,MAAa,gBAAmB;AACzE,SAAO,IAAI,YAAY,MAAM;AAAA,IAC3B,QAAQ;AAAA,MACN;AAAA,IACF;AAAA,IACA,YAAY;AAAA,EACd,CAAC;AACH;AAEO,IAAM,eAAe,CAC1B,KACA,YACM;AACN,MAAI,YAAY;AAChB,aAAW,OAAO,SAAS;AACzB,UAAM,QAAS,QAAgB,GAAG;AAClC,QAAI,OAAO,UAAU,aAAa;AAChC,UACG,IAAY,GAAG,MAAM;AAAA,OAErB,OAAO,UAAU,YAAY,UAAU,OACxC;AACA;AAAA,MACF;AACA,kBAAY;AAAA,IACd;AAAA,EACF;AAEA,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AACF;AAOO,IAAM,WAAW,MAAM;AAC5B,MAAI;AACF,WAAO,OAAO,SAAS,OAAO,MAAM,QAAQ;AAAA,EAC9C,SAAS,OAAO;AACd,WAAO;AAAA,EACT;AACF;AAIO,IAAM,gBAAgB,CAC3B,UACmD;AACnD,SACE,CAAC,CAAC,SACF,OAAO,UAAU,YACjB,UAAU,SACV,WAAW,SACX,aAAa;AAEjB;AAEO,IAAM,yBAAyB,CAAC,cAAkC;AACvE,QAAM,oBAAoB,WAAW;AAAA,IACnC;AAAA,EACF;AAEA,SAAO,oBACH,MAAM,KAAK,iBAAiB,EAAE;AAAA,IAC5B,CAAC,YACC,QAAQ,WAAW,MAAM,CAAE,QAA6B;AAAA,EAC5D,IACA,CAAC;AACP;AAGA,IAAM,sCAAsC,CAAC,GAAQ,MAAoB;AAEvE,MACE,MAAM,QAAQ,CAAC,KACf,MAAM,QAAQ,CAAC,KACf,EAAE,WAAW,KACb,EAAE,WAAW,GACb;AACA,WAAO;AAAA,EACT;AACA,SAAO,MAAM;AACf;AAMO,IAAM,iBAAiB,CAI5B,MACA,MACA,aAWA,QAAQ,UACL;AACH,QAAM,QAAQ,OAAO,KAAK,IAAI;AAC9B,QAAM,QAAQ,OAAO,KAAK,IAAI;AAC9B,MAAI,MAAM,WAAW,MAAM,QAAQ;AACjC,QAAI,OAAO;AACT,cAAQ;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,MAAI,eAAe,MAAM,QAAQ,WAAW,GAAG;AAC7C,eAAW,OAAO,aAAa;AAC7B,YAAM,MACJ,KAAK,GAAG,MAAM,KAAK,GAAG,KACtB,oCAAoC,KAAK,GAAG,GAAG,KAAK,GAAG,CAAC;AAC1D,UAAI,CAAC,KAAK;AACR,YAAI,OAAO;AACT,kBAAQ;AAAA,YACN,qBAAqB,GAAG;AAAA,YACxB;AAAA,YACA,KAAK,GAAG;AAAA,YACR,KAAK,GAAG;AAAA,UACV;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,MAAM,CAAC,QAAQ;AAC1B,UAAM,aACJ,cACE,GAAc;AAClB,UAAM,MAAM,aACR,WAAW,KAAK,GAAG,GAAG,KAAK,GAAG,CAAC,IAC/B,KAAK,GAAG,MAAM,KAAK,GAAG,KACtB,oCAAoC,KAAK,GAAG,GAAG,KAAK,GAAG,CAAC;AAE5D,QAAI,CAAC,OAAO,OAAO;AACjB,cAAQ;AAAA,QACN,qBAAqB,GAAG;AAAA,QACxB;AAAA,QACA,KAAK,GAAG;AAAA,QACR,KAAK,GAAG;AAAA,MACV;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAIO,IAAM,uBAAuB,CAClC,sBACA,iBACA,EAAE,2BAA2B,KAAK,IAAI,CAAC,MACpC;AACH,SAAO,SAAS,YAAY,OAAU;AACpC,2BAAuB,KAAK;AAE5B,QACE,CAAC,4BACD,CAAE,OAA4B,kBAC9B;AACA,aAAO,kBAAkB,KAAK;AAAA,IAChC;AAAA,EACF;AACF;AAMO,IAAM,cAAc,CACzB,OACA,SACA,eACU;AACV,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AACA,MAAI,YAAY;AACd,YAAQ,MAAM,OAAO;AACrB,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,MAAM,OAAO;AACzB;AAEO,SAAS,UAAU,WAAgB,SAAoC;AAC5E,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,OAAO;AAAA,EACzB;AACF;AAKO,IAAM,UAAU,CACrB,SACG;AACH,MAAI;AACJ,MAAI;AAEJ,QAAM,MAAM,SAAU,MAAS;AAC7B,UAAM,cAAc,OAAO,QAAQ,IAAI;AAEvC,QAAI,UAAU;AACZ,UAAI,eAAe;AACnB,iBAAW,CAAC,KAAK,KAAK,KAAK,aAAa;AACtC,YAAI,SAAS,IAAI,GAAG,MAAM,OAAO;AAC/B,yBAAe;AACf;AAAA,QACF;AAAA,MACF;AACA,UAAI,cAAc;AAChB,eAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,SAAS,KAAK,IAAI;AAExB,eAAW,IAAI,IAAI,WAAW;AAC9B,iBAAa;AAEb,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,MAAM;AAChB,eAAW;AACX,iBAAa;AAAA,EACf;AAEA,SAAO;AACT;AAGO,IAAM,aAAa,CAExB,YAEA,UACe;AACf,SAAO,sBAAsB,OAAO,sBAAsB,MACtD,WAAW,IAAI,KAAU,IACzB,cAAc,aACd,WAAW,SAAS,KAAU,IAC9B,WAAW,eAAe,KAAK;AACrC;AAEO,IAAM,YAAY,CAAI,QAAc,KAAK,MAAM,KAAK,UAAU,GAAG,CAAC;AAElE,IAAM,eAAe,CAC1B,WACA,cACG;AACH,MAAI,eAAe,WAAW,SAAS,GAAG;AACxC,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAiDO,SAAS,iBAKd,QAQA,MACA,UACA,SACqB;AACrB,MAAI,CAAC,QAAQ;AACX,WAAO,MAAM;AAAA,IAAC;AAAA,EAChB;AACA,UAAQ,mBAAmB,MAAM,UAAU,OAAO;AAClD,SAAO,MAAM;AACX,YAAQ,sBAAsB,MAAM,UAAU,OAAO;AAAA,EACvD;AACF;AAEO,SAAS,qBAAqB,QAAoB,SAAS,MAAM;AACtE,QAAM,MAAM,OAAO;AAEnB,MAAI,MAAM,GAAG;AACX,WAAO;AAAA,EACT;AAEA,MAAI,IAAI,OAAO,CAAC;AAChB,MAAI,IAAI,OAAO,CAAC;AAChB,QAAM,IAAI,OAAO,CAAC;AAElB,MAAI,SAAS,IAAI,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE;AAAA,IAC3D;AAAA,EACF,CAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI;AAAA,IACxD,EAAE,CAAC;AAAA,IACH,EAAE,CAAC;AAAA,EACL,EAAE,QAAQ,CAAC,CAAC;AAEZ,WAAS,IAAI,GAAG,MAAM,MAAM,GAAG,IAAI,KAAK,KAAK;AAC3C,QAAI,OAAO,CAAC;AACZ,QAAI,OAAO,IAAI,CAAC;AAChB,cAAU,GAAG,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE;AAAA,MACjE;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ;AACV,cAAU;AAAA,EACZ;AAEA,SAAO;AACT;AAEO,IAAM,eAAe,CAAC,QAAgB;AAC3C,SAAO,IAAI,QAAQ,aAAa,IAAI;AACtC;AA+BO,IAAM,gBAAgB,CAC3B,UACG;AACH,SAAO;AACT;AAKO,IAAM,aAAa,OACxB,OACG,SACiB;AACpB,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAQ,GAAG,GAAG,IAAI,CAAC;AAAA,EACrB,CAAC;AACH;AAEO,IAAM,YAAY,IAAI,SAC3B,KAAK,IAAI,GAAG,KAAK,IAAI,CAAC,QAAS,MAAM,IAAI,CAAE,CAAC,IAAI;AAuB3C,IAAM,cAAN,MAAqB;AAAA,EAI1B,YACE,QACA,aACA;AANF,wBAAiB;AACjB,wBAAiB,WAA6B,CAAC;AAM7C,SAAK,OAAO,IAAI;AAAA,MACd;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEO,MAAM;AACX,UAAM,WAAW,CAAC,UAAoD;AACpE,UAAI,MAAM,KAAK,QAAQ;AAGrB,cAAM,CAAC,OAAO,KAAK,IAAI,MAAM,KAAK;AAClC,aAAK,QAAQ,KAAK,IAAI;AAAA,MACxB;AAAA,IACF;AAEA,SAAK,KAAK,iBAAiB,aAAa,QAAQ;AAEhD,WAAO,KAAK,KAAK,MAAM,EAAE,KAAK,MAAM;AAClC,iBAAW,MAAM;AACf,aAAK,KAAK,oBAAoB,aAAa,QAAQ;AAAA,MACrD,CAAC;AAED,aAAO,OAAO,OAAO,KAAK,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AACF;AAMO,IAAM,qBAAqB,CAAC,QAAgB;AACjD,SAAO,IAAI,QAAQ,MAAM,QAAQ;AACnC;AAEO,IAAM,YAAY,CAAI,UAC3B,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAEhC,IAAM,OAAO,CAIlB,QACA,SACG;AACH,SAAO,KAAK,OAAO,CAAC,KAAK,QAAmB;AAC1C,QAAI,OAAO,QAAQ;AACjB,UAAI,GAAG,IAAI,OAAO,GAAG;AAAA,IACvB;AACA,WAAO;AAAA,EACT,GAAG,CAAC,CAAuB;AAC7B;;;AY1sCO,IAAM,4BAA4B,CACvC,YACiD;AACjD,SAAO,CAAC,CAAC,WAAW,QAAQ,SAAS,WAAW,CAAC,CAAC,QAAQ;AAC5D;AAEO,IAAM,iBAAiB,CAC5B,YACsC;AACtC,SAAO,CAAC,CAAC,WAAW,QAAQ,SAAS;AACvC;AAEO,IAAM,sBAAsB,CACjC,YAC2C;AAC3C,SAAO,CAAC,CAAC,WAAW,QAAQ,SAAS;AACvC;AAEO,IAAM,kBAAkB,CAC7B,YACuC;AACvC,SAAO,CAAC,CAAC,WAAW,QAAQ,SAAS;AACvC;AAEO,IAAM,sBAAsB,CACjC,YAC2C;AAC3C,SACE,CAAC,CAAC,YAAY,QAAQ,SAAS,YAAY,QAAQ,SAAS;AAEhE;AAEO,IAAM,gBAAgB,CAC3B,YACqC;AACrC,SAAO,WAAW,QAAQ,QAAQ,SAAS;AAC7C;AAEO,IAAM,iBAAiB,CAC5B,YACsC;AACtC,SAAO,WAAW,QAAQ,QAAQ,SAAS;AAC7C;AAEO,IAAM,sBAAsB,CACjC,YAC2C;AAC3C,SAAO,WAAW,QAAQ,QAAQ,SAAS;AAC7C;AAEO,IAAM,qBAAqB,CAChC,YAC0C;AAC1C,SACE,WAAW,SACV,QAAQ,SAAS,WAAW,QAAQ,SAAS;AAElD;AAEO,IAAM,oBAAoB,CAC/B,YACyC;AACzC,SAAO,WAAW,QAAQ,sBAAsB,QAAQ,IAAI;AAC9D;AAEO,IAAM,wBAAwB,CACnC,gBACY;AACZ,SAAO,gBAAgB;AACzB;AAEO,IAAM,kBAAkB,CAC7B,YACuC;AACvC,SAAO,WAAW,QAAQ,oBAAoB,QAAQ,IAAI;AAC5D;AAEO,IAAM,iBAAiB,CAC5B,YACsC;AACtC,SAAO,WAAW,QAAQ,QAAQ,SAAS;AAC7C;AAEO,IAAM,eAAe,CAC1B,YAC2C;AAC3C,SAAO,eAAe,OAAO,KAAK,QAAQ;AAC5C;AAEO,IAAM,sBAAsB,CACjC,gBACY;AACZ,SACE,gBAAgB,WAAW,gBAAgB;AAE/C;AAEO,IAAM,mBAAmB,CAC9B,SACA,gBAAgB,SACuB;AACvC,SACE,WAAW,SACV,CAAC,QAAQ,UAAU,kBAAkB,SACtC,qBAAqB,QAAQ,IAAI;AAErC;AAEO,IAAM,uBAAuB,CAClC,gBACY;AACZ,SAAO,gBAAgB;AACzB;AAEO,IAAM,oBAAoB,CAC/B,SACA,gBAAgB,SACyB;AACzC,SACE,WAAW,SACV,CAAC,QAAQ,UAAU,kBAAkB,UACrC,QAAQ,SAAS,eAChB,QAAQ,SAAS,aACjB,QAAQ,SAAS,aACjB,QAAQ,SAAS,WACjB,QAAQ,SAAS,YACjB,QAAQ,SAAS,gBACjB,QAAQ,SAAS,WACjB,QAAQ,SAAS,gBAChB,QAAQ,SAAS,UAAU,CAAC,QAAQ;AAE3C;AAEO,IAAM,wBAAwB,CACnC,YACyC;AACzC,SACE,WAAW,SACV,QAAQ,SAAS,eAChB,QAAQ,SAAS,aACjB,QAAQ,SAAS,WACjB,QAAQ,SAAS,YACjB,QAAQ,SAAS,gBACjB,QAAQ,SAAS,WACjB,QAAQ,SAAS,gBAChB,QAAQ,SAAS,UAAU,CAAC,QAAQ;AAE3C;AAoBO,IAAM,0BAA0B,CACrC,SACA,gBAAgB,SACuB;AACvC,SACE,WAAW,SACV,CAAC,QAAQ,UAAU,kBAAkB,UACrC,QAAQ,SAAS,eAChB,QAAQ,SAAS,aACjB,QAAQ,SAAS,aACjB,eAAe,OAAO;AAE5B;AAEO,IAAM,sBAAsB,CACjC,YACiC;AACjC,QAAM,OAA0C,SAAS;AACzD,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AACA,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,aAAa;AAChB,aAAO;AAAA,IACT;AAAA,IACA,SAAS;AACP,kBAAY,MAAM,IAAI;AACtB,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEO,IAAM,yBAAyB,CACpC,YAC8C;AAC9C,SACE,QAAQ,SAAS,eACjB,QAAQ,SAAS,aACjB,QAAQ,SAAS;AAErB;AAEO,IAAM,sBAAsB,CACjC,YAC2E;AAC3E,SACE,wBAAwB,OAAO,KAC/B,CAAC,CAAC,QAAQ,eAAe,KAAK,CAAC,EAAE,KAAK,MAAM,SAAS,MAAM;AAE/D;AAEO,IAAM,qBAAqB,CAChC,YACkD;AAClD,SACE,YAAY,QACZ,iBAAiB,WACjB,QAAQ,gBAAgB,QACxB,cAAc,OAAO;AAEzB;AAEO,IAAM,wBAAwB,CAAC,SACpC,SAAS,eACT,SAAS,gBACT,SAAS,YACT,SAAS;AAEJ,IAAM,4BAA4B,CAAC,SACxC,SAAS,UAAU,SAAS,WAAW,SAAS;AAE3C,IAAM,iCAAiC,CAC5C,eACA,YACG;AACH,OACG,kBAAkB,UAAU;AAAA;AAAA,EAG3B,kBAAkB,UAAU,WAC9B,sBAAsB,QAAQ,IAAI,GAClC;AACA,WAAO;AAAA,EACT;AACA,MACE,kBAAkB,UAAU,uBAC5B,0BAA0B,QAAQ,IAAI,GACtC;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEO,IAAM,oCAAoC,CAC/C,YACG;AACH,MAAI,0BAA0B,QAAQ,IAAI,GAAG;AAC3C,WAAO;AAAA,MACL,MAAM,UAAU;AAAA,IAClB;AAAA,EACF;AAEA,MAAI,sBAAsB,QAAQ,IAAI,GAAG;AACvC,WAAO;AAAA,MACL,MAAM,UAAU;AAAA,IAClB;AAAA,EACF;AAEA,SAAO;AACT;AAEO,IAAM,sBAAsB,CACjC,YACiC;AACjC,SACE,OAAO,OAAO,SAAS,YAAY,KAClC,QAA8B,cAAc;AAEjD;;;AChUO,IAAM,cAAc,CACzB,MACA,MACA,eACG;AACH,QAAM,QAAQ,KACX,MAAM,IAAI,EAGV,IAAI,CAAC,MAAM,KAAK,GAAG,EACnB,KAAK,IAAI;AACZ,QAAM,WAAW,WAAW,IAAI;AAChC,QAAM,SAAS,cAAc,OAAO,UAAU,UAAU;AACxD,QAAM,QAAQ,aAAa,OAAO,IAAI;AACtC,SAAO,EAAE,OAAO,OAAO;AACzB;AAEA,IAAM,aAAa,uCAAuC,kBAAkB;AAGrE,IAAM,wBAAwB,CACnC,MACA,eACG;AACH,QAAM,eAAe,gBAAgB,IAAI;AACzC,MAAI,iBAAiB,GAAG;AACtB,WACE,YAAY,WAAW,MAAM,EAAE,EAAE,KAAK,IAAI,GAAG,MAAM,UAAU,EAAE,QAC/D,qBAAqB;AAAA,EAEzB;AACA,SAAO,eAAe,qBAAqB;AAC7C;AAEO,IAAM,yBAAyB,CACpC,MACA,eACG;AACH,SAAO,YAAY,IAAI,MAAM,UAAU,EAAE,QAAQ,qBAAqB;AACxE;AAEO,IAAM,yBAAyB,MAAM;AAC1C,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,cAAc;AAAA,MACZ,UAAU;AAAA,MACV,YAAY;AAAA,IACd,CAAC;AAAA,EACH;AACA,SAAO,QAAQ;AACjB;AAEO,IAAM,gBAAgB,CAAC,SAAiB;AAC7C,SACE,aAAa,IAAI,EAEd,QAAQ,OAAO,UAAU;AAEhC;AAEA,IAAM,iBAAiB,CAAC,SAAiB;AACvC,SAAO,cAAc,IAAI,EAAE,MAAM,IAAI;AACvC;AAMO,IAAM,mBAAmB,CAAC,gBAAuC;AACtE,QAAM,YAAY,eAAe,YAAY,IAAI,EAAE;AACnD,SAAQ,YAAY,SAClB,YACA,YAAY;AAChB;AAMO,IAAM,oBAAoB,CAC/B,UACA,eACG;AACH,SAAO,WAAW;AACpB;AAGO,IAAM,yBAAyB,CACpC,UACA,eACG;AACH,SAAO,kBAAkB,UAAU,UAAU,IAAI,qBAAqB;AACxE;AAEA,IAAI;AAOG,IAAM,+BAA+B,CAAC,aAAkC;AAC7E,wBAAsB;AACxB;AAMA,IAAM,4BAAN,MAA+D;AAAA,EAG7D,cAAc;AAFd,wBAAQ;AAGN,SAAK,SAAS,SAAS,cAAc,QAAQ;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,aAAa,MAAc,YAAgC;AAChE,UAAM,UAAU,KAAK,OAAO,WAAW,IAAI;AAC3C,YAAQ,OAAO;AACf,UAAM,UAAU,QAAQ,YAAY,IAAI;AACxC,UAAM,eAAe,QAAQ;AAK7B,QAAI,UAAU,GAAG;AACf,aAAO,eAAe;AAAA,IACxB;AAEA,WAAO;AAAA,EACT;AACF;AAEO,IAAM,eAAe,CAAC,MAAc,SAAqB;AAC9D,MAAI,CAAC,qBAAqB;AACxB,0BAAsB,IAAI,0BAA0B;AAAA,EACtD;AAEA,SAAO,oBAAoB,aAAa,MAAM,IAAI;AACpD;AAEO,IAAM,eAAe,CAAC,MAAc,SAAqB;AAC9D,QAAM,QAAQ,eAAe,IAAI;AACjC,MAAI,QAAQ;AACZ,QAAM,QAAQ,CAACC,UAAS;AACtB,YAAQ,KAAK,IAAI,OAAO,aAAaA,OAAM,IAAI,CAAC;AAAA,EAClD,CAAC;AAED,SAAO;AACT;AAEO,IAAM,gBAAgB,CAC3B,MACA,UACA,eACG;AACH,QAAM,YAAY,eAAe,IAAI,EAAE;AACvC,SAAO,kBAAkB,UAAU,UAAU,IAAI;AACnD;AAEO,IAAM,YAAa,uBAAM;AAC9B,QAAM,kBAAwD,CAAC;AAE/D,QAAM,YAAY,CAAC,MAAc,SAAqB;AACpD,UAAM,UAAU,KAAK,WAAW,CAAC;AACjC,QAAI,CAAC,gBAAgB,IAAI,GAAG;AAC1B,sBAAgB,IAAI,IAAI,CAAC;AAAA,IAC3B;AACA,QAAI,CAAC,gBAAgB,IAAI,EAAE,OAAO,GAAG;AACnC,YAAM,QAAQ,aAAa,MAAM,IAAI;AACrC,sBAAgB,IAAI,EAAE,OAAO,IAAI;AAAA,IACnC;AAEA,WAAO,gBAAgB,IAAI,EAAE,OAAO;AAAA,EACtC;AAEA,QAAM,WAAW,CAAC,SAAqB;AACrC,WAAO,gBAAgB,IAAI;AAAA,EAC7B;AAEA,QAAM,aAAa,CAAC,SAAqB;AACvC,oBAAgB,IAAI,IAAI,CAAC;AAAA,EAC3B;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF,GAAG;AAYI,IAAM,kBAAkB,CAAC,SAAqB;AACnD,QAAM,QAAQ,UAAU,SAAS,IAAI;AACrC,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AACA,QAAM,oBAAoB,MAAM,OAAO,CAAC,QAAQ,QAAQ,MAAS;AACjE,SAAO,KAAK,IAAI,GAAG,iBAAiB;AACtC;;;AC3NA,IAAI;AACJ,IAAI;AACJ,IAAI;AAKG,IAAM,cAAc,CAAC,SAAiB;AAC3C,MAAI,CAAC,gBAAgB;AACnB,qBAAiB,MAAM,MAAM,GAAG,OAAO,OAAO,GAAG,CAAC;AAAA,EACpD;AAEA,SAAO,eAAe,KAAK,IAAI;AACjC;AAEA,IAAM,oBAAoB,MAAM;AAC9B,MAAI,CAAC,sBAAsB;AACzB,QAAI;AACF,6BAAuB,0BAA0B;AAAA,IACnD,QAAQ;AACN,6BAAuB,wBAAwB;AAAA,IACjD;AAAA,EACF;AAEA,SAAO;AACT;AAEA,IAAM,gBAAgB,MAAM;AAC1B,MAAI,CAAC,kBAAkB;AACrB,uBAAmB,qBAAqB;AAAA,EAC1C;AAEA,SAAO;AACT;AAKA,IAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASb,YAAY;AAAA,EACZ,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWR,SAAS;AAAA,EACT,SAAS;AACX;AAKA,IAAM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMV,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcN,SAAQ;AAAA,EACR,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOT,UAAU;AACZ;AAEA,IAAM,QAAQ;AAAA,EACZ,MAAM;AAAA,EACN,QACE;AAAA,EACF,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AACR;AAWA,IAAM,0BAA0B,MAC9B,MAAM;AAAA,EACJ,cAAc;AAAA,EACd,MAAM,GAAG,OAAO,QAAQ,OAAO,YAAY,IAAI,IAAI;AACrD;AASF,IAAM,4BAA4B,MAChC,MAAM;AAAA;AAAA,EAEJ,cAAc;AAAA;AAAA,EAEd,MAAM,OAAO,OAAO,UAAU,EAAE,MAAM;AAAA,EACtC,MAAM,MAAM,OAAO,YAAY,OAAO,MAAM,EAAE,MAAM;AAAA;AAAA,EAEpD,MAAM,OAAO,IAAI,MAAM,IAAI,QAAQ,EAChC,cAAc,OAAO,SAAS,IAAI,OAAO,EACzC,MAAM;AAAA,EACT,MAAM,MAAM,IAAI,IAAI,EACjB,cAAc,OAAO,QAAQ,OAAO,SAAS,IAAI,OAAO,EACxD,MAAM;AAAA;AAAA,EAET,MAAM,WAAW,IAAI,OAAO,EAAE,cAAc,OAAO,OAAO,EAAE,MAAM;AAAA,EAClE,MAAM,UAAU,IAAI,OAAO,EAAE,cAAc,OAAO,OAAO,EAAE,MAAM;AAAA,EACjE,MAAM,UAAU,OAAO,OAAO,EAAE,WAAW,OAAO,OAAO,EAAE,MAAM;AACnE;AAyBF,IAAM,uBAAuB,MAC3B,MAAM;AAAA,EACJ,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,QACJ,MAAM,MAAM,IAAI,MAAM,MAAM,MAAM,KAAK,MAAM,IAAI,MAAM,IAAI,MAAM,GAAG,MAAM,OAAO,MAAM;AAAA,MACzF;AAAA,IACF;AAAA,EACF;AACF;AAKF,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA,EAIZ,OAAO,CAAC,UAA0B,IAAI,OAAO,OAAO,GAAG;AAAA;AAAA;AAAA;AAAA,EAIvD,MAAM,IAAI,YAA8B,QAAQ,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE;AAAA;AAAA;AAAA;AAAA,EAI5E,KAAK,IAAI,YAA8B,MAAM,MAAM,MAAM,KAAK,GAAG,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA,EAIzE,IAAI,IAAI,YACN,MAAM,MAAM,QAAQ,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA,EAIpD,OAAO,IAAI,YACT,MAAM,MAAM,IAAI,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG;AAAA;AAAA;AAAA;AAAA,EAI3C,OAAO,IAAI,YACT,MAAM,MAAM,IAAI,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG;AAC7C;AAMA,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA,EAIZ,IAAI,IAAI,YAAsB;AAC5B,UAAM,SAAS,MAAM,KAAK,GAAG,OAAO;AACpC,WAAO,MAAM,MAAM,KAAK,MAAM,IAAI;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAIA,QAAQ,IAAI,YAAsB;AAChC,UAAM,SAAS,MAAM,KAAK,GAAG,OAAO;AACpC,UAAM,UAAU,MAAM,MAAM,MAAM,OAAO,MAAM,IAAI;AACnD,WAAO,MAAM,MAAM,OAAO;AAAA,EAI5B;AAAA;AAAA;AAAA;AAAA,EAIA,OAAO,IAAI,YAAsB;AAC/B,UAAM,SAAS,MAAM,KAAK,GAAG,OAAO;AACpC,UAAM,UAAU,MAAM,MAAM,MAAM,QAAQ,MAAM,IAAI;AACpD,WAAO,MAAM,MAAM,OAAO;AAAA,EAI5B;AAAA;AAAA;AAAA;AAAA,EAIA,YAAY,IAAI,YAAsB;AACpC,UAAM,SAAS,MAAM,KAAK,GAAG,OAAO;AACpC,UAAM,UAAU,MAAM,MAAM,MAAM,QAAQ,MAAM,SAAS,MAAM,IAAI;AACnE,WAAO,MAAM,MAAM,OAAO;AAAA,EAI5B;AAAA;AAAA;AAAA;AAAA,EAIA,WAAW,IAAI,YAAsB;AACnC,UAAM,SAAS,MAAM,KAAK,GAAG,OAAO;AACpC,UAAM,UAAU,MAAM,MAAM,MAAM,QAAQ,MAAM,SAAS,MAAM,IAAI;AACnE,WAAO,MAAM,MAAM,OAAO;AAAA,EAI5B;AAAA;AAAA;AAAA;AAAA,EAIA,WAAW,IAAI,YAAsB;AACnC,UAAM,SAAS,MAAM,KAAK,GAAG,OAAO;AACpC,UAAM,UAAU,MAAM,MAAM,MAAM,OAAO,MAAM,IAAI;AACnD,WAAO,MAAM,MAAM,OAAO;AAAA,EAI5B;AAAA;AAAA;AAAA;AAAA,EAIA,UAAU,IAAI,YAAsB;AAClC,UAAM,SAAS,MAAM,KAAK,GAAG,OAAO;AACpC,UAAM,UAAU,MAAM,MAAM,MAAM,QAAQ,MAAM,IAAI;AACpD,WAAO,MAAM,MAAM,OAAO;AAAA,EAI5B;AAAA,EACA,OAAO,CAAC,iBAA+B;AAAA;AAAA;AAAA;AAAA,IAIrC,OAAO;AAAA;AAAA;AAAA;AAAA,IAIP,aAAa,IAAI,YAAsB;AACrC,YAAM,OAAO,YAAY;AACzB,YAAM,YAAY,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM;AAChD,YAAM,UAAU,MAAM,MAAM,IAAI,WAAW,IAAI;AAC/C,aAAO,MAAM,MAAM,OAAO;AAAA,IAI5B;AAAA;AAAA;AAAA;AAAA,IAIA,YAAY,IAAI,YAAsB;AACpC,YAAM,OAAO,YAAY;AACzB,YAAM,WAAW,MAAM,OAAO,GAAG,OAAO,EAAE,MAAM;AAChD,YAAM,UAAU,MAAM,MAAM,IAAI,MAAM,QAAQ;AAC9C,aAAO,MAAM,MAAM,OAAO;AAAA,IAI5B;AAAA;AAAA;AAAA;AAAA,IAIA,eAAe,IAAI,YAAsB;AACvC,YAAM,OAAO,YAAY;AACzB,YAAM,eAAe,MAAM,SAAS,GAAG,OAAO,EAAE,MAAM;AACtD,YAAM,UAAU,MAAM,MAAM,IAAI,cAAc,IAAI;AAClD,aAAO,MAAM,MAAM,OAAO;AAAA,IAI5B;AAAA;AAAA;AAAA;AAAA,IAIA,eAAe,IAAI,YAAsB;AACvC,YAAM,OAAO,YAAY;AACzB,YAAM,cAAc,MAAM,UAAU,GAAG,OAAO,EAAE,MAAM;AACtD,YAAM,UAAU,MAAM,MAAM,IAAI,MAAM,WAAW;AACjD,aAAO,MAAM,MAAM,OAAO;AAAA,IAI5B;AAAA,EACF;AACF;AAKO,IAAM,cAAc,CAACC,UAAiB;AAC3C,QAAM,iBAAiB,kBAAkB;AAKzC,SAAOA,MAAK,UAAU,KAAK,EAAE,MAAM,cAAc,EAAE,OAAO,OAAO;AACnE;AAKO,IAAM,WAAW,CACtB,MACA,MACA,aACW;AAIX,MAAI,CAAC,OAAO,SAAS,QAAQ,KAAK,WAAW,GAAG;AAC9C,WAAO;AAAA,EACT;AAEA,QAAM,QAAuB,CAAC;AAC9B,QAAM,gBAAgB,KAAK,MAAM,IAAI;AAErC,aAAW,gBAAgB,eAAe;AACxC,UAAM,mBAAmB,aAAa,cAAc,IAAI;AAExD,QAAI,oBAAoB,UAAU;AAChC,YAAM,KAAK,YAAY;AACvB;AAAA,IACF;AAEA,UAAM,cAAc,SAAS,cAAc,MAAM,QAAQ;AACzD,UAAM,KAAK,GAAG,WAAW;AAAA,EAC3B;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAKA,IAAM,WAAW,CACfA,OACA,MACA,aACa;AACb,QAAM,QAAuB,CAAC;AAC9B,QAAM,SAAS,YAAYA,KAAI;AAC/B,QAAM,gBAAgB,OAAO,OAAO,QAAQ,EAAE;AAE9C,MAAI,cAAc;AAClB,MAAI,mBAAmB;AAEvB,MAAI,WAAW,cAAc,KAAK;AAElC,SAAO,CAAC,SAAS,MAAM;AACrB,UAAM,QAAQ,SAAS;AACvB,UAAM,WAAW,cAAc;AAG/B,UAAM,gBAAgB,kBAAkB,KAAK,IACzC,mBAAmB,UAAU,UAAU,OAAO,IAAI,IAClD,aAAa,UAAU,IAAI;AAG/B,QAAI,KAAK,KAAK,KAAK,KAAK,iBAAiB,UAAU;AACjD,oBAAc;AACd,yBAAmB;AACnB,iBAAW,cAAc,KAAK;AAC9B;AAAA,IACF;AAGA,QAAI,CAAC,aAAa;AAChB,YAAM,cAAc,SAAS,OAAO,MAAM,QAAQ;AAClD,YAAM,eAAe,YAAY,YAAY,SAAS,CAAC,KAAK;AAC5D,YAAM,iBAAiB,YAAY,MAAM,GAAG,EAAE;AAE9C,YAAM,KAAK,GAAG,cAAc;AAG5B,oBAAc;AACd,yBAAmB,aAAa,cAAc,IAAI;AAClD,iBAAW,cAAc,KAAK;AAAA,IAChC,OAAO;AAEL,YAAM,KAAK,YAAY,QAAQ,CAAC;AAGhC,oBAAc;AACd,yBAAmB;AAAA,IACrB;AAAA,EACF;AAGA,MAAI,aAAa;AACf,UAAM,eAAe,SAAS,aAAa,MAAM,QAAQ;AACzD,UAAM,KAAK,YAAY;AAAA,EACzB;AAEA,SAAO;AACT;AAKA,IAAM,WAAW,CACf,MACA,MACA,aACkB;AAElB,MAAI,cAAc,EAAE,KAAK,IAAI,GAAG;AAC9B,WAAO,CAAC,IAAI;AAAA,EACd;AAEA,yBAAuB,IAAI;AAE3B,QAAM,QAAuB,CAAC;AAC9B,QAAM,QAAQ,MAAM,KAAK,IAAI;AAE7B,MAAI,cAAc;AAClB,MAAI,mBAAmB;AAEvB,aAAW,QAAQ,OAAO;AACxB,UAAM,aAAa,UAAU,UAAU,MAAM,IAAI;AACjD,UAAM,gBAAgB,mBAAmB;AAEzC,QAAI,iBAAiB,UAAU;AAC7B,oBAAc,cAAc;AAC5B,yBAAmB;AACnB;AAAA,IACF;AAEA,QAAI,aAAa;AACf,YAAM,KAAK,WAAW;AAAA,IACxB;AAEA,kBAAc;AACd,uBAAmB;AAAA,EACrB;AAEA,MAAI,aAAa;AACf,UAAM,KAAK,WAAW;AAAA,EACxB;AAEA,SAAO;AACT;AAKA,IAAM,WAAW,CAACA,OAAc,MAAkB,aAAqB;AACrE,QAAM,wBAAwB,aAAaA,OAAM,IAAI,IAAI;AAEzD,MAAI,CAAC,uBAAuB;AAC1B,WAAOA;AAAA,EACT;AAGA,MAAI,CAAC,EAAE,aAAa,WAAW,IAAIA,MAAK,MAAM,cAAc,KAAK;AAAA,IAC/DA;AAAA,IACAA,MAAK,QAAQ;AAAA,IACb;AAAA,EACF;AAEA,MAAI,mBAAmB,aAAa,aAAa,IAAI;AAErD,aAAW,cAAc,MAAM,KAAK,WAAW,GAAG;AAChD,UAAM,aAAa,UAAU,UAAU,YAAY,IAAI;AACvD,UAAM,gBAAgB,mBAAmB;AAEzC,QAAI,gBAAgB,UAAU;AAC5B;AAAA,IACF;AAEA,kBAAc,cAAc;AAC5B,uBAAmB;AAAA,EACrB;AAEA,SAAO;AACT;AAOA,IAAM,oBAAoB,CAAC,yBAAiC;AAC1D,SACE,qBAAqB,YAAY,CAAC,MAAM,UACxC,qBAAqB,YAAY,CAAC,MAAM;AAE5C;AAKA,IAAM,yBAAyB,CAAC,SAAiB;AAC/C,MAAI,+BAAgB,SAAS,IAAI,QAAQ,+BAAgB,KAAK;AAC5D,QAAI,KAAK,KAAK,IAAI,GAAG;AACnB,YAAM,IAAI,MAAM,0CAA0C;AAAA,IAC5D;AAAA,EACF;AACF;;;AC9iBA,OAAOC,YAAW;;;ACqBlB,OAAO,WAAW;AAmBlB,SAAS,iBAAiB;;;AChD1B,SAAS,sBAAsB;;;ACD/B,OAAO,QAAQ;AA4BR,IAAM,mCAAmC;AACzC,IAAM,iBAAiB;AAEvB,IAAM,4BAA4B;AAElC,IAAM,qCAAqC;AAC3C,IAAM,yCAAyC;AAC/C,IAAM,iCAAiC,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC;AAGrD,IAAM,yBAAyB,CACpC,OAIA,aACG;AACH,SAAO,SAAS,IAAI,CAAC,UAAU,GAAG,KAAK,EAAE,KAAK,CAAC;AACjD;AAEO,IAAM,gBAAgB;AAAA,EAC3B,aAAa;AAAA,EACb,UAAU;AAAA,EACV,OAAO;AAAA;AAAA,EAEP,MAAM,uBAAuB,QAAQ,8BAA8B;AAAA,EACnE,KAAK,uBAAuB,OAAO,8BAA8B;AAAA,EACjE,MAAM,uBAAuB,QAAQ,8BAA8B;AAAA,EACnE,OAAO,uBAAuB,SAAS,8BAA8B;AAAA,EACrE,QAAQ,uBAAuB,UAAU,8BAA8B;AAAA,EACvE,MAAM,uBAAuB,QAAQ,8BAA8B;AAAA,EACnE,MAAM,uBAAuB,QAAQ,8BAA8B;AAAA,EACnE,MAAM,uBAAuB,QAAQ,8BAA8B;AAAA,EACnE,OAAO,uBAAuB,SAAS,8BAA8B;AAAA,EACrE,QAAQ,uBAAuB,UAAU,8BAA8B;AAAA,EACvE,QAAQ,uBAAuB,UAAU,8BAA8B;AAAA;AAAA,EAEvE,QAAQ,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAChE;AAEA,IAAM,wBAAwB,KAAK,eAAe;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAOM,IAAM,+BAA+B;AAAA,EAC1C,cAAc;AAAA,EACd,cAAc,IAAI,kCAAkC;AAAA,EACpD,cAAc,MAAM,kCAAkC;AAAA,EACtD,cAAc,KAAK,kCAAkC;AAAA,EACrD,cAAc,OAAO,kCAAkC;AACzD;AAGO,IAAM,mCAAmC;AAAA,EAC9C,cAAc;AAAA,EACd,cAAc,IAAI,sCAAsC;AAAA,EACxD,cAAc,MAAM,sCAAsC;AAAA,EAC1D,cAAc,KAAK,sCAAsC;AAAA,EACzD,cAAc,OAAO,sCAAsC;AAC7D;AAGO,IAAM,kCAAkC;AAAA,EAC7C,cAAc;AAAA;AAAA,EAEd;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AACF;AAMO,IAAM,uCAAuC;AAAA;AAAA,EAElD,aAAa,cAAc;AAAA,EAC3B,OAAO,cAAc;AAAA,EACrB,MAAM,cAAc;AAAA,EACpB,UAAU,cAAc;AAAA,EACxB,QAAQ,cAAc;AAAA;AAAA,EAEtB,GAAG;AACL;AAGO,IAAM,2CAA2C;AAAA,EACtD,aAAa,cAAc;AAAA,EAC3B,OAAO,cAAc;AAAA,EACrB,MAAM,cAAc;AAAA,EACpB,UAAU,cAAc;AAAA,EACxB,QAAQ,cAAc;AAAA,EAEtB,GAAG;AACL;AAOO,IAAM,4BAA4B,CAAC,UACxC;AAAA;AAAA,EAEE,cAAc,KAAK,KAAK;AAAA,EACxB,cAAc,KAAK,KAAK;AAAA,EACxB,cAAc,OAAO,KAAK;AAAA,EAC1B,cAAc,MAAM,KAAK;AAAA,EACzB,cAAc,KAAK,KAAK;AAAA;AAAA,EAGxB,cAAc,MAAM,KAAK;AAAA,EACzB,cAAc,KAAK,KAAK;AAAA,EACxB,cAAc,OAAO,KAAK;AAAA,EAC1B,cAAc,OAAO,KAAK;AAAA,EAC1B,cAAc,IAAI,KAAK;AACzB;AAEK,IAAM,WAAW,CAAC,GAAW,GAAW,MAC7C,MAAM,KAAK,OAAO,KAAK,OAAO,KAAK,KAAK,GAAG,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;;;ADxJ3D,IAAM,cAAN,MAAM,YAAW;AAyExB;AAxEE,cADW,aACI,MAAK,IAAI,eAAe;AACvC,cAFW,aAEI,SAAQ,oBAAI,QAAyC;AAAA;AAAA;AAAA;AAAA;AAMpE,cARW,aAQG,OAAM,CAA8B,YAAe;AAC/D,SAAO,YAAW,MAAM;AAAA,IACtB;AAAA,EACF;AAGF;AAEA,cAhBW,aAgBG,OAAM,CAClB,SACA,UAGG,YAAW,MAAM,IAAI,SAAS,KAAK;AAExC,cAvBW,aAuBG,UAAS,CAAC,YACtB,YAAW,MAAM,OAAO,OAAO;AAEjC,cA1BW,aA0BG,WAAU,MAAM;AAC5B,cAAW,QAAQ,oBAAI,QAAQ;AACjC;AAAA;AAAA;AAAA;AAAA;AAMA,cAlCW,aAkCG,wBAAuB,CAGnC,SACA,iBAKG;AAEH,QAAM,cAAc,cAAc,cAC9B,SACA,YAAW,IAAI,OAAO;AAI1B,MAAI,gBAAgB,QAAW;AAC7B,WAAO;AAAA,EACT;AAEA,yBAAuB,OAAO,OAAO;AAErC,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,YAAW;AAAA,IACX,gBAAgB;AAAA,MACd,aAAa;AAAA,MACb,uBAAuB,cAAc;AAAA,MACrC,wBAAwB;AAAA,IAC1B;AAAA,EACF;AAIA,cAAW,MAAM,IAAI,SAAS,KAAK;AAEnC,SAAO;AACT;AAxEK,IAAM,aAAN;;;AEbP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,OAAO,WAAW;AAElB,OAAOC,SAAQ;AACf,OAAO,UAAU;AAoCc,SAqI7B,UArI6B,KA4B7B,YA5B6B;AAhCxB,IAAM,gBAAgB,CAAC,UAAiB;AAE/C,IAAM,eAAe,CAAC,UACpB,UAAU,MAAM,QAAQC,IAAG,QAAQ;AAQ9B,IAAM,aAAa,CACxB,GACA,OAAsB,QACnB;AACH,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,IAAI,OAAO,SAAS,WAAY,EAAE,OAAO,KAAK,IAAa;AAC3D,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAY;AAAA,MACZ,WAAU;AAAA,MACV,MAAK;AAAA,MACL,SAAS,OAAO,KAAK,IAAI,MAAM;AAAA,MAC/B,WAAW,KAAK,EAAE,cAAc,OAAO,CAAC;AAAA,MACxC;AAAA,MACC,GAAG;AAAA,MAEH,iBAAO,MAAM,WAAW,oBAAC,UAAK,MAAK,gBAAe,GAAM,IAAK;AAAA;AAAA,EAChE;AAEJ;AAEA,IAAM,kBAAwB;AAAA,EAC5B,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,gBAAgB;AAClB;AAEA,IAAM,0BAAgC;AAAA,EACpC,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,gBAAgB;AAClB;AAKO,IAAM,WAAW;AAAA,EACtB,qBAAC,OAAE,aAAa,KACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,cAAS,QAAO,8BAA6B;AAAA,IAC9C,oBAAC,UAAK,GAAE,8CAA6C;AAAA,IACrD,oBAAC,UAAK,GAAE,6CAA4C;AAAA,KACtD;AAAA,EACA;AACF;AAGO,IAAM,cAAc;AAAA,EACzB,qBAAC,OAAE,aAAY,QACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,qCAAoC;AAAA,IAC5C,oBAAC,UAAK,GAAE,oCAAmC;AAAA,IAC3C,oBAAC,UAAK,IAAG,KAAI,IAAG,KAAI,IAAG,KAAI,IAAG,MAAK;AAAA,IACnC,oBAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK;AAAA,IACrC,oBAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK;AAAA,KACvC;AAAA,EACA;AACF;AAGO,IAAM,WAAW;AAAA,EACtB,qBAAC,SAAI,aAAY,OACf;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK;AAAA,IACrC,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,KACvC;AAAA,EACA;AACF;AAGO,IAAM,WAAW;AAAA,EACtB,qBAAC,OAAE,aAAY,OACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI;AAAA,IAC9B,oBAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI;AAAA,IAC9B,oBAAC,YAAO,IAAG,MAAK,IAAG,KAAI,GAAE,KAAI;AAAA,KAC/B;AAAA,EACA;AACF;AAGO,IAAM,UAAU;AAAA,EACrB,qBAAC,SAAI,aAAY,OACf;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,gCAA+B;AAAA,IACvC,oBAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,IACtC,oBAAC,UAAK,IAAG,KAAI,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI;AAAA,KACrC;AAAA,EACA;AACF;AAGO,IAAM,eAAe;AAAA,EAC1B,qBAAC,OACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,QAAO;AAAA,QACP,aAAY;AAAA;AAAA,IACd;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,QAAO;AAAA,QACP,aAAY;AAAA;AAAA,IACd;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,IAAG;AAAA,QACH,OAAO,EAAE,UAAU,QAAQ;AAAA,QAC3B,WAAU;AAAA,QACV,GAAG;AAAA,QACH,GAAG;AAAA,QACH,OAAO;AAAA,QACP,QAAQ;AAAA,QAER;AAAA,UAAC;AAAA;AAAA,YACC,QAAO;AAAA,YACP,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA,IACF;AAAA,IACA,oBAAC,OAAE,MAAK,sBACN;AAAA,MAAC;AAAA;AAAA,QACC,QAAO;AAAA,QACP,GAAE;AAAA,QACF,MAAK;AAAA;AAAA,IACP,GACF;AAAA,KACF;AAAA,EACA;AACF;AAGO,IAAM,aAAa;AAAA,EACxB,qBAAC,OAAE,aAAY,QACb;AAAA,wBAAC,UAAK,GAAE,iIAAgI;AAAA,IACxI,oBAAC,UAAK,GAAE,mEAAkE;AAAA,IAC1E,oBAAC,UAAK,GAAE,yFAAwF;AAAA,KAClG;AAAA,EACA;AACF;AAGO,IAAM,yBAAyB;AAAA,EACpC,iCACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,QAAO;AAAA,QACP,aAAa;AAAA,QACb,eAAc;AAAA;AAAA,IAChB;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,UAAS;AAAA,QACT,UAAS;AAAA,QACT,GAAE;AAAA,QACF,MAAK;AAAA;AAAA,IACP;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,QAAO;AAAA,QACP,aAAa;AAAA,QACb,eAAc;AAAA;AAAA,IAChB;AAAA,KACF;AAAA,EACA,EAAE,OAAO,IAAI,QAAQ,IAAI,MAAM,OAAO;AACxC;AAGO,IAAM,yBAAyB;AAAA,EACpC,iCACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,QAAO;AAAA,QACP,aAAa;AAAA,QACb,eAAc;AAAA;AAAA,IAChB;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,UAAS;AAAA,QACT,UAAS;AAAA,QACT,GAAE;AAAA,QACF,MAAK;AAAA;AAAA,IACP;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,QAAO;AAAA,QACP,aAAa;AAAA,QACb,eAAc;AAAA;AAAA,IAChB;AAAA,KACF;AAAA,EACA,EAAE,OAAO,IAAI,QAAQ,IAAI,MAAM,OAAO;AACxC;AAGO,IAAM,+BAA+B;AAAA,EAC1C,iCACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,QAAO;AAAA,QACP,aAAa;AAAA,QACb,eAAc;AAAA;AAAA,IAChB;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,UAAS;AAAA,QACT,UAAS;AAAA,QACT,GAAE;AAAA,QACF,MAAK;AAAA;AAAA,IACP;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,QAAO;AAAA,QACP,aAAa;AAAA,QACb,eAAc;AAAA;AAAA,IAChB;AAAA,KACF;AAAA,EACA,EAAE,OAAO,IAAI,QAAQ,IAAI,MAAM,OAAO;AACxC;AAGO,IAAM,YAAY;AAAA,EACvB,oBAAC,OAAE,MAAK,gBACN;AAAA,IAAC;AAAA;AAAA,MACC,GAAE;AAAA,MACF,MAAK;AAAA;AAAA,EACP,GACF;AAAA,EACA,EAAE,OAAO,IAAI,QAAQ,IAAI,MAAM,OAAO;AACxC;AAGO,IAAM,gBAAgB;AAAA,EAC3B,qBAAC,OAAE,QAAO,gBAAe,eAAc,SAAQ,gBAAe,SAC5D;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,8KAA6K;AAAA,IACrL,oBAAC,UAAK,GAAE,sBAAqB;AAAA,KAC/B;AAAA,EACA,EAAE,MAAM,QAAQ,OAAO,IAAI,QAAQ,IAAI,aAAa,KAAK;AAC3D;AAGO,IAAM,gBAAgB;AAAA,EAC3B,qBAAC,OAAE,aAAY,OACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,KAAI,GAAE,KAAI,OAAM,MAAK,QAAO,MAAK,IAAG,KAAI;AAAA,KAClD;AAAA,EACA;AACF;AAGO,IAAM,cAAc;AAAA,EACzB,qBAAC,OAAE,aAAY,OACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,iKAAgK;AAAA,KAC1K;AAAA,EAEA;AACF;AAGO,IAAM,cAAc;AAAA,EACzB,qBAAC,OAAE,aAAY,OACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI;AAAA,KAChC;AAAA,EAEA;AACF;AAGO,IAAM,YAAY;AAAA,EACvB,qBAAC,OAAE,aAAY,OACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,IACrC,oBAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,IACtC,oBAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK;AAAA,KACvC;AAAA,EACA;AACF;AAGO,IAAM,WAAW;AAAA,EACtB,oBAAC,UAAK,GAAE,oBAAmB,aAAY,OAAM;AAAA,EAC7C;AACF;AAEO,IAAM,cAAc;AAAA,EACzB,qBAAC,OAAE,aAAY,QACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,gEAA+D;AAAA,IACvE,oBAAC,UAAK,GAAE,WAAU;AAAA,IAClB,oBAAC,UAAK,GAAE,iDAAgD;AAAA,KAC1D;AAAA,EACA;AACF;AAGO,IAAM,eAAe;AAAA,EAC1B,qBAAC,OAAE,aAAY,QACb;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,UAAS;AAAA,QACT,GAAE;AAAA;AAAA,IACJ;AAAA,IACA,oBAAC,UAAK,GAAE,4BAA2B;AAAA,KACrC;AAAA,EAEA;AACF;AAGO,IAAM,WAAW;AAAA,EACtB,qBAAC,OAAE,aAAY,OACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK;AAAA,IACpC,oBAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,IACtC,oBAAC,UAAK,IAAG,OAAM,IAAG,MAAK,IAAG,QAAO,IAAG,MAAK;AAAA,IACzC,oBAAC,UAAK,IAAG,QAAO,IAAG,OAAM,IAAG,MAAK,IAAG,MAAK;AAAA,IACzC,oBAAC,cAAS,QAAO,wBAAuB;AAAA,KAC1C;AAAA,EACA;AACF;AAGO,IAAM,YAAY;AAAA,EACvB,qBAAC,OAAE,aAAY,QACb;AAAA,wBAAC,UAAK,GAAE,mBAAkB;AAAA,IAC1B,oBAAC,UAAK,GAAE,iKAAgK;AAAA,IACxK,oBAAC,UAAK,GAAE,kEAAiE;AAAA,IACzE,oBAAC,UAAK,GAAE,kEAAiE;AAAA,KAC3E;AAAA,EACA;AACF;AAGO,IAAM,aAAa;AAAA,EACxB,qBAAC,OAAE,aAAY,OACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,mGAAkG;AAAA,IAC1G,oBAAC,UAAK,GAAE,sBAAqB;AAAA,KAC/B;AAAA,EACA;AACF;AAEO,IAAM,aAAa;AAAA,EACxB,oBAAC,UAAK,aAAY,QAAO,GAAE,oCAAmC;AAAA,EAC9D;AACF;AAEO,IAAM,cAAc;AAAA,EACzB,oBAAC,UAAK,GAAE,YAAW,aAAY,QAAO;AAAA,EACtC;AACF;AAEO,IAAM,gBAAgB;AAAA,EAC3B,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,gBAAe;AAAA,IACvB,oBAAC,UAAK,GAAE,qIAAoI;AAAA,IAC5I,oBAAC,UAAK,GAAE,YAAW;AAAA,KACrB;AAAA,EACA;AACF;AAEO,IAAM,YAAY;AAAA,EACvB;AAAA,IAAC;AAAA;AAAA,MACC,aAAY;AAAA,MACZ,GAAE;AAAA;AAAA,EACJ;AAAA,EACA;AACF;AAEO,IAAM,YAAY;AAAA,EACvB,qBAAC,OAAE,aAAY,QACb;AAAA,wBAAC,cAAS,QAAO,oBAAmB;AAAA,IACpC,oBAAC,cAAS,QAAO,iBAAgB;AAAA,KACnC;AAAA,EACA;AACF;AAEO,IAAM,gBAAgB;AAAA,EAC3B,qBAAC,OAAE,aAAY,QACb;AAAA,wBAAC,UAAK,GAAE,kIAAiI;AAAA,IACzI;AAAA,MAAC;AAAA;AAAA,QACC,UAAS;AAAA,QACT,GAAE;AAAA;AAAA,IACJ;AAAA,KACF;AAAA,EACA;AACF;AAEO,IAAM,WAAW;AAAA,EACtB;AAAA,IAAC;AAAA;AAAA,MACC,UAAS;AAAA,MACT,GAAE;AAAA,MACF,QAAO;AAAA;AAAA,EACT;AAAA,EACA;AACF;AAEO,IAAM,UAAU;AAAA,EACrB,oBAAC,OAAE,QAAO,gBAAe,gBAAe,SACtC,8BAAC,UAAK,GAAE,4MAA2M,GACrN;AAAA,EACA,EAAE,GAAG,yBAAyB,aAAa,IAAI;AACjD;AAEO,IAAM,oBAAoB;AAAA,EAC/B,qBAAC,OAAE,aAAY,OACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,IAAG,KAAI,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI;AAAA,IACnC,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,IACrC,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,KACvC;AAAA,EACA;AACF;AAEO,IAAM,aAAa;AAAA,EACxB;AAAA,IAAC;AAAA;AAAA,MACC,aAAY;AAAA,MACZ,GAAE;AAAA;AAAA,EACJ;AAAA,EACA;AACF;AAEO,IAAM,WAAW;AAAA,EACtB,qBAAC,OAAE,aAAY,OACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI;AAAA,IAC9B,oBAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,SAAQ;AAAA,IACzC,oBAAC,UAAK,GAAE,qDAAoD;AAAA,KAC9D;AAAA,EACA;AACF;AAEO,IAAM,eAAe;AAAA,EAC1B,qBAAC,OAAE,aAAY,QACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI;AAAA,IAC9B,oBAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,SAAQ;AAAA,IACzC,oBAAC,UAAK,GAAE,qDAAoD;AAAA,KAC9D;AAAA,EACA;AACF;AAEO,IAAM,mBAAmB;AAAA,EAC9B;AAAA,IAAC;AAAA;AAAA,MACC,aAAY;AAAA,MACZ,GAAE;AAAA;AAAA,EACJ;AAAA,EACA;AACF;AAEO,IAAM,aAAa;AAAA,EACxB;AAAA,IAAC;AAAA;AAAA,MACC,GAAE;AAAA,MACF,aAAY;AAAA;AAAA,EACd;AAAA,EACA;AACF;AAEO,IAAM,cAAc;AAAA,EACzB,qBAAC,OAAE,aAAY,QACb;AAAA,wBAAC,UAAK,GAAE,qMAAoM;AAAA,IAC5M,oBAAC,UAAK,GAAE,kSAAiS;AAAA,KAC3S;AAAA,EACA;AACF;AAEO,IAAM,aAAa;AAAA,EACxB,qBAAC,OAAE,aAAY,QACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,qCAAoC;AAAA,IAC5C,oBAAC,UAAK,GAAE,8CAA6C;AAAA,KACvD;AAAA,EACA;AACF;AAEO,IAAM,YAAY;AAAA,EACvB,oBAAC,cAAS,MAAK,QAAO,QAAO,gBAAe,QAAO,kBAAiB;AAAA,EACpE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AACF;AAEO,IAAM,WAAW;AAAA,EACtB,qBAAC,OAAE,aAAY,QACb;AAAA,wBAAC,UAAK,GAAE,+FAA8F;AAAA,IACtG,oBAAC,UAAK,GAAE,gGAA+F;AAAA,KACzG;AAAA,EACA;AACF;AAEO,IAAM,OAAO;AAAA,EAClB;AAAA,EACA,EAAE,OAAO,KAAK,QAAQ,IAAI;AAC5B;AAEO,IAAM,SAAS;AAAA,EACpB;AAAA,EACA,EAAE,OAAO,KAAK,QAAQ,IAAI;AAC5B;AAGO,IAAM,WAAW;AAAA,EACtB;AAAA,IAAC;AAAA;AAAA,MACC,GAAE;AAAA,MACF,aAAY;AAAA;AAAA,EACd;AAAA,EACA;AACF;AAEO,IAAM,YAAY;AAAA,EACvB;AAAA,EACA,EAAE,OAAO,KAAK,QAAQ,IAAI;AAC5B;AAEO,IAAM,UAAU;AAAA,EACrB;AACF;AAEO,IAAM,iBAAiB;AAAA,EAC5B,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,wDAAuD;AAAA,IAC/D,oBAAC,UAAK,GAAE,mKAAkK;AAAA,IAC1K,oBAAC,UAAK,GAAE,4MAA2M;AAAA,KACrN;AAAA,EACA;AACF;AAEO,IAAM,kBAAkB;AAAA,EAC7B,qBAAC,OAAE,aAAY,QACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,mEAAkE;AAAA,IAC1E,oBAAC,UAAK,GAAE,6CAA4C;AAAA,IACpD,oBAAC,UAAK,GAAE,kDAAiD;AAAA,IACzD,oBAAC,UAAK,GAAE,YAAW;AAAA,IACnB,oBAAC,UAAK,GAAE,qBAAoB;AAAA,KAC9B;AAAA,EACA;AACF;AAEO,IAAM,mBAAmB;AAAA,EAC9B;AAAA,EACA,EAAE,OAAO,KAAK,QAAQ,IAAI;AAC5B;AAEO,IAAM,SAAS;AAAA,EACpB;AAAA,EACA,EAAE,OAAO,KAAK,QAAQ,IAAI;AAC5B;AAEO,IAAM,UAAU;AAAA,EACrB;AAAA,EACA,EAAE,OAAO,KAAK,QAAQ,IAAI;AAC5B;AAEO,IAAM,OAAO;AAAA,EAClB;AACF;AAEO,IAAM,OAAO;AAAA,EAClB;AACF;AAEO,IAAM,WAAW;AAAA,EACtB;AAAA,IAAC;AAAA;AAAA,MACC,GAAE;AAAA,MACF,aAAY;AAAA;AAAA,EACd;AAAA,EACA;AACF;AAEO,IAAM,WAAW;AAAA,EACtB;AAAA,IAAC;AAAA;AAAA,MACC,GAAE;AAAA,MACF,aAAY;AAAA;AAAA,EACd;AAAA,EACA;AACF;AAEO,IAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA,EAAE,QAAQ,KAAK;AACjB;AAEO,IAAM,QAAQ;AAAA,EACnB;AAAA,IAAC;AAAA;AAAA,MACC,GAAE;AAAA,MACF,aAAY;AAAA;AAAA,EACd;AAAA,EACA;AACF;AAEO,IAAM,UAAU;AAAA,EACrB;AACF;AAEO,IAAM,WAAW;AAAA,EACtB;AAAA,EACA,EAAE,OAAO,IAAI,QAAQ,GAAG;AAC1B;AAEO,IAAM,eAAe;AAAA,EAC1B,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,kFAAiF;AAAA,IACzF,oBAAC,UAAK,GAAE,cAAa;AAAA,IACrB,oBAAC,UAAK,GAAE,iBAAgB;AAAA,KAC1B;AAAA,EACA;AACF;AAEO,IAAM,eAAe;AAAA,EAC1B,iCACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,GAAE;AAAA;AAAA,IACJ;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,QAAO;AAAA,QACP,MAAK;AAAA,QACL,GAAE;AAAA;AAAA,IACJ;AAAA,KACF;AAAA,EACA,EAAE,OAAO,IAAI,QAAQ,GAAG;AAC1B;AAIO,IAAM,YAAY;AAAA,EACvB;AAAA,IAAC;AAAA;AAAA,MACC,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,MAAK;AAAA,MACL,GAAE;AAAA;AAAA,EACJ;AAAA,EACA,EAAE,OAAO,KAAK;AAChB;AAEA,IAAM,mBACJ,qBAAC,OAAE,aAAa,KACd;AAAA,sBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,EAClD,oBAAC,UAAK,GAAE,eAAc;AAAA,EACtB,oBAAC,UAAK,GAAE,cAAa;AAAA,EACrB,oBAAC,UAAK,GAAE,eAAc;AAAA,EACtB,oBAAC,UAAK,GAAE,aAAY;AAAA,GACtB;AAGF,IAAM,oBACJ,qBAAC,OAAE,aAAa,KACd;AAAA,sBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,EAClD,oBAAC,UAAK,GAAE,cAAa;AAAA,EACrB,oBAAC,UAAK,GAAE,eAAc;AAAA,EACtB,oBAAC,UAAK,GAAE,aAAY;AAAA,GACtB;AAGK,IAAM,mBAAmB,WAAW,mBAAmB,eAAe;AAEtE,IAAM,mBAAmB,WAAW,mBAAmB;AAAA,EAC5D,GAAG;AAAA,EACH,OAAO;AAAA,IACL,WAAW;AAAA,EACb;AACF,CAAC;AAEM,IAAM,mBAAmB,WAAW,kBAAkB,eAAe;AAErE,IAAM,iBAAiB,WAAW,kBAAkB;AAAA,EACzD,GAAG;AAAA,EACH,OAAO;AAAA,IACL,WAAW;AAAA,EACb;AACF,CAAC;AAQM,IAAM,eAAe;AAAA,EAC1B,iCACE;AAAA,yBAAC,OAAE,UAAS,WAAU,QAAO,gBAAe,aAAY,QACtD;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,eAAc;AAAA,UACd,gBAAe;AAAA;AAAA,MACjB;AAAA,MACA,oBAAC,UAAK,GAAE,kTAAiT;AAAA,OAC3T;AAAA,IACA,oBAAC,UACC,8BAAC,cAAS,IAAG,KACX,8BAAC,UAAK,MAAK,QAAO,GAAE,iBAAgB,GACtC,GACF;AAAA,KACF;AAAA,EACA;AACF;AAEO,IAAM,kBAAkB;AAAA,EAC7B,iCACE;AAAA,yBAAC,OAAE,UAAS,WAAU,QAAO,gBAAe,aAAY,QACtD;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,eAAc;AAAA,UACd,gBAAe;AAAA;AAAA,MACjB;AAAA,MACA,oBAAC,UAAK,GAAE,mTAAkT;AAAA,OAC5T;AAAA,IACA,oBAAC,UACC,8BAAC,cAAS,IAAG,KACX,8BAAC,UAAK,MAAK,QAAO,GAAE,iBAAgB,GACtC,GACF;AAAA,KACF;AAAA,EACA;AACF;AAEO,IAAM,gBAAgB;AAAA,EAC3B,iCACE;AAAA,yBAAC,OAAE,UAAS,WAAU,QAAO,gBAAe,aAAY,QACtD;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,eAAc;AAAA,UACd,gBAAe;AAAA;AAAA,MACjB;AAAA,MACA,oBAAC,UAAK,GAAE,qTAAoT;AAAA,OAC9T;AAAA,IACA,oBAAC,UACC,8BAAC,cAAS,IAAG,KACX,8BAAC,UAAK,MAAK,QAAO,GAAE,iBAAgB,GACtC,GACF;AAAA,KACF;AAAA,EACA;AACF;AAEO,IAAM,iBAAiB;AAAA,EAC5B,iCACE;AAAA,yBAAC,OAAE,UAAS,WAAU,QAAO,gBAAe,aAAY,QACtD;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,eAAc;AAAA,UACd,gBAAe;AAAA;AAAA,MACjB;AAAA,MACA,oBAAC,UAAK,GAAE,qTAAoT;AAAA,OAC9T;AAAA,IACA,oBAAC,UACC,8BAAC,cAAS,IAAG,KACX,8BAAC,UAAK,MAAK,QAAO,GAAE,iBAAgB,GACtC,GACF;AAAA,KACF;AAAA,EACA;AACF;AAEO,IAAM,6BAA6B;AAAA,EACxC,iCACE;AAAA,yBAAC,OAAE,UAAS,WAAU,QAAO,gBAAe,aAAY,QACtD;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,eAAc;AAAA,UACd,gBAAe;AAAA;AAAA,MACjB;AAAA,MACA,oBAAC,UAAK,GAAE,6JAA4J;AAAA,OACtK;AAAA,IACA,oBAAC,UACC,8BAAC,cAAS,IAAG,KACX,8BAAC,UAAK,MAAK,QAAO,GAAE,iBAAgB,GACtC,GACF;AAAA,KACF;AAAA,EACA;AACF;AAEO,IAAM,2BAA2B;AAAA,EACtC,iCACE;AAAA,yBAAC,OAAE,UAAS,WAAU,QAAO,gBAAe,aAAY,QACtD;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,eAAc;AAAA,UACd,gBAAe;AAAA;AAAA,MACjB;AAAA,MACA,oBAAC,UAAK,GAAE,4JAA2J;AAAA,OACrK;AAAA,IACA,oBAAC,UACC,8BAAC,cAAS,IAAG,KACX,8BAAC,UAAK,MAAK,QAAO,GAAE,iBAAgB,GACtC,GACF;AAAA,KACF;AAAA,EACA;AACF;AAEO,IAAM,uBAAuB;AAAA,EAClC,qBAAC,OAAE,QAAO,gBAAe,aAAY,QACnC;AAAA,wBAAC,UAAK,GAAE,mBAAkB,eAAc,SAAQ,gBAAe,SAAQ;AAAA,IACvE,oBAAC,UAAK,GAAE,mBAAkB,gBAAe,SAAQ;AAAA,IACjD,oBAAC,UAAK,GAAE,oBAAmB,eAAc,SAAQ,gBAAe,SAAQ;AAAA,IACxE,oBAAC,UAAK,GAAE,kTAAiT;AAAA,KAC3T;AAAA,EACA;AACF;AAEO,IAAM,yBAAyB;AAAA,EACpC,qBAAC,OAAE,QAAO,gBAAe,aAAY,QACnC;AAAA,wBAAC,UAAK,GAAE,qBAAoB,eAAc,SAAQ,gBAAe,SAAQ;AAAA,IACzE,oBAAC,UAAK,GAAE,oBAAmB,gBAAe,SAAQ;AAAA,IAClD,oBAAC,UAAK,GAAE,mBAAkB,eAAc,SAAQ,gBAAe,SAAQ;AAAA,IACvE,oBAAC,UAAK,GAAE,kTAAiT;AAAA,KAC3T;AAAA,EACA;AACF;AAEO,IAAM,YAAY;AAAA,EACvB,qBAAC,OAAE,aAAY,OACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,YAAO,IAAG,KAAI,IAAG,KAAI,GAAE,KAAI;AAAA,IAC5B,oBAAC,UAAK,GAAE,6CAA4C;AAAA,IACpD,oBAAC,UAAK,GAAE,6BAA4B;AAAA,IACpC,oBAAC,UAAK,GAAE,gCAA+B;AAAA,KACzC;AAAA,EACA;AACF;AAGO,IAAM,QAAQ;AAAA,EACnB;AACF;AAEO,IAAM,OAAO;AAAA,EAClB;AACF;AAEO,IAAM,YAAY;AAAA,EACvB,iCACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,UAAS;AAAA,QACT,QAAO;AAAA,QACP,aAAY;AAAA,QACZ,eAAc;AAAA,QACd,gBAAe;AAAA,QAEf,8BAAC,UAAK,GAAE,wBAAuB;AAAA;AAAA,IACjC;AAAA,IACA,oBAAC,UACC,8BAAC,cAAS,IAAG,KACX,8BAAC,UAAK,MAAK,QAAO,GAAE,iBAAgB,GACtC,GACF;AAAA,KACF;AAAA,EACA;AACF;AAEO,IAAM,QAAQ;AAAA,EACnB;AAAA,EACA,EAAE,QAAQ,KAAK;AACjB;AAGO,IAAM,SAAS;AAAA,EACpB;AAAA,EACA,EAAE,OAAO,GAAG;AACd;AAEO,IAAM,OAAO;AAAA,EAClB;AAAA,EACA,EAAE,OAAO,KAAK,QAAQ,IAAI;AAC5B;AAIO,IAAM,YAAY,MAAM;AAAA,EAAK,CAAC,EAAE,MAAM,MAC3C;AAAA,IACE,iCACE;AAAA,0BAAC,UAAK,GAAE,qBAAoB,MAAM,cAAc,KAAK,GAAG;AAAA,MACxD;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,QAAQ,cAAc,KAAK;AAAA,UAC3B,aAAY;AAAA;AAAA,MACd;AAAA,MACA,oBAAC,UAAK,GAAE,wBAAuB,MAAM,cAAc,KAAK,GAAG;AAAA,MAC3D;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,QAAQ,cAAc,KAAK;AAAA,UAC3B,aAAY;AAAA;AAAA,MACd;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAM,aAAa,KAAK;AAAA,UACxB,QAAQ,cAAc,KAAK;AAAA,UAC3B,aAAY;AAAA,UAEZ;AAAA,gCAAC,UAAK,GAAE,OAAM,GAAE,OAAM,OAAM,MAAK,QAAO,MAAK;AAAA,YAC7C,oBAAC,UAAK,GAAE,OAAM,GAAE,SAAQ,OAAM,MAAK,QAAO,MAAK;AAAA,YAC/C,oBAAC,UAAK,GAAE,SAAQ,GAAE,SAAQ,OAAM,MAAK,QAAO,MAAK;AAAA,YACjD,oBAAC,UAAK,GAAE,SAAQ,GAAE,OAAM,OAAM,MAAK,QAAO,MAAK;AAAA;AAAA;AAAA,MACjD;AAAA,OACF;AAAA,IACA,EAAE,OAAO,KAAK,QAAQ,KAAK,QAAQ,KAAK;AAAA,EAC1C;AACF;AAEO,IAAM,cAAc,MAAM;AAAA,EAAK,CAAC,EAAE,MAAM,MAC7C;AAAA,IACE,iCACE;AAAA,0BAAC,UAAK,GAAE,qBAAoB,MAAM,cAAc,KAAK,GAAG;AAAA,MACxD;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,QAAQ,cAAc,KAAK;AAAA,UAC3B,aAAY;AAAA;AAAA,MACd;AAAA,MACA,oBAAC,UAAK,GAAE,wBAAuB,MAAM,cAAc,KAAK,GAAG;AAAA,MAC3D;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,QAAQ,cAAc,KAAK;AAAA,UAC3B,aAAY;AAAA;AAAA,MACd;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAM,aAAa,KAAK;AAAA,UACxB,QAAQ,cAAc,KAAK;AAAA,UAC3B,aAAY;AAAA,UAEZ;AAAA,gCAAC,UAAK,GAAE,OAAM,GAAE,OAAM,OAAM,MAAK,QAAO,MAAK;AAAA,YAC7C,oBAAC,UAAK,GAAE,QAAO,GAAE,SAAQ,OAAM,MAAK,QAAO,MAAK;AAAA,YAChD,oBAAC,UAAK,GAAE,SAAQ,GAAE,SAAQ,OAAM,MAAK,QAAO,MAAK;AAAA,YACjD,oBAAC,UAAK,GAAE,SAAQ,GAAE,QAAO,OAAM,MAAK,QAAO,MAAK;AAAA,YAChD,oBAAC,UAAK,GAAE,SAAQ,GAAE,OAAM,OAAM,MAAK,QAAO,MAAK;AAAA,YAC/C,oBAAC,UAAK,GAAE,OAAM,GAAE,SAAQ,OAAM,MAAK,QAAO,MAAK;AAAA;AAAA;AAAA,MACjD;AAAA,OACF;AAAA,IACA,EAAE,OAAO,KAAK,QAAQ,KAAK,QAAQ,KAAK;AAAA,EAC1C;AACF;AAEO,IAAM,iBAAiB;AAAA,EAC5B,oBAAC,OAAE,aAAa,MACd,8BAAC,UAAK,GAAE,oQAAmQ,GAC7Q;AAAA,EACA;AACF;AAEO,IAAM,kBAAkB;AAAA,EAC7B,iCACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,QAAO;AAAA,QACP,aAAY;AAAA;AAAA,IACd;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,IAAG;AAAA,QACH,OAAO,EAAE,UAAU,QAAQ;AAAA,QAC3B,WAAU;AAAA,QACV,GAAG;AAAA,QACH,GAAG;AAAA,QACH,OAAO;AAAA,QACP,QAAQ;AAAA,QAER;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA,YACL,QAAO;AAAA,YACP,aAAY;AAAA;AAAA,QACd;AAAA;AAAA,IACF;AAAA,IACA,oBAAC,OAAE,MAAK,yBACN;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,QAAO;AAAA,QACP,aAAY;AAAA,QACZ,eAAc;AAAA,QACd,gBAAe;AAAA;AAAA,IACjB,GACF;AAAA,KACF;AAAA,EACA;AACF;AAEO,IAAM,qBAAqB;AAAA,EAChC,iCACE;AAAA,yBAAC,OAAE,UAAS,WACV;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,QAAO;AAAA,UACP,aAAY;AAAA;AAAA,MACd;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,IAAG;AAAA,UACH,OAAO,EAAE,UAAU,QAAQ;AAAA,UAC3B,WAAU;AAAA,UACV,GAAG;AAAA,UACH,GAAG;AAAA,UACH,OAAO;AAAA,UACP,QAAQ;AAAA,UAER;AAAA,YAAC;AAAA;AAAA,cACC,GAAE;AAAA,cACF,QAAO;AAAA,cACP,aAAY;AAAA,cACZ,eAAc;AAAA,cACd,gBAAe;AAAA;AAAA,UACjB;AAAA;AAAA,MACF;AAAA,MACA,oBAAC,OAAE,MAAK,4BACN;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,MAAK;AAAA;AAAA,MACP,GACF;AAAA,OACF;AAAA,IACA,oBAAC,UACC,8BAAC,cAAS,IAAG,KACX,8BAAC,UAAK,MAAK,QAAO,GAAE,iBAAgB,GACtC,GACF;AAAA,KACF;AAAA,EACA;AACF;AAEO,IAAM,gBAAgB;AAAA,EAC3B,iCACE;AAAA,wBAAC,OAAE,UAAS,WACV;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,QAAO;AAAA,QACP,aAAY;AAAA;AAAA,IACd,GACF;AAAA,IACA,oBAAC,UACC,8BAAC,cAAS,IAAG,KACX,8BAAC,UAAK,MAAK,QAAO,GAAE,iBAAgB,GACtC,GACF;AAAA,KACF;AAAA,EACA,EAAE,GAAG,yBAAyB,MAAM,eAAe;AACrD;AAEO,IAAM,sBAAsB;AAAA,EACjC,gCACE;AAAA,IAAC;AAAA;AAAA,MACC,GAAE;AAAA,MACF,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA;AAAA,EACjB,GACF;AAAA,EACA;AACF;AAEO,IAAM,sBAAsB;AAAA,EACjC;AAAA,IAAC;AAAA;AAAA,MACC,GAAE;AAAA,MACF,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA;AAAA,EACjB;AAAA,EACA;AACF;AAEO,IAAM,2BAA2B;AAAA,EACtC;AAAA,IAAC;AAAA;AAAA,MACC,GAAE;AAAA,MACF,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA;AAAA,EACjB;AAAA,EACA;AACF;AAEO,IAAM,uBAAuB,MAAM;AAAA,EAAK,CAAC,EAAE,MAAM,MACtD;AAAA,IACE;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,QAAQ,cAAc,KAAK;AAAA,QAC3B,aAAa;AAAA,QACb,MAAK;AAAA,QACL,eAAc;AAAA;AAAA,IAChB;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAEO,IAAM,wBAAwB;AAAA,EACnC,qBAAC,OAAE,aAAY,KACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,WAAU;AAAA,IAClB,oBAAC,UAAK,GAAE,YAAW;AAAA,IACnB,oBAAC,UAAK,GAAE,YAAW;AAAA,KACrB;AAAA,EACA;AACF;AAGO,IAAM,wBAAwB;AAAA,EACnC,qBAAC,OAAE,aAAY,KACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,cAAa;AAAA,IACrB,oBAAC,UAAK,GAAE,cAAa;AAAA,IACrB,oBAAC,UAAK,GAAE,cAAa;AAAA,KACvB;AAAA,EACA;AACF;AAEO,IAAM,0BAA0B;AAAA,EACrC;AAAA,IAAC;AAAA;AAAA,MACC,GAAE;AAAA,MACF,aAAY;AAAA;AAAA,EACd;AAAA,EACA;AACF;AAEO,IAAM,uBAAuB;AAAA,EAClC;AAAA,IAAC;AAAA;AAAA,MACC,GAAE;AAAA,MACF,aAAY;AAAA;AAAA,EACd;AAAA,EACA;AACF;AAEO,IAAM,2BAA2B;AAAA,EACtC;AAAA,IAAC;AAAA;AAAA,MACC,GAAE;AAAA,MACF,aAAY;AAAA;AAAA,EACd;AAAA,EACA;AACF;AAEO,IAAM,gBAAgB;AAAA,EAC3B,qBAAC,SAAI,aAAY,OACf;AAAA,wBAAC,UAAK,GAAE,8HAA6H;AAAA,IACrI,oBAAC,UAAK,GAAE,4BAA2B;AAAA,IACnC,oBAAC,UAAK,GAAE,4BAA2B;AAAA,IACnC,oBAAC,UAAK,GAAE,4BAA2B;AAAA,IACnC,oBAAC,UAAK,GAAE,qBAAoB;AAAA,IAC5B,oBAAC,UAAK,GAAE,4BAA2B;AAAA,IACnC,oBAAC,UAAK,GAAE,4BAA2B;AAAA,IACnC,oBAAC,UAAK,GAAE,4BAA2B;AAAA,IACnC,oBAAC,UAAK,GAAE,4BAA2B;AAAA,IACnC,oBAAC,UAAK,GAAE,uBAAsB;AAAA,IAC9B,oBAAC,UAAK,GAAE,4BAA2B;AAAA,IACnC,oBAAC,UAAK,GAAE,4BAA2B;AAAA,KACrC;AAAA,EACA;AACF;AAGO,IAAM,gBAAgB;AAAA,EAC3B;AAAA,IAAC;AAAA;AAAA,MACC,aAAY;AAAA,MACZ,QAAO;AAAA,MACP,eAAc;AAAA,MACd,gBAAe;AAAA,MAEf;AAAA,4BAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,QAClD,oBAAC,UAAK,GAAE,6BAA4B;AAAA,QACpC,oBAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,QAAO;AAAA,QACvC,oBAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,QAAO;AAAA,QACvC,oBAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,QAAO;AAAA,QACvC,oBAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,SAAQ;AAAA,QACzC,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI,IAAG,SAAQ;AAAA,QACvC,oBAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,SAAQ;AAAA,QACzC,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI,IAAG,SAAQ;AAAA,QACvC,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI,IAAG,SAAQ;AAAA,QACvC,oBAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,SAAQ;AAAA,QACzC,oBAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,SAAQ;AAAA,QACzC,oBAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,SAAQ;AAAA;AAAA;AAAA,EAC3C;AAAA,EACA;AACF;AAEO,IAAM,oBAAoB;AAAA,EAC/B,qBAAC,OAAE,QAAO,gBAAe,SAAS,KAAK,aAAa,GAClD;AAAA,wBAAC,UAAK,GAAE,cAAa;AAAA,IACrB,oBAAC,UAAK,GAAE,YAAW;AAAA,IACnB,oBAAC,UAAK,GAAE,cAAa;AAAA,KACvB;AAAA,EACA;AACF;AAEO,IAAM,qBAAqB,MAAM;AAAA,EACtC,CAAC,EAAE,OAAO,MAAM,MACd;AAAA,IACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,OAAO,kCAAkC;AAAA,QACpD,QAAO;AAAA,QACP,aAAa;AAAA,QACb,MAAK;AAAA,QAEL;AAAA,8BAAC,UAAK,GAAE,mCAAkC;AAAA,UAC1C,oBAAC,UAAK,GAAE,2BAA0B;AAAA;AAAA;AAAA,IACpC;AAAA,IACA,EAAE,OAAO,IAAI,QAAQ,GAAG;AAAA,EAC1B;AACJ;AAEO,IAAM,sBAAsB,MAAM;AAAA,EACvC,CAAC,EAAE,OAAO,MAAM,MACd;AAAA,IACE;AAAA,MAAC;AAAA;AAAA,QACC,QAAO;AAAA,QACP,MAAK;AAAA,QACL,WAAW,OAAO,kCAAkC;AAAA,QAEpD;AAAA,8BAAC,UAAK,GAAE,eAAc,aAAa,GAAG;AAAA,UACtC,oBAAC,YAAO,GAAE,KAAI,WAAU,0BAAyB;AAAA;AAAA;AAAA,IACnD;AAAA,IACA,EAAE,OAAO,IAAI,QAAQ,GAAG;AAAA,EAC1B;AACJ;AAEO,IAAM,6BAA6B,MAAM;AAAA,EAC9C,CAAC,EAAE,OAAO,MAAM,MACd;AAAA,IACE;AAAA,MAAC;AAAA;AAAA,QACC,QAAO;AAAA,QACP,MAAK;AAAA,QACL,WAAW,OAAO,kCAAkC;AAAA,QACpD,aAAa;AAAA,QAEb;AAAA,8BAAC,UAAK,GAAE,eAAc;AAAA,UACtB,oBAAC,YAAO,GAAE,KAAI,WAAU,0BAAyB;AAAA;AAAA;AAAA,IACnD;AAAA,IACA,EAAE,OAAO,IAAI,QAAQ,GAAG;AAAA,EAC1B;AACJ;AAEO,IAAM,mBAAmB,MAAM;AAAA,EACpC,CAAC,EAAE,OAAO,MAAM,MACd;AAAA,IACE,oBAAC,OAAE,WAAW,OAAO,kCAAkC,IACrD;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,QAAO;AAAA,QACP,aAAa;AAAA,QACb,MAAK;AAAA;AAAA,IACP,GACF;AAAA,IACA,EAAE,OAAO,IAAI,QAAQ,GAAG;AAAA,EAC1B;AACJ;AAEO,IAAM,wBAAwB,MAAM;AAAA,EACzC,CAAC,EAAE,OAAO,MAAM,MACd;AAAA,IACE;AAAA,MAAC;AAAA;AAAA,QACC,QAAO;AAAA,QACP,MAAK;AAAA,QACL,WAAW,OAAO,kCAAkC;AAAA,QAEpD;AAAA,8BAAC,UAAK,GAAE,eAAc,aAAa,GAAG;AAAA,UACtC,oBAAC,UAAK,GAAE,wCAAuC;AAAA;AAAA;AAAA,IACjD;AAAA,IACA,EAAE,OAAO,IAAI,QAAQ,GAAG;AAAA,EAC1B;AACJ;AAEO,IAAM,+BAA+B,MAAM;AAAA,EAChD,CAAC,EAAE,OAAO,MAAM,MACd;AAAA,IACE;AAAA,MAAC;AAAA;AAAA,QACC,QAAO;AAAA,QACP,MAAK;AAAA,QACL,WAAW,OAAO,kCAAkC;AAAA,QACpD,aAAa;AAAA,QACb,gBAAe;AAAA,QAEf;AAAA,8BAAC,UAAK,GAAE,aAAY;AAAA,UACpB,oBAAC,UAAK,GAAE,sBAAqB,MAAK,QAAO;AAAA;AAAA;AAAA,IAC3C;AAAA,IAEA,EAAE,OAAO,IAAI,QAAQ,GAAG;AAAA,EAC1B;AACJ;AAEO,IAAM,uBAAuB,MAAM;AAAA,EACxC,CAAC,EAAE,OAAO,MAAM,MACd;AAAA,IACE;AAAA,MAAC;AAAA;AAAA,QACC,QAAO;AAAA,QACP,MAAK;AAAA,QACL,WAAW,OAAO,kCAAkC;AAAA,QACpD,gBAAe;AAAA,QACf,aAAa;AAAA,QAEb;AAAA,8BAAC,UAAK,GAAE,aAAY;AAAA,UACpB,oBAAC,UAAK,GAAE,6BAA4B;AAAA;AAAA;AAAA,IACtC;AAAA,IACA,EAAE,OAAO,IAAI,QAAQ,GAAG;AAAA,EAC1B;AACJ;AAEO,IAAM,8BAA8B,MAAM;AAAA,EAC/C,CAAC,EAAE,OAAO,MAAM,MACd;AAAA,IACE;AAAA,MAAC;AAAA;AAAA,QACC,QAAO;AAAA,QACP,MAAK;AAAA,QACL,WAAW,OAAO,kCAAkC;AAAA,QACpD,gBAAe;AAAA,QACf,aAAa;AAAA,QAEb;AAAA,8BAAC,UAAK,GAAE,aAAY;AAAA,UACpB,oBAAC,UAAK,GAAE,6BAA4B;AAAA;AAAA;AAAA,IACtC;AAAA,IACA,EAAE,OAAO,IAAI,QAAQ,GAAG;AAAA,EAC1B;AACJ;AAEO,IAAM,wBAAwB,MAAM;AAAA,EACzC,CAAC,EAAE,OAAO,MAAM,MACd;AAAA,IACE;AAAA,MAAC;AAAA;AAAA,QACC,QAAO;AAAA,QACP,MAAK;AAAA,QACL,WAAW,OAAO,KAAK;AAAA,QACvB,gBAAe;AAAA,QACf,aAAa;AAAA,QAEb,8BAAC,UAAK,GAAE,sCAAqC;AAAA;AAAA,IAC/C;AAAA,IACA,EAAE,OAAO,IAAI,QAAQ,GAAG;AAAA,EAC1B;AACJ;AAEO,IAAM,2BAA2B,MAAM;AAAA,EAC5C,CAAC,EAAE,OAAO,MAAM,MACd;AAAA,IACE;AAAA,MAAC;AAAA;AAAA,QACC,QAAO;AAAA,QACP,MAAK;AAAA,QACL,WAAW,OAAO,KAAK;AAAA,QACvB,gBAAe;AAAA,QACf,aAAa;AAAA,QAEb,8BAAC,UAAK,GAAE,iCAAgC;AAAA;AAAA,IAC1C;AAAA,IACA,EAAE,OAAO,IAAI,QAAQ,GAAG;AAAA,EAC1B;AACJ;AAEO,IAAM,iCAAiC,MAAM;AAAA,EAClD,CAAC,EAAE,OAAO,MAAM,MACd;AAAA,IACE;AAAA,MAAC;AAAA;AAAA,QACC,QAAO;AAAA,QACP,MAAK;AAAA,QACL,WAAW,OAAO,KAAK;AAAA,QACvB,gBAAe;AAAA,QACf,aAAa;AAAA,QAEb,8BAAC,UAAK,GAAE,0DAAyD;AAAA;AAAA,IACnE;AAAA,IACA,EAAE,OAAO,IAAI,QAAQ,GAAG;AAAA,EAC1B;AACJ;AAEO,IAAM,oBAAoB;AAAA,EAC/B,iCACE;AAAA,wBAAC,OAAE,UAAS,WACV;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,QAAO;AAAA,QACP,aAAY;AAAA,QACZ,eAAc;AAAA,QACd,gBAAe;AAAA;AAAA,IACjB,GACF;AAAA,IACA,oBAAC,UACC,8BAAC,cAAS,IAAG,KACX,8BAAC,UAAK,MAAK,QAAO,GAAE,iBAAgB,GACtC,GACF;AAAA,KACF;AAAA,EACA;AACF;AAEO,IAAM,qBAAqB;AAAA,EAChC,iCACE;AAAA,wBAAC,OAAE,UAAS,WACV;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,QAAO;AAAA,QACP,aAAY;AAAA,QACZ,eAAc;AAAA,QACd,gBAAe;AAAA;AAAA,IACjB,GACF;AAAA,IACA,oBAAC,UACC,8BAAC,cAAS,IAAG,KACX,8BAAC,UAAK,MAAK,QAAO,GAAE,iBAAgB,GACtC,GACF;AAAA,KACF;AAAA,EACA;AACF;AAEO,IAAM,oBAAoB;AAAA,EAC/B,iCACE;AAAA,wBAAC,OAAE,UAAS,WACV;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,QAAO;AAAA,QACP,aAAY;AAAA,QACZ,eAAc;AAAA,QACd,gBAAe;AAAA;AAAA,IACjB,GACF;AAAA,IACA,oBAAC,UACC,8BAAC,cAAS,IAAG,KACX,8BAAC,UAAK,MAAK,QAAO,GAAE,iBAAgB,GACtC,GACF;AAAA,KACF;AAAA,EACA;AACF;AAEO,IAAM,yBAAyB;AAAA,EACpC,gCACE;AAAA,IAAC;AAAA;AAAA,MACC,GAAE;AAAA,MACF,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA;AAAA,EACjB,GACF;AAAA,EACA;AACF;AAEO,IAAM,eAAe;AAAA,EAC1B,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,gBAAe;AAAA,IACvB,oBAAC,UAAK,GAAE,YAAW;AAAA,IACnB,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,iBAAgB;AAAA,IACxB,oBAAC,UAAK,GAAE,YAAW;AAAA,IACnB,oBAAC,UAAK,GAAE,YAAW;AAAA,KACrB;AAAA,EACA;AACF;AAEO,IAAM,wBAAwB;AAAA,EACnC,gCACE;AAAA,IAAC;AAAA;AAAA,MACC,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA,MAEf;AAAA,4BAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,QAClD,oBAAC,UAAK,GAAE,YAAW;AAAA,QACnB,oBAAC,UAAK,GAAE,WAAU;AAAA,QAClB,oBAAC,UAAK,GAAE,YAAW;AAAA,QACnB,oBAAC,UAAK,GAAE,YAAW;AAAA,QACnB,oBAAC,UAAK,GAAE,WAAU;AAAA,QAClB,oBAAC,UAAK,GAAE,WAAU;AAAA,QAClB,oBAAC,UAAK,GAAE,UAAS;AAAA;AAAA;AAAA,EACnB,GACF;AAAA,EACA;AACF;AAEO,IAAM,uBAAuB;AAAA,EAClC,gCACE;AAAA,IAAC;AAAA;AAAA,MACC,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA,MAEf,8BAAC,UAAK,GAAE,6GAA4G;AAAA;AAAA,EACtH,GACF;AAAA,EACA;AACF;AAEO,IAAM,qBAAqB;AAAA,EAChC,iCACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,UAAS;AAAA,QACT,QAAO;AAAA,QACP,aAAY;AAAA,QACZ,eAAc;AAAA,QACd,gBAAe;AAAA,QAEf,8BAAC,UAAK,GAAE,+FAA8F;AAAA;AAAA,IACxG;AAAA,IACA,oBAAC,UACC,8BAAC,cAAS,IAAG,KACX,8BAAC,UAAK,MAAK,QAAO,GAAE,iBAAgB,GACtC,GACF;AAAA,KACF;AAAA,EACA;AACF;AAEO,IAAM,oBAAoB;AAAA,EAC/B;AAAA,IAAC;AAAA;AAAA,MACC,QAAO;AAAA,MACP,MAAK;AAAA,MACL,eAAc;AAAA,MACd,gBAAe;AAAA,MACf,aAAa;AAAA,MAEb;AAAA,4BAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,QAClD,oBAAC,UAAK,IAAG,KAAI,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI;AAAA,QACnC,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,QACrC,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA;AAAA;AAAA,EACvC;AAAA,EACA;AACF;AAEO,IAAM,sBAAsB;AAAA,EACjC;AAAA,IAAC;AAAA;AAAA,MACC,QAAO;AAAA,MACP,MAAK;AAAA,MACL,eAAc;AAAA,MACd,gBAAe;AAAA,MAEf;AAAA,4BAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,QAClD,oBAAC,UAAK,IAAG,KAAI,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI;AAAA,QACnC,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,QACrC,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA;AAAA;AAAA,EACvC;AAAA,EACA;AACF;AAEO,IAAM,qBAAqB;AAAA,EAChC;AAAA,IAAC;AAAA;AAAA,MACC,QAAO;AAAA,MACP,MAAK;AAAA,MACL,eAAc;AAAA,MACd,gBAAe;AAAA,MAEf;AAAA,4BAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,QAClD,oBAAC,UAAK,IAAG,KAAI,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI;AAAA,QACnC,oBAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,QACtC,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA;AAAA;AAAA,EACvC;AAAA,EACA;AACF;AAGO,IAAM,mBAAmB,MAAM;AAAA,EAAK,CAAC,EAAE,MAAM,MAClD;AAAA,IACE;AAAA,MAAC;AAAA;AAAA,QACC,aAAY;AAAA,QACZ,QAAO;AAAA,QACP,MAAK;AAAA,QACL,eAAc;AAAA,QACd,gBAAe;AAAA,QAEf;AAAA,8BAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,UAClD,oBAAC,UAAK,IAAG,KAAI,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI;AAAA,UACnC,oBAAC,UAAK,GAAE,KAAI,GAAE,KAAI,OAAM,KAAI,QAAO,MAAK,IAAG,KAAI;AAAA;AAAA;AAAA,IACjD;AAAA,IACA;AAAA,EACF;AACF;AAGO,IAAM,sBAAsB,MAAM;AAAA,EAAK,CAAC,EAAE,MAAM,MACrD;AAAA,IACE;AAAA,MAAC;AAAA;AAAA,QACC,aAAY;AAAA,QACZ,QAAO;AAAA,QACP,MAAK;AAAA,QACL,eAAc;AAAA,QACd,gBAAe;AAAA,QAEf;AAAA,8BAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,UAClD,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,UACrC,oBAAC,UAAK,GAAE,KAAI,GAAE,KAAI,OAAM,KAAI,QAAO,MAAK,IAAG,KAAI;AAAA;AAAA;AAAA,IACjD;AAAA,IACA;AAAA,EACF;AACF;AAGO,IAAM,sBAAsB,MAAM;AAAA,EAAK,CAAC,EAAE,MAAM,MACrD;AAAA,IACE;AAAA,MAAC;AAAA;AAAA,QACC,aAAY;AAAA,QACZ,QAAO;AAAA,QACP,MAAK;AAAA,QACL,eAAc;AAAA,QACd,gBAAe;AAAA,QAEf;AAAA,8BAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,UAClD,oBAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK;AAAA,UACpC,oBAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,UACtC,oBAAC,UAAK,GAAE,KAAI,GAAE,KAAI,OAAM,KAAI,QAAO,MAAK,IAAG,KAAI;AAAA;AAAA;AAAA,IACjD;AAAA,IACA;AAAA,EACF;AACF;AAEO,IAAM,YAAY;AAAA,EACvB,qBAAC,OACC;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,oBAAmB;AAAA,IAC3B,oBAAC,UAAK,GAAE,uBAAsB;AAAA,IAC9B,oBAAC,UAAK,GAAE,uBAAsB;AAAA,IAC9B,oBAAC,UAAK,GAAE,sBAAqB;AAAA,IAC7B,oBAAC,UAAK,GAAE,sBAAqB;AAAA,KAC/B;AAAA,EACA;AACF;AAEO,IAAM,cAAc;AAAA,EACzB;AAAA,IAAC;AAAA;AAAA,MACC,GAAE;AAAA,MACF,MAAK;AAAA;AAAA,EACP;AAAA,EACA,EAAE,OAAO,KAAK,QAAQ,IAAI;AAC5B;AAEO,IAAM,SAAS;AAAA,EACpB,oBAAC,UAAK,GAAE,4UAA2U;AACrV;AAEO,IAAM,WAAW;AAAA,EACtB,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,oCAAmC;AAAA,IAC3C,oBAAC,UAAK,GAAE,oCAAmC;AAAA,IAC3C,oBAAC,UAAK,GAAE,iCAAgC;AAAA,IACxC,oBAAC,UAAK,GAAE,iNAAgN;AAAA,KAC1N;AAAA,EACA;AACF;AAEO,IAAM,eAAe;AAAA,EAC1B,iCACE;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,8CAA6C;AAAA,IACrD,oBAAC,UAAK,GAAE,kBAAiB;AAAA,IACzB,oBAAC,UAAK,GAAE,cAAa;AAAA,KACvB;AAAA,EACA;AACF;AAEO,IAAM,WAAW;AAAA,EACtB,iCACE;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,gFAA+E;AAAA,IACvF,oBAAC,UAAK,GAAE,gEAA+D;AAAA,KACzE;AAAA,EACA;AACF;AAEO,IAAM,UAAU;AAAA,EACrB,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,2CAA0C;AAAA,IAClD,oBAAC,UAAK,GAAE,4CAA2C;AAAA,IACnD,oBAAC,UAAK,GAAE,2BAA0B;AAAA,IAClC,oBAAC,UAAK,GAAE,mBAAkB;AAAA,KAC5B;AAAA,EACA;AACF;AAEO,IAAM,WAAW;AAAA,EACtB,iCACE;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,8CAA6C;AAAA,IACrD,oBAAC,UAAK,GAAE,gBAAe;AAAA,IACvB,oBAAC,UAAK,GAAE,qDAAoD;AAAA,KAC9D;AAAA,EACA;AACF;AAEO,IAAM,iBAAiB;AAAA,EAC5B,iCACE;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,kBAAiB;AAAA,KAC3B;AAAA,EACA;AACF;AAEO,IAAM,uBAAuB;AAAA,EAClC,iCACE;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,aAAY;AAAA,QACZ,MAAK;AAAA;AAAA,IACN;AAAA,KACH;AAAA,EACA;AACF;AAEO,IAAM,kBAAkB;AAAA,EAC7B,iCACE;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,oBAAmB;AAAA,KAC7B;AAAA,EACA;AACF;AAEO,IAAM,oBAAoB;AAAA,EAC/B,iCACE;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,qIAAoI;AAAA,IAC5I,oBAAC,UAAK,GAAE,WAAU;AAAA,IAClB,oBAAC,UAAK,GAAE,cAAa;AAAA,KACvB;AAAA,EACA;AACF;AAEO,IAAM,iBAAiB;AAAA,EAC5B,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,8EAA6E;AAAA,KACvF;AAAA,EACA;AACF;AAEO,IAAM,iBAAiB;AAAA,EAC5B,qBAAC,OAAE,aAAa,KACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,iBAAgB;AAAA,IACxB,oBAAC,UAAK,GAAE,4CAA2C;AAAA,IACnD,oBAAC,UAAK,GAAE,iFAAgF;AAAA,KAC1F;AAAA,EACA;AACF;AAEO,IAAM,gBAAgB;AAAA,EAC3B,qBAAC,OAAE,aAAa,KACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,cAAa;AAAA,IACrB,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,cAAa;AAAA,KACvB;AAAA,EACA;AACF;AAEO,IAAM,kBAAkB;AAAA,EAC7B;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,GAAE;AAAA;AAAA,EACJ;AACF;AAEO,IAAM,iBAAiB;AAAA,EAC5B,qBAAC,OAAE,aAAY,QACb;AAAA,wBAAC,UAAK,GAAE,uBAAsB;AAAA,IAC9B,oBAAC,UAAK,GAAE,4BAA2B;AAAA,IACnC,oBAAC,UAAK,GAAE,iCAAgC;AAAA,KAC1C;AAAA,EACA;AACF;AAEO,IAAM,uBAAuB;AAAA,EAClC;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA,MACf,WAAU;AAAA,MAEV;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,GAAE;AAAA;AAAA,QACJ;AAAA,QACA,oBAAC,UAAK,GAAE,+JAA8J;AAAA;AAAA;AAAA,EACxK;AAAA,EAEA;AACF;AAEO,IAAM,YAAY;AAAA,EACvB,qBAAC,OAAE,QAAO,gBAAe,MAAK,QAC5B;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB;AAAA,IACtC,oBAAC,UAAK,GAAE,iCAAgC;AAAA,IACxC,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,oEAAmE;AAAA,IAC3E,oBAAC,UAAK,GAAE,sEAAqE;AAAA,KAC/E;AAAA,EACA;AACF;AAEO,IAAM,gBAAgB;AAAA,EAC3B,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB;AAAA,IACtC,oBAAC,UAAK,GAAE,iCAAgC;AAAA,IACxC,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,oEAAmE;AAAA,IAC3E,oBAAC,UAAK,GAAE,sEAAqE;AAAA,KAC/E;AAAA,EACA;AACF;AAEO,IAAM,aAAa;AAAA,EACxB,qBAAC,OAAE,QAAO,gBAAe,MAAK,QAC5B;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,iEAAgE;AAAA,IACxE,oBAAC,UAAK,GAAE,kEAAiE;AAAA,IACzE,oBAAC,UAAK,GAAE,oGAAmG;AAAA,IAC3G,oBAAC,UAAK,GAAE,6DAA4D;AAAA,IACpE,oBAAC,UAAK,GAAE,mEAAkE;AAAA,IAC1E,oBAAC,UAAK,GAAE,4GAA2G;AAAA,KACrH;AAAA,EACA;AACF;AAEO,IAAM,iBAAiB;AAAA,EAC5B,qBAAC,OAAE,QAAO,gBAAe,MAAK,QAC5B;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,4BAA2B;AAAA,IACnC,oBAAC,UAAK,GAAE,2BAA0B;AAAA,IAClC,oBAAC,UAAK,GAAE,2BAA0B;AAAA,IAClC,oBAAC,UAAK,GAAE,8BAA6B;AAAA,KACvC;AAAA,EACA;AACF;AAEO,IAAM,UAAU;AAAA,EACrB,qBAAC,OAAE,QAAO,gBAAe,MAAK,QAAO,aAAa,KAChD;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,uCAAsC;AAAA,IAC9C,oBAAC,UAAK,GAAE,qFAAoF;AAAA,KAC9F;AAAA,EACA;AACF;AAEO,IAAM,gBAAgB;AAAA,EAC3B,qBAAC,OAAE,QAAO,gBAAe,MAAK,QAC5B;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,wCAAuC;AAAA,IAC/C,oBAAC,UAAK,GAAE,uMAAsM;AAAA,IAC9M,oBAAC,UAAK,GAAE,cAAa;AAAA,KACvB;AAAA,EACA;AACF;AAEO,IAAM,YAAY;AAAA,EACvB,qBAAC,OAAE,QAAO,gBAAe,MAAK,QAC5B;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,4DAA2D;AAAA,IACnE,oBAAC,UAAK,GAAE,2DAA0D;AAAA,IAClE,oBAAC,UAAK,GAAE,mCAAkC;AAAA,IAC1C,oBAAC,UAAK,GAAE,mCAAkC;AAAA,IAC1C,oBAAC,UAAK,GAAE,iCAAgC;AAAA,IACxC,oBAAC,UAAK,GAAE,oCAAmC;AAAA,KAC7C;AAAA,EACA;AACF;AAEO,IAAM,gBAAgB;AAAA,EAC3B,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,4DAA2D;AAAA,IACnE,oBAAC,UAAK,GAAE,2DAA0D;AAAA,IAClE,oBAAC,UAAK,GAAE,mCAAkC;AAAA,IAC1C,oBAAC,UAAK,GAAE,mCAAkC;AAAA,IAC1C,oBAAC,UAAK,GAAE,iCAAgC;AAAA,IACxC,oBAAC,UAAK,GAAE,oCAAmC;AAAA,KAC7C;AAAA,EACA;AACF;AAEO,IAAM,aAAa;AAAA,EACxB,qBAAC,OAAE,aAAa,KACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,8CAA6C;AAAA,IACrD,oBAAC,UAAK,GAAE,gBAAe;AAAA,KACzB;AAAA,EACA;AACF;AAEO,IAAM,YAAY;AAAA,EACvB,qBAAC,OAAE,aAAa,KACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,wCAAuC;AAAA,IAC/C,oBAAC,UAAK,GAAE,eAAc;AAAA,IACtB,oBAAC,UAAK,GAAE,sBAAqB;AAAA,KAC/B;AAAA,EACA;AACF;AAEO,IAAM,iBAAiB;AAAA,EAC5B,qBAAC,OAAE,aAAa,KACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,+EAA8E;AAAA,IACtF,oBAAC,UAAK,GAAE,wBAAuB;AAAA,IAC/B,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,cAAa;AAAA,KACvB;AAAA,EACA;AACF;AAEO,IAAM,sBAAsB;AAAA,EACjC,qBAAC,OAAE,aAAa,KACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,cAAa;AAAA,IACrB,oBAAC,UAAK,GAAE,2EAA0E;AAAA,IAClF,oBAAC,UAAK,GAAE,kEAAiE;AAAA,IACzE,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,cAAa;AAAA,KACvB;AAAA,EACA;AACF;AAEO,IAAM,WAAW;AAAA,EACtB,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,uCAAsC;AAAA,KAChD;AAAA,EACA;AACF;AACO,IAAM,gBAAgB;AAAA,EAC3B,qBAAC,OACC;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,gFAA+E;AAAA,IACvF,oBAAC,UAAK,GAAE,cAAa;AAAA,IACrB,oBAAC,UAAK,GAAE,cAAa;AAAA,IACrB,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,YAAW;AAAA,IACnB,oBAAC,UAAK,GAAE,YAAW;AAAA,IACnB,oBAAC,UAAK,GAAE,YAAW;AAAA,IACnB,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,cAAa;AAAA,IACrB,oBAAC,UAAK,GAAE,cAAa;AAAA,IACrB,oBAAC,UAAK,GAAE,cAAa;AAAA,KACvB;AAAA,EACA;AACF;AAEO,IAAM,aAAa;AAAA,EACxB,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,WAAU;AAAA,IAClB,oBAAC,UAAK,GAAE,cAAa;AAAA,IACrB,oBAAC,UAAK,GAAE,WAAU;AAAA,IAClB,oBAAC,UAAK,GAAE,YAAW;AAAA,IACnB,oBAAC,UAAK,GAAE,WAAU;AAAA,IAClB,oBAAC,UAAK,GAAE,YAAW;AAAA,IACnB,oBAAC,UAAK,GAAE,YAAW;AAAA,IACnB,oBAAC,UAAK,GAAE,WAAU;AAAA,IAClB,oBAAC,UAAK,GAAE,WAAU;AAAA,IAClB,oBAAC,UAAK,GAAE,UAAS;AAAA,IACjB,oBAAC,UAAK,GAAE,YAAW;AAAA,KACrB;AAAA,EACA;AACF;AAEO,IAAM,eAAe;AAAA,EAC1B,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,cAAa;AAAA,IACrB,oBAAC,UAAK,GAAE,yBAAwB;AAAA,IAChC,oBAAC,UAAK,GAAE,wBAAuB;AAAA,KACjC;AAAA,EACA;AACF;AAEO,IAAM,iBAAiB;AAAA,EAC5B,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,cAAa;AAAA,IACrB,oBAAC,UAAK,GAAE,yBAAwB;AAAA,IAChC,oBAAC,UAAK,GAAE,wBAAuB;AAAA,KACjC;AAAA,EACA;AACF;AAEO,IAAM,YAAY;AAAA,EACvB,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,kFAAiF;AAAA,IACzF,oBAAC,UAAK,GAAE,+CAA8C;AAAA,IACtD,oBAAC,UAAK,GAAE,kFAAiF;AAAA,KAC3F;AAAA,EACA;AACF;AAEO,IAAM,eAAe;AAAA,EAC1B,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,8CAA6C;AAAA,IACrD,oBAAC,UAAK,GAAE,gBAAe;AAAA,IACvB,oBAAC,UAAK,GAAE,+BAA8B;AAAA,IACtC,oBAAC,UAAK,GAAE,YAAW;AAAA,IACnB,oBAAC,UAAK,GAAE,4BAA2B;AAAA,IACnC,oBAAC,UAAK,GAAE,WAAU;AAAA,IAClB,oBAAC,UAAK,GAAE,2BAA0B;AAAA,KACpC;AAAA,EACA;AACF;AAEO,IAAM,UAAU;AAAA,EACrB,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,2BAA0B;AAAA,IAClC,oBAAC,UAAK,GAAE,mCAAkC;AAAA,IAC1C,oBAAC,UAAK,GAAE,2IAA0I;AAAA,IAClJ,oBAAC,UAAK,GAAE,mBAAkB;AAAA,IAC1B,oBAAC,UAAK,GAAE,iDAAgD;AAAA,KAC1D;AAAA,EACA;AACF;AAEO,IAAM,UAAU;AAAA,EACrB,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,2BAA0B;AAAA,IAClC,oBAAC,UAAK,GAAE,mCAAkC;AAAA,IAC1C,oBAAC,UAAK,GAAE,iDAAgD;AAAA,IACxD,oBAAC,UAAK,GAAE,uCAAsC;AAAA,IAC9C,oBAAC,UAAK,GAAE,oBAAmB;AAAA,KAC7B;AAAA,EACA;AACF;AAEO,IAAM,aAAa;AAAA,EACxB,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,+GAA8G;AAAA,IACtH,oBAAC,UAAK,GAAE,YAAW;AAAA,IACnB,oBAAC,UAAK,GAAE,aAAY;AAAA,KACtB;AAAA,EACA;AACF;AAEO,IAAM,aAAa;AAAA,EACxB,qBAAC,OAAE,aAAa,MACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,2HAA0H;AAAA,IAClI,oBAAC,UAAK,GAAE,6CAA4C;AAAA,IACpD,oBAAC,UAAK,GAAE,8CAA6C;AAAA,IACrD,oBAAC,UAAK,GAAE,oDAAmD;AAAA,IAC3D,oBAAC,UAAK,GAAE,wCAAuC;AAAA,KACjD;AAAA,EACA;AACF;AAEO,IAAM,oBAAoB;AAAA,EAC/B,qBAAC,OAAE,QAAO,gBACR;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,sGAAqG;AAAA,KAC/G;AAAA,EACA,EAAE,GAAG,iBAAiB,aAAa,IAAI;AACzC;AAGO,IAAM,YAAY;AAAA,EACvB,qBAAC,OAAE,aAAa,KACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,mFAAkF;AAAA,IAC1F,oBAAC,UAAK,GAAE,mBAAkB;AAAA,IAC1B,oBAAC,UAAK,GAAE,gBAAe;AAAA,KACzB;AAAA,EACA;AACF;AAEO,IAAM,cAAc;AAAA,EACzB,qBAAC,OACC;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,iFAAgF;AAAA,IACxF,oBAAC,UAAK,GAAE,mBAAkB;AAAA,KAC5B;AAAA,EACA;AACF;AAEO,IAAM,WAAW;AAAA,EACtB,qBAAC,OAAE,aAAa,KACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,WAAU;AAAA,IAClB,oBAAC,UAAK,GAAE,YAAW;AAAA,IACnB,oBAAC,UAAK,GAAE,YAAW;AAAA,IACnB,oBAAC,UAAK,GAAE,WAAU;AAAA,IAClB,oBAAC,UAAK,GAAE,YAAW;AAAA,IACnB,oBAAC,UAAK,GAAE,YAAW;AAAA,KACrB;AAAA,EACA;AACF;AAEO,IAAM,iBAAiB;AAAA,EAC5B,qBAAC,OAAE,aAAa,KACd;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,iFAAgF;AAAA,IACxF,oBAAC,UAAK,GAAE,iFAAgF;AAAA,IACxF,oBAAC,UAAK,GAAE,mCAAkC;AAAA,KAC5C;AAAA,EACA;AACF;AAGO,IAAM,iBAAiB;AAAA,EAC5B,qBAAC,OACC;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,gBAAe;AAAA,IACvB,oBAAC,UAAK,GAAE,gBAAe;AAAA,KACzB;AAAA,EACA;AACF;AAGO,IAAM,iBAAiB;AAAA,EAC5B,qBAAC,OACC;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,0EAAyE;AAAA,IACjF,oBAAC,UAAK,GAAE,kBAAiB;AAAA,KAC3B;AAAA,EACA;AACF;AAGO,IAAM,iBAAiB;AAAA,EAC5B,qBAAC,OACC;AAAA,wBAAC,UAAK,GAAE,oBAAmB;AAAA,IAC3B,oBAAC,UAAK,GAAE,qCAAoC;AAAA,KAC9C;AAAA,EACA;AACF;AAEO,IAAM,mBAAmB;AAAA,EAC9B,qBAAC,OACC;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,iBAAgB;AAAA,KAC1B;AAAA,EACA;AACF;AAEO,IAAM,iBAAiB;AAAA,EAC5B,qBAAC,OACC;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,kBAAiB;AAAA,KAC3B;AAAA,EACA;AACF;AAEO,IAAM,SAAS;AAAA,EACpB,qBAAC,OACC;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,kBAAiB;AAAA,KAC3B;AAAA,EACA;AACF;AAEO,IAAM,WAAW;AAAA,EACtB,qBAAC,OAAE,aAAY,QACb;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,4BAA2B;AAAA,IACnC,oBAAC,UAAK,GAAE,4BAA2B;AAAA,KACrC;AAAA,EACA;AACF;AAEO,IAAM,kBAAkB;AAAA,EAC7B,qBAAC,OACC;AAAA,wBAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,IAClD,oBAAC,UAAK,GAAE,0CAAyC;AAAA,IACjD,oBAAC,UAAK,GAAE,2CAA0C;AAAA,IAClD,oBAAC,UAAK,GAAE,2CAA0C;AAAA,IAClD,oBAAC,UAAK,GAAE,4CAA2C;AAAA,IACnD,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,aAAY;AAAA,IACpB,oBAAC,UAAK,GAAE,cAAa;AAAA,IACrB,oBAAC,UAAK,GAAE,cAAa;AAAA,KACvB;AAAA,EACA;AACF;;;ACxoEO,IAAM,gBAA8C;AAAA,EACzD,CAAC,YAAY,UAAU,GAAG;AAAA,IACxB,SAAS;AAAA,MACP,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAAA,IACA,MAAM;AAAA,EACR;AAAA,EACA,CAAC,YAAY,MAAM,GAAG;AAAA,IACpB,SAAS;AAAA,MACP,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAAA,IACA,MAAM;AAAA,EACR;AAAA,EACA,CAAC,YAAY,YAAY,CAAC,GAAG;AAAA,IAC3B,SAAS;AAAA,MACP,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAAA,IACA,MAAM;AAAA,EACR;AAAA,EACA,CAAC,YAAY,cAAc,CAAC,GAAG;AAAA,IAC7B,SAAS;AAAA,MACP,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAAA,IACA,MAAM;AAAA,EACR;AAAA,EACA,CAAC,YAAY,MAAM,GAAG;AAAA,IACpB,SAAS;AAAA,MACP,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAAA,IACA,MAAM;AAAA,IACN,YAAY;AAAA,EACd;AAAA,EACA,CAAC,YAAY,SAAS,GAAG;AAAA,IACvB,SAAS;AAAA,MACP,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAAA,IACA,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,OAAO;AAAA,EACT;AAAA,EACA,CAAC,YAAY,QAAQ,GAAG;AAAA,IACtB,SAAS;AAAA,MACP,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAAA,IACA,MAAM;AAAA,IACN,YAAY;AAAA,EACd;AAAA,EACA,CAAC,YAAY,iBAAiB,CAAC,GAAG;AAAA,IAChC,SAAS;AAAA,MACP,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAAA,IACA,YAAY;AAAA,EACd;AAAA,EACA,CAAC,sBAAsB,OAAO,GAAG;AAAA,IAC/B,SAAS;AAAA,MACP,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAAA,IACA,UAAU;AAAA,EACZ;AAAA,EACA,CAAC,sBAAsB,gBAAgB,CAAC,GAAG;AAAA,IACzC,SAAS;AAAA;AAAA,MAEP,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAAA,IACA,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AACF;AAGO,IAAM,sBAAsB;AAAA,EACjC,OACE;AAAA,EACF,WACE;AAAA,EACF,aACE;AAAA,EACF,SAAS;AAAA,EACT,YACE;AACJ;AAGO,IAAM,sBAAsB;;;ACnJ5B,IAAM,cAAN,cAA0B,MAAM;AAAA,EACrC,YACE,UAAkB,2BAClB,OAA2B,gBAC3B;AACA,UAAM;AACN,SAAK,OAAO;AACZ,SAAK,UAAU;AAAA,EACjB;AACF;AAEO,IAAM,aAAN,cAAyB,aAAa;AAAA,EAC3C,YAAY,UAAkB,mBAAmB;AAC/C,UAAM,SAAS,YAAY;AAAA,EAC7B;AACF;AAMO,IAAM,sBAAN,cAAkC,MAAM;AAAA,EAE7C,YACE,UAAU,0BACV,OAAgC,0BAChC;AACA,UAAM,OAAO;AALf,wBAAO;AAML,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,8BAAN,cAA0C,MAAM;AAAA,EAAhD;AAAA;AACL,wBAAO,QAAO;AAAA;AAChB;AAIO,IAAM,2BAAN,cAAuC,MAAM;AAAA,EAElD,YACE,UAAU,8BACV,OAAyB,0BACzB;AACA,UAAM,OAAO;AALf,wBAAO;AAML,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,4BAAN,cAAwC,MAAM;AAAA,EAEnD,YACE,UAAU,yCACV,OAAyB,4BACzB;AACA,UAAM,OAAO;AALf,wBAAO;AAML,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AACF;AAMO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EACzC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;;;ACvEA,IAAM,aAAN,MAAiB;AAAA,EAGf,YAAY,WAAgB;AAF5B,wBAAO;AASP;AAAA;AAAA;AAAA,wBAAO;AANL,SAAK,WAAW,IAAI,OAAO,WAAW,EAAE,MAAM,SAAS,CAAC;AAAA,EAC1D;AAMF;AAOO,IAAM,aAAN,MAAM,YAAiB;AAAA,EAKpB,YACN,WACA,SAGA;AATF,wBAAQ,eAA+B,oBAAI,IAAI;AAC/C,wBAAiB;AACjB,wBAAiB;AAQf,SAAK,YAAY;AAEjB,SAAK,YAAY,QAAQ,OAAO;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OAAc,OACZ,WACA,UAEI,CAAC,GACa;AAClB,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,yBAAyB;AAAA,IACrC;AAEA,QAAI,CAAC,YAAY,OAAO,UAAU,SAAS,MAAM,YAAY,KAAK;AAEhE,YAAM,IAAI,0BAA0B;AAAA,IACtC;AAEA,WAAO,IAAI,YAAW,WAAW,OAAO;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,YACX,MACA,SACY;AACZ,QAAI;AAEJ,UAAM,aAAa,MAAM,KAAK,KAAK,WAAW,EAAE,MAAM;AACtD,QAAI,YAAY;AACd,WAAK,YAAY,OAAO,UAAU;AAClC,eAAS;AAAA,IACX,OAAO;AACL,eAAS,MAAM,KAAK,aAAa;AAAA,IACnC;AAEA,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,aAAO,SAAS,YAAY,KAAK,iBAAiB,QAAQ,OAAO;AACjE,aAAO,SAAS,UAAU,KAAK,eAAe,QAAQ,MAAM;AAE5D,aAAO,SAAS,YAAY,MAAM,OAAO;AACzC,aAAO;AAAA,QAAkB,MACvB;AAAA,UACE,IAAI,MAAM,qCAAqC,KAAK,SAAS,KAAK;AAAA,QACpE;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,QAAQ;AACnB,eAAW,UAAU,KAAK,aAAa;AACrC,aAAO,kBAAkB,OAAO;AAChC,aAAO,SAAS,UAAU;AAAA,IAC5B;AAEA,SAAK,YAAY,MAAM;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eAAoC;AAChD,UAAM,SAAS,IAAI,WAAW,KAAK,SAAS;AAE5C,WAAO,oBAAoB,SAAS,CAAC,WAAwB;AAC3D,aAAO,SAAS,UAAU;AAE1B,UAAI,KAAK,YAAY,IAAI,MAAM,GAAG;AAChC,aAAK,YAAY,OAAO,MAAM;AAG9B,gBAAQ;AAAA,UACN;AAAA,QACF;AAAA,MACF,WAAW,QAAQ;AACjB,eAAO;AAAA,MACT,OAAO;AACL,gBAAQ,MAAM,6BAA6B;AAAA,MAC7C;AAAA,IACF,GAAG,KAAK,SAAS;AAEjB,WAAO;AAAA,EACT;AAAA,EAEQ,iBAAiB,QAAoB,SAA6B;AACxE,WAAO,CAAC,MAAmB;AACzB,aAAO,kBAAkB;AACzB,WAAK,YAAY,IAAI,MAAM;AAC3B,cAAQ,EAAE,IAAI;AAAA,IAChB;AAAA,EACF;AAAA,EAEQ,eACN,QACA,QACA;AACA,WAAO,CAAC,MAAkB;AAExB,aAAO,kBAAkB,MAAM,OAAO,CAAC,CAAC;AACxC,aAAO,kBAAkB,MAAM;AAG/B,WAAK,MAAM;AAAA,IACb;AAAA,EACF;AACF;;;AClJA,IAAI,mBAAmB,OAAO,WAAW;AAalC,IAAM,gCAAgC,OAC3C,aACA,eACoB;AACpB,QAAM,EAAE,UAAU,gBAAgB,SAAS,IACzC,MAAM,0BAA0B;AAElC,MAAI,CAAC,kBAAkB;AACrB,WAAO,eAAe,aAAa,UAAU;AAAA,EAC/C;AAEA,SAAO,WAAW,YAAY;AAC5B,QAAI;AACF,YAAMC,cAAa,MAAM,sBAAsB;AAG/C,YAAM,kBAAkB,YAAY,MAAM,CAAC;AAC3C,YAAM,SAAS,MAAMA,YAAW;AAAA,QAC9B;AAAA,UACE,SAAS,SAAS;AAAA,UAClB,aAAa;AAAA,UACb;AAAA,QACF;AAAA,QACA,EAAE,UAAU,CAAC,eAAe,EAAE;AAAA,MAChC;AAGA,aAAO,SAAS,MAAM;AAAA,IACxB,SAAS,GAAG;AAEV,yBAAmB;AAEnB;AAAA;AAAA,QAEE,EACE,YAAY,MACX,aAAa,4BACZ,aAAa;AAAA,QAEjB;AAEA,gBAAQ;AAAA,UACN;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAGA,aAAO,eAAe,aAAa,UAAU;AAAA,IAC/C;AAAA,EACF,CAAC;AACH;AAGA,IAAI,eAAuE;AAC3E,IAAI,eAAuE;AAE3E,IAAM,4BAA4B,YAAY;AAC5C,MAAI,CAAC,cAAc;AACjB,mBAAe,OAAO,0BAAuB;AAAA,EAC/C;AAEA,SAAO;AACT;AAEA,IAAM,4BAA4B,YAAY;AAC5C,MAAI,CAAC,cAAc;AAEjB,mBAAe,OAAO,0BAAuB;AAAA,EAC/C;AAEA,SAAO;AACT;AAYA,IAAI,aAEO;AAOX,IAAM,wBAAwB,MAAM;AAClC,MAAI,CAAC,YAAY;AAEf,iBAAa,WAAW,YAAY;AAClC,YAAM,EAAE,UAAU,IAAI,MAAM,0BAA0B;AAEtD,YAAM,OAAO,WAAW,OAGtB,SAAS;AAEX,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;AC1HO,IAAM,sBAAN,MAAM,oBAAmB;AAAA,EAU9B,YAAY,QAAgB,KAAa,aAAmC;AAT5E,wBAAgB;AAChB,wBAAgB;AASd,SAAK,OAAO,oBAAmB,WAAW,GAAG;AAE7C,UAAM,UAAU,KAAK,KAClB,IAAI,CAAC,QAAQ,OAAO,GAAG,KAAK,oBAAmB,UAAU,GAAG,CAAC,EAAE,EAC/D,KAAK,IAAI;AAEZ,SAAK,WAAW,IAAI,SAAS,QAAQ,SAAS;AAAA,MAC5C,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,MAAM,YAAiD;AAE5D,QAAI,CAAC,KAAK,qBAAqB,EAAE,KAAK,UAAU,GAAG;AACjD;AAAA,IACF;AAEA,UAAM,aAAa,MAAM,KAAK,UAAU,EAAE;AAAA,MACxC,CAAC,SAAS,KAAK,YAAY,CAAC;AAAA,IAC9B;AAEA,WAAO,KAAK,WAAW,UAAU,EAAE;AAAA,MACjC,CAAC,YACC,6BAA6B,KAAK,SAAS,MAAM,cAAc,OAAO;AAAA,IAC1E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAa,WAAW,YAA4C;AAClE,QAAI,IAAI;AACR,UAAM,gBAAgB,CAAC;AAEvB,WAAO,IAAI,KAAK,KAAK,QAAQ;AAC3B,YAAM,MAAM,KAAK,KAAK,CAAC;AAEvB,UAAI;AACF,cAAM,cAAc,MAAM,KAAK,UAAU,GAAG;AAC5C,cAAM,SAAS,MAAM;AAAA,UACnB;AAAA,UACA;AAAA,QACF;AAEA,eAAO;AAAA,MACT,SAAS,GAAG;AACV,sBAAc,KAAK,IAAI,IAAI,SAAS,CAAC,qBAAqB,CAAC,GAAG;AAAA,MAChE;AAEA;AAAA,IACF;AAEA,YAAQ;AAAA,MACN,gCAAgC,KAAK,SAAS,MAAM;AAAA,MACpD,KAAK,UAAU,eAAe,QAAW,CAAC;AAAA,IAC5C;AAIA,WAAO,KAAK,KAAK,SAAS,KAAK,KAAK,KAAK,KAAK,SAAS,CAAC,EAAE,SAAS,IAAI;AAAA,EACzE;AAAA,EAEO,UAAU,KAA0C;AACzD,WAAO,WAAW,YAAY;AAC5B,YAAM,WAAW,MAAM,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA,QAIhC,OAAO;AAAA,QACP,SAAS;AAAA,UACP,QAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,eAAe,MAAM,IAAI,SAAS,IAAI;AACxD,cAAM,IAAI;AAAA,UACR,oBAAoB,SAAS,MAAM,SAAS,UAAU;AAAA,QACxD;AAAA,MACF;AAEA,YAAM,cAAc,MAAM,SAAS,YAAY;AAC/C,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA,EAEQ,uBAAuB;AAI7B,UAAM,oBAAoB,KAAK,SAAS,aACrC,MAAM,MAAM,EACZ,IAAI,CAAC,UAAU;AACd,YAAM,CAACC,QAAO,GAAG,IAAI,MAAM,QAAQ,MAAM,EAAE,EAAE,MAAM,GAAG;AACtD,UAAI,KAAK;AACP,eAAO,OAAOA,MAAK,SAAS,GAAG;AAAA,MACjC;AAEA,aAAO,OAAOA,MAAK;AAAA,IACrB,CAAC,EACA,KAAK,EAAE;AAEV,WAAO,IAAI,OAAO,IAAI,iBAAiB,KAAK,GAAG;AAAA,EACjD;AAAA,EAEA,OAAe,WAAW,KAAgC;AACxD,QAAI,IAAI,WAAW,MAAM,GAAG;AAE1B,aAAO,CAAC,GAAG;AAAA,IACb;AAEA,QAAI,IAAI,WAAW,mBAAmB,GAAG;AAEvC,aAAO,CAAC;AAAA,IACV;AAEA,QAAI,IAAI,WAAW,MAAM,GAAG;AAE1B,aAAO,CAAC,IAAI,IAAI,GAAG,CAAC;AAAA,IACtB;AAGA,UAAM,WAAmB,IAAI,QAAQ,QAAQ,EAAE;AAC/C,UAAM,OAAc,CAAC;AAErB,QAAI,OAAO,OAAO,0BAA0B,UAAU;AACpD,YAAM,oBAAoB,KAAK;AAAA,QAC7B,OAAO;AAAA,MACT;AAEA,WAAK,KAAK,IAAI,IAAI,UAAU,iBAAiB,CAAC;AAAA,IAChD,WAAW,MAAM,QAAQ,OAAO,qBAAqB,GAAG;AACtD,aAAO,sBAAsB,QAAQ,CAAC,SAAS;AAC7C,cAAM,oBAAoB,KAAK,iBAAiB,IAAI;AACpD,aAAK,KAAK,IAAI,IAAI,UAAU,iBAAiB,CAAC;AAAA,MAChD,CAAC;AAAA,IACH;AAGA,SAAK,KAAK,IAAI,IAAI,UAAU,oBAAmB,mBAAmB,CAAC;AAEnE,WAAO;AAAA,EACT;AAAA,EAEA,OAAe,UAAU,KAAoB;AAC3C,QAAI,EAAE,eAAe,MAAM;AAEzB,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,QAAQ,IAAI,IAAI,GAAG,EAAE,SAAS,MAAM,GAAG;AAE7C,UAAI,MAAM,WAAW,GAAG;AACtB,eAAO;AAAA,MACT;AAEA,aAAO,WAAW,MAAM,IAAI,CAAC;AAAA,IAC/B,SAAS,OAAO;AACd,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,OAAe,iBAAiB,SAAiB;AAC/C,QAAI,SAAS;AAKb,QAAI,SAAS,KAAK,MAAM,GAAG;AACzB,eAAS,IAAI;AAAA,QACX,OAAO,QAAQ,WAAW,EAAE;AAAA,QAC5B,QAAQ,UAAU;AAAA,MACpB,EAAE,SAAS;AAAA,IACb;AAGA,aAAS,GAAG,OAAO,QAAQ,QAAQ,EAAE,CAAC;AAEtC,WAAO;AAAA,EACT;AACF;AAtME,cAJW,qBAIa,uBAAsB,kBAC5C,+BAAgB,gBACZ,GAAG,+BAAgB,aAAa,IAAI,+BAAgB,WAAW,KAC/D,wBACN;AARK,IAAM,qBAAN;;;;;;ACFA,IAAM,oBAAoD;AAAA,EAC/D;AAAA,IACE,KAAK;AAAA,EACP;AACF;;;;;;;;;;;;;;;AC6DO,IAAM,uBAAuD;AAAA,EAClE;AAAA,IACE,KAAK;AAAA,IACL,aAAa;AAAA,MACX,cACE;AAAA,IACJ;AAAA,EACF;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,aAAa;AAAA,MACX,cACE;AAAA,IACJ;AAAA,EACF;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,aAAa;AAAA,MACX,cACE;AAAA,IACJ;AAAA,EACF;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,aAAa,EAAE,cAAc,QAAQ;AAAA,EACvC;AACF;;;AC3FO,IAAM,iBAAiD;AAAA,EAC5D;AAAA,IACE,KAAK;AAAA,EACP;AACF;;;;;;;;;;;;;;;;;;;;;;;;ACiHO,IAAM,sBAAsD;AAAA,EACjE;AAAA,IACE,KAAK;AAAA,IACL,aAAa;AAAA,MACX,cACE;AAAA,IACJ;AAAA,EACF;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,aAAa;AAAA,MACX,cACE;AAAA,IACJ;AAAA,EACF;AAAA,EACA,EAAE,KAAK,6DAAI,aAAa,EAAE,cAAc,6BAA6B,EAAE;AAAA,EACvE;AAAA,IACE,KAAK;AAAA,IACL,aAAa;AAAA,MACX,cACE;AAAA,IACJ;AAAA,EACF;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,aAAa;AAAA,MACX,cACE;AAAA,IACJ;AAAA,EACF;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,aAAa;AAAA,MACX,cACE;AAAA,IACJ;AAAA,EACF;AAAA,EACA,EAAE,KAAK,6DAAI,aAAa,EAAE,cAAc,kBAAkB,EAAE;AAC9D;;;AC3JO,IAAM,qBAAqD;AAAA,EAChE;AAAA,IACE,KAAK;AAAA,EACP;AACF;;;;;;ACJO,IAAM,sBAAsD;AAAA,EACjE;AAAA,IACE,KAAK;AAAA,EACP;AACF;;;;;;;;;ACDO,IAAM,kBAAkD;AAAA,EAC7D;AAAA,IACE,KAAK;AAAA,IACL,aAAa,EAAE,cAAc,oBAAoB,UAAU;AAAA,EAC7D;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,aAAa,EAAE,cAAc,oBAAoB,MAAM;AAAA,EACzD;AACF;;;;;;;;;;;;;;;;;;ACNO,IAAM,kBAAkD;AAAA,EAC7D;AAAA,IACE,KAAK;AAAA,IACL,aAAa;AAAA,MACX,cAAc,oBAAoB;AAAA,MAClC,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,aAAa,EAAE,cAAc,oBAAoB,SAAS,QAAQ,MAAM;AAAA,EAC1E;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,aAAa;AAAA,MACX,cAAc,oBAAoB;AAAA,MAClC,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,aAAa,EAAE,cAAc,oBAAoB,WAAW,QAAQ,MAAM;AAAA,EAC5E;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,aAAa,EAAE,cAAc,oBAAoB,OAAO,QAAQ,MAAM;AAAA,EACxE;AACF;;;;;;ACjCO,IAAM,kBAAkD;AAAA,EAC7D;AAAA,IACE,KAAK;AAAA,EACP;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACyOO,IAAM,mBAAmD;AAAA,EAC9D;AAAA,IACE,KAAK;AAAA,IACL,aAAa;AAAA,MACX,cACE;AAAA,IACJ;AAAA,EACF;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,aAAa;AAAA,MACX,cACE;AAAA,IACJ;AAAA,EACF;AAAA,EACA,EAAE,KAAK,0DAAI,aAAa,EAAE,cAAc,0BAA0B,EAAE;AAAA,EACpE;AAAA,IACE,KAAK;AAAA,IACL,aAAa,EAAE,cAAc,sCAAsC;AAAA,EACrE;AAAA,EACA,EAAE,KAAK,0DAAI,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACxD,EAAE,KAAK,0DAAI,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACxD,EAAE,KAAK,0DAAI,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACxD,EAAE,KAAK,0DAAI,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACxD,EAAE,KAAK,0DAAI,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACxD,EAAE,KAAK,0DAAI,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACxD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,0BAA0B,EAAE;AAAA,EACrE,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAAc,EAAE;AAAA,EACzD,EAAE,KAAK,0DAAK,aAAa,EAAE,cAAc,cAA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",
6
+ "names": ["UserIdleState", "nanoid", "start", "line", "distance", "line", "solution", "t", "s", "polygon", "start", "newValues", "line", "line", "rough", "oc", "oc", "workerPool", "start", "fontFaces", "ellipse", "polygon", "curve", "line", "ellipse", "r", "top", "right", "bottom", "left", "sides", "line", "shape", "distance", "t", "distance", "crop", "shouldMaintainAspectRatio", "getSvgPathFromStroke", "arrowheadPoints", "options", "getCurvePathOps", "minX", "minY", "maxX", "maxY", "distance", "x3", "y3", "x4", "y4", "rough", "coords", "curve", "element", "isBindingEnabled", "start", "distance", "selectGroupsForSelectedElements", "round", "newElement", "distance", "getCurvePathOps", "newTextElement", "shouldMaintainAspectRatio", "index", "rough", "lowerBound", "upperBound", "i", "current", "newElement", "x1", "y1", "x2", "y2", "element", "opacity", "uncroppedWidth", "uncroppedHeight", "mimeTypes", "file", "startArrowhead", "endArrowhead", "x", "y", "points", "elements", "defaultAppState", "getNonDeletedElements", "throttle", "rough", "line", "hasHeader", "index", "file", "error", "isRTL", "exportToCanvas", "exportToSvg", "getNonDeletedElements", "line", "EPSILON", "element", "getNonDeletedElements", "start", "shouldRotateWithDiscreteAngle", "shouldResizeFromCenter", "shouldMaintainAspectRatio", "x1", "y1", "x2", "y2", "scaleX", "width", "height", "newElement", "shouldMaintainAspectRatio", "shouldResizeFromCenter", "getNonDeletedElements", "file", "nanoid", "chunk"]
7
+ }