@tldraw/editor 3.12.0-canary.a6c2905c622f → 3.12.0-canary.a880bf3ec9cb

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 (131) hide show
  1. package/dist-cjs/index.d.ts +158 -17
  2. package/dist-cjs/index.js +3 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/TldrawEditor.js +5 -0
  5. package/dist-cjs/lib/TldrawEditor.js.map +2 -2
  6. package/dist-cjs/lib/components/GeometryDebuggingView.js +2 -2
  7. package/dist-cjs/lib/components/GeometryDebuggingView.js.map +2 -2
  8. package/dist-cjs/lib/components/Shape.js +10 -14
  9. package/dist-cjs/lib/components/Shape.js.map +2 -2
  10. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +10 -1
  11. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  12. package/dist-cjs/lib/editor/Editor.js +224 -32
  13. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  14. package/dist-cjs/lib/editor/derivations/notVisibleShapes.js +1 -1
  15. package/dist-cjs/lib/editor/derivations/notVisibleShapes.js.map +2 -2
  16. package/dist-cjs/lib/editor/managers/FocusManager.js +1 -1
  17. package/dist-cjs/lib/editor/managers/FocusManager.js.map +2 -2
  18. package/dist-cjs/lib/editor/managers/FontManager.js +1 -1
  19. package/dist-cjs/lib/editor/managers/FontManager.js.map +2 -2
  20. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +12 -0
  21. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  22. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +4 -13
  23. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
  24. package/dist-cjs/lib/editor/tools/StateNode.js +4 -1
  25. package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
  26. package/dist-cjs/lib/editor/types/selection-types.js.map +1 -1
  27. package/dist-cjs/lib/exports/StyleEmbedder.js +19 -5
  28. package/dist-cjs/lib/exports/StyleEmbedder.js.map +2 -2
  29. package/dist-cjs/lib/exports/cssRules.js +127 -0
  30. package/dist-cjs/lib/exports/cssRules.js.map +7 -0
  31. package/dist-cjs/lib/exports/parseCss.js +0 -69
  32. package/dist-cjs/lib/exports/parseCss.js.map +2 -2
  33. package/dist-cjs/lib/hooks/useCanvasEvents.js +13 -8
  34. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +3 -3
  35. package/dist-cjs/lib/hooks/useDocumentEvents.js +16 -0
  36. package/dist-cjs/lib/hooks/useDocumentEvents.js.map +2 -2
  37. package/dist-cjs/lib/hooks/useGestureEvents.js +12 -6
  38. package/dist-cjs/lib/hooks/useGestureEvents.js.map +2 -2
  39. package/dist-cjs/lib/license/Watermark.js +10 -20
  40. package/dist-cjs/lib/license/Watermark.js.map +2 -2
  41. package/dist-cjs/lib/primitives/geometry/Geometry2d.js +133 -16
  42. package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +3 -3
  43. package/dist-cjs/lib/primitives/geometry/Group2d.js +53 -10
  44. package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
  45. package/dist-cjs/lib/primitives/intersect.js +20 -0
  46. package/dist-cjs/lib/primitives/intersect.js.map +2 -2
  47. package/dist-cjs/lib/utils/debug-flags.js +2 -1
  48. package/dist-cjs/lib/utils/debug-flags.js.map +2 -2
  49. package/dist-cjs/lib/utils/reorderShapes.js +2 -8
  50. package/dist-cjs/lib/utils/reorderShapes.js.map +2 -2
  51. package/dist-cjs/version.js +3 -3
  52. package/dist-cjs/version.js.map +1 -1
  53. package/dist-esm/index.d.mts +158 -17
  54. package/dist-esm/index.mjs +8 -2
  55. package/dist-esm/index.mjs.map +2 -2
  56. package/dist-esm/lib/TldrawEditor.mjs +5 -0
  57. package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
  58. package/dist-esm/lib/components/GeometryDebuggingView.mjs +3 -3
  59. package/dist-esm/lib/components/GeometryDebuggingView.mjs.map +2 -2
  60. package/dist-esm/lib/components/Shape.mjs +11 -15
  61. package/dist-esm/lib/components/Shape.mjs.map +2 -2
  62. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +10 -1
  63. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  64. package/dist-esm/lib/editor/Editor.mjs +225 -32
  65. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  66. package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs +1 -1
  67. package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs.map +2 -2
  68. package/dist-esm/lib/editor/managers/FocusManager.mjs +1 -1
  69. package/dist-esm/lib/editor/managers/FocusManager.mjs.map +2 -2
  70. package/dist-esm/lib/editor/managers/FontManager.mjs +1 -1
  71. package/dist-esm/lib/editor/managers/FontManager.mjs.map +2 -2
  72. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +12 -0
  73. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  74. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +4 -13
  75. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
  76. package/dist-esm/lib/editor/tools/StateNode.mjs +4 -1
  77. package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
  78. package/dist-esm/lib/exports/StyleEmbedder.mjs +21 -12
  79. package/dist-esm/lib/exports/StyleEmbedder.mjs.map +2 -2
  80. package/dist-esm/lib/exports/cssRules.mjs +107 -0
  81. package/dist-esm/lib/exports/cssRules.mjs.map +7 -0
  82. package/dist-esm/lib/exports/parseCss.mjs +0 -69
  83. package/dist-esm/lib/exports/parseCss.mjs.map +2 -2
  84. package/dist-esm/lib/hooks/useCanvasEvents.mjs +13 -8
  85. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +3 -3
  86. package/dist-esm/lib/hooks/useDocumentEvents.mjs +16 -0
  87. package/dist-esm/lib/hooks/useDocumentEvents.mjs.map +2 -2
  88. package/dist-esm/lib/hooks/useGestureEvents.mjs +12 -6
  89. package/dist-esm/lib/hooks/useGestureEvents.mjs.map +2 -2
  90. package/dist-esm/lib/license/Watermark.mjs +10 -20
  91. package/dist-esm/lib/license/Watermark.mjs.map +2 -2
  92. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +137 -14
  93. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
  94. package/dist-esm/lib/primitives/geometry/Group2d.mjs +54 -11
  95. package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
  96. package/dist-esm/lib/primitives/intersect.mjs +20 -0
  97. package/dist-esm/lib/primitives/intersect.mjs.map +2 -2
  98. package/dist-esm/lib/utils/debug-flags.mjs +2 -1
  99. package/dist-esm/lib/utils/debug-flags.mjs.map +2 -2
  100. package/dist-esm/lib/utils/reorderShapes.mjs +2 -8
  101. package/dist-esm/lib/utils/reorderShapes.mjs.map +2 -2
  102. package/dist-esm/version.mjs +3 -3
  103. package/dist-esm/version.mjs.map +1 -1
  104. package/editor.css +51 -30
  105. package/package.json +7 -7
  106. package/src/index.ts +11 -2
  107. package/src/lib/TldrawEditor.tsx +30 -3
  108. package/src/lib/components/GeometryDebuggingView.tsx +3 -3
  109. package/src/lib/components/Shape.tsx +15 -19
  110. package/src/lib/components/default-components/DefaultCanvas.tsx +6 -1
  111. package/src/lib/editor/Editor.ts +334 -39
  112. package/src/lib/editor/derivations/notVisibleShapes.ts +1 -1
  113. package/src/lib/editor/managers/FocusManager.ts +1 -1
  114. package/src/lib/editor/managers/FontManager.ts +1 -1
  115. package/src/lib/editor/shapes/ShapeUtil.ts +14 -0
  116. package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +7 -15
  117. package/src/lib/editor/tools/StateNode.ts +6 -1
  118. package/src/lib/editor/types/selection-types.ts +3 -0
  119. package/src/lib/exports/StyleEmbedder.ts +25 -15
  120. package/src/lib/exports/cssRules.ts +126 -0
  121. package/src/lib/exports/parseCss.ts +0 -79
  122. package/src/lib/hooks/useCanvasEvents.ts +15 -8
  123. package/src/lib/hooks/useDocumentEvents.ts +18 -0
  124. package/src/lib/hooks/useGestureEvents.ts +12 -6
  125. package/src/lib/license/Watermark.tsx +18 -29
  126. package/src/lib/primitives/geometry/Geometry2d.ts +196 -16
  127. package/src/lib/primitives/geometry/Group2d.ts +75 -12
  128. package/src/lib/primitives/intersect.ts +41 -0
  129. package/src/lib/utils/debug-flags.ts +1 -0
  130. package/src/lib/utils/reorderShapes.ts +2 -9
  131. package/src/version.ts +3 -3
@@ -155,6 +155,25 @@ function intersectPolygonPolygon(polygonA, polygonB) {
155
155
  if (result.size === 0) return null;
156
156
  return orderClockwise([...result.values()]);
157
157
  }
158
+ function intersectPolys(polyA, polyB, isAClosed, isBClosed) {
159
+ const result = /* @__PURE__ */ new Map();
160
+ for (let i = 0, n = isAClosed ? polyA.length : polyA.length - 1; i < n; i++) {
161
+ const currentA = polyA[i];
162
+ const nextA = polyA[(i + 1) % polyA.length];
163
+ for (let j = 0, m = isBClosed ? polyB.length : polyB.length - 1; j < m; j++) {
164
+ const currentB = polyB[j];
165
+ const nextB = polyB[(j + 1) % polyB.length];
166
+ const intersection = intersectLineSegmentLineSegment(currentA, nextA, currentB, nextB);
167
+ if (intersection !== null) {
168
+ const id = getPointId(intersection);
169
+ if (!result.has(id)) {
170
+ result.set(id, intersection);
171
+ }
172
+ }
173
+ }
174
+ }
175
+ return [...result.values()];
176
+ }
158
177
  function getPointId(point) {
159
178
  return `${point.x},${point.y}`;
160
179
  }
@@ -198,6 +217,7 @@ export {
198
217
  intersectLineSegmentPolyline,
199
218
  intersectPolygonBounds,
200
219
  intersectPolygonPolygon,
220
+ intersectPolys,
201
221
  linesIntersect,
202
222
  polygonIntersectsPolyline,
203
223
  polygonsIntersect
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/primitives/intersect.ts"],
4
- "sourcesContent": ["import { Box } from './Box'\nimport { pointInPolygon } from './utils'\nimport { Vec, VecLike } from './Vec'\n\n// need even more intersections? See https://gist.github.com/steveruizok/35c02d526c707003a5c79761bfb89a52\n\n/**\n * Find the intersection between a line segment and a line segment.\n *\n * @param a1 - The first segment's first point.\n * @param a2 - The first segment's second point.\n * @param b1 - The second segment's first point.\n * @param b2 - The second segment's second point.\n * @public\n */\nexport function intersectLineSegmentLineSegment(\n\ta1: VecLike,\n\ta2: VecLike,\n\tb1: VecLike,\n\tb2: VecLike\n) {\n\tconst ABx = a1.x - b1.x\n\tconst ABy = a1.y - b1.y\n\tconst BVx = b2.x - b1.x\n\tconst BVy = b2.y - b1.y\n\tconst AVx = a2.x - a1.x\n\tconst AVy = a2.y - a1.y\n\tconst ua_t = BVx * ABy - BVy * ABx\n\tconst ub_t = AVx * ABy - AVy * ABx\n\tconst u_b = BVy * AVx - BVx * AVy\n\n\tif (ua_t === 0 || ub_t === 0) return null // coincident\n\n\tif (u_b === 0) return null // parallel\n\n\tif (u_b !== 0) {\n\t\tconst ua = ua_t / u_b\n\t\tconst ub = ub_t / u_b\n\t\tif (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {\n\t\t\treturn Vec.AddXY(a1, ua * AVx, ua * AVy)\n\t\t}\n\t}\n\n\treturn null // no intersection\n}\n\n/**\n * Find the intersections between a line segment and a circle.\n *\n * @param a1 - The segment's first point.\n * @param a2 - The segment's second point.\n * @param c - The circle's center.\n * @param r - The circle's radius.\n * @public\n */\nexport function intersectLineSegmentCircle(a1: VecLike, a2: VecLike, c: VecLike, r: number) {\n\tconst a = (a2.x - a1.x) * (a2.x - a1.x) + (a2.y - a1.y) * (a2.y - a1.y)\n\tconst b = 2 * ((a2.x - a1.x) * (a1.x - c.x) + (a2.y - a1.y) * (a1.y - c.y))\n\tconst cc =\n\t\tc.x * c.x + c.y * c.y + a1.x * a1.x + a1.y * a1.y - 2 * (c.x * a1.x + c.y * a1.y) - r * r\n\tconst deter = b * b - 4 * a * cc\n\n\tif (deter < 0) return null // outside\n\tif (deter === 0) return null // tangent\n\n\tconst e = Math.sqrt(deter)\n\tconst u1 = (-b + e) / (2 * a)\n\tconst u2 = (-b - e) / (2 * a)\n\n\tif ((u1 < 0 || u1 > 1) && (u2 < 0 || u2 > 1)) {\n\t\treturn null // outside or inside\n\t\t// if ((u1 < 0 && u2 < 0) || (u1 > 1 && u2 > 1)) {\n\t\t// \treturn null // outside\n\t\t// } else return null // inside'\n\t}\n\n\tconst result: VecLike[] = []\n\n\tif (0 <= u1 && u1 <= 1) result.push(Vec.Lrp(a1, a2, u1))\n\tif (0 <= u2 && u2 <= 1) result.push(Vec.Lrp(a1, a2, u2))\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\n/**\n * Find the intersections between a line segment and a polyline.\n *\n * @param a1 - The segment's first point.\n * @param a2 - The segment's second point.\n * @param points - The points in the polyline.\n * @public\n */\nexport function intersectLineSegmentPolyline(a1: VecLike, a2: VecLike, points: VecLike[]) {\n\tconst result: VecLike[] = []\n\tlet segmentIntersection: VecLike | null\n\n\tfor (let i = 0, n = points.length - 1; i < n; i++) {\n\t\tsegmentIntersection = intersectLineSegmentLineSegment(a1, a2, points[i], points[i + 1])\n\t\tif (segmentIntersection) result.push(segmentIntersection)\n\t}\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\n/**\n * Find the intersections between a line segment and a closed polygon.\n *\n * @param a1 - The segment's first point.\n * @param a2 - The segment's second point.\n * @param points - The points in the polygon.\n * @public\n */\nexport function intersectLineSegmentPolygon(a1: VecLike, a2: VecLike, points: VecLike[]) {\n\tconst result: VecLike[] = []\n\tlet segmentIntersection: VecLike | null\n\n\tfor (let i = 1, n = points.length; i < n + 1; i++) {\n\t\tsegmentIntersection = intersectLineSegmentLineSegment(\n\t\t\ta1,\n\t\t\ta2,\n\t\t\tpoints[i - 1],\n\t\t\tpoints[i % points.length]\n\t\t)\n\t\tif (segmentIntersection) result.push(segmentIntersection)\n\t}\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\n/**\n * Find the intersections between a circle and a circle.\n *\n * @param c1 - The first circle's center.\n * @param r1 - The first circle's radius.\n * @param c2 - The second circle's center.\n * @param r2 - The second circle's radius.\n * @public\n */\nexport function intersectCircleCircle(c1: VecLike, r1: number, c2: VecLike, r2: number) {\n\tlet dx = c2.x - c1.x\n\tlet dy = c2.y - c1.y\n\tconst d = Math.sqrt(dx * dx + dy * dy),\n\t\tx = (d * d - r2 * r2 + r1 * r1) / (2 * d),\n\t\ty = Math.sqrt(r1 * r1 - x * x)\n\tdx /= d\n\tdy /= d\n\treturn [\n\t\tnew Vec(c1.x + dx * x - dy * y, c1.y + dy * x + dx * y),\n\t\tnew Vec(c1.x + dx * x + dy * y, c1.y + dy * x - dx * y),\n\t]\n}\n\n/**\n * Find the intersections between a circle and a bounding box.\n *\n * @param c - The circle's center.\n * @param r - The circle's radius.\n * @param points - The points in the polygon.\n * @public\n */\nexport function intersectCirclePolygon(c: VecLike, r: number, points: VecLike[]) {\n\tconst result: VecLike[] = []\n\tlet a: VecLike, b: VecLike, int: VecLike[] | null\n\n\tfor (let i = 0, n = points.length; i < n; i++) {\n\t\ta = points[i]\n\t\tb = points[(i + 1) % points.length]\n\t\tint = intersectLineSegmentCircle(a, b, c, r)\n\t\tif (int) result.push(...int)\n\t}\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\n/**\n * Find the intersections between a circle and a bounding box.\n *\n * @param c - The circle's center.\n * @param r - The circle's radius.\n * @param points - The points in the polyline.\n * @public\n */\nexport function intersectCirclePolyline(c: VecLike, r: number, points: VecLike[]) {\n\tconst result: VecLike[] = []\n\tlet a: VecLike, b: VecLike, int: VecLike[] | null\n\n\tfor (let i = 1, n = points.length; i < n; i++) {\n\t\ta = points[i - 1]\n\t\tb = points[i]\n\t\tint = intersectLineSegmentCircle(a, b, c, r)\n\t\tif (int) result.push(...int)\n\t}\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\n/**\n * Find the intersections between a polygon and a bounding box.\n *\n * @public\n */\nexport function intersectPolygonBounds(points: VecLike[], bounds: Box) {\n\tconst result: VecLike[] = []\n\tlet segmentIntersection: VecLike[] | null\n\n\tfor (const side of bounds.sides) {\n\t\tsegmentIntersection = intersectLineSegmentPolygon(side[0], side[1], points)\n\t\tif (segmentIntersection) result.push(...segmentIntersection)\n\t}\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\nfunction ccw(A: VecLike, B: VecLike, C: VecLike) {\n\treturn (C.y - A.y) * (B.x - A.x) > (B.y - A.y) * (C.x - A.x)\n}\n\n/** @public */\nexport function linesIntersect(A: VecLike, B: VecLike, C: VecLike, D: VecLike) {\n\treturn ccw(A, C, D) !== ccw(B, C, D) && ccw(A, B, C) !== ccw(A, B, D)\n}\n\n/**\n * Create a new convex polygon as the intersection of two convex polygons.\n *\n * @param polygonA - An array of points representing the first polygon.\n * @param polygonB - An array of points representing the second polygon.\n * @public\n */\nexport function intersectPolygonPolygon(\n\tpolygonA: VecLike[],\n\tpolygonB: VecLike[]\n): VecLike[] | null {\n\t// Create an empty polygon as result\n\tconst result: Map<string, VecLike> = new Map()\n\tlet a: VecLike, b: VecLike, c: VecLike, d: VecLike\n\n\t// Add all corners of PolygonA that is inside PolygonB to result\n\tfor (let i = 0, n = polygonA.length; i < n; i++) {\n\t\ta = polygonA[i]\n\t\tif (pointInPolygon(a, polygonB)) {\n\t\t\tconst id = getPointId(a)\n\t\t\tif (!result.has(id)) {\n\t\t\t\tresult.set(id, a)\n\t\t\t}\n\t\t}\n\t}\n\t// Add all corners of PolygonB that is inside PolygonA to result\n\tfor (let i = 0, n = polygonB.length; i < n; i++) {\n\t\ta = polygonB[i]\n\t\tif (pointInPolygon(a, polygonA)) {\n\t\t\tconst id = getPointId(a)\n\t\t\tif (!result.has(id)) {\n\t\t\t\tresult.set(id, a)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Add all intersection points to result\n\tfor (let i = 0, n = polygonA.length; i < n; i++) {\n\t\ta = polygonA[i]\n\t\tb = polygonA[(i + 1) % polygonA.length]\n\n\t\tfor (let j = 0, m = polygonB.length; j < m; j++) {\n\t\t\tc = polygonB[j]\n\t\t\td = polygonB[(j + 1) % polygonB.length]\n\t\t\tconst intersection = intersectLineSegmentLineSegment(a, b, c, d)\n\n\t\t\tif (intersection !== null) {\n\t\t\t\tconst id = getPointId(intersection)\n\t\t\t\tif (!result.has(id)) {\n\t\t\t\t\tresult.set(id, intersection)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (result.size === 0) return null // no intersection\n\n\t// Order all points in the result counter-clockwise.\n\treturn orderClockwise([...result.values()])\n}\n\nfunction getPointId(point: VecLike) {\n\treturn `${point.x},${point.y}`\n}\n\nfunction orderClockwise(points: VecLike[]): VecLike[] {\n\tconst C = Vec.Average(points)\n\treturn points.sort((A, B) => Vec.Angle(C, A) - Vec.Angle(C, B))\n}\n\n/** @public */\nexport function polygonsIntersect(a: VecLike[], b: VecLike[]) {\n\tlet a0: VecLike, a1: VecLike, b0: VecLike, b1: VecLike\n\tfor (let i = 0, n = a.length; i < n; i++) {\n\t\ta0 = a[i]\n\t\ta1 = a[(i + 1) % n]\n\t\tfor (let j = 0, m = b.length; j < m; j++) {\n\t\t\tb0 = b[j]\n\t\t\tb1 = b[(j + 1) % m]\n\t\t\tif (linesIntersect(a0, a1, b0, b1)) return true\n\t\t}\n\t}\n\treturn false\n}\n\n/** @public */\nexport function polygonIntersectsPolyline(polygon: VecLike[], polyline: VecLike[]) {\n\tlet a: VecLike, b: VecLike, c: VecLike, d: VecLike\n\tfor (let i = 0, n = polygon.length; i < n; i++) {\n\t\ta = polygon[i]\n\t\tb = polygon[(i + 1) % n]\n\n\t\tfor (let j = 1, m = polyline.length; j < m; j++) {\n\t\t\tc = polyline[j - 1]\n\t\t\td = polyline[j]\n\t\t\tif (linesIntersect(a, b, c, d)) return true\n\t\t}\n\t}\n\treturn false\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Box } from './Box'\nimport { pointInPolygon } from './utils'\nimport { Vec, VecLike } from './Vec'\n\n// need even more intersections? See https://gist.github.com/steveruizok/35c02d526c707003a5c79761bfb89a52\n\n/**\n * Find the intersection between a line segment and a line segment.\n *\n * @param a1 - The first segment's first point.\n * @param a2 - The first segment's second point.\n * @param b1 - The second segment's first point.\n * @param b2 - The second segment's second point.\n * @public\n */\nexport function intersectLineSegmentLineSegment(\n\ta1: VecLike,\n\ta2: VecLike,\n\tb1: VecLike,\n\tb2: VecLike\n) {\n\tconst ABx = a1.x - b1.x\n\tconst ABy = a1.y - b1.y\n\tconst BVx = b2.x - b1.x\n\tconst BVy = b2.y - b1.y\n\tconst AVx = a2.x - a1.x\n\tconst AVy = a2.y - a1.y\n\tconst ua_t = BVx * ABy - BVy * ABx\n\tconst ub_t = AVx * ABy - AVy * ABx\n\tconst u_b = BVy * AVx - BVx * AVy\n\n\tif (ua_t === 0 || ub_t === 0) return null // coincident\n\n\tif (u_b === 0) return null // parallel\n\n\tif (u_b !== 0) {\n\t\tconst ua = ua_t / u_b\n\t\tconst ub = ub_t / u_b\n\t\tif (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {\n\t\t\treturn Vec.AddXY(a1, ua * AVx, ua * AVy)\n\t\t}\n\t}\n\n\treturn null // no intersection\n}\n\n/**\n * Find the intersections between a line segment and a circle.\n *\n * @param a1 - The segment's first point.\n * @param a2 - The segment's second point.\n * @param c - The circle's center.\n * @param r - The circle's radius.\n * @public\n */\nexport function intersectLineSegmentCircle(a1: VecLike, a2: VecLike, c: VecLike, r: number) {\n\tconst a = (a2.x - a1.x) * (a2.x - a1.x) + (a2.y - a1.y) * (a2.y - a1.y)\n\tconst b = 2 * ((a2.x - a1.x) * (a1.x - c.x) + (a2.y - a1.y) * (a1.y - c.y))\n\tconst cc =\n\t\tc.x * c.x + c.y * c.y + a1.x * a1.x + a1.y * a1.y - 2 * (c.x * a1.x + c.y * a1.y) - r * r\n\tconst deter = b * b - 4 * a * cc\n\n\tif (deter < 0) return null // outside\n\tif (deter === 0) return null // tangent\n\n\tconst e = Math.sqrt(deter)\n\tconst u1 = (-b + e) / (2 * a)\n\tconst u2 = (-b - e) / (2 * a)\n\n\tif ((u1 < 0 || u1 > 1) && (u2 < 0 || u2 > 1)) {\n\t\treturn null // outside or inside\n\t\t// if ((u1 < 0 && u2 < 0) || (u1 > 1 && u2 > 1)) {\n\t\t// \treturn null // outside\n\t\t// } else return null // inside'\n\t}\n\n\tconst result: VecLike[] = []\n\n\tif (0 <= u1 && u1 <= 1) result.push(Vec.Lrp(a1, a2, u1))\n\tif (0 <= u2 && u2 <= 1) result.push(Vec.Lrp(a1, a2, u2))\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\n/**\n * Find the intersections between a line segment and a polyline.\n *\n * @param a1 - The segment's first point.\n * @param a2 - The segment's second point.\n * @param points - The points in the polyline.\n * @public\n */\nexport function intersectLineSegmentPolyline(a1: VecLike, a2: VecLike, points: VecLike[]) {\n\tconst result: VecLike[] = []\n\tlet segmentIntersection: VecLike | null\n\n\tfor (let i = 0, n = points.length - 1; i < n; i++) {\n\t\tsegmentIntersection = intersectLineSegmentLineSegment(a1, a2, points[i], points[i + 1])\n\t\tif (segmentIntersection) result.push(segmentIntersection)\n\t}\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\n/**\n * Find the intersections between a line segment and a closed polygon.\n *\n * @param a1 - The segment's first point.\n * @param a2 - The segment's second point.\n * @param points - The points in the polygon.\n * @public\n */\nexport function intersectLineSegmentPolygon(a1: VecLike, a2: VecLike, points: VecLike[]) {\n\tconst result: VecLike[] = []\n\tlet segmentIntersection: VecLike | null\n\n\tfor (let i = 1, n = points.length; i < n + 1; i++) {\n\t\tsegmentIntersection = intersectLineSegmentLineSegment(\n\t\t\ta1,\n\t\t\ta2,\n\t\t\tpoints[i - 1],\n\t\t\tpoints[i % points.length]\n\t\t)\n\t\tif (segmentIntersection) result.push(segmentIntersection)\n\t}\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\n/**\n * Find the intersections between a circle and a circle.\n *\n * @param c1 - The first circle's center.\n * @param r1 - The first circle's radius.\n * @param c2 - The second circle's center.\n * @param r2 - The second circle's radius.\n * @public\n */\nexport function intersectCircleCircle(c1: VecLike, r1: number, c2: VecLike, r2: number) {\n\tlet dx = c2.x - c1.x\n\tlet dy = c2.y - c1.y\n\tconst d = Math.sqrt(dx * dx + dy * dy),\n\t\tx = (d * d - r2 * r2 + r1 * r1) / (2 * d),\n\t\ty = Math.sqrt(r1 * r1 - x * x)\n\tdx /= d\n\tdy /= d\n\treturn [\n\t\tnew Vec(c1.x + dx * x - dy * y, c1.y + dy * x + dx * y),\n\t\tnew Vec(c1.x + dx * x + dy * y, c1.y + dy * x - dx * y),\n\t]\n}\n\n/**\n * Find the intersections between a circle and a bounding box.\n *\n * @param c - The circle's center.\n * @param r - The circle's radius.\n * @param points - The points in the polygon.\n * @public\n */\nexport function intersectCirclePolygon(c: VecLike, r: number, points: VecLike[]) {\n\tconst result: VecLike[] = []\n\tlet a: VecLike, b: VecLike, int: VecLike[] | null\n\n\tfor (let i = 0, n = points.length; i < n; i++) {\n\t\ta = points[i]\n\t\tb = points[(i + 1) % points.length]\n\t\tint = intersectLineSegmentCircle(a, b, c, r)\n\t\tif (int) result.push(...int)\n\t}\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\n/**\n * Find the intersections between a circle and a bounding box.\n *\n * @param c - The circle's center.\n * @param r - The circle's radius.\n * @param points - The points in the polyline.\n * @public\n */\nexport function intersectCirclePolyline(c: VecLike, r: number, points: VecLike[]) {\n\tconst result: VecLike[] = []\n\tlet a: VecLike, b: VecLike, int: VecLike[] | null\n\n\tfor (let i = 1, n = points.length; i < n; i++) {\n\t\ta = points[i - 1]\n\t\tb = points[i]\n\t\tint = intersectLineSegmentCircle(a, b, c, r)\n\t\tif (int) result.push(...int)\n\t}\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\n/**\n * Find the intersections between a polygon and a bounding box.\n *\n * @public\n */\nexport function intersectPolygonBounds(points: VecLike[], bounds: Box) {\n\tconst result: VecLike[] = []\n\tlet segmentIntersection: VecLike[] | null\n\n\tfor (const side of bounds.sides) {\n\t\tsegmentIntersection = intersectLineSegmentPolygon(side[0], side[1], points)\n\t\tif (segmentIntersection) result.push(...segmentIntersection)\n\t}\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\nfunction ccw(A: VecLike, B: VecLike, C: VecLike) {\n\treturn (C.y - A.y) * (B.x - A.x) > (B.y - A.y) * (C.x - A.x)\n}\n\n/** @public */\nexport function linesIntersect(A: VecLike, B: VecLike, C: VecLike, D: VecLike) {\n\treturn ccw(A, C, D) !== ccw(B, C, D) && ccw(A, B, C) !== ccw(A, B, D)\n}\n\n/**\n * Create a new convex polygon as the intersection of two convex polygons.\n *\n * @param polygonA - An array of points representing the first polygon.\n * @param polygonB - An array of points representing the second polygon.\n * @public\n */\nexport function intersectPolygonPolygon(\n\tpolygonA: VecLike[],\n\tpolygonB: VecLike[]\n): VecLike[] | null {\n\t// Create an empty polygon as result\n\tconst result: Map<string, VecLike> = new Map()\n\tlet a: VecLike, b: VecLike, c: VecLike, d: VecLike\n\n\t// Add all corners of PolygonA that is inside PolygonB to result\n\tfor (let i = 0, n = polygonA.length; i < n; i++) {\n\t\ta = polygonA[i]\n\t\tif (pointInPolygon(a, polygonB)) {\n\t\t\tconst id = getPointId(a)\n\t\t\tif (!result.has(id)) {\n\t\t\t\tresult.set(id, a)\n\t\t\t}\n\t\t}\n\t}\n\t// Add all corners of PolygonB that is inside PolygonA to result\n\tfor (let i = 0, n = polygonB.length; i < n; i++) {\n\t\ta = polygonB[i]\n\t\tif (pointInPolygon(a, polygonA)) {\n\t\t\tconst id = getPointId(a)\n\t\t\tif (!result.has(id)) {\n\t\t\t\tresult.set(id, a)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Add all intersection points to result\n\tfor (let i = 0, n = polygonA.length; i < n; i++) {\n\t\ta = polygonA[i]\n\t\tb = polygonA[(i + 1) % polygonA.length]\n\n\t\tfor (let j = 0, m = polygonB.length; j < m; j++) {\n\t\t\tc = polygonB[j]\n\t\t\td = polygonB[(j + 1) % polygonB.length]\n\t\t\tconst intersection = intersectLineSegmentLineSegment(a, b, c, d)\n\n\t\t\tif (intersection !== null) {\n\t\t\t\tconst id = getPointId(intersection)\n\t\t\t\tif (!result.has(id)) {\n\t\t\t\t\tresult.set(id, intersection)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (result.size === 0) return null // no intersection\n\n\t// Order all points in the result counter-clockwise.\n\treturn orderClockwise([...result.values()])\n}\n\n/**\n * Find all the points where `polyA` and `polyB` intersect and returns them in an undefined order.\n * To find the polygon that's the intersection of polyA and polyB, use `intersectPolygonPolygon`\n * instead, which orders the points and includes internal points.\n *\n * @param polyA - The first polygon.\n * @param polyB - The second polygon.\n * @param isAClosed - Whether `polyA` is a closed polygon or a polyline.\n * @param isBClosed - Whether `polyB` is a closed polygon or a polyline.\n * @public\n */\nexport function intersectPolys(\n\tpolyA: VecLike[],\n\tpolyB: VecLike[],\n\tisAClosed: boolean,\n\tisBClosed: boolean\n): VecLike[] {\n\tconst result: Map<string, VecLike> = new Map()\n\n\t// Add all intersection points to result\n\tfor (let i = 0, n = isAClosed ? polyA.length : polyA.length - 1; i < n; i++) {\n\t\tconst currentA = polyA[i]\n\t\tconst nextA = polyA[(i + 1) % polyA.length]\n\n\t\tfor (let j = 0, m = isBClosed ? polyB.length : polyB.length - 1; j < m; j++) {\n\t\t\tconst currentB = polyB[j]\n\t\t\tconst nextB = polyB[(j + 1) % polyB.length]\n\t\t\tconst intersection = intersectLineSegmentLineSegment(currentA, nextA, currentB, nextB)\n\n\t\t\tif (intersection !== null) {\n\t\t\t\tconst id = getPointId(intersection)\n\t\t\t\tif (!result.has(id)) {\n\t\t\t\t\tresult.set(id, intersection)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn [...result.values()]\n}\n\nfunction getPointId(point: VecLike) {\n\treturn `${point.x},${point.y}`\n}\n\nfunction orderClockwise(points: VecLike[]): VecLike[] {\n\tconst C = Vec.Average(points)\n\treturn points.sort((A, B) => Vec.Angle(C, A) - Vec.Angle(C, B))\n}\n\n/** @public */\nexport function polygonsIntersect(a: VecLike[], b: VecLike[]) {\n\tlet a0: VecLike, a1: VecLike, b0: VecLike, b1: VecLike\n\tfor (let i = 0, n = a.length; i < n; i++) {\n\t\ta0 = a[i]\n\t\ta1 = a[(i + 1) % n]\n\t\tfor (let j = 0, m = b.length; j < m; j++) {\n\t\t\tb0 = b[j]\n\t\t\tb1 = b[(j + 1) % m]\n\t\t\tif (linesIntersect(a0, a1, b0, b1)) return true\n\t\t}\n\t}\n\treturn false\n}\n\n/** @public */\nexport function polygonIntersectsPolyline(polygon: VecLike[], polyline: VecLike[]) {\n\tlet a: VecLike, b: VecLike, c: VecLike, d: VecLike\n\tfor (let i = 0, n = polygon.length; i < n; i++) {\n\t\ta = polygon[i]\n\t\tb = polygon[(i + 1) % n]\n\n\t\tfor (let j = 1, m = polyline.length; j < m; j++) {\n\t\t\tc = polyline[j - 1]\n\t\t\td = polyline[j]\n\t\t\tif (linesIntersect(a, b, c, d)) return true\n\t\t}\n\t}\n\treturn false\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -40,7 +40,8 @@ const debugFlags = {
40
40
  forceSrgb: createDebugValue("forceSrgbColors", { defaults: { all: false } }),
41
41
  debugGeometry: createDebugValue("debugGeometry", { defaults: { all: false } }),
42
42
  hideShapes: createDebugValue("hideShapes", { defaults: { all: false } }),
43
- editOnType: createDebugValue("editOnType", { defaults: { all: false } })
43
+ editOnType: createDebugValue("editOnType", { defaults: { all: false } }),
44
+ a11y: createDebugValue("a11y", { defaults: { all: false } })
44
45
  };
45
46
  if (typeof Element !== "undefined") {
46
47
  const nativeElementRemoveChild = Element.prototype.removeChild;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/utils/debug-flags.ts"],
4
- "sourcesContent": ["import { Atom, atom, react } from '@tldraw/state'\nimport { deleteFromSessionStorage, getFromSessionStorage, setInSessionStorage } from '@tldraw/utils'\n\n// --- 1. DEFINE ---\n//\n// Define your debug values and feature flags here. Use `createDebugValue` to\n// create an arbitrary value with defaults for production, staging, and\n// development. Use `createFeatureFlag` to create a boolean flag which will be\n// `true` by default in development and staging, and `false` in production.\n/** @internal */\nexport const featureFlags: Record<string, DebugFlag<boolean>> = {}\n\n/** @internal */\nexport const pointerCaptureTrackingObject = createDebugValue(\n\t'pointerCaptureTrackingObject',\n\t// ideally we wouldn't store this mutable value in an atom but it's not\n\t// a big deal for debug values\n\t{\n\t\tdefaults: { all: new Map<Element, number>() },\n\t\tshouldStoreForSession: false,\n\t}\n)\n\n/** @internal */\nexport const debugFlags = {\n\t// --- DEBUG VALUES ---\n\tlogPreventDefaults: createDebugValue('logPreventDefaults', {\n\t\tdefaults: { all: false },\n\t}),\n\tlogPointerCaptures: createDebugValue('logPointerCaptures', {\n\t\tdefaults: { all: false },\n\t}),\n\tlogElementRemoves: createDebugValue('logElementRemoves', {\n\t\tdefaults: { all: false },\n\t}),\n\tdebugSvg: createDebugValue('debugSvg', {\n\t\tdefaults: { all: false },\n\t}),\n\tshowFps: createDebugValue('showFps', {\n\t\tdefaults: { all: false },\n\t}),\n\tmeasurePerformance: createDebugValue('measurePerformance', { defaults: { all: false } }),\n\tthrowToBlob: createDebugValue('throwToBlob', {\n\t\tdefaults: { all: false },\n\t}),\n\treconnectOnPing: createDebugValue('reconnectOnPing', {\n\t\tdefaults: { all: false },\n\t}),\n\tdebugCursors: createDebugValue('debugCursors', {\n\t\tdefaults: { all: false },\n\t}),\n\tforceSrgb: createDebugValue('forceSrgbColors', { defaults: { all: false } }),\n\tdebugGeometry: createDebugValue('debugGeometry', { defaults: { all: false } }),\n\thideShapes: createDebugValue('hideShapes', { defaults: { all: false } }),\n\teditOnType: createDebugValue('editOnType', { defaults: { all: false } }),\n} as const\n\ndeclare global {\n\tinterface Window {\n\t\ttldrawLog(message: any): void\n\t}\n}\n\n// --- 2. USE ---\n// In normal code, read from debug flags directly by calling .value on them:\n// if (debugFlags.preventDefaultLogging.value) { ... }\n//\n// In react, wrap your reads in `useValue` (or your component in `track`)\n// so they react to changes:\n// const shouldLog = useValue(debugFlags.preventDefaultLogging)\n\n// --- 3. GET FUNKY ---\n// If you need to do fun stuff like monkey-patching in response to flag changes,\n// add that here. Make sure you wrap your code in `react` so it runs\n// automatically when values change!\n\nif (typeof Element !== 'undefined') {\n\tconst nativeElementRemoveChild = Element.prototype.removeChild\n\treact('element removal logging', () => {\n\t\tif (debugFlags.logElementRemoves.get()) {\n\t\t\tElement.prototype.removeChild = function <T extends Node>(this: any, child: Node): T {\n\t\t\t\tconsole.warn('[tldraw] removing child:', child)\n\t\t\t\treturn nativeElementRemoveChild.call(this, child) as T\n\t\t\t}\n\t\t} else {\n\t\t\tElement.prototype.removeChild = nativeElementRemoveChild\n\t\t}\n\t})\n}\n\n// --- IMPLEMENTATION ---\n// you probably don't need to read this if you're just using the debug values system\nfunction createDebugValue<T>(\n\tname: string,\n\t{\n\t\tdefaults,\n\t\tshouldStoreForSession = true,\n\t}: { defaults: DebugFlagDefaults<T>; shouldStoreForSession?: boolean }\n) {\n\treturn createDebugValueBase({\n\t\tname,\n\t\tdefaults,\n\t\tshouldStoreForSession,\n\t})\n}\n\n// function createFeatureFlag<T>(\n// \tname: string,\n// \t{\n// \t\tdefaults,\n// \t\tshouldStoreForSession = true,\n// \t}: { defaults: DebugFlagDefaults<T>; shouldStoreForSession?: boolean }\n// ) {\n// \treturn createDebugValueBase({\n// \t\tname,\n// \t\tdefaults,\n// \t\tshouldStoreForSession,\n// \t})\n// }\n\nfunction createDebugValueBase<T>(def: DebugFlagDef<T>): DebugFlag<T> {\n\tconst defaultValue = getDefaultValue(def)\n\tconst storedValue = def.shouldStoreForSession\n\t\t? (getStoredInitialValue(def.name) as T | null)\n\t\t: null\n\tconst valueAtom = atom(`debug:${def.name}`, storedValue ?? defaultValue)\n\n\tif (typeof window !== 'undefined') {\n\t\tif (def.shouldStoreForSession) {\n\t\t\treact(`debug:${def.name}`, () => {\n\t\t\t\tconst currentValue = valueAtom.get()\n\t\t\t\tif (currentValue === defaultValue) {\n\t\t\t\t\tdeleteFromSessionStorage(`tldraw_debug:${def.name}`)\n\t\t\t\t} else {\n\t\t\t\t\tsetInSessionStorage(`tldraw_debug:${def.name}`, JSON.stringify(currentValue))\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\tObject.defineProperty(window, `tldraw${def.name.replace(/^[a-z]/, (l) => l.toUpperCase())}`, {\n\t\t\tget() {\n\t\t\t\treturn valueAtom.get()\n\t\t\t},\n\t\t\tset(newValue) {\n\t\t\t\tvalueAtom.set(newValue)\n\t\t\t},\n\t\t\tconfigurable: true,\n\t\t})\n\t}\n\n\treturn Object.assign(valueAtom, def)\n}\n\nfunction getStoredInitialValue(name: string) {\n\ttry {\n\t\treturn JSON.parse(getFromSessionStorage(`tldraw_debug:${name}`) ?? 'null')\n\t} catch {\n\t\treturn null\n\t}\n}\n\n// process.env might not be defined, but we can't access it using optional\n// chaining because some bundlers search for `process.env.SOMETHING` as a string\n// and replace it with its value.\nfunction readEnv(fn: () => string | undefined) {\n\ttry {\n\t\treturn fn()\n\t} catch {\n\t\treturn null\n\t}\n}\n\nfunction getDefaultValue<T>(def: DebugFlagDef<T>): T {\n\tconst env =\n\t\treadEnv(() => process.env.TLDRAW_ENV) ??\n\t\treadEnv(() => process.env.VERCEL_PUBLIC_TLDRAW_ENV) ??\n\t\treadEnv(() => process.env.NEXT_PUBLIC_TLDRAW_ENV) ??\n\t\t// default to production because if we don't have one of these, this is probably a library use\n\t\t'production'\n\n\tswitch (env) {\n\t\tcase 'production':\n\t\t\treturn def.defaults.production ?? def.defaults.all\n\t\tcase 'preview':\n\t\tcase 'staging':\n\t\t\treturn def.defaults.staging ?? def.defaults.all\n\t\tdefault:\n\t\t\treturn def.defaults.development ?? def.defaults.all\n\t}\n}\n\n/** @internal */\nexport interface DebugFlagDefaults<T> {\n\tdevelopment?: T\n\tstaging?: T\n\tproduction?: T\n\tall: T\n}\n\n/** @internal */\nexport interface DebugFlagDef<T> {\n\tname: string\n\tdefaults: DebugFlagDefaults<T>\n\tshouldStoreForSession: boolean\n}\n\n/** @internal */\nexport type DebugFlag<T> = DebugFlagDef<T> & Atom<T>\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Atom, atom, react } from '@tldraw/state'\nimport { deleteFromSessionStorage, getFromSessionStorage, setInSessionStorage } from '@tldraw/utils'\n\n// --- 1. DEFINE ---\n//\n// Define your debug values and feature flags here. Use `createDebugValue` to\n// create an arbitrary value with defaults for production, staging, and\n// development. Use `createFeatureFlag` to create a boolean flag which will be\n// `true` by default in development and staging, and `false` in production.\n/** @internal */\nexport const featureFlags: Record<string, DebugFlag<boolean>> = {}\n\n/** @internal */\nexport const pointerCaptureTrackingObject = createDebugValue(\n\t'pointerCaptureTrackingObject',\n\t// ideally we wouldn't store this mutable value in an atom but it's not\n\t// a big deal for debug values\n\t{\n\t\tdefaults: { all: new Map<Element, number>() },\n\t\tshouldStoreForSession: false,\n\t}\n)\n\n/** @internal */\nexport const debugFlags = {\n\t// --- DEBUG VALUES ---\n\tlogPreventDefaults: createDebugValue('logPreventDefaults', {\n\t\tdefaults: { all: false },\n\t}),\n\tlogPointerCaptures: createDebugValue('logPointerCaptures', {\n\t\tdefaults: { all: false },\n\t}),\n\tlogElementRemoves: createDebugValue('logElementRemoves', {\n\t\tdefaults: { all: false },\n\t}),\n\tdebugSvg: createDebugValue('debugSvg', {\n\t\tdefaults: { all: false },\n\t}),\n\tshowFps: createDebugValue('showFps', {\n\t\tdefaults: { all: false },\n\t}),\n\tmeasurePerformance: createDebugValue('measurePerformance', { defaults: { all: false } }),\n\tthrowToBlob: createDebugValue('throwToBlob', {\n\t\tdefaults: { all: false },\n\t}),\n\treconnectOnPing: createDebugValue('reconnectOnPing', {\n\t\tdefaults: { all: false },\n\t}),\n\tdebugCursors: createDebugValue('debugCursors', {\n\t\tdefaults: { all: false },\n\t}),\n\tforceSrgb: createDebugValue('forceSrgbColors', { defaults: { all: false } }),\n\tdebugGeometry: createDebugValue('debugGeometry', { defaults: { all: false } }),\n\thideShapes: createDebugValue('hideShapes', { defaults: { all: false } }),\n\teditOnType: createDebugValue('editOnType', { defaults: { all: false } }),\n\ta11y: createDebugValue('a11y', { defaults: { all: false } }),\n} as const\n\ndeclare global {\n\tinterface Window {\n\t\ttldrawLog(message: any): void\n\t}\n}\n\n// --- 2. USE ---\n// In normal code, read from debug flags directly by calling .value on them:\n// if (debugFlags.preventDefaultLogging.value) { ... }\n//\n// In react, wrap your reads in `useValue` (or your component in `track`)\n// so they react to changes:\n// const shouldLog = useValue(debugFlags.preventDefaultLogging)\n\n// --- 3. GET FUNKY ---\n// If you need to do fun stuff like monkey-patching in response to flag changes,\n// add that here. Make sure you wrap your code in `react` so it runs\n// automatically when values change!\n\nif (typeof Element !== 'undefined') {\n\tconst nativeElementRemoveChild = Element.prototype.removeChild\n\treact('element removal logging', () => {\n\t\tif (debugFlags.logElementRemoves.get()) {\n\t\t\tElement.prototype.removeChild = function <T extends Node>(this: any, child: Node): T {\n\t\t\t\tconsole.warn('[tldraw] removing child:', child)\n\t\t\t\treturn nativeElementRemoveChild.call(this, child) as T\n\t\t\t}\n\t\t} else {\n\t\t\tElement.prototype.removeChild = nativeElementRemoveChild\n\t\t}\n\t})\n}\n\n// --- IMPLEMENTATION ---\n// you probably don't need to read this if you're just using the debug values system\nfunction createDebugValue<T>(\n\tname: string,\n\t{\n\t\tdefaults,\n\t\tshouldStoreForSession = true,\n\t}: { defaults: DebugFlagDefaults<T>; shouldStoreForSession?: boolean }\n) {\n\treturn createDebugValueBase({\n\t\tname,\n\t\tdefaults,\n\t\tshouldStoreForSession,\n\t})\n}\n\n// function createFeatureFlag<T>(\n// \tname: string,\n// \t{\n// \t\tdefaults,\n// \t\tshouldStoreForSession = true,\n// \t}: { defaults: DebugFlagDefaults<T>; shouldStoreForSession?: boolean }\n// ) {\n// \treturn createDebugValueBase({\n// \t\tname,\n// \t\tdefaults,\n// \t\tshouldStoreForSession,\n// \t})\n// }\n\nfunction createDebugValueBase<T>(def: DebugFlagDef<T>): DebugFlag<T> {\n\tconst defaultValue = getDefaultValue(def)\n\tconst storedValue = def.shouldStoreForSession\n\t\t? (getStoredInitialValue(def.name) as T | null)\n\t\t: null\n\tconst valueAtom = atom(`debug:${def.name}`, storedValue ?? defaultValue)\n\n\tif (typeof window !== 'undefined') {\n\t\tif (def.shouldStoreForSession) {\n\t\t\treact(`debug:${def.name}`, () => {\n\t\t\t\tconst currentValue = valueAtom.get()\n\t\t\t\tif (currentValue === defaultValue) {\n\t\t\t\t\tdeleteFromSessionStorage(`tldraw_debug:${def.name}`)\n\t\t\t\t} else {\n\t\t\t\t\tsetInSessionStorage(`tldraw_debug:${def.name}`, JSON.stringify(currentValue))\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\tObject.defineProperty(window, `tldraw${def.name.replace(/^[a-z]/, (l) => l.toUpperCase())}`, {\n\t\t\tget() {\n\t\t\t\treturn valueAtom.get()\n\t\t\t},\n\t\t\tset(newValue) {\n\t\t\t\tvalueAtom.set(newValue)\n\t\t\t},\n\t\t\tconfigurable: true,\n\t\t})\n\t}\n\n\treturn Object.assign(valueAtom, def)\n}\n\nfunction getStoredInitialValue(name: string) {\n\ttry {\n\t\treturn JSON.parse(getFromSessionStorage(`tldraw_debug:${name}`) ?? 'null')\n\t} catch {\n\t\treturn null\n\t}\n}\n\n// process.env might not be defined, but we can't access it using optional\n// chaining because some bundlers search for `process.env.SOMETHING` as a string\n// and replace it with its value.\nfunction readEnv(fn: () => string | undefined) {\n\ttry {\n\t\treturn fn()\n\t} catch {\n\t\treturn null\n\t}\n}\n\nfunction getDefaultValue<T>(def: DebugFlagDef<T>): T {\n\tconst env =\n\t\treadEnv(() => process.env.TLDRAW_ENV) ??\n\t\treadEnv(() => process.env.VERCEL_PUBLIC_TLDRAW_ENV) ??\n\t\treadEnv(() => process.env.NEXT_PUBLIC_TLDRAW_ENV) ??\n\t\t// default to production because if we don't have one of these, this is probably a library use\n\t\t'production'\n\n\tswitch (env) {\n\t\tcase 'production':\n\t\t\treturn def.defaults.production ?? def.defaults.all\n\t\tcase 'preview':\n\t\tcase 'staging':\n\t\t\treturn def.defaults.staging ?? def.defaults.all\n\t\tdefault:\n\t\t\treturn def.defaults.development ?? def.defaults.all\n\t}\n}\n\n/** @internal */\nexport interface DebugFlagDefaults<T> {\n\tdevelopment?: T\n\tstaging?: T\n\tproduction?: T\n\tall: T\n}\n\n/** @internal */\nexport interface DebugFlagDef<T> {\n\tname: string\n\tdefaults: DebugFlagDefaults<T>\n\tshouldStoreForSession: boolean\n}\n\n/** @internal */\nexport type DebugFlag<T> = DebugFlagDef<T> & Atom<T>\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -88,20 +88,14 @@ function reorderToFront(moving, children, changes) {
88
88
  );
89
89
  }
90
90
  }
91
- function getVerticesInPageSpace(editor, shape) {
92
- const geo = editor.getShapeGeometry(shape);
93
- const pageTransform = editor.getShapePageTransform(shape);
94
- if (!geo || !pageTransform) return null;
95
- return pageTransform.applyToPoints(geo.vertices);
96
- }
97
91
  function getOverlapChecker(editor, moving) {
98
92
  const movingVertices = Array.from(moving).map((shape) => {
99
- const vertices = getVerticesInPageSpace(editor, shape);
93
+ const vertices = editor.getShapePageGeometry(shape).vertices;
100
94
  if (!vertices) return null;
101
95
  return { shape, vertices };
102
96
  }).filter(Boolean);
103
97
  const isOverlapping = (child) => {
104
- const vertices = getVerticesInPageSpace(editor, child);
98
+ const vertices = editor.getShapePageGeometry(child).vertices;
105
99
  if (!vertices) return false;
106
100
  return movingVertices.some((other) => {
107
101
  return polygonsIntersect(other.vertices, vertices);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/utils/reorderShapes.ts"],
4
- "sourcesContent": ["import { TLParentId, TLShape, TLShapeId, TLShapePartial } from '@tldraw/tlschema'\nimport { IndexKey, compact, getIndicesBetween, sortByIndex } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\nimport { Vec } from '../primitives/Vec'\nimport { polygonsIntersect } from '../primitives/intersect'\n\nexport function getReorderingShapesChanges(\n\teditor: Editor,\n\toperation: 'toBack' | 'toFront' | 'forward' | 'backward',\n\tids: TLShapeId[],\n\topts?: { considerAllShapes?: boolean }\n) {\n\tif (ids.length === 0) return []\n\n\t// From the ids that are moving, collect the parents, their children, and which of those children are moving\n\tconst parents = new Map<TLParentId, { moving: Set<TLShape>; children: TLShape[] }>()\n\n\tfor (const shape of compact(ids.map((id) => editor.getShape(id)))) {\n\t\tconst { parentId } = shape\n\t\tif (!parents.has(parentId)) {\n\t\t\tparents.set(parentId, {\n\t\t\t\tchildren: compact(\n\t\t\t\t\teditor.getSortedChildIdsForParent(parentId).map((id) => editor.getShape(id))\n\t\t\t\t),\n\t\t\t\tmoving: new Set(),\n\t\t\t})\n\t\t}\n\t\tparents.get(parentId)!.moving.add(shape)\n\t}\n\n\tconst changes: TLShapePartial[] = []\n\n\tswitch (operation) {\n\t\tcase 'toBack': {\n\t\t\tparents.forEach(({ moving, children }) => reorderToBack(moving, children, changes))\n\t\t\tbreak\n\t\t}\n\t\tcase 'toFront': {\n\t\t\tparents.forEach(({ moving, children }) => reorderToFront(moving, children, changes))\n\t\t\tbreak\n\t\t}\n\t\tcase 'forward': {\n\t\t\tparents.forEach(({ moving, children }) =>\n\t\t\t\treorderForward(editor, moving, children, changes, opts)\n\t\t\t)\n\t\t\tbreak\n\t\t}\n\t\tcase 'backward': {\n\t\t\tparents.forEach(({ moving, children }) =>\n\t\t\t\treorderBackward(editor, moving, children, changes, opts)\n\t\t\t)\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn changes\n}\n\n/**\n * Reorders the moving shapes to the back of the parent's children.\n *\n * @param moving The set of shapes that are moving\n * @param children The parent's children\n * @param changes The changes array to push changes to\n */\nfunction reorderToBack(moving: Set<TLShape>, children: TLShape[], changes: TLShapePartial[]) {\n\tconst len = children.length\n\n\t// If all of the children are moving, there's nothing to do\n\tif (moving.size === len) return\n\n\tlet below: IndexKey | undefined\n\tlet above: IndexKey | undefined\n\n\t// Starting at the bottom of this parent's children...\n\tfor (let i = 0; i < len; i++) {\n\t\tconst shape = children[i]\n\n\t\tif (moving.has(shape)) {\n\t\t\t// If we've found a moving shape before we've found a non-moving shape,\n\t\t\t// then that shape is already at the back; we can remove it from the\n\t\t\t// moving set and mark it as the shape that will be below the moved shapes.\n\t\t\tbelow = shape.index\n\t\t\tmoving.delete(shape)\n\t\t} else {\n\t\t\t// The first non-moving shape we find will be above our moved shapes; we'll\n\t\t\t// put our moving shapes between it and the shape marked as below (if any).\n\t\t\tabove = shape.index\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif (moving.size === 0) {\n\t\t// If our moving set is empty, there's nothing to do; all of our shapes were\n\t\t// already at the back of the parent's children.\n\t\treturn\n\t} else {\n\t\t// Sort the moving shapes by their current index, then apply the new indices\n\t\tconst indices = getIndicesBetween(below, above, moving.size)\n\t\tchanges.push(\n\t\t\t...Array.from(moving.values())\n\t\t\t\t.sort(sortByIndex)\n\t\t\t\t.map((shape, i) => ({ ...shape, index: indices[i] }))\n\t\t)\n\t}\n}\n\n/**\n * Reorders the moving shapes to the front of the parent's children.\n *\n * @param moving The set of shapes that are moving\n * @param children The parent's children\n * @param changes The changes array to push changes to\n */\nfunction reorderToFront(moving: Set<TLShape>, children: TLShape[], changes: TLShapePartial[]) {\n\tconst len = children.length\n\n\t// If all of the children are moving, there's nothing to do\n\tif (moving.size === len) return\n\n\tlet below: IndexKey | undefined\n\tlet above: IndexKey | undefined\n\n\t// Starting at the top of this parent's children...\n\tfor (let i = len - 1; i > -1; i--) {\n\t\tconst shape = children[i]\n\n\t\tif (moving.has(shape)) {\n\t\t\t// If we've found a moving shape before we've found a non-moving shape,\n\t\t\t// then that shape is already at the front; we can remove it from the\n\t\t\t// moving set and mark it as the shape that will be above the moved shapes.\n\t\t\tabove = shape.index\n\t\t\tmoving.delete(shape)\n\t\t} else {\n\t\t\t// The first non-moving shape we find will be below our moved shapes; we'll\n\t\t\t// put our moving shapes between it and the shape marked as above (if any).\n\t\t\tbelow = shape.index\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif (moving.size === 0) {\n\t\t// If our moving set is empty, there's nothing to do; all of our shapes were\n\t\t// already at the front of the parent's children.\n\t\treturn\n\t} else {\n\t\t// Sort the moving shapes by their current index, then apply the new indices\n\t\tconst indices = getIndicesBetween(below, above, moving.size)\n\t\tchanges.push(\n\t\t\t...Array.from(moving.values())\n\t\t\t\t.sort(sortByIndex)\n\t\t\t\t.map((shape, i) => ({ ...shape, index: indices[i] }))\n\t\t)\n\t}\n}\n\nfunction getVerticesInPageSpace(editor: Editor, shape: TLShape) {\n\tconst geo = editor.getShapeGeometry(shape)\n\tconst pageTransform = editor.getShapePageTransform(shape)\n\tif (!geo || !pageTransform) return null\n\treturn pageTransform.applyToPoints(geo.vertices)\n}\n\nfunction getOverlapChecker(editor: Editor, moving: Set<TLShape>) {\n\tconst movingVertices = Array.from(moving)\n\t\t.map((shape) => {\n\t\t\tconst vertices = getVerticesInPageSpace(editor, shape)\n\t\t\tif (!vertices) return null\n\t\t\treturn { shape, vertices }\n\t\t})\n\t\t.filter(Boolean) as { shape: TLShape; vertices: Vec[] }[]\n\n\tconst isOverlapping = (child: TLShape) => {\n\t\tconst vertices = getVerticesInPageSpace(editor, child)\n\t\tif (!vertices) return false\n\t\treturn movingVertices.some((other) => {\n\t\t\treturn polygonsIntersect(other.vertices, vertices)\n\t\t})\n\t}\n\n\treturn isOverlapping\n}\n\n/**\n * Reorders the moving shapes forward in the parent's children.\n *\n * @param editor The editor\n * @param moving The set of shapes that are moving\n * @param children The parent's children\n * @param changes The changes array to push changes to\n * @param opts The options\n */\nfunction reorderForward(\n\teditor: Editor,\n\tmoving: Set<TLShape>,\n\tchildren: TLShape[],\n\tchanges: TLShapePartial[],\n\topts?: { considerAllShapes?: boolean }\n) {\n\tconst isOverlapping = getOverlapChecker(editor, moving)\n\n\tconst len = children.length\n\n\t// If all of the children are moving, there's nothing to do\n\tif (moving.size === len) return\n\n\tlet state = { name: 'skipping' } as\n\t\t| { name: 'skipping' }\n\t\t| { name: 'selecting'; selectIndex: number }\n\n\t// Starting at the bottom of this parent's children...\n\tfor (let i = 0; i < len; i++) {\n\t\tconst isMoving = moving.has(children[i])\n\n\t\tswitch (state.name) {\n\t\t\tcase 'skipping': {\n\t\t\t\tif (!isMoving) continue\n\t\t\t\t// If we find a moving shape while skipping, start selecting\n\t\t\t\tstate = { name: 'selecting', selectIndex: i }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'selecting': {\n\t\t\t\tif (isMoving) continue\n\t\t\t\tif (!opts?.considerAllShapes && !isOverlapping(children[i])) continue\n\t\t\t\t// if we find a non-moving and overlapping shape while selecting, move all selected\n\t\t\t\t// shapes in front of the not moving shape; and start skipping\n\t\t\t\tconst { selectIndex } = state\n\t\t\t\tgetIndicesBetween(children[i].index, children[i + 1]?.index, i - selectIndex).forEach(\n\t\t\t\t\t(index, k) => {\n\t\t\t\t\t\tconst child = children[selectIndex + k]\n\t\t\t\t\t\t// If the shape is not moving (therefore also not overlapping), skip it\n\t\t\t\t\t\tif (!moving.has(child)) return\n\t\t\t\t\t\tchanges.push({ ...child, index })\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t\tstate = { name: 'skipping' }\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Reorders the moving shapes backward in the parent's children.\n *\n * @param editor The editor\n * @param moving The set of shapes that are moving\n * @param children The parent's children\n * @param changes The changes array to push changes to\n * @param opts The options\n */\nfunction reorderBackward(\n\teditor: Editor,\n\tmoving: Set<TLShape>,\n\tchildren: TLShape[],\n\tchanges: TLShapePartial[],\n\topts?: { considerAllShapes?: boolean }\n) {\n\tconst isOverlapping = getOverlapChecker(editor, moving)\n\n\tconst len = children.length\n\n\tif (moving.size === len) return\n\n\tlet state = { name: 'skipping' } as\n\t\t| { name: 'skipping' }\n\t\t| { name: 'selecting'; selectIndex: number }\n\n\t// Starting at the top of this parent's children...\n\tfor (let i = len - 1; i > -1; i--) {\n\t\tconst isMoving = moving.has(children[i])\n\n\t\tswitch (state.name) {\n\t\t\tcase 'skipping': {\n\t\t\t\tif (!isMoving) continue\n\t\t\t\t// If we find a moving shape while skipping, start selecting\n\t\t\t\tstate = { name: 'selecting', selectIndex: i }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'selecting': {\n\t\t\t\tif (isMoving) continue\n\t\t\t\tif (!opts?.considerAllShapes && !isOverlapping(children[i])) continue\n\t\t\t\t// if we find a non-moving and overlapping shape while selecting, move all selected\n\t\t\t\t// shapes in behind of the not moving shape; and start skipping\n\t\t\t\tgetIndicesBetween(children[i - 1]?.index, children[i].index, state.selectIndex - i).forEach(\n\t\t\t\t\t(index, k) => {\n\t\t\t\t\t\tconst child = children[i + k + 1]\n\t\t\t\t\t\t// If the shape is not moving (therefore also not overlapping), skip it\n\t\t\t\t\t\tif (!moving.has(child)) return\n\t\t\t\t\t\tchanges.push({ ...child, index })\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t\tstate = { name: 'skipping' }\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { TLParentId, TLShape, TLShapeId, TLShapePartial } from '@tldraw/tlschema'\nimport { IndexKey, compact, getIndicesBetween, sortByIndex } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\nimport { Vec } from '../primitives/Vec'\nimport { polygonsIntersect } from '../primitives/intersect'\n\nexport function getReorderingShapesChanges(\n\teditor: Editor,\n\toperation: 'toBack' | 'toFront' | 'forward' | 'backward',\n\tids: TLShapeId[],\n\topts?: { considerAllShapes?: boolean }\n) {\n\tif (ids.length === 0) return []\n\n\t// From the ids that are moving, collect the parents, their children, and which of those children are moving\n\tconst parents = new Map<TLParentId, { moving: Set<TLShape>; children: TLShape[] }>()\n\n\tfor (const shape of compact(ids.map((id) => editor.getShape(id)))) {\n\t\tconst { parentId } = shape\n\t\tif (!parents.has(parentId)) {\n\t\t\tparents.set(parentId, {\n\t\t\t\tchildren: compact(\n\t\t\t\t\teditor.getSortedChildIdsForParent(parentId).map((id) => editor.getShape(id))\n\t\t\t\t),\n\t\t\t\tmoving: new Set(),\n\t\t\t})\n\t\t}\n\t\tparents.get(parentId)!.moving.add(shape)\n\t}\n\n\tconst changes: TLShapePartial[] = []\n\n\tswitch (operation) {\n\t\tcase 'toBack': {\n\t\t\tparents.forEach(({ moving, children }) => reorderToBack(moving, children, changes))\n\t\t\tbreak\n\t\t}\n\t\tcase 'toFront': {\n\t\t\tparents.forEach(({ moving, children }) => reorderToFront(moving, children, changes))\n\t\t\tbreak\n\t\t}\n\t\tcase 'forward': {\n\t\t\tparents.forEach(({ moving, children }) =>\n\t\t\t\treorderForward(editor, moving, children, changes, opts)\n\t\t\t)\n\t\t\tbreak\n\t\t}\n\t\tcase 'backward': {\n\t\t\tparents.forEach(({ moving, children }) =>\n\t\t\t\treorderBackward(editor, moving, children, changes, opts)\n\t\t\t)\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn changes\n}\n\n/**\n * Reorders the moving shapes to the back of the parent's children.\n *\n * @param moving The set of shapes that are moving\n * @param children The parent's children\n * @param changes The changes array to push changes to\n */\nfunction reorderToBack(moving: Set<TLShape>, children: TLShape[], changes: TLShapePartial[]) {\n\tconst len = children.length\n\n\t// If all of the children are moving, there's nothing to do\n\tif (moving.size === len) return\n\n\tlet below: IndexKey | undefined\n\tlet above: IndexKey | undefined\n\n\t// Starting at the bottom of this parent's children...\n\tfor (let i = 0; i < len; i++) {\n\t\tconst shape = children[i]\n\n\t\tif (moving.has(shape)) {\n\t\t\t// If we've found a moving shape before we've found a non-moving shape,\n\t\t\t// then that shape is already at the back; we can remove it from the\n\t\t\t// moving set and mark it as the shape that will be below the moved shapes.\n\t\t\tbelow = shape.index\n\t\t\tmoving.delete(shape)\n\t\t} else {\n\t\t\t// The first non-moving shape we find will be above our moved shapes; we'll\n\t\t\t// put our moving shapes between it and the shape marked as below (if any).\n\t\t\tabove = shape.index\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif (moving.size === 0) {\n\t\t// If our moving set is empty, there's nothing to do; all of our shapes were\n\t\t// already at the back of the parent's children.\n\t\treturn\n\t} else {\n\t\t// Sort the moving shapes by their current index, then apply the new indices\n\t\tconst indices = getIndicesBetween(below, above, moving.size)\n\t\tchanges.push(\n\t\t\t...Array.from(moving.values())\n\t\t\t\t.sort(sortByIndex)\n\t\t\t\t.map((shape, i) => ({ ...shape, index: indices[i] }))\n\t\t)\n\t}\n}\n\n/**\n * Reorders the moving shapes to the front of the parent's children.\n *\n * @param moving The set of shapes that are moving\n * @param children The parent's children\n * @param changes The changes array to push changes to\n */\nfunction reorderToFront(moving: Set<TLShape>, children: TLShape[], changes: TLShapePartial[]) {\n\tconst len = children.length\n\n\t// If all of the children are moving, there's nothing to do\n\tif (moving.size === len) return\n\n\tlet below: IndexKey | undefined\n\tlet above: IndexKey | undefined\n\n\t// Starting at the top of this parent's children...\n\tfor (let i = len - 1; i > -1; i--) {\n\t\tconst shape = children[i]\n\n\t\tif (moving.has(shape)) {\n\t\t\t// If we've found a moving shape before we've found a non-moving shape,\n\t\t\t// then that shape is already at the front; we can remove it from the\n\t\t\t// moving set and mark it as the shape that will be above the moved shapes.\n\t\t\tabove = shape.index\n\t\t\tmoving.delete(shape)\n\t\t} else {\n\t\t\t// The first non-moving shape we find will be below our moved shapes; we'll\n\t\t\t// put our moving shapes between it and the shape marked as above (if any).\n\t\t\tbelow = shape.index\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif (moving.size === 0) {\n\t\t// If our moving set is empty, there's nothing to do; all of our shapes were\n\t\t// already at the front of the parent's children.\n\t\treturn\n\t} else {\n\t\t// Sort the moving shapes by their current index, then apply the new indices\n\t\tconst indices = getIndicesBetween(below, above, moving.size)\n\t\tchanges.push(\n\t\t\t...Array.from(moving.values())\n\t\t\t\t.sort(sortByIndex)\n\t\t\t\t.map((shape, i) => ({ ...shape, index: indices[i] }))\n\t\t)\n\t}\n}\n\nfunction getOverlapChecker(editor: Editor, moving: Set<TLShape>) {\n\tconst movingVertices = Array.from(moving)\n\t\t.map((shape) => {\n\t\t\tconst vertices = editor.getShapePageGeometry(shape).vertices\n\t\t\tif (!vertices) return null\n\t\t\treturn { shape, vertices }\n\t\t})\n\t\t.filter(Boolean) as { shape: TLShape; vertices: Vec[] }[]\n\n\tconst isOverlapping = (child: TLShape) => {\n\t\tconst vertices = editor.getShapePageGeometry(child).vertices\n\t\tif (!vertices) return false\n\t\treturn movingVertices.some((other) => {\n\t\t\treturn polygonsIntersect(other.vertices, vertices)\n\t\t})\n\t}\n\n\treturn isOverlapping\n}\n\n/**\n * Reorders the moving shapes forward in the parent's children.\n *\n * @param editor The editor\n * @param moving The set of shapes that are moving\n * @param children The parent's children\n * @param changes The changes array to push changes to\n * @param opts The options\n */\nfunction reorderForward(\n\teditor: Editor,\n\tmoving: Set<TLShape>,\n\tchildren: TLShape[],\n\tchanges: TLShapePartial[],\n\topts?: { considerAllShapes?: boolean }\n) {\n\tconst isOverlapping = getOverlapChecker(editor, moving)\n\n\tconst len = children.length\n\n\t// If all of the children are moving, there's nothing to do\n\tif (moving.size === len) return\n\n\tlet state = { name: 'skipping' } as\n\t\t| { name: 'skipping' }\n\t\t| { name: 'selecting'; selectIndex: number }\n\n\t// Starting at the bottom of this parent's children...\n\tfor (let i = 0; i < len; i++) {\n\t\tconst isMoving = moving.has(children[i])\n\n\t\tswitch (state.name) {\n\t\t\tcase 'skipping': {\n\t\t\t\tif (!isMoving) continue\n\t\t\t\t// If we find a moving shape while skipping, start selecting\n\t\t\t\tstate = { name: 'selecting', selectIndex: i }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'selecting': {\n\t\t\t\tif (isMoving) continue\n\t\t\t\tif (!opts?.considerAllShapes && !isOverlapping(children[i])) continue\n\t\t\t\t// if we find a non-moving and overlapping shape while selecting, move all selected\n\t\t\t\t// shapes in front of the not moving shape; and start skipping\n\t\t\t\tconst { selectIndex } = state\n\t\t\t\tgetIndicesBetween(children[i].index, children[i + 1]?.index, i - selectIndex).forEach(\n\t\t\t\t\t(index, k) => {\n\t\t\t\t\t\tconst child = children[selectIndex + k]\n\t\t\t\t\t\t// If the shape is not moving (therefore also not overlapping), skip it\n\t\t\t\t\t\tif (!moving.has(child)) return\n\t\t\t\t\t\tchanges.push({ ...child, index })\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t\tstate = { name: 'skipping' }\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Reorders the moving shapes backward in the parent's children.\n *\n * @param editor The editor\n * @param moving The set of shapes that are moving\n * @param children The parent's children\n * @param changes The changes array to push changes to\n * @param opts The options\n */\nfunction reorderBackward(\n\teditor: Editor,\n\tmoving: Set<TLShape>,\n\tchildren: TLShape[],\n\tchanges: TLShapePartial[],\n\topts?: { considerAllShapes?: boolean }\n) {\n\tconst isOverlapping = getOverlapChecker(editor, moving)\n\n\tconst len = children.length\n\n\tif (moving.size === len) return\n\n\tlet state = { name: 'skipping' } as\n\t\t| { name: 'skipping' }\n\t\t| { name: 'selecting'; selectIndex: number }\n\n\t// Starting at the top of this parent's children...\n\tfor (let i = len - 1; i > -1; i--) {\n\t\tconst isMoving = moving.has(children[i])\n\n\t\tswitch (state.name) {\n\t\t\tcase 'skipping': {\n\t\t\t\tif (!isMoving) continue\n\t\t\t\t// If we find a moving shape while skipping, start selecting\n\t\t\t\tstate = { name: 'selecting', selectIndex: i }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'selecting': {\n\t\t\t\tif (isMoving) continue\n\t\t\t\tif (!opts?.considerAllShapes && !isOverlapping(children[i])) continue\n\t\t\t\t// if we find a non-moving and overlapping shape while selecting, move all selected\n\t\t\t\t// shapes in behind of the not moving shape; and start skipping\n\t\t\t\tgetIndicesBetween(children[i - 1]?.index, children[i].index, state.selectIndex - i).forEach(\n\t\t\t\t\t(index, k) => {\n\t\t\t\t\t\tconst child = children[i + k + 1]\n\t\t\t\t\t\t// If the shape is not moving (therefore also not overlapping), skip it\n\t\t\t\t\t\tif (!moving.has(child)) return\n\t\t\t\t\t\tchanges.push({ ...child, index })\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t\tstate = { name: 'skipping' }\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,8 +1,8 @@
1
- const version = "3.12.0-canary.a6c2905c622f";
1
+ const version = "3.12.0-canary.a880bf3ec9cb";
2
2
  const publishDates = {
3
3
  major: "2024-09-13T14:36:29.063Z",
4
- minor: "2025-03-21T09:33:46.759Z",
5
- patch: "2025-03-21T09:33:46.759Z"
4
+ minor: "2025-04-14T14:49:48.759Z",
5
+ patch: "2025-04-14T14:49:48.759Z"
6
6
  };
7
7
  export {
8
8
  publishDates,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/version.ts"],
4
- "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.12.0-canary.a6c2905c622f'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-03-21T09:33:46.759Z',\n\tpatch: '2025-03-21T09:33:46.759Z',\n}\n"],
4
+ "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.12.0-canary.a880bf3ec9cb'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-04-14T14:49:48.759Z',\n\tpatch: '2025-04-14T14:49:48.759Z',\n}\n"],
5
5
  "mappings": "AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
6
6
  "names": []
7
7
  }
package/editor.css CHANGED
@@ -63,31 +63,40 @@
63
63
 
64
64
  /* Cursor SVGs */
65
65
  --tl-cursor-none: none;
66
- --tl-cursor-default: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m12 24.4219v-16.015l11.591 11.619h-6.781l-.411.124z' fill='white'/><path d='m21.0845 25.0962-3.605 1.535-4.682-11.089 3.686-1.553z' fill='white'/><path d='m19.751 24.4155-1.844.774-3.1-7.374 1.841-.775z' fill='black'/><path d='m13 10.814v11.188l2.969-2.866.428-.139h4.768z' fill='black'/></g></svg>")
66
+ --tl-cursor-default:
67
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m12 24.4219v-16.015l11.591 11.619h-6.781l-.411.124z' fill='white'/><path d='m21.0845 25.0962-3.605 1.535-4.682-11.089 3.686-1.553z' fill='white'/><path d='m19.751 24.4155-1.844.774-3.1-7.374 1.841-.775z' fill='black'/><path d='m13 10.814v11.188l2.969-2.866.428-.139h4.768z' fill='black'/></g></svg>")
67
68
  12 8,
68
69
  default;
69
- --tl-cursor-pointer: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m13.3315 21.3799c-.284-.359-.629-1.093-1.243-1.984-.348-.504-1.211-1.453-1.468-1.935-.223-.426-.199-.617-.146-.97.094-.628.738-1.117 1.425-1.051.519.049.959.392 1.355.716.239.195.533.574.71.788.163.196.203.277.377.509.23.307.302.459.214.121-.071-.496-.187-1.343-.355-2.092-.128-.568-.159-.657-.281-1.093-.129-.464-.195-.789-.316-1.281-.084-.348-.235-1.059-.276-1.459-.057-.547-.087-1.439.264-1.849.275-.321.906-.418 1.297-.22.512.259.803 1.003.936 1.3.239.534.387 1.151.516 1.961.164 1.031.466 2.462.476 2.763.024-.369-.068-1.146-.004-1.5.058-.321.328-.694.666-.795.286-.085.621-.116.916-.055.313.064.643.288.766.499.362.624.369 1.899.384 1.831.086-.376.071-1.229.284-1.584.14-.234.497-.445.687-.479.294-.052.655-.068.964-.008.249.049.586.345.677.487.218.344.342 1.317.379 1.658.015.141.074-.392.293-.736.406-.639 1.843-.763 1.898.639.025.654.02.624.02 1.064 0 .517-.012.828-.04 1.202-.031.4-.117 1.304-.242 1.742-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.191 1.813-.118.562-.079.566-.102.965-.023.398.121.922.121.922s-.802.104-1.234.035c-.391-.063-.875-.841-1-1.079-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.031-3.139.02 0 0 .185-1.011-.227-1.358-.305-.259-.83-.784-1.144-1.06z' fill='white'/><g stroke='black' stroke-linecap='round' stroke-width='.75'><path d='m13.3315 21.3799c-.284-.359-.629-1.093-1.243-1.984-.348-.504-1.211-1.453-1.468-1.935-.223-.426-.199-.617-.146-.97.094-.628.738-1.117 1.425-1.051.519.049.959.392 1.355.716.239.195.533.574.71.788.163.196.203.277.377.509.23.307.302.459.214.121-.071-.496-.187-1.343-.355-2.092-.128-.568-.159-.657-.281-1.093-.129-.464-.195-.789-.316-1.281-.084-.348-.235-1.059-.276-1.459-.057-.547-.087-1.439.264-1.849.275-.321.906-.418 1.297-.22.512.259.803 1.003.936 1.3.239.534.387 1.151.516 1.961.164 1.031.466 2.462.476 2.763.024-.369-.068-1.146-.004-1.5.058-.321.328-.694.666-.795.286-.085.621-.116.916-.055.313.064.643.288.766.499.362.624.369 1.899.384 1.831.086-.376.071-1.229.284-1.584.14-.234.497-.445.687-.479.294-.052.655-.068.964-.008.249.049.586.345.677.487.218.344.342 1.317.379 1.658.015.141.074-.392.293-.736.406-.639 1.843-.763 1.898.639.025.654.02.624.02 1.064 0 .517-.012.828-.04 1.202-.031.4-.117 1.304-.242 1.742-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.191 1.813-.118.562-.079.566-.102.965-.023.398.121.922.121.922s-.802.104-1.234.035c-.391-.063-.875-.841-1-1.079-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.031-3.139.02 0 0 .185-1.011-.227-1.358-.305-.259-.83-.784-1.144-1.06z' stroke-linejoin='round'/><path d='m21.5664 21.7344v-3.459'/><path d='m19.5508 21.7461-.016-3.473'/><path d='m17.5547 18.3047.021 3.426'/></g></g></svg>")
70
+ --tl-cursor-pointer:
71
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m13.3315 21.3799c-.284-.359-.629-1.093-1.243-1.984-.348-.504-1.211-1.453-1.468-1.935-.223-.426-.199-.617-.146-.97.094-.628.738-1.117 1.425-1.051.519.049.959.392 1.355.716.239.195.533.574.71.788.163.196.203.277.377.509.23.307.302.459.214.121-.071-.496-.187-1.343-.355-2.092-.128-.568-.159-.657-.281-1.093-.129-.464-.195-.789-.316-1.281-.084-.348-.235-1.059-.276-1.459-.057-.547-.087-1.439.264-1.849.275-.321.906-.418 1.297-.22.512.259.803 1.003.936 1.3.239.534.387 1.151.516 1.961.164 1.031.466 2.462.476 2.763.024-.369-.068-1.146-.004-1.5.058-.321.328-.694.666-.795.286-.085.621-.116.916-.055.313.064.643.288.766.499.362.624.369 1.899.384 1.831.086-.376.071-1.229.284-1.584.14-.234.497-.445.687-.479.294-.052.655-.068.964-.008.249.049.586.345.677.487.218.344.342 1.317.379 1.658.015.141.074-.392.293-.736.406-.639 1.843-.763 1.898.639.025.654.02.624.02 1.064 0 .517-.012.828-.04 1.202-.031.4-.117 1.304-.242 1.742-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.191 1.813-.118.562-.079.566-.102.965-.023.398.121.922.121.922s-.802.104-1.234.035c-.391-.063-.875-.841-1-1.079-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.031-3.139.02 0 0 .185-1.011-.227-1.358-.305-.259-.83-.784-1.144-1.06z' fill='white'/><g stroke='black' stroke-linecap='round' stroke-width='.75'><path d='m13.3315 21.3799c-.284-.359-.629-1.093-1.243-1.984-.348-.504-1.211-1.453-1.468-1.935-.223-.426-.199-.617-.146-.97.094-.628.738-1.117 1.425-1.051.519.049.959.392 1.355.716.239.195.533.574.71.788.163.196.203.277.377.509.23.307.302.459.214.121-.071-.496-.187-1.343-.355-2.092-.128-.568-.159-.657-.281-1.093-.129-.464-.195-.789-.316-1.281-.084-.348-.235-1.059-.276-1.459-.057-.547-.087-1.439.264-1.849.275-.321.906-.418 1.297-.22.512.259.803 1.003.936 1.3.239.534.387 1.151.516 1.961.164 1.031.466 2.462.476 2.763.024-.369-.068-1.146-.004-1.5.058-.321.328-.694.666-.795.286-.085.621-.116.916-.055.313.064.643.288.766.499.362.624.369 1.899.384 1.831.086-.376.071-1.229.284-1.584.14-.234.497-.445.687-.479.294-.052.655-.068.964-.008.249.049.586.345.677.487.218.344.342 1.317.379 1.658.015.141.074-.392.293-.736.406-.639 1.843-.763 1.898.639.025.654.02.624.02 1.064 0 .517-.012.828-.04 1.202-.031.4-.117 1.304-.242 1.742-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.191 1.813-.118.562-.079.566-.102.965-.023.398.121.922.121.922s-.802.104-1.234.035c-.391-.063-.875-.841-1-1.079-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.031-3.139.02 0 0 .185-1.011-.227-1.358-.305-.259-.83-.784-1.144-1.06z' stroke-linejoin='round'/><path d='m21.5664 21.7344v-3.459'/><path d='m19.5508 21.7461-.016-3.473'/><path d='m17.5547 18.3047.021 3.426'/></g></g></svg>")
70
72
  14 10,
71
73
  pointer;
72
- --tl-cursor-cross: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m25 16h-6.01v-6h-2.98v6h-6.01v3h6.01v6h2.98v-6h6.01z' fill='white'/><path d='m23.9902 17.0103h-6v-6.01h-.98v6.01h-6v.98h6v6.01h.98v-6.01h6z' fill='%23231f1f'/></g></svg>")
74
+ --tl-cursor-cross:
75
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m25 16h-6.01v-6h-2.98v6h-6.01v3h6.01v6h2.98v-6h6.01z' fill='white'/><path d='m23.9902 17.0103h-6v-6.01h-.98v6.01h-6v.98h6v6.01h.98v-6.01h6z' fill='%23231f1f'/></g></svg>")
73
76
  16 16,
74
77
  crosshair;
75
- --tl-cursor-move: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m19 14h1v1h-1zm1 6h-1v-1h1zm-5-5h-1v-1h1zm0 5h-1v-1h1zm2-10.987-7.985 7.988 5.222 5.221 2.763 2.763 7.984-7.985z' fill='white'/><g fill='black'><path d='m23.5664 16.9971-2.557-2.809v1.829h-4.009-4.001v-1.829l-2.571 2.809 2.572 2.808-.001-1.808h4.001 4.009l-.001 1.808z'/><path d='m17.9873 17h.013v-4.001l1.807.001-2.807-2.571-2.809 2.57h1.809v4.001h.008v4.002l-1.828-.001 2.807 2.577 2.805-2.576h-1.805z'/></g></g></svg>")
78
+ --tl-cursor-move:
79
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m19 14h1v1h-1zm1 6h-1v-1h1zm-5-5h-1v-1h1zm0 5h-1v-1h1zm2-10.987-7.985 7.988 5.222 5.221 2.763 2.763 7.984-7.985z' fill='white'/><g fill='black'><path d='m23.5664 16.9971-2.557-2.809v1.829h-4.009-4.001v-1.829l-2.571 2.809 2.572 2.808-.001-1.808h4.001 4.009l-.001 1.808z'/><path d='m17.9873 17h.013v-4.001l1.807.001-2.807-2.571-2.809 2.57h1.809v4.001h.008v4.002l-1.828-.001 2.807 2.577 2.805-2.576h-1.805z'/></g></g></svg>")
76
80
  16 16,
77
81
  move;
78
- --tl-cursor-grab: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m13.5557 17.5742c-.098-.375-.196-.847-.406-1.552-.167-.557-.342-.859-.47-1.233-.155-.455-.303-.721-.496-1.181-.139-.329-.364-1.048-.457-1.44-.119-.509.033-.924.244-1.206.253-.339.962-.49 1.357-.351.371.13.744.512.916.788.288.46.357.632.717 1.542.393.992.564 1.918.611 2.231l.085.452c-.001-.04-.043-1.122-.044-1.162-.035-1.029-.06-1.823-.038-2.939.002-.126.064-.587.084-.715.078-.5.305-.8.673-.979.412-.201.926-.215 1.401-.017.423.173.626.55.687 1.022.014.109.094.987.093 1.107-.013 1.025.006 1.641.015 2.174.004.231.003 1.625.017 1.469.061-.656.094-3.189.344-3.942.144-.433.405-.746.794-.929.431-.203 1.113-.07 1.404.243.285.305.446.692.482 1.153.032.405-.019.897-.02 1.245 0 .867-.021 1.324-.037 2.121-.001.038-.015.298.023.182.094-.28.188-.542.266-.745.049-.125.241-.614.359-.859.114-.234.211-.369.415-.688.2-.313.415-.448.668-.561.54-.235 1.109.112 1.301.591.086.215.009.713-.028 1.105-.061.647-.254 1.306-.352 1.648-.128.447-.274 1.235-.34 1.601-.072.394-.234 1.382-.359 1.82-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.192 1.812-.117.563-.078.567-.101.965-.024.399.121.923.121.923s-.802.104-1.234.034c-.391-.062-.875-.841-1-1.078-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.03-3.139.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.284-.36-.629-1.093-1.243-1.985-.348-.504-1.027-1.085-1.284-1.579-.223-.425-.331-.954-.19-1.325.225-.594.675-.897 1.362-.832.519.05.848.206 1.238.537.225.19.573.534.75.748.163.195.203.276.377.509.23.307.302.459.214.121' fill='white'/><g stroke='black' stroke-linecap='round' stroke-width='.75'><path d='m13.5557 17.5742c-.098-.375-.196-.847-.406-1.552-.167-.557-.342-.859-.47-1.233-.155-.455-.303-.721-.496-1.181-.139-.329-.364-1.048-.457-1.44-.119-.509.033-.924.244-1.206.253-.339.962-.49 1.357-.351.371.13.744.512.916.788.288.46.357.632.717 1.542.393.992.564 1.918.611 2.231l.085.452c-.001-.04-.043-1.122-.044-1.162-.035-1.029-.06-1.823-.038-2.939.002-.126.064-.587.084-.715.078-.5.305-.8.673-.979.412-.201.926-.215 1.401-.017.423.173.626.55.687 1.022.014.109.094.987.093 1.107-.013 1.025.006 1.641.015 2.174.004.231.003 1.625.017 1.469.061-.656.094-3.189.344-3.942.144-.433.405-.746.794-.929.431-.203 1.113-.07 1.404.243.285.305.446.692.482 1.153.032.405-.019.897-.02 1.245 0 .867-.021 1.324-.037 2.121-.001.038-.015.298.023.182.094-.28.188-.542.266-.745.049-.125.241-.614.359-.859.114-.234.211-.369.415-.688.2-.313.415-.448.668-.561.54-.235 1.109.112 1.301.591.086.215.009.713-.028 1.105-.061.647-.254 1.306-.352 1.648-.128.447-.274 1.235-.34 1.601-.072.394-.234 1.382-.359 1.82-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.192 1.812-.117.563-.078.567-.101.965-.024.399.121.923.121.923s-.802.104-1.234.034c-.391-.062-.875-.841-1-1.078-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.03-3.139.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.284-.36-.629-1.093-1.243-1.985-.348-.504-1.027-1.085-1.284-1.579-.223-.425-.331-.954-.19-1.325.225-.594.675-.897 1.362-.832.519.05.848.206 1.238.537.225.19.573.534.75.748.163.195.203.276.377.509.23.307.302.459.214.121' stroke-linejoin='round'/><path d='m20.5664 21.7344v-3.459'/><path d='m18.5508 21.7461-.016-3.473'/><path d='m16.5547 18.3047.021 3.426'/></g></g></svg>")
82
+ --tl-cursor-grab:
83
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m13.5557 17.5742c-.098-.375-.196-.847-.406-1.552-.167-.557-.342-.859-.47-1.233-.155-.455-.303-.721-.496-1.181-.139-.329-.364-1.048-.457-1.44-.119-.509.033-.924.244-1.206.253-.339.962-.49 1.357-.351.371.13.744.512.916.788.288.46.357.632.717 1.542.393.992.564 1.918.611 2.231l.085.452c-.001-.04-.043-1.122-.044-1.162-.035-1.029-.06-1.823-.038-2.939.002-.126.064-.587.084-.715.078-.5.305-.8.673-.979.412-.201.926-.215 1.401-.017.423.173.626.55.687 1.022.014.109.094.987.093 1.107-.013 1.025.006 1.641.015 2.174.004.231.003 1.625.017 1.469.061-.656.094-3.189.344-3.942.144-.433.405-.746.794-.929.431-.203 1.113-.07 1.404.243.285.305.446.692.482 1.153.032.405-.019.897-.02 1.245 0 .867-.021 1.324-.037 2.121-.001.038-.015.298.023.182.094-.28.188-.542.266-.745.049-.125.241-.614.359-.859.114-.234.211-.369.415-.688.2-.313.415-.448.668-.561.54-.235 1.109.112 1.301.591.086.215.009.713-.028 1.105-.061.647-.254 1.306-.352 1.648-.128.447-.274 1.235-.34 1.601-.072.394-.234 1.382-.359 1.82-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.192 1.812-.117.563-.078.567-.101.965-.024.399.121.923.121.923s-.802.104-1.234.034c-.391-.062-.875-.841-1-1.078-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.03-3.139.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.284-.36-.629-1.093-1.243-1.985-.348-.504-1.027-1.085-1.284-1.579-.223-.425-.331-.954-.19-1.325.225-.594.675-.897 1.362-.832.519.05.848.206 1.238.537.225.19.573.534.75.748.163.195.203.276.377.509.23.307.302.459.214.121' fill='white'/><g stroke='black' stroke-linecap='round' stroke-width='.75'><path d='m13.5557 17.5742c-.098-.375-.196-.847-.406-1.552-.167-.557-.342-.859-.47-1.233-.155-.455-.303-.721-.496-1.181-.139-.329-.364-1.048-.457-1.44-.119-.509.033-.924.244-1.206.253-.339.962-.49 1.357-.351.371.13.744.512.916.788.288.46.357.632.717 1.542.393.992.564 1.918.611 2.231l.085.452c-.001-.04-.043-1.122-.044-1.162-.035-1.029-.06-1.823-.038-2.939.002-.126.064-.587.084-.715.078-.5.305-.8.673-.979.412-.201.926-.215 1.401-.017.423.173.626.55.687 1.022.014.109.094.987.093 1.107-.013 1.025.006 1.641.015 2.174.004.231.003 1.625.017 1.469.061-.656.094-3.189.344-3.942.144-.433.405-.746.794-.929.431-.203 1.113-.07 1.404.243.285.305.446.692.482 1.153.032.405-.019.897-.02 1.245 0 .867-.021 1.324-.037 2.121-.001.038-.015.298.023.182.094-.28.188-.542.266-.745.049-.125.241-.614.359-.859.114-.234.211-.369.415-.688.2-.313.415-.448.668-.561.54-.235 1.109.112 1.301.591.086.215.009.713-.028 1.105-.061.647-.254 1.306-.352 1.648-.128.447-.274 1.235-.34 1.601-.072.394-.234 1.382-.359 1.82-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.192 1.812-.117.563-.078.567-.101.965-.024.399.121.923.121.923s-.802.104-1.234.034c-.391-.062-.875-.841-1-1.078-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.03-3.139.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.284-.36-.629-1.093-1.243-1.985-.348-.504-1.027-1.085-1.284-1.579-.223-.425-.331-.954-.19-1.325.225-.594.675-.897 1.362-.832.519.05.848.206 1.238.537.225.19.573.534.75.748.163.195.203.276.377.509.23.307.302.459.214.121' stroke-linejoin='round'/><path d='m20.5664 21.7344v-3.459'/><path d='m18.5508 21.7461-.016-3.473'/><path d='m16.5547 18.3047.021 3.426'/></g></g></svg>")
79
84
  16 16,
80
85
  grab;
81
- --tl-cursor-grabbing: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m13.5732 12.0361c.48-.178 1.427-.069 1.677.473.213.462.396 1.241.406 1.075.024-.369-.024-1.167.137-1.584.117-.304.347-.59.686-.691.285-.086.62-.116.916-.055.313.064.642.287.765.499.362.623.368 1.899.385 1.831.064-.272.07-1.229.283-1.584.141-.235.497-.445.687-.479.294-.052.656-.068.964-.008.249.049.586.344.677.487.219.344.342 1.316.379 1.658.016.141.074-.393.293-.736.406-.639 1.844-.763 1.898.639.026.654.02.624.02 1.064 0 .516-.012.828-.04 1.202-.03.399-.116 1.304-.241 1.742-.086.301-.371.978-.653 1.384 0 0-1.074 1.25-1.191 1.812-.117.563-.078.567-.102.965-.023.399.121.923.121.923s-.801.104-1.234.034c-.391-.062-.875-.84-1-1.078-.172-.328-.539-.265-.682-.023-.224.383-.709 1.07-1.05 1.113-.669.084-2.055.03-3.14.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.283-.36-1.002-.929-1.243-1.985-.213-.936-.192-1.395.037-1.77.232-.381.67-.589.854-.625.208-.042.692-.039.875.062.223.123.313.159.488.391.23.307.312.456.213.121-.076-.262-.322-.595-.434-.97-.109-.361-.401-.943-.38-1.526.008-.221.103-.771.832-1.042' fill='white'/><g stroke='black' stroke-width='.75'><path d='m13.5732 12.0361c.48-.178 1.427-.069 1.677.473.213.462.396 1.241.406 1.075.024-.369-.024-1.167.137-1.584.117-.304.347-.59.686-.691.285-.086.62-.116.916-.055.313.064.642.287.765.499.362.623.368 1.899.385 1.831.064-.272.07-1.229.283-1.584.141-.235.497-.445.687-.479.294-.052.656-.068.964-.008.249.049.586.344.677.487.219.344.342 1.316.379 1.658.016.141.074-.393.293-.736.406-.639 1.844-.763 1.898.639.026.654.02.624.02 1.064 0 .516-.012.828-.04 1.202-.03.399-.116 1.304-.241 1.742-.086.301-.371.978-.653 1.384 0 0-1.074 1.25-1.191 1.812-.117.563-.078.567-.102.965-.023.399.121.923.121.923s-.801.104-1.234.034c-.391-.062-.875-.84-1-1.078-.172-.328-.539-.265-.682-.023-.224.383-.709 1.07-1.05 1.113-.669.084-2.055.03-3.14.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.283-.36-1.002-.929-1.243-1.985-.213-.936-.192-1.395.037-1.77.232-.381.67-.589.854-.625.208-.042.692-.039.875.062.223.123.313.159.488.391.23.307.312.456.213.121-.076-.262-.322-.595-.434-.97-.109-.361-.401-.943-.38-1.526.008-.221.103-.771.832-1.042z' stroke-linejoin='round'/><path d='m20.5664 19.7344v-3.459' stroke-linecap='round'/><path d='m18.5508 19.7461-.016-3.473' stroke-linecap='round'/><path d='m16.5547 16.3047.021 3.426' stroke-linecap='round'/></g></g></svg>")
86
+ --tl-cursor-grabbing:
87
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m13.5732 12.0361c.48-.178 1.427-.069 1.677.473.213.462.396 1.241.406 1.075.024-.369-.024-1.167.137-1.584.117-.304.347-.59.686-.691.285-.086.62-.116.916-.055.313.064.642.287.765.499.362.623.368 1.899.385 1.831.064-.272.07-1.229.283-1.584.141-.235.497-.445.687-.479.294-.052.656-.068.964-.008.249.049.586.344.677.487.219.344.342 1.316.379 1.658.016.141.074-.393.293-.736.406-.639 1.844-.763 1.898.639.026.654.02.624.02 1.064 0 .516-.012.828-.04 1.202-.03.399-.116 1.304-.241 1.742-.086.301-.371.978-.653 1.384 0 0-1.074 1.25-1.191 1.812-.117.563-.078.567-.102.965-.023.399.121.923.121.923s-.801.104-1.234.034c-.391-.062-.875-.84-1-1.078-.172-.328-.539-.265-.682-.023-.224.383-.709 1.07-1.05 1.113-.669.084-2.055.03-3.14.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.283-.36-1.002-.929-1.243-1.985-.213-.936-.192-1.395.037-1.77.232-.381.67-.589.854-.625.208-.042.692-.039.875.062.223.123.313.159.488.391.23.307.312.456.213.121-.076-.262-.322-.595-.434-.97-.109-.361-.401-.943-.38-1.526.008-.221.103-.771.832-1.042' fill='white'/><g stroke='black' stroke-width='.75'><path d='m13.5732 12.0361c.48-.178 1.427-.069 1.677.473.213.462.396 1.241.406 1.075.024-.369-.024-1.167.137-1.584.117-.304.347-.59.686-.691.285-.086.62-.116.916-.055.313.064.642.287.765.499.362.623.368 1.899.385 1.831.064-.272.07-1.229.283-1.584.141-.235.497-.445.687-.479.294-.052.656-.068.964-.008.249.049.586.344.677.487.219.344.342 1.316.379 1.658.016.141.074-.393.293-.736.406-.639 1.844-.763 1.898.639.026.654.02.624.02 1.064 0 .516-.012.828-.04 1.202-.03.399-.116 1.304-.241 1.742-.086.301-.371.978-.653 1.384 0 0-1.074 1.25-1.191 1.812-.117.563-.078.567-.102.965-.023.399.121.923.121.923s-.801.104-1.234.034c-.391-.062-.875-.84-1-1.078-.172-.328-.539-.265-.682-.023-.224.383-.709 1.07-1.05 1.113-.669.084-2.055.03-3.14.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.283-.36-1.002-.929-1.243-1.985-.213-.936-.192-1.395.037-1.77.232-.381.67-.589.854-.625.208-.042.692-.039.875.062.223.123.313.159.488.391.23.307.312.456.213.121-.076-.262-.322-.595-.434-.97-.109-.361-.401-.943-.38-1.526.008-.221.103-.771.832-1.042z' stroke-linejoin='round'/><path d='m20.5664 19.7344v-3.459' stroke-linecap='round'/><path d='m18.5508 19.7461-.016-3.473' stroke-linecap='round'/><path d='m16.5547 16.3047.021 3.426' stroke-linecap='round'/></g></g></svg>")
82
88
  16 16,
83
89
  grabbing;
84
- --tl-cursor-text: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path fill='white' d='M7.94 0a5.25 5.25 0 0 0-3.47 1.17A5.27 5.27 0 0 0 1 0H0v3h1c1.41 0 1.85.7 2 1v3.94H2v3h1v3c-.13.3-.57 1-2 1H0v3h1a5.27 5.27 0 0 0 3.47-1.17c.98.8 2.21 1.21 3.47 1.17h1v-3h-1c-1.41 0-1.85-.7-2-1v-3H7v-3H6V4c.13-.3.57-1 2-1h1V0H7.94z'/><path fill='black' d='M7.94 2V1a4 4 0 0 0-3.47 1.64A4 4 0 0 0 1 1v1c1.3-.17 2.56.6 3 1.84v5.1H3v1h1v4.16c-.45 1.24-1.7 2-3 1.84v1a4.05 4.05 0 0 0 3.47-1.63 4.05 4.05 0 0 0 3.47 1.63v-1A2.82 2.82 0 0 1 5 14.1V9.93h1v-1H5V3.85A2.81 2.81 0 0 1 7.94 2z'/></g></svg>")
90
+ --tl-cursor-text:
91
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path fill='white' d='M7.94 0a5.25 5.25 0 0 0-3.47 1.17A5.27 5.27 0 0 0 1 0H0v3h1c1.41 0 1.85.7 2 1v3.94H2v3h1v3c-.13.3-.57 1-2 1H0v3h1a5.27 5.27 0 0 0 3.47-1.17c.98.8 2.21 1.21 3.47 1.17h1v-3h-1c-1.41 0-1.85-.7-2-1v-3H7v-3H6V4c.13-.3.57-1 2-1h1V0H7.94z'/><path fill='black' d='M7.94 2V1a4 4 0 0 0-3.47 1.64A4 4 0 0 0 1 1v1c1.3-.17 2.56.6 3 1.84v5.1H3v1h1v4.16c-.45 1.24-1.7 2-3 1.84v1a4.05 4.05 0 0 0 3.47-1.63 4.05 4.05 0 0 0 3.47 1.63v-1A2.82 2.82 0 0 1 5 14.1V9.93h1v-1H5V3.85A2.81 2.81 0 0 1 7.94 2z'/></g></svg>")
85
92
  4 10,
86
93
  text;
87
- --tl-cursor-zoom-in: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5' fill='white'/><path d='m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5z' stroke='black'/><g fill='black'><path d='m18 14h-2v-2h-2v2h-2v1.98h2v2.02h2v-2.02h2z'/><path d='m23.5859 25 1.414-1.414-5.449-5.449-1.414 1.414z'/></g></g></svg>")
94
+ --tl-cursor-zoom-in:
95
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5' fill='white'/><path d='m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5z' stroke='black'/><g fill='black'><path d='m18 14h-2v-2h-2v2h-2v1.98h2v2.02h2v-2.02h2z'/><path d='m23.5859 25 1.414-1.414-5.449-5.449-1.414 1.414z'/></g></g></svg>")
88
96
  16 16,
89
97
  zoom-in;
90
- --tl-cursor-zoom-out: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5' fill='white'/><path d='m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5z' stroke='black'/><g fill='black'><path d='m18 16h-5.98v-1.98h5.98z'/><path d='m23.5859 25 1.414-1.414-5.449-5.449-1.414 1.414z'/></g></g></svg>")
98
+ --tl-cursor-zoom-out:
99
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5' fill='white'/><path d='m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5z' stroke='black'/><g fill='black'><path d='m18 16h-5.98v-1.98h5.98z'/><path d='m23.5859 25 1.414-1.414-5.449-5.449-1.414 1.414z'/></g></g></svg>")
91
100
  16 16,
92
101
  zoom-out;
93
102
 
@@ -114,10 +123,10 @@
114
123
  /* text outline */
115
124
  --a: calc(min(0.5, 1 / var(--tl-zoom)) * 2px);
116
125
  --b: calc(min(0.5, 1 / var(--tl-zoom)) * -2px);
117
- --tl-text-outline-reference: 0 var(--b) 0 var(--color-background),
118
- 0 var(--a) 0 var(--color-background), var(--b) var(--b) 0 var(--color-background),
119
- var(--a) var(--b) 0 var(--color-background), var(--a) var(--a) 0 var(--color-background),
120
- var(--b) var(--a) 0 var(--color-background);
126
+ --tl-text-outline-reference:
127
+ 0 var(--b) 0 var(--color-background), 0 var(--a) 0 var(--color-background),
128
+ var(--b) var(--b) 0 var(--color-background), var(--a) var(--b) 0 var(--color-background),
129
+ var(--a) var(--a) 0 var(--color-background), var(--b) var(--a) 0 var(--color-background);
121
130
  --tl-text-outline: var(--tl-text-outline-reference);
122
131
  /* own properties */
123
132
  position: relative;
@@ -168,11 +177,14 @@
168
177
  --color-laser: hsl(0, 100%, 50%);
169
178
  /* Shadows */
170
179
  --shadow-1: 0px 1px 2px hsl(0, 0%, 0%, 25%), 0px 1px 3px hsl(0, 0%, 0%, 9%);
171
- --shadow-2: 0px 0px 2px hsl(0, 0%, 0%, 16%), 0px 2px 3px hsl(0, 0%, 0%, 24%),
180
+ --shadow-2:
181
+ 0px 0px 2px hsl(0, 0%, 0%, 16%), 0px 2px 3px hsl(0, 0%, 0%, 24%),
172
182
  0px 2px 6px hsl(0, 0%, 0%, 0.1), inset 0px 0px 0px 1px var(--color-panel-contrast);
173
- --shadow-3: 0px 1px 2px hsl(0, 0%, 0%, 28%), 0px 2px 6px hsl(0, 0%, 0%, 14%),
183
+ --shadow-3:
184
+ 0px 1px 2px hsl(0, 0%, 0%, 28%), 0px 2px 6px hsl(0, 0%, 0%, 14%),
174
185
  inset 0px 0px 0px 1px var(--color-panel-contrast);
175
- --shadow-4: 0px 0px 3px hsl(0, 0%, 0%, 19%), 0px 5px 4px hsl(0, 0%, 0%, 16%),
186
+ --shadow-4:
187
+ 0px 0px 3px hsl(0, 0%, 0%, 19%), 0px 5px 4px hsl(0, 0%, 0%, 16%),
176
188
  0px 2px 16px hsl(0, 0%, 0%, 6%), inset 0px 0px 0px 1px var(--color-panel-contrast);
177
189
  }
178
190
 
@@ -215,11 +227,14 @@
215
227
  --color-text: hsl(210, 17%, 98%);
216
228
  --color-laser: hsl(0, 100%, 50%);
217
229
  /* Shadows */
218
- --shadow-1: 0px 1px 2px hsl(0, 0%, 0%, 16.1%), 0px 1px 3px hsl(0, 0%, 0%, 22%),
230
+ --shadow-1:
231
+ 0px 1px 2px hsl(0, 0%, 0%, 16.1%), 0px 1px 3px hsl(0, 0%, 0%, 22%),
219
232
  inset 0px 0px 0px 1px var(--color-panel-contrast);
220
- --shadow-2: 0px 1px 3px hsl(0, 0%, 0%, 66.6%), 0px 2px 6px hsl(0, 0%, 0%, 33%),
233
+ --shadow-2:
234
+ 0px 1px 3px hsl(0, 0%, 0%, 66.6%), 0px 2px 6px hsl(0, 0%, 0%, 33%),
221
235
  inset 0px 0px 0px 1px var(--color-panel-contrast);
222
- --shadow-3: 0px 1px 3px hsl(0, 0%, 0%, 50%), 0px 2px 12px hsl(0, 0%, 0%, 50%),
236
+ --shadow-3:
237
+ 0px 1px 3px hsl(0, 0%, 0%, 50%), 0px 2px 12px hsl(0, 0%, 0%, 50%),
223
238
  inset 0px 0px 0px 1px var(--color-panel-contrast);
224
239
  }
225
240
 
@@ -897,16 +912,17 @@ input,
897
912
  cursor: var(--tl-cursor-default);
898
913
  }
899
914
 
915
+ .tl-rich-text[data-is-ready-for-editing='true'],
916
+ .tl-text-wrapper[data-is-ready-for-editing='true'] .tl-text-input {
917
+ cursor: var(--tl-cursor-text);
918
+ }
919
+
900
920
  .tl-text-input::selection {
901
921
  background: var(--color-selected);
902
922
  color: var(--color-selected-contrast);
903
923
  text-shadow: none;
904
924
  }
905
925
 
906
- .tl-rich-text[data-iseditinganything='true'] {
907
- cursor: var(--tl-cursor-text);
908
- }
909
-
910
926
  .tl-rich-text .ProseMirror {
911
927
  word-wrap: break-word;
912
928
  overflow-wrap: break-word;
@@ -1421,13 +1437,17 @@ input,
1421
1437
  }
1422
1438
 
1423
1439
  .tl-frame-heading {
1440
+ --frame-padding-x: 6px;
1441
+ --frame-height: 24px;
1442
+ --frame-minimum-width: 32px;
1443
+ --frame-offset-width: 16px;
1424
1444
  display: flex;
1425
1445
  align-items: center;
1426
1446
  position: absolute;
1427
1447
  transform-origin: 0% 100%;
1428
1448
  overflow: hidden;
1429
1449
  max-width: 100%;
1430
- min-width: 32px;
1450
+ min-width: var(--frame-minimum-width);
1431
1451
  height: auto;
1432
1452
  font-size: 12px;
1433
1453
  padding-bottom: 4px;
@@ -1439,32 +1459,33 @@ input,
1439
1459
  /* scale from bottom left corner so we can pin it to the top left corner of the frame */
1440
1460
  transform-origin: 0% 100%;
1441
1461
  display: flex;
1442
- height: 100%;
1462
+ height: var(--frame-height);
1443
1463
  width: 100%;
1444
1464
  align-items: center;
1445
1465
  border-radius: var(--radius-1);
1446
- background-color: var(--color-background);
1447
1466
  }
1448
1467
 
1449
1468
  .tl-frame-label {
1450
1469
  pointer-events: all;
1451
1470
  overflow: hidden;
1452
1471
  text-overflow: ellipsis;
1453
- padding: var(--space-3) var(--space-3);
1472
+ padding: 0px var(--frame-padding-x);
1473
+ border-radius: var(--radius-1);
1454
1474
  position: relative;
1455
1475
  font-size: inherit;
1456
1476
  white-space: pre;
1457
- border: 1px solid transparent;
1458
1477
  }
1459
1478
 
1460
1479
  .tl-frame-label__editing {
1461
1480
  color: transparent;
1462
1481
  white-space: pre;
1463
1482
  width: auto;
1483
+ min-width: var(--frame-minimum-width);
1484
+ height: 100%;
1464
1485
  overflow: visible;
1465
1486
  background-color: var(--color-panel);
1466
- border-radius: var(--radius-1);
1467
1487
  border-color: var(--color-selected);
1488
+ box-shadow: inset 0px 0px 0px 1.5px var(--color-selected);
1468
1489
  }
1469
1490
 
1470
1491
  .tl-frame-name-input {
@@ -1472,7 +1493,7 @@ input,
1472
1493
  border: none;
1473
1494
  background: none;
1474
1495
  outline: none;
1475
- padding: var(--space-3) var(--space-3);
1496
+ padding: 0px var(--frame-padding-x);
1476
1497
  inset: 0px;
1477
1498
  height: 100%;
1478
1499
  width: 100%;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tldraw/editor",
3
3
  "description": "A tiny little drawing app (editor).",
4
- "version": "3.12.0-canary.a6c2905c622f",
4
+ "version": "3.12.0-canary.a880bf3ec9cb",
5
5
  "author": {
6
6
  "name": "tldraw Inc.",
7
7
  "email": "hello@tldraw.com"
@@ -48,12 +48,12 @@
48
48
  "@tiptap/core": "^2.9.1",
49
49
  "@tiptap/pm": "^2.9.1",
50
50
  "@tiptap/react": "^2.9.1",
51
- "@tldraw/state": "3.12.0-canary.a6c2905c622f",
52
- "@tldraw/state-react": "3.12.0-canary.a6c2905c622f",
53
- "@tldraw/store": "3.12.0-canary.a6c2905c622f",
54
- "@tldraw/tlschema": "3.12.0-canary.a6c2905c622f",
55
- "@tldraw/utils": "3.12.0-canary.a6c2905c622f",
56
- "@tldraw/validate": "3.12.0-canary.a6c2905c622f",
51
+ "@tldraw/state": "3.12.0-canary.a880bf3ec9cb",
52
+ "@tldraw/state-react": "3.12.0-canary.a880bf3ec9cb",
53
+ "@tldraw/store": "3.12.0-canary.a880bf3ec9cb",
54
+ "@tldraw/tlschema": "3.12.0-canary.a880bf3ec9cb",
55
+ "@tldraw/utils": "3.12.0-canary.a880bf3ec9cb",
56
+ "@tldraw/validate": "3.12.0-canary.a880bf3ec9cb",
57
57
  "@types/core-js": "^2.5.8",
58
58
  "@use-gesture/react": "^10.3.1",
59
59
  "classnames": "^2.5.1",