@weasel-js/geom 1.13.0 → 1.14.1

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 (50) hide show
  1. package/README.md +6 -2
  2. package/dist/3d/index.d.ts +8 -1
  3. package/dist/3d/index.js +25 -1
  4. package/dist/3d/index.js.map +1 -1
  5. package/dist/booleans/index.d.ts +6 -5
  6. package/dist/booleans/index.js +583 -73
  7. package/dist/booleans/index.js.map +1 -1
  8. package/dist/{chunk-CE7IY7TB.js → chunk-2N6OWA7E.js} +3 -3
  9. package/dist/{chunk-CE7IY7TB.js.map → chunk-2N6OWA7E.js.map} +1 -1
  10. package/dist/{chunk-Q66NA2FU.js → chunk-3HQJGI63.js} +8 -5
  11. package/dist/chunk-3HQJGI63.js.map +1 -0
  12. package/dist/{chunk-YPWFGFQX.js → chunk-3YH5XU3H.js} +125 -8
  13. package/dist/chunk-3YH5XU3H.js.map +1 -0
  14. package/dist/{chunk-UI3FUWXM.js → chunk-42TZDN5C.js} +4 -4
  15. package/dist/{chunk-UI3FUWXM.js.map → chunk-42TZDN5C.js.map} +1 -1
  16. package/dist/{chunk-B53BERKG.js → chunk-B3D6KWW3.js} +110 -8
  17. package/dist/chunk-B3D6KWW3.js.map +1 -0
  18. package/dist/{chunk-2PKPKU4P.js → chunk-EURWZUNY.js} +25 -22
  19. package/dist/chunk-EURWZUNY.js.map +1 -0
  20. package/dist/{chunk-VHXOCDZ2.js → chunk-FROQPADA.js} +6 -6
  21. package/dist/{chunk-VHXOCDZ2.js.map → chunk-FROQPADA.js.map} +1 -1
  22. package/dist/{chunk-UGE57OTX.js → chunk-GWSJQSQE.js} +11 -8
  23. package/dist/chunk-GWSJQSQE.js.map +1 -0
  24. package/dist/chunk-XXNK4N7Z.js +683 -0
  25. package/dist/chunk-XXNK4N7Z.js.map +1 -0
  26. package/dist/chunk-ZOMUTU7J.js +249 -0
  27. package/dist/chunk-ZOMUTU7J.js.map +1 -0
  28. package/dist/{curvature-PkoLduGc.d.ts → curvature-CDOI32hv.d.ts} +46 -3
  29. package/dist/curves/index.d.ts +2 -2
  30. package/dist/curves/index.js +4 -4
  31. package/dist/index.d.ts +172 -45
  32. package/dist/index.js +244 -178
  33. package/dist/index.js.map +1 -1
  34. package/dist/nd/index.d.ts +28 -1
  35. package/dist/nd/index.js +27 -675
  36. package/dist/nd/index.js.map +1 -1
  37. package/dist/{path-BW8d_2RY.d.ts → path-t80OoJnM.d.ts} +11 -0
  38. package/dist/tessellate/index.d.ts +11 -4
  39. package/dist/tessellate/index.js +4 -4
  40. package/dist/warp/index.d.ts +1 -1
  41. package/dist/warp/index.js +238 -64
  42. package/dist/warp/index.js.map +1 -1
  43. package/package.json +1 -1
  44. package/dist/chunk-2PKPKU4P.js.map +0 -1
  45. package/dist/chunk-B53BERKG.js.map +0 -1
  46. package/dist/chunk-Q66NA2FU.js.map +0 -1
  47. package/dist/chunk-STGSBIOL.js +0 -152
  48. package/dist/chunk-STGSBIOL.js.map +0 -1
  49. package/dist/chunk-UGE57OTX.js.map +0 -1
  50. package/dist/chunk-YPWFGFQX.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,22 +1,23 @@
1
- import { carryCorners, evalSeg, parseSubpaths, keepCorners, anchorRange, subSeg, writePath, derivSeg } from './chunk-YPWFGFQX.js';
2
- export { CORNER_RESTORE_TOLERANCE, cornerTraces, keepCorners, restoreCorners } from './chunk-YPWFGFQX.js';
1
+ import { carryCorners, parseSubpaths, intersectSegments, evalSeg, keepCorners, anchorRange, subSeg, writePath, derivSeg } from './chunk-3YH5XU3H.js';
2
+ export { CORNER_RESTORE_TOLERANCE, cornerTraces, intersectSegments, keepCorners, restoreCorners } from './chunk-3YH5XU3H.js';
3
+ import { createBvh } from './chunk-XXNK4N7Z.js';
3
4
  import { PORT_REACH, portControls, portCurvePoints } from './chunk-YQADYJJ7.js';
4
5
  export { PORT_REACH } from './chunk-YQADYJJ7.js';
5
- import { cubicDerivativeAt, cubicCurvatureAt } from './chunk-UI3FUWXM.js';
6
- export { SPIRO_KINDS, combTeeth, cubicCurvatureAt, cubicCurvatureSource, cubicDerivativeAt, curvatureComb, eulerAngleAt, eulerCurvatureAt, eulerCurvatureDerivativesAt, eulerPointAt, fitEulerSegment, isSpiroKind, placeEulerSegment, solveSpiro, spiroContoursFromControl, spiroContoursOf, spiroControlPath, spiroToPath } from './chunk-UI3FUWXM.js';
7
- import { extractPolylines } from './chunk-VHXOCDZ2.js';
8
- import { boundsOfPath, fitPointRun, keepCorner } from './chunk-STGSBIOL.js';
9
- export { boundsOfPath } from './chunk-STGSBIOL.js';
10
- import { countPathAnchors, pathToAnchors, anchorsToPath, isAnchorSmooth, segmentEnds, isStraightSegment, nearestSegmentT } from './chunk-Q66NA2FU.js';
11
- export { anchorsToPath, countPathAnchors, isAnchorSmooth, isStraightSegment, nearestSegmentT, pathToAnchors, segmentEnds } from './chunk-Q66NA2FU.js';
12
- import { nearestOnLine, nearestOnPath, nearestOnQuadratic, nearestOnCubic } from './chunk-CE7IY7TB.js';
13
- export { nearestOnCubic, nearestOnLine, nearestOnPath, nearestOnQuadratic } from './chunk-CE7IY7TB.js';
14
- import { resolveCorners, pointInPolygon, cornerCuts, fillsOpenSubpaths, schneiderFit, fitCubicWithTangents, flattenCubic, pointSegmentDist2, flattenQuadratic, DEFAULT_FLATTEN_TOLERANCE, segmentsCross } from './chunk-2PKPKU4P.js';
15
- export { CORNER_FIT_TOLERANCE, CORNER_KEYWORDS, DEFAULT_FLATTEN_TOLERANCE, cornerCenter, cornerCuts, cornerFrameAt, cornerFrames, cornerKeywordOf, cornerShapeK, cornerShapePieces, cornerShapePoint, defaultOpenFill, fillsOpenSubpaths, fitCubicWithTangents, flattenCubic, flattenCubicWithArcLen, flattenQuadratic, flattenQuadraticWithArcLen, isCornerShape, nextCornerShape, pointInPolygon, pointSegmentDist2, remapPerAnchor, resolveCorners, resolveCornersWithSources, schneiderFit, segmentsCross, setDefaultOpenFill } from './chunk-2PKPKU4P.js';
6
+ import { cubicDerivativeAt, cubicCurvatureAt } from './chunk-42TZDN5C.js';
7
+ export { SPIRO_KINDS, combTeeth, cubicCurvatureAt, cubicCurvatureSource, cubicDerivativeAt, curvatureComb, eulerAngleAt, eulerCurvatureAt, eulerCurvatureDerivativesAt, eulerPointAt, fitEulerSegment, isSpiroKind, placeEulerSegment, solveSpiro, spiroContoursFromControl, spiroContoursOf, spiroControlPath, spiroToPath } from './chunk-42TZDN5C.js';
8
+ import { extractPolylines } from './chunk-FROQPADA.js';
9
+ import { boundsOfPath, fitPointRun, keepCorner } from './chunk-ZOMUTU7J.js';
10
+ export { boundsOfPath } from './chunk-ZOMUTU7J.js';
11
+ import { countPathAnchors, pathToAnchors, anchorsToPath, isAnchorSmooth, segmentEnds, isStraightSegment, nearestSegmentT } from './chunk-3HQJGI63.js';
12
+ export { anchorsToPath, countPathAnchors, isAnchorSmooth, isStraightSegment, nearestSegmentT, pathToAnchors, segmentEnds } from './chunk-3HQJGI63.js';
13
+ import { nearestOnLine, nearestOnPath, nearestOnQuadratic, nearestOnCubic } from './chunk-2N6OWA7E.js';
14
+ export { nearestOnCubic, nearestOnLine, nearestOnPath, nearestOnQuadratic } from './chunk-2N6OWA7E.js';
15
+ import { resolveCorners, pointInPolygon, cornerCuts, fillsOpenSubpaths, schneiderFit, fitCubicWithTangents, flattenCubic, pointSegmentDist2, flattenQuadratic, DEFAULT_FLATTEN_TOLERANCE, segmentsCross, tangentAt } from './chunk-EURWZUNY.js';
16
+ export { CORNER_FIT_TOLERANCE, CORNER_KEYWORDS, DEFAULT_FLATTEN_TOLERANCE, cornerCenter, cornerCuts, cornerFrameAt, cornerFrames, cornerKeywordOf, cornerShapeK, cornerShapePieces, cornerShapePoint, defaultOpenFill, fillsOpenSubpaths, fitCubicWithTangents, flattenCubic, flattenCubicWithArcLen, flattenQuadratic, flattenQuadraticWithArcLen, isCornerShape, nextCornerShape, pointInPolygon, pointSegmentDist2, remapPerAnchor, resolveCorners, resolveCornersWithSources, schneiderFit, segmentsCross, setDefaultOpenFill } from './chunk-EURWZUNY.js';
16
17
  import { SINGULAR_RATIO, clamp } from './chunk-755Y4YZS.js';
