tldraw 4.3.0-canary.ef37ae623ce8 → 4.3.0-canary.ef709265bb13

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 (114) hide show
  1. package/dist-cjs/index.d.ts +3 -0
  2. package/dist-cjs/index.js +2 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/canvas/TldrawSelectionForeground.js +2 -2
  5. package/dist-cjs/lib/canvas/TldrawSelectionForeground.js.map +2 -2
  6. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +5 -10
  7. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  8. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +3 -3
  9. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  10. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +1 -1
  11. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  12. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +3 -4
  13. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  14. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +1 -1
  15. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  16. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +4 -5
  17. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  18. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +2 -1
  19. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js.map +2 -2
  20. package/dist-cjs/lib/shapes/shared/ShapeFill.js +2 -2
  21. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  22. package/dist-cjs/lib/shapes/shared/{useForceSolid.js → useEfficientZoomThreshold.js} +10 -7
  23. package/dist-cjs/lib/shapes/shared/useEfficientZoomThreshold.js.map +7 -0
  24. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +1 -1
  25. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
  26. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +1 -1
  27. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +2 -2
  28. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.js +3 -9
  29. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.js.map +2 -2
  30. package/dist-cjs/lib/ui/components/ZoomMenu/DefaultZoomMenu.js +1 -1
  31. package/dist-cjs/lib/ui/components/ZoomMenu/DefaultZoomMenu.js.map +2 -2
  32. package/dist-cjs/lib/ui/components/menu-items.js +3 -1
  33. package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
  34. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +1 -1
  35. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  36. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +143 -88
  37. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  38. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +1 -1
  39. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  40. package/dist-cjs/lib/ui/version.js +3 -3
  41. package/dist-cjs/lib/ui/version.js.map +1 -1
  42. package/dist-cjs/lib/utils/text/richText.js +7 -17
  43. package/dist-cjs/lib/utils/text/richText.js.map +3 -3
  44. package/dist-esm/index.d.mts +3 -0
  45. package/dist-esm/index.mjs +3 -1
  46. package/dist-esm/index.mjs.map +2 -2
  47. package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs +2 -2
  48. package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs.map +2 -2
  49. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +6 -12
  50. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  51. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +3 -3
  52. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  53. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +1 -1
  54. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  55. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +3 -4
  56. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  57. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +1 -1
  58. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  59. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +4 -5
  60. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  61. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs +3 -2
  62. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs.map +2 -2
  63. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +2 -2
  64. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  65. package/dist-esm/lib/shapes/shared/useEfficientZoomThreshold.mjs +12 -0
  66. package/dist-esm/lib/shapes/shared/useEfficientZoomThreshold.mjs.map +7 -0
  67. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +1 -1
  68. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
  69. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +1 -1
  70. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +2 -2
  71. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.mjs +2 -8
  72. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.mjs.map +2 -2
  73. package/dist-esm/lib/ui/components/ZoomMenu/DefaultZoomMenu.mjs +1 -1
  74. package/dist-esm/lib/ui/components/ZoomMenu/DefaultZoomMenu.mjs.map +2 -2
  75. package/dist-esm/lib/ui/components/menu-items.mjs +3 -1
  76. package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
  77. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +2 -2
  78. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  79. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +151 -90
  80. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  81. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +2 -2
  82. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  83. package/dist-esm/lib/ui/version.mjs +3 -3
  84. package/dist-esm/lib/ui/version.mjs.map +1 -1
  85. package/dist-esm/lib/utils/text/richText.mjs +3 -3
  86. package/dist-esm/lib/utils/text/richText.mjs.map +2 -2
  87. package/package.json +3 -3
  88. package/src/index.ts +1 -0
  89. package/src/lib/canvas/TldrawSelectionForeground.tsx +2 -2
  90. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +6 -11
  91. package/src/lib/shapes/draw/DrawShapeUtil.tsx +3 -3
  92. package/src/lib/shapes/frame/FrameShapeUtil.tsx +1 -1
  93. package/src/lib/shapes/geo/GeoShapeUtil.tsx +3 -4
  94. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +1 -1
  95. package/src/lib/shapes/note/NoteShapeUtil.tsx +6 -8
  96. package/src/lib/shapes/shared/HyperlinkButton.tsx +3 -2
  97. package/src/lib/shapes/shared/ShapeFill.tsx +2 -2
  98. package/src/lib/shapes/shared/useEfficientZoomThreshold.ts +10 -0
  99. package/src/lib/shapes/shared/useImageOrVideoAsset.ts +1 -1
  100. package/src/lib/shapes/video/VideoShapeUtil.tsx +2 -1
  101. package/src/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.tsx +1 -9
  102. package/src/lib/ui/components/ZoomMenu/DefaultZoomMenu.tsx +1 -1
  103. package/src/lib/ui/components/menu-items.tsx +3 -1
  104. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +2 -2
  105. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +196 -108
  106. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +2 -2
  107. package/src/lib/ui/version.ts +3 -3
  108. package/src/lib/utils/text/richText.ts +3 -3
  109. package/src/test/commands/cameraState.test.ts +299 -0
  110. package/src/test/commands/putContent.test.ts +79 -1
  111. package/dist-cjs/lib/shapes/shared/useForceSolid.js.map +0 -7
  112. package/dist-esm/lib/shapes/shared/useForceSolid.mjs +0 -9
  113. package/dist-esm/lib/shapes/shared/useForceSolid.mjs.map +0 -7
  114. package/src/lib/shapes/shared/useForceSolid.ts +0 -6
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/arrow/ArrowShapeUtil.tsx"],
4
- "sourcesContent": ["import {\n\tArc2d,\n\tBox,\n\tEMPTY_ARRAY,\n\tEdge2d,\n\tEditor,\n\tGeometry2d,\n\tGroup2d,\n\tIndexKey,\n\tPI2,\n\tPolyline2d,\n\tRectangle2d,\n\tSVGContainer,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLArrowBinding,\n\tTLArrowBindingProps,\n\tTLArrowShape,\n\tTLArrowShapeProps,\n\tTLHandle,\n\tTLHandleDragInfo,\n\tTLResizeInfo,\n\tTLShapePartial,\n\tTLShapeUtilCanBeLaidOutOpts,\n\tTLShapeUtilCanBindOpts,\n\tTLShapeUtilCanvasSvgDef,\n\tVec,\n\tWeakCache,\n\tarrowShapeMigrations,\n\tarrowShapeProps,\n\tclamp,\n\tdebugFlags,\n\texhaustiveSwitchError,\n\tgetColorValue,\n\tgetDefaultColorTheme,\n\tgetFontsFromRichText,\n\tinvLerp,\n\tlerp,\n\tmapObjectMapValues,\n\tmaybeSnapToGrid,\n\tstructuredClone,\n\ttoDomPrecision,\n\ttoRichText,\n\ttrack,\n\tuseEditor,\n\tuseIsEditing,\n\tuseSharedSafeId,\n\tuseValue,\n} from '@tldraw/editor'\nimport React, { useMemo } from 'react'\nimport { updateArrowTerminal } from '../../bindings/arrow/ArrowBindingUtil'\nimport { isEmptyRichText, renderPlaintextFromRichText } from '../../utils/text/richText'\nimport { PathBuilder } from '../shared/PathBuilder'\nimport { RichTextLabel, RichTextSVG } from '../shared/RichTextLabel'\nimport { ShapeFill } from '../shared/ShapeFill'\nimport { ARROW_LABEL_PADDING, STROKE_SIZES, TEXT_PROPS } from '../shared/default-shape-constants'\nimport { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport { getArrowBodyPath, getArrowHandlePath } from './ArrowPath'\nimport { ArrowShapeOptions } from './arrow-types'\nimport {\n\tgetArrowLabelDefaultPosition,\n\tgetArrowLabelFontSize,\n\tgetArrowLabelPosition,\n} from './arrowLabel'\nimport { updateArrowTargetState } from './arrowTargetState'\nimport { getArrowheadPathForType } from './arrowheads'\nimport { ElbowArrowDebug } from './elbow/ElbowArrowDebug'\nimport { ElbowArrowAxes } from './elbow/definitions'\nimport { getElbowArrowSnapLines, perpDistanceToLineAngle } from './elbow/elbowArrowSnapLines'\nimport {\n\tTLArrowBindings,\n\tcreateOrUpdateArrowBinding,\n\tgetArrowBindings,\n\tgetArrowInfo,\n\tgetArrowTerminalsInArrowSpace,\n\tremoveArrowBinding,\n} from './shared'\n\nenum ArrowHandles {\n\tStart = 'start',\n\tMiddle = 'middle',\n\tEnd = 'end',\n}\n\n/** @public */\nexport class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {\n\tstatic override type = 'arrow' as const\n\tstatic override props = arrowShapeProps\n\tstatic override migrations = arrowShapeMigrations\n\n\toverride options: ArrowShapeOptions = {\n\t\texpandElbowLegLength: {\n\t\t\ts: 28,\n\t\t\tm: 36,\n\t\t\tl: 44,\n\t\t\txl: 66,\n\t\t},\n\t\tminElbowLegLength: {\n\t\t\ts: STROKE_SIZES.s * 3,\n\t\t\tm: STROKE_SIZES.m * 3,\n\t\t\tl: STROKE_SIZES.l * 3,\n\t\t\txl: STROKE_SIZES.xl * 3,\n\t\t},\n\t\tminElbowHandleDistance: 16,\n\n\t\tarcArrowCenterSnapDistance: 16,\n\t\telbowArrowCenterSnapDistance: 24,\n\t\telbowArrowEdgeSnapDistance: 20,\n\t\telbowArrowPointSnapDistance: 24,\n\t\telbowArrowAxisSnapDistance: 16,\n\n\t\tlabelCenterSnapDistance: 10,\n\n\t\telbowMidpointSnapDistance: 10,\n\t\telbowMinSegmentLengthToShowMidpointHandle: 20,\n\n\t\thoverPreciseTimeout: 600,\n\t\tpointingPreciseTimeout: 320,\n\n\t\tshouldBeExact: (editor: Editor) => editor.inputs.altKey,\n\t\tshouldIgnoreTargets: (editor: Editor) => editor.inputs.ctrlKey,\n\t}\n\n\toverride canEdit() {\n\t\treturn true\n\t}\n\toverride canBind({ toShapeType }: TLShapeUtilCanBindOpts<TLArrowShape>): boolean {\n\t\t// bindings can go from arrows to shapes, but not from shapes to arrows\n\t\treturn toShapeType !== 'arrow'\n\t}\n\toverride canSnap() {\n\t\treturn false\n\t}\n\toverride hideResizeHandles() {\n\t\treturn true\n\t}\n\toverride hideRotateHandle() {\n\t\treturn true\n\t}\n\toverride hideSelectionBoundsBg() {\n\t\treturn true\n\t}\n\toverride hideSelectionBoundsFg() {\n\t\treturn true\n\t}\n\toverride hideInMinimap() {\n\t\treturn true\n\t}\n\n\toverride canBeLaidOut(shape: TLArrowShape, info: TLShapeUtilCanBeLaidOutOpts) {\n\t\tif (info.type === 'flip') {\n\t\t\t// If we don't have this then the flip will be non-idempotent; that is, the flip will be multipotent, varipotent, or perhaps even omni-potent... and we can't have that\n\t\t\tconst bindings = getArrowBindings(this.editor, shape)\n\t\t\tconst { start, end } = bindings\n\t\t\tconst { shapes = [] } = info\n\t\t\tif (start && !shapes.find((s) => s.id === start.toId)) return false\n\t\t\tif (end && !shapes.find((s) => s.id === end.toId)) return false\n\t\t}\n\t\treturn true\n\t}\n\n\toverride getFontFaces(shape: TLArrowShape) {\n\t\tif (isEmptyRichText(shape.props.richText)) return EMPTY_ARRAY\n\n\t\treturn getFontsFromRichText(this.editor, shape.props.richText, {\n\t\t\tfamily: `tldraw_${shape.props.font}`,\n\t\t\tweight: 'normal',\n\t\t\tstyle: 'normal',\n\t\t})\n\t}\n\n\toverride getDefaultProps(): TLArrowShape['props'] {\n\t\treturn {\n\t\t\tkind: 'arc',\n\t\t\telbowMidPoint: 0.5,\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tfill: 'none',\n\t\t\tcolor: 'black',\n\t\t\tlabelColor: 'black',\n\t\t\tbend: 0,\n\t\t\tstart: { x: 0, y: 0 },\n\t\t\tend: { x: 2, y: 0 },\n\t\t\tarrowheadStart: 'none',\n\t\t\tarrowheadEnd: 'arrow',\n\t\t\trichText: toRichText(''),\n\t\t\tlabelPosition: 0.5,\n\t\t\tfont: 'draw',\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLArrowShape) {\n\t\tconst isEditing = this.editor.getEditingShapeId() === shape.id\n\t\tconst info = getArrowInfo(this.editor, shape)!\n\n\t\tconst debugGeom: Geometry2d[] = []\n\n\t\tconst bodyGeom =\n\t\t\tinfo.type === 'straight'\n\t\t\t\t? new Edge2d({\n\t\t\t\t\t\tstart: Vec.From(info.start.point),\n\t\t\t\t\t\tend: Vec.From(info.end.point),\n\t\t\t\t\t})\n\t\t\t\t: info.type === 'arc'\n\t\t\t\t\t? new Arc2d({\n\t\t\t\t\t\t\tcenter: Vec.Cast(info.handleArc.center),\n\t\t\t\t\t\t\tstart: Vec.Cast(info.start.point),\n\t\t\t\t\t\t\tend: Vec.Cast(info.end.point),\n\t\t\t\t\t\t\tsweepFlag: info.bodyArc.sweepFlag,\n\t\t\t\t\t\t\tlargeArcFlag: info.bodyArc.largeArcFlag,\n\t\t\t\t\t\t})\n\t\t\t\t\t: new Polyline2d({ points: info.route.points })\n\n\t\tlet labelGeom\n\t\tif (isEditing || !isEmptyRichText(shape.props.richText)) {\n\t\t\tconst labelPosition = getArrowLabelPosition(this.editor, shape)\n\t\t\tif (debugFlags.debugGeometry.get()) {\n\t\t\t\tdebugGeom.push(...labelPosition.debugGeom)\n\t\t\t}\n\t\t\tlabelGeom = new Rectangle2d({\n\t\t\t\tx: labelPosition.box.x,\n\t\t\t\ty: labelPosition.box.y,\n\t\t\t\twidth: labelPosition.box.w,\n\t\t\t\theight: labelPosition.box.h,\n\t\t\t\tisFilled: true,\n\t\t\t\tisLabel: true,\n\t\t\t})\n\t\t}\n\n\t\treturn new Group2d({\n\t\t\tchildren: [...(labelGeom ? [bodyGeom, labelGeom] : [bodyGeom]), ...debugGeom],\n\t\t})\n\t}\n\n\toverride getHandles(shape: TLArrowShape): TLHandle[] {\n\t\tconst info = getArrowInfo(this.editor, shape)!\n\n\t\tconst handles: TLHandle[] = [\n\t\t\t{\n\t\t\t\tid: ArrowHandles.Start,\n\t\t\t\ttype: 'vertex',\n\t\t\t\tindex: 'a1' as IndexKey,\n\t\t\t\tx: info.start.handle.x,\n\t\t\t\ty: info.start.handle.y,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: ArrowHandles.End,\n\t\t\t\ttype: 'vertex',\n\t\t\t\tindex: 'a3' as IndexKey,\n\t\t\t\tx: info.end.handle.x,\n\t\t\t\ty: info.end.handle.y,\n\t\t\t},\n\t\t]\n\n\t\tif (shape.props.kind === 'arc' && (info.type === 'straight' || info.type === 'arc')) {\n\t\t\thandles.push({\n\t\t\t\tid: ArrowHandles.Middle,\n\t\t\t\ttype: 'virtual',\n\t\t\t\tindex: 'a2' as IndexKey,\n\t\t\t\tx: info.middle.x,\n\t\t\t\ty: info.middle.y,\n\t\t\t})\n\t\t}\n\n\t\tif (shape.props.kind === 'elbow' && info.type === 'elbow' && info.route.midpointHandle) {\n\t\t\tconst shapePageTransform = this.editor.getShapePageTransform(shape.id)!\n\n\t\t\tconst segmentStart = shapePageTransform.applyToPoint(info.route.midpointHandle.segmentStart)\n\t\t\tconst segmentEnd = shapePageTransform.applyToPoint(info.route.midpointHandle.segmentEnd)\n\t\t\tconst segmentLength = Vec.Dist(segmentStart, segmentEnd) * this.editor.getZoomLevel()\n\n\t\t\tif (segmentLength > this.options.elbowMinSegmentLengthToShowMidpointHandle) {\n\t\t\t\thandles.push({\n\t\t\t\t\tid: ArrowHandles.Middle,\n\t\t\t\t\ttype: 'vertex',\n\t\t\t\t\tindex: 'a2' as IndexKey,\n\t\t\t\t\tx: info.route.midpointHandle.point.x,\n\t\t\t\t\ty: info.route.midpointHandle.point.y,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\treturn handles\n\t}\n\n\toverride getText(shape: TLArrowShape) {\n\t\treturn renderPlaintextFromRichText(this.editor, shape.props.richText)\n\t}\n\n\toverride onHandleDrag(shape: TLArrowShape, info: TLHandleDragInfo<TLArrowShape>) {\n\t\tconst handleId = info.handle.id as ArrowHandles\n\t\tswitch (handleId) {\n\t\t\tcase ArrowHandles.Middle:\n\t\t\t\tswitch (shape.props.kind) {\n\t\t\t\t\tcase 'arc':\n\t\t\t\t\t\treturn this.onArcMidpointHandleDrag(shape, info)\n\t\t\t\t\tcase 'elbow':\n\t\t\t\t\t\treturn this.onElbowMidpointHandleDrag(shape, info)\n\t\t\t\t\tdefault:\n\t\t\t\t\t\texhaustiveSwitchError(shape.props.kind)\n\t\t\t\t}\n\t\t\tcase ArrowHandles.Start:\n\t\t\tcase ArrowHandles.End:\n\t\t\t\treturn this.onTerminalHandleDrag(shape, info, handleId)\n\t\t\tdefault:\n\t\t\t\texhaustiveSwitchError(handleId)\n\t\t}\n\t}\n\n\tprivate onArcMidpointHandleDrag(shape: TLArrowShape, { handle }: TLHandleDragInfo<TLArrowShape>) {\n\t\tconst bindings = getArrowBindings(this.editor, shape)\n\n\t\t// Bending the arrow...\n\t\tconst { start, end } = getArrowTerminalsInArrowSpace(this.editor, shape, bindings)\n\n\t\tconst delta = Vec.Sub(end, start)\n\t\tconst v = Vec.Per(delta)\n\n\t\tconst med = Vec.Med(end, start)\n\t\tconst A = Vec.Sub(med, v)\n\t\tconst B = Vec.Add(med, v)\n\n\t\tconst point = Vec.NearestPointOnLineSegment(A, B, handle, false)\n\t\tlet bend = Vec.Dist(point, med)\n\t\tif (Vec.Clockwise(point, end, med)) bend *= -1\n\t\treturn { id: shape.id, type: shape.type, props: { bend } }\n\t}\n\n\tprivate onElbowMidpointHandleDrag(\n\t\tshape: TLArrowShape,\n\t\t{ handle }: TLHandleDragInfo<TLArrowShape>\n\t) {\n\t\tconst info = getArrowInfo(this.editor, shape)\n\t\tif (info?.type !== 'elbow') return\n\n\t\tconst shapeToPageTransform = this.editor.getShapePageTransform(shape.id)!\n\t\tconst handlePagePoint = shapeToPageTransform.applyToPoint(handle)\n\t\tconst axisName = info.route.midpointHandle?.axis\n\t\tif (!axisName) return\n\t\tconst axis = ElbowArrowAxes[axisName]\n\n\t\tconst midRange = info.elbow[axis.midRange]\n\t\tif (!midRange) return\n\n\t\t// We're snapping against a list of parallel lines. The way we do this is to calculate the\n\t\t// angle of the line we're snapping to...\n\t\tlet angle = Vec.Angle(\n\t\t\tshapeToPageTransform.applyToPoint(axis.v(0, 0)),\n\t\t\tshapeToPageTransform.applyToPoint(axis.v(0, 1))\n\t\t)\n\t\tif (angle < 0) angle += Math.PI\n\n\t\t// ...then calculate the perpendicular distance from the origin to the (infinite) line in\n\t\t// question. This returns a signed distance - lines \"behind\" the origin are negative.\n\t\tconst handlePoint = perpDistanceToLineAngle(handlePagePoint, angle)\n\n\t\t// As we're only ever moving along one dimension, we can use this perpendicular distance for\n\t\t// all of our snapping calculations.\n\t\tconst loPoint = perpDistanceToLineAngle(\n\t\t\tshapeToPageTransform.applyToPoint(axis.v(midRange.lo, 0)),\n\t\t\tangle\n\t\t)\n\t\tconst hiPoint = perpDistanceToLineAngle(\n\t\t\tshapeToPageTransform.applyToPoint(axis.v(midRange.hi, 0)),\n\t\t\tangle\n\t\t)\n\n\t\t// we want to snap to certain points. the maximum distance at which a snap will occur is\n\t\t// relative to the zoom level:\n\t\tconst maxSnapDistance = this.options.elbowMidpointSnapDistance / this.editor.getZoomLevel()\n\n\t\t// we snap to the midpoint of the range by default\n\t\tconst midPoint = perpDistanceToLineAngle(\n\t\t\tshapeToPageTransform.applyToPoint(axis.v(lerp(midRange.lo, midRange.hi, 0.5), 0)),\n\t\t\tangle\n\t\t)\n\n\t\tlet snapPoint = midPoint\n\t\tlet snapDistance = Math.abs(midPoint - handlePoint)\n\n\t\t// then we check all the other arrows that are on-screen.\n\t\tfor (const [snapAngle, snapLines] of getElbowArrowSnapLines(this.editor)) {\n\t\t\tconst { isParallel, isFlippedParallel } = anglesAreApproximatelyParallel(angle, snapAngle)\n\t\t\tif (isParallel || isFlippedParallel) {\n\t\t\t\tfor (const snapLine of snapLines) {\n\t\t\t\t\tconst doesShareStartIntersection =\n\t\t\t\t\t\tsnapLine.startBoundShapeId &&\n\t\t\t\t\t\t(snapLine.startBoundShapeId === info.bindings.start?.toId ||\n\t\t\t\t\t\t\tsnapLine.startBoundShapeId === info.bindings.end?.toId)\n\n\t\t\t\t\tconst doesShareEndIntersection =\n\t\t\t\t\t\tsnapLine.endBoundShapeId &&\n\t\t\t\t\t\t(snapLine.endBoundShapeId === info.bindings.start?.toId ||\n\t\t\t\t\t\t\tsnapLine.endBoundShapeId === info.bindings.end?.toId)\n\n\t\t\t\t\tif (!doesShareStartIntersection && !doesShareEndIntersection) continue\n\n\t\t\t\t\tconst point = isFlippedParallel ? -snapLine.perpDistance : snapLine.perpDistance\n\t\t\t\t\tconst distance = Math.abs(point - handlePoint)\n\t\t\t\t\tif (distance < snapDistance) {\n\t\t\t\t\t\tsnapPoint = point\n\t\t\t\t\t\tsnapDistance = distance\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (snapDistance > maxSnapDistance) {\n\t\t\tsnapPoint = handlePoint\n\t\t}\n\n\t\tconst newMid = clamp(invLerp(loPoint, hiPoint, snapPoint), 0, 1)\n\n\t\treturn {\n\t\t\tid: shape.id,\n\t\t\ttype: shape.type,\n\t\t\tprops: {\n\t\t\t\telbowMidPoint: newMid,\n\t\t\t},\n\t\t}\n\t}\n\n\tprivate onTerminalHandleDrag(\n\t\tshape: TLArrowShape,\n\t\t{ handle, isPrecise }: TLHandleDragInfo<TLArrowShape>,\n\t\thandleId: ArrowHandles.Start | ArrowHandles.End\n\t) {\n\t\tconst bindings = getArrowBindings(this.editor, shape)\n\n\t\tconst update: TLShapePartial<TLArrowShape> = { id: shape.id, type: 'arrow', props: {} }\n\n\t\tconst currentBinding = bindings[handleId]\n\n\t\tconst oppositeHandleId = handleId === ArrowHandles.Start ? ArrowHandles.End : ArrowHandles.Start\n\t\tconst oppositeBinding = bindings[oppositeHandleId]\n\n\t\tconst targetInfo = updateArrowTargetState({\n\t\t\teditor: this.editor,\n\t\t\tpointInPageSpace: this.editor.getShapePageTransform(shape.id)!.applyToPoint(handle),\n\t\t\tarrow: shape,\n\t\t\tisPrecise: isPrecise,\n\t\t\tcurrentBinding,\n\t\t\toppositeBinding,\n\t\t})\n\n\t\tif (!targetInfo) {\n\t\t\t// todo: maybe double check that this isn't equal to the other handle too?\n\t\t\tremoveArrowBinding(this.editor, shape, handleId)\n\t\t\tconst newPoint = maybeSnapToGrid(new Vec(handle.x, handle.y), this.editor)\n\t\t\tupdate.props![handleId] = {\n\t\t\t\tx: newPoint.x,\n\t\t\t\ty: newPoint.y,\n\t\t\t}\n\t\t\treturn update\n\t\t}\n\n\t\t// we've got a target! the handle is being dragged over a shape, bind to it\n\t\tconst bindingProps: TLArrowBindingProps = {\n\t\t\tterminal: handleId,\n\t\t\tnormalizedAnchor: targetInfo.normalizedAnchor,\n\t\t\tisPrecise: targetInfo.isPrecise,\n\t\t\tisExact: targetInfo.isExact,\n\t\t\tsnap: targetInfo.snap,\n\t\t}\n\n\t\tcreateOrUpdateArrowBinding(this.editor, shape, targetInfo.target.id, bindingProps)\n\n\t\tconst newBindings = getArrowBindings(this.editor, shape)\n\t\tif (newBindings.start && newBindings.end && newBindings.start.toId === newBindings.end.toId) {\n\t\t\tif (\n\t\t\t\tVec.Equals(newBindings.start.props.normalizedAnchor, newBindings.end.props.normalizedAnchor)\n\t\t\t) {\n\t\t\t\tcreateOrUpdateArrowBinding(this.editor, shape, newBindings.end.toId, {\n\t\t\t\t\t...newBindings.end.props,\n\t\t\t\t\tnormalizedAnchor: {\n\t\t\t\t\t\tx: newBindings.end.props.normalizedAnchor.x + 0.05,\n\t\t\t\t\t\ty: newBindings.end.props.normalizedAnchor.y,\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\treturn update\n\t}\n\n\toverride onTranslateStart(shape: TLArrowShape) {\n\t\tconst bindings = getArrowBindings(this.editor, shape)\n\n\t\t// ...if the user is dragging ONLY this arrow, for elbow shapes, we can't maintain the bindings well just yet so we remove them entirely\n\t\tif (shape.props.kind === 'elbow' && this.editor.getOnlySelectedShapeId() === shape.id) {\n\t\t\tconst info = getArrowInfo(this.editor, shape)\n\t\t\tif (!info) return\n\t\t\tconst update: TLShapePartial<TLArrowShape> = { id: shape.id, type: 'arrow', props: {} }\n\t\t\tif (bindings.start) {\n\t\t\t\tupdate.props!.start = { x: info.start.point.x, y: info.start.point.y }\n\t\t\t\tremoveArrowBinding(this.editor, shape, 'start')\n\t\t\t}\n\t\t\tif (bindings.end) {\n\t\t\t\tupdate.props!.end = { x: info.end.point.x, y: info.end.point.y }\n\t\t\t\tremoveArrowBinding(this.editor, shape, 'end')\n\t\t\t}\n\t\t\treturn update\n\t\t}\n\n\t\tconst terminalsInArrowSpace = getArrowTerminalsInArrowSpace(this.editor, shape, bindings)\n\t\tconst shapePageTransform = this.editor.getShapePageTransform(shape.id)!\n\n\t\t// If at least one bound shape is in the selection, do nothing;\n\t\t// If no bound shapes are in the selection, unbind any bound shapes\n\n\t\tconst selectedShapeIds = this.editor.getSelectedShapeIds()\n\n\t\tif (\n\t\t\t(bindings.start &&\n\t\t\t\t(selectedShapeIds.includes(bindings.start.toId) ||\n\t\t\t\t\tthis.editor.isAncestorSelected(bindings.start.toId))) ||\n\t\t\t(bindings.end &&\n\t\t\t\t(selectedShapeIds.includes(bindings.end.toId) ||\n\t\t\t\t\tthis.editor.isAncestorSelected(bindings.end.toId)))\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\t// When we start translating shapes, record where their bindings were in page space so we\n\t\t// can maintain them as we translate the arrow\n\t\tshapeAtTranslationStart.set(shape, {\n\t\t\tpagePosition: shapePageTransform.applyToPoint(shape),\n\t\t\tterminalBindings: mapObjectMapValues(terminalsInArrowSpace, (terminalName, point) => {\n\t\t\t\tconst binding = bindings[terminalName]\n\t\t\t\tif (!binding) return null\n\t\t\t\treturn {\n\t\t\t\t\tbinding,\n\t\t\t\t\tshapePosition: point,\n\t\t\t\t\tpagePosition: shapePageTransform.applyToPoint(point),\n\t\t\t\t}\n\t\t\t}),\n\t\t})\n\n\t\t// update arrow terminal bindings eagerly to make sure the arrows unbind nicely when translating\n\t\tif (bindings.start) {\n\t\t\tupdateArrowTerminal({\n\t\t\t\teditor: this.editor,\n\t\t\t\tarrow: shape,\n\t\t\t\tterminal: 'start',\n\t\t\t\tuseHandle: true,\n\t\t\t})\n\t\t\tshape = this.editor.getShape(shape.id) as TLArrowShape\n\t\t}\n\t\tif (bindings.end) {\n\t\t\tupdateArrowTerminal({\n\t\t\t\teditor: this.editor,\n\t\t\t\tarrow: shape,\n\t\t\t\tterminal: 'end',\n\t\t\t\tuseHandle: true,\n\t\t\t})\n\t\t}\n\n\t\tfor (const handleName of [ArrowHandles.Start, ArrowHandles.End] as const) {\n\t\t\tconst binding = bindings[handleName]\n\t\t\tif (!binding) continue\n\n\t\t\tthis.editor.updateBinding({\n\t\t\t\t...binding,\n\t\t\t\tprops: { ...binding.props, isPrecise: true },\n\t\t\t})\n\t\t}\n\n\t\treturn\n\t}\n\n\toverride onTranslate(initialShape: TLArrowShape, shape: TLArrowShape) {\n\t\tconst atTranslationStart = shapeAtTranslationStart.get(initialShape)\n\t\tif (!atTranslationStart) return\n\n\t\tconst shapePageTransform = this.editor.getShapePageTransform(shape.id)!\n\t\tconst pageDelta = Vec.Sub(\n\t\t\tshapePageTransform.applyToPoint(shape),\n\t\t\tatTranslationStart.pagePosition\n\t\t)\n\n\t\tfor (const terminalBinding of Object.values(atTranslationStart.terminalBindings)) {\n\t\t\tif (!terminalBinding) continue\n\n\t\t\tconst newPagePoint = Vec.Add(terminalBinding.pagePosition, Vec.Mul(pageDelta, 0.5))\n\t\t\tconst newTarget = this.editor.getShapeAtPoint(newPagePoint, {\n\t\t\t\thitInside: true,\n\t\t\t\thitFrameInside: true,\n\t\t\t\tmargin: 0,\n\t\t\t\tfilter: (targetShape) => {\n\t\t\t\t\treturn (\n\t\t\t\t\t\t!targetShape.isLocked &&\n\t\t\t\t\t\tthis.editor.canBindShapes({ fromShape: shape, toShape: targetShape, binding: 'arrow' })\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t})\n\n\t\t\tif (newTarget?.id === terminalBinding.binding.toId) {\n\t\t\t\tconst targetBounds = Box.ZeroFix(this.editor.getShapeGeometry(newTarget).bounds)\n\t\t\t\tconst pointInTargetSpace = this.editor.getPointInShapeSpace(newTarget, newPagePoint)\n\t\t\t\tconst normalizedAnchor = {\n\t\t\t\t\tx: (pointInTargetSpace.x - targetBounds.minX) / targetBounds.width,\n\t\t\t\t\ty: (pointInTargetSpace.y - targetBounds.minY) / targetBounds.height,\n\t\t\t\t}\n\t\t\t\tcreateOrUpdateArrowBinding(this.editor, shape, newTarget.id, {\n\t\t\t\t\t...terminalBinding.binding.props,\n\t\t\t\t\tnormalizedAnchor,\n\t\t\t\t\tisPrecise: true,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tremoveArrowBinding(this.editor, shape, terminalBinding.binding.props.terminal)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate readonly _resizeInitialBindings = new WeakCache<TLArrowShape, TLArrowBindings>()\n\n\toverride onResize(shape: TLArrowShape, info: TLResizeInfo<TLArrowShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\tconst bindings = this._resizeInitialBindings.get(shape, () =>\n\t\t\tgetArrowBindings(this.editor, shape)\n\t\t)\n\t\tconst terminals = getArrowTerminalsInArrowSpace(this.editor, shape, bindings)\n\n\t\tconst { start, end } = structuredClone<TLArrowShape['props']>(shape.props)\n\t\tlet { bend } = shape.props\n\n\t\t// Rescale start handle if it's not bound to a shape\n\t\tif (!bindings.start) {\n\t\t\tstart.x = terminals.start.x * scaleX\n\t\t\tstart.y = terminals.start.y * scaleY\n\t\t}\n\n\t\t// Rescale end handle if it's not bound to a shape\n\t\tif (!bindings.end) {\n\t\t\tend.x = terminals.end.x * scaleX\n\t\t\tend.y = terminals.end.y * scaleY\n\t\t}\n\n\t\t// todo: we should only change the normalized anchor positions\n\t\t// of the shape's handles if the bound shape is also being resized\n\n\t\tconst mx = Math.abs(scaleX)\n\t\tconst my = Math.abs(scaleY)\n\n\t\tconst startNormalizedAnchor = bindings?.start\n\t\t\t? Vec.From(bindings.start.props.normalizedAnchor)\n\t\t\t: null\n\t\tconst endNormalizedAnchor = bindings?.end ? Vec.From(bindings.end.props.normalizedAnchor) : null\n\n\t\tif (scaleX < 0 && scaleY >= 0) {\n\t\t\tif (bend !== 0) {\n\t\t\t\tbend *= -1\n\t\t\t\tbend *= Math.max(mx, my)\n\t\t\t}\n\n\t\t\tif (startNormalizedAnchor) {\n\t\t\t\tstartNormalizedAnchor.x = 1 - startNormalizedAnchor.x\n\t\t\t}\n\n\t\t\tif (endNormalizedAnchor) {\n\t\t\t\tendNormalizedAnchor.x = 1 - endNormalizedAnchor.x\n\t\t\t}\n\t\t} else if (scaleX >= 0 && scaleY < 0) {\n\t\t\tif (bend !== 0) {\n\t\t\t\tbend *= -1\n\t\t\t\tbend *= Math.max(mx, my)\n\t\t\t}\n\n\t\t\tif (startNormalizedAnchor) {\n\t\t\t\tstartNormalizedAnchor.y = 1 - startNormalizedAnchor.y\n\t\t\t}\n\n\t\t\tif (endNormalizedAnchor) {\n\t\t\t\tendNormalizedAnchor.y = 1 - endNormalizedAnchor.y\n\t\t\t}\n\t\t} else if (scaleX >= 0 && scaleY >= 0) {\n\t\t\tif (bend !== 0) {\n\t\t\t\tbend *= Math.max(mx, my)\n\t\t\t}\n\t\t} else if (scaleX < 0 && scaleY < 0) {\n\t\t\tif (bend !== 0) {\n\t\t\t\tbend *= Math.max(mx, my)\n\t\t\t}\n\n\t\t\tif (startNormalizedAnchor) {\n\t\t\t\tstartNormalizedAnchor.x = 1 - startNormalizedAnchor.x\n\t\t\t\tstartNormalizedAnchor.y = 1 - startNormalizedAnchor.y\n\t\t\t}\n\n\t\t\tif (endNormalizedAnchor) {\n\t\t\t\tendNormalizedAnchor.x = 1 - endNormalizedAnchor.x\n\t\t\t\tendNormalizedAnchor.y = 1 - endNormalizedAnchor.y\n\t\t\t}\n\t\t}\n\n\t\tif (bindings.start && startNormalizedAnchor) {\n\t\t\tcreateOrUpdateArrowBinding(this.editor, shape, bindings.start.toId, {\n\t\t\t\t...bindings.start.props,\n\t\t\t\tnormalizedAnchor: startNormalizedAnchor.toJson(),\n\t\t\t})\n\t\t}\n\t\tif (bindings.end && endNormalizedAnchor) {\n\t\t\tcreateOrUpdateArrowBinding(this.editor, shape, bindings.end.toId, {\n\t\t\t\t...bindings.end.props,\n\t\t\t\tnormalizedAnchor: endNormalizedAnchor.toJson(),\n\t\t\t})\n\t\t}\n\n\t\tconst next = {\n\t\t\tprops: {\n\t\t\t\tstart,\n\t\t\t\tend,\n\t\t\t\tbend,\n\t\t\t},\n\t\t}\n\n\t\treturn next\n\t}\n\n\toverride onDoubleClickHandle(\n\t\tshape: TLArrowShape,\n\t\thandle: TLHandle\n\t): TLShapePartial<TLArrowShape> | void {\n\t\tswitch (handle.id) {\n\t\t\tcase ArrowHandles.Start: {\n\t\t\t\treturn {\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\t...shape.props,\n\t\t\t\t\t\tarrowheadStart: shape.props.arrowheadStart === 'none' ? 'arrow' : 'none',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase ArrowHandles.End: {\n\t\t\t\treturn {\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\t...shape.props,\n\t\t\t\t\t\tarrowheadEnd: shape.props.arrowheadEnd === 'none' ? 'arrow' : 'none',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tcomponent(shape: TLArrowShape) {\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst theme = useDefaultColorTheme()\n\t\tconst onlySelectedShape = this.editor.getOnlySelectedShape()\n\t\tconst shouldDisplayHandles =\n\t\t\tthis.editor.isInAny(\n\t\t\t\t'select.idle',\n\t\t\t\t'select.pointing_handle',\n\t\t\t\t'select.dragging_handle',\n\t\t\t\t'select.translating',\n\t\t\t\t'arrow.dragging'\n\t\t\t) && !this.editor.getIsReadonly()\n\n\t\tconst info = getArrowInfo(this.editor, shape)\n\t\tif (!info?.isValid) return null\n\n\t\tconst labelPosition = getArrowLabelPosition(this.editor, shape)\n\t\tconst isSelected = shape.id === this.editor.getOnlySelectedShapeId()\n\t\tconst isEditing = this.editor.getEditingShapeId() === shape.id\n\t\tconst showArrowLabel = isEditing || !isEmptyRichText(shape.props.richText)\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<SVGContainer style={{ minWidth: 50, minHeight: 50 }}>\n\t\t\t\t\t<ArrowSvg\n\t\t\t\t\t\tshape={shape}\n\t\t\t\t\t\tshouldDisplayHandles={shouldDisplayHandles && onlySelectedShape?.id === shape.id}\n\t\t\t\t\t/>\n\t\t\t\t\t{shape.props.kind === 'elbow' && debugFlags.debugElbowArrows.get() && (\n\t\t\t\t\t\t<ElbowArrowDebug arrow={shape} />\n\t\t\t\t\t)}\n\t\t\t\t</SVGContainer>\n\t\t\t\t{showArrowLabel && (\n\t\t\t\t\t<RichTextLabel\n\t\t\t\t\t\tshapeId={shape.id}\n\t\t\t\t\t\ttype=\"arrow\"\n\t\t\t\t\t\tfont={shape.props.font}\n\t\t\t\t\t\tfontSize={getArrowLabelFontSize(shape)}\n\t\t\t\t\t\tlineHeight={TEXT_PROPS.lineHeight}\n\t\t\t\t\t\talign=\"middle\"\n\t\t\t\t\t\tverticalAlign=\"middle\"\n\t\t\t\t\t\tlabelColor={getColorValue(theme, shape.props.labelColor, 'solid')}\n\t\t\t\t\t\trichText={shape.props.richText}\n\t\t\t\t\t\ttextWidth={labelPosition.box.w - ARROW_LABEL_PADDING * 2 * shape.props.scale}\n\t\t\t\t\t\tisSelected={isSelected}\n\t\t\t\t\t\tpadding={0}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\ttransform: `translate(${labelPosition.box.center.x}px, ${labelPosition.box.center.y}px)`,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</>\n\t\t)\n\t}\n\n\tindicator(shape: TLArrowShape) {\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst isEditing = useIsEditing(shape.id)\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst clipPathId = useSharedSafeId(shape.id + '_clip')\n\n\t\tconst info = getArrowInfo(this.editor, shape)\n\t\tif (!info) return null\n\n\t\tconst { start, end } = getArrowTerminalsInArrowSpace(this.editor, shape, info?.bindings)\n\t\tconst geometry = this.editor.getShapeGeometry<Group2d>(shape)\n\t\tconst bounds = geometry.bounds\n\t\tconst isEmpty = isEmptyRichText(shape.props.richText)\n\n\t\tconst labelGeometry = isEditing || !isEmpty ? (geometry.children[1] as Rectangle2d) : null\n\n\t\tif (Vec.Equals(start, end)) return null\n\n\t\tconst strokeWidth = STROKE_SIZES[shape.props.size] * shape.props.scale\n\n\t\tconst as = info.start.arrowhead && getArrowheadPathForType(info, 'start', strokeWidth)\n\t\tconst ae = info.end.arrowhead && getArrowheadPathForType(info, 'end', strokeWidth)\n\n\t\tconst includeClipPath =\n\t\t\t(as && info.start.arrowhead !== 'arrow') ||\n\t\t\t(ae && info.end.arrowhead !== 'arrow') ||\n\t\t\t!!labelGeometry\n\n\t\tconst labelBounds = labelGeometry ? labelGeometry.getBounds() : new Box(0, 0, 0, 0)\n\n\t\tif (isEditing && labelGeometry) {\n\t\t\treturn (\n\t\t\t\t<rect\n\t\t\t\t\tx={toDomPrecision(labelBounds.x)}\n\t\t\t\t\ty={toDomPrecision(labelBounds.y)}\n\t\t\t\t\twidth={labelBounds.w}\n\t\t\t\t\theight={labelBounds.h}\n\t\t\t\t\trx={3.5 * shape.props.scale}\n\t\t\t\t\try={3.5 * shape.props.scale}\n\t\t\t\t/>\n\t\t\t)\n\t\t}\n\t\tconst clipStartArrowhead = !(\n\t\t\tinfo.start.arrowhead === 'none' || info.start.arrowhead === 'arrow'\n\t\t)\n\t\tconst clipEndArrowhead = !(info.end.arrowhead === 'none' || info.end.arrowhead === 'arrow')\n\n\t\treturn (\n\t\t\t<g>\n\t\t\t\t{includeClipPath && (\n\t\t\t\t\t<defs>\n\t\t\t\t\t\t<ArrowClipPath\n\t\t\t\t\t\t\tradius={3.5 * shape.props.scale}\n\t\t\t\t\t\t\thasText={!isEmpty}\n\t\t\t\t\t\t\tbounds={bounds}\n\t\t\t\t\t\t\tlabelBounds={labelBounds}\n\t\t\t\t\t\t\tas={clipStartArrowhead && as ? as : ''}\n\t\t\t\t\t\t\tae={clipEndArrowhead && ae ? ae : ''}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</defs>\n\t\t\t\t)}\n\t\t\t\t<g\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tclipPath: includeClipPath ? `url(#${clipPathId})` : undefined,\n\t\t\t\t\t\tWebkitClipPath: includeClipPath ? `url(#${clipPathId})` : undefined,\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{/* This rect needs to be here if we're creating a mask due to an svg quirk on Chrome */}\n\t\t\t\t\t{includeClipPath && (\n\t\t\t\t\t\t<rect\n\t\t\t\t\t\t\tx={bounds.minX - 100}\n\t\t\t\t\t\t\ty={bounds.minY - 100}\n\t\t\t\t\t\t\twidth={bounds.width + 200}\n\t\t\t\t\t\t\theight={bounds.height + 200}\n\t\t\t\t\t\t\topacity={0}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{getArrowBodyPath(\n\t\t\t\t\t\tshape,\n\t\t\t\t\t\tinfo,\n\t\t\t\t\t\tshape.props.dash === 'draw'\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tstyle: 'draw',\n\t\t\t\t\t\t\t\t\trandomSeed: shape.id,\n\t\t\t\t\t\t\t\t\tstrokeWidth: 1,\n\t\t\t\t\t\t\t\t\tpasses: 1,\n\t\t\t\t\t\t\t\t\toffset: 0,\n\t\t\t\t\t\t\t\t\troundness: strokeWidth * 2,\n\t\t\t\t\t\t\t\t\tprops: { strokeWidth: undefined },\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: { style: 'solid', strokeWidth: 1, props: { strokeWidth: undefined } }\n\t\t\t\t\t)}\n\t\t\t\t</g>\n\t\t\t\t{as && <path d={as} />}\n\t\t\t\t{ae && <path d={ae} />}\n\t\t\t\t{labelGeometry && (\n\t\t\t\t\t<rect\n\t\t\t\t\t\tx={toDomPrecision(labelBounds.x)}\n\t\t\t\t\t\ty={toDomPrecision(labelBounds.y)}\n\t\t\t\t\t\twidth={labelBounds.w}\n\t\t\t\t\t\theight={labelBounds.h}\n\t\t\t\t\t\trx={3.5}\n\t\t\t\t\t\try={3.5}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride onEditStart(shape: TLArrowShape) {\n\t\tif (isEmptyRichText(shape.props.richText)) {\n\t\t\t// editing text for the first time, so set the position to the default:\n\t\t\tconst labelPosition = getArrowLabelDefaultPosition(this.editor, shape)\n\t\t\tthis.editor.updateShape({\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tprops: { labelPosition },\n\t\t\t})\n\t\t}\n\t}\n\n\toverride toSvg(shape: TLArrowShape, ctx: SvgExportContext) {\n\t\tctx.addExportDef(getFillDefForExport(shape.props.fill))\n\t\tconst theme = getDefaultColorTheme(ctx)\n\t\tconst scaleFactor = 1 / shape.props.scale\n\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<ArrowSvg shape={shape} shouldDisplayHandles={false} />\n\t\t\t\t<RichTextSVG\n\t\t\t\t\tfontSize={getArrowLabelFontSize(shape)}\n\t\t\t\t\tfont={shape.props.font}\n\t\t\t\t\talign=\"middle\"\n\t\t\t\t\tverticalAlign=\"middle\"\n\t\t\t\t\tlabelColor={getColorValue(theme, shape.props.labelColor, 'solid')}\n\t\t\t\t\trichText={shape.props.richText}\n\t\t\t\t\tbounds={getArrowLabelPosition(this.editor, shape)\n\t\t\t\t\t\t.box.clone()\n\t\t\t\t\t\t.expandBy(-ARROW_LABEL_PADDING * shape.props.scale)}\n\t\t\t\t\tpadding={0}\n\t\t\t\t\tshowTextOutline={true}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride getCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn [\n\t\t\tgetFillDefForCanvas(),\n\t\t\t{\n\t\t\t\tkey: `arrow:dot`,\n\t\t\t\tcomponent: ArrowheadDotDef,\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: `arrow:cross`,\n\t\t\t\tcomponent: ArrowheadCrossDef,\n\t\t\t},\n\t\t]\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLArrowShape,\n\t\tendShape: TLArrowShape,\n\t\tprogress: number\n\t): TLArrowShapeProps {\n\t\treturn {\n\t\t\t...(progress > 0.5 ? endShape.props : startShape.props),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, progress),\n\t\t\tstart: {\n\t\t\t\tx: lerp(startShape.props.start.x, endShape.props.start.x, progress),\n\t\t\t\ty: lerp(startShape.props.start.y, endShape.props.start.y, progress),\n\t\t\t},\n\t\t\tend: {\n\t\t\t\tx: lerp(startShape.props.end.x, endShape.props.end.x, progress),\n\t\t\t\ty: lerp(startShape.props.end.y, endShape.props.end.y, progress),\n\t\t\t},\n\t\t\tbend: lerp(startShape.props.bend, endShape.props.bend, progress),\n\t\t\tlabelPosition: lerp(startShape.props.labelPosition, endShape.props.labelPosition, progress),\n\t\t}\n\t}\n}\n\nexport function getArrowLength(editor: Editor, shape: TLArrowShape): number {\n\tconst info = getArrowInfo(editor, shape)!\n\n\treturn info.type === 'straight'\n\t\t? Vec.Dist(info.start.handle, info.end.handle)\n\t\t: info.type === 'arc'\n\t\t\t? Math.abs(info.handleArc.length)\n\t\t\t: info.route.distance\n}\n\nconst ArrowSvg = track(function ArrowSvg({\n\tshape,\n\tshouldDisplayHandles,\n}: {\n\tshape: TLArrowShape\n\tshouldDisplayHandles: boolean\n}) {\n\tconst editor = useEditor()\n\tconst theme = useDefaultColorTheme()\n\tconst info = getArrowInfo(editor, shape)\n\tconst isForceSolid = useValue(\n\t\t'force solid',\n\t\t() => {\n\t\t\treturn editor.getZoomLevel() < 0.2\n\t\t},\n\t\t[editor]\n\t)\n\tconst clipPathId = useSharedSafeId(shape.id + '_clip')\n\tconst arrowheadDotId = useSharedSafeId('arrowhead-dot')\n\tconst arrowheadCrossId = useSharedSafeId('arrowhead-cross')\n\tconst isEditing = useIsEditing(shape.id)\n\tconst geometry = editor.getShapeGeometry(shape)\n\tif (!geometry) return null\n\tconst bounds = Box.ZeroFix(geometry.bounds)\n\tconst bindings = getArrowBindings(editor, shape)\n\tconst isEmpty = isEmptyRichText(shape.props.richText)\n\n\tif (!info?.isValid) return null\n\n\tconst strokeWidth = STROKE_SIZES[shape.props.size] * shape.props.scale\n\n\tconst as = info.start.arrowhead && getArrowheadPathForType(info, 'start', strokeWidth)\n\tconst ae = info.end.arrowhead && getArrowheadPathForType(info, 'end', strokeWidth)\n\n\tlet handlePath: null | React.JSX.Element = null\n\n\tif (shouldDisplayHandles && (bindings.start || bindings.end)) {\n\t\thandlePath = getArrowHandlePath(info, {\n\t\t\tstyle: 'dashed',\n\t\t\tstart: 'skip',\n\t\t\tend: 'skip',\n\t\t\tlengthRatio: 2.5,\n\t\t\tstrokeWidth: 2 / editor.getZoomLevel(),\n\t\t\tprops: {\n\t\t\t\tclassName: 'tl-arrow-hint',\n\t\t\t\tmarkerStart: bindings.start\n\t\t\t\t\t? bindings.start.props.isExact\n\t\t\t\t\t\t? ''\n\t\t\t\t\t\t: bindings.start.props.isPrecise\n\t\t\t\t\t\t\t? `url(#${arrowheadCrossId})`\n\t\t\t\t\t\t\t: `url(#${arrowheadDotId})`\n\t\t\t\t\t: '',\n\t\t\t\tmarkerEnd: bindings.end\n\t\t\t\t\t? bindings.end.props.isExact\n\t\t\t\t\t\t? ''\n\t\t\t\t\t\t: bindings.end.props.isPrecise\n\t\t\t\t\t\t\t? `url(#${arrowheadCrossId})`\n\t\t\t\t\t\t\t: `url(#${arrowheadDotId})`\n\t\t\t\t\t: '',\n\t\t\t\topacity: 0.16,\n\t\t\t},\n\t\t})\n\t}\n\n\tconst labelPosition = getArrowLabelPosition(editor, shape)\n\n\tconst clipStartArrowhead = !(info.start.arrowhead === 'none' || info.start.arrowhead === 'arrow')\n\tconst clipEndArrowhead = !(info.end.arrowhead === 'none' || info.end.arrowhead === 'arrow')\n\n\treturn (\n\t\t<>\n\t\t\t{/* Yep */}\n\t\t\t<defs>\n\t\t\t\t<clipPath id={clipPathId}>\n\t\t\t\t\t<ArrowClipPath\n\t\t\t\t\t\tradius={3.5 * shape.props.scale}\n\t\t\t\t\t\thasText={isEditing || !isEmpty}\n\t\t\t\t\t\tbounds={bounds}\n\t\t\t\t\t\tlabelBounds={labelPosition.box}\n\t\t\t\t\t\tas={clipStartArrowhead && as ? as : ''}\n\t\t\t\t\t\tae={clipEndArrowhead && ae ? ae : ''}\n\t\t\t\t\t/>\n\t\t\t\t</clipPath>\n\t\t\t</defs>\n\t\t\t<g\n\t\t\t\tfill=\"none\"\n\t\t\t\tstroke={getColorValue(theme, shape.props.color, 'solid')}\n\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tpointerEvents=\"none\"\n\t\t\t>\n\t\t\t\t{handlePath}\n\t\t\t\t<g\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tclipPath: `url(#${clipPathId})`,\n\t\t\t\t\t\tWebkitClipPath: `url(#${clipPathId})`,\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<rect\n\t\t\t\t\t\tx={toDomPrecision(bounds.minX - 100)}\n\t\t\t\t\t\ty={toDomPrecision(bounds.minY - 100)}\n\t\t\t\t\t\twidth={toDomPrecision(bounds.width + 200)}\n\t\t\t\t\t\theight={toDomPrecision(bounds.height + 200)}\n\t\t\t\t\t\topacity={0}\n\t\t\t\t\t/>\n\t\t\t\t\t{getArrowBodyPath(shape, info, {\n\t\t\t\t\t\tstyle: shape.props.dash,\n\t\t\t\t\t\tstrokeWidth,\n\t\t\t\t\t\tforceSolid: isForceSolid,\n\t\t\t\t\t\trandomSeed: shape.id,\n\t\t\t\t\t})}\n\t\t\t\t</g>\n\t\t\t\t{as && clipStartArrowhead && shape.props.fill !== 'none' && (\n\t\t\t\t\t<ShapeFill\n\t\t\t\t\t\ttheme={theme}\n\t\t\t\t\t\td={as}\n\t\t\t\t\t\tcolor={shape.props.color}\n\t\t\t\t\t\tfill={shape.props.fill}\n\t\t\t\t\t\tscale={shape.props.scale}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t{ae && clipEndArrowhead && shape.props.fill !== 'none' && (\n\t\t\t\t\t<ShapeFill\n\t\t\t\t\t\ttheme={theme}\n\t\t\t\t\t\td={ae}\n\t\t\t\t\t\tcolor={shape.props.color}\n\t\t\t\t\t\tfill={shape.props.fill}\n\t\t\t\t\t\tscale={shape.props.scale}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t{as && <path d={as} />}\n\t\t\t\t{ae && <path d={ae} />}\n\t\t\t</g>\n\t\t</>\n\t)\n})\n\nfunction ArrowClipPath({\n\tradius,\n\thasText,\n\tbounds,\n\tlabelBounds,\n\tas,\n\tae,\n}: {\n\tradius: number\n\thasText: boolean\n\tbounds: Box\n\tlabelBounds: Box\n\tas: string\n\tae: string\n}) {\n\tconst path = useMemo(() => {\n\t\t// The direction in which we create the different path parts is important, as it determines what gets clipped.\n\t\t// See the description on the directions in the non-zero fill rule example:\n\t\t// https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule#nonzero\n\t\tconst path = new PathBuilder()\n\n\t\t// We create this one in the clockwise direction\n\t\tpath\n\t\t\t.moveTo(bounds.left - 100, bounds.top - 100)\n\t\t\t.lineTo(bounds.right + 100, bounds.top - 100)\n\t\t\t.lineTo(bounds.right + 100, bounds.bottom + 100)\n\t\t\t.lineTo(bounds.left - 100, bounds.bottom + 100)\n\t\t\t.close()\n\n\t\tif (hasText) {\n\t\t\t// We create this one in the counter-clockwise direction, which cuts out the label box\n\t\t\tpath\n\t\t\t\t.moveTo(labelBounds.left, labelBounds.top + radius)\n\t\t\t\t.lineTo(labelBounds.left, labelBounds.bottom - radius)\n\t\t\t\t.circularArcTo(radius, false, false, labelBounds.left + radius, labelBounds.bottom)\n\t\t\t\t.lineTo(labelBounds.right - radius, labelBounds.bottom)\n\t\t\t\t.circularArcTo(radius, false, false, labelBounds.right, labelBounds.bottom - radius)\n\t\t\t\t.lineTo(labelBounds.right, labelBounds.top + radius)\n\t\t\t\t.circularArcTo(radius, false, false, labelBounds.right - radius, labelBounds.top)\n\t\t\t\t.lineTo(labelBounds.left + radius, labelBounds.top)\n\t\t\t\t.circularArcTo(radius, false, false, labelBounds.left, labelBounds.top + radius)\n\t\t\t\t.close()\n\t\t}\n\n\t\treturn path.toD()\n\t}, [\n\t\tradius,\n\t\thasText,\n\t\tbounds.bottom,\n\t\tbounds.left,\n\t\tbounds.right,\n\t\tbounds.top,\n\t\tlabelBounds.bottom,\n\t\tlabelBounds.left,\n\t\tlabelBounds.right,\n\t\tlabelBounds.top,\n\t])\n\n\t// We also append the arrowhead paths to the clip path, so that we also clip the arrowheads\n\treturn <path d={`${path}${as}${ae}`} />\n}\n\nconst shapeAtTranslationStart = new WeakMap<\n\tTLArrowShape,\n\t{\n\t\tpagePosition: Vec\n\t\tterminalBindings: Record<\n\t\t\t'start' | 'end',\n\t\t\t{\n\t\t\t\tpagePosition: Vec\n\t\t\t\tshapePosition: Vec\n\t\t\t\tbinding: TLArrowBinding\n\t\t\t} | null\n\t\t>\n\t}\n>()\n\nfunction ArrowheadDotDef() {\n\tconst id = useSharedSafeId('arrowhead-dot')\n\treturn (\n\t\t<marker id={id} className=\"tl-arrow-hint\" refX=\"3.0\" refY=\"3.0\" orient=\"0\">\n\t\t\t<circle cx=\"3\" cy=\"3\" r=\"2\" strokeDasharray=\"100%\" />\n\t\t</marker>\n\t)\n}\n\nfunction ArrowheadCrossDef() {\n\tconst id = useSharedSafeId('arrowhead-cross')\n\treturn (\n\t\t<marker id={id} className=\"tl-arrow-hint\" refX=\"3.0\" refY=\"3.0\" orient=\"auto\">\n\t\t\t<line x1=\"1.5\" y1=\"1.5\" x2=\"4.5\" y2=\"4.5\" strokeDasharray=\"100%\" />\n\t\t\t<line x1=\"1.5\" y1=\"4.5\" x2=\"4.5\" y2=\"1.5\" strokeDasharray=\"100%\" />\n\t\t</marker>\n\t)\n}\n\n/**\n * Take 2 angles and return true if they are approximately parallel. Angle that point in the same\n * (or opposite) directions are considered parallel. This also handles wrap around - e.g. 0, \u03C0, and\n * 2\u03C0 are all considered parallel.\n */\nfunction anglesAreApproximatelyParallel(a: number, b: number, tolerance = 0.0001) {\n\tconst diff = Math.abs(a - b)\n\n\tconst isParallel = diff < tolerance\n\tconst isFlippedParallel = Math.abs(diff - Math.PI) < tolerance\n\tconst is360Parallel = Math.abs(diff - PI2) < tolerance\n\n\treturn { isParallel: isParallel || is360Parallel, isFlippedParallel }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tArc2d,\n\tBox,\n\tEMPTY_ARRAY,\n\tEdge2d,\n\tEditor,\n\tGeometry2d,\n\tGroup2d,\n\tIndexKey,\n\tPI2,\n\tPolyline2d,\n\tRectangle2d,\n\tSVGContainer,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLArrowBinding,\n\tTLArrowBindingProps,\n\tTLArrowShape,\n\tTLArrowShapeProps,\n\tTLHandle,\n\tTLHandleDragInfo,\n\tTLResizeInfo,\n\tTLShapePartial,\n\tTLShapeUtilCanBeLaidOutOpts,\n\tTLShapeUtilCanBindOpts,\n\tTLShapeUtilCanvasSvgDef,\n\tVec,\n\tWeakCache,\n\tarrowShapeMigrations,\n\tarrowShapeProps,\n\tclamp,\n\tdebugFlags,\n\texhaustiveSwitchError,\n\tgetColorValue,\n\tgetDefaultColorTheme,\n\tgetFontsFromRichText,\n\tinvLerp,\n\tlerp,\n\tmapObjectMapValues,\n\tmaybeSnapToGrid,\n\tstructuredClone,\n\ttoDomPrecision,\n\ttoRichText,\n\ttrack,\n\tuseEditor,\n\tuseIsEditing,\n\tuseSharedSafeId,\n} from '@tldraw/editor'\nimport React, { useMemo } from 'react'\nimport { updateArrowTerminal } from '../../bindings/arrow/ArrowBindingUtil'\nimport { isEmptyRichText, renderPlaintextFromRichText } from '../../utils/text/richText'\nimport { PathBuilder } from '../shared/PathBuilder'\nimport { RichTextLabel, RichTextSVG } from '../shared/RichTextLabel'\nimport { ShapeFill } from '../shared/ShapeFill'\nimport { ARROW_LABEL_PADDING, STROKE_SIZES, TEXT_PROPS } from '../shared/default-shape-constants'\nimport { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport { useEfficientZoomThreshold } from '../shared/useEfficientZoomThreshold'\nimport { getArrowBodyPath, getArrowHandlePath } from './ArrowPath'\nimport { ArrowShapeOptions } from './arrow-types'\nimport {\n\tgetArrowLabelDefaultPosition,\n\tgetArrowLabelFontSize,\n\tgetArrowLabelPosition,\n} from './arrowLabel'\nimport { updateArrowTargetState } from './arrowTargetState'\nimport { getArrowheadPathForType } from './arrowheads'\nimport { ElbowArrowDebug } from './elbow/ElbowArrowDebug'\nimport { ElbowArrowAxes } from './elbow/definitions'\nimport { getElbowArrowSnapLines, perpDistanceToLineAngle } from './elbow/elbowArrowSnapLines'\nimport {\n\tTLArrowBindings,\n\tcreateOrUpdateArrowBinding,\n\tgetArrowBindings,\n\tgetArrowInfo,\n\tgetArrowTerminalsInArrowSpace,\n\tremoveArrowBinding,\n} from './shared'\n\nenum ArrowHandles {\n\tStart = 'start',\n\tMiddle = 'middle',\n\tEnd = 'end',\n}\n\n/** @public */\nexport class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {\n\tstatic override type = 'arrow' as const\n\tstatic override props = arrowShapeProps\n\tstatic override migrations = arrowShapeMigrations\n\n\toverride options: ArrowShapeOptions = {\n\t\texpandElbowLegLength: {\n\t\t\ts: 28,\n\t\t\tm: 36,\n\t\t\tl: 44,\n\t\t\txl: 66,\n\t\t},\n\t\tminElbowLegLength: {\n\t\t\ts: STROKE_SIZES.s * 3,\n\t\t\tm: STROKE_SIZES.m * 3,\n\t\t\tl: STROKE_SIZES.l * 3,\n\t\t\txl: STROKE_SIZES.xl * 3,\n\t\t},\n\t\tminElbowHandleDistance: 16,\n\n\t\tarcArrowCenterSnapDistance: 16,\n\t\telbowArrowCenterSnapDistance: 24,\n\t\telbowArrowEdgeSnapDistance: 20,\n\t\telbowArrowPointSnapDistance: 24,\n\t\telbowArrowAxisSnapDistance: 16,\n\n\t\tlabelCenterSnapDistance: 10,\n\n\t\telbowMidpointSnapDistance: 10,\n\t\telbowMinSegmentLengthToShowMidpointHandle: 20,\n\n\t\thoverPreciseTimeout: 600,\n\t\tpointingPreciseTimeout: 320,\n\n\t\tshouldBeExact: (editor: Editor) => editor.inputs.altKey,\n\t\tshouldIgnoreTargets: (editor: Editor) => editor.inputs.ctrlKey,\n\t}\n\n\toverride canEdit() {\n\t\treturn true\n\t}\n\toverride canBind({ toShapeType }: TLShapeUtilCanBindOpts<TLArrowShape>): boolean {\n\t\t// bindings can go from arrows to shapes, but not from shapes to arrows\n\t\treturn toShapeType !== 'arrow'\n\t}\n\toverride canSnap() {\n\t\treturn false\n\t}\n\toverride hideResizeHandles() {\n\t\treturn true\n\t}\n\toverride hideRotateHandle() {\n\t\treturn true\n\t}\n\toverride hideSelectionBoundsBg() {\n\t\treturn true\n\t}\n\toverride hideSelectionBoundsFg() {\n\t\treturn true\n\t}\n\toverride hideInMinimap() {\n\t\treturn true\n\t}\n\n\toverride canBeLaidOut(shape: TLArrowShape, info: TLShapeUtilCanBeLaidOutOpts) {\n\t\tif (info.type === 'flip') {\n\t\t\t// If we don't have this then the flip will be non-idempotent; that is, the flip will be multipotent, varipotent, or perhaps even omni-potent... and we can't have that\n\t\t\tconst bindings = getArrowBindings(this.editor, shape)\n\t\t\tconst { start, end } = bindings\n\t\t\tconst { shapes = [] } = info\n\t\t\tif (start && !shapes.find((s) => s.id === start.toId)) return false\n\t\t\tif (end && !shapes.find((s) => s.id === end.toId)) return false\n\t\t}\n\t\treturn true\n\t}\n\n\toverride getFontFaces(shape: TLArrowShape) {\n\t\tif (isEmptyRichText(shape.props.richText)) return EMPTY_ARRAY\n\n\t\treturn getFontsFromRichText(this.editor, shape.props.richText, {\n\t\t\tfamily: `tldraw_${shape.props.font}`,\n\t\t\tweight: 'normal',\n\t\t\tstyle: 'normal',\n\t\t})\n\t}\n\n\toverride getDefaultProps(): TLArrowShape['props'] {\n\t\treturn {\n\t\t\tkind: 'arc',\n\t\t\telbowMidPoint: 0.5,\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tfill: 'none',\n\t\t\tcolor: 'black',\n\t\t\tlabelColor: 'black',\n\t\t\tbend: 0,\n\t\t\tstart: { x: 0, y: 0 },\n\t\t\tend: { x: 2, y: 0 },\n\t\t\tarrowheadStart: 'none',\n\t\t\tarrowheadEnd: 'arrow',\n\t\t\trichText: toRichText(''),\n\t\t\tlabelPosition: 0.5,\n\t\t\tfont: 'draw',\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLArrowShape) {\n\t\tconst isEditing = this.editor.getEditingShapeId() === shape.id\n\t\tconst info = getArrowInfo(this.editor, shape)!\n\n\t\tconst debugGeom: Geometry2d[] = []\n\n\t\tconst bodyGeom =\n\t\t\tinfo.type === 'straight'\n\t\t\t\t? new Edge2d({\n\t\t\t\t\t\tstart: Vec.From(info.start.point),\n\t\t\t\t\t\tend: Vec.From(info.end.point),\n\t\t\t\t\t})\n\t\t\t\t: info.type === 'arc'\n\t\t\t\t\t? new Arc2d({\n\t\t\t\t\t\t\tcenter: Vec.Cast(info.handleArc.center),\n\t\t\t\t\t\t\tstart: Vec.Cast(info.start.point),\n\t\t\t\t\t\t\tend: Vec.Cast(info.end.point),\n\t\t\t\t\t\t\tsweepFlag: info.bodyArc.sweepFlag,\n\t\t\t\t\t\t\tlargeArcFlag: info.bodyArc.largeArcFlag,\n\t\t\t\t\t\t})\n\t\t\t\t\t: new Polyline2d({ points: info.route.points })\n\n\t\tlet labelGeom\n\t\tif (isEditing || !isEmptyRichText(shape.props.richText)) {\n\t\t\tconst labelPosition = getArrowLabelPosition(this.editor, shape)\n\t\t\tif (debugFlags.debugGeometry.get()) {\n\t\t\t\tdebugGeom.push(...labelPosition.debugGeom)\n\t\t\t}\n\t\t\tlabelGeom = new Rectangle2d({\n\t\t\t\tx: labelPosition.box.x,\n\t\t\t\ty: labelPosition.box.y,\n\t\t\t\twidth: labelPosition.box.w,\n\t\t\t\theight: labelPosition.box.h,\n\t\t\t\tisFilled: true,\n\t\t\t\tisLabel: true,\n\t\t\t})\n\t\t}\n\n\t\treturn new Group2d({\n\t\t\tchildren: [...(labelGeom ? [bodyGeom, labelGeom] : [bodyGeom]), ...debugGeom],\n\t\t})\n\t}\n\n\toverride getHandles(shape: TLArrowShape): TLHandle[] {\n\t\tconst info = getArrowInfo(this.editor, shape)!\n\n\t\tconst handles: TLHandle[] = [\n\t\t\t{\n\t\t\t\tid: ArrowHandles.Start,\n\t\t\t\ttype: 'vertex',\n\t\t\t\tindex: 'a1' as IndexKey,\n\t\t\t\tx: info.start.handle.x,\n\t\t\t\ty: info.start.handle.y,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: ArrowHandles.End,\n\t\t\t\ttype: 'vertex',\n\t\t\t\tindex: 'a3' as IndexKey,\n\t\t\t\tx: info.end.handle.x,\n\t\t\t\ty: info.end.handle.y,\n\t\t\t},\n\t\t]\n\n\t\tif (shape.props.kind === 'arc' && (info.type === 'straight' || info.type === 'arc')) {\n\t\t\thandles.push({\n\t\t\t\tid: ArrowHandles.Middle,\n\t\t\t\ttype: 'virtual',\n\t\t\t\tindex: 'a2' as IndexKey,\n\t\t\t\tx: info.middle.x,\n\t\t\t\ty: info.middle.y,\n\t\t\t})\n\t\t}\n\n\t\tif (shape.props.kind === 'elbow' && info.type === 'elbow' && info.route.midpointHandle) {\n\t\t\tconst shapePageTransform = this.editor.getShapePageTransform(shape.id)!\n\n\t\t\tconst segmentStart = shapePageTransform.applyToPoint(info.route.midpointHandle.segmentStart)\n\t\t\tconst segmentEnd = shapePageTransform.applyToPoint(info.route.midpointHandle.segmentEnd)\n\t\t\tconst segmentLength = Vec.Dist(segmentStart, segmentEnd) * this.editor.getEfficientZoomLevel()\n\n\t\t\tif (segmentLength > this.options.elbowMinSegmentLengthToShowMidpointHandle) {\n\t\t\t\thandles.push({\n\t\t\t\t\tid: ArrowHandles.Middle,\n\t\t\t\t\ttype: 'vertex',\n\t\t\t\t\tindex: 'a2' as IndexKey,\n\t\t\t\t\tx: info.route.midpointHandle.point.x,\n\t\t\t\t\ty: info.route.midpointHandle.point.y,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\treturn handles\n\t}\n\n\toverride getText(shape: TLArrowShape) {\n\t\treturn renderPlaintextFromRichText(this.editor, shape.props.richText)\n\t}\n\n\toverride onHandleDrag(shape: TLArrowShape, info: TLHandleDragInfo<TLArrowShape>) {\n\t\tconst handleId = info.handle.id as ArrowHandles\n\t\tswitch (handleId) {\n\t\t\tcase ArrowHandles.Middle:\n\t\t\t\tswitch (shape.props.kind) {\n\t\t\t\t\tcase 'arc':\n\t\t\t\t\t\treturn this.onArcMidpointHandleDrag(shape, info)\n\t\t\t\t\tcase 'elbow':\n\t\t\t\t\t\treturn this.onElbowMidpointHandleDrag(shape, info)\n\t\t\t\t\tdefault:\n\t\t\t\t\t\texhaustiveSwitchError(shape.props.kind)\n\t\t\t\t}\n\t\t\tcase ArrowHandles.Start:\n\t\t\tcase ArrowHandles.End:\n\t\t\t\treturn this.onTerminalHandleDrag(shape, info, handleId)\n\t\t\tdefault:\n\t\t\t\texhaustiveSwitchError(handleId)\n\t\t}\n\t}\n\n\tprivate onArcMidpointHandleDrag(shape: TLArrowShape, { handle }: TLHandleDragInfo<TLArrowShape>) {\n\t\tconst bindings = getArrowBindings(this.editor, shape)\n\n\t\t// Bending the arrow...\n\t\tconst { start, end } = getArrowTerminalsInArrowSpace(this.editor, shape, bindings)\n\n\t\tconst delta = Vec.Sub(end, start)\n\t\tconst v = Vec.Per(delta)\n\n\t\tconst med = Vec.Med(end, start)\n\t\tconst A = Vec.Sub(med, v)\n\t\tconst B = Vec.Add(med, v)\n\n\t\tconst point = Vec.NearestPointOnLineSegment(A, B, handle, false)\n\t\tlet bend = Vec.Dist(point, med)\n\t\tif (Vec.Clockwise(point, end, med)) bend *= -1\n\t\treturn { id: shape.id, type: shape.type, props: { bend } }\n\t}\n\n\tprivate onElbowMidpointHandleDrag(\n\t\tshape: TLArrowShape,\n\t\t{ handle }: TLHandleDragInfo<TLArrowShape>\n\t) {\n\t\tconst info = getArrowInfo(this.editor, shape)\n\t\tif (info?.type !== 'elbow') return\n\n\t\tconst shapeToPageTransform = this.editor.getShapePageTransform(shape.id)!\n\t\tconst handlePagePoint = shapeToPageTransform.applyToPoint(handle)\n\t\tconst axisName = info.route.midpointHandle?.axis\n\t\tif (!axisName) return\n\t\tconst axis = ElbowArrowAxes[axisName]\n\n\t\tconst midRange = info.elbow[axis.midRange]\n\t\tif (!midRange) return\n\n\t\t// We're snapping against a list of parallel lines. The way we do this is to calculate the\n\t\t// angle of the line we're snapping to...\n\t\tlet angle = Vec.Angle(\n\t\t\tshapeToPageTransform.applyToPoint(axis.v(0, 0)),\n\t\t\tshapeToPageTransform.applyToPoint(axis.v(0, 1))\n\t\t)\n\t\tif (angle < 0) angle += Math.PI\n\n\t\t// ...then calculate the perpendicular distance from the origin to the (infinite) line in\n\t\t// question. This returns a signed distance - lines \"behind\" the origin are negative.\n\t\tconst handlePoint = perpDistanceToLineAngle(handlePagePoint, angle)\n\n\t\t// As we're only ever moving along one dimension, we can use this perpendicular distance for\n\t\t// all of our snapping calculations.\n\t\tconst loPoint = perpDistanceToLineAngle(\n\t\t\tshapeToPageTransform.applyToPoint(axis.v(midRange.lo, 0)),\n\t\t\tangle\n\t\t)\n\t\tconst hiPoint = perpDistanceToLineAngle(\n\t\t\tshapeToPageTransform.applyToPoint(axis.v(midRange.hi, 0)),\n\t\t\tangle\n\t\t)\n\n\t\t// we want to snap to certain points. the maximum distance at which a snap will occur is\n\t\t// relative to the zoom level:\n\t\tconst maxSnapDistance =\n\t\t\tthis.options.elbowMidpointSnapDistance / this.editor.getEfficientZoomLevel()\n\n\t\t// we snap to the midpoint of the range by default\n\t\tconst midPoint = perpDistanceToLineAngle(\n\t\t\tshapeToPageTransform.applyToPoint(axis.v(lerp(midRange.lo, midRange.hi, 0.5), 0)),\n\t\t\tangle\n\t\t)\n\n\t\tlet snapPoint = midPoint\n\t\tlet snapDistance = Math.abs(midPoint - handlePoint)\n\n\t\t// then we check all the other arrows that are on-screen.\n\t\tfor (const [snapAngle, snapLines] of getElbowArrowSnapLines(this.editor)) {\n\t\t\tconst { isParallel, isFlippedParallel } = anglesAreApproximatelyParallel(angle, snapAngle)\n\t\t\tif (isParallel || isFlippedParallel) {\n\t\t\t\tfor (const snapLine of snapLines) {\n\t\t\t\t\tconst doesShareStartIntersection =\n\t\t\t\t\t\tsnapLine.startBoundShapeId &&\n\t\t\t\t\t\t(snapLine.startBoundShapeId === info.bindings.start?.toId ||\n\t\t\t\t\t\t\tsnapLine.startBoundShapeId === info.bindings.end?.toId)\n\n\t\t\t\t\tconst doesShareEndIntersection =\n\t\t\t\t\t\tsnapLine.endBoundShapeId &&\n\t\t\t\t\t\t(snapLine.endBoundShapeId === info.bindings.start?.toId ||\n\t\t\t\t\t\t\tsnapLine.endBoundShapeId === info.bindings.end?.toId)\n\n\t\t\t\t\tif (!doesShareStartIntersection && !doesShareEndIntersection) continue\n\n\t\t\t\t\tconst point = isFlippedParallel ? -snapLine.perpDistance : snapLine.perpDistance\n\t\t\t\t\tconst distance = Math.abs(point - handlePoint)\n\t\t\t\t\tif (distance < snapDistance) {\n\t\t\t\t\t\tsnapPoint = point\n\t\t\t\t\t\tsnapDistance = distance\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (snapDistance > maxSnapDistance) {\n\t\t\tsnapPoint = handlePoint\n\t\t}\n\n\t\tconst newMid = clamp(invLerp(loPoint, hiPoint, snapPoint), 0, 1)\n\n\t\treturn {\n\t\t\tid: shape.id,\n\t\t\ttype: shape.type,\n\t\t\tprops: {\n\t\t\t\telbowMidPoint: newMid,\n\t\t\t},\n\t\t}\n\t}\n\n\tprivate onTerminalHandleDrag(\n\t\tshape: TLArrowShape,\n\t\t{ handle, isPrecise }: TLHandleDragInfo<TLArrowShape>,\n\t\thandleId: ArrowHandles.Start | ArrowHandles.End\n\t) {\n\t\tconst bindings = getArrowBindings(this.editor, shape)\n\n\t\tconst update: TLShapePartial<TLArrowShape> = { id: shape.id, type: 'arrow', props: {} }\n\n\t\tconst currentBinding = bindings[handleId]\n\n\t\tconst oppositeHandleId = handleId === ArrowHandles.Start ? ArrowHandles.End : ArrowHandles.Start\n\t\tconst oppositeBinding = bindings[oppositeHandleId]\n\n\t\tconst targetInfo = updateArrowTargetState({\n\t\t\teditor: this.editor,\n\t\t\tpointInPageSpace: this.editor.getShapePageTransform(shape.id)!.applyToPoint(handle),\n\t\t\tarrow: shape,\n\t\t\tisPrecise: isPrecise,\n\t\t\tcurrentBinding,\n\t\t\toppositeBinding,\n\t\t})\n\n\t\tif (!targetInfo) {\n\t\t\t// todo: maybe double check that this isn't equal to the other handle too?\n\t\t\tremoveArrowBinding(this.editor, shape, handleId)\n\t\t\tconst newPoint = maybeSnapToGrid(new Vec(handle.x, handle.y), this.editor)\n\t\t\tupdate.props![handleId] = {\n\t\t\t\tx: newPoint.x,\n\t\t\t\ty: newPoint.y,\n\t\t\t}\n\t\t\treturn update\n\t\t}\n\n\t\t// we've got a target! the handle is being dragged over a shape, bind to it\n\t\tconst bindingProps: TLArrowBindingProps = {\n\t\t\tterminal: handleId,\n\t\t\tnormalizedAnchor: targetInfo.normalizedAnchor,\n\t\t\tisPrecise: targetInfo.isPrecise,\n\t\t\tisExact: targetInfo.isExact,\n\t\t\tsnap: targetInfo.snap,\n\t\t}\n\n\t\tcreateOrUpdateArrowBinding(this.editor, shape, targetInfo.target.id, bindingProps)\n\n\t\tconst newBindings = getArrowBindings(this.editor, shape)\n\t\tif (newBindings.start && newBindings.end && newBindings.start.toId === newBindings.end.toId) {\n\t\t\tif (\n\t\t\t\tVec.Equals(newBindings.start.props.normalizedAnchor, newBindings.end.props.normalizedAnchor)\n\t\t\t) {\n\t\t\t\tcreateOrUpdateArrowBinding(this.editor, shape, newBindings.end.toId, {\n\t\t\t\t\t...newBindings.end.props,\n\t\t\t\t\tnormalizedAnchor: {\n\t\t\t\t\t\tx: newBindings.end.props.normalizedAnchor.x + 0.05,\n\t\t\t\t\t\ty: newBindings.end.props.normalizedAnchor.y,\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\treturn update\n\t}\n\n\toverride onTranslateStart(shape: TLArrowShape) {\n\t\tconst bindings = getArrowBindings(this.editor, shape)\n\n\t\t// ...if the user is dragging ONLY this arrow, for elbow shapes, we can't maintain the bindings well just yet so we remove them entirely\n\t\tif (shape.props.kind === 'elbow' && this.editor.getOnlySelectedShapeId() === shape.id) {\n\t\t\tconst info = getArrowInfo(this.editor, shape)\n\t\t\tif (!info) return\n\t\t\tconst update: TLShapePartial<TLArrowShape> = { id: shape.id, type: 'arrow', props: {} }\n\t\t\tif (bindings.start) {\n\t\t\t\tupdate.props!.start = { x: info.start.point.x, y: info.start.point.y }\n\t\t\t\tremoveArrowBinding(this.editor, shape, 'start')\n\t\t\t}\n\t\t\tif (bindings.end) {\n\t\t\t\tupdate.props!.end = { x: info.end.point.x, y: info.end.point.y }\n\t\t\t\tremoveArrowBinding(this.editor, shape, 'end')\n\t\t\t}\n\t\t\treturn update\n\t\t}\n\n\t\tconst terminalsInArrowSpace = getArrowTerminalsInArrowSpace(this.editor, shape, bindings)\n\t\tconst shapePageTransform = this.editor.getShapePageTransform(shape.id)!\n\n\t\t// If at least one bound shape is in the selection, do nothing;\n\t\t// If no bound shapes are in the selection, unbind any bound shapes\n\n\t\tconst selectedShapeIds = this.editor.getSelectedShapeIds()\n\n\t\tif (\n\t\t\t(bindings.start &&\n\t\t\t\t(selectedShapeIds.includes(bindings.start.toId) ||\n\t\t\t\t\tthis.editor.isAncestorSelected(bindings.start.toId))) ||\n\t\t\t(bindings.end &&\n\t\t\t\t(selectedShapeIds.includes(bindings.end.toId) ||\n\t\t\t\t\tthis.editor.isAncestorSelected(bindings.end.toId)))\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\t// When we start translating shapes, record where their bindings were in page space so we\n\t\t// can maintain them as we translate the arrow\n\t\tshapeAtTranslationStart.set(shape, {\n\t\t\tpagePosition: shapePageTransform.applyToPoint(shape),\n\t\t\tterminalBindings: mapObjectMapValues(terminalsInArrowSpace, (terminalName, point) => {\n\t\t\t\tconst binding = bindings[terminalName]\n\t\t\t\tif (!binding) return null\n\t\t\t\treturn {\n\t\t\t\t\tbinding,\n\t\t\t\t\tshapePosition: point,\n\t\t\t\t\tpagePosition: shapePageTransform.applyToPoint(point),\n\t\t\t\t}\n\t\t\t}),\n\t\t})\n\n\t\t// update arrow terminal bindings eagerly to make sure the arrows unbind nicely when translating\n\t\tif (bindings.start) {\n\t\t\tupdateArrowTerminal({\n\t\t\t\teditor: this.editor,\n\t\t\t\tarrow: shape,\n\t\t\t\tterminal: 'start',\n\t\t\t\tuseHandle: true,\n\t\t\t})\n\t\t\tshape = this.editor.getShape(shape.id) as TLArrowShape\n\t\t}\n\t\tif (bindings.end) {\n\t\t\tupdateArrowTerminal({\n\t\t\t\teditor: this.editor,\n\t\t\t\tarrow: shape,\n\t\t\t\tterminal: 'end',\n\t\t\t\tuseHandle: true,\n\t\t\t})\n\t\t}\n\n\t\tfor (const handleName of [ArrowHandles.Start, ArrowHandles.End] as const) {\n\t\t\tconst binding = bindings[handleName]\n\t\t\tif (!binding) continue\n\n\t\t\tthis.editor.updateBinding({\n\t\t\t\t...binding,\n\t\t\t\tprops: { ...binding.props, isPrecise: true },\n\t\t\t})\n\t\t}\n\n\t\treturn\n\t}\n\n\toverride onTranslate(initialShape: TLArrowShape, shape: TLArrowShape) {\n\t\tconst atTranslationStart = shapeAtTranslationStart.get(initialShape)\n\t\tif (!atTranslationStart) return\n\n\t\tconst shapePageTransform = this.editor.getShapePageTransform(shape.id)!\n\t\tconst pageDelta = Vec.Sub(\n\t\t\tshapePageTransform.applyToPoint(shape),\n\t\t\tatTranslationStart.pagePosition\n\t\t)\n\n\t\tfor (const terminalBinding of Object.values(atTranslationStart.terminalBindings)) {\n\t\t\tif (!terminalBinding) continue\n\n\t\t\tconst newPagePoint = Vec.Add(terminalBinding.pagePosition, Vec.Mul(pageDelta, 0.5))\n\t\t\tconst newTarget = this.editor.getShapeAtPoint(newPagePoint, {\n\t\t\t\thitInside: true,\n\t\t\t\thitFrameInside: true,\n\t\t\t\tmargin: 0,\n\t\t\t\tfilter: (targetShape) => {\n\t\t\t\t\treturn (\n\t\t\t\t\t\t!targetShape.isLocked &&\n\t\t\t\t\t\tthis.editor.canBindShapes({ fromShape: shape, toShape: targetShape, binding: 'arrow' })\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t})\n\n\t\t\tif (newTarget?.id === terminalBinding.binding.toId) {\n\t\t\t\tconst targetBounds = Box.ZeroFix(this.editor.getShapeGeometry(newTarget).bounds)\n\t\t\t\tconst pointInTargetSpace = this.editor.getPointInShapeSpace(newTarget, newPagePoint)\n\t\t\t\tconst normalizedAnchor = {\n\t\t\t\t\tx: (pointInTargetSpace.x - targetBounds.minX) / targetBounds.width,\n\t\t\t\t\ty: (pointInTargetSpace.y - targetBounds.minY) / targetBounds.height,\n\t\t\t\t}\n\t\t\t\tcreateOrUpdateArrowBinding(this.editor, shape, newTarget.id, {\n\t\t\t\t\t...terminalBinding.binding.props,\n\t\t\t\t\tnormalizedAnchor,\n\t\t\t\t\tisPrecise: true,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tremoveArrowBinding(this.editor, shape, terminalBinding.binding.props.terminal)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate readonly _resizeInitialBindings = new WeakCache<TLArrowShape, TLArrowBindings>()\n\n\toverride onResize(shape: TLArrowShape, info: TLResizeInfo<TLArrowShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\tconst bindings = this._resizeInitialBindings.get(shape, () =>\n\t\t\tgetArrowBindings(this.editor, shape)\n\t\t)\n\t\tconst terminals = getArrowTerminalsInArrowSpace(this.editor, shape, bindings)\n\n\t\tconst { start, end } = structuredClone<TLArrowShape['props']>(shape.props)\n\t\tlet { bend } = shape.props\n\n\t\t// Rescale start handle if it's not bound to a shape\n\t\tif (!bindings.start) {\n\t\t\tstart.x = terminals.start.x * scaleX\n\t\t\tstart.y = terminals.start.y * scaleY\n\t\t}\n\n\t\t// Rescale end handle if it's not bound to a shape\n\t\tif (!bindings.end) {\n\t\t\tend.x = terminals.end.x * scaleX\n\t\t\tend.y = terminals.end.y * scaleY\n\t\t}\n\n\t\t// todo: we should only change the normalized anchor positions\n\t\t// of the shape's handles if the bound shape is also being resized\n\n\t\tconst mx = Math.abs(scaleX)\n\t\tconst my = Math.abs(scaleY)\n\n\t\tconst startNormalizedAnchor = bindings?.start\n\t\t\t? Vec.From(bindings.start.props.normalizedAnchor)\n\t\t\t: null\n\t\tconst endNormalizedAnchor = bindings?.end ? Vec.From(bindings.end.props.normalizedAnchor) : null\n\n\t\tif (scaleX < 0 && scaleY >= 0) {\n\t\t\tif (bend !== 0) {\n\t\t\t\tbend *= -1\n\t\t\t\tbend *= Math.max(mx, my)\n\t\t\t}\n\n\t\t\tif (startNormalizedAnchor) {\n\t\t\t\tstartNormalizedAnchor.x = 1 - startNormalizedAnchor.x\n\t\t\t}\n\n\t\t\tif (endNormalizedAnchor) {\n\t\t\t\tendNormalizedAnchor.x = 1 - endNormalizedAnchor.x\n\t\t\t}\n\t\t} else if (scaleX >= 0 && scaleY < 0) {\n\t\t\tif (bend !== 0) {\n\t\t\t\tbend *= -1\n\t\t\t\tbend *= Math.max(mx, my)\n\t\t\t}\n\n\t\t\tif (startNormalizedAnchor) {\n\t\t\t\tstartNormalizedAnchor.y = 1 - startNormalizedAnchor.y\n\t\t\t}\n\n\t\t\tif (endNormalizedAnchor) {\n\t\t\t\tendNormalizedAnchor.y = 1 - endNormalizedAnchor.y\n\t\t\t}\n\t\t} else if (scaleX >= 0 && scaleY >= 0) {\n\t\t\tif (bend !== 0) {\n\t\t\t\tbend *= Math.max(mx, my)\n\t\t\t}\n\t\t} else if (scaleX < 0 && scaleY < 0) {\n\t\t\tif (bend !== 0) {\n\t\t\t\tbend *= Math.max(mx, my)\n\t\t\t}\n\n\t\t\tif (startNormalizedAnchor) {\n\t\t\t\tstartNormalizedAnchor.x = 1 - startNormalizedAnchor.x\n\t\t\t\tstartNormalizedAnchor.y = 1 - startNormalizedAnchor.y\n\t\t\t}\n\n\t\t\tif (endNormalizedAnchor) {\n\t\t\t\tendNormalizedAnchor.x = 1 - endNormalizedAnchor.x\n\t\t\t\tendNormalizedAnchor.y = 1 - endNormalizedAnchor.y\n\t\t\t}\n\t\t}\n\n\t\tif (bindings.start && startNormalizedAnchor) {\n\t\t\tcreateOrUpdateArrowBinding(this.editor, shape, bindings.start.toId, {\n\t\t\t\t...bindings.start.props,\n\t\t\t\tnormalizedAnchor: startNormalizedAnchor.toJson(),\n\t\t\t})\n\t\t}\n\t\tif (bindings.end && endNormalizedAnchor) {\n\t\t\tcreateOrUpdateArrowBinding(this.editor, shape, bindings.end.toId, {\n\t\t\t\t...bindings.end.props,\n\t\t\t\tnormalizedAnchor: endNormalizedAnchor.toJson(),\n\t\t\t})\n\t\t}\n\n\t\tconst next = {\n\t\t\tprops: {\n\t\t\t\tstart,\n\t\t\t\tend,\n\t\t\t\tbend,\n\t\t\t},\n\t\t}\n\n\t\treturn next\n\t}\n\n\toverride onDoubleClickHandle(\n\t\tshape: TLArrowShape,\n\t\thandle: TLHandle\n\t): TLShapePartial<TLArrowShape> | void {\n\t\tswitch (handle.id) {\n\t\t\tcase ArrowHandles.Start: {\n\t\t\t\treturn {\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\t...shape.props,\n\t\t\t\t\t\tarrowheadStart: shape.props.arrowheadStart === 'none' ? 'arrow' : 'none',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase ArrowHandles.End: {\n\t\t\t\treturn {\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\t...shape.props,\n\t\t\t\t\t\tarrowheadEnd: shape.props.arrowheadEnd === 'none' ? 'arrow' : 'none',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tcomponent(shape: TLArrowShape) {\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst theme = useDefaultColorTheme()\n\t\tconst onlySelectedShape = this.editor.getOnlySelectedShape()\n\t\tconst shouldDisplayHandles =\n\t\t\tthis.editor.isInAny(\n\t\t\t\t'select.idle',\n\t\t\t\t'select.pointing_handle',\n\t\t\t\t'select.dragging_handle',\n\t\t\t\t'select.translating',\n\t\t\t\t'arrow.dragging'\n\t\t\t) && !this.editor.getIsReadonly()\n\n\t\tconst info = getArrowInfo(this.editor, shape)\n\t\tif (!info?.isValid) return null\n\n\t\tconst labelPosition = getArrowLabelPosition(this.editor, shape)\n\t\tconst isSelected = shape.id === this.editor.getOnlySelectedShapeId()\n\t\tconst isEditing = this.editor.getEditingShapeId() === shape.id\n\t\tconst showArrowLabel = isEditing || !isEmptyRichText(shape.props.richText)\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<SVGContainer style={{ minWidth: 50, minHeight: 50 }}>\n\t\t\t\t\t<ArrowSvg\n\t\t\t\t\t\tshape={shape}\n\t\t\t\t\t\tshouldDisplayHandles={shouldDisplayHandles && onlySelectedShape?.id === shape.id}\n\t\t\t\t\t/>\n\t\t\t\t\t{shape.props.kind === 'elbow' && debugFlags.debugElbowArrows.get() && (\n\t\t\t\t\t\t<ElbowArrowDebug arrow={shape} />\n\t\t\t\t\t)}\n\t\t\t\t</SVGContainer>\n\t\t\t\t{showArrowLabel && (\n\t\t\t\t\t<RichTextLabel\n\t\t\t\t\t\tshapeId={shape.id}\n\t\t\t\t\t\ttype=\"arrow\"\n\t\t\t\t\t\tfont={shape.props.font}\n\t\t\t\t\t\tfontSize={getArrowLabelFontSize(shape)}\n\t\t\t\t\t\tlineHeight={TEXT_PROPS.lineHeight}\n\t\t\t\t\t\talign=\"middle\"\n\t\t\t\t\t\tverticalAlign=\"middle\"\n\t\t\t\t\t\tlabelColor={getColorValue(theme, shape.props.labelColor, 'solid')}\n\t\t\t\t\t\trichText={shape.props.richText}\n\t\t\t\t\t\ttextWidth={labelPosition.box.w - ARROW_LABEL_PADDING * 2 * shape.props.scale}\n\t\t\t\t\t\tisSelected={isSelected}\n\t\t\t\t\t\tpadding={0}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\ttransform: `translate(${labelPosition.box.center.x}px, ${labelPosition.box.center.y}px)`,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</>\n\t\t)\n\t}\n\n\tindicator(shape: TLArrowShape) {\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst isEditing = useIsEditing(shape.id)\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst clipPathId = useSharedSafeId(shape.id + '_clip')\n\n\t\tconst info = getArrowInfo(this.editor, shape)\n\t\tif (!info) return null\n\n\t\tconst { start, end } = getArrowTerminalsInArrowSpace(this.editor, shape, info?.bindings)\n\t\tconst geometry = this.editor.getShapeGeometry<Group2d>(shape)\n\t\tconst bounds = geometry.bounds\n\t\tconst isEmpty = isEmptyRichText(shape.props.richText)\n\n\t\tconst labelGeometry = isEditing || !isEmpty ? (geometry.children[1] as Rectangle2d) : null\n\n\t\tif (Vec.Equals(start, end)) return null\n\n\t\tconst strokeWidth = STROKE_SIZES[shape.props.size] * shape.props.scale\n\n\t\tconst as = info.start.arrowhead && getArrowheadPathForType(info, 'start', strokeWidth)\n\t\tconst ae = info.end.arrowhead && getArrowheadPathForType(info, 'end', strokeWidth)\n\n\t\tconst includeClipPath =\n\t\t\t(as && info.start.arrowhead !== 'arrow') ||\n\t\t\t(ae && info.end.arrowhead !== 'arrow') ||\n\t\t\t!!labelGeometry\n\n\t\tconst labelBounds = labelGeometry ? labelGeometry.getBounds() : new Box(0, 0, 0, 0)\n\n\t\tif (isEditing && labelGeometry) {\n\t\t\treturn (\n\t\t\t\t<rect\n\t\t\t\t\tx={toDomPrecision(labelBounds.x)}\n\t\t\t\t\ty={toDomPrecision(labelBounds.y)}\n\t\t\t\t\twidth={labelBounds.w}\n\t\t\t\t\theight={labelBounds.h}\n\t\t\t\t\trx={3.5 * shape.props.scale}\n\t\t\t\t\try={3.5 * shape.props.scale}\n\t\t\t\t/>\n\t\t\t)\n\t\t}\n\t\tconst clipStartArrowhead = !(\n\t\t\tinfo.start.arrowhead === 'none' || info.start.arrowhead === 'arrow'\n\t\t)\n\t\tconst clipEndArrowhead = !(info.end.arrowhead === 'none' || info.end.arrowhead === 'arrow')\n\n\t\treturn (\n\t\t\t<g>\n\t\t\t\t{includeClipPath && (\n\t\t\t\t\t<defs>\n\t\t\t\t\t\t<ArrowClipPath\n\t\t\t\t\t\t\tradius={3.5 * shape.props.scale}\n\t\t\t\t\t\t\thasText={!isEmpty}\n\t\t\t\t\t\t\tbounds={bounds}\n\t\t\t\t\t\t\tlabelBounds={labelBounds}\n\t\t\t\t\t\t\tas={clipStartArrowhead && as ? as : ''}\n\t\t\t\t\t\t\tae={clipEndArrowhead && ae ? ae : ''}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</defs>\n\t\t\t\t)}\n\t\t\t\t<g\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tclipPath: includeClipPath ? `url(#${clipPathId})` : undefined,\n\t\t\t\t\t\tWebkitClipPath: includeClipPath ? `url(#${clipPathId})` : undefined,\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{/* This rect needs to be here if we're creating a mask due to an svg quirk on Chrome */}\n\t\t\t\t\t{includeClipPath && (\n\t\t\t\t\t\t<rect\n\t\t\t\t\t\t\tx={bounds.minX - 100}\n\t\t\t\t\t\t\ty={bounds.minY - 100}\n\t\t\t\t\t\t\twidth={bounds.width + 200}\n\t\t\t\t\t\t\theight={bounds.height + 200}\n\t\t\t\t\t\t\topacity={0}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{getArrowBodyPath(\n\t\t\t\t\t\tshape,\n\t\t\t\t\t\tinfo,\n\t\t\t\t\t\tshape.props.dash === 'draw'\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tstyle: 'draw',\n\t\t\t\t\t\t\t\t\trandomSeed: shape.id,\n\t\t\t\t\t\t\t\t\tstrokeWidth: 1,\n\t\t\t\t\t\t\t\t\tpasses: 1,\n\t\t\t\t\t\t\t\t\toffset: 0,\n\t\t\t\t\t\t\t\t\troundness: strokeWidth * 2,\n\t\t\t\t\t\t\t\t\tprops: { strokeWidth: undefined },\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: { style: 'solid', strokeWidth: 1, props: { strokeWidth: undefined } }\n\t\t\t\t\t)}\n\t\t\t\t</g>\n\t\t\t\t{as && <path d={as} />}\n\t\t\t\t{ae && <path d={ae} />}\n\t\t\t\t{labelGeometry && (\n\t\t\t\t\t<rect\n\t\t\t\t\t\tx={toDomPrecision(labelBounds.x)}\n\t\t\t\t\t\ty={toDomPrecision(labelBounds.y)}\n\t\t\t\t\t\twidth={labelBounds.w}\n\t\t\t\t\t\theight={labelBounds.h}\n\t\t\t\t\t\trx={3.5}\n\t\t\t\t\t\try={3.5}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride onEditStart(shape: TLArrowShape) {\n\t\tif (isEmptyRichText(shape.props.richText)) {\n\t\t\t// editing text for the first time, so set the position to the default:\n\t\t\tconst labelPosition = getArrowLabelDefaultPosition(this.editor, shape)\n\t\t\tthis.editor.updateShape({\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tprops: { labelPosition },\n\t\t\t})\n\t\t}\n\t}\n\n\toverride toSvg(shape: TLArrowShape, ctx: SvgExportContext) {\n\t\tctx.addExportDef(getFillDefForExport(shape.props.fill))\n\t\tconst theme = getDefaultColorTheme(ctx)\n\t\tconst scaleFactor = 1 / shape.props.scale\n\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<ArrowSvg shape={shape} shouldDisplayHandles={false} />\n\t\t\t\t<RichTextSVG\n\t\t\t\t\tfontSize={getArrowLabelFontSize(shape)}\n\t\t\t\t\tfont={shape.props.font}\n\t\t\t\t\talign=\"middle\"\n\t\t\t\t\tverticalAlign=\"middle\"\n\t\t\t\t\tlabelColor={getColorValue(theme, shape.props.labelColor, 'solid')}\n\t\t\t\t\trichText={shape.props.richText}\n\t\t\t\t\tbounds={getArrowLabelPosition(this.editor, shape)\n\t\t\t\t\t\t.box.clone()\n\t\t\t\t\t\t.expandBy(-ARROW_LABEL_PADDING * shape.props.scale)}\n\t\t\t\t\tpadding={0}\n\t\t\t\t\tshowTextOutline={true}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride getCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn [\n\t\t\tgetFillDefForCanvas(),\n\t\t\t{\n\t\t\t\tkey: `arrow:dot`,\n\t\t\t\tcomponent: ArrowheadDotDef,\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: `arrow:cross`,\n\t\t\t\tcomponent: ArrowheadCrossDef,\n\t\t\t},\n\t\t]\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLArrowShape,\n\t\tendShape: TLArrowShape,\n\t\tprogress: number\n\t): TLArrowShapeProps {\n\t\treturn {\n\t\t\t...(progress > 0.5 ? endShape.props : startShape.props),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, progress),\n\t\t\tstart: {\n\t\t\t\tx: lerp(startShape.props.start.x, endShape.props.start.x, progress),\n\t\t\t\ty: lerp(startShape.props.start.y, endShape.props.start.y, progress),\n\t\t\t},\n\t\t\tend: {\n\t\t\t\tx: lerp(startShape.props.end.x, endShape.props.end.x, progress),\n\t\t\t\ty: lerp(startShape.props.end.y, endShape.props.end.y, progress),\n\t\t\t},\n\t\t\tbend: lerp(startShape.props.bend, endShape.props.bend, progress),\n\t\t\tlabelPosition: lerp(startShape.props.labelPosition, endShape.props.labelPosition, progress),\n\t\t}\n\t}\n}\n\nexport function getArrowLength(editor: Editor, shape: TLArrowShape): number {\n\tconst info = getArrowInfo(editor, shape)!\n\n\treturn info.type === 'straight'\n\t\t? Vec.Dist(info.start.handle, info.end.handle)\n\t\t: info.type === 'arc'\n\t\t\t? Math.abs(info.handleArc.length)\n\t\t\t: info.route.distance\n}\n\nconst ArrowSvg = track(function ArrowSvg({\n\tshape,\n\tshouldDisplayHandles,\n}: {\n\tshape: TLArrowShape\n\tshouldDisplayHandles: boolean\n}) {\n\tconst editor = useEditor()\n\tconst theme = useDefaultColorTheme()\n\tconst info = getArrowInfo(editor, shape)\n\tconst isForceSolid = useEfficientZoomThreshold(shape.props.scale * 0.25)\n\tconst clipPathId = useSharedSafeId(shape.id + '_clip')\n\tconst arrowheadDotId = useSharedSafeId('arrowhead-dot')\n\tconst arrowheadCrossId = useSharedSafeId('arrowhead-cross')\n\tconst isEditing = useIsEditing(shape.id)\n\tconst geometry = editor.getShapeGeometry(shape)\n\tif (!geometry) return null\n\tconst bounds = Box.ZeroFix(geometry.bounds)\n\tconst bindings = getArrowBindings(editor, shape)\n\tconst isEmpty = isEmptyRichText(shape.props.richText)\n\n\tif (!info?.isValid) return null\n\n\tconst strokeWidth = STROKE_SIZES[shape.props.size] * shape.props.scale\n\n\tconst as = info.start.arrowhead && getArrowheadPathForType(info, 'start', strokeWidth)\n\tconst ae = info.end.arrowhead && getArrowheadPathForType(info, 'end', strokeWidth)\n\n\tlet handlePath: null | React.JSX.Element = null\n\n\tif (shouldDisplayHandles && (bindings.start || bindings.end)) {\n\t\thandlePath = getArrowHandlePath(info, {\n\t\t\tstyle: 'dashed',\n\t\t\tstart: 'skip',\n\t\t\tend: 'skip',\n\t\t\tlengthRatio: 2.5,\n\t\t\tstrokeWidth: 2 / editor.getEfficientZoomLevel(),\n\t\t\tprops: {\n\t\t\t\tclassName: 'tl-arrow-hint',\n\t\t\t\tmarkerStart: bindings.start\n\t\t\t\t\t? bindings.start.props.isExact\n\t\t\t\t\t\t? ''\n\t\t\t\t\t\t: bindings.start.props.isPrecise\n\t\t\t\t\t\t\t? `url(#${arrowheadCrossId})`\n\t\t\t\t\t\t\t: `url(#${arrowheadDotId})`\n\t\t\t\t\t: '',\n\t\t\t\tmarkerEnd: bindings.end\n\t\t\t\t\t? bindings.end.props.isExact\n\t\t\t\t\t\t? ''\n\t\t\t\t\t\t: bindings.end.props.isPrecise\n\t\t\t\t\t\t\t? `url(#${arrowheadCrossId})`\n\t\t\t\t\t\t\t: `url(#${arrowheadDotId})`\n\t\t\t\t\t: '',\n\t\t\t\topacity: 0.16,\n\t\t\t},\n\t\t})\n\t}\n\n\tconst labelPosition = getArrowLabelPosition(editor, shape)\n\n\tconst clipStartArrowhead = !(info.start.arrowhead === 'none' || info.start.arrowhead === 'arrow')\n\tconst clipEndArrowhead = !(info.end.arrowhead === 'none' || info.end.arrowhead === 'arrow')\n\n\treturn (\n\t\t<>\n\t\t\t{/* Yep */}\n\t\t\t<defs>\n\t\t\t\t<clipPath id={clipPathId}>\n\t\t\t\t\t<ArrowClipPath\n\t\t\t\t\t\tradius={3.5 * shape.props.scale}\n\t\t\t\t\t\thasText={isEditing || !isEmpty}\n\t\t\t\t\t\tbounds={bounds}\n\t\t\t\t\t\tlabelBounds={labelPosition.box}\n\t\t\t\t\t\tas={clipStartArrowhead && as ? as : ''}\n\t\t\t\t\t\tae={clipEndArrowhead && ae ? ae : ''}\n\t\t\t\t\t/>\n\t\t\t\t</clipPath>\n\t\t\t</defs>\n\t\t\t<g\n\t\t\t\tfill=\"none\"\n\t\t\t\tstroke={getColorValue(theme, shape.props.color, 'solid')}\n\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tpointerEvents=\"none\"\n\t\t\t>\n\t\t\t\t{handlePath}\n\t\t\t\t<g\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tclipPath: `url(#${clipPathId})`,\n\t\t\t\t\t\tWebkitClipPath: `url(#${clipPathId})`,\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<rect\n\t\t\t\t\t\tx={toDomPrecision(bounds.minX - 100)}\n\t\t\t\t\t\ty={toDomPrecision(bounds.minY - 100)}\n\t\t\t\t\t\twidth={toDomPrecision(bounds.width + 200)}\n\t\t\t\t\t\theight={toDomPrecision(bounds.height + 200)}\n\t\t\t\t\t\topacity={0}\n\t\t\t\t\t/>\n\t\t\t\t\t{getArrowBodyPath(shape, info, {\n\t\t\t\t\t\tstyle: shape.props.dash,\n\t\t\t\t\t\tstrokeWidth,\n\t\t\t\t\t\tforceSolid: isForceSolid,\n\t\t\t\t\t\trandomSeed: shape.id,\n\t\t\t\t\t})}\n\t\t\t\t</g>\n\t\t\t\t{as && clipStartArrowhead && shape.props.fill !== 'none' && (\n\t\t\t\t\t<ShapeFill\n\t\t\t\t\t\ttheme={theme}\n\t\t\t\t\t\td={as}\n\t\t\t\t\t\tcolor={shape.props.color}\n\t\t\t\t\t\tfill={shape.props.fill}\n\t\t\t\t\t\tscale={shape.props.scale}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t{ae && clipEndArrowhead && shape.props.fill !== 'none' && (\n\t\t\t\t\t<ShapeFill\n\t\t\t\t\t\ttheme={theme}\n\t\t\t\t\t\td={ae}\n\t\t\t\t\t\tcolor={shape.props.color}\n\t\t\t\t\t\tfill={shape.props.fill}\n\t\t\t\t\t\tscale={shape.props.scale}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t{as && <path d={as} />}\n\t\t\t\t{ae && <path d={ae} />}\n\t\t\t</g>\n\t\t</>\n\t)\n})\n\nfunction ArrowClipPath({\n\tradius,\n\thasText,\n\tbounds,\n\tlabelBounds,\n\tas,\n\tae,\n}: {\n\tradius: number\n\thasText: boolean\n\tbounds: Box\n\tlabelBounds: Box\n\tas: string\n\tae: string\n}) {\n\tconst path = useMemo(() => {\n\t\t// The direction in which we create the different path parts is important, as it determines what gets clipped.\n\t\t// See the description on the directions in the non-zero fill rule example:\n\t\t// https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule#nonzero\n\t\tconst path = new PathBuilder()\n\n\t\t// We create this one in the clockwise direction\n\t\tpath\n\t\t\t.moveTo(bounds.left - 100, bounds.top - 100)\n\t\t\t.lineTo(bounds.right + 100, bounds.top - 100)\n\t\t\t.lineTo(bounds.right + 100, bounds.bottom + 100)\n\t\t\t.lineTo(bounds.left - 100, bounds.bottom + 100)\n\t\t\t.close()\n\n\t\tif (hasText) {\n\t\t\t// We create this one in the counter-clockwise direction, which cuts out the label box\n\t\t\tpath\n\t\t\t\t.moveTo(labelBounds.left, labelBounds.top + radius)\n\t\t\t\t.lineTo(labelBounds.left, labelBounds.bottom - radius)\n\t\t\t\t.circularArcTo(radius, false, false, labelBounds.left + radius, labelBounds.bottom)\n\t\t\t\t.lineTo(labelBounds.right - radius, labelBounds.bottom)\n\t\t\t\t.circularArcTo(radius, false, false, labelBounds.right, labelBounds.bottom - radius)\n\t\t\t\t.lineTo(labelBounds.right, labelBounds.top + radius)\n\t\t\t\t.circularArcTo(radius, false, false, labelBounds.right - radius, labelBounds.top)\n\t\t\t\t.lineTo(labelBounds.left + radius, labelBounds.top)\n\t\t\t\t.circularArcTo(radius, false, false, labelBounds.left, labelBounds.top + radius)\n\t\t\t\t.close()\n\t\t}\n\n\t\treturn path.toD()\n\t}, [\n\t\tradius,\n\t\thasText,\n\t\tbounds.bottom,\n\t\tbounds.left,\n\t\tbounds.right,\n\t\tbounds.top,\n\t\tlabelBounds.bottom,\n\t\tlabelBounds.left,\n\t\tlabelBounds.right,\n\t\tlabelBounds.top,\n\t])\n\n\t// We also append the arrowhead paths to the clip path, so that we also clip the arrowheads\n\treturn <path d={`${path}${as}${ae}`} />\n}\n\nconst shapeAtTranslationStart = new WeakMap<\n\tTLArrowShape,\n\t{\n\t\tpagePosition: Vec\n\t\tterminalBindings: Record<\n\t\t\t'start' | 'end',\n\t\t\t{\n\t\t\t\tpagePosition: Vec\n\t\t\t\tshapePosition: Vec\n\t\t\t\tbinding: TLArrowBinding\n\t\t\t} | null\n\t\t>\n\t}\n>()\n\nfunction ArrowheadDotDef() {\n\tconst id = useSharedSafeId('arrowhead-dot')\n\treturn (\n\t\t<marker id={id} className=\"tl-arrow-hint\" refX=\"3.0\" refY=\"3.0\" orient=\"0\">\n\t\t\t<circle cx=\"3\" cy=\"3\" r=\"2\" strokeDasharray=\"100%\" />\n\t\t</marker>\n\t)\n}\n\nfunction ArrowheadCrossDef() {\n\tconst id = useSharedSafeId('arrowhead-cross')\n\treturn (\n\t\t<marker id={id} className=\"tl-arrow-hint\" refX=\"3.0\" refY=\"3.0\" orient=\"auto\">\n\t\t\t<line x1=\"1.5\" y1=\"1.5\" x2=\"4.5\" y2=\"4.5\" strokeDasharray=\"100%\" />\n\t\t\t<line x1=\"1.5\" y1=\"4.5\" x2=\"4.5\" y2=\"1.5\" strokeDasharray=\"100%\" />\n\t\t</marker>\n\t)\n}\n\n/**\n * Take 2 angles and return true if they are approximately parallel. Angle that point in the same\n * (or opposite) directions are considered parallel. This also handles wrap around - e.g. 0, \u03C0, and\n * 2\u03C0 are all considered parallel.\n */\nfunction anglesAreApproximatelyParallel(a: number, b: number, tolerance = 0.0001) {\n\tconst diff = Math.abs(a - b)\n\n\tconst isParallel = diff < tolerance\n\tconst isFlippedParallel = Math.abs(diff - Math.PI) < tolerance\n\tconst is360Parallel = Math.abs(diff - PI2) < tolerance\n\n\treturn { isParallel: isParallel || is360Parallel, isFlippedParallel }\n}\n"],
5
+ "mappings": "AAqwBG,mBAEE,KADD,YADD;AArwBH;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAGA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAaA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAgB,eAAe;AAC/B,SAAS,2BAA2B;AACpC,SAAS,iBAAiB,mCAAmC;AAC7D,SAAS,mBAAmB;AAC5B,SAAS,eAAe,mBAAmB;AAC3C,SAAS,iBAAiB;AAC1B,SAAS,qBAAqB,cAAc,kBAAkB;AAC9D,SAAS,qBAAqB,2BAA2B;AACzD,SAAS,4BAA4B;AACrC,SAAS,iCAAiC;AAC1C,SAAS,kBAAkB,0BAA0B;AAErD;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,8BAA8B;AACvC,SAAS,+BAA+B;AACxC,SAAS,uBAAuB;AAChC,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB,+BAA+B;AAChE;AAAA,EAEC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AAEP,IAAK,eAAL,kBAAKA,kBAAL;AACC,EAAAA,cAAA,WAAQ;AACR,EAAAA,cAAA,YAAS;AACT,EAAAA,cAAA,SAAM;AAHF,SAAAA;AAAA,GAAA;AAOE,MAAM,uBAAuB,UAAwB;AAAA,EAC3D,OAAgB,OAAO;AAAA,EACvB,OAAgB,QAAQ;AAAA,EACxB,OAAgB,aAAa;AAAA,EAEpB,UAA6B;AAAA,IACrC,sBAAsB;AAAA,MACrB,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,IAAI;AAAA,IACL;AAAA,IACA,mBAAmB;AAAA,MAClB,GAAG,aAAa,IAAI;AAAA,MACpB,GAAG,aAAa,IAAI;AAAA,MACpB,GAAG,aAAa,IAAI;AAAA,MACpB,IAAI,aAAa,KAAK;AAAA,IACvB;AAAA,IACA,wBAAwB;AAAA,IAExB,4BAA4B;AAAA,IAC5B,8BAA8B;AAAA,IAC9B,4BAA4B;AAAA,IAC5B,6BAA6B;AAAA,IAC7B,4BAA4B;AAAA,IAE5B,yBAAyB;AAAA,IAEzB,2BAA2B;AAAA,IAC3B,2CAA2C;AAAA,IAE3C,qBAAqB;AAAA,IACrB,wBAAwB;AAAA,IAExB,eAAe,CAAC,WAAmB,OAAO,OAAO;AAAA,IACjD,qBAAqB,CAAC,WAAmB,OAAO,OAAO;AAAA,EACxD;AAAA,EAES,UAAU;AAClB,WAAO;AAAA,EACR;AAAA,EACS,QAAQ,EAAE,YAAY,GAAkD;AAEhF,WAAO,gBAAgB;AAAA,EACxB;AAAA,EACS,UAAU;AAClB,WAAO;AAAA,EACR;AAAA,EACS,oBAAoB;AAC5B,WAAO;AAAA,EACR;AAAA,EACS,mBAAmB;AAC3B,WAAO;AAAA,EACR;AAAA,EACS,wBAAwB;AAChC,WAAO;AAAA,EACR;AAAA,EACS,wBAAwB;AAChC,WAAO;AAAA,EACR;AAAA,EACS,gBAAgB;AACxB,WAAO;AAAA,EACR;AAAA,EAES,aAAa,OAAqB,MAAmC;AAC7E,QAAI,KAAK,SAAS,QAAQ;AAEzB,YAAM,WAAW,iBAAiB,KAAK,QAAQ,KAAK;AACpD,YAAM,EAAE,OAAO,IAAI,IAAI;AACvB,YAAM,EAAE,SAAS,CAAC,EAAE,IAAI;AACxB,UAAI,SAAS,CAAC,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,IAAI,EAAG,QAAO;AAC9D,UAAI,OAAO,CAAC,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI,IAAI,EAAG,QAAO;AAAA,IAC3D;AACA,WAAO;AAAA,EACR;AAAA,EAES,aAAa,OAAqB;AAC1C,QAAI,gBAAgB,MAAM,MAAM,QAAQ,EAAG,QAAO;AAElD,WAAO,qBAAqB,KAAK,QAAQ,MAAM,MAAM,UAAU;AAAA,MAC9D,QAAQ,UAAU,MAAM,MAAM,IAAI;AAAA,MAClC,QAAQ;AAAA,MACR,OAAO;AAAA,IACR,CAAC;AAAA,EACF;AAAA,EAES,kBAAyC;AACjD,WAAO;AAAA,MACN,MAAM;AAAA,MACN,eAAe;AAAA,MACf,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,MAAM;AAAA,MACN,OAAO,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,MACpB,KAAK,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,MAClB,gBAAgB;AAAA,MAChB,cAAc;AAAA,MACd,UAAU,WAAW,EAAE;AAAA,MACvB,eAAe;AAAA,MACf,MAAM;AAAA,MACN,OAAO;AAAA,IACR;AAAA,EACD;AAAA,EAEA,YAAY,OAAqB;AAChC,UAAM,YAAY,KAAK,OAAO,kBAAkB,MAAM,MAAM;AAC5D,UAAM,OAAO,aAAa,KAAK,QAAQ,KAAK;AAE5C,UAAM,YAA0B,CAAC;AAEjC,UAAM,WACL,KAAK,SAAS,aACX,IAAI,OAAO;AAAA,MACX,OAAO,IAAI,KAAK,KAAK,MAAM,KAAK;AAAA,MAChC,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK;AAAA,IAC7B,CAAC,IACA,KAAK,SAAS,QACb,IAAI,MAAM;AAAA,MACV,QAAQ,IAAI,KAAK,KAAK,UAAU,MAAM;AAAA,MACtC,OAAO,IAAI,KAAK,KAAK,MAAM,KAAK;AAAA,MAChC,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK;AAAA,MAC5B,WAAW,KAAK,QAAQ;AAAA,MACxB,cAAc,KAAK,QAAQ;AAAA,IAC5B,CAAC,IACA,IAAI,WAAW,EAAE,QAAQ,KAAK,MAAM,OAAO,CAAC;AAEjD,QAAI;AACJ,QAAI,aAAa,CAAC,gBAAgB,MAAM,MAAM,QAAQ,GAAG;AACxD,YAAM,gBAAgB,sBAAsB,KAAK,QAAQ,KAAK;AAC9D,UAAI,WAAW,cAAc,IAAI,GAAG;AACnC,kBAAU,KAAK,GAAG,cAAc,SAAS;AAAA,MAC1C;AACA,kBAAY,IAAI,YAAY;AAAA,QAC3B,GAAG,cAAc,IAAI;AAAA,QACrB,GAAG,cAAc,IAAI;AAAA,QACrB,OAAO,cAAc,IAAI;AAAA,QACzB,QAAQ,cAAc,IAAI;AAAA,QAC1B,UAAU;AAAA,QACV,SAAS;AAAA,MACV,CAAC;AAAA,IACF;AAEA,WAAO,IAAI,QAAQ;AAAA,MAClB,UAAU,CAAC,GAAI,YAAY,CAAC,UAAU,SAAS,IAAI,CAAC,QAAQ,GAAI,GAAG,SAAS;AAAA,IAC7E,CAAC;AAAA,EACF;AAAA,EAES,WAAW,OAAiC;AACpD,UAAM,OAAO,aAAa,KAAK,QAAQ,KAAK;AAE5C,UAAM,UAAsB;AAAA,MAC3B;AAAA,QACC,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,QACP,GAAG,KAAK,MAAM,OAAO;AAAA,QACrB,GAAG,KAAK,MAAM,OAAO;AAAA,MACtB;AAAA,MACA;AAAA,QACC,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,QACP,GAAG,KAAK,IAAI,OAAO;AAAA,QACnB,GAAG,KAAK,IAAI,OAAO;AAAA,MACpB;AAAA,IACD;AAEA,QAAI,MAAM,MAAM,SAAS,UAAU,KAAK,SAAS,cAAc,KAAK,SAAS,QAAQ;AACpF,cAAQ,KAAK;AAAA,QACZ,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,QACP,GAAG,KAAK,OAAO;AAAA,QACf,GAAG,KAAK,OAAO;AAAA,MAChB,CAAC;AAAA,IACF;AAEA,QAAI,MAAM,MAAM,SAAS,WAAW,KAAK,SAAS,WAAW,KAAK,MAAM,gBAAgB;AACvF,YAAM,qBAAqB,KAAK,OAAO,sBAAsB,MAAM,EAAE;AAErE,YAAM,eAAe,mBAAmB,aAAa,KAAK,MAAM,eAAe,YAAY;AAC3F,YAAM,aAAa,mBAAmB,aAAa,KAAK,MAAM,eAAe,UAAU;AACvF,YAAM,gBAAgB,IAAI,KAAK,cAAc,UAAU,IAAI,KAAK,OAAO,sBAAsB;AAE7F,UAAI,gBAAgB,KAAK,QAAQ,2CAA2C;AAC3E,gBAAQ,KAAK;AAAA,UACZ,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,OAAO;AAAA,UACP,GAAG,KAAK,MAAM,eAAe,MAAM;AAAA,UACnC,GAAG,KAAK,MAAM,eAAe,MAAM;AAAA,QACpC,CAAC;AAAA,MACF;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA,EAES,QAAQ,OAAqB;AACrC,WAAO,4BAA4B,KAAK,QAAQ,MAAM,MAAM,QAAQ;AAAA,EACrE;AAAA,EAES,aAAa,OAAqB,MAAsC;AAChF,UAAM,WAAW,KAAK,OAAO;AAC7B,YAAQ,UAAU;AAAA,MACjB,KAAK;AACJ,gBAAQ,MAAM,MAAM,MAAM;AAAA,UACzB,KAAK;AACJ,mBAAO,KAAK,wBAAwB,OAAO,IAAI;AAAA,UAChD,KAAK;AACJ,mBAAO,KAAK,0BAA0B,OAAO,IAAI;AAAA,UAClD;AACC,kCAAsB,MAAM,MAAM,IAAI;AAAA,QACxC;AAAA,MACD,KAAK;AAAA,MACL,KAAK;AACJ,eAAO,KAAK,qBAAqB,OAAO,MAAM,QAAQ;AAAA,MACvD;AACC,8BAAsB,QAAQ;AAAA,IAChC;AAAA,EACD;AAAA,EAEQ,wBAAwB,OAAqB,EAAE,OAAO,GAAmC;AAChG,UAAM,WAAW,iBAAiB,KAAK,QAAQ,KAAK;AAGpD,UAAM,EAAE,OAAO,IAAI,IAAI,8BAA8B,KAAK,QAAQ,OAAO,QAAQ;AAEjF,UAAM,QAAQ,IAAI,IAAI,KAAK,KAAK;AAChC,UAAM,IAAI,IAAI,IAAI,KAAK;AAEvB,UAAM,MAAM,IAAI,IAAI,KAAK,KAAK;AAC9B,UAAM,IAAI,IAAI,IAAI,KAAK,CAAC;AACxB,UAAM,IAAI,IAAI,IAAI,KAAK,CAAC;AAExB,UAAM,QAAQ,IAAI,0BAA0B,GAAG,GAAG,QAAQ,KAAK;AAC/D,QAAI,OAAO,IAAI,KAAK,OAAO,GAAG;AAC9B,QAAI,IAAI,UAAU,OAAO,KAAK,GAAG,EAAG,SAAQ;AAC5C,WAAO,EAAE,IAAI,MAAM,IAAI,MAAM,MAAM,MAAM,OAAO,EAAE,KAAK,EAAE;AAAA,EAC1D;AAAA,EAEQ,0BACP,OACA,EAAE,OAAO,GACR;AACD,UAAM,OAAO,aAAa,KAAK,QAAQ,KAAK;AAC5C,QAAI,MAAM,SAAS,QAAS;AAE5B,UAAM,uBAAuB,KAAK,OAAO,sBAAsB,MAAM,EAAE;AACvE,UAAM,kBAAkB,qBAAqB,aAAa,MAAM;AAChE,UAAM,WAAW,KAAK,MAAM,gBAAgB;AAC5C,QAAI,CAAC,SAAU;AACf,UAAM,OAAO,eAAe,QAAQ;AAEpC,UAAM,WAAW,KAAK,MAAM,KAAK,QAAQ;AACzC,QAAI,CAAC,SAAU;AAIf,QAAI,QAAQ,IAAI;AAAA,MACf,qBAAqB,aAAa,KAAK,EAAE,GAAG,CAAC,CAAC;AAAA,MAC9C,qBAAqB,aAAa,KAAK,EAAE,GAAG,CAAC,CAAC;AAAA,IAC/C;AACA,QAAI,QAAQ,EAAG,UAAS,KAAK;AAI7B,UAAM,cAAc,wBAAwB,iBAAiB,KAAK;AAIlE,UAAM,UAAU;AAAA,MACf,qBAAqB,aAAa,KAAK,EAAE,SAAS,IAAI,CAAC,CAAC;AAAA,MACxD;AAAA,IACD;AACA,UAAM,UAAU;AAAA,MACf,qBAAqB,aAAa,KAAK,EAAE,SAAS,IAAI,CAAC,CAAC;AAAA,MACxD;AAAA,IACD;AAIA,UAAM,kBACL,KAAK,QAAQ,4BAA4B,KAAK,OAAO,sBAAsB;AAG5E,UAAM,WAAW;AAAA,MAChB,qBAAqB,aAAa,KAAK,EAAE,KAAK,SAAS,IAAI,SAAS,IAAI,GAAG,GAAG,CAAC,CAAC;AAAA,MAChF;AAAA,IACD;AAEA,QAAI,YAAY;AAChB,QAAI,eAAe,KAAK,IAAI,WAAW,WAAW;AAGlD,eAAW,CAAC,WAAW,SAAS,KAAK,uBAAuB,KAAK,MAAM,GAAG;AACzE,YAAM,EAAE,YAAY,kBAAkB,IAAI,+BAA+B,OAAO,SAAS;AACzF,UAAI,cAAc,mBAAmB;AACpC,mBAAW,YAAY,WAAW;AACjC,gBAAM,6BACL,SAAS,sBACR,SAAS,sBAAsB,KAAK,SAAS,OAAO,QACpD,SAAS,sBAAsB,KAAK,SAAS,KAAK;AAEpD,gBAAM,2BACL,SAAS,oBACR,SAAS,oBAAoB,KAAK,SAAS,OAAO,QAClD,SAAS,oBAAoB,KAAK,SAAS,KAAK;AAElD,cAAI,CAAC,8BAA8B,CAAC,yBAA0B;AAE9D,gBAAM,QAAQ,oBAAoB,CAAC,SAAS,eAAe,SAAS;AACpE,gBAAM,WAAW,KAAK,IAAI,QAAQ,WAAW;AAC7C,cAAI,WAAW,cAAc;AAC5B,wBAAY;AACZ,2BAAe;AAAA,UAChB;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,QAAI,eAAe,iBAAiB;AACnC,kBAAY;AAAA,IACb;AAEA,UAAM,SAAS,MAAM,QAAQ,SAAS,SAAS,SAAS,GAAG,GAAG,CAAC;AAE/D,WAAO;AAAA,MACN,IAAI,MAAM;AAAA,MACV,MAAM,MAAM;AAAA,MACZ,OAAO;AAAA,QACN,eAAe;AAAA,MAChB;AAAA,IACD;AAAA,EACD;AAAA,EAEQ,qBACP,OACA,EAAE,QAAQ,UAAU,GACpB,UACC;AACD,UAAM,WAAW,iBAAiB,KAAK,QAAQ,KAAK;AAEpD,UAAM,SAAuC,EAAE,IAAI,MAAM,IAAI,MAAM,SAAS,OAAO,CAAC,EAAE;AAEtF,UAAM,iBAAiB,SAAS,QAAQ;AAExC,UAAM,mBAAmB,aAAa,sBAAqB,kBAAmB;AAC9E,UAAM,kBAAkB,SAAS,gBAAgB;AAEjD,UAAM,aAAa,uBAAuB;AAAA,MACzC,QAAQ,KAAK;AAAA,MACb,kBAAkB,KAAK,OAAO,sBAAsB,MAAM,EAAE,EAAG,aAAa,MAAM;AAAA,MAClF,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,IACD,CAAC;AAED,QAAI,CAAC,YAAY;AAEhB,yBAAmB,KAAK,QAAQ,OAAO,QAAQ;AAC/C,YAAM,WAAW,gBAAgB,IAAI,IAAI,OAAO,GAAG,OAAO,CAAC,GAAG,KAAK,MAAM;AACzE,aAAO,MAAO,QAAQ,IAAI;AAAA,QACzB,GAAG,SAAS;AAAA,QACZ,GAAG,SAAS;AAAA,MACb;AACA,aAAO;AAAA,IACR;AAGA,UAAM,eAAoC;AAAA,MACzC,UAAU;AAAA,MACV,kBAAkB,WAAW;AAAA,MAC7B,WAAW,WAAW;AAAA,MACtB,SAAS,WAAW;AAAA,MACpB,MAAM,WAAW;AAAA,IAClB;AAEA,+BAA2B,KAAK,QAAQ,OAAO,WAAW,OAAO,IAAI,YAAY;AAEjF,UAAM,cAAc,iBAAiB,KAAK,QAAQ,KAAK;AACvD,QAAI,YAAY,SAAS,YAAY,OAAO,YAAY,MAAM,SAAS,YAAY,IAAI,MAAM;AAC5F,UACC,IAAI,OAAO,YAAY,MAAM,MAAM,kBAAkB,YAAY,IAAI,MAAM,gBAAgB,GAC1F;AACD,mCAA2B,KAAK,QAAQ,OAAO,YAAY,IAAI,MAAM;AAAA,UACpE,GAAG,YAAY,IAAI;AAAA,UACnB,kBAAkB;AAAA,YACjB,GAAG,YAAY,IAAI,MAAM,iBAAiB,IAAI;AAAA,YAC9C,GAAG,YAAY,IAAI,MAAM,iBAAiB;AAAA,UAC3C;AAAA,QACD,CAAC;AAAA,MACF;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA,EAES,iBAAiB,OAAqB;AAC9C,UAAM,WAAW,iBAAiB,KAAK,QAAQ,KAAK;AAGpD,QAAI,MAAM,MAAM,SAAS,WAAW,KAAK,OAAO,uBAAuB,MAAM,MAAM,IAAI;AACtF,YAAM,OAAO,aAAa,KAAK,QAAQ,KAAK;AAC5C,UAAI,CAAC,KAAM;AACX,YAAM,SAAuC,EAAE,IAAI,MAAM,IAAI,MAAM,SAAS,OAAO,CAAC,EAAE;AACtF,UAAI,SAAS,OAAO;AACnB,eAAO,MAAO,QAAQ,EAAE,GAAG,KAAK,MAAM,MAAM,GAAG,GAAG,KAAK,MAAM,MAAM,EAAE;AACrE,2BAAmB,KAAK,QAAQ,OAAO,OAAO;AAAA,MAC/C;AACA,UAAI,SAAS,KAAK;AACjB,eAAO,MAAO,MAAM,EAAE,GAAG,KAAK,IAAI,MAAM,GAAG,GAAG,KAAK,IAAI,MAAM,EAAE;AAC/D,2BAAmB,KAAK,QAAQ,OAAO,KAAK;AAAA,MAC7C;AACA,aAAO;AAAA,IACR;AAEA,UAAM,wBAAwB,8BAA8B,KAAK,QAAQ,OAAO,QAAQ;AACxF,UAAM,qBAAqB,KAAK,OAAO,sBAAsB,MAAM,EAAE;AAKrE,UAAM,mBAAmB,KAAK,OAAO,oBAAoB;AAEzD,QACE,SAAS,UACR,iBAAiB,SAAS,SAAS,MAAM,IAAI,KAC7C,KAAK,OAAO,mBAAmB,SAAS,MAAM,IAAI,MACnD,SAAS,QACR,iBAAiB,SAAS,SAAS,IAAI,IAAI,KAC3C,KAAK,OAAO,mBAAmB,SAAS,IAAI,IAAI,IACjD;AACD;AAAA,IACD;AAIA,4BAAwB,IAAI,OAAO;AAAA,MAClC,cAAc,mBAAmB,aAAa,KAAK;AAAA,MACnD,kBAAkB,mBAAmB,uBAAuB,CAAC,cAAc,UAAU;AACpF,cAAM,UAAU,SAAS,YAAY;AACrC,YAAI,CAAC,QAAS,QAAO;AACrB,eAAO;AAAA,UACN;AAAA,UACA,eAAe;AAAA,UACf,cAAc,mBAAmB,aAAa,KAAK;AAAA,QACpD;AAAA,MACD,CAAC;AAAA,IACF,CAAC;AAGD,QAAI,SAAS,OAAO;AACnB,0BAAoB;AAAA,QACnB,QAAQ,KAAK;AAAA,QACb,OAAO;AAAA,QACP,UAAU;AAAA,QACV,WAAW;AAAA,MACZ,CAAC;AACD,cAAQ,KAAK,OAAO,SAAS,MAAM,EAAE;AAAA,IACtC;AACA,QAAI,SAAS,KAAK;AACjB,0BAAoB;AAAA,QACnB,QAAQ,KAAK;AAAA,QACb,OAAO;AAAA,QACP,UAAU;AAAA,QACV,WAAW;AAAA,MACZ,CAAC;AAAA,IACF;AAEA,eAAW,cAAc,CAAC,qBAAoB,eAAgB,GAAY;AACzE,YAAM,UAAU,SAAS,UAAU;AACnC,UAAI,CAAC,QAAS;AAEd,WAAK,OAAO,cAAc;AAAA,QACzB,GAAG;AAAA,QACH,OAAO,EAAE,GAAG,QAAQ,OAAO,WAAW,KAAK;AAAA,MAC5C,CAAC;AAAA,IACF;AAEA;AAAA,EACD;AAAA,EAES,YAAY,cAA4B,OAAqB;AACrE,UAAM,qBAAqB,wBAAwB,IAAI,YAAY;AACnE,QAAI,CAAC,mBAAoB;AAEzB,UAAM,qBAAqB,KAAK,OAAO,sBAAsB,MAAM,EAAE;AACrE,UAAM,YAAY,IAAI;AAAA,MACrB,mBAAmB,aAAa,KAAK;AAAA,MACrC,mBAAmB;AAAA,IACpB;AAEA,eAAW,mBAAmB,OAAO,OAAO,mBAAmB,gBAAgB,GAAG;AACjF,UAAI,CAAC,gBAAiB;AAEtB,YAAM,eAAe,IAAI,IAAI,gBAAgB,cAAc,IAAI,IAAI,WAAW,GAAG,CAAC;AAClF,YAAM,YAAY,KAAK,OAAO,gBAAgB,cAAc;AAAA,QAC3D,WAAW;AAAA,QACX,gBAAgB;AAAA,QAChB,QAAQ;AAAA,QACR,QAAQ,CAAC,gBAAgB;AACxB,iBACC,CAAC,YAAY,YACb,KAAK,OAAO,cAAc,EAAE,WAAW,OAAO,SAAS,aAAa,SAAS,QAAQ,CAAC;AAAA,QAExF;AAAA,MACD,CAAC;AAED,UAAI,WAAW,OAAO,gBAAgB,QAAQ,MAAM;AACnD,cAAM,eAAe,IAAI,QAAQ,KAAK,OAAO,iBAAiB,SAAS,EAAE,MAAM;AAC/E,cAAM,qBAAqB,KAAK,OAAO,qBAAqB,WAAW,YAAY;AACnF,cAAM,mBAAmB;AAAA,UACxB,IAAI,mBAAmB,IAAI,aAAa,QAAQ,aAAa;AAAA,UAC7D,IAAI,mBAAmB,IAAI,aAAa,QAAQ,aAAa;AAAA,QAC9D;AACA,mCAA2B,KAAK,QAAQ,OAAO,UAAU,IAAI;AAAA,UAC5D,GAAG,gBAAgB,QAAQ;AAAA,UAC3B;AAAA,UACA,WAAW;AAAA,QACZ,CAAC;AAAA,MACF,OAAO;AACN,2BAAmB,KAAK,QAAQ,OAAO,gBAAgB,QAAQ,MAAM,QAAQ;AAAA,MAC9E;AAAA,IACD;AAAA,EACD;AAAA,EAEiB,yBAAyB,IAAI,UAAyC;AAAA,EAE9E,SAAS,OAAqB,MAAkC;AACxE,UAAM,EAAE,QAAQ,OAAO,IAAI;AAE3B,UAAM,WAAW,KAAK,uBAAuB;AAAA,MAAI;AAAA,MAAO,MACvD,iBAAiB,KAAK,QAAQ,KAAK;AAAA,IACpC;AACA,UAAM,YAAY,8BAA8B,KAAK,QAAQ,OAAO,QAAQ;AAE5E,UAAM,EAAE,OAAO,IAAI,IAAI,gBAAuC,MAAM,KAAK;AACzE,QAAI,EAAE,KAAK,IAAI,MAAM;AAGrB,QAAI,CAAC,SAAS,OAAO;AACpB,YAAM,IAAI,UAAU,MAAM,IAAI;AAC9B,YAAM,IAAI,UAAU,MAAM,IAAI;AAAA,IAC/B;AAGA,QAAI,CAAC,SAAS,KAAK;AAClB,UAAI,IAAI,UAAU,IAAI,IAAI;AAC1B,UAAI,IAAI,UAAU,IAAI,IAAI;AAAA,IAC3B;AAKA,UAAM,KAAK,KAAK,IAAI,MAAM;AAC1B,UAAM,KAAK,KAAK,IAAI,MAAM;AAE1B,UAAM,wBAAwB,UAAU,QACrC,IAAI,KAAK,SAAS,MAAM,MAAM,gBAAgB,IAC9C;AACH,UAAM,sBAAsB,UAAU,MAAM,IAAI,KAAK,SAAS,IAAI,MAAM,gBAAgB,IAAI;AAE5F,QAAI,SAAS,KAAK,UAAU,GAAG;AAC9B,UAAI,SAAS,GAAG;AACf,gBAAQ;AACR,gBAAQ,KAAK,IAAI,IAAI,EAAE;AAAA,MACxB;AAEA,UAAI,uBAAuB;AAC1B,8BAAsB,IAAI,IAAI,sBAAsB;AAAA,MACrD;AAEA,UAAI,qBAAqB;AACxB,4BAAoB,IAAI,IAAI,oBAAoB;AAAA,MACjD;AAAA,IACD,WAAW,UAAU,KAAK,SAAS,GAAG;AACrC,UAAI,SAAS,GAAG;AACf,gBAAQ;AACR,gBAAQ,KAAK,IAAI,IAAI,EAAE;AAAA,MACxB;AAEA,UAAI,uBAAuB;AAC1B,8BAAsB,IAAI,IAAI,sBAAsB;AAAA,MACrD;AAEA,UAAI,qBAAqB;AACxB,4BAAoB,IAAI,IAAI,oBAAoB;AAAA,MACjD;AAAA,IACD,WAAW,UAAU,KAAK,UAAU,GAAG;AACtC,UAAI,SAAS,GAAG;AACf,gBAAQ,KAAK,IAAI,IAAI,EAAE;AAAA,MACxB;AAAA,IACD,WAAW,SAAS,KAAK,SAAS,GAAG;AACpC,UAAI,SAAS,GAAG;AACf,gBAAQ,KAAK,IAAI,IAAI,EAAE;AAAA,MACxB;AAEA,UAAI,uBAAuB;AAC1B,8BAAsB,IAAI,IAAI,sBAAsB;AACpD,8BAAsB,IAAI,IAAI,sBAAsB;AAAA,MACrD;AAEA,UAAI,qBAAqB;AACxB,4BAAoB,IAAI,IAAI,oBAAoB;AAChD,4BAAoB,IAAI,IAAI,oBAAoB;AAAA,MACjD;AAAA,IACD;AAEA,QAAI,SAAS,SAAS,uBAAuB;AAC5C,iCAA2B,KAAK,QAAQ,OAAO,SAAS,MAAM,MAAM;AAAA,QACnE,GAAG,SAAS,MAAM;AAAA,QAClB,kBAAkB,sBAAsB,OAAO;AAAA,MAChD,CAAC;AAAA,IACF;AACA,QAAI,SAAS,OAAO,qBAAqB;AACxC,iCAA2B,KAAK,QAAQ,OAAO,SAAS,IAAI,MAAM;AAAA,QACjE,GAAG,SAAS,IAAI;AAAA,QAChB,kBAAkB,oBAAoB,OAAO;AAAA,MAC9C,CAAC;AAAA,IACF;AAEA,UAAM,OAAO;AAAA,MACZ,OAAO;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA,EAES,oBACR,OACA,QACsC;AACtC,YAAQ,OAAO,IAAI;AAAA,MAClB,KAAK,qBAAoB;AACxB,eAAO;AAAA,UACN,IAAI,MAAM;AAAA,UACV,MAAM,MAAM;AAAA,UACZ,OAAO;AAAA,YACN,GAAG,MAAM;AAAA,YACT,gBAAgB,MAAM,MAAM,mBAAmB,SAAS,UAAU;AAAA,UACnE;AAAA,QACD;AAAA,MACD;AAAA,MACA,KAAK,iBAAkB;AACtB,eAAO;AAAA,UACN,IAAI,MAAM;AAAA,UACV,MAAM,MAAM;AAAA,UACZ,OAAO;AAAA,YACN,GAAG,MAAM;AAAA,YACT,cAAc,MAAM,MAAM,iBAAiB,SAAS,UAAU;AAAA,UAC/D;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEA,UAAU,OAAqB;AAE9B,UAAM,QAAQ,qBAAqB;AACnC,UAAM,oBAAoB,KAAK,OAAO,qBAAqB;AAC3D,UAAM,uBACL,KAAK,OAAO;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD,KAAK,CAAC,KAAK,OAAO,cAAc;AAEjC,UAAM,OAAO,aAAa,KAAK,QAAQ,KAAK;AAC5C,QAAI,CAAC,MAAM,QAAS,QAAO;AAE3B,UAAM,gBAAgB,sBAAsB,KAAK,QAAQ,KAAK;AAC9D,UAAM,aAAa,MAAM,OAAO,KAAK,OAAO,uBAAuB;AACnE,UAAM,YAAY,KAAK,OAAO,kBAAkB,MAAM,MAAM;AAC5D,UAAM,iBAAiB,aAAa,CAAC,gBAAgB,MAAM,MAAM,QAAQ;AAEzE,WACC,iCACC;AAAA,2BAAC,gBAAa,OAAO,EAAE,UAAU,IAAI,WAAW,GAAG,GAClD;AAAA;AAAA,UAAC;AAAA;AAAA,YACA;AAAA,YACA,sBAAsB,wBAAwB,mBAAmB,OAAO,MAAM;AAAA;AAAA,QAC/E;AAAA,QACC,MAAM,MAAM,SAAS,WAAW,WAAW,iBAAiB,IAAI,KAChE,oBAAC,mBAAgB,OAAO,OAAO;AAAA,SAEjC;AAAA,MACC,kBACA;AAAA,QAAC;AAAA;AAAA,UACA,SAAS,MAAM;AAAA,UACf,MAAK;AAAA,UACL,MAAM,MAAM,MAAM;AAAA,UAClB,UAAU,sBAAsB,KAAK;AAAA,UACrC,YAAY,WAAW;AAAA,UACvB,OAAM;AAAA,UACN,eAAc;AAAA,UACd,YAAY,cAAc,OAAO,MAAM,MAAM,YAAY,OAAO;AAAA,UAChE,UAAU,MAAM,MAAM;AAAA,UACtB,WAAW,cAAc,IAAI,IAAI,sBAAsB,IAAI,MAAM,MAAM;AAAA,UACvE;AAAA,UACA,SAAS;AAAA,UACT,OAAO;AAAA,YACN,WAAW,aAAa,cAAc,IAAI,OAAO,CAAC,OAAO,cAAc,IAAI,OAAO,CAAC;AAAA,UACpF;AAAA;AAAA,MACD;AAAA,OAEF;AAAA,EAEF;AAAA,EAEA,UAAU,OAAqB;AAE9B,UAAM,YAAY,aAAa,MAAM,EAAE;AAEvC,UAAM,aAAa,gBAAgB,MAAM,KAAK,OAAO;AAErD,UAAM,OAAO,aAAa,KAAK,QAAQ,KAAK;AAC5C,QAAI,CAAC,KAAM,QAAO;AAElB,UAAM,EAAE,OAAO,IAAI,IAAI,8BAA8B,KAAK,QAAQ,OAAO,MAAM,QAAQ;AACvF,UAAM,WAAW,KAAK,OAAO,iBAA0B,KAAK;AAC5D,UAAM,SAAS,SAAS;AACxB,UAAM,UAAU,gBAAgB,MAAM,MAAM,QAAQ;AAEpD,UAAM,gBAAgB,aAAa,CAAC,UAAW,SAAS,SAAS,CAAC,IAAoB;AAEtF,QAAI,IAAI,OAAO,OAAO,GAAG,EAAG,QAAO;AAEnC,UAAM,cAAc,aAAa,MAAM,MAAM,IAAI,IAAI,MAAM,MAAM;AAEjE,UAAM,KAAK,KAAK,MAAM,aAAa,wBAAwB,MAAM,SAAS,WAAW;AACrF,UAAM,KAAK,KAAK,IAAI,aAAa,wBAAwB,MAAM,OAAO,WAAW;AAEjF,UAAM,kBACJ,MAAM,KAAK,MAAM,cAAc,WAC/B,MAAM,KAAK,IAAI,cAAc,WAC9B,CAAC,CAAC;AAEH,UAAM,cAAc,gBAAgB,cAAc,UAAU,IAAI,IAAI,IAAI,GAAG,GAAG,GAAG,CAAC;AAElF,QAAI,aAAa,eAAe;AAC/B,aACC;AAAA,QAAC;AAAA;AAAA,UACA,GAAG,eAAe,YAAY,CAAC;AAAA,UAC/B,GAAG,eAAe,YAAY,CAAC;AAAA,UAC/B,OAAO,YAAY;AAAA,UACnB,QAAQ,YAAY;AAAA,UACpB,IAAI,MAAM,MAAM,MAAM;AAAA,UACtB,IAAI,MAAM,MAAM,MAAM;AAAA;AAAA,MACvB;AAAA,IAEF;AACA,UAAM,qBAAqB,EAC1B,KAAK,MAAM,cAAc,UAAU,KAAK,MAAM,cAAc;AAE7D,UAAM,mBAAmB,EAAE,KAAK,IAAI,cAAc,UAAU,KAAK,IAAI,cAAc;AAEnF,WACC,qBAAC,OACC;AAAA,yBACA,oBAAC,UACA;AAAA,QAAC;AAAA;AAAA,UACA,QAAQ,MAAM,MAAM,MAAM;AAAA,UAC1B,SAAS,CAAC;AAAA,UACV;AAAA,UACA;AAAA,UACA,IAAI,sBAAsB,KAAK,KAAK;AAAA,UACpC,IAAI,oBAAoB,KAAK,KAAK;AAAA;AAAA,MACnC,GACD;AAAA,MAED;AAAA,QAAC;AAAA;AAAA,UACA,OAAO;AAAA,YACN,UAAU,kBAAkB,QAAQ,UAAU,MAAM;AAAA,YACpD,gBAAgB,kBAAkB,QAAQ,UAAU,MAAM;AAAA,UAC3D;AAAA,UAGC;AAAA,+BACA;AAAA,cAAC;AAAA;AAAA,gBACA,GAAG,OAAO,OAAO;AAAA,gBACjB,GAAG,OAAO,OAAO;AAAA,gBACjB,OAAO,OAAO,QAAQ;AAAA,gBACtB,QAAQ,OAAO,SAAS;AAAA,gBACxB,SAAS;AAAA;AAAA,YACV;AAAA,YAGA;AAAA,cACA;AAAA,cACA;AAAA,cACA,MAAM,MAAM,SAAS,SAClB;AAAA,gBACA,OAAO;AAAA,gBACP,YAAY,MAAM;AAAA,gBAClB,aAAa;AAAA,gBACb,QAAQ;AAAA,gBACR,QAAQ;AAAA,gBACR,WAAW,cAAc;AAAA,gBACzB,OAAO,EAAE,aAAa,OAAU;AAAA,cACjC,IACC,EAAE,OAAO,SAAS,aAAa,GAAG,OAAO,EAAE,aAAa,OAAU,EAAE;AAAA,YACxE;AAAA;AAAA;AAAA,MACD;AAAA,MACC,MAAM,oBAAC,UAAK,GAAG,IAAI;AAAA,MACnB,MAAM,oBAAC,UAAK,GAAG,IAAI;AAAA,MACnB,iBACA;AAAA,QAAC;AAAA;AAAA,UACA,GAAG,eAAe,YAAY,CAAC;AAAA,UAC/B,GAAG,eAAe,YAAY,CAAC;AAAA,UAC/B,OAAO,YAAY;AAAA,UACnB,QAAQ,YAAY;AAAA,UACpB,IAAI;AAAA,UACJ,IAAI;AAAA;AAAA,MACL;AAAA,OAEF;AAAA,EAEF;AAAA,EAES,YAAY,OAAqB;AACzC,QAAI,gBAAgB,MAAM,MAAM,QAAQ,GAAG;AAE1C,YAAM,gBAAgB,6BAA6B,KAAK,QAAQ,KAAK;AACrE,WAAK,OAAO,YAAY;AAAA,QACvB,IAAI,MAAM;AAAA,QACV,MAAM,MAAM;AAAA,QACZ,OAAO,EAAE,cAAc;AAAA,MACxB,CAAC;AAAA,IACF;AAAA,EACD;AAAA,EAES,MAAM,OAAqB,KAAuB;AAC1D,QAAI,aAAa,oBAAoB,MAAM,MAAM,IAAI,CAAC;AACtD,UAAM,QAAQ,qBAAqB,GAAG;AACtC,UAAM,cAAc,IAAI,MAAM,MAAM;AAEpC,WACC,qBAAC,OAAE,WAAW,SAAS,WAAW,KACjC;AAAA,0BAAC,YAAS,OAAc,sBAAsB,OAAO;AAAA,MACrD;AAAA,QAAC;AAAA;AAAA,UACA,UAAU,sBAAsB,KAAK;AAAA,UACrC,MAAM,MAAM,MAAM;AAAA,UAClB,OAAM;AAAA,UACN,eAAc;AAAA,UACd,YAAY,cAAc,OAAO,MAAM,MAAM,YAAY,OAAO;AAAA,UAChE,UAAU,MAAM,MAAM;AAAA,UACtB,QAAQ,sBAAsB,KAAK,QAAQ,KAAK,EAC9C,IAAI,MAAM,EACV,SAAS,CAAC,sBAAsB,MAAM,MAAM,KAAK;AAAA,UACnD,SAAS;AAAA,UACT,iBAAiB;AAAA;AAAA,MAClB;AAAA,OACD;AAAA,EAEF;AAAA,EAES,mBAA8C;AACtD,WAAO;AAAA,MACN,oBAAoB;AAAA,MACpB;AAAA,QACC,KAAK;AAAA,QACL,WAAW;AAAA,MACZ;AAAA,MACA;AAAA,QACC,KAAK;AAAA,QACL,WAAW;AAAA,MACZ;AAAA,IACD;AAAA,EACD;AAAA,EACS,qBACR,YACA,UACA,UACoB;AACpB,WAAO;AAAA,MACN,GAAI,WAAW,MAAM,SAAS,QAAQ,WAAW;AAAA,MACjD,OAAO,KAAK,WAAW,MAAM,OAAO,SAAS,MAAM,OAAO,QAAQ;AAAA,MAClE,OAAO;AAAA,QACN,GAAG,KAAK,WAAW,MAAM,MAAM,GAAG,SAAS,MAAM,MAAM,GAAG,QAAQ;AAAA,QAClE,GAAG,KAAK,WAAW,MAAM,MAAM,GAAG,SAAS,MAAM,MAAM,GAAG,QAAQ;AAAA,MACnE;AAAA,MACA,KAAK;AAAA,QACJ,GAAG,KAAK,WAAW,MAAM,IAAI,GAAG,SAAS,MAAM,IAAI,GAAG,QAAQ;AAAA,QAC9D,GAAG,KAAK,WAAW,MAAM,IAAI,GAAG,SAAS,MAAM,IAAI,GAAG,QAAQ;AAAA,MAC/D;AAAA,MACA,MAAM,KAAK,WAAW,MAAM,MAAM,SAAS,MAAM,MAAM,QAAQ;AAAA,MAC/D,eAAe,KAAK,WAAW,MAAM,eAAe,SAAS,MAAM,eAAe,QAAQ;AAAA,IAC3F;AAAA,EACD;AACD;AAEO,SAAS,eAAe,QAAgB,OAA6B;AAC3E,QAAM,OAAO,aAAa,QAAQ,KAAK;AAEvC,SAAO,KAAK,SAAS,aAClB,IAAI,KAAK,KAAK,MAAM,QAAQ,KAAK,IAAI,MAAM,IAC3C,KAAK,SAAS,QACb,KAAK,IAAI,KAAK,UAAU,MAAM,IAC9B,KAAK,MAAM;AAChB;AAEA,MAAM,WAAW,MAAM,SAASC,UAAS;AAAA,EACxC;AAAA,EACA;AACD,GAGG;AACF,QAAM,SAAS,UAAU;AACzB,QAAM,QAAQ,qBAAqB;AACnC,QAAM,OAAO,aAAa,QAAQ,KAAK;AACvC,QAAM,eAAe,0BAA0B,MAAM,MAAM,QAAQ,IAAI;AACvE,QAAM,aAAa,gBAAgB,MAAM,KAAK,OAAO;AACrD,QAAM,iBAAiB,gBAAgB,eAAe;AACtD,QAAM,mBAAmB,gBAAgB,iBAAiB;AAC1D,QAAM,YAAY,aAAa,MAAM,EAAE;AACvC,QAAM,WAAW,OAAO,iBAAiB,KAAK;AAC9C,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,SAAS,IAAI,QAAQ,SAAS,MAAM;AAC1C,QAAM,WAAW,iBAAiB,QAAQ,KAAK;AAC/C,QAAM,UAAU,gBAAgB,MAAM,MAAM,QAAQ;AAEpD,MAAI,CAAC,MAAM,QAAS,QAAO;AAE3B,QAAM,cAAc,aAAa,MAAM,MAAM,IAAI,IAAI,MAAM,MAAM;AAEjE,QAAM,KAAK,KAAK,MAAM,aAAa,wBAAwB,MAAM,SAAS,WAAW;AACrF,QAAM,KAAK,KAAK,IAAI,aAAa,wBAAwB,MAAM,OAAO,WAAW;AAEjF,MAAI,aAAuC;AAE3C,MAAI,yBAAyB,SAAS,SAAS,SAAS,MAAM;AAC7D,iBAAa,mBAAmB,MAAM;AAAA,MACrC,OAAO;AAAA,MACP,OAAO;AAAA,MACP,KAAK;AAAA,MACL,aAAa;AAAA,MACb,aAAa,IAAI,OAAO,sBAAsB;AAAA,MAC9C,OAAO;AAAA,QACN,WAAW;AAAA,QACX,aAAa,SAAS,QACnB,SAAS,MAAM,MAAM,UACpB,KACA,SAAS,MAAM,MAAM,YACpB,QAAQ,gBAAgB,MACxB,QAAQ,cAAc,MACxB;AAAA,QACH,WAAW,SAAS,MACjB,SAAS,IAAI,MAAM,UAClB,KACA,SAAS,IAAI,MAAM,YAClB,QAAQ,gBAAgB,MACxB,QAAQ,cAAc,MACxB;AAAA,QACH,SAAS;AAAA,MACV;AAAA,IACD,CAAC;AAAA,EACF;AAEA,QAAM,gBAAgB,sBAAsB,QAAQ,KAAK;AAEzD,QAAM,qBAAqB,EAAE,KAAK,MAAM,cAAc,UAAU,KAAK,MAAM,cAAc;AACzF,QAAM,mBAAmB,EAAE,KAAK,IAAI,cAAc,UAAU,KAAK,IAAI,cAAc;AAEnF,SACC,iCAEC;AAAA,wBAAC,UACA,8BAAC,cAAS,IAAI,YACb;AAAA,MAAC;AAAA;AAAA,QACA,QAAQ,MAAM,MAAM,MAAM;AAAA,QAC1B,SAAS,aAAa,CAAC;AAAA,QACvB;AAAA,QACA,aAAa,cAAc;AAAA,QAC3B,IAAI,sBAAsB,KAAK,KAAK;AAAA,QACpC,IAAI,oBAAoB,KAAK,KAAK;AAAA;AAAA,IACnC,GACD,GACD;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACA,MAAK;AAAA,QACL,QAAQ,cAAc,OAAO,MAAM,MAAM,OAAO,OAAO;AAAA,QACvD;AAAA,QACA,gBAAe;AAAA,QACf,eAAc;AAAA,QACd,eAAc;AAAA,QAEb;AAAA;AAAA,UACD;AAAA,YAAC;AAAA;AAAA,cACA,OAAO;AAAA,gBACN,UAAU,QAAQ,UAAU;AAAA,gBAC5B,gBAAgB,QAAQ,UAAU;AAAA,cACnC;AAAA,cAEA;AAAA;AAAA,kBAAC;AAAA;AAAA,oBACA,GAAG,eAAe,OAAO,OAAO,GAAG;AAAA,oBACnC,GAAG,eAAe,OAAO,OAAO,GAAG;AAAA,oBACnC,OAAO,eAAe,OAAO,QAAQ,GAAG;AAAA,oBACxC,QAAQ,eAAe,OAAO,SAAS,GAAG;AAAA,oBAC1C,SAAS;AAAA;AAAA,gBACV;AAAA,gBACC,iBAAiB,OAAO,MAAM;AAAA,kBAC9B,OAAO,MAAM,MAAM;AAAA,kBACnB;AAAA,kBACA,YAAY;AAAA,kBACZ,YAAY,MAAM;AAAA,gBACnB,CAAC;AAAA;AAAA;AAAA,UACF;AAAA,UACC,MAAM,sBAAsB,MAAM,MAAM,SAAS,UACjD;AAAA,YAAC;AAAA;AAAA,cACA;AAAA,cACA,GAAG;AAAA,cACH,OAAO,MAAM,MAAM;AAAA,cACnB,MAAM,MAAM,MAAM;AAAA,cAClB,OAAO,MAAM,MAAM;AAAA;AAAA,UACpB;AAAA,UAEA,MAAM,oBAAoB,MAAM,MAAM,SAAS,UAC/C;AAAA,YAAC;AAAA;AAAA,cACA;AAAA,cACA,GAAG;AAAA,cACH,OAAO,MAAM,MAAM;AAAA,cACnB,MAAM,MAAM,MAAM;AAAA,cAClB,OAAO,MAAM,MAAM;AAAA;AAAA,UACpB;AAAA,UAEA,MAAM,oBAAC,UAAK,GAAG,IAAI;AAAA,UACnB,MAAM,oBAAC,UAAK,GAAG,IAAI;AAAA;AAAA;AAAA,IACrB;AAAA,KACD;AAEF,CAAC;AAED,SAAS,cAAc;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAOG;AACF,QAAM,OAAO,QAAQ,MAAM;AAI1B,UAAMC,QAAO,IAAI,YAAY;AAG7B,IAAAA,MACE,OAAO,OAAO,OAAO,KAAK,OAAO,MAAM,GAAG,EAC1C,OAAO,OAAO,QAAQ,KAAK,OAAO,MAAM,GAAG,EAC3C,OAAO,OAAO,QAAQ,KAAK,OAAO,SAAS,GAAG,EAC9C,OAAO,OAAO,OAAO,KAAK,OAAO,SAAS,GAAG,EAC7C,MAAM;AAER,QAAI,SAAS;AAEZ,MAAAA,MACE,OAAO,YAAY,MAAM,YAAY,MAAM,MAAM,EACjD,OAAO,YAAY,MAAM,YAAY,SAAS,MAAM,EACpD,cAAc,QAAQ,OAAO,OAAO,YAAY,OAAO,QAAQ,YAAY,MAAM,EACjF,OAAO,YAAY,QAAQ,QAAQ,YAAY,MAAM,EACrD,cAAc,QAAQ,OAAO,OAAO,YAAY,OAAO,YAAY,SAAS,MAAM,EAClF,OAAO,YAAY,OAAO,YAAY,MAAM,MAAM,EAClD,cAAc,QAAQ,OAAO,OAAO,YAAY,QAAQ,QAAQ,YAAY,GAAG,EAC/E,OAAO,YAAY,OAAO,QAAQ,YAAY,GAAG,EACjD,cAAc,QAAQ,OAAO,OAAO,YAAY,MAAM,YAAY,MAAM,MAAM,EAC9E,MAAM;AAAA,IACT;AAEA,WAAOA,MAAK,IAAI;AAAA,EACjB,GAAG;AAAA,IACF;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,EACb,CAAC;AAGD,SAAO,oBAAC,UAAK,GAAG,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,IAAI;AACtC;AAEA,MAAM,0BAA0B,oBAAI,QAalC;AAEF,SAAS,kBAAkB;AAC1B,QAAM,KAAK,gBAAgB,eAAe;AAC1C,SACC,oBAAC,YAAO,IAAQ,WAAU,iBAAgB,MAAK,OAAM,MAAK,OAAM,QAAO,KACtE,8BAAC,YAAO,IAAG,KAAI,IAAG,KAAI,GAAE,KAAI,iBAAgB,QAAO,GACpD;AAEF;AAEA,SAAS,oBAAoB;AAC5B,QAAM,KAAK,gBAAgB,iBAAiB;AAC5C,SACC,qBAAC,YAAO,IAAQ,WAAU,iBAAgB,MAAK,OAAM,MAAK,OAAM,QAAO,QACtE;AAAA,wBAAC,UAAK,IAAG,OAAM,IAAG,OAAM,IAAG,OAAM,IAAG,OAAM,iBAAgB,QAAO;AAAA,IACjE,oBAAC,UAAK,IAAG,OAAM,IAAG,OAAM,IAAG,OAAM,IAAG,OAAM,iBAAgB,QAAO;AAAA,KAClE;AAEF;AAOA,SAAS,+BAA+B,GAAW,GAAW,YAAY,MAAQ;AACjF,QAAM,OAAO,KAAK,IAAI,IAAI,CAAC;AAE3B,QAAM,aAAa,OAAO;AAC1B,QAAM,oBAAoB,KAAK,IAAI,OAAO,KAAK,EAAE,IAAI;AACrD,QAAM,gBAAgB,KAAK,IAAI,OAAO,GAAG,IAAI;AAE7C,SAAO,EAAE,YAAY,cAAc,eAAe,kBAAkB;AACrE;",
6
6
  "names": ["ArrowHandles", "ArrowSvg", "path"]