17
18
  export { EPS, approxEq, clamp, cross, dot, len2, sign, sub } from './chunk-755Y4YZS.js';
18
- import { PATH_M, PATH_L, PATH_C, PATH_Q, PATH_Z, PathBuilder, withCorner, scaleCorners, forEachSegment, pathCommandCoordCount, withoutCorners, elevateQuadraticToCubic, cubicEvalAt, cubicPointAt, splitCubicAtT, cubicAxisExtremaTs, rectToContour, splitCubicAt } from './chunk-B53BERKG.js';
19
- export { PATH_C, PATH_CMD_LENGTHS, PATH_COMMANDS, PATH_L, PATH_M, PATH_Q, PATH_Z, PathBuilder, asPolygonPath, boundsOfCoords, boxContainsBox, boxContainsPoint, compactCorners, cornerAt, cornerSpecAt, cubicAxisExtremaTs, cubicBounds, cubicEvalAt, cubicPointAt, elevateQuadraticToCubic, ellipsePath, forEachSegment, hasCorners, lerpCorners, linePath, pathCommandCoordCount, polygonFromPoints, polylineFromPoints, quadraticEvalAt, rectPath, rectToContour, regularPolygonPath, scaleCorners, splitCubicAt, splitCubicAtT, splitLineAt, splitQuadraticAt, starPath, unionBox, withCorner, withoutCorners } from './chunk-B53BERKG.js';
19
+ import { worldCoords, PATH_M, PATH_L, PATH_C, PATH_Q, PATH_Z, PathBuilder, withCorner, scaleCorners, originFor, coordsFrom, forEachSegment, pathCommandCoordCount, withoutCorners, elevateQuadraticToCubic, cubicEvalAt, cubicPointAt, splitCubicAtT, cubicAxisExtremaTs, rectToContour, splitCubicAt } from './chunk-B3D6KWW3.js';
20
+ export { ORIGIN_THRESHOLD, PATH_C, PATH_CMD_LENGTHS, PATH_COMMANDS, PATH_L, PATH_M, PATH_Q, PATH_Z, PathBuilder, addOrigin, asPolygonPath, boundsOfCoords, boxContainsBox, boxContainsPoint, compactCorners, coordsFrom, cornerAt, cornerSpecAt, cubicAxisExtremaTs, cubicBounds, cubicEvalAt, cubicPointAt, elevateQuadraticToCubic, ellipsePath, forEachSegment, hasCorners, joinPaths, lerpCorners, linePath, originFor, originOf, pathCommandCoordCount, pathPoint, polygonFromPoints, polylineFromPoints, quadraticEvalAt, rectPath, rectToContour, regularPolygonPath, scaleCorners, splitCubicAt, splitCubicAtT, splitLineAt, splitQuadraticAt, starPath, unionBox, withCorner, withoutCorners, worldCoords } from './chunk-B3D6KWW3.js';
20
21
 
21
22
  // src/view.ts
22
23
  var ZOOM_FLOOR = 1e-9;
@@ -440,25 +441,26 @@ function pathShape(path, options = {}) {
440
441
  // src/track/run.ts
441
442
  var pointsDown = (normal2) => normal2.y > 1e-9;
442
443
  function trackRun(shape, from = 0, to = 1, options = {}) {
443
- const { side = "auto", about = (from + to) / 2 } = options;
444
+ const { side = "auto", about = (from + to) / 2, direction = "ltr" } = options;
445
+ const rtl = direction === "rtl";
444
446
  const mid = shape.at(about);
445
447
  const flipped = side === "auto" ? pointsDown(mid.normal) : side === "flipped";
446
448
  const sgn = flipped ? -1 : 1;
447
449
  const reading = (n) => ({ x: -(sgn * n.y), y: sgn * n.x });
448
450
  const r0 = reading(mid.normal);
449
- const reversed3 = r0.x * mid.tangent.x + r0.y * mid.tangent.y < 0;
451
+ const reversed3 = r0.x * mid.tangent.x + r0.y * mid.tangent.y < 0 !== rtl;
450
452
  const span = to - from;
451
453
  const lo = Math.min(from, to);
452
454
  const hi = Math.max(from, to);
453
- const toF = (g) => reversed3 ? to - g * span : from + g * span;
455
+ const toShape = (g) => reversed3 ? to - g * span : from + g * span;
454
456
  const at2 = (g, options2) => {
455
- const s = options2?.open ? shape.at(toF(g), options2) : shape.at(toF(clamp(g, 0, 1)));
457
+ const s = options2?.open ? shape.at(toShape(g), options2) : shape.at(toShape(clamp(g, 0, 1)));
456
458
  const dir = reading(s.normal);
457
459
  const angle = Math.atan2(dir.y, dir.x) * 180 / Math.PI;
458
460
  const normal2 = { x: sgn * s.normal.x, y: sgn * s.normal.y };
459
461
  return {
460
462
  point: s.point,
461
- tangent: dir,
463
+ tangent: rtl ? { x: -dir.x, y: -dir.y } : dir,
462
464
  normal: normal2,
463
465
  angle: angle === 0 ? 0 : angle === -180 ? 180 : angle,
464
466
  turned: pointsDown(normal2)
@@ -470,7 +472,7 @@ function trackRun(shape, from = 0, to = 1, options = {}) {
470
472
  const q = shape.at(f).point;
471
473
  const dist = Math.hypot(p.x - q.x, p.y - q.y);
472
474
  if (!options2?.open) return { f: toG(f), dist };
473
- return { f: toG(shape.nearest(p, { open: true, about: toF(options2.about ?? 0.5) }).f), dist };
475
+ return { f: toG(shape.nearest(p, { open: true, about: toShape(options2.about ?? 0.5) }).f), dist };
474
476
  };
475
477
  return {
476
478
  kind: shape.kind,
@@ -481,7 +483,9 @@ function trackRun(shape, from = 0, to = 1, options = {}) {
481
483
  to,
482
484
  flipped,
483
485
  reversed: reversed3,
486
+ direction,
484
487
  at: at2,
488
+ toShape,
485
489
  nearest
486
490
  };
487
491
  }
@@ -495,7 +499,7 @@ function pathToD(given) {
495
499
  return `M${num(x)} ${num(y)}h${num(width)}v${num(height)}h${num(-width)}Z`;
496
500
  }
497
501
  const cmds = path.commands;
498
- const xs = path.coords;
502
+ const xs = worldCoords(path);
499
503
  const out = [];
500
504
  let ci = 0;
501
505
  for (let i = 0; i < cmds.length; i++) {
@@ -732,7 +736,9 @@ function portCurvePoints2(ax, ay, bx, by, outNormal, inNormal, samples, reach =
732
736
 
733
737
  // src/pathSubpaths.ts
734
738
  function flatSubpaths(path, tolerance) {
735
- const { commands, coords } = resolveCorners(path);
739
+ const drawn = resolveCorners(path);
740
+ const { commands } = drawn;
741
+ const coords = worldCoords(drawn);
736
742
  const closed = [];
737
743
  const open = [];
738
744
  let sub3 = [];
@@ -1174,7 +1180,7 @@ function unionBoundsPath(paths) {
1174
1180
 
1175
1181
  // src/paths/transformPath.ts
1176
1182
  var AXIS_ALIGNED_EPSILON = 1e-9;
1177
- function transformPath(path, m) {
1183
+ function transformPath(path, m, opts = {}) {
1178
1184
  const [a, b, c, d, e, f] = m;
1179
1185
  if (path.kind === "rect") {
1180
1186
  if (Math.abs(b) < AXIS_ALIGNED_EPSILON && Math.abs(c) < AXIS_ALIGNED_EPSILON) {
@@ -1190,15 +1196,25 @@ function transformPath(path, m) {
1190
1196
  height: Math.abs(y1 - y0)
1191
1197
  };
1192
1198
  }
1193
- const poly = new PathBuilder().moveTo(path.x, path.y).lineTo(path.x + path.width, path.y).lineTo(path.x + path.width, path.y + path.height).lineTo(path.x, path.y + path.height).close().build();
1194
- return transformPolygon(poly, m);
1199
+ const poly = new PathBuilder().autoOrigin().moveTo(path.x, path.y).lineTo(path.x + path.width, path.y).lineTo(path.x + path.width, path.y + path.height).lineTo(path.x, path.y + path.height).close().build();
1200
+ return transformPolygon(poly, m, opts);
1195
1201
  }
1196
- return transformPolygon(path, m);
1202
+ return transformPolygon(path, m, opts);
1197
1203
  }
1198
- function transformPolygon(path, m) {
1199
- const mapped = transformCoords(path.coords, m);
1204
+ function transformPolygon(path, m, opts) {
1200
1205
  const scaled2 = scaleCorners(path, Math.sqrt(Math.abs(m[0] * m[3] - m[1] * m[2])));
1201
- return { ...scaled2, coords: Float32Array.from(mapped) };
1206
+ const o = path.origin;
1207
+ if (o === void 0) {
1208
+ const mapped = transformCoords(path.coords, m);
1209
+ const picked = opts.autoOrigin !== false ? originFor(mapped) : void 0;
1210
+ return picked ? { ...scaled2, coords: coordsFrom(picked, mapped), origin: picked } : { ...scaled2, coords: Float32Array.from(mapped) };
1211
+ }
1212
+ const [a, b, c, d, e, f] = m;
1213
+ return {
1214
+ ...scaled2,
1215
+ coords: Float32Array.from(transformCoords(path.coords, [a, b, c, d, 0, 0])),
1216
+ origin: { x: a * o.x + c * o.y + e, y: b * o.x + d * o.y + f }
1217
+ };
1202
1218
  }
1203
1219
 
1204
1220
  // src/paths/transform.ts
@@ -1209,6 +1225,8 @@ function translatePath(path, dx2, dy2) {
1209
1225
  return translatePolygonCopy(path, dx2, dy2);
1210
1226
  }
1211
1227
  function translatePolygonCopy(path, dx2, dy2) {
1228
+ const o = path.origin;
1229
+ if (o) return { ...path, coords: path.coords.slice(), origin: { x: o.x + dx2, y: o.y + dy2 } };
1212
1230
  const next = new Float32Array(path.coords.length);
1213
1231
  const { commands, coords } = path;
1214
1232
  forEachSegment(commands, coords, (cmd, ci) => {
@@ -1529,7 +1547,7 @@ var ARG_COUNTS = {
1529
1547
  };
1530
1548
  function pathFromD(d, onWarn) {
1531
1549
  const tokens = tokenize(d);
1532
- const b = new PathBuilder();
1550
+ const b = new PathBuilder().autoOrigin();
1533
1551
  const st = {
1534
1552
  x: 0,
1535
1553
  y: 0,
@@ -1797,7 +1815,9 @@ function pathToCubicContours(path) {
1797
1815
  if (current.segs.length > 0) out.push(current);
1798
1816
  current = null;
1799
1817
  };
1800
- const { commands, coords } = resolveCorners(path);
1818
+ const drawn = resolveCorners(path);
1819
+ const { commands } = drawn;
1820
+ const coords = worldCoords(drawn);
1801
1821
  forEachSegment(commands, coords, (cmd, ci, px, py, _i, opens) => {
1802
1822
  if (opens) {
1803
1823
  current = { segs: [], closed: false };
@@ -2105,6 +2125,103 @@ function repeatAlongPath(shape, path, opts = {}) {
2105
2125
  });
2106
2126
  }
2107
2127
 
2128
+ // src/paths/contourSamples.ts
2129
+ function sampleAt({ c, line }, t) {
2130
+ const [x, y] = cubicEvalAt(...c, t);
2131
+ const seg = { line, p0: { x: c[0], y: c[1] }, c1: { x: c[2], y: c[3] }, c2: { x: c[4], y: c[5] }, p3: { x: c[6], y: c[7] } };
2132
+ return { at: { x, y }, dir: tangentAt(seg, t) };
2133
+ }
2134
+ function sampleContour(contour, pieces) {
2135
+ const out = [];
2136
+ for (const seg of contour.segs) for (let k = 0; k < pieces; k++) out.push(sampleAt(seg, k / pieces));
2137
+ const last = contour.segs.at(-1);
2138
+ if (!contour.closed && last !== void 0) out.push(sampleAt(last, 1));
2139
+ return out;
2140
+ }
2141
+ function polylineContour(points, closed) {
2142
+ const segs = [];
2143
+ for (let i = 1; i < points.length; i++) {
2144
+ segs.push(lineSegment(points[i - 1].x, points[i - 1].y, points[i].x, points[i].y));
2145
+ }
2146
+ return { segs, closed };
2147
+ }
2148
+ function countParam(value, fallback, min = 0) {
2149
+ const v = value === void 0 || !Number.isFinite(value) ? fallback : Math.round(value);
2150
+ return Math.max(min, Math.min(v, 1e3));
2151
+ }
2152
+
2153
+ // src/paths/roughenPath.ts
2154
+ function hash01(seed, i, k) {
2155
+ let h = Math.imul((seed | 0) ^ 625341585, 2654435761) ^ Math.imul(i + 1, 2246822519) ^ Math.imul(k + 1, 3266489917);
2156
+ h = Math.imul(h ^ h >>> 16, 2146121005);
2157
+ h = Math.imul(h ^ h >>> 15, 2221713035);
2158
+ h ^= h >>> 16;
2159
+ return (h >>> 0) / 4294967296;
2160
+ }
2161
+ function roughenPath(path, opts) {
2162
+ const { size, seed = 0 } = opts;
2163
+ if (!(size > 0 && Number.isFinite(size))) return path;
2164
+ const pieces = countParam(opts.detail, 4) + 1;
2165
+ const contours = pathToCubicContours(path).map((contour, r) => polylineContour(
2166
+ sampleContour(contour, pieces).map(({ at: at2 }, i) => ({
2167
+ x: at2.x + (hash01(seed, r * 65536 + i, 0) * 2 - 1) * size,
2168
+ y: at2.y + (hash01(seed, r * 65536 + i, 1) * 2 - 1) * size
2169
+ })),
2170
+ contour.closed
2171
+ ));
2172
+ return cubicContoursToPath(contours, path.kind === "polygon" ? path.fillRule : "nonzero");
2173
+ }
2174
+
2175
+ // src/paths/zigzagPath.ts
2176
+ function zigzagPath(path, opts) {
2177
+ const { size, smooth = false } = opts;
2178
+ if (!(size !== 0 && Number.isFinite(size))) return path;
2179
+ const pieces = countParam(opts.ridges, 4) + 1;
2180
+ const contours = pathToCubicContours(path).map((contour) => {
2181
+ let normal2 = { x: 0, y: 0 };
2182
+ const points = sampleContour(contour, pieces).map(({ at: at2, dir }, i) => {
2183
+ if (dir) normal2 = { x: -dir.y, y: dir.x };
2184
+ const side = i % 2 === 0 ? size : -size;
2185
+ return { x: at2.x + normal2.x * side, y: at2.y + normal2.y * side };
2186
+ });
2187
+ return smooth ? smoothThrough(points, contour.closed) : polylineContour(points, contour.closed);
2188
+ });
2189
+ return cubicContoursToPath(contours, path.kind === "polygon" ? path.fillRule : "nonzero");
2190
+ }
2191
+ function smoothThrough(points, closed) {
2192
+ const n = points.length;
2193
+ const at2 = (i) => closed ? points[(i + n) % n] : points[Math.max(0, Math.min(n - 1, i))];
2194
+ const reach = (i) => ({ x: (at2(i + 1).x - at2(i - 1).x) / 6, y: (at2(i + 1).y - at2(i - 1).y) / 6 });
2195
+ const segs = [];
2196
+ for (let i = 0; i < (closed ? n : n - 1); i++) {
2197
+ const a = at2(i);
2198
+ const b = at2(i + 1);
2199
+ const ra = reach(i);
2200
+ const rb = reach(i + 1);
2201
+ segs.push({ c: [a.x, a.y, a.x + ra.x, a.y + ra.y, b.x - rb.x, b.y - rb.y, b.x, b.y], line: false });
2202
+ }
2203
+ return { segs, closed };
2204
+ }
2205
+
2206
+ // src/paths/puckerBloatPath.ts
2207
+ function puckerBloatPath(path, opts) {
2208
+ const { amount } = opts;
2209
+ if (!(amount !== 0 && Number.isFinite(amount))) return path;
2210
+ const b = boundsOfPath(path);
2211
+ const cx = b.x + b.width / 2;
2212
+ const cy = b.y + b.height / 2;
2213
+ const handle = (x, y) => [x + (x - cx) * amount, y + (y - cy) * amount];
2214
+ const anchor = (x, y) => [x - (x - cx) * amount / 2, y - (y - cy) * amount / 2];
2215
+ const contours = pathToCubicContours(path).map(({ segs, closed }) => ({
2216
+ closed,
2217
+ segs: segs.map(({ c }) => ({
2218
+ c: [...anchor(c[0], c[1]), ...handle(c[2], c[3]), ...handle(c[4], c[5]), ...anchor(c[6], c[7])],
2219
+ line: false
2220
+ }))
2221
+ }));
2222
+ return cubicContoursToPath(contours, path.kind === "polygon" ? path.fillRule : "nonzero");
2223
+ }
2224
+
2108
2225
  // src/paths/pathDistance.ts
2109
2226
  function pointToRectPerimeterDist(px, py, rx, ry, rw, rh) {
2110
2227
  const dx2 = Math.max(rx - px, px - (rx + rw), 0);
@@ -2119,116 +2236,7 @@ function pathDistanceToPoint(path, px, py) {
2119
2236
  return pointToRectPerimeterDist(px, py, path.x, path.y, path.width, path.height);
2120
2237
  }
2121
2238
  const drawn = resolveCorners(path);
2122
- return nearestOnPath(drawn.commands, drawn.coords, px, py)?.dist ?? Infinity;
2123
- }
2124
-
2125
- // src/intersect/segmentIntersections.ts
2126
- var FLAT = 1e-4;
2127
- var MAX_DEPTH = 48;
2128
- var SAME_T = 1e-7;
2129
- var MAX_HITS = 16;
2130
- function boxOf(pts) {
2131
- let x0 = Infinity, y0 = Infinity, x1 = -Infinity, y1 = -Infinity;
2132
- for (const p of pts) {
2133
- if (p.x < x0) x0 = p.x;
2134
- if (p.x > x1) x1 = p.x;
2135
- if (p.y < y0) y0 = p.y;
2136
- if (p.y > y1) y1 = p.y;
2137
- }
2138
- return [x0, y0, x1, y1];
2139
- }
2140
- function flatness(pts) {
2141
- if (pts.length === 2) return 0;
2142
- const a = pts[0], b = pts[pts.length - 1];
2143
- const dx2 = b.x - a.x, dy2 = b.y - a.y;
2144
- const len = Math.hypot(dx2, dy2);
2145
- let worst2 = 0;
2146
- for (let i = 1; i < pts.length - 1; i++) {
2147
- const p = pts[i];
2148
- const d = len === 0 ? Math.hypot(p.x - a.x, p.y - a.y) : Math.abs((p.x - a.x) * dy2 - (p.y - a.y) * dx2) / len;
2149
- if (d > worst2) worst2 = d;
2150
- }
2151
- return worst2;
2152
- }
2153
- function halve(p) {
2154
- let row = p.pts;
2155
- const left = [row[0]];
2156
- const right = [row[row.length - 1]];
2157
- while (row.length > 1) {
2158
- const next = [];
2159
- for (let i = 0; i + 1 < row.length; i++) {
2160
- next.push({ x: (row[i].x + row[i + 1].x) / 2, y: (row[i].y + row[i + 1].y) / 2 });
2161
- }
2162
- row = next;
2163
- left.push(row[0]);
2164
- right.unshift(row[row.length - 1]);
2165
- }
2166
- const tm = (p.t0 + p.t1) / 2;
2167
- return [{ pts: left, t0: p.t0, t1: tm }, { pts: right, t0: tm, t1: p.t1 }];
2168
- }
2169
- function chordCross(p0, p1, q0, q1, slack) {
2170
- const rx = p1.x - p0.x, ry = p1.y - p0.y;
2171
- const sx = q1.x - q0.x, sy = q1.y - q0.y;
2172
- const den = rx * sy - ry * sx;
2173
- if (den === 0) return null;
2174
- const qx = q0.x - p0.x, qy = q0.y - p0.y;
2175
- const u = (qx * sy - qy * sx) / den;
2176
- const v = (qx * ry - qy * rx) / den;
2177
- if (u < -slack || u > 1 + slack || v < -slack || v > 1 + slack) return null;
2178
- return [u, v];
2179
- }
2180
- function refine(a, b, ta, tb) {
2181
- for (let i = 0; i < 12; i++) {
2182
- const pa = evalSeg(a, ta), pb = evalSeg(b, tb);
2183
- const fx = pa.x - pb.x, fy = pa.y - pb.y;
2184
- if (Math.abs(fx) + Math.abs(fy) < 1e-12) break;
2185
- const da = derivSeg(a, ta), db = derivSeg(b, tb);
2186
- const det = -da.x * db.y + da.y * db.x;
2187
- if (det === 0) break;
2188
- const dta = (-fx * -db.y - -fy * -db.x) / det;
2189
- const dtb = (da.x * -fy - da.y * -fx) / det;
2190
- ta = Math.min(1, Math.max(0, ta + dta));
2191
- tb = Math.min(1, Math.max(0, tb + dtb));
2192
- }
2193
- return [ta, tb];
2194
- }
2195
- function intersectSegments(a, b) {
2196
- if (a.length === 2 && b.length === 2) {
2197
- const uv = chordCross(a[0], a[1], b[0], b[1], 1e-12);
2198
- if (!uv) return [];
2199
- const ta = Math.min(1, Math.max(0, uv[0]));
2200
- const tb = Math.min(1, Math.max(0, uv[1]));
2201
- const p = evalSeg(a, ta);
2202
- return [{ ta, tb, x: p.x, y: p.y }];
2203
- }
2204
- const out = [];
2205
- const push = (ta, tb) => {
2206
- [ta, tb] = refine(a, b, ta, tb);
2207
- const pa = evalSeg(a, ta), pb = evalSeg(b, tb);
2208
- if (Math.hypot(pa.x - pb.x, pa.y - pb.y) > 1e-6 * (1 + Math.abs(pa.x) + Math.abs(pa.y))) return;
2209
- if (out.some((h) => Math.abs(h.ta - ta) < SAME_T && Math.abs(h.tb - tb) < SAME_T)) return;
2210
- out.push({ ta, tb, x: pa.x, y: pa.y });
2211
- };
2212
- const stack = [[{ pts: a, t0: 0, t1: 1 }, { pts: b, t0: 0, t1: 1 }, 0]];
2213
- while (stack.length > 0 && out.length < MAX_HITS) {
2214
- const [p, q, depth] = stack.pop();
2215
- const bp = boxOf(p.pts), bq = boxOf(q.pts);
2216
- if (bp[0] > bq[2] + FLAT || bq[0] > bp[2] + FLAT || bp[1] > bq[3] + FLAT || bq[1] > bp[3] + FLAT) continue;
2217
- const fp = flatness(p.pts), fq = flatness(q.pts);
2218
- if (fp <= FLAT && fq <= FLAT || depth >= MAX_DEPTH) {
2219
- const uv = chordCross(p.pts[0], p.pts[p.pts.length - 1], q.pts[0], q.pts[q.pts.length - 1], 1e-6);
2220
- if (uv) push(p.t0 + uv[0] * (p.t1 - p.t0), q.t0 + uv[1] * (q.t1 - q.t0));
2221
- continue;
2222
- }
2223
- if (fp >= fq) {
2224
- const [l, r] = halve(p);
2225
- stack.push([l, q, depth + 1], [r, q, depth + 1]);
2226
- } else {
2227
- const [l, r] = halve(q);
2228
- stack.push([p, l, depth + 1], [p, r, depth + 1]);
2229
- }
2230
- }
2231
- return out.sort((h, k) => h.ta - k.ta);
2239
+ return nearestOnPath(drawn.commands, worldCoords(drawn), px, py)?.dist ?? Infinity;
2232
2240
  }
2233
2241
 
2234
2242
  // src/intersect/pathSegments.ts
@@ -2494,6 +2502,45 @@ function quadrantPoints(segs) {
2494
2502
  }
2495
2503
  return out;
2496
2504
  }
2505
+ var SPATIAL = /* @__PURE__ */ new WeakMap();
2506
+ function spatialOf(index) {
2507
+ let sp = SPATIAL.get(index);
2508
+ if (!sp) SPATIAL.set(index, sp = { targets: /* @__PURE__ */ new Map() });
2509
+ return sp;
2510
+ }
2511
+ function targetsIn(index, kind, box) {
2512
+ const sp = spatialOf(index);
2513
+ const list = index.targets(kind);
2514
+ let held = sp.targets.get(kind);
2515
+ if (held?.list !== list) {
2516
+ const tree = createBvh(2, list.map((t, i) => [i, [t.x, t.y, t.x, t.y]]));
2517
+ sp.targets.set(kind, held = { list, tree });
2518
+ }
2519
+ const out = [];
2520
+ held.tree.queryBox(box, (i) => {
2521
+ out.push(i);
2522
+ });
2523
+ return out.sort((a, b) => a - b);
2524
+ }
2525
+ function segmentsIn(index, box) {
2526
+ const sp = spatialOf(index);
2527
+ const list = index.segments;
2528
+ if (sp.segments?.list !== list) {
2529
+ const at3 = [];
2530
+ const entries = [];
2531
+ list.forEach((segs, path) => segs.forEach((seg, k) => {
2532
+ entries.push([at3.length, [seg.box.x0, seg.box.y0, seg.box.x1, seg.box.y1]]);
2533
+ at3.push([path, k]);
2534
+ }));
2535
+ sp.segments = { list, tree: createBvh(2, entries), at: at3 };
2536
+ }
2537
+ const { tree, at: at2 } = sp.segments;
2538
+ const found = [];
2539
+ tree.queryBox(box, (i) => {
2540
+ found.push(i);
2541
+ });
2542
+ return found.sort((a, b) => a - b).map((i) => at2[i]);
2543
+ }
2497
2544
  function nearestOnSeg(s, p) {
2498
2545
  if (s.length === 2) return nearestOnLine(p.x, p.y, s[0].x, s[0].y, s[1].x, s[1].y);
2499
2546
  if (s.length === 3) return nearestOnQuadratic(p.x, p.y, s[0].x, s[0].y, s[1].x, s[1].y, s[2].x, s[2].y);
@@ -2515,39 +2562,39 @@ function findPathSnaps(index, probe, query) {
2515
2562
  const distance = metric(x - probe.x, y - probe.y);
2516
2563
  if (distance <= r) hits.push({ kind, x, y, distance, paths });
2517
2564
  };
2565
+ const rx = sx > 0 ? r / sx : Infinity, ry = sy > 0 ? r / sy : Infinity;
2566
+ const box = [probe.x - rx, probe.y - ry, probe.x + rx, probe.y + ry];
2518
2567
  for (const kind of STATIC_KINDS) {
2519
2568
  if (!kinds.has(kind)) continue;
2520
- for (const t of index.targets(kind)) if (!t.paths.some(skip)) offer(kind, t.x, t.y, t.paths);
2569
+ const list = index.targets(kind);
2570
+ for (const i of targetsIn(index, kind, box)) {
2571
+ const t = list[i];
2572
+ if (!t.paths.some(skip)) offer(kind, t.x, t.y, t.paths);
2573
+ }
2521
2574
  }
2522
- const rx = r / (sx || 1), ry = r / (sy || 1);
2523
- const near2 = (s) => s.box.x0 - rx <= probe.x && probe.x <= s.box.x1 + rx && s.box.y0 - ry <= probe.y && probe.y <= s.box.y1 + ry;
2524
2575
  const o = query.origin;
2525
- if (o && (kinds.has("tangent") || kinds.has("perpendicular"))) {
2526
- index.segments.forEach((segs, path) => {
2527
- if (skip(path)) return;
2528
- for (const s of segs) {
2529
- if (!near2(s)) continue;
2530
- const lists = [];
2531
- if (kinds.has("tangent")) lists.push(["tangent", tangentTsFrom(s.pts, o)]);
2532
- if (kinds.has("perpendicular")) lists.push(["perpendicular", perpendicularTsFrom(s.pts, o)]);
2533
- for (const [kind, ts] of lists) {
2534
- for (const t of ts) {
2535
- const p = evalSeg(s.pts, t);
2536
- if (metric(p.x - o.x, p.y - o.y) > r) offer(kind, p.x, p.y, [path]);
2537
- }
2576
+ const tangents = o !== void 0 && (kinds.has("tangent") || kinds.has("perpendicular"));
2577
+ if (!tangents && !kinds.has("nearest")) return hits;
2578
+ const near2 = segmentsIn(index, box).filter(([path]) => !skip(path));
2579
+ if (o && tangents) {
2580
+ for (const [path, k] of near2) {
2581
+ const s = index.segments[path][k];
2582
+ const lists = [];
2583
+ if (kinds.has("tangent")) lists.push(["tangent", tangentTsFrom(s.pts, o)]);
2584
+ if (kinds.has("perpendicular")) lists.push(["perpendicular", perpendicularTsFrom(s.pts, o)]);
2585
+ for (const [kind, ts] of lists) {
2586
+ for (const t of ts) {
2587
+ const p = evalSeg(s.pts, t);
2588
+ if (metric(p.x - o.x, p.y - o.y) > r) offer(kind, p.x, p.y, [path]);
2538
2589
  }
2539
2590
  }
2540
- });
2591
+ }
2541
2592
  }
2542
2593
  if (hits.length > 0 || !kinds.has("nearest")) return hits;
2543
- index.segments.forEach((segs, path) => {
2544
- if (skip(path)) return;
2545
- for (const s of segs) {
2546
- if (!near2(s)) continue;
2547
- const n = nearestOnSeg(s.pts, probe);
2548
- offer("nearest", n.x, n.y, [path]);
2549
- }
2550
- });
2594
+ for (const [path, k] of near2) {
2595
+ const n = nearestOnSeg(index.segments[path][k].pts, probe);
2596
+ offer("nearest", n.x, n.y, [path]);
2597
+ }
2551
2598
  return hits;
2552
2599
  }
2553
2600
 
@@ -2675,7 +2722,8 @@ var keyOf = (p) => `${p.x},${p.y}`;
2675
2722
  function heldBy(path, set) {
2676
2723
  const coords = new Float32Array(path.coords.length);
2677
2724
  for (let i = 0; i < coords.length; i++) coords[i] = i >> 1;
2678
- const indexed = pathToAnchors({ ...path, coords }).anchors;
2725
+ const { origin: _indicesHaveNone, ...bare } = path;
2726
+ const indexed = pathToAnchors({ ...bare, coords }).anchors;
2679
2727
  return indexed.map((sub3, s) => {
2680
2728
  if (sub3.length === set.anchors[s].length + 1) sub3[0].inHandle = sub3.pop().inHandle;
2681
2729
  return sub3.map((a, i) => ({ point: a.x, in: a.inHandle?.x, out: a.outHandle?.x, sub: s, idx: i }));
@@ -2694,7 +2742,7 @@ function writtenFrom(set) {
2694
2742
  ...a.outHandle ? { outHandle: at(k + 2) } : {}
2695
2743
  };
2696
2744
  }));
2697
- return anchorsToPath(coded, set.closed).coords;
2745
+ return worldCoords(anchorsToPath(coded, set.closed));
2698
2746
  }
2699
2747
  function neighbor(sub3, closed, i, step) {
2700
2748
  for (let n = 1; n < sub3.length; n++) {
@@ -2817,6 +2865,14 @@ function standoff(anchor, normal2, px, scale3) {
2817
2865
  ny /= l;
2818
2866
  return { x: anchor.x + nx * px / scale3.x, y: anchor.y + ny * px / scale3.y, nx, ny };
2819
2867
  }
2868
+ function pxExtentInFrame(px, scale3, frame) {
2869
+ const [a, b, c, d] = frame;
2870
+ const ux = a * scale3.x, uy = b * scale3.y;
2871
+ const vx = c * scale3.x, vy = d * scale3.y;
2872
+ const det = Math.abs(ux * vy - uy * vx);
2873
+ if (det === 0) return { x: 0, y: 0 };
2874
+ return { x: px * Math.hypot(vx, vy) / det, y: px * Math.hypot(ux, uy) / det };
2875
+ }
2820
2876
  function screenAngleOf(rotation, scale3) {
2821
2877
  return Math.atan2(Math.sin(rotation) * scale3.y, Math.cos(rotation) * scale3.x);
2822
2878
  }
@@ -3427,7 +3483,7 @@ function unit(p) {
3427
3483
  }
3428
3484
 
3429
3485
  // src/paths/growRegion.ts
3430
- var MAX_DEPTH2 = 6;
3486
+ var MAX_DEPTH = 6;
3431
3487
  var SAMPLES3 = [0.2, 0.35, 0.5, 0.65, 0.8];
3432
3488
  function growRegion(path, distance, opts = {}) {
3433
3489
  const b = new PathBuilder();
@@ -3595,7 +3651,7 @@ function offsetSeg(seg, ctx, depth) {
3595
3651
  ],
3596
3652
  line: false
3597
3653
  };
3598
- if (depth >= MAX_DEPTH2 || offsetError(c, out.c, ctx) <= ctx.tol) return [out];
3654
+ if (depth >= MAX_DEPTH || offsetError(c, out.c, ctx) <= ctx.tol) return [out];
3599
3655
  const [l, r] = splitSegment(seg, 0.5);
3600
3656
  return [...offsetSeg(l, ctx, depth + 1), ...offsetSeg(r, ctx, depth + 1)];
3601
3657
  }
@@ -3663,7 +3719,7 @@ var STEPS = 16;
3663
3719
  var END2 = 1e-7;
3664
3720
  function segmentCrossings(segs) {
3665
3721
  const flat = segs.map((s) => flatten2(s));
3666
- const boxes = flat.map(boxOf2);
3722
+ const boxes = flat.map(boxOf);
3667
3723
  const out = [];
3668
3724
  for (let a = 0; a < segs.length; a++) {
3669
3725
  for (let b = a + 1; b < segs.length; b++) {
@@ -3674,7 +3730,7 @@ function segmentCrossings(segs) {
3674
3730
  const hit = linesCross(pa[i], pa[i + 1], pb[j], pb[j + 1]);
3675
3731
  if (hit === null) continue;
3676
3732
  const guess = [(i + hit[0]) / (pa.length - 1), (j + hit[1]) / (pb.length - 1)];
3677
- const [s, t] = segs[a].line && segs[b].line ? guess : refine2(segs[a].c, segs[b].c, guess);
3733
+ const [s, t] = segs[a].line && segs[b].line ? guess : refine(segs[a].c, segs[b].c, guess);
3678
3734
  if (atEnd(s) && atEnd(t)) continue;
3679
3735
  if (out.some((x) => x.a === a && x.b === b && Math.abs(x.s - s) < 1e-6 && Math.abs(x.t - t) < 1e-6)) continue;
3680
3736
  out.push({ a, b, s, t });
@@ -3691,7 +3747,7 @@ function flatten2(seg) {
3691
3747
  for (let i = 0; i <= STEPS; i++) out.push(cubicEvalAt(...seg.c, i / STEPS));
3692
3748
  return out;
3693
3749
  }
3694
- function boxOf2(pts) {
3750
+ function boxOf(pts) {
3695
3751
  const b = [Infinity, Infinity, -Infinity, -Infinity];
3696
3752
  for (const [x, y] of pts) {
3697
3753
  b[0] = Math.min(b[0], x);
@@ -3710,7 +3766,7 @@ function linesCross(a, b, c, d) {
3710
3766
  const w = ((c[0] - a[0]) * ry - (c[1] - a[1]) * rx) / den;
3711
3767
  return u >= 0 && u <= 1 && w >= 0 && w <= 1 ? [u, w] : null;
3712
3768
  }
3713
- function refine2(a, b, guess) {
3769
+ function refine(a, b, guess) {
3714
3770
  const gap = (s2, t2) => {
3715
3771
  const p = cubicEvalAt(...a, s2), q = cubicEvalAt(...b, t2);
3716
3772
  return [p[0] - q[0], p[1] - q[1]];
@@ -4890,6 +4946,9 @@ function rotatePathAround(path, cx, cy, rotation) {
4890
4946
  function rotatePolygon(path, cx, cy, rotation) {
4891
4947
  const cos = Math.cos(rotation);
4892
4948
  const sin = Math.sin(rotation);
4949
+ if (path.origin) {
4950
+ return transformPath(path, [cos, sin, -sin, cos, cx - cx * cos + cy * sin, cy - cx * sin - cy * cos]);
4951
+ }
4893
4952
  const { commands, coords } = path;
4894
4953
  const next = new Float32Array(coords.length);
4895
4954
  forEachSegment(commands, coords, (cmd, ci) => {
@@ -4938,6 +4997,13 @@ function poseFrameOf(pose) {
4938
4997
  const about = [a, b, c, d, cx - (a * cx + c * cy), cy - (b * cx + d * cy)];
4939
4998
  return p.rotation ? multiply(rotateAboutPoint(cx, cy, p.rotation), about) : about;
4940
4999
  }
5000
+ function boxFrameOf(pose) {
5001
+ const p = pose;
5002
+ if (!p || p.x == null || p.y == null || p.width == null || p.height == null) return null;
5003
+ const at2 = translate(p.x, p.y);
5004
+ const frame = poseFrameOf(p);
5005
+ return frame ? multiply(frame, at2) : at2;
5006
+ }
4941
5007
  function poseFrameInverseOf(pose) {
4942
5008
  if (!poseLinearOf(pose)) {
4943
5009
  const r = poseRotationOf(pose);
@@ -5123,7 +5189,7 @@ function smudgePath(path, opts) {
5123
5189
  if (!(radius > 0) || strength === 0 || delta.x === 0 && delta.y === 0) return path;
5124
5190
  const detail = opts.detail ?? radius / 3;
5125
5191
  return editAnchorSet(path, (set) => {
5126
- refine3(set, center, radius, detail);
5192
+ refine2(set, center, radius, detail);
5127
5193
  let touched = false;
5128
5194
  let flat = 0;
5129
5195
  for (const sub3 of set.anchors) {
@@ -5143,7 +5209,7 @@ function weight(p, c, radius) {
5143
5209
  const u2 = ((p.x - c.x) ** 2 + (p.y - c.y) ** 2) / (radius * radius);
5144
5210
  return u2 >= 1 ? 0 : (1 - u2) ** 2;
5145
5211
  }
5146
- function refine3(set, c, radius, detail) {
5212
+ function refine2(set, c, radius, detail) {
5147
5213
  if (!Number.isFinite(detail) || detail <= 0) return;
5148
5214
  let added = 0;
5149
5215
  for (let sub3 = 0; sub3 < set.anchors.length; sub3++) {
@@ -6787,6 +6853,6 @@ function typedArrayReplacer(_key, value) {
6787
6853
  return tagTypedArray(value) ?? value;
6788
6854
  }
6789
6855
 
6790
- export { ANCHOR_FIELDS, CONSTRAINT_TOLERANCE, EASINGS, PATH_SNAP_KINDS, SPRING_PRESETS, TYPED_ARRAY_CONSTRUCTORS, ZOOM_FLOOR, addExtremaAnchors, anchorAt, anchorCount, anchorOriginsOf, anchorSymmetries, anchorSymmetry, anchorsBefore, anchorsInRect, anchorsUnderBrush, anchorsWhere, applyToPoint, arcShape, averageAnchorsAt, balanceFactorToward, bendAlongPath, bendSegment, bendSide, blendPaths, boxToBox, circlePath, clampRectWithin, closestOpenEnds, composePath, conflictingConstraints, constrainPathEdit, constrainPathsEdit, constraintAnchors, constraintApplies, constraintFits, convertSegments, cornerAnchors, createPathSnapIndex, cubicBezierEasing, cubicContoursToPath, decomposePath, deleteAnchorsAt, directionMarks, easeIn, easeInBack, easeInBounce, easeInCirc, easeInCubic, easeInElastic, easeInExpo, easeInOut, easeInOutBack, easeInOutBounce, easeInOutCirc, easeInOutCubic, easeInOutElastic, easeInOutExpo, easeInOutQuad, easeInOutQuart, easeInOutQuint, easeInOutSine, easeInQuad, easeInQuart, easeInQuint, easeInSine, easeOut, easeOutBack, easeOutBounce, easeOutCirc, easeOutCubic, easeOutElastic, easeOutExpo, easeOutQuad, easeOutQuart, easeOutQuint, easeOutSine, editAnchorSet, editAnchorSetTracked, ellipseShape, equalizeSegmentHandles, everyNthAnchor, extendToMeet, findPathSnap, findPathSnaps, fitAffine, fitCubicThroughDeletion, flatAnchorIndex, flatIndexesAfterReverse, growAnchorSelection, growRegion, handleAlongItsAngle, handleAtItsLength, handleBalances, harmonizeAnchors, hasOpenSubpath, identity, insertAnchorOnSegment, intersectSegments, invert, invertAnchorSelection, isSegmentStraight, joinAnchorsAt, joinSubpathEnds, lengthToward, lengthenOpenEnd, lengthenPathEnd, lineShape, linear, locateAnchor, makeHandlesSymmetric, mapConstraintAnchors, mat3, meanScale, measureAnchorPath, measurePath, mergeRegion, moveHandleSymmetric, moveHandleTo, multiply, nearestPathAnchor, normalizeZoom, offsetCornerTraces, openEndAt, openEndRay, openPathEnds, openSubpathAt, pathAnchorPoints, pathAwayFromAnchors, pathContainsPoint, pathContainsPolygon, pathContainsRect, pathCrossings, pathDistanceToPoint, pathEndAnchorIndex, pathEndFrame, pathFromD, pathInPoseFrame, pathInWorld, pathIntersectsPolygon, pathIntersectsRect, pathSegments, pathShape, pathSignedArea, pathThroughPoseFrame, pathToCubicContours, pathToD, placeAlongRun, placeRect, pointAlongPath, pointInPath, polygonContainsPath, polygonIntersectsPath, portControls2 as portControls, portCurvePoints2 as portCurvePoints, poseFrameInverseOf, poseFrameOf, poseLinearOf, poseRotationOf, prepareBlend, pxExtent, readAnchorFields, rectMarkerPath, remapAnchorValues, remapConstraints, remapPointValues, repeatAlongPath, resamplePath, resolveEasing, retractHandles, reverseAnchors, reversePath, reverseSubpaths, reviveTypedArrays, rotate, rotateAboutPoint, rotatePathAround, roundRectPath, runLength, runPlaces, runStationAt, scale, scaleDelta, scalePathToBounds, scaleSegmentHandles, screenAngleOf, segmentAt2 as segmentAt, segmentBetween, segmentExtremaTs, segmentsBetweenAnchors, setSubpathStart, shiftTrack, shrinkAnchorSelection, simplifyAnchorsAt, simplifyPath, simplifySpan, simplifySubpath, smoothAnchors, smudgePath, softFalloff, softSelectionBand, softSelectionWeights, solveConstraints, solvePathConstraints, splitByClosure, splitSubpaths, squarePath, standoff, stationsAlongPath, strokeHitTest, subpathEndAt, subpathsOfAnchors, tagTypedArray, tagTypedArrays, trackRun, trackShapeD, trackSlice, transformCoords, transformPath, translate, translateAnchorBy, translateAnchorsSymmetric, translatePath, trimPathAt, typedArrayReplacer, unionBoundsPath, unsatisfiedConstraints, untagTypedArray, viewToMat3, withAnchorPoints, withinPxBox, withinPxRadius, worldEditToStorage, writeAnchorField };
6856
+ export { ANCHOR_FIELDS, CONSTRAINT_TOLERANCE, EASINGS, PATH_SNAP_KINDS, SPRING_PRESETS, TYPED_ARRAY_CONSTRUCTORS, ZOOM_FLOOR, addExtremaAnchors, anchorAt, anchorCount, anchorOriginsOf, anchorSymmetries, anchorSymmetry, anchorsBefore, anchorsInRect, anchorsUnderBrush, anchorsWhere, applyToPoint, arcShape, averageAnchorsAt, balanceFactorToward, bendAlongPath, bendSegment, bendSide, blendPaths, boxFrameOf, boxToBox, circlePath, clampRectWithin, closestOpenEnds, composePath, conflictingConstraints, constrainPathEdit, constrainPathsEdit, constraintAnchors, constraintApplies, constraintFits, convertSegments, cornerAnchors, createPathSnapIndex, cubicBezierEasing, cubicContoursToPath, decomposePath, deleteAnchorsAt, directionMarks, easeIn, easeInBack, easeInBounce, easeInCirc, easeInCubic, easeInElastic, easeInExpo, easeInOut, easeInOutBack, easeInOutBounce, easeInOutCirc, easeInOutCubic, easeInOutElastic, easeInOutExpo, easeInOutQuad, easeInOutQuart, easeInOutQuint, easeInOutSine, easeInQuad, easeInQuart, easeInQuint, easeInSine, easeOut, easeOutBack, easeOutBounce, easeOutCirc, easeOutCubic, easeOutElastic, easeOutExpo, easeOutQuad, easeOutQuart, easeOutQuint, easeOutSine, editAnchorSet, editAnchorSetTracked, ellipseShape, equalizeSegmentHandles, everyNthAnchor, extendToMeet, findPathSnap, findPathSnaps, fitAffine, fitCubicThroughDeletion, flatAnchorIndex, flatIndexesAfterReverse, growAnchorSelection, growRegion, handleAlongItsAngle, handleAtItsLength, handleBalances, harmonizeAnchors, hasOpenSubpath, identity, insertAnchorOnSegment, invert, invertAnchorSelection, isSegmentStraight, joinAnchorsAt, joinSubpathEnds, lengthToward, lengthenOpenEnd, lengthenPathEnd, lineShape, linear, locateAnchor, makeHandlesSymmetric, mapConstraintAnchors, mat3, meanScale, measureAnchorPath, measurePath, mergeRegion, moveHandleSymmetric, moveHandleTo, multiply, nearestPathAnchor, normalizeZoom, offsetCornerTraces, openEndAt, openEndRay, openPathEnds, openSubpathAt, pathAnchorPoints, pathAwayFromAnchors, pathContainsPoint, pathContainsPolygon, pathContainsRect, pathCrossings, pathDistanceToPoint, pathEndAnchorIndex, pathEndFrame, pathFromD, pathInPoseFrame, pathInWorld, pathIntersectsPolygon, pathIntersectsRect, pathSegments, pathShape, pathSignedArea, pathThroughPoseFrame, pathToCubicContours, pathToD, placeAlongRun, placeRect, pointAlongPath, pointInPath, polygonContainsPath, polygonIntersectsPath, portControls2 as portControls, portCurvePoints2 as portCurvePoints, poseFrameInverseOf, poseFrameOf, poseLinearOf, poseRotationOf, prepareBlend, puckerBloatPath, pxExtent, pxExtentInFrame, readAnchorFields, rectMarkerPath, remapAnchorValues, remapConstraints, remapPointValues, repeatAlongPath, resamplePath, resolveEasing, retractHandles, reverseAnchors, reversePath, reverseSubpaths, reviveTypedArrays, rotate, rotateAboutPoint, rotatePathAround, roughenPath, roundRectPath, runLength, runPlaces, runStationAt, scale, scaleDelta, scalePathToBounds, scaleSegmentHandles, screenAngleOf, segmentAt2 as segmentAt, segmentBetween, segmentExtremaTs, segmentsBetweenAnchors, setSubpathStart, shiftTrack, shrinkAnchorSelection, simplifyAnchorsAt, simplifyPath, simplifySpan, simplifySubpath, smoothAnchors, smudgePath, softFalloff, softSelectionBand, softSelectionWeights, solveConstraints, solvePathConstraints, splitByClosure, splitSubpaths, squarePath, standoff, stationsAlongPath, strokeHitTest, subpathEndAt, subpathsOfAnchors, tagTypedArray, tagTypedArrays, trackRun, trackShapeD, trackSlice, transformCoords, transformPath, translate, translateAnchorBy, translateAnchorsSymmetric, translatePath, trimPathAt, typedArrayReplacer, unionBoundsPath, unsatisfiedConstraints, untagTypedArray, viewToMat3, withAnchorPoints, withinPxBox, withinPxRadius, worldEditToStorage, writeAnchorField, zigzagPath };
6791
6857
  //# sourceMappingURL=index.js.map
6792
6858
  //# sourceMappingURL=index.js.map