7
7
  }
@@ -99,7 +99,7 @@ class DrawShapeUtil extends ShapeUtil {
99
99
  const forceSolid = useValue(
100
100
  "force solid",
101
101
  () => {
102
- const zoomLevel = this.editor.getZoomLevel();
102
+ const zoomLevel = this.editor.getEfficientZoomLevel();
103
103
  return zoomLevel < 0.5 && zoomLevel < 1.5 / sw;
104
104
  },
105
105
  [this.editor, sw]
@@ -170,7 +170,7 @@ function DrawShapeSvg({ shape, zoomOverride }) {
170
170
  const forceSolid = useValue(
171
171
  "force solid",
172
172
  () => {
173
- const zoomLevel = zoomOverride ?? editor.getZoomLevel();
173
+ const zoomLevel = zoomOverride ?? editor.getEfficientZoomLevel();
174
174
  return zoomLevel < 0.5 && zoomLevel < 1.5 / sw;
175
175
  },
176
176
  [editor, sw, zoomOverride]
@@ -178,7 +178,7 @@ function DrawShapeSvg({ shape, zoomOverride }) {
178
178
  const dotAdjustment = useValue(
179
179
  "dot adjustment",
180
180
  () => {
181
- const zoomLevel = zoomOverride ?? editor.getZoomLevel();
181
+ const zoomLevel = zoomOverride ?? editor.getEfficientZoomLevel();
182
182
  return zoomLevel < 0.2 ? 0 : 0.1;
183
183
  },
184
184
  [editor, zoomOverride]
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/draw/DrawShapeUtil.tsx"],
4
- "sourcesContent": ["import {\n\tBox,\n\tCircle2d,\n\tPolygon2d,\n\tPolyline2d,\n\tSVGContainer,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLDrawShape,\n\tTLDrawShapeProps,\n\tTLDrawShapeSegment,\n\tTLResizeInfo,\n\tTLShapeUtilCanvasSvgDef,\n\tVecLike,\n\tdrawShapeMigrations,\n\tdrawShapeProps,\n\tgetColorValue,\n\tlast,\n\tlerp,\n\trng,\n\ttoFixed,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport { ShapeFill } from '../shared/ShapeFill'\nimport { STROKE_SIZES } from '../shared/default-shape-constants'\nimport { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'\nimport { getStrokePoints } from '../shared/freehand/getStrokePoints'\nimport { getSvgPathFromStrokePoints } from '../shared/freehand/svg'\nimport { svgInk } from '../shared/freehand/svgInk'\nimport { interpolateSegments } from '../shared/interpolate-props'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport { getDrawShapeStrokeDashArray, getFreehandOptions, getPointsFromSegments } from './getPath'\n\n/** @public */\nexport interface DrawShapeOptions {\n\t/**\n\t * The maximum number of points in a line before the draw tool will begin a new shape.\n\t * A higher number will lead to poor performance while drawing very long lines.\n\t */\n\treadonly maxPointsPerShape: number\n}\n\n/** @public */\nexport class DrawShapeUtil extends ShapeUtil<TLDrawShape> {\n\tstatic override type = 'draw' as const\n\tstatic override props = drawShapeProps\n\tstatic override migrations = drawShapeMigrations\n\n\toverride options: DrawShapeOptions = {\n\t\tmaxPointsPerShape: 600,\n\t}\n\n\toverride hideResizeHandles(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideRotateHandle(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideSelectionBoundsFg(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\n\toverride getDefaultProps(): TLDrawShape['props'] {\n\t\treturn {\n\t\t\tsegments: [],\n\t\t\tcolor: 'black',\n\t\t\tfill: 'none',\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tisComplete: false,\n\t\t\tisClosed: false,\n\t\t\tisPen: false,\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLDrawShape) {\n\t\tconst points = getPointsFromSegments(shape.props.segments)\n\n\t\tconst sw = (STROKE_SIZES[shape.props.size] + 1) * shape.props.scale\n\n\t\t// A dot\n\t\tif (shape.props.segments.length === 1) {\n\t\t\tconst box = Box.FromPoints(points)\n\t\t\tif (box.width < sw * 2 && box.height < sw * 2) {\n\t\t\t\treturn new Circle2d({\n\t\t\t\t\tx: -sw,\n\t\t\t\t\ty: -sw,\n\t\t\t\t\tradius: sw,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst strokePoints = getStrokePoints(\n\t\t\tpoints,\n\t\t\tgetFreehandOptions(shape.props, sw, shape.props.isPen, true)\n\t\t).map((p) => p.point)\n\n\t\t// A closed draw stroke\n\t\tif (shape.props.isClosed && strokePoints.length > 2) {\n\t\t\treturn new Polygon2d({\n\t\t\t\tpoints: strokePoints,\n\t\t\t\tisFilled: shape.props.fill !== 'none',\n\t\t\t})\n\t\t}\n\n\t\tif (strokePoints.length === 1) {\n\t\t\treturn new Circle2d({\n\t\t\t\tx: -sw,\n\t\t\t\ty: -sw,\n\t\t\t\tradius: sw,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\t// An open draw stroke\n\t\treturn new Polyline2d({\n\t\t\tpoints: strokePoints,\n\t\t})\n\t}\n\n\tcomponent(shape: TLDrawShape) {\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<DrawShapeSvg shape={shape} />\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLDrawShape) {\n\t\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\n\t\tlet sw = (STROKE_SIZES[shape.props.size] + 1) * shape.props.scale\n\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst forceSolid = useValue(\n\t\t\t'force solid',\n\t\t\t() => {\n\t\t\t\tconst zoomLevel = this.editor.getZoomLevel()\n\t\t\t\treturn zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\t\t\t},\n\t\t\t[this.editor, sw]\n\t\t)\n\n\t\tif (\n\t\t\t!forceSolid &&\n\t\t\t!shape.props.isPen &&\n\t\t\tshape.props.dash === 'draw' &&\n\t\t\tallPointsFromSegments.length === 1\n\t\t) {\n\t\t\tsw += rng(shape.id)() * (sw / 6)\n\t\t}\n\n\t\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\t\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, true)\n\t\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\t\tconst solidStrokePath =\n\t\t\tstrokePoints.length > 1\n\t\t\t\t? getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed)\n\t\t\t\t: getDot(allPointsFromSegments[0], sw)\n\n\t\treturn <path d={solidStrokePath} />\n\t}\n\n\toverride toSvg(shape: TLDrawShape, ctx: SvgExportContext) {\n\t\tctx.addExportDef(getFillDefForExport(shape.props.fill))\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<DrawShapeSvg shape={shape} zoomOverride={1} />\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride getCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn [getFillDefForCanvas()]\n\t}\n\n\toverride onResize(shape: TLDrawShape, info: TLResizeInfo<TLDrawShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\tconst newSegments: TLDrawShapeSegment[] = []\n\n\t\tfor (const segment of shape.props.segments) {\n\t\t\tnewSegments.push({\n\t\t\t\t...segment,\n\t\t\t\tpoints: segment.points.map(({ x, y, z }) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tx: toFixed(scaleX * x),\n\t\t\t\t\t\ty: toFixed(scaleY * y),\n\t\t\t\t\t\tz,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t})\n\t\t}\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tsegments: newSegments,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride expandSelectionOutlinePx(shape: TLDrawShape): number {\n\t\tconst multiplier = shape.props.dash === 'draw' ? 1.6 : 1\n\t\treturn ((STROKE_SIZES[shape.props.size] * multiplier) / 2) * shape.props.scale\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLDrawShape,\n\t\tendShape: TLDrawShape,\n\t\tt: number\n\t): TLDrawShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tsegments: interpolateSegments(startShape.props.segments, endShape.props.segments, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction getDot(point: VecLike, sw: number) {\n\tconst r = (sw + 1) * 0.5\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getIsDot(shape: TLDrawShape) {\n\treturn shape.props.segments.length === 1 && shape.props.segments[0].points.length < 2\n}\n\nfunction DrawShapeSvg({ shape, zoomOverride }: { shape: TLDrawShape; zoomOverride?: number }) {\n\tconst theme = useDefaultColorTheme()\n\tconst editor = useEditor()\n\n\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\n\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\n\tlet sw = (STROKE_SIZES[shape.props.size] + 1) * shape.props.scale\n\tconst forceSolid = useValue(\n\t\t'force solid',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getZoomLevel()\n\t\t\treturn zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\t\t},\n\t\t[editor, sw, zoomOverride]\n\t)\n\n\tconst dotAdjustment = useValue(\n\t\t'dot adjustment',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getZoomLevel()\n\t\t\t// If we're zoomed way out (10%), then we need to make the dotted line go to 9 instead 0.1\n\t\t\t// Chrome doesn't render anything otherwise.\n\t\t\treturn zoomLevel < 0.2 ? 0 : 0.1\n\t\t},\n\t\t[editor, zoomOverride]\n\t)\n\n\tif (\n\t\t!forceSolid &&\n\t\t!shape.props.isPen &&\n\t\tshape.props.dash === 'draw' &&\n\t\tallPointsFromSegments.length === 1\n\t) {\n\t\tsw += rng(shape.id)() * (sw / 6)\n\t}\n\n\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, forceSolid)\n\n\tif (!forceSolid && shape.props.dash === 'draw') {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{shape.props.isClosed && shape.props.fill && allPointsFromSegments.length > 1 ? (\n\t\t\t\t\t<ShapeFill\n\t\t\t\t\t\td={getSvgPathFromStrokePoints(\n\t\t\t\t\t\t\tgetStrokePoints(allPointsFromSegments, options),\n\t\t\t\t\t\t\tshape.props.isClosed\n\t\t\t\t\t\t)}\n\t\t\t\t\t\ttheme={theme}\n\t\t\t\t\t\tcolor={shape.props.color}\n\t\t\t\t\t\tfill={shape.props.isClosed ? shape.props.fill : 'none'}\n\t\t\t\t\t\tscale={shape.props.scale}\n\t\t\t\t\t/>\n\t\t\t\t) : null}\n\t\t\t\t<path\n\t\t\t\t\td={svgInk(allPointsFromSegments, options)}\n\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\tfill={getColorValue(theme, shape.props.color, 'solid')}\n\t\t\t\t/>\n\t\t\t</>\n\t\t)\n\t}\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\tconst isDot = strokePoints.length < 2\n\tconst solidStrokePath = isDot\n\t\t? getDot(allPointsFromSegments[0], 0)\n\t\t: getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed)\n\n\treturn (\n\t\t<>\n\t\t\t<ShapeFill\n\t\t\t\td={solidStrokePath}\n\t\t\t\ttheme={theme}\n\t\t\t\tcolor={shape.props.color}\n\t\t\t\tfill={isDot || shape.props.isClosed ? shape.props.fill : 'none'}\n\t\t\t\tscale={shape.props.scale}\n\t\t\t/>\n\t\t\t<path\n\t\t\t\td={solidStrokePath}\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tfill={isDot ? getColorValue(theme, shape.props.color, 'solid') : 'none'}\n\t\t\t\tstroke={getColorValue(theme, shape.props.color, 'solid')}\n\t\t\t\tstrokeWidth={sw}\n\t\t\t\tstrokeDasharray={isDot ? 'none' : getDrawShapeStrokeDashArray(shape, sw, dotAdjustment)}\n\t\t\t\tstrokeDashoffset=\"0\"\n\t\t\t/>\n\t\t</>\n\t)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tBox,\n\tCircle2d,\n\tPolygon2d,\n\tPolyline2d,\n\tSVGContainer,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLDrawShape,\n\tTLDrawShapeProps,\n\tTLDrawShapeSegment,\n\tTLResizeInfo,\n\tTLShapeUtilCanvasSvgDef,\n\tVecLike,\n\tdrawShapeMigrations,\n\tdrawShapeProps,\n\tgetColorValue,\n\tlast,\n\tlerp,\n\trng,\n\ttoFixed,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport { ShapeFill } from '../shared/ShapeFill'\nimport { STROKE_SIZES } from '../shared/default-shape-constants'\nimport { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'\nimport { getStrokePoints } from '../shared/freehand/getStrokePoints'\nimport { getSvgPathFromStrokePoints } from '../shared/freehand/svg'\nimport { svgInk } from '../shared/freehand/svgInk'\nimport { interpolateSegments } from '../shared/interpolate-props'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport { getDrawShapeStrokeDashArray, getFreehandOptions, getPointsFromSegments } from './getPath'\n\n/** @public */\nexport interface DrawShapeOptions {\n\t/**\n\t * The maximum number of points in a line before the draw tool will begin a new shape.\n\t * A higher number will lead to poor performance while drawing very long lines.\n\t */\n\treadonly maxPointsPerShape: number\n}\n\n/** @public */\nexport class DrawShapeUtil extends ShapeUtil<TLDrawShape> {\n\tstatic override type = 'draw' as const\n\tstatic override props = drawShapeProps\n\tstatic override migrations = drawShapeMigrations\n\n\toverride options: DrawShapeOptions = {\n\t\tmaxPointsPerShape: 600,\n\t}\n\n\toverride hideResizeHandles(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideRotateHandle(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideSelectionBoundsFg(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\n\toverride getDefaultProps(): TLDrawShape['props'] {\n\t\treturn {\n\t\t\tsegments: [],\n\t\t\tcolor: 'black',\n\t\t\tfill: 'none',\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tisComplete: false,\n\t\t\tisClosed: false,\n\t\t\tisPen: false,\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLDrawShape) {\n\t\tconst points = getPointsFromSegments(shape.props.segments)\n\n\t\tconst sw = (STROKE_SIZES[shape.props.size] + 1) * shape.props.scale\n\n\t\t// A dot\n\t\tif (shape.props.segments.length === 1) {\n\t\t\tconst box = Box.FromPoints(points)\n\t\t\tif (box.width < sw * 2 && box.height < sw * 2) {\n\t\t\t\treturn new Circle2d({\n\t\t\t\t\tx: -sw,\n\t\t\t\t\ty: -sw,\n\t\t\t\t\tradius: sw,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst strokePoints = getStrokePoints(\n\t\t\tpoints,\n\t\t\tgetFreehandOptions(shape.props, sw, shape.props.isPen, true)\n\t\t).map((p) => p.point)\n\n\t\t// A closed draw stroke\n\t\tif (shape.props.isClosed && strokePoints.length > 2) {\n\t\t\treturn new Polygon2d({\n\t\t\t\tpoints: strokePoints,\n\t\t\t\tisFilled: shape.props.fill !== 'none',\n\t\t\t})\n\t\t}\n\n\t\tif (strokePoints.length === 1) {\n\t\t\treturn new Circle2d({\n\t\t\t\tx: -sw,\n\t\t\t\ty: -sw,\n\t\t\t\tradius: sw,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\t// An open draw stroke\n\t\treturn new Polyline2d({\n\t\t\tpoints: strokePoints,\n\t\t})\n\t}\n\n\tcomponent(shape: TLDrawShape) {\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<DrawShapeSvg shape={shape} />\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLDrawShape) {\n\t\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\n\t\tlet sw = (STROKE_SIZES[shape.props.size] + 1) * shape.props.scale\n\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst forceSolid = useValue(\n\t\t\t'force solid',\n\t\t\t() => {\n\t\t\t\tconst zoomLevel = this.editor.getEfficientZoomLevel()\n\t\t\t\treturn zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\t\t\t},\n\t\t\t[this.editor, sw]\n\t\t)\n\n\t\tif (\n\t\t\t!forceSolid &&\n\t\t\t!shape.props.isPen &&\n\t\t\tshape.props.dash === 'draw' &&\n\t\t\tallPointsFromSegments.length === 1\n\t\t) {\n\t\t\tsw += rng(shape.id)() * (sw / 6)\n\t\t}\n\n\t\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\t\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, true)\n\t\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\t\tconst solidStrokePath =\n\t\t\tstrokePoints.length > 1\n\t\t\t\t? getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed)\n\t\t\t\t: getDot(allPointsFromSegments[0], sw)\n\n\t\treturn <path d={solidStrokePath} />\n\t}\n\n\toverride toSvg(shape: TLDrawShape, ctx: SvgExportContext) {\n\t\tctx.addExportDef(getFillDefForExport(shape.props.fill))\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<DrawShapeSvg shape={shape} zoomOverride={1} />\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride getCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn [getFillDefForCanvas()]\n\t}\n\n\toverride onResize(shape: TLDrawShape, info: TLResizeInfo<TLDrawShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\tconst newSegments: TLDrawShapeSegment[] = []\n\n\t\tfor (const segment of shape.props.segments) {\n\t\t\tnewSegments.push({\n\t\t\t\t...segment,\n\t\t\t\tpoints: segment.points.map(({ x, y, z }) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tx: toFixed(scaleX * x),\n\t\t\t\t\t\ty: toFixed(scaleY * y),\n\t\t\t\t\t\tz,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t})\n\t\t}\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tsegments: newSegments,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride expandSelectionOutlinePx(shape: TLDrawShape): number {\n\t\tconst multiplier = shape.props.dash === 'draw' ? 1.6 : 1\n\t\treturn ((STROKE_SIZES[shape.props.size] * multiplier) / 2) * shape.props.scale\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLDrawShape,\n\t\tendShape: TLDrawShape,\n\t\tt: number\n\t): TLDrawShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tsegments: interpolateSegments(startShape.props.segments, endShape.props.segments, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction getDot(point: VecLike, sw: number) {\n\tconst r = (sw + 1) * 0.5\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getIsDot(shape: TLDrawShape) {\n\treturn shape.props.segments.length === 1 && shape.props.segments[0].points.length < 2\n}\n\nfunction DrawShapeSvg({ shape, zoomOverride }: { shape: TLDrawShape; zoomOverride?: number }) {\n\tconst theme = useDefaultColorTheme()\n\tconst editor = useEditor()\n\n\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\n\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\n\tlet sw = (STROKE_SIZES[shape.props.size] + 1) * shape.props.scale\n\tconst forceSolid = useValue(\n\t\t'force solid',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getEfficientZoomLevel()\n\t\t\treturn zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\t\t},\n\t\t[editor, sw, zoomOverride]\n\t)\n\n\tconst dotAdjustment = useValue(\n\t\t'dot adjustment',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getEfficientZoomLevel()\n\t\t\t// If we're zoomed way out (10%), then we need to make the dotted line go to 9 instead 0.1\n\t\t\t// Chrome doesn't render anything otherwise.\n\t\t\treturn zoomLevel < 0.2 ? 0 : 0.1\n\t\t},\n\t\t[editor, zoomOverride]\n\t)\n\n\tif (\n\t\t!forceSolid &&\n\t\t!shape.props.isPen &&\n\t\tshape.props.dash === 'draw' &&\n\t\tallPointsFromSegments.length === 1\n\t) {\n\t\tsw += rng(shape.id)() * (sw / 6)\n\t}\n\n\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, forceSolid)\n\n\tif (!forceSolid && shape.props.dash === 'draw') {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{shape.props.isClosed && shape.props.fill && allPointsFromSegments.length > 1 ? (\n\t\t\t\t\t<ShapeFill\n\t\t\t\t\t\td={getSvgPathFromStrokePoints(\n\t\t\t\t\t\t\tgetStrokePoints(allPointsFromSegments, options),\n\t\t\t\t\t\t\tshape.props.isClosed\n\t\t\t\t\t\t)}\n\t\t\t\t\t\ttheme={theme}\n\t\t\t\t\t\tcolor={shape.props.color}\n\t\t\t\t\t\tfill={shape.props.isClosed ? shape.props.fill : 'none'}\n\t\t\t\t\t\tscale={shape.props.scale}\n\t\t\t\t\t/>\n\t\t\t\t) : null}\n\t\t\t\t<path\n\t\t\t\t\td={svgInk(allPointsFromSegments, options)}\n\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\tfill={getColorValue(theme, shape.props.color, 'solid')}\n\t\t\t\t/>\n\t\t\t</>\n\t\t)\n\t}\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\tconst isDot = strokePoints.length < 2\n\tconst solidStrokePath = isDot\n\t\t? getDot(allPointsFromSegments[0], 0)\n\t\t: getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed)\n\n\treturn (\n\t\t<>\n\t\t\t<ShapeFill\n\t\t\t\td={solidStrokePath}\n\t\t\t\ttheme={theme}\n\t\t\t\tcolor={shape.props.color}\n\t\t\t\tfill={isDot || shape.props.isClosed ? shape.props.fill : 'none'}\n\t\t\t\tscale={shape.props.scale}\n\t\t\t/>\n\t\t\t<path\n\t\t\t\td={solidStrokePath}\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tfill={isDot ? getColorValue(theme, shape.props.color, 'solid') : 'none'}\n\t\t\t\tstroke={getColorValue(theme, shape.props.color, 'solid')}\n\t\t\t\tstrokeWidth={sw}\n\t\t\t\tstrokeDasharray={isDot ? 'none' : getDrawShapeStrokeDashArray(shape, sw, dotAdjustment)}\n\t\t\t\tstrokeDashoffset=\"0\"\n\t\t\t/>\n\t\t</>\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -79,7 +79,7 @@ class FrameShapeUtil extends BaseBoxShapeUtil {
79
79
  }
80
80
  getGeometry(shape) {
81
81
  const { editor } = this;
82
- const z = editor.getZoomLevel();
82
+ const z = editor.getEfficientZoomLevel();
83
83
  const labelSide = getFrameHeadingSide(editor, shape);
84
84
  const isVertical = labelSide % 2 === 1;
85
85
  const rotatedTopEdgeWidth = isVertical ? shape.props.h : shape.props.w;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/frame/FrameShapeUtil.tsx"],
4
- "sourcesContent": ["import {\n\tBaseBoxShapeUtil,\n\tDefaultColorStyle,\n\tGeometry2d,\n\tGroup2d,\n\tRectangle2d,\n\tSVGContainer,\n\tSvgExportContext,\n\tTLClickEventInfo,\n\tTLDragShapesOutInfo,\n\tTLDragShapesOverInfo,\n\tTLFrameShape,\n\tTLFrameShapeProps,\n\tTLResizeInfo,\n\tTLShape,\n\tTLShapePartial,\n\tTLShapeUtilConstructor,\n\tclamp,\n\tcompact,\n\tframeShapeMigrations,\n\tframeShapeProps,\n\tgetColorValue,\n\tgetDefaultColorTheme,\n\tlerp,\n\tresizeBox,\n\ttoDomPrecision,\n\tuseValue,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { fitFrameToContent, getFrameChildrenBounds } from '../../utils/frames/frames'\nimport {\n\tTLCreateTextJsxFromSpansOpts,\n\tcreateTextJsxFromSpans,\n} from '../shared/createTextJsxFromSpans'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport { FrameHeading } from './components/FrameHeading'\nimport {\n\tgetFrameHeadingOpts,\n\tgetFrameHeadingSide,\n\tgetFrameHeadingSize,\n\tgetFrameHeadingTranslation,\n} from './frameHelpers'\n\n// Some of these values are repeated in CSS and need to match\nconst FRAME_HEADING_EXTRA_WIDTH = 12\nconst FRAME_HEADING_MIN_WIDTH = 32\nconst FRAME_HEADING_NOCOLORS_OFFSET_X = -7\nconst FRAME_HEADING_OFFSET_Y = 4\n\n/** @public */\nexport interface FrameShapeOptions {\n\t/**\n\t * When true, the frame will display colors for the shape's headings and background.\n\t */\n\tshowColors: boolean\n}\n\nexport function defaultEmptyAs(str: string, dflt: string) {\n\tif (str.match(/^\\s*$/)) {\n\t\treturn dflt\n\t}\n\treturn str\n}\n\n/** @public */\nexport class FrameShapeUtil extends BaseBoxShapeUtil<TLFrameShape> {\n\tstatic override type = 'frame' as const\n\tstatic override props = frameShapeProps\n\tstatic override migrations = frameShapeMigrations\n\n\toverride options: FrameShapeOptions = {\n\t\tshowColors: false,\n\t}\n\n\t// evil crimes :)\n\t// By default, showColors is off. Because they use style props, which are picked up\n\t// automatically, we don't have DefaultColorStyle in the props in the schema by default.\n\t// Instead, when someone calls .configure to turn the option on, we manually add in the color\n\t// style here so it plays nicely with the other editor APIs.\n\tstatic override configure<T extends TLShapeUtilConstructor<any, any>>(\n\t\tthis: T,\n\t\toptions: T extends new (...args: any[]) => { options: infer Options } ? Partial<Options> : never\n\t): T {\n\t\tconst withOptions = super.configure.call(this, options) as T\n\t\tif ((options as any).showColors) {\n\t\t\t;(withOptions as any).props = { ...withOptions.props, color: DefaultColorStyle }\n\t\t}\n\t\treturn withOptions\n\t}\n\n\toverride canEdit() {\n\t\treturn true\n\t}\n\n\toverride canResize() {\n\t\treturn true\n\t}\n\n\toverride canResizeChildren() {\n\t\treturn false\n\t}\n\n\toverride isExportBoundsContainer(): boolean {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLFrameShape['props'] {\n\t\treturn { w: 160 * 2, h: 90 * 2, name: '', color: 'black' }\n\t}\n\n\toverride getAriaDescriptor(shape: TLFrameShape) {\n\t\treturn shape.props.name\n\t}\n\n\toverride getGeometry(shape: TLFrameShape): Geometry2d {\n\t\tconst { editor } = this\n\n\t\tconst z = editor.getZoomLevel()\n\n\t\t// Which dimension measures the top edge after rotation?\n\t\tconst labelSide = getFrameHeadingSide(editor, shape)\n\t\tconst isVertical = labelSide % 2 === 1\n\t\tconst rotatedTopEdgeWidth = isVertical ? shape.props.h : shape.props.w\n\n\t\t// Get the size of the heading (max width equal to the rotatedTopEdgeWidth)\n\t\tconst opts = getFrameHeadingOpts(rotatedTopEdgeWidth, false)\n\t\tconst headingSize = getFrameHeadingSize(editor, shape, opts)\n\n\t\t// If NOT showing frame colors, we need to offset the label\n\t\t// to the left so that the title is in line with the shape edge\n\t\t// and add that extra width to the right side of the label\n\t\tconst isShowingFrameColors = this.options.showColors\n\n\t\t// Scale everything into **screen space**\n\t\tconst extraWidth = FRAME_HEADING_EXTRA_WIDTH / z\n\t\tconst minWidth = FRAME_HEADING_MIN_WIDTH / z\n\t\tconst maxWidth = rotatedTopEdgeWidth + (isShowingFrameColors ? 1 : extraWidth)\n\n\t\tconst labelWidth = headingSize.w / z\n\t\tconst labelHeight = headingSize.h / z\n\n\t\tconst clampedLabelWidth = clamp(labelWidth + extraWidth, minWidth, maxWidth)\n\n\t\tconst offsetX = (isShowingFrameColors ? -1 : FRAME_HEADING_NOCOLORS_OFFSET_X) / z\n\t\tconst offsetY = FRAME_HEADING_OFFSET_Y / z\n\n\t\t// In page space\n\t\tconst width = isVertical ? labelHeight : clampedLabelWidth\n\t\tconst height = isVertical ? clampedLabelWidth : labelHeight\n\n\t\t// Calculate label position based on side. The position needs to always appear\n\t\t// at the top left of the shape, regardless of rotation. The label must be\n\t\t// between a minimum and maximum. The minimum is arbitrary; the maximum is the\n\t\t// width of the edge of the frame where the label will be shown.\n\n\t\tlet x: number, y: number\n\n\t\tswitch (labelSide) {\n\t\t\tcase 0: {\n\t\t\t\t// top\n\t\t\t\tx = offsetX\n\t\t\t\ty = -(labelHeight + offsetY)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 1: {\n\t\t\t\t// right\n\t\t\t\tx = -(labelHeight + offsetY)\n\t\t\t\ty = shape.props.h - (offsetX + clampedLabelWidth)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 2: {\n\t\t\t\t// bottom\n\t\t\t\tx = shape.props.w - (offsetX + clampedLabelWidth)\n\t\t\t\ty = shape.props.h + offsetY\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 3: {\n\t\t\t\t// left\n\t\t\t\tx = shape.props.w + offsetY\n\t\t\t\ty = offsetX\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn new Group2d({\n\t\t\tchildren: [\n\t\t\t\tnew Rectangle2d({\n\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\theight: shape.props.h,\n\t\t\t\t\tisFilled: false,\n\t\t\t\t}),\n\t\t\t\tnew Rectangle2d({\n\t\t\t\t\tx,\n\t\t\t\t\ty,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t\tisLabel: true,\n\t\t\t\t\texcludeFromShapeBounds: true,\n\t\t\t\t}),\n\t\t\t],\n\t\t})\n\t}\n\n\toverride getText(shape: TLFrameShape): string | undefined {\n\t\treturn shape.props.name\n\t}\n\n\toverride component(shape: TLFrameShape) {\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst theme = useDefaultColorTheme()\n\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst isCreating = useValue(\n\t\t\t'is creating this shape',\n\t\t\t() => {\n\t\t\t\tconst resizingState = this.editor.getStateDescendant('select.resizing')\n\t\t\t\tif (!resizingState) return false\n\t\t\t\tif (!resizingState.getIsActive()) return false\n\t\t\t\tconst info = (resizingState as typeof resizingState & { info: { isCreating: boolean } })\n\t\t\t\t\t?.info\n\t\t\t\tif (!info) return false\n\t\t\t\treturn info.isCreating && this.editor.getOnlySelectedShapeId() === shape.id\n\t\t\t},\n\t\t\t[shape.id]\n\t\t)\n\n\t\tconst showFrameColors = this.options.showColors\n\t\tconst colorToUse = showFrameColors ? shape.props.color : 'black'\n\t\tconst frameFill = getColorValue(theme, colorToUse, 'frameFill')\n\t\tconst frameStroke = getColorValue(theme, colorToUse, 'frameStroke')\n\t\tconst frameHeadingStroke = showFrameColors\n\t\t\t? getColorValue(theme, colorToUse, 'frameHeadingStroke')\n\t\t\t: theme.background\n\t\tconst frameHeadingFill = showFrameColors\n\t\t\t? getColorValue(theme, colorToUse, 'frameHeadingFill')\n\t\t\t: theme.background\n\t\tconst frameHeadingText = getColorValue(theme, colorToUse, 'frameText')\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<SVGContainer>\n\t\t\t\t\t<rect\n\t\t\t\t\t\tclassName={classNames('tl-frame__body', { 'tl-frame__creating': isCreating })}\n\t\t\t\t\t\tfill={frameFill}\n\t\t\t\t\t\tstroke={frameStroke}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\twidth: `calc(${shape.props.w}px + 1px / var(--tl-zoom))`,\n\t\t\t\t\t\t\theight: `calc(${shape.props.h}px + 1px / var(--tl-zoom))`,\n\t\t\t\t\t\t\ttransform: `translate(calc(-0.5px / var(--tl-zoom)), calc(-0.5px / var(--tl-zoom)))`,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</SVGContainer>\n\t\t\t\t{isCreating ? null : (\n\t\t\t\t\t<FrameHeading\n\t\t\t\t\t\tid={shape.id}\n\t\t\t\t\t\tname={shape.props.name}\n\t\t\t\t\t\tfill={frameHeadingFill}\n\t\t\t\t\t\tstroke={frameHeadingStroke}\n\t\t\t\t\t\tcolor={frameHeadingText}\n\t\t\t\t\t\twidth={shape.props.w}\n\t\t\t\t\t\theight={shape.props.h}\n\t\t\t\t\t\toffsetX={showFrameColors ? -1 : -7}\n\t\t\t\t\t\tshowColors={this.options.showColors}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</>\n\t\t)\n\t}\n\n\toverride toSvg(shape: TLFrameShape, ctx: SvgExportContext) {\n\t\tconst theme = getDefaultColorTheme({ isDarkMode: ctx.isDarkMode })\n\n\t\t// rotate right 45 deg\n\t\tconst labelSide = getFrameHeadingSide(this.editor, shape)\n\t\tconst isVertical = labelSide % 2 === 1\n\t\tconst rotatedTopEdgeWidth = isVertical ? shape.props.h : shape.props.w\n\t\tconst labelTranslate = getFrameHeadingTranslation(shape, labelSide, true)\n\n\t\t// Truncate with ellipsis\n\t\tconst opts: TLCreateTextJsxFromSpansOpts = getFrameHeadingOpts(rotatedTopEdgeWidth - 12, true)\n\n\t\tconst frameTitle = defaultEmptyAs(shape.props.name, 'Frame') + String.fromCharCode(8203)\n\t\tconst labelBounds = getFrameHeadingSize(this.editor, shape, opts)\n\t\tconst spans = this.editor.textMeasure.measureTextSpans(frameTitle, opts)\n\t\tconst text = createTextJsxFromSpans(this.editor, spans, opts)\n\n\t\tconst showFrameColors = this.options.showColors\n\t\tconst colorToUse = showFrameColors ? shape.props.color : 'black'\n\t\tconst frameFill = getColorValue(theme, colorToUse, 'frameFill')\n\t\tconst frameStroke = getColorValue(theme, colorToUse, 'frameStroke')\n\t\tconst frameHeadingStroke = showFrameColors\n\t\t\t? getColorValue(theme, colorToUse, 'frameHeadingStroke')\n\t\t\t: theme.background\n\t\tconst frameHeadingFill = showFrameColors\n\t\t\t? getColorValue(theme, colorToUse, 'frameHeadingFill')\n\t\t\t: theme.background\n\t\tconst frameHeadingText = getColorValue(theme, colorToUse, 'frameText')\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<rect\n\t\t\t\t\twidth={shape.props.w}\n\t\t\t\t\theight={shape.props.h}\n\t\t\t\t\tfill={frameFill}\n\t\t\t\t\tstroke={frameStroke}\n\t\t\t\t\tstrokeWidth={1}\n\t\t\t\t\tx={0}\n\t\t\t\t\trx={0}\n\t\t\t\t\try={0}\n\t\t\t\t/>\n\t\t\t\t<g fill={frameHeadingText} transform={labelTranslate}>\n\t\t\t\t\t<rect\n\t\t\t\t\t\tx={labelBounds.x - (showFrameColors ? 0 : 6)}\n\t\t\t\t\t\ty={labelBounds.y - 6}\n\t\t\t\t\t\twidth={Math.min(rotatedTopEdgeWidth, labelBounds.width + 12)}\n\t\t\t\t\t\theight={labelBounds.height}\n\t\t\t\t\t\tfill={frameHeadingFill}\n\t\t\t\t\t\tstroke={frameHeadingStroke}\n\t\t\t\t\t\trx={4}\n\t\t\t\t\t\try={4}\n\t\t\t\t\t/>\n\t\t\t\t\t<g transform={`translate(${showFrameColors ? 8 : 0}, 4)`}>{text}</g>\n\t\t\t\t</g>\n\t\t\t</>\n\t\t)\n\t}\n\n\tindicator(shape: TLFrameShape) {\n\t\treturn (\n\t\t\t<rect\n\t\t\t\twidth={toDomPrecision(shape.props.w)}\n\t\t\t\theight={toDomPrecision(shape.props.h)}\n\t\t\t\tclassName={`tl-frame-indicator`}\n\t\t\t/>\n\t\t)\n\t}\n\n\toverride providesBackgroundForChildren(): boolean {\n\t\treturn true\n\t}\n\n\toverride getClipPath(shape: TLFrameShape) {\n\t\treturn this.editor.getShapeGeometry(shape.id).vertices\n\t}\n\n\toverride canReceiveNewChildrenOfType(shape: TLShape) {\n\t\treturn !shape.isLocked\n\t}\n\n\toverride onResize(shape: any, info: TLResizeInfo<any>) {\n\t\treturn resizeBox(shape, info)\n\t}\n\n\toverride getInterpolatedProps(\n\t\tstartShape: TLFrameShape,\n\t\tendShape: TLFrameShape,\n\t\tt: number\n\t): TLFrameShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t}\n\t}\n\n\toverride onDoubleClickEdge(shape: TLFrameShape, info: TLClickEventInfo) {\n\t\tif (info.target !== 'selection') return\n\t\tconst { handle } = info\n\n\t\t// If handle is missing, we can't determine which edge was clicked\n\t\tif (!handle) return\n\n\t\tconst isHorizontalEdge = handle === 'left' || handle === 'right'\n\t\tconst isVerticalEdge = handle === 'top' || handle === 'bottom'\n\n\t\tconst childIds = this.editor.getSortedChildIdsForParent(shape.id)\n\t\tconst children = compact(childIds.map((id) => this.editor.getShape(id)))\n\t\tif (!children.length) return\n\n\t\tconst { dx, dy, w, h } = getFrameChildrenBounds(children, this.editor, { padding: 10 })\n\n\t\tthis.editor.run(() => {\n\t\t\tconst changes: TLShapePartial[] = childIds.map((childId) => {\n\t\t\t\tconst childShape = this.editor.getShape(childId)!\n\t\t\t\treturn {\n\t\t\t\t\tid: childShape.id,\n\t\t\t\t\ttype: childShape.type,\n\t\t\t\t\tx: isHorizontalEdge ? childShape.x + dx : childShape.x,\n\t\t\t\t\ty: isVerticalEdge ? childShape.y + dy : childShape.y,\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tthis.editor.updateShapes(changes)\n\t\t})\n\n\t\treturn {\n\t\t\tid: shape.id,\n\t\t\ttype: shape.type,\n\t\t\tprops: {\n\t\t\t\tw: isHorizontalEdge ? w : shape.props.w,\n\t\t\t\th: isVerticalEdge ? h : shape.props.h,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onDoubleClickCorner(shape: TLFrameShape) {\n\t\tfitFrameToContent(this.editor, shape.id, { padding: 10 })\n\t\treturn {\n\t\t\tid: shape.id,\n\t\t\ttype: shape.type,\n\t\t}\n\t}\n\n\toverride onDragShapesIn(\n\t\tshape: TLFrameShape,\n\t\tdraggingShapes: TLShape[],\n\t\t{ initialParentIds, initialIndices }: TLDragShapesOverInfo\n\t) {\n\t\tconst { editor } = this\n\n\t\tif (draggingShapes.every((s) => s.parentId === shape.id)) return\n\n\t\t// Check to see whether any of the shapes can have their old index restored\n\t\tlet canRestoreOriginalIndices = false\n\t\tconst previousChildren = draggingShapes.filter((s) => shape.id === initialParentIds.get(s.id))\n\n\t\tif (previousChildren.length > 0) {\n\t\t\tconst currentChildren = compact(\n\t\t\t\teditor.getSortedChildIdsForParent(shape).map((id) => editor.getShape(id))\n\t\t\t)\n\t\t\tif (previousChildren.every((s) => !currentChildren.find((c) => c.index === s.index))) {\n\t\t\t\tcanRestoreOriginalIndices = true\n\t\t\t}\n\t\t}\n\n\t\t// I can't imagine this happening, but if any of the children are the ancestor of the frame, quit here\n\t\tif (draggingShapes.some((s) => editor.hasAncestor(shape, s.id))) return\n\n\t\t// Reparent the shapes to the new parent\n\t\teditor.reparentShapes(draggingShapes, shape.id)\n\n\t\t// If we can restore the original indices, then do so\n\t\tif (canRestoreOriginalIndices) {\n\t\t\tfor (const shape of previousChildren) {\n\t\t\t\teditor.updateShape({\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tindex: initialIndices.get(shape.id),\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onDragShapesOut(\n\t\tshape: TLFrameShape,\n\t\tdraggingShapes: TLShape[],\n\t\tinfo: TLDragShapesOutInfo\n\t): void {\n\t\tconst { editor } = this\n\t\t// When a user drags shapes out of a frame, and if we're not dragging into a new shape, then reparent\n\t\t// the dragging shapes (that are current children of the frame) onto the current page instead\n\t\tif (!info.nextDraggingOverShapeId) {\n\t\t\teditor.reparentShapes(\n\t\t\t\tdraggingShapes.filter(\n\t\t\t\t\t(s) => s.parentId === shape.id && this.canReceiveNewChildrenOfType(s)\n\t\t\t\t),\n\t\t\t\teditor.getCurrentPageId()\n\t\t\t)\n\t\t}\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tBaseBoxShapeUtil,\n\tDefaultColorStyle,\n\tGeometry2d,\n\tGroup2d,\n\tRectangle2d,\n\tSVGContainer,\n\tSvgExportContext,\n\tTLClickEventInfo,\n\tTLDragShapesOutInfo,\n\tTLDragShapesOverInfo,\n\tTLFrameShape,\n\tTLFrameShapeProps,\n\tTLResizeInfo,\n\tTLShape,\n\tTLShapePartial,\n\tTLShapeUtilConstructor,\n\tclamp,\n\tcompact,\n\tframeShapeMigrations,\n\tframeShapeProps,\n\tgetColorValue,\n\tgetDefaultColorTheme,\n\tlerp,\n\tresizeBox,\n\ttoDomPrecision,\n\tuseValue,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { fitFrameToContent, getFrameChildrenBounds } from '../../utils/frames/frames'\nimport {\n\tTLCreateTextJsxFromSpansOpts,\n\tcreateTextJsxFromSpans,\n} from '../shared/createTextJsxFromSpans'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport { FrameHeading } from './components/FrameHeading'\nimport {\n\tgetFrameHeadingOpts,\n\tgetFrameHeadingSide,\n\tgetFrameHeadingSize,\n\tgetFrameHeadingTranslation,\n} from './frameHelpers'\n\n// Some of these values are repeated in CSS and need to match\nconst FRAME_HEADING_EXTRA_WIDTH = 12\nconst FRAME_HEADING_MIN_WIDTH = 32\nconst FRAME_HEADING_NOCOLORS_OFFSET_X = -7\nconst FRAME_HEADING_OFFSET_Y = 4\n\n/** @public */\nexport interface FrameShapeOptions {\n\t/**\n\t * When true, the frame will display colors for the shape's headings and background.\n\t */\n\tshowColors: boolean\n}\n\nexport function defaultEmptyAs(str: string, dflt: string) {\n\tif (str.match(/^\\s*$/)) {\n\t\treturn dflt\n\t}\n\treturn str\n}\n\n/** @public */\nexport class FrameShapeUtil extends BaseBoxShapeUtil<TLFrameShape> {\n\tstatic override type = 'frame' as const\n\tstatic override props = frameShapeProps\n\tstatic override migrations = frameShapeMigrations\n\n\toverride options: FrameShapeOptions = {\n\t\tshowColors: false,\n\t}\n\n\t// evil crimes :)\n\t// By default, showColors is off. Because they use style props, which are picked up\n\t// automatically, we don't have DefaultColorStyle in the props in the schema by default.\n\t// Instead, when someone calls .configure to turn the option on, we manually add in the color\n\t// style here so it plays nicely with the other editor APIs.\n\tstatic override configure<T extends TLShapeUtilConstructor<any, any>>(\n\t\tthis: T,\n\t\toptions: T extends new (...args: any[]) => { options: infer Options } ? Partial<Options> : never\n\t): T {\n\t\tconst withOptions = super.configure.call(this, options) as T\n\t\tif ((options as any).showColors) {\n\t\t\t;(withOptions as any).props = { ...withOptions.props, color: DefaultColorStyle }\n\t\t}\n\t\treturn withOptions\n\t}\n\n\toverride canEdit() {\n\t\treturn true\n\t}\n\n\toverride canResize() {\n\t\treturn true\n\t}\n\n\toverride canResizeChildren() {\n\t\treturn false\n\t}\n\n\toverride isExportBoundsContainer(): boolean {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLFrameShape['props'] {\n\t\treturn { w: 160 * 2, h: 90 * 2, name: '', color: 'black' }\n\t}\n\n\toverride getAriaDescriptor(shape: TLFrameShape) {\n\t\treturn shape.props.name\n\t}\n\n\toverride getGeometry(shape: TLFrameShape): Geometry2d {\n\t\tconst { editor } = this\n\n\t\tconst z = editor.getEfficientZoomLevel()\n\n\t\t// Which dimension measures the top edge after rotation?\n\t\tconst labelSide = getFrameHeadingSide(editor, shape)\n\t\tconst isVertical = labelSide % 2 === 1\n\t\tconst rotatedTopEdgeWidth = isVertical ? shape.props.h : shape.props.w\n\n\t\t// Get the size of the heading (max width equal to the rotatedTopEdgeWidth)\n\t\tconst opts = getFrameHeadingOpts(rotatedTopEdgeWidth, false)\n\t\tconst headingSize = getFrameHeadingSize(editor, shape, opts)\n\n\t\t// If NOT showing frame colors, we need to offset the label\n\t\t// to the left so that the title is in line with the shape edge\n\t\t// and add that extra width to the right side of the label\n\t\tconst isShowingFrameColors = this.options.showColors\n\n\t\t// Scale everything into **screen space**\n\t\tconst extraWidth = FRAME_HEADING_EXTRA_WIDTH / z\n\t\tconst minWidth = FRAME_HEADING_MIN_WIDTH / z\n\t\tconst maxWidth = rotatedTopEdgeWidth + (isShowingFrameColors ? 1 : extraWidth)\n\n\t\tconst labelWidth = headingSize.w / z\n\t\tconst labelHeight = headingSize.h / z\n\n\t\tconst clampedLabelWidth = clamp(labelWidth + extraWidth, minWidth, maxWidth)\n\n\t\tconst offsetX = (isShowingFrameColors ? -1 : FRAME_HEADING_NOCOLORS_OFFSET_X) / z\n\t\tconst offsetY = FRAME_HEADING_OFFSET_Y / z\n\n\t\t// In page space\n\t\tconst width = isVertical ? labelHeight : clampedLabelWidth\n\t\tconst height = isVertical ? clampedLabelWidth : labelHeight\n\n\t\t// Calculate label position based on side. The position needs to always appear\n\t\t// at the top left of the shape, regardless of rotation. The label must be\n\t\t// between a minimum and maximum. The minimum is arbitrary; the maximum is the\n\t\t// width of the edge of the frame where the label will be shown.\n\n\t\tlet x: number, y: number\n\n\t\tswitch (labelSide) {\n\t\t\tcase 0: {\n\t\t\t\t// top\n\t\t\t\tx = offsetX\n\t\t\t\ty = -(labelHeight + offsetY)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 1: {\n\t\t\t\t// right\n\t\t\t\tx = -(labelHeight + offsetY)\n\t\t\t\ty = shape.props.h - (offsetX + clampedLabelWidth)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 2: {\n\t\t\t\t// bottom\n\t\t\t\tx = shape.props.w - (offsetX + clampedLabelWidth)\n\t\t\t\ty = shape.props.h + offsetY\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 3: {\n\t\t\t\t// left\n\t\t\t\tx = shape.props.w + offsetY\n\t\t\t\ty = offsetX\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn new Group2d({\n\t\t\tchildren: [\n\t\t\t\tnew Rectangle2d({\n\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\theight: shape.props.h,\n\t\t\t\t\tisFilled: false,\n\t\t\t\t}),\n\t\t\t\tnew Rectangle2d({\n\t\t\t\t\tx,\n\t\t\t\t\ty,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t\tisLabel: true,\n\t\t\t\t\texcludeFromShapeBounds: true,\n\t\t\t\t}),\n\t\t\t],\n\t\t})\n\t}\n\n\toverride getText(shape: TLFrameShape): string | undefined {\n\t\treturn shape.props.name\n\t}\n\n\toverride component(shape: TLFrameShape) {\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst theme = useDefaultColorTheme()\n\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst isCreating = useValue(\n\t\t\t'is creating this shape',\n\t\t\t() => {\n\t\t\t\tconst resizingState = this.editor.getStateDescendant('select.resizing')\n\t\t\t\tif (!resizingState) return false\n\t\t\t\tif (!resizingState.getIsActive()) return false\n\t\t\t\tconst info = (resizingState as typeof resizingState & { info: { isCreating: boolean } })\n\t\t\t\t\t?.info\n\t\t\t\tif (!info) return false\n\t\t\t\treturn info.isCreating && this.editor.getOnlySelectedShapeId() === shape.id\n\t\t\t},\n\t\t\t[shape.id]\n\t\t)\n\n\t\tconst showFrameColors = this.options.showColors\n\t\tconst colorToUse = showFrameColors ? shape.props.color : 'black'\n\t\tconst frameFill = getColorValue(theme, colorToUse, 'frameFill')\n\t\tconst frameStroke = getColorValue(theme, colorToUse, 'frameStroke')\n\t\tconst frameHeadingStroke = showFrameColors\n\t\t\t? getColorValue(theme, colorToUse, 'frameHeadingStroke')\n\t\t\t: theme.background\n\t\tconst frameHeadingFill = showFrameColors\n\t\t\t? getColorValue(theme, colorToUse, 'frameHeadingFill')\n\t\t\t: theme.background\n\t\tconst frameHeadingText = getColorValue(theme, colorToUse, 'frameText')\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<SVGContainer>\n\t\t\t\t\t<rect\n\t\t\t\t\t\tclassName={classNames('tl-frame__body', { 'tl-frame__creating': isCreating })}\n\t\t\t\t\t\tfill={frameFill}\n\t\t\t\t\t\tstroke={frameStroke}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\twidth: `calc(${shape.props.w}px + 1px / var(--tl-zoom))`,\n\t\t\t\t\t\t\theight: `calc(${shape.props.h}px + 1px / var(--tl-zoom))`,\n\t\t\t\t\t\t\ttransform: `translate(calc(-0.5px / var(--tl-zoom)), calc(-0.5px / var(--tl-zoom)))`,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</SVGContainer>\n\t\t\t\t{isCreating ? null : (\n\t\t\t\t\t<FrameHeading\n\t\t\t\t\t\tid={shape.id}\n\t\t\t\t\t\tname={shape.props.name}\n\t\t\t\t\t\tfill={frameHeadingFill}\n\t\t\t\t\t\tstroke={frameHeadingStroke}\n\t\t\t\t\t\tcolor={frameHeadingText}\n\t\t\t\t\t\twidth={shape.props.w}\n\t\t\t\t\t\theight={shape.props.h}\n\t\t\t\t\t\toffsetX={showFrameColors ? -1 : -7}\n\t\t\t\t\t\tshowColors={this.options.showColors}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</>\n\t\t)\n\t}\n\n\toverride toSvg(shape: TLFrameShape, ctx: SvgExportContext) {\n\t\tconst theme = getDefaultColorTheme({ isDarkMode: ctx.isDarkMode })\n\n\t\t// rotate right 45 deg\n\t\tconst labelSide = getFrameHeadingSide(this.editor, shape)\n\t\tconst isVertical = labelSide % 2 === 1\n\t\tconst rotatedTopEdgeWidth = isVertical ? shape.props.h : shape.props.w\n\t\tconst labelTranslate = getFrameHeadingTranslation(shape, labelSide, true)\n\n\t\t// Truncate with ellipsis\n\t\tconst opts: TLCreateTextJsxFromSpansOpts = getFrameHeadingOpts(rotatedTopEdgeWidth - 12, true)\n\n\t\tconst frameTitle = defaultEmptyAs(shape.props.name, 'Frame') + String.fromCharCode(8203)\n\t\tconst labelBounds = getFrameHeadingSize(this.editor, shape, opts)\n\t\tconst spans = this.editor.textMeasure.measureTextSpans(frameTitle, opts)\n\t\tconst text = createTextJsxFromSpans(this.editor, spans, opts)\n\n\t\tconst showFrameColors = this.options.showColors\n\t\tconst colorToUse = showFrameColors ? shape.props.color : 'black'\n\t\tconst frameFill = getColorValue(theme, colorToUse, 'frameFill')\n\t\tconst frameStroke = getColorValue(theme, colorToUse, 'frameStroke')\n\t\tconst frameHeadingStroke = showFrameColors\n\t\t\t? getColorValue(theme, colorToUse, 'frameHeadingStroke')\n\t\t\t: theme.background\n\t\tconst frameHeadingFill = showFrameColors\n\t\t\t? getColorValue(theme, colorToUse, 'frameHeadingFill')\n\t\t\t: theme.background\n\t\tconst frameHeadingText = getColorValue(theme, colorToUse, 'frameText')\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<rect\n\t\t\t\t\twidth={shape.props.w}\n\t\t\t\t\theight={shape.props.h}\n\t\t\t\t\tfill={frameFill}\n\t\t\t\t\tstroke={frameStroke}\n\t\t\t\t\tstrokeWidth={1}\n\t\t\t\t\tx={0}\n\t\t\t\t\trx={0}\n\t\t\t\t\try={0}\n\t\t\t\t/>\n\t\t\t\t<g fill={frameHeadingText} transform={labelTranslate}>\n\t\t\t\t\t<rect\n\t\t\t\t\t\tx={labelBounds.x - (showFrameColors ? 0 : 6)}\n\t\t\t\t\t\ty={labelBounds.y - 6}\n\t\t\t\t\t\twidth={Math.min(rotatedTopEdgeWidth, labelBounds.width + 12)}\n\t\t\t\t\t\theight={labelBounds.height}\n\t\t\t\t\t\tfill={frameHeadingFill}\n\t\t\t\t\t\tstroke={frameHeadingStroke}\n\t\t\t\t\t\trx={4}\n\t\t\t\t\t\try={4}\n\t\t\t\t\t/>\n\t\t\t\t\t<g transform={`translate(${showFrameColors ? 8 : 0}, 4)`}>{text}</g>\n\t\t\t\t</g>\n\t\t\t</>\n\t\t)\n\t}\n\n\tindicator(shape: TLFrameShape) {\n\t\treturn (\n\t\t\t<rect\n\t\t\t\twidth={toDomPrecision(shape.props.w)}\n\t\t\t\theight={toDomPrecision(shape.props.h)}\n\t\t\t\tclassName={`tl-frame-indicator`}\n\t\t\t/>\n\t\t)\n\t}\n\n\toverride providesBackgroundForChildren(): boolean {\n\t\treturn true\n\t}\n\n\toverride getClipPath(shape: TLFrameShape) {\n\t\treturn this.editor.getShapeGeometry(shape.id).vertices\n\t}\n\n\toverride canReceiveNewChildrenOfType(shape: TLShape) {\n\t\treturn !shape.isLocked\n\t}\n\n\toverride onResize(shape: any, info: TLResizeInfo<any>) {\n\t\treturn resizeBox(shape, info)\n\t}\n\n\toverride getInterpolatedProps(\n\t\tstartShape: TLFrameShape,\n\t\tendShape: TLFrameShape,\n\t\tt: number\n\t): TLFrameShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t}\n\t}\n\n\toverride onDoubleClickEdge(shape: TLFrameShape, info: TLClickEventInfo) {\n\t\tif (info.target !== 'selection') return\n\t\tconst { handle } = info\n\n\t\t// If handle is missing, we can't determine which edge was clicked\n\t\tif (!handle) return\n\n\t\tconst isHorizontalEdge = handle === 'left' || handle === 'right'\n\t\tconst isVerticalEdge = handle === 'top' || handle === 'bottom'\n\n\t\tconst childIds = this.editor.getSortedChildIdsForParent(shape.id)\n\t\tconst children = compact(childIds.map((id) => this.editor.getShape(id)))\n\t\tif (!children.length) return\n\n\t\tconst { dx, dy, w, h } = getFrameChildrenBounds(children, this.editor, { padding: 10 })\n\n\t\tthis.editor.run(() => {\n\t\t\tconst changes: TLShapePartial[] = childIds.map((childId) => {\n\t\t\t\tconst childShape = this.editor.getShape(childId)!\n\t\t\t\treturn {\n\t\t\t\t\tid: childShape.id,\n\t\t\t\t\ttype: childShape.type,\n\t\t\t\t\tx: isHorizontalEdge ? childShape.x + dx : childShape.x,\n\t\t\t\t\ty: isVerticalEdge ? childShape.y + dy : childShape.y,\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tthis.editor.updateShapes(changes)\n\t\t})\n\n\t\treturn {\n\t\t\tid: shape.id,\n\t\t\ttype: shape.type,\n\t\t\tprops: {\n\t\t\t\tw: isHorizontalEdge ? w : shape.props.w,\n\t\t\t\th: isVerticalEdge ? h : shape.props.h,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onDoubleClickCorner(shape: TLFrameShape) {\n\t\tfitFrameToContent(this.editor, shape.id, { padding: 10 })\n\t\treturn {\n\t\t\tid: shape.id,\n\t\t\ttype: shape.type,\n\t\t}\n\t}\n\n\toverride onDragShapesIn(\n\t\tshape: TLFrameShape,\n\t\tdraggingShapes: TLShape[],\n\t\t{ initialParentIds, initialIndices }: TLDragShapesOverInfo\n\t) {\n\t\tconst { editor } = this\n\n\t\tif (draggingShapes.every((s) => s.parentId === shape.id)) return\n\n\t\t// Check to see whether any of the shapes can have their old index restored\n\t\tlet canRestoreOriginalIndices = false\n\t\tconst previousChildren = draggingShapes.filter((s) => shape.id === initialParentIds.get(s.id))\n\n\t\tif (previousChildren.length > 0) {\n\t\t\tconst currentChildren = compact(\n\t\t\t\teditor.getSortedChildIdsForParent(shape).map((id) => editor.getShape(id))\n\t\t\t)\n\t\t\tif (previousChildren.every((s) => !currentChildren.find((c) => c.index === s.index))) {\n\t\t\t\tcanRestoreOriginalIndices = true\n\t\t\t}\n\t\t}\n\n\t\t// I can't imagine this happening, but if any of the children are the ancestor of the frame, quit here\n\t\tif (draggingShapes.some((s) => editor.hasAncestor(shape, s.id))) return\n\n\t\t// Reparent the shapes to the new parent\n\t\teditor.reparentShapes(draggingShapes, shape.id)\n\n\t\t// If we can restore the original indices, then do so\n\t\tif (canRestoreOriginalIndices) {\n\t\t\tfor (const shape of previousChildren) {\n\t\t\t\teditor.updateShape({\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tindex: initialIndices.get(shape.id),\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onDragShapesOut(\n\t\tshape: TLFrameShape,\n\t\tdraggingShapes: TLShape[],\n\t\tinfo: TLDragShapesOutInfo\n\t): void {\n\t\tconst { editor } = this\n\t\t// When a user drags shapes out of a frame, and if we're not dragging into a new shape, then reparent\n\t\t// the dragging shapes (that are current children of the frame) onto the current page instead\n\t\tif (!info.nextDraggingOverShapeId) {\n\t\t\teditor.reparentShapes(\n\t\t\t\tdraggingShapes.filter(\n\t\t\t\t\t(s) => s.parentId === shape.id && this.canReceiveNewChildrenOfType(s)\n\t\t\t\t),\n\t\t\t\teditor.getCurrentPageId()\n\t\t\t)\n\t\t}\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["shape"]
7
7
  }
@@ -36,6 +36,7 @@ import {
36
36
  import { getFillDefForCanvas, getFillDefForExport } from "../shared/defaultStyleDefs.mjs";
37
37
  import { useDefaultColorTheme } from "../shared/useDefaultColorTheme.mjs";
38
38
  import { useIsReadyForEditing } from "../shared/useEditablePlainText.mjs";
39
+ import { useEfficientZoomThreshold } from "../shared/useEfficientZoomThreshold.mjs";
39
40
  import { GeoShapeBody } from "./components/GeoShapeBody.mjs";
40
41
  import { getGeoShapePath } from "./getGeoShapePath.mjs";
41
42
  const MIN_SIZE_WITH_LABEL = 17 * 3;
@@ -158,7 +159,7 @@ class GeoShapeUtil extends BaseBoxShapeUtil {
158
159
  const isReadyForEditing = useIsReadyForEditing(editor, shape.id);
159
160
  const isEmpty = isEmptyRichText(shape.props.richText);
160
161
  const showHtmlContainer = isReadyForEditing || !isEmpty;
161
- const isForceSolid = useValue("force solid", () => editor.getZoomLevel() < 0.2, [editor]);
162
+ const isForceSolid = useEfficientZoomThreshold(shape.props.scale * 0.25);
162
163
  return /* @__PURE__ */ jsxs(Fragment, { children: [
163
164
  /* @__PURE__ */ jsx(SVGContainer, { children: /* @__PURE__ */ jsx(GeoShapeBody, { shape, shouldScale: true, forceSolid: isForceSolid }) }),
164
165
  showHtmlContainer && /* @__PURE__ */ jsx(
@@ -193,9 +194,7 @@ class GeoShapeUtil extends BaseBoxShapeUtil {
193
194
  ] });
194
195
  }
195
196
  indicator(shape) {
196
- const isZoomedOut = useValue("isZoomedOut", () => this.editor.getZoomLevel() < 0.25, [
197
- this.editor
198
- ]);
197
+ const isZoomedOut = useEfficientZoomThreshold(shape.props.scale * 0.25);
199
198
  const { size, dash, scale } = shape.props;
200
199
  const strokeWidth = STROKE_SIZES[size];
201
200
  const path = getGeoShapePath(shape);