curvy 2.0.0-alpha.10 → 2.0.0-alpha.11

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 (34) hide show
  1. package/dist/characteristic/index.mjs +1 -1
  2. package/dist/curve/index.mjs +1 -1
  3. package/dist/interval/index.mjs +2 -2
  4. package/dist/interval/interval.d.ts +14 -0
  5. package/dist/path/index.mjs +30 -10
  6. package/dist/path/index.mjs.map +1 -1
  7. package/dist/polynomial/cubic.d.ts +10 -0
  8. package/dist/polynomial/index.mjs +2 -2
  9. package/dist/polynomial/linear.d.ts +10 -0
  10. package/dist/polynomial/quadratic.d.ts +10 -0
  11. package/dist/shared/{characteristic-B0VEB_OA.mjs → characteristic-Hb7F8SBw.mjs} +2 -2
  12. package/dist/shared/{characteristic-B0VEB_OA.mjs.map → characteristic-Hb7F8SBw.mjs.map} +1 -1
  13. package/dist/shared/{cubic-NEn7E6V_.mjs → cubic-DHJrzZJN.mjs} +22 -5
  14. package/dist/shared/cubic-DHJrzZJN.mjs.map +1 -0
  15. package/dist/shared/{interval-CqC3ZIqj.mjs → interval-Dm35Xhy4.mjs} +19 -2
  16. package/dist/shared/interval-Dm35Xhy4.mjs.map +1 -0
  17. package/dist/shared/{interval2d-C0eduE-V.mjs → interval2d-DPmvk_Qe.mjs} +2 -2
  18. package/dist/shared/{interval2d-C0eduE-V.mjs.map → interval2d-DPmvk_Qe.mjs.map} +1 -1
  19. package/dist/shared/{quadratic-Dlxqo2V1.mjs → quadratic-BZmfZE71.mjs} +27 -5
  20. package/dist/shared/quadratic-BZmfZE71.mjs.map +1 -0
  21. package/dist/shared/{rationalCubic2d-3S5K69Jy.mjs → rationalCubic2d-IroMR6AA.mjs} +10 -10
  22. package/dist/shared/rationalCubic2d-IroMR6AA.mjs.map +1 -0
  23. package/dist/shared/{rationalCubic2d-CJY-feGw.mjs → rationalCubic2d-nN-oSrLr.mjs} +18 -8
  24. package/dist/shared/rationalCubic2d-nN-oSrLr.mjs.map +1 -0
  25. package/dist/shared/{solution-UKGK826h.mjs → solution-B6KY1E7M.mjs} +2 -2
  26. package/dist/shared/{solution-UKGK826h.mjs.map → solution-B6KY1E7M.mjs.map} +1 -1
  27. package/dist/solution/index.mjs +1 -1
  28. package/dist/splines/index.mjs +4 -4
  29. package/package.json +1 -1
  30. package/dist/shared/cubic-NEn7E6V_.mjs.map +0 -1
  31. package/dist/shared/interval-CqC3ZIqj.mjs.map +0 -1
  32. package/dist/shared/quadratic-Dlxqo2V1.mjs.map +0 -1
  33. package/dist/shared/rationalCubic2d-3S5K69Jy.mjs.map +0 -1
  34. package/dist/shared/rationalCubic2d-CJY-feGw.mjs.map +0 -1
@@ -1,2 +1,2 @@
1
- import { n as characteristic_exports } from "../shared/characteristic-B0VEB_OA.mjs";
1
+ import { n as characteristic_exports } from "../shared/characteristic-Hb7F8SBw.mjs";
2
2
  export { characteristic_exports as Characteristic };
@@ -1,2 +1,2 @@
1
- import { S as linear2d_exports, g as quadratic2d_exports, o as cubic2d_exports, r as rationalCubic2d_exports } from "../shared/rationalCubic2d-3S5K69Jy.mjs";
1
+ import { S as linear2d_exports, g as quadratic2d_exports, o as cubic2d_exports, r as rationalCubic2d_exports } from "../shared/rationalCubic2d-IroMR6AA.mjs";
2
2
  export { cubic2d_exports as CubicCurve2d, linear2d_exports as LinearCurve2d, quadratic2d_exports as QuadraticCurve2d, rationalCubic2d_exports as RationalCubicCurve2d };
@@ -1,3 +1,3 @@
1
- import { s as interval_exports } from "../shared/interval-CqC3ZIqj.mjs";
2
- import { n as interval2d_exports } from "../shared/interval2d-C0eduE-V.mjs";
1
+ import { s as interval_exports } from "../shared/interval-Dm35Xhy4.mjs";
2
+ import { n as interval2d_exports } from "../shared/interval2d-DPmvk_Qe.mjs";
3
3
  export { interval_exports as Interval, interval2d_exports as Interval2d };
@@ -240,6 +240,20 @@ export declare const contains: {
240
240
  */
241
241
  (value: number): (interval: Interval) => boolean;
242
242
  };
243
+ /**
244
+ * Float-tolerant containment: returns `true` if `value` is in the interval or
245
+ * within `eps` of either boundary. Endpoint inclusivity is ignored — at the
246
+ * `EPSILON` scale the open/closed distinction loses meaning, and the use case
247
+ * is "is this query approximately in this range, accounting for float drift?".
248
+ * Use {@link contains} if you need kind-strict semantics.
249
+ *
250
+ * @param interval - The interval to check against.
251
+ * @param value - The value to check.
252
+ * @param eps - The absolute tolerance. Defaults to {@link EPSILON}.
253
+ * @returns `true` when `interval.start - eps <= value <= interval.end + eps`.
254
+ * @since 2.0.0
255
+ */
256
+ export declare const containsApprox: (interval: Interval, value: number, eps?: number) => boolean;
243
257
  export declare const containsInterval: {
244
258
  /**
245
259
  * Checks if `inner` is a subset of `outer` — every point of `inner` is also
@@ -1,12 +1,12 @@
1
1
  import { t as __exportAll } from "../shared/chunk-25Hzd3z8.mjs";
2
2
  import { Pipeable, dual, invariant } from "../utils.mjs";
3
3
  import { epsEquals } from "../number.mjs";
4
- import { p as unit } from "../shared/interval-CqC3ZIqj.mjs";
5
- import { o as none } from "../shared/solution-UKGK826h.mjs";
6
- import { d as isIncreasing, n as isDecreasing$1, r as isIncreasing$1, u as isDecreasing } from "../shared/quadratic-Dlxqo2V1.mjs";
7
- import { a as union } from "../shared/interval2d-C0eduE-V.mjs";
8
- import { C as solve$4, T as solveAtY$4, _ as solve$5, b as boundingBox$4, h as length$5, m as boundingBox$5, v as solveAtX$5, w as solveAtX$4, x as length$4, y as solveAtY$5 } from "../shared/rationalCubic2d-3S5K69Jy.mjs";
9
- import { n as rationalCubic2d_exports, r as cubic2d_exports } from "../shared/rationalCubic2d-CJY-feGw.mjs";
4
+ import { p as unit } from "../shared/interval-Dm35Xhy4.mjs";
5
+ import { o as none, r as isNone, s as one } from "../shared/solution-B6KY1E7M.mjs";
6
+ import { d as isIncreasing, n as isDecreasing$1, r as isIncreasing$1, u as isDecreasing } from "../shared/quadratic-BZmfZE71.mjs";
7
+ import { a as union } from "../shared/interval2d-DPmvk_Qe.mjs";
8
+ import { C as solve$4, T as solveAtY$4, _ as solve$5, b as boundingBox$4, h as length$5, m as boundingBox$5, v as solveAtX$5, w as solveAtX$4, x as length$4, y as solveAtY$5 } from "../shared/rationalCubic2d-IroMR6AA.mjs";
9
+ import { n as rationalCubic2d_exports, r as cubic2d_exports } from "../shared/rationalCubic2d-nN-oSrLr.mjs";
10
10
  //#region src/path/linear2d.internal.ts
11
11
  const LinearPath2dTypeId = Symbol("curvy/path/linear2d");
12
12
  /** @internal */
@@ -162,7 +162,12 @@ const solveAtX$3 = dual(2, (p, x) => {
162
162
  const ex = c.x.c0 + c.x.c1;
163
163
  const lo = Math.min(sx, ex);
164
164
  const hi = Math.max(sx, ex);
165
- if (x >= lo - 1e-10 && x <= hi + 1e-10) return solveAtX$4(c, x);
165
+ if (x >= lo - 1e-10 && x <= hi + 1e-10) {
166
+ if (epsEquals(x, sx)) return one(c.y.c0);
167
+ if (epsEquals(x, ex)) return one(c.y.c0 + c.y.c1);
168
+ const sol = solveAtX$4(c, x);
169
+ if (!isNone(sol)) return sol;
170
+ }
166
171
  }
167
172
  return none;
168
173
  });
@@ -173,7 +178,12 @@ const solveAtY$3 = dual(2, (p, y) => {
173
178
  const ey = c.y.c0 + c.y.c1;
174
179
  const lo = Math.min(sy, ey);
175
180
  const hi = Math.max(sy, ey);
176
- if (y >= lo - 1e-10 && y <= hi + 1e-10) return solveAtY$4(c, y);
181
+ if (y >= lo - 1e-10 && y <= hi + 1e-10) {
182
+ if (epsEquals(y, sy)) return one(c.x.c0);
183
+ if (epsEquals(y, ey)) return one(c.x.c0 + c.x.c1);
184
+ const sol = solveAtY$4(c, y);
185
+ if (!isNone(sol)) return sol;
186
+ }
177
187
  }
178
188
  return none;
179
189
  });
@@ -531,7 +541,12 @@ const solveAtX$1 = dual(2, (p, x) => {
531
541
  const ex = c.x.c0 + c.x.c1 + c.x.c2;
532
542
  const lo = Math.min(sx, ex);
533
543
  const hi = Math.max(sx, ex);
534
- if (x >= lo - 1e-10 && x <= hi + 1e-10) return solveAtX$5(c, x);
544
+ if (x >= lo - 1e-10 && x <= hi + 1e-10) {
545
+ if (epsEquals(x, sx)) return one(c.y.c0);
546
+ if (epsEquals(x, ex)) return one(c.y.c0 + c.y.c1 + c.y.c2);
547
+ const sol = solveAtX$5(c, x);
548
+ if (!isNone(sol)) return sol;
549
+ }
535
550
  }
536
551
  return none;
537
552
  });
@@ -542,7 +557,12 @@ const solveAtY$1 = dual(2, (p, y) => {
542
557
  const ey = c.y.c0 + c.y.c1 + c.y.c2;
543
558
  const lo = Math.min(sy, ey);
544
559
  const hi = Math.max(sy, ey);
545
- if (y >= lo - 1e-10 && y <= hi + 1e-10) return solveAtY$5(c, y);
560
+ if (y >= lo - 1e-10 && y <= hi + 1e-10) {
561
+ if (epsEquals(y, sy)) return one(c.x.c0);
562
+ if (epsEquals(y, ey)) return one(c.x.c0 + c.x.c1 + c.x.c2);
563
+ const sol = solveAtY$5(c, y);
564
+ if (!isNone(sol)) return sol;
565
+ }
546
566
  }
547
567
  return none;
548
568
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["isLinearPath2d","make","fromArray","append","length","LinearCurve2d.length","Interval.unit","solve","LinearCurve2d.solve","toPathData","isContinuous","asContinuous","isIncreasingX","LinearPolynomial.isIncreasing","isDecreasingX","LinearPolynomial.isDecreasing","isMonotonicX","isIncreasingY","isDecreasingY","isMonotonicY","asIncreasingX","asDecreasingX","asMonotonicX","asIncreasingY","asDecreasingY","asMonotonicY","solveAtX","LinearCurve2d.solveAtX","Solution.none","solveAtY","LinearCurve2d.solveAtY","boundingBox","LinearCurve2d.boundingBox","Interval2d.union","make","internal.make","fromArray","internal.fromArray","internal.isLinearPath2d","append","internal.append","length","internal.length","solve","internal.solve","toPathData","internal.toPathData","isContinuous","internal.isContinuous","asContinuous","internal.asContinuous","isIncreasingX","internal.isIncreasingX","isDecreasingX","internal.isDecreasingX","isMonotonicX","internal.isMonotonicX","isIncreasingY","internal.isIncreasingY","isDecreasingY","internal.isDecreasingY","isMonotonicY","internal.isMonotonicY","asIncreasingX","internal.asIncreasingX","asDecreasingX","internal.asDecreasingX","asMonotonicX","internal.asMonotonicX","asIncreasingY","internal.asIncreasingY","asDecreasingY","internal.asDecreasingY","asMonotonicY","internal.asMonotonicY","solveAtX","internal.solveAtX","solveAtY","internal.solveAtY","boundingBox","internal.boundingBox","isQuadraticPath2d","make","fromArray","append","length","QuadraticCurve2d.length","Interval.unit","solve","QuadraticCurve2d.solve","toPathData","isContinuous","asContinuous","isIncreasingX","QuadraticPolynomial.isIncreasing","isDecreasingX","QuadraticPolynomial.isDecreasing","isMonotonicX","isIncreasingY","isDecreasingY","isMonotonicY","asIncreasingX","asDecreasingX","asMonotonicX","asIncreasingY","asDecreasingY","asMonotonicY","solveAtX","QuadraticCurve2d.solveAtX","Solution.none","solveAtY","QuadraticCurve2d.solveAtY","boundingBox","QuadraticCurve2d.boundingBox","Interval2d.union","internal.make","internal.fromArray","internal.isQuadraticPath2d","internal.append","internal.length","internal.solve","internal.toPathData","internal.isContinuous","internal.asContinuous","internal.isIncreasingX","internal.isDecreasingX","internal.isMonotonicX","internal.isIncreasingY","internal.isDecreasingY","internal.isMonotonicY","internal.asIncreasingX","internal.asDecreasingX","internal.asMonotonicX","internal.asIncreasingY","internal.asDecreasingY","internal.asMonotonicY","internal.solveAtX","internal.solveAtY","internal.boundingBox"],"sources":["../../src/path/linear2d.internal.ts","../../src/path/linear2d.ts","../../src/path/quadratic2d.internal.ts","../../src/path/quadratic2d.ts"],"sourcesContent":["import * as Interval2d from '../interval/interval2d.ts'\nimport * as LinearCurve2d from '../curve/linear2d.ts'\nimport * as Interval from '../interval/interval.ts'\nimport * as LinearPolynomial from '../polynomial/linear.ts'\nimport * as Solution from '../solution/solution.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport { invariant } from '../utils.ts'\nimport { EPSILON, epsEquals } from '../number.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { LinearPath2d } from './linear2d.ts'\nimport {\n PathTraits,\n type Continuous,\n type DecreasingX,\n type DecreasingY,\n type IncreasingX,\n type IncreasingY,\n type MonotonicX,\n type MonotonicY,\n} from './traits.ts'\n\nexport const LinearPath2dTypeId: unique symbol = Symbol('curvy/path/linear2d')\nexport type LinearPath2dTypeId = typeof LinearPath2dTypeId\n\n/** @internal */\nexport class LinearPath2dImpl extends Pipeable implements LinearPath2d<unknown> {\n readonly [LinearPath2dTypeId]: LinearPath2dTypeId = LinearPath2dTypeId\n declare readonly [PathTraits]: unknown\n\n readonly curves: ReadonlyArray<LinearCurve2d.LinearCurve2d>\n\n constructor(curves: ReadonlyArray<LinearCurve2d.LinearCurve2d>) {\n super()\n this.curves = curves\n }\n\n [Symbol.iterator](): Iterator<LinearCurve2d.LinearCurve2d> {\n return this.curves[Symbol.iterator]()\n }\n}\n\n/** @internal */\nexport const isLinearPath2d = (p: unknown): p is LinearPath2d =>\n typeof p === 'object' && p !== null && LinearPath2dTypeId in p\n\n/** @internal */\nexport const make = (...curves: ReadonlyArray<LinearCurve2d.LinearCurve2d>): LinearPath2d =>\n new LinearPath2dImpl(curves)\n\n/** @internal */\nexport const fromArray = (curves: ReadonlyArray<LinearCurve2d.LinearCurve2d>) =>\n new LinearPath2dImpl(curves)\n\n/** @internal */\nexport const append = dual<\n (c: LinearCurve2d.LinearCurve2d) => (p: LinearPath2d) => LinearPath2d,\n (p: LinearPath2d, c: LinearCurve2d.LinearCurve2d) => LinearPath2d\n>(2, (p: LinearPath2d, c: LinearCurve2d.LinearCurve2d) => fromArray([...p, c]))\n\n/** @internal */\nexport const length = (p: LinearPath2d) => {\n let total = 0\n for (const curve of p) {\n total += LinearCurve2d.length(curve, Interval.unit)\n }\n\n return total\n}\n\n/** @internal */\nexport const solve = dual<\n (u: number) => (p: LinearPath2d) => Vector2,\n (p: LinearPath2d, u: number) => Vector2\n>(2, (p: LinearPath2d, u: number) => {\n const curves = p instanceof LinearPath2dImpl ? p.curves : [...p]\n\n if (u === 1) {\n const last = curves.at(-1) as LinearCurve2d.LinearCurve2d\n return LinearCurve2d.solve(last, 1)\n }\n\n const t = u * curves.length\n const i = Math.floor(t)\n const curve = curves[i] as LinearCurve2d.LinearCurve2d\n return LinearCurve2d.solve(curve, t - i)\n})\n\n/** @internal */\nexport const toPathData = (p: LinearPath2d): string => {\n let result = ''\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n\n for (const curve of p) {\n const startX = curve.x.c0\n const startY = curve.y.c0\n const endX = curve.x.c0 + curve.x.c1\n const endY = curve.y.c0 + curve.y.c1\n\n if (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY)) {\n result += ` M ${startX},${startY}`\n }\n result += ` L ${endX},${endY}`\n\n prevEndX = endX\n prevEndY = endY\n }\n\n return result.slice(1)\n}\n\n/** @internal */\nexport const isContinuous = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & Continuous> => {\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n let first = true\n\n for (const curve of p) {\n const startX = curve.x.c0\n const startY = curve.y.c0\n if (!first && (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY))) {\n return false\n }\n prevEndX = curve.x.c0 + curve.x.c1\n prevEndY = curve.y.c0 + curve.y.c1\n first = false\n }\n return true\n}\n\n/** @internal */\nexport const asContinuous = <T>(p: LinearPath2d<T>): LinearPath2d<T & Continuous> => {\n invariant(isContinuous(p), 'linear path is not continuous')\n return p\n}\n\n// Per-axis monotonicity refiners. A path is monotonic-on-an-axis when every\n// segment's per-axis polynomial is strictly monotonic in the same direction\n// AND adjacent segments' ranges on that axis don't overlap (modulo float\n// tolerance) — so the path's u → axis mapping is monotonic across joins.\n\n/** @internal */\nexport const isIncreasingX = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & IncreasingX> => {\n let prevEnd = Number.NEGATIVE_INFINITY\n for (const c of p) {\n if (!LinearPolynomial.isIncreasing(c.x)) {\n return false\n }\n if (c.x.c0 < prevEnd - EPSILON) {\n return false\n }\n prevEnd = c.x.c0 + c.x.c1\n }\n return true\n}\n\n/** @internal */\nexport const isDecreasingX = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & DecreasingX> => {\n let prevEnd = Number.POSITIVE_INFINITY\n for (const c of p) {\n if (!LinearPolynomial.isDecreasing(c.x)) {\n return false\n }\n if (c.x.c0 > prevEnd + EPSILON) {\n return false\n }\n prevEnd = c.x.c0 + c.x.c1\n }\n return true\n}\n\n/** @internal */\nexport const isMonotonicX = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & MonotonicX> =>\n isIncreasingX(p) || isDecreasingX(p)\n\n/** @internal */\nexport const isIncreasingY = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & IncreasingY> => {\n let prevEnd = Number.NEGATIVE_INFINITY\n for (const c of p) {\n if (!LinearPolynomial.isIncreasing(c.y)) {\n return false\n }\n if (c.y.c0 < prevEnd - EPSILON) {\n return false\n }\n prevEnd = c.y.c0 + c.y.c1\n }\n return true\n}\n\n/** @internal */\nexport const isDecreasingY = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & DecreasingY> => {\n let prevEnd = Number.POSITIVE_INFINITY\n for (const c of p) {\n if (!LinearPolynomial.isDecreasing(c.y)) {\n return false\n }\n if (c.y.c0 > prevEnd + EPSILON) {\n return false\n }\n prevEnd = c.y.c0 + c.y.c1\n }\n return true\n}\n\n/** @internal */\nexport const isMonotonicY = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & MonotonicY> =>\n isIncreasingY(p) || isDecreasingY(p)\n\n/** @internal */\nexport const asIncreasingX = <T>(p: LinearPath2d<T>): LinearPath2d<T & IncreasingX> => {\n invariant(isIncreasingX(p), 'linear path is not increasing in x')\n return p\n}\n\n/** @internal */\nexport const asDecreasingX = <T>(p: LinearPath2d<T>): LinearPath2d<T & DecreasingX> => {\n invariant(isDecreasingX(p), 'linear path is not decreasing in x')\n return p\n}\n\n/** @internal */\nexport const asMonotonicX = <T>(p: LinearPath2d<T>): LinearPath2d<T & MonotonicX> => {\n invariant(isMonotonicX(p), 'linear path is not monotonic in x')\n return p\n}\n\n/** @internal */\nexport const asIncreasingY = <T>(p: LinearPath2d<T>): LinearPath2d<T & IncreasingY> => {\n invariant(isIncreasingY(p), 'linear path is not increasing in y')\n return p\n}\n\n/** @internal */\nexport const asDecreasingY = <T>(p: LinearPath2d<T>): LinearPath2d<T & DecreasingY> => {\n invariant(isDecreasingY(p), 'linear path is not decreasing in y')\n return p\n}\n\n/** @internal */\nexport const asMonotonicY = <T>(p: LinearPath2d<T>): LinearPath2d<T & MonotonicY> => {\n invariant(isMonotonicY(p), 'linear path is not monotonic in y')\n return p\n}\n\n// solveAtX/solveAtY for `Monotonic{X,Y}` paths: locate the segment whose axis\n// range contains the queried value, then delegate to the curve-level solver.\n// Caller-side trait constraints guarantee a single solution; the runtime\n// function returns `None` when the value is outside the path's range.\n/** @internal */\nexport const solveAtX = dual(2, (p: LinearPath2d, x: number): Solution.AtMostOne<number> => {\n for (const c of p) {\n const sx = c.x.c0\n const ex = c.x.c0 + c.x.c1\n const lo = Math.min(sx, ex)\n const hi = Math.max(sx, ex)\n if (x >= lo - EPSILON && x <= hi + EPSILON) {\n return LinearCurve2d.solveAtX(c, x)\n }\n }\n return Solution.none\n})\n\n/** @internal */\nexport const solveAtY = dual(2, (p: LinearPath2d, y: number): Solution.AtMostOne<number> => {\n for (const c of p) {\n const sy = c.y.c0\n const ey = c.y.c0 + c.y.c1\n const lo = Math.min(sy, ey)\n const hi = Math.max(sy, ey)\n if (y >= lo - EPSILON && y <= hi + EPSILON) {\n return LinearCurve2d.solveAtY(c, y)\n }\n }\n return Solution.none\n})\n\n/** @internal */\nexport const boundingBox = (\n p: LinearPath2d,\n): Interval2d.Interval2d<Interval.Closed, Interval.Closed> => {\n const iter = p[Symbol.iterator]()\n const first = iter.next()\n // path invariant: at least one curve, so first.value is defined\n let acc = LinearCurve2d.boundingBox(first.value as LinearCurve2d.LinearCurve2d)\n for (let next = iter.next(); !next.done; next = iter.next()) {\n acc = Interval2d.union(acc, LinearCurve2d.boundingBox(next.value))\n }\n return acc\n}\n","import type { Interval2d } from '../interval/interval2d.ts'\nimport type { LinearCurve2d } from '../curve/linear2d.ts'\nimport type { Closed } from '../interval/interval.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { LinearPath2dTypeId } from './linear2d.internal.ts'\nimport * as internal from './linear2d.internal.ts'\nimport type {\n Continuous,\n DecreasingX,\n DecreasingY,\n IncreasingX,\n IncreasingY,\n MonotonicX,\n MonotonicY,\n PathTraits,\n} from './traits.ts'\n\nexport type {\n Continuous,\n DecreasingX,\n DecreasingY,\n IncreasingX,\n IncreasingY,\n MonotonicX,\n MonotonicY,\n} from './traits.ts'\n\n/**\n * A linear path in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The `Trait` type parameter accumulates trait brands as the path is refined\n * via `isContinuous` / `asContinuous`. A `Continuous` path's `toPathData`\n * skips the per-segment discontinuity check.\n *\n * @since 1.0.0\n */\nexport interface LinearPath2d<out Trait = unknown> extends Pipeable, Iterable<LinearCurve2d> {\n readonly [LinearPath2dTypeId]: LinearPath2dTypeId\n readonly [PathTraits]: Trait\n}\n\n/**\n * Creates a new `LinearPath2d` instance from a sequence of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `LinearPath2d` instance.\n * @since 2.0.0\n */\nexport const make: (...curves: ReadonlyArray<LinearCurve2d>) => LinearPath2d = internal.make\n\n/**\n * Creates a new `LinearPath2d` instance from an array of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `LinearPath2d` instance.\n * @since 2.0.0\n */\nexport const fromArray: (curves: ReadonlyArray<LinearCurve2d>) => LinearPath2d = internal.fromArray\n\n/**\n * Checks if a value is a `LinearPath2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `LinearPath2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isLinearPath2d: (p: unknown) => p is LinearPath2d = internal.isLinearPath2d\n\nexport const append: {\n /**\n * Appends a linear curve to a linear path.\n *\n * @param c - The linear curve to append.\n * @returns A function that takes a linear path and returns a new linear path.\n * @since 1.0.0\n */\n (c: LinearCurve2d): (p: LinearPath2d) => LinearPath2d\n /**\n * Appends a linear curve to a linear path.\n *\n * @param p - The linear path to append to.\n * @param c - The linear curve to append.\n * @returns A new `LinearPath2d` instance with the appended curve.\n * @since 1.0.0\n */\n (p: LinearPath2d, c: LinearCurve2d): LinearPath2d\n} = internal.append\n\n/**\n * Calculates the length of a linear path.\n *\n * @param p - The linear path to calculate the length of.\n * @returns The length of the linear path.\n * @since 1.0.0\n */\nexport const length: (p: LinearPath2d) => number = internal.length\n\nexport const solve: {\n /**\n * Solves a linear path for a given parameter.\n *\n * @param u - The parameter to solve for.\n * @returns A function that takes a linear path and returns the solved point.\n * @since 1.0.0\n */\n (u: number): (p: LinearPath2d) => Vector2\n /**\n * Solves a linear path for a given parameter.\n *\n * @param p - The linear path to solve.\n * @param u - The parameter to solve for.\n * @returns The solved point on the linear path.\n * @since 1.0.0\n */\n (p: LinearPath2d, u: number): Vector2\n} = internal.solve\n\n/**\n * Serializes a linear path as an SVG path data string (the value of a `<path>`\n * element's `d` attribute), using `M` and `L` commands. Discontinuities between\n * curves emit a fresh `M` command.\n *\n * @param p - The linear path to serialize.\n * @returns The SVG path data string.\n * @since 2.0.0\n */\nexport const toPathData: (p: LinearPath2d) => string = internal.toPathData\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & Continuous>` when adjacent curves connect at their join\n * points.\n *\n * @param p - The linear path to check.\n * @returns `true` when the path is continuous (G⁰).\n * @since 2.0.0\n */\nexport const isContinuous: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & Continuous> =\n internal.isContinuous\n\n/**\n * Asserts that the linear path is continuous, throwing on failure.\n *\n * @param p - The linear path to assert against.\n * @returns The same path, typed with the `Continuous` brand.\n * @throws When the path has a discontinuity between adjacent curves.\n * @since 2.0.0\n */\nexport const asContinuous: <T>(p: LinearPath2d<T>) => LinearPath2d<T & Continuous> =\n internal.asContinuous\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & IncreasingX>` when every segment's x-polynomial is\n * strictly increasing and adjacent segments' x-ranges don't overlap.\n *\n * @since 2.0.0\n */\nexport const isIncreasingX: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & IncreasingX> =\n internal.isIncreasingX\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & DecreasingX>` when every segment's x-polynomial is\n * strictly decreasing and adjacent segments' x-ranges don't overlap.\n *\n * @since 2.0.0\n */\nexport const isDecreasingX: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & DecreasingX> =\n internal.isDecreasingX\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & MonotonicX>` when the path is either increasing or\n * decreasing in x along its full parameter domain.\n *\n * @since 2.0.0\n */\nexport const isMonotonicX: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & MonotonicX> =\n internal.isMonotonicX\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & IncreasingY>`. The y-axis analog of {@link isIncreasingX}.\n *\n * @since 2.0.0\n */\nexport const isIncreasingY: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & IncreasingY> =\n internal.isIncreasingY\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & DecreasingY>`. The y-axis analog of {@link isDecreasingX}.\n *\n * @since 2.0.0\n */\nexport const isDecreasingY: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & DecreasingY> =\n internal.isDecreasingY\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & MonotonicY>`. The y-axis analog of {@link isMonotonicX}.\n *\n * @since 2.0.0\n */\nexport const isMonotonicY: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & MonotonicY> =\n internal.isMonotonicY\n\n/**\n * Asserts that the path is strictly increasing in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasingX: <T>(p: LinearPath2d<T>) => LinearPath2d<T & IncreasingX> =\n internal.asIncreasingX\n\n/**\n * Asserts that the path is strictly decreasing in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasingX: <T>(p: LinearPath2d<T>) => LinearPath2d<T & DecreasingX> =\n internal.asDecreasingX\n\n/**\n * Asserts that the path is monotonic in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asMonotonicX: <T>(p: LinearPath2d<T>) => LinearPath2d<T & MonotonicX> =\n internal.asMonotonicX\n\n/**\n * Asserts that the path is strictly increasing in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasingY: <T>(p: LinearPath2d<T>) => LinearPath2d<T & IncreasingY> =\n internal.asIncreasingY\n\n/**\n * Asserts that the path is strictly decreasing in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasingY: <T>(p: LinearPath2d<T>) => LinearPath2d<T & DecreasingY> =\n internal.asDecreasingY\n\n/**\n * Asserts that the path is monotonic in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asMonotonicY: <T>(p: LinearPath2d<T>) => LinearPath2d<T & MonotonicY> =\n internal.asMonotonicY\n\nexport const solveAtX: {\n /**\n * Evaluates the path's y value at a given x. Requires the path to carry the\n * `MonotonicX` brand — without it, an x query could match multiple\n * segments and the return cardinality would be unbounded.\n *\n * Returns `Solution.none` when x falls outside the path's x-range.\n *\n * @param p - A path branded `MonotonicX`.\n * @param x - The x coordinate.\n * @returns The y value at x, or `none` when x is outside the path's range.\n * @since 2.0.0\n */\n <T extends MonotonicX>(p: LinearPath2d<T>, x: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (x: number): <T extends MonotonicX>(p: LinearPath2d<T>) => Solution.AtMostOne<number>\n} = internal.solveAtX as never\n\nexport const solveAtY: {\n /**\n * Evaluates the path's x value at a given y. Requires the path to carry the\n * `MonotonicY` brand. Returns `Solution.none` when y is outside the path's\n * y-range.\n *\n * @param p - A path branded `MonotonicY`.\n * @param y - The y coordinate.\n * @returns The x value at y, or `none` when y is outside the path's range.\n * @since 2.0.0\n */\n <T extends MonotonicY>(p: LinearPath2d<T>, y: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (y: number): <T extends MonotonicY>(p: LinearPath2d<T>) => Solution.AtMostOne<number>\n} = internal.solveAtY as never\n\n/**\n * Computes the axis-aligned bounding box of the path — the smallest closed\n * `Box2d` enclosing every segment.\n *\n * @param p - The linear path.\n * @returns A closed `Box2d` enclosing the path.\n * @since 2.0.0\n */\nexport const boundingBox: (p: LinearPath2d) => Interval2d<Closed, Closed> = internal.boundingBox\n","import * as Interval2d from '../interval/interval2d.ts'\nimport * as QuadraticCurve2d from '../curve/quadratic2d.ts'\nimport * as Interval from '../interval/interval.ts'\nimport * as QuadraticPolynomial from '../polynomial/quadratic.ts'\nimport * as Solution from '../solution/solution.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport { invariant } from '../utils.ts'\nimport { EPSILON, epsEquals } from '../number.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { QuadraticPath2d } from './quadratic2d.ts'\nimport {\n PathTraits,\n type Continuous,\n type DecreasingX,\n type DecreasingY,\n type IncreasingX,\n type IncreasingY,\n type MonotonicX,\n type MonotonicY,\n} from './traits.ts'\n\nexport const QuadraticPath2dTypeId: unique symbol = Symbol('curvy/path/quadratic2d')\nexport type QuadraticPath2dTypeId = typeof QuadraticPath2dTypeId\n\n/** @internal */\nexport class QuadraticPath2dImpl extends Pipeable implements QuadraticPath2d<unknown> {\n readonly [QuadraticPath2dTypeId]: QuadraticPath2dTypeId = QuadraticPath2dTypeId\n declare readonly [PathTraits]: unknown\n\n readonly curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>\n\n constructor(curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>) {\n super()\n this.curves = curves\n }\n\n [Symbol.iterator](): Iterator<QuadraticCurve2d.QuadraticCurve2d> {\n return this.curves[Symbol.iterator]()\n }\n}\n\n/** @internal */\nexport const isQuadraticPath2d = (p: unknown): p is QuadraticPath2d =>\n typeof p === 'object' && p !== null && QuadraticPath2dTypeId in p\n\n/** @internal */\nexport const make = (\n ...curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>\n): QuadraticPath2d => new QuadraticPath2dImpl(curves)\n\n/** @internal */\nexport const fromArray = (\n curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>,\n): QuadraticPath2d => new QuadraticPath2dImpl(curves)\n\n/** @internal */\nexport const append = dual<\n (c: QuadraticCurve2d.QuadraticCurve2d) => (p: QuadraticPath2d) => QuadraticPath2d,\n (p: QuadraticPath2d, c: QuadraticCurve2d.QuadraticCurve2d) => QuadraticPath2d\n>(2, (p: QuadraticPath2d, c: QuadraticCurve2d.QuadraticCurve2d) => fromArray([...p, c]))\n\n/** @internal */\nexport const length = (p: QuadraticPath2d) => {\n let total = 0\n for (const curve of p) {\n total += QuadraticCurve2d.length(curve, Interval.unit)\n }\n\n return total\n}\n\n/** @internal */\nexport const solve = dual<\n (u: number) => (p: QuadraticPath2d) => Vector2,\n (p: QuadraticPath2d, u: number) => Vector2\n>(2, (p: QuadraticPath2d, u: number) => {\n const curves = p instanceof QuadraticPath2dImpl ? p.curves : [...p]\n\n if (u === 1) {\n const last = curves.at(-1) as QuadraticCurve2d.QuadraticCurve2d\n return QuadraticCurve2d.solve(last, 1)\n }\n\n const t = u * curves.length\n const i = Math.floor(t)\n const curve = curves[i] as QuadraticCurve2d.QuadraticCurve2d\n return QuadraticCurve2d.solve(curve, t - i)\n})\n\n// Quadratic Bernstein basis: P(t) = (1-t)²·p0 + 2(1-t)t·p1 + t²·p2\n// expanded gives c0 = p0, c1 = -2p0 + 2p1, c2 = p0 - 2p1 + p2, so:\n// p0 = c0, p1 = c0 + c1/2, p2 = c0 + c1 + c2.\n/** @internal */\nexport const toPathData = (p: QuadraticPath2d): string => {\n let result = ''\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n\n for (const curve of p) {\n const c0x = curve.x.c0\n const c0y = curve.y.c0\n const c1x = curve.x.c1\n const c1y = curve.y.c1\n const c2x = curve.x.c2\n const c2y = curve.y.c2\n\n const startX = c0x\n const startY = c0y\n const ctrlX = c0x + c1x / 2\n const ctrlY = c0y + c1y / 2\n const endX = c0x + c1x + c2x\n const endY = c0y + c1y + c2y\n\n if (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY)) {\n result += ` M ${startX},${startY}`\n }\n result += ` Q ${ctrlX},${ctrlY} ${endX},${endY}`\n\n prevEndX = endX\n prevEndY = endY\n }\n\n return result.slice(1)\n}\n\n/** @internal */\nexport const isContinuous = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & Continuous> => {\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n let first = true\n\n for (const curve of p) {\n const startX = curve.x.c0\n const startY = curve.y.c0\n if (!first && (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY))) {\n return false\n }\n prevEndX = curve.x.c0 + curve.x.c1 + curve.x.c2\n prevEndY = curve.y.c0 + curve.y.c1 + curve.y.c2\n first = false\n }\n return true\n}\n\n/** @internal */\nexport const asContinuous = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & Continuous> => {\n invariant(isContinuous(p), 'quadratic path is not continuous')\n return p\n}\n\n// Per-axis monotonicity for the path: every segment's axis polynomial must be\n// strictly monotonic over the unit interval AND adjacent segments' axis\n// ranges must not overlap (modulo EPSILON for float drift).\n/** @internal */\nexport const isIncreasingX = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & IncreasingX> => {\n let prevEnd = Number.NEGATIVE_INFINITY\n for (const c of p) {\n if (!QuadraticPolynomial.isIncreasing(c.x, Interval.unit)) {\n return false\n }\n if (c.x.c0 < prevEnd - EPSILON) {\n return false\n }\n prevEnd = c.x.c0 + c.x.c1 + c.x.c2\n }\n return true\n}\n\n/** @internal */\nexport const isDecreasingX = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & DecreasingX> => {\n let prevEnd = Number.POSITIVE_INFINITY\n for (const c of p) {\n if (!QuadraticPolynomial.isDecreasing(c.x, Interval.unit)) {\n return false\n }\n if (c.x.c0 > prevEnd + EPSILON) {\n return false\n }\n prevEnd = c.x.c0 + c.x.c1 + c.x.c2\n }\n return true\n}\n\n/** @internal */\nexport const isMonotonicX = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & MonotonicX> =>\n isIncreasingX(p) || isDecreasingX(p)\n\n/** @internal */\nexport const isIncreasingY = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & IncreasingY> => {\n let prevEnd = Number.NEGATIVE_INFINITY\n for (const c of p) {\n if (!QuadraticPolynomial.isIncreasing(c.y, Interval.unit)) {\n return false\n }\n if (c.y.c0 < prevEnd - EPSILON) {\n return false\n }\n prevEnd = c.y.c0 + c.y.c1 + c.y.c2\n }\n return true\n}\n\n/** @internal */\nexport const isDecreasingY = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & DecreasingY> => {\n let prevEnd = Number.POSITIVE_INFINITY\n for (const c of p) {\n if (!QuadraticPolynomial.isDecreasing(c.y, Interval.unit)) {\n return false\n }\n if (c.y.c0 > prevEnd + EPSILON) {\n return false\n }\n prevEnd = c.y.c0 + c.y.c1 + c.y.c2\n }\n return true\n}\n\n/** @internal */\nexport const isMonotonicY = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & MonotonicY> =>\n isIncreasingY(p) || isDecreasingY(p)\n\n/** @internal */\nexport const asIncreasingX = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & IncreasingX> => {\n invariant(isIncreasingX(p), 'quadratic path is not increasing in x')\n return p\n}\n\n/** @internal */\nexport const asDecreasingX = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & DecreasingX> => {\n invariant(isDecreasingX(p), 'quadratic path is not decreasing in x')\n return p\n}\n\n/** @internal */\nexport const asMonotonicX = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & MonotonicX> => {\n invariant(isMonotonicX(p), 'quadratic path is not monotonic in x')\n return p\n}\n\n/** @internal */\nexport const asIncreasingY = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & IncreasingY> => {\n invariant(isIncreasingY(p), 'quadratic path is not increasing in y')\n return p\n}\n\n/** @internal */\nexport const asDecreasingY = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & DecreasingY> => {\n invariant(isDecreasingY(p), 'quadratic path is not decreasing in y')\n return p\n}\n\n/** @internal */\nexport const asMonotonicY = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & MonotonicY> => {\n invariant(isMonotonicY(p), 'quadratic path is not monotonic in y')\n return p\n}\n\n// solveAtX/Y on a monotonic-axis path: locate the segment whose axis range\n// contains the queried value, then delegate to the curve solver. Since the\n// path is monotonic in that axis, at most one segment matches and the\n// curve-level call is single-valued.\n/** @internal */\nexport const solveAtX = dual(2, (p: QuadraticPath2d, x: number): Solution.AtMostOne<number> => {\n for (const c of p) {\n const sx = c.x.c0\n const ex = c.x.c0 + c.x.c1 + c.x.c2\n const lo = Math.min(sx, ex)\n const hi = Math.max(sx, ex)\n if (x >= lo - EPSILON && x <= hi + EPSILON) {\n return QuadraticCurve2d.solveAtX(c, x) as Solution.AtMostOne<number>\n }\n }\n return Solution.none\n})\n\n/** @internal */\nexport const solveAtY = dual(2, (p: QuadraticPath2d, y: number): Solution.AtMostOne<number> => {\n for (const c of p) {\n const sy = c.y.c0\n const ey = c.y.c0 + c.y.c1 + c.y.c2\n const lo = Math.min(sy, ey)\n const hi = Math.max(sy, ey)\n if (y >= lo - EPSILON && y <= hi + EPSILON) {\n return QuadraticCurve2d.solveAtY(c, y) as Solution.AtMostOne<number>\n }\n }\n return Solution.none\n})\n\n/** @internal */\nexport const boundingBox = (\n p: QuadraticPath2d,\n): Interval2d.Interval2d<Interval.Closed, Interval.Closed> => {\n const iter = p[Symbol.iterator]()\n const first = iter.next()\n let acc = QuadraticCurve2d.boundingBox(first.value as QuadraticCurve2d.QuadraticCurve2d)\n for (let next = iter.next(); !next.done; next = iter.next()) {\n acc = Interval2d.union(acc, QuadraticCurve2d.boundingBox(next.value))\n }\n return acc\n}\n","import type { Interval2d } from '../interval/interval2d.ts'\nimport type { QuadraticCurve2d } from '../curve/quadratic2d.ts'\nimport type { Closed } from '../interval/interval.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { QuadraticPath2dTypeId } from './quadratic2d.internal.ts'\nimport * as internal from './quadratic2d.internal.ts'\nimport type {\n Continuous,\n DecreasingX,\n DecreasingY,\n IncreasingX,\n IncreasingY,\n MonotonicX,\n MonotonicY,\n PathTraits,\n} from './traits.ts'\n\nexport type {\n Continuous,\n DecreasingX,\n DecreasingY,\n IncreasingX,\n IncreasingY,\n MonotonicX,\n MonotonicY,\n} from './traits.ts'\n\n/**\n * A quadratic path in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The `Trait` type parameter accumulates trait brands as the path is refined\n * via `isContinuous` / `asContinuous`.\n *\n * @since 1.0.0\n */\nexport interface QuadraticPath2d<out Trait = unknown> extends Pipeable, Iterable<QuadraticCurve2d> {\n readonly [QuadraticPath2dTypeId]: QuadraticPath2dTypeId\n readonly [PathTraits]: Trait\n}\n\n/**\n * Creates a new `QuadraticPath2d` instance from a sequence of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `QuadraticPath2d` instance.\n * @since 2.0.0\n */\nexport const make: (...curves: ReadonlyArray<QuadraticCurve2d>) => QuadraticPath2d = internal.make\n\n/**\n * Creates a new `QuadraticPath2d` instance from an array of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `QuadraticPath2d` instance.\n * @since 2.0.0\n */\nexport const fromArray: (curves: ReadonlyArray<QuadraticCurve2d>) => QuadraticPath2d =\n internal.fromArray\n\n/**\n * Checks if a value is a `QuadraticPath2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `QuadraticPath2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isQuadraticPath2d: (p: unknown) => p is QuadraticPath2d = internal.isQuadraticPath2d\n\nexport const append: {\n /**\n * Appends a quadratic curve to a quadratic path.\n *\n * @param c - The quadratic curve to append.\n * @returns A function that takes a quadratic path and returns a new quadratic path.\n * @since 1.0.0\n */\n (c: QuadraticCurve2d): (p: QuadraticPath2d) => QuadraticPath2d\n /**\n * Appends a quadratic curve to a quadratic path.\n *\n * @param p - The quadratic path to append to.\n * @param c - The quadratic curve to append.\n * @returns A new `QuadraticPath2d` instance with the appended curve.\n * @since 1.0.0\n */\n (p: QuadraticPath2d, c: QuadraticCurve2d): QuadraticPath2d\n} = internal.append\n\n/**\n * Calculates the length of a quadratic path.\n *\n * @param p - The quadratic path to calculate the length of.\n * @returns The length of the path.\n */\nexport const length: (p: QuadraticPath2d) => number = internal.length\n\nexport const solve: {\n /**\n * Solves a quadratic path at a given parameter.\n *\n * @param u - The parameter to solve for.\n * @returns A function that takes a quadratic path and returns the solved point.\n * @since 1.0.0\n */\n (u: number): (p: QuadraticPath2d) => Vector2\n /**\n * Solves a quadratic path at a given parameter.\n *\n * @param p - The quadratic path to solve.\n * @param u - The parameter to solve for.\n * @returns The solved point.\n * @since 1.0.0\n */\n (p: QuadraticPath2d, u: number): Vector2\n} = internal.solve\n\n/**\n * Serializes a quadratic path as an SVG path data string (the value of a\n * `<path>` element's `d` attribute), using `M` and `Q` commands. Discontinuities\n * between curves emit a fresh `M` command.\n *\n * @param p - The quadratic path to serialize.\n * @returns The SVG path data string.\n * @since 2.0.0\n */\nexport const toPathData: (p: QuadraticPath2d) => string = internal.toPathData\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & Continuous>` when adjacent curves connect.\n *\n * @since 2.0.0\n */\nexport const isContinuous: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & Continuous> =\n internal.isContinuous\n\n/**\n * Asserts that the quadratic path is continuous, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asContinuous: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & Continuous> =\n internal.asContinuous\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & IncreasingX>` when every segment's x-polynomial is\n * strictly increasing on `[0, 1]` and adjacent segments' x-ranges don't\n * overlap.\n *\n * @since 2.0.0\n */\nexport const isIncreasingX: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & IncreasingX> =\n internal.isIncreasingX\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & DecreasingX>`.\n *\n * @since 2.0.0\n */\nexport const isDecreasingX: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & DecreasingX> =\n internal.isDecreasingX\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & MonotonicX>`.\n *\n * @since 2.0.0\n */\nexport const isMonotonicX: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & MonotonicX> =\n internal.isMonotonicX\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & IncreasingY>`.\n *\n * @since 2.0.0\n */\nexport const isIncreasingY: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & IncreasingY> =\n internal.isIncreasingY\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & DecreasingY>`.\n *\n * @since 2.0.0\n */\nexport const isDecreasingY: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & DecreasingY> =\n internal.isDecreasingY\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & MonotonicY>`.\n *\n * @since 2.0.0\n */\nexport const isMonotonicY: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & MonotonicY> =\n internal.isMonotonicY\n\n/**\n * Asserts that the path is strictly increasing in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasingX: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & IncreasingX> =\n internal.asIncreasingX\n\n/**\n * Asserts that the path is strictly decreasing in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasingX: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & DecreasingX> =\n internal.asDecreasingX\n\n/**\n * Asserts that the path is monotonic in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asMonotonicX: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & MonotonicX> =\n internal.asMonotonicX\n\n/**\n * Asserts that the path is strictly increasing in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasingY: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & IncreasingY> =\n internal.asIncreasingY\n\n/**\n * Asserts that the path is strictly decreasing in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasingY: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & DecreasingY> =\n internal.asDecreasingY\n\n/**\n * Asserts that the path is monotonic in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asMonotonicY: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & MonotonicY> =\n internal.asMonotonicY\n\nexport const solveAtX: {\n /**\n * Evaluates the path's y value at a given x. Requires the path to carry\n * the `MonotonicX` brand. Returns `Solution.none` when x is outside the\n * path's x-range.\n *\n * @param p - A path branded `MonotonicX`.\n * @param x - The x coordinate.\n * @returns The y value at x, or `none` when x is outside the path's range.\n * @since 2.0.0\n */\n <T extends MonotonicX>(p: QuadraticPath2d<T>, x: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (x: number): <T extends MonotonicX>(p: QuadraticPath2d<T>) => Solution.AtMostOne<number>\n} = internal.solveAtX as never\n\nexport const solveAtY: {\n /**\n * Evaluates the path's x value at a given y. Requires the path to carry\n * the `MonotonicY` brand. Returns `Solution.none` when y is outside the\n * path's y-range.\n *\n * @param p - A path branded `MonotonicY`.\n * @param y - The y coordinate.\n * @returns The x value at y, or `none` when y is outside the path's range.\n * @since 2.0.0\n */\n <T extends MonotonicY>(p: QuadraticPath2d<T>, y: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (y: number): <T extends MonotonicY>(p: QuadraticPath2d<T>) => Solution.AtMostOne<number>\n} = internal.solveAtY as never\n\n/**\n * Computes the axis-aligned bounding box of the path — the smallest closed\n * `Box2d` enclosing every segment.\n *\n * @param p - The quadratic path.\n * @returns A closed `Box2d` enclosing the path.\n * @since 2.0.0\n */\nexport const boundingBox: (p: QuadraticPath2d) => Interval2d<Closed, Closed> = internal.boundingBox\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["isLinearPath2d","make","fromArray","append","length","LinearCurve2d.length","Interval.unit","solve","LinearCurve2d.solve","toPathData","isContinuous","asContinuous","isIncreasingX","LinearPolynomial.isIncreasing","isDecreasingX","LinearPolynomial.isDecreasing","isMonotonicX","isIncreasingY","isDecreasingY","isMonotonicY","asIncreasingX","asDecreasingX","asMonotonicX","asIncreasingY","asDecreasingY","asMonotonicY","solveAtX","Solution.one","LinearCurve2d.solveAtX","Solution.isNone","Solution.none","solveAtY","LinearCurve2d.solveAtY","boundingBox","LinearCurve2d.boundingBox","Interval2d.union","make","internal.make","fromArray","internal.fromArray","internal.isLinearPath2d","append","internal.append","length","internal.length","solve","internal.solve","toPathData","internal.toPathData","isContinuous","internal.isContinuous","asContinuous","internal.asContinuous","isIncreasingX","internal.isIncreasingX","isDecreasingX","internal.isDecreasingX","isMonotonicX","internal.isMonotonicX","isIncreasingY","internal.isIncreasingY","isDecreasingY","internal.isDecreasingY","isMonotonicY","internal.isMonotonicY","asIncreasingX","internal.asIncreasingX","asDecreasingX","internal.asDecreasingX","asMonotonicX","internal.asMonotonicX","asIncreasingY","internal.asIncreasingY","asDecreasingY","internal.asDecreasingY","asMonotonicY","internal.asMonotonicY","solveAtX","internal.solveAtX","solveAtY","internal.solveAtY","boundingBox","internal.boundingBox","isQuadraticPath2d","make","fromArray","append","length","QuadraticCurve2d.length","Interval.unit","solve","QuadraticCurve2d.solve","toPathData","isContinuous","asContinuous","isIncreasingX","QuadraticPolynomial.isIncreasing","isDecreasingX","QuadraticPolynomial.isDecreasing","isMonotonicX","isIncreasingY","isDecreasingY","isMonotonicY","asIncreasingX","asDecreasingX","asMonotonicX","asIncreasingY","asDecreasingY","asMonotonicY","solveAtX","Solution.one","QuadraticCurve2d.solveAtX","Solution.isNone","Solution.none","solveAtY","QuadraticCurve2d.solveAtY","boundingBox","QuadraticCurve2d.boundingBox","Interval2d.union","internal.make","internal.fromArray","internal.isQuadraticPath2d","internal.append","internal.length","internal.solve","internal.toPathData","internal.isContinuous","internal.asContinuous","internal.isIncreasingX","internal.isDecreasingX","internal.isMonotonicX","internal.isIncreasingY","internal.isDecreasingY","internal.isMonotonicY","internal.asIncreasingX","internal.asDecreasingX","internal.asMonotonicX","internal.asIncreasingY","internal.asDecreasingY","internal.asMonotonicY","internal.solveAtX","internal.solveAtY","internal.boundingBox"],"sources":["../../src/path/linear2d.internal.ts","../../src/path/linear2d.ts","../../src/path/quadratic2d.internal.ts","../../src/path/quadratic2d.ts"],"sourcesContent":["import * as Interval2d from '../interval/interval2d.ts'\nimport * as LinearCurve2d from '../curve/linear2d.ts'\nimport * as Interval from '../interval/interval.ts'\nimport * as LinearPolynomial from '../polynomial/linear.ts'\nimport * as Solution from '../solution/solution.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport { invariant } from '../utils.ts'\nimport { EPSILON, epsEquals } from '../number.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { LinearPath2d } from './linear2d.ts'\nimport {\n PathTraits,\n type Continuous,\n type DecreasingX,\n type DecreasingY,\n type IncreasingX,\n type IncreasingY,\n type MonotonicX,\n type MonotonicY,\n} from './traits.ts'\n\nexport const LinearPath2dTypeId: unique symbol = Symbol('curvy/path/linear2d')\nexport type LinearPath2dTypeId = typeof LinearPath2dTypeId\n\n/** @internal */\nexport class LinearPath2dImpl extends Pipeable implements LinearPath2d<unknown> {\n readonly [LinearPath2dTypeId]: LinearPath2dTypeId = LinearPath2dTypeId\n declare readonly [PathTraits]: unknown\n\n readonly curves: ReadonlyArray<LinearCurve2d.LinearCurve2d>\n\n constructor(curves: ReadonlyArray<LinearCurve2d.LinearCurve2d>) {\n super()\n this.curves = curves\n }\n\n [Symbol.iterator](): Iterator<LinearCurve2d.LinearCurve2d> {\n return this.curves[Symbol.iterator]()\n }\n}\n\n/** @internal */\nexport const isLinearPath2d = (p: unknown): p is LinearPath2d =>\n typeof p === 'object' && p !== null && LinearPath2dTypeId in p\n\n/** @internal */\nexport const make = (...curves: ReadonlyArray<LinearCurve2d.LinearCurve2d>): LinearPath2d =>\n new LinearPath2dImpl(curves)\n\n/** @internal */\nexport const fromArray = (curves: ReadonlyArray<LinearCurve2d.LinearCurve2d>) =>\n new LinearPath2dImpl(curves)\n\n/** @internal */\nexport const append = dual<\n (c: LinearCurve2d.LinearCurve2d) => (p: LinearPath2d) => LinearPath2d,\n (p: LinearPath2d, c: LinearCurve2d.LinearCurve2d) => LinearPath2d\n>(2, (p: LinearPath2d, c: LinearCurve2d.LinearCurve2d) => fromArray([...p, c]))\n\n/** @internal */\nexport const length = (p: LinearPath2d) => {\n let total = 0\n for (const curve of p) {\n total += LinearCurve2d.length(curve, Interval.unit)\n }\n\n return total\n}\n\n/** @internal */\nexport const solve = dual<\n (u: number) => (p: LinearPath2d) => Vector2,\n (p: LinearPath2d, u: number) => Vector2\n>(2, (p: LinearPath2d, u: number) => {\n const curves = p instanceof LinearPath2dImpl ? p.curves : [...p]\n\n if (u === 1) {\n const last = curves.at(-1) as LinearCurve2d.LinearCurve2d\n return LinearCurve2d.solve(last, 1)\n }\n\n const t = u * curves.length\n const i = Math.floor(t)\n const curve = curves[i] as LinearCurve2d.LinearCurve2d\n return LinearCurve2d.solve(curve, t - i)\n})\n\n/** @internal */\nexport const toPathData = (p: LinearPath2d): string => {\n let result = ''\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n\n for (const curve of p) {\n const startX = curve.x.c0\n const startY = curve.y.c0\n const endX = curve.x.c0 + curve.x.c1\n const endY = curve.y.c0 + curve.y.c1\n\n if (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY)) {\n result += ` M ${startX},${startY}`\n }\n result += ` L ${endX},${endY}`\n\n prevEndX = endX\n prevEndY = endY\n }\n\n return result.slice(1)\n}\n\n/** @internal */\nexport const isContinuous = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & Continuous> => {\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n let first = true\n\n for (const curve of p) {\n const startX = curve.x.c0\n const startY = curve.y.c0\n if (!first && (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY))) {\n return false\n }\n prevEndX = curve.x.c0 + curve.x.c1\n prevEndY = curve.y.c0 + curve.y.c1\n first = false\n }\n return true\n}\n\n/** @internal */\nexport const asContinuous = <T>(p: LinearPath2d<T>): LinearPath2d<T & Continuous> => {\n invariant(isContinuous(p), 'linear path is not continuous')\n return p\n}\n\n// Per-axis monotonicity refiners. A path is monotonic-on-an-axis when every\n// segment's per-axis polynomial is strictly monotonic in the same direction\n// AND adjacent segments' ranges on that axis don't overlap (modulo float\n// tolerance) — so the path's u → axis mapping is monotonic across joins.\n\n/** @internal */\nexport const isIncreasingX = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & IncreasingX> => {\n let prevEnd = Number.NEGATIVE_INFINITY\n for (const c of p) {\n if (!LinearPolynomial.isIncreasing(c.x)) {\n return false\n }\n if (c.x.c0 < prevEnd - EPSILON) {\n return false\n }\n prevEnd = c.x.c0 + c.x.c1\n }\n return true\n}\n\n/** @internal */\nexport const isDecreasingX = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & DecreasingX> => {\n let prevEnd = Number.POSITIVE_INFINITY\n for (const c of p) {\n if (!LinearPolynomial.isDecreasing(c.x)) {\n return false\n }\n if (c.x.c0 > prevEnd + EPSILON) {\n return false\n }\n prevEnd = c.x.c0 + c.x.c1\n }\n return true\n}\n\n/** @internal */\nexport const isMonotonicX = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & MonotonicX> =>\n isIncreasingX(p) || isDecreasingX(p)\n\n/** @internal */\nexport const isIncreasingY = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & IncreasingY> => {\n let prevEnd = Number.NEGATIVE_INFINITY\n for (const c of p) {\n if (!LinearPolynomial.isIncreasing(c.y)) {\n return false\n }\n if (c.y.c0 < prevEnd - EPSILON) {\n return false\n }\n prevEnd = c.y.c0 + c.y.c1\n }\n return true\n}\n\n/** @internal */\nexport const isDecreasingY = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & DecreasingY> => {\n let prevEnd = Number.POSITIVE_INFINITY\n for (const c of p) {\n if (!LinearPolynomial.isDecreasing(c.y)) {\n return false\n }\n if (c.y.c0 > prevEnd + EPSILON) {\n return false\n }\n prevEnd = c.y.c0 + c.y.c1\n }\n return true\n}\n\n/** @internal */\nexport const isMonotonicY = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & MonotonicY> =>\n isIncreasingY(p) || isDecreasingY(p)\n\n/** @internal */\nexport const asIncreasingX = <T>(p: LinearPath2d<T>): LinearPath2d<T & IncreasingX> => {\n invariant(isIncreasingX(p), 'linear path is not increasing in x')\n return p\n}\n\n/** @internal */\nexport const asDecreasingX = <T>(p: LinearPath2d<T>): LinearPath2d<T & DecreasingX> => {\n invariant(isDecreasingX(p), 'linear path is not decreasing in x')\n return p\n}\n\n/** @internal */\nexport const asMonotonicX = <T>(p: LinearPath2d<T>): LinearPath2d<T & MonotonicX> => {\n invariant(isMonotonicX(p), 'linear path is not monotonic in x')\n return p\n}\n\n/** @internal */\nexport const asIncreasingY = <T>(p: LinearPath2d<T>): LinearPath2d<T & IncreasingY> => {\n invariant(isIncreasingY(p), 'linear path is not increasing in y')\n return p\n}\n\n/** @internal */\nexport const asDecreasingY = <T>(p: LinearPath2d<T>): LinearPath2d<T & DecreasingY> => {\n invariant(isDecreasingY(p), 'linear path is not decreasing in y')\n return p\n}\n\n/** @internal */\nexport const asMonotonicY = <T>(p: LinearPath2d<T>): LinearPath2d<T & MonotonicY> => {\n invariant(isMonotonicY(p), 'linear path is not monotonic in y')\n return p\n}\n\n// solveAtX/solveAtY for `Monotonic{X,Y}` paths. Two defenses against float\n// drift at interior knots (where adjacent segments both bracket the query):\n// 1. Snap to t=0/t=1 endpoint y when the query is within EPSILON of a\n// segment's start or end.\n// 2. Fall through to the next bracketing segment on `none`. Linear paths\n// don't currently surface drift (degree-1 `c0 + c1 = x` is stable), but\n// the same shape applies for symmetry with quadratic / cubic.\n/** @internal */\nexport const solveAtX = dual(2, (p: LinearPath2d, x: number): Solution.AtMostOne<number> => {\n for (const c of p) {\n const sx = c.x.c0\n const ex = c.x.c0 + c.x.c1\n const lo = Math.min(sx, ex)\n const hi = Math.max(sx, ex)\n if (x >= lo - EPSILON && x <= hi + EPSILON) {\n if (epsEquals(x, sx)) {\n return Solution.one(c.y.c0)\n }\n if (epsEquals(x, ex)) {\n return Solution.one(c.y.c0 + c.y.c1)\n }\n const sol = LinearCurve2d.solveAtX(c, x)\n if (!Solution.isNone(sol)) {\n return sol\n }\n }\n }\n return Solution.none\n})\n\n/** @internal */\nexport const solveAtY = dual(2, (p: LinearPath2d, y: number): Solution.AtMostOne<number> => {\n for (const c of p) {\n const sy = c.y.c0\n const ey = c.y.c0 + c.y.c1\n const lo = Math.min(sy, ey)\n const hi = Math.max(sy, ey)\n if (y >= lo - EPSILON && y <= hi + EPSILON) {\n if (epsEquals(y, sy)) {\n return Solution.one(c.x.c0)\n }\n if (epsEquals(y, ey)) {\n return Solution.one(c.x.c0 + c.x.c1)\n }\n const sol = LinearCurve2d.solveAtY(c, y)\n if (!Solution.isNone(sol)) {\n return sol\n }\n }\n }\n return Solution.none\n})\n\n/** @internal */\nexport const boundingBox = (\n p: LinearPath2d,\n): Interval2d.Interval2d<Interval.Closed, Interval.Closed> => {\n const iter = p[Symbol.iterator]()\n const first = iter.next()\n // path invariant: at least one curve, so first.value is defined\n let acc = LinearCurve2d.boundingBox(first.value as LinearCurve2d.LinearCurve2d)\n for (let next = iter.next(); !next.done; next = iter.next()) {\n acc = Interval2d.union(acc, LinearCurve2d.boundingBox(next.value))\n }\n return acc\n}\n","import type { Interval2d } from '../interval/interval2d.ts'\nimport type { LinearCurve2d } from '../curve/linear2d.ts'\nimport type { Closed } from '../interval/interval.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { LinearPath2dTypeId } from './linear2d.internal.ts'\nimport * as internal from './linear2d.internal.ts'\nimport type {\n Continuous,\n DecreasingX,\n DecreasingY,\n IncreasingX,\n IncreasingY,\n MonotonicX,\n MonotonicY,\n PathTraits,\n} from './traits.ts'\n\nexport type {\n Continuous,\n DecreasingX,\n DecreasingY,\n IncreasingX,\n IncreasingY,\n MonotonicX,\n MonotonicY,\n} from './traits.ts'\n\n/**\n * A linear path in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The `Trait` type parameter accumulates trait brands as the path is refined\n * via `isContinuous` / `asContinuous`. A `Continuous` path's `toPathData`\n * skips the per-segment discontinuity check.\n *\n * @since 1.0.0\n */\nexport interface LinearPath2d<out Trait = unknown> extends Pipeable, Iterable<LinearCurve2d> {\n readonly [LinearPath2dTypeId]: LinearPath2dTypeId\n readonly [PathTraits]: Trait\n}\n\n/**\n * Creates a new `LinearPath2d` instance from a sequence of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `LinearPath2d` instance.\n * @since 2.0.0\n */\nexport const make: (...curves: ReadonlyArray<LinearCurve2d>) => LinearPath2d = internal.make\n\n/**\n * Creates a new `LinearPath2d` instance from an array of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `LinearPath2d` instance.\n * @since 2.0.0\n */\nexport const fromArray: (curves: ReadonlyArray<LinearCurve2d>) => LinearPath2d = internal.fromArray\n\n/**\n * Checks if a value is a `LinearPath2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `LinearPath2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isLinearPath2d: (p: unknown) => p is LinearPath2d = internal.isLinearPath2d\n\nexport const append: {\n /**\n * Appends a linear curve to a linear path.\n *\n * @param c - The linear curve to append.\n * @returns A function that takes a linear path and returns a new linear path.\n * @since 1.0.0\n */\n (c: LinearCurve2d): (p: LinearPath2d) => LinearPath2d\n /**\n * Appends a linear curve to a linear path.\n *\n * @param p - The linear path to append to.\n * @param c - The linear curve to append.\n * @returns A new `LinearPath2d` instance with the appended curve.\n * @since 1.0.0\n */\n (p: LinearPath2d, c: LinearCurve2d): LinearPath2d\n} = internal.append\n\n/**\n * Calculates the length of a linear path.\n *\n * @param p - The linear path to calculate the length of.\n * @returns The length of the linear path.\n * @since 1.0.0\n */\nexport const length: (p: LinearPath2d) => number = internal.length\n\nexport const solve: {\n /**\n * Solves a linear path for a given parameter.\n *\n * @param u - The parameter to solve for.\n * @returns A function that takes a linear path and returns the solved point.\n * @since 1.0.0\n */\n (u: number): (p: LinearPath2d) => Vector2\n /**\n * Solves a linear path for a given parameter.\n *\n * @param p - The linear path to solve.\n * @param u - The parameter to solve for.\n * @returns The solved point on the linear path.\n * @since 1.0.0\n */\n (p: LinearPath2d, u: number): Vector2\n} = internal.solve\n\n/**\n * Serializes a linear path as an SVG path data string (the value of a `<path>`\n * element's `d` attribute), using `M` and `L` commands. Discontinuities between\n * curves emit a fresh `M` command.\n *\n * @param p - The linear path to serialize.\n * @returns The SVG path data string.\n * @since 2.0.0\n */\nexport const toPathData: (p: LinearPath2d) => string = internal.toPathData\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & Continuous>` when adjacent curves connect at their join\n * points.\n *\n * @param p - The linear path to check.\n * @returns `true` when the path is continuous (G⁰).\n * @since 2.0.0\n */\nexport const isContinuous: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & Continuous> =\n internal.isContinuous\n\n/**\n * Asserts that the linear path is continuous, throwing on failure.\n *\n * @param p - The linear path to assert against.\n * @returns The same path, typed with the `Continuous` brand.\n * @throws When the path has a discontinuity between adjacent curves.\n * @since 2.0.0\n */\nexport const asContinuous: <T>(p: LinearPath2d<T>) => LinearPath2d<T & Continuous> =\n internal.asContinuous\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & IncreasingX>` when every segment's x-polynomial is\n * strictly increasing and adjacent segments' x-ranges don't overlap.\n *\n * @since 2.0.0\n */\nexport const isIncreasingX: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & IncreasingX> =\n internal.isIncreasingX\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & DecreasingX>` when every segment's x-polynomial is\n * strictly decreasing and adjacent segments' x-ranges don't overlap.\n *\n * @since 2.0.0\n */\nexport const isDecreasingX: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & DecreasingX> =\n internal.isDecreasingX\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & MonotonicX>` when the path is either increasing or\n * decreasing in x along its full parameter domain.\n *\n * @since 2.0.0\n */\nexport const isMonotonicX: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & MonotonicX> =\n internal.isMonotonicX\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & IncreasingY>`. The y-axis analog of {@link isIncreasingX}.\n *\n * @since 2.0.0\n */\nexport const isIncreasingY: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & IncreasingY> =\n internal.isIncreasingY\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & DecreasingY>`. The y-axis analog of {@link isDecreasingX}.\n *\n * @since 2.0.0\n */\nexport const isDecreasingY: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & DecreasingY> =\n internal.isDecreasingY\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & MonotonicY>`. The y-axis analog of {@link isMonotonicX}.\n *\n * @since 2.0.0\n */\nexport const isMonotonicY: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & MonotonicY> =\n internal.isMonotonicY\n\n/**\n * Asserts that the path is strictly increasing in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasingX: <T>(p: LinearPath2d<T>) => LinearPath2d<T & IncreasingX> =\n internal.asIncreasingX\n\n/**\n * Asserts that the path is strictly decreasing in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasingX: <T>(p: LinearPath2d<T>) => LinearPath2d<T & DecreasingX> =\n internal.asDecreasingX\n\n/**\n * Asserts that the path is monotonic in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asMonotonicX: <T>(p: LinearPath2d<T>) => LinearPath2d<T & MonotonicX> =\n internal.asMonotonicX\n\n/**\n * Asserts that the path is strictly increasing in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasingY: <T>(p: LinearPath2d<T>) => LinearPath2d<T & IncreasingY> =\n internal.asIncreasingY\n\n/**\n * Asserts that the path is strictly decreasing in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasingY: <T>(p: LinearPath2d<T>) => LinearPath2d<T & DecreasingY> =\n internal.asDecreasingY\n\n/**\n * Asserts that the path is monotonic in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asMonotonicY: <T>(p: LinearPath2d<T>) => LinearPath2d<T & MonotonicY> =\n internal.asMonotonicY\n\nexport const solveAtX: {\n /**\n * Evaluates the path's y value at a given x. Requires the path to carry the\n * `MonotonicX` brand — without it, an x query could match multiple\n * segments and the return cardinality would be unbounded.\n *\n * Returns `Solution.none` when x falls outside the path's x-range.\n *\n * @param p - A path branded `MonotonicX`.\n * @param x - The x coordinate.\n * @returns The y value at x, or `none` when x is outside the path's range.\n * @since 2.0.0\n */\n <T extends MonotonicX>(p: LinearPath2d<T>, x: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (x: number): <T extends MonotonicX>(p: LinearPath2d<T>) => Solution.AtMostOne<number>\n} = internal.solveAtX as never\n\nexport const solveAtY: {\n /**\n * Evaluates the path's x value at a given y. Requires the path to carry the\n * `MonotonicY` brand. Returns `Solution.none` when y is outside the path's\n * y-range.\n *\n * @param p - A path branded `MonotonicY`.\n * @param y - The y coordinate.\n * @returns The x value at y, or `none` when y is outside the path's range.\n * @since 2.0.0\n */\n <T extends MonotonicY>(p: LinearPath2d<T>, y: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (y: number): <T extends MonotonicY>(p: LinearPath2d<T>) => Solution.AtMostOne<number>\n} = internal.solveAtY as never\n\n/**\n * Computes the axis-aligned bounding box of the path — the smallest closed\n * `Box2d` enclosing every segment.\n *\n * @param p - The linear path.\n * @returns A closed `Box2d` enclosing the path.\n * @since 2.0.0\n */\nexport const boundingBox: (p: LinearPath2d) => Interval2d<Closed, Closed> = internal.boundingBox\n","import * as Interval2d from '../interval/interval2d.ts'\nimport * as QuadraticCurve2d from '../curve/quadratic2d.ts'\nimport * as Interval from '../interval/interval.ts'\nimport * as QuadraticPolynomial from '../polynomial/quadratic.ts'\nimport * as Solution from '../solution/solution.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport { invariant } from '../utils.ts'\nimport { EPSILON, epsEquals } from '../number.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { QuadraticPath2d } from './quadratic2d.ts'\nimport {\n PathTraits,\n type Continuous,\n type DecreasingX,\n type DecreasingY,\n type IncreasingX,\n type IncreasingY,\n type MonotonicX,\n type MonotonicY,\n} from './traits.ts'\n\nexport const QuadraticPath2dTypeId: unique symbol = Symbol('curvy/path/quadratic2d')\nexport type QuadraticPath2dTypeId = typeof QuadraticPath2dTypeId\n\n/** @internal */\nexport class QuadraticPath2dImpl extends Pipeable implements QuadraticPath2d<unknown> {\n readonly [QuadraticPath2dTypeId]: QuadraticPath2dTypeId = QuadraticPath2dTypeId\n declare readonly [PathTraits]: unknown\n\n readonly curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>\n\n constructor(curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>) {\n super()\n this.curves = curves\n }\n\n [Symbol.iterator](): Iterator<QuadraticCurve2d.QuadraticCurve2d> {\n return this.curves[Symbol.iterator]()\n }\n}\n\n/** @internal */\nexport const isQuadraticPath2d = (p: unknown): p is QuadraticPath2d =>\n typeof p === 'object' && p !== null && QuadraticPath2dTypeId in p\n\n/** @internal */\nexport const make = (\n ...curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>\n): QuadraticPath2d => new QuadraticPath2dImpl(curves)\n\n/** @internal */\nexport const fromArray = (\n curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>,\n): QuadraticPath2d => new QuadraticPath2dImpl(curves)\n\n/** @internal */\nexport const append = dual<\n (c: QuadraticCurve2d.QuadraticCurve2d) => (p: QuadraticPath2d) => QuadraticPath2d,\n (p: QuadraticPath2d, c: QuadraticCurve2d.QuadraticCurve2d) => QuadraticPath2d\n>(2, (p: QuadraticPath2d, c: QuadraticCurve2d.QuadraticCurve2d) => fromArray([...p, c]))\n\n/** @internal */\nexport const length = (p: QuadraticPath2d) => {\n let total = 0\n for (const curve of p) {\n total += QuadraticCurve2d.length(curve, Interval.unit)\n }\n\n return total\n}\n\n/** @internal */\nexport const solve = dual<\n (u: number) => (p: QuadraticPath2d) => Vector2,\n (p: QuadraticPath2d, u: number) => Vector2\n>(2, (p: QuadraticPath2d, u: number) => {\n const curves = p instanceof QuadraticPath2dImpl ? p.curves : [...p]\n\n if (u === 1) {\n const last = curves.at(-1) as QuadraticCurve2d.QuadraticCurve2d\n return QuadraticCurve2d.solve(last, 1)\n }\n\n const t = u * curves.length\n const i = Math.floor(t)\n const curve = curves[i] as QuadraticCurve2d.QuadraticCurve2d\n return QuadraticCurve2d.solve(curve, t - i)\n})\n\n// Quadratic Bernstein basis: P(t) = (1-t)²·p0 + 2(1-t)t·p1 + t²·p2\n// expanded gives c0 = p0, c1 = -2p0 + 2p1, c2 = p0 - 2p1 + p2, so:\n// p0 = c0, p1 = c0 + c1/2, p2 = c0 + c1 + c2.\n/** @internal */\nexport const toPathData = (p: QuadraticPath2d): string => {\n let result = ''\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n\n for (const curve of p) {\n const c0x = curve.x.c0\n const c0y = curve.y.c0\n const c1x = curve.x.c1\n const c1y = curve.y.c1\n const c2x = curve.x.c2\n const c2y = curve.y.c2\n\n const startX = c0x\n const startY = c0y\n const ctrlX = c0x + c1x / 2\n const ctrlY = c0y + c1y / 2\n const endX = c0x + c1x + c2x\n const endY = c0y + c1y + c2y\n\n if (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY)) {\n result += ` M ${startX},${startY}`\n }\n result += ` Q ${ctrlX},${ctrlY} ${endX},${endY}`\n\n prevEndX = endX\n prevEndY = endY\n }\n\n return result.slice(1)\n}\n\n/** @internal */\nexport const isContinuous = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & Continuous> => {\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n let first = true\n\n for (const curve of p) {\n const startX = curve.x.c0\n const startY = curve.y.c0\n if (!first && (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY))) {\n return false\n }\n prevEndX = curve.x.c0 + curve.x.c1 + curve.x.c2\n prevEndY = curve.y.c0 + curve.y.c1 + curve.y.c2\n first = false\n }\n return true\n}\n\n/** @internal */\nexport const asContinuous = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & Continuous> => {\n invariant(isContinuous(p), 'quadratic path is not continuous')\n return p\n}\n\n// Per-axis monotonicity for the path: every segment's axis polynomial must be\n// strictly monotonic over the unit interval AND adjacent segments' axis\n// ranges must not overlap (modulo EPSILON for float drift).\n/** @internal */\nexport const isIncreasingX = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & IncreasingX> => {\n let prevEnd = Number.NEGATIVE_INFINITY\n for (const c of p) {\n if (!QuadraticPolynomial.isIncreasing(c.x, Interval.unit)) {\n return false\n }\n if (c.x.c0 < prevEnd - EPSILON) {\n return false\n }\n prevEnd = c.x.c0 + c.x.c1 + c.x.c2\n }\n return true\n}\n\n/** @internal */\nexport const isDecreasingX = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & DecreasingX> => {\n let prevEnd = Number.POSITIVE_INFINITY\n for (const c of p) {\n if (!QuadraticPolynomial.isDecreasing(c.x, Interval.unit)) {\n return false\n }\n if (c.x.c0 > prevEnd + EPSILON) {\n return false\n }\n prevEnd = c.x.c0 + c.x.c1 + c.x.c2\n }\n return true\n}\n\n/** @internal */\nexport const isMonotonicX = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & MonotonicX> =>\n isIncreasingX(p) || isDecreasingX(p)\n\n/** @internal */\nexport const isIncreasingY = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & IncreasingY> => {\n let prevEnd = Number.NEGATIVE_INFINITY\n for (const c of p) {\n if (!QuadraticPolynomial.isIncreasing(c.y, Interval.unit)) {\n return false\n }\n if (c.y.c0 < prevEnd - EPSILON) {\n return false\n }\n prevEnd = c.y.c0 + c.y.c1 + c.y.c2\n }\n return true\n}\n\n/** @internal */\nexport const isDecreasingY = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & DecreasingY> => {\n let prevEnd = Number.POSITIVE_INFINITY\n for (const c of p) {\n if (!QuadraticPolynomial.isDecreasing(c.y, Interval.unit)) {\n return false\n }\n if (c.y.c0 > prevEnd + EPSILON) {\n return false\n }\n prevEnd = c.y.c0 + c.y.c1 + c.y.c2\n }\n return true\n}\n\n/** @internal */\nexport const isMonotonicY = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & MonotonicY> =>\n isIncreasingY(p) || isDecreasingY(p)\n\n/** @internal */\nexport const asIncreasingX = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & IncreasingX> => {\n invariant(isIncreasingX(p), 'quadratic path is not increasing in x')\n return p\n}\n\n/** @internal */\nexport const asDecreasingX = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & DecreasingX> => {\n invariant(isDecreasingX(p), 'quadratic path is not decreasing in x')\n return p\n}\n\n/** @internal */\nexport const asMonotonicX = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & MonotonicX> => {\n invariant(isMonotonicX(p), 'quadratic path is not monotonic in x')\n return p\n}\n\n/** @internal */\nexport const asIncreasingY = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & IncreasingY> => {\n invariant(isIncreasingY(p), 'quadratic path is not increasing in y')\n return p\n}\n\n/** @internal */\nexport const asDecreasingY = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & DecreasingY> => {\n invariant(isDecreasingY(p), 'quadratic path is not decreasing in y')\n return p\n}\n\n/** @internal */\nexport const asMonotonicY = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & MonotonicY> => {\n invariant(isMonotonicY(p), 'quadratic path is not monotonic in y')\n return p\n}\n\n// solveAtX/Y on a monotonic-axis path. Two defenses against float drift at\n// interior knots, where two adjacent segments both bracket the query and the\n// polynomial-inverse solver may return `none` for both:\n// 1. Snap to t=0/t=1 endpoint y when the query is within EPSILON of a\n// segment's start or end — bypasses polynomial inversion at knots.\n// 2. Fall through to the next bracketing segment on `none`. `MonotonicX/Y`\n// admits at most one real solution across the path, so retrying is safe.\n/** @internal */\nexport const solveAtX = dual(2, (p: QuadraticPath2d, x: number): Solution.AtMostOne<number> => {\n for (const c of p) {\n const sx = c.x.c0\n const ex = c.x.c0 + c.x.c1 + c.x.c2\n const lo = Math.min(sx, ex)\n const hi = Math.max(sx, ex)\n if (x >= lo - EPSILON && x <= hi + EPSILON) {\n if (epsEquals(x, sx)) {\n return Solution.one(c.y.c0)\n }\n if (epsEquals(x, ex)) {\n return Solution.one(c.y.c0 + c.y.c1 + c.y.c2)\n }\n const sol = QuadraticCurve2d.solveAtX(c, x) as Solution.AtMostOne<number>\n if (!Solution.isNone(sol)) {\n return sol\n }\n }\n }\n return Solution.none\n})\n\n/** @internal */\nexport const solveAtY = dual(2, (p: QuadraticPath2d, y: number): Solution.AtMostOne<number> => {\n for (const c of p) {\n const sy = c.y.c0\n const ey = c.y.c0 + c.y.c1 + c.y.c2\n const lo = Math.min(sy, ey)\n const hi = Math.max(sy, ey)\n if (y >= lo - EPSILON && y <= hi + EPSILON) {\n if (epsEquals(y, sy)) {\n return Solution.one(c.x.c0)\n }\n if (epsEquals(y, ey)) {\n return Solution.one(c.x.c0 + c.x.c1 + c.x.c2)\n }\n const sol = QuadraticCurve2d.solveAtY(c, y) as Solution.AtMostOne<number>\n if (!Solution.isNone(sol)) {\n return sol\n }\n }\n }\n return Solution.none\n})\n\n/** @internal */\nexport const boundingBox = (\n p: QuadraticPath2d,\n): Interval2d.Interval2d<Interval.Closed, Interval.Closed> => {\n const iter = p[Symbol.iterator]()\n const first = iter.next()\n let acc = QuadraticCurve2d.boundingBox(first.value as QuadraticCurve2d.QuadraticCurve2d)\n for (let next = iter.next(); !next.done; next = iter.next()) {\n acc = Interval2d.union(acc, QuadraticCurve2d.boundingBox(next.value))\n }\n return acc\n}\n","import type { Interval2d } from '../interval/interval2d.ts'\nimport type { QuadraticCurve2d } from '../curve/quadratic2d.ts'\nimport type { Closed } from '../interval/interval.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { QuadraticPath2dTypeId } from './quadratic2d.internal.ts'\nimport * as internal from './quadratic2d.internal.ts'\nimport type {\n Continuous,\n DecreasingX,\n DecreasingY,\n IncreasingX,\n IncreasingY,\n MonotonicX,\n MonotonicY,\n PathTraits,\n} from './traits.ts'\n\nexport type {\n Continuous,\n DecreasingX,\n DecreasingY,\n IncreasingX,\n IncreasingY,\n MonotonicX,\n MonotonicY,\n} from './traits.ts'\n\n/**\n * A quadratic path in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The `Trait` type parameter accumulates trait brands as the path is refined\n * via `isContinuous` / `asContinuous`.\n *\n * @since 1.0.0\n */\nexport interface QuadraticPath2d<out Trait = unknown> extends Pipeable, Iterable<QuadraticCurve2d> {\n readonly [QuadraticPath2dTypeId]: QuadraticPath2dTypeId\n readonly [PathTraits]: Trait\n}\n\n/**\n * Creates a new `QuadraticPath2d` instance from a sequence of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `QuadraticPath2d` instance.\n * @since 2.0.0\n */\nexport const make: (...curves: ReadonlyArray<QuadraticCurve2d>) => QuadraticPath2d = internal.make\n\n/**\n * Creates a new `QuadraticPath2d` instance from an array of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `QuadraticPath2d` instance.\n * @since 2.0.0\n */\nexport const fromArray: (curves: ReadonlyArray<QuadraticCurve2d>) => QuadraticPath2d =\n internal.fromArray\n\n/**\n * Checks if a value is a `QuadraticPath2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `QuadraticPath2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isQuadraticPath2d: (p: unknown) => p is QuadraticPath2d = internal.isQuadraticPath2d\n\nexport const append: {\n /**\n * Appends a quadratic curve to a quadratic path.\n *\n * @param c - The quadratic curve to append.\n * @returns A function that takes a quadratic path and returns a new quadratic path.\n * @since 1.0.0\n */\n (c: QuadraticCurve2d): (p: QuadraticPath2d) => QuadraticPath2d\n /**\n * Appends a quadratic curve to a quadratic path.\n *\n * @param p - The quadratic path to append to.\n * @param c - The quadratic curve to append.\n * @returns A new `QuadraticPath2d` instance with the appended curve.\n * @since 1.0.0\n */\n (p: QuadraticPath2d, c: QuadraticCurve2d): QuadraticPath2d\n} = internal.append\n\n/**\n * Calculates the length of a quadratic path.\n *\n * @param p - The quadratic path to calculate the length of.\n * @returns The length of the path.\n */\nexport const length: (p: QuadraticPath2d) => number = internal.length\n\nexport const solve: {\n /**\n * Solves a quadratic path at a given parameter.\n *\n * @param u - The parameter to solve for.\n * @returns A function that takes a quadratic path and returns the solved point.\n * @since 1.0.0\n */\n (u: number): (p: QuadraticPath2d) => Vector2\n /**\n * Solves a quadratic path at a given parameter.\n *\n * @param p - The quadratic path to solve.\n * @param u - The parameter to solve for.\n * @returns The solved point.\n * @since 1.0.0\n */\n (p: QuadraticPath2d, u: number): Vector2\n} = internal.solve\n\n/**\n * Serializes a quadratic path as an SVG path data string (the value of a\n * `<path>` element's `d` attribute), using `M` and `Q` commands. Discontinuities\n * between curves emit a fresh `M` command.\n *\n * @param p - The quadratic path to serialize.\n * @returns The SVG path data string.\n * @since 2.0.0\n */\nexport const toPathData: (p: QuadraticPath2d) => string = internal.toPathData\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & Continuous>` when adjacent curves connect.\n *\n * @since 2.0.0\n */\nexport const isContinuous: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & Continuous> =\n internal.isContinuous\n\n/**\n * Asserts that the quadratic path is continuous, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asContinuous: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & Continuous> =\n internal.asContinuous\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & IncreasingX>` when every segment's x-polynomial is\n * strictly increasing on `[0, 1]` and adjacent segments' x-ranges don't\n * overlap.\n *\n * @since 2.0.0\n */\nexport const isIncreasingX: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & IncreasingX> =\n internal.isIncreasingX\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & DecreasingX>`.\n *\n * @since 2.0.0\n */\nexport const isDecreasingX: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & DecreasingX> =\n internal.isDecreasingX\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & MonotonicX>`.\n *\n * @since 2.0.0\n */\nexport const isMonotonicX: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & MonotonicX> =\n internal.isMonotonicX\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & IncreasingY>`.\n *\n * @since 2.0.0\n */\nexport const isIncreasingY: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & IncreasingY> =\n internal.isIncreasingY\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & DecreasingY>`.\n *\n * @since 2.0.0\n */\nexport const isDecreasingY: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & DecreasingY> =\n internal.isDecreasingY\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & MonotonicY>`.\n *\n * @since 2.0.0\n */\nexport const isMonotonicY: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & MonotonicY> =\n internal.isMonotonicY\n\n/**\n * Asserts that the path is strictly increasing in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasingX: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & IncreasingX> =\n internal.asIncreasingX\n\n/**\n * Asserts that the path is strictly decreasing in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasingX: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & DecreasingX> =\n internal.asDecreasingX\n\n/**\n * Asserts that the path is monotonic in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asMonotonicX: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & MonotonicX> =\n internal.asMonotonicX\n\n/**\n * Asserts that the path is strictly increasing in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasingY: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & IncreasingY> =\n internal.asIncreasingY\n\n/**\n * Asserts that the path is strictly decreasing in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasingY: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & DecreasingY> =\n internal.asDecreasingY\n\n/**\n * Asserts that the path is monotonic in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asMonotonicY: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & MonotonicY> =\n internal.asMonotonicY\n\nexport const solveAtX: {\n /**\n * Evaluates the path's y value at a given x. Requires the path to carry\n * the `MonotonicX` brand. Returns `Solution.none` when x is outside the\n * path's x-range.\n *\n * @param p - A path branded `MonotonicX`.\n * @param x - The x coordinate.\n * @returns The y value at x, or `none` when x is outside the path's range.\n * @since 2.0.0\n */\n <T extends MonotonicX>(p: QuadraticPath2d<T>, x: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (x: number): <T extends MonotonicX>(p: QuadraticPath2d<T>) => Solution.AtMostOne<number>\n} = internal.solveAtX as never\n\nexport const solveAtY: {\n /**\n * Evaluates the path's x value at a given y. Requires the path to carry\n * the `MonotonicY` brand. Returns `Solution.none` when y is outside the\n * path's y-range.\n *\n * @param p - A path branded `MonotonicY`.\n * @param y - The y coordinate.\n * @returns The x value at y, or `none` when y is outside the path's range.\n * @since 2.0.0\n */\n <T extends MonotonicY>(p: QuadraticPath2d<T>, y: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (y: number): <T extends MonotonicY>(p: QuadraticPath2d<T>) => Solution.AtMostOne<number>\n} = internal.solveAtY as never\n\n/**\n * Computes the axis-aligned bounding box of the path — the smallest closed\n * `Box2d` enclosing every segment.\n *\n * @param p - The quadratic path.\n * @returns A closed `Box2d` enclosing the path.\n * @since 2.0.0\n */\nexport const boundingBox: (p: QuadraticPath2d) => Interval2d<Closed, Closed> = internal.boundingBox\n"],"mappings":"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"}
@@ -337,6 +337,16 @@ export declare const range: {
337
337
  */
338
338
  (domain: Interval): (p: CubicPolynomial) => Closed;
339
339
  };
340
+ /**
341
+ * Calculates the range of a cubic polynomial over the unit interval `[0, 1]`.
342
+ * Equivalent to `range(p, Interval.unit)` — accounts for up to two interior
343
+ * extrema in `[0, 1]`.
344
+ *
345
+ * @param p - The cubic polynomial.
346
+ * @returns The closed range of the polynomial over `[0, 1]`.
347
+ * @since 2.0.0
348
+ */
349
+ export declare const unitRange: (p: CubicPolynomial) => Closed;
340
350
  export declare const length: {
341
351
  /**
342
352
  * Calculates the length of a cubic polynomial.
@@ -1,3 +1,3 @@
1
- import { t as cubic_exports } from "../shared/cubic-NEn7E6V_.mjs";
2
- import { o as quadratic_exports, p as linear_exports } from "../shared/quadratic-Dlxqo2V1.mjs";
1
+ import { t as cubic_exports } from "../shared/cubic-DHJrzZJN.mjs";
2
+ import { o as quadratic_exports, p as linear_exports } from "../shared/quadratic-BZmfZE71.mjs";
3
3
  export { cubic_exports as CubicPolynomial, linear_exports as LinearPolynomial, quadratic_exports as QuadraticPolynomial };
@@ -296,6 +296,16 @@ export declare const range: {
296
296
  */
297
297
  (domain: Interval): (p: LinearPolynomial) => Closed;
298
298
  };
299
+ /**
300
+ * Calculates the range of a linear polynomial over the unit interval `[0, 1]`.
301
+ * Equivalent to `range(p, Interval.unit)` but without the import and call
302
+ * overhead — directly evaluates the endpoints.
303
+ *
304
+ * @param p - The linear polynomial.
305
+ * @returns The closed range of the polynomial over `[0, 1]`.
306
+ * @since 2.0.0
307
+ */
308
+ export declare const unitRange: (p: LinearPolynomial) => Closed;
299
309
  export declare const length: {
300
310
  /**
301
311
  * Calculates the length of a linear polynomial within a particular domain `Interval`.
@@ -331,6 +331,16 @@ export declare const range: {
331
331
  */
332
332
  (domain: Interval): (p: QuadraticPolynomial) => Closed;
333
333
  };
334
+ /**
335
+ * Computes the range of the quadratic polynomial over the unit interval
336
+ * `[0, 1]`. Equivalent to `range(p, Interval.unit)` — accounts for any
337
+ * interior extremum in `[0, 1]`.
338
+ *
339
+ * @param p - The quadratic polynomial.
340
+ * @returns The closed range of the polynomial over `[0, 1]`.
341
+ * @since 2.0.0
342
+ */
343
+ export declare const unitRange: (p: QuadraticPolynomial) => Closed;
334
344
  export declare const length: {
335
345
  /**
336
346
  * Computes the length of the quadratic polynomial over a given interval.
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./chunk-25Hzd3z8.mjs";
2
2
  import { roundDown } from "../number.mjs";
3
3
  import { a as vectorProductLeft, n as make } from "./matrix4x4-BWmf4lZM.mjs";
4
- import { r as fromVector } from "./cubic-NEn7E6V_.mjs";
4
+ import { r as fromVector } from "./cubic-DHJrzZJN.mjs";
5
5
  //#region src/characteristic/characteristic.ts
6
6
  var characteristic_exports = /* @__PURE__ */ __exportAll({
7
7
  apply: () => apply,
@@ -101,4 +101,4 @@ const apply = (matrix, ...channels) => {
101
101
  //#endregion
102
102
  export { cubicHermite as a, cubicBezier as i, characteristic_exports as n, cubicBasisSpline as r, apply as t };
103
103
 
104
- //# sourceMappingURL=characteristic-B0VEB_OA.mjs.map
104
+ //# sourceMappingURL=characteristic-Hb7F8SBw.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"characteristic-B0VEB_OA.mjs","names":["Matrix4x4.make","CubicPolynomial.fromVector","Matrix4x4.vectorProductLeft"],"sources":["../../src/characteristic/characteristic.ts"],"sourcesContent":["import * as Matrix4x4 from '../matrix/matrix4x4.ts'\nimport * as CubicPolynomial from '../polynomial/cubic.ts'\nimport { roundDown } from '../number.ts'\nimport type * as Vector4 from '../vector/vector4.ts'\n\n/**\n * The cubic Bézier characteristic matrix.\n *\n * Maps Bernstein-basis control points `(P₀, P₁, P₂, P₃)` to monomial cubic\n * coefficients `(c₀, c₁, c₂, c₃)` for `c₀ + c₁·t + c₂·t² + c₃·t³`. The matrix\n * IS the Bézier spline family — combined with control points (via {@link apply}),\n * it produces the cubic polynomial that parameterizes the curve.\n *\n * @since 2.0.0\n */\nexport const cubicBezier: Matrix4x4.Matrix4x4 = Matrix4x4.make(\n 1,\n 0,\n 0,\n 0,\n -3,\n 3,\n 0,\n 0,\n 3,\n -6,\n 3,\n 0,\n -1,\n 3,\n -3,\n 1,\n)\n\n/**\n * The cubic Hermite characteristic matrix.\n *\n * Maps Hermite control data `(P₀, V₀, P₁, V₁)` — two endpoints and two\n * tangent vectors — to monomial cubic coefficients.\n *\n * @since 2.0.0\n */\nexport const cubicHermite: Matrix4x4.Matrix4x4 = Matrix4x4.make(\n 1,\n 0,\n 0,\n 0,\n 0,\n 1,\n 0,\n 0,\n -3,\n -2,\n 3,\n -1,\n 2,\n 1,\n -2,\n 1,\n)\n\n/**\n * The uniform cubic B-spline (basis spline) characteristic matrix.\n *\n * Maps a window of four control points to the monomial cubic coefficients\n * of one segment of the corresponding uniform cubic B-spline. Stride-1\n * application produces a C² piecewise spline; the curve does not generally\n * pass through the control points.\n *\n * @since 2.0.0\n */\nexport const cubicBasisSpline: Matrix4x4.Matrix4x4 = Matrix4x4.make(\n 1 / 6,\n 4 / 6,\n roundDown(1 / 6),\n 0,\n -0.5,\n 0,\n 0.5,\n 0,\n 0.5,\n -1,\n 0.5,\n 0,\n -1 / 6,\n 0.5,\n -0.5,\n 1 / 6,\n)\n\nconst cardinalCache = new Map<number, Matrix4x4.Matrix4x4>()\n\n/**\n * The cubic Cardinal spline characteristic matrix, parameterized by tension.\n *\n * Maps four control points to the monomial cubic coefficients of one\n * Cardinal segment. The tension `s` controls how tightly the curve hugs\n * the control points: `s = 0` produces straight-line segments between\n * adjacent points, `s = 0.5` is the Catmull-Rom variant (see\n * {@link cubicCatmullRom}), and higher values produce looser, more curved\n * shapes.\n *\n * Cached per tension value — repeated calls with the same tension return\n * the same matrix instance.\n *\n * @param tension - The tension parameter.\n * @returns The characteristic matrix for that tension.\n * @since 2.0.0\n */\nexport const cubicCardinal = (tension: number): Matrix4x4.Matrix4x4 => {\n let m = cardinalCache.get(tension)\n if (m === undefined) {\n m = Matrix4x4.make(\n 0,\n 1,\n 0,\n 0,\n -tension,\n 0,\n tension,\n 0,\n 2 * tension,\n tension - 3,\n 3 - 2 * tension,\n -tension,\n -tension,\n 2 - tension,\n tension - 2,\n tension,\n )\n cardinalCache.set(tension, m)\n }\n return m\n}\n\n/**\n * The cubic Catmull-Rom characteristic matrix — Cardinal with tension `0.5`.\n * The most common Cardinal-family variant; reused widely enough to deserve\n * a constant.\n *\n * @since 2.0.0\n */\nexport const cubicCatmullRom: Matrix4x4.Matrix4x4 = cubicCardinal(0.5)\n\n/**\n * Applies a characteristic matrix to N channels of control values, producing\n * N cubic polynomials in monomial form.\n *\n * Each channel is a `Vector4` packing one axis's values across the four\n * control points: `(v₀, v₁, v₂, v₃)`. The result tuple has the same arity\n * as the input.\n *\n * The polynomial 2D spline pipeline applies this with two channels (x, y);\n * the rational 2D pipeline uses three (x, y, w) where `w` is the projective\n * denominator. Higher channel counts generalize to 3D, rational 3D, and\n * beyond — the characteristic matrix doesn't care about the geometric\n * domain, only about how to combine four samples per channel.\n *\n * @param matrix - The characteristic matrix of the spline family.\n * @param channels - One `Vector4` per output polynomial, packing the four control values for that channel.\n * @returns A tuple of cubic polynomials, one per input channel.\n * @since 2.0.0\n */\nexport const apply = <const Channels extends ReadonlyArray<Vector4.Vector4>>(\n matrix: Matrix4x4.Matrix4x4,\n ...channels: Channels\n): { readonly [K in keyof Channels]: CubicPolynomial.CubicPolynomial } => {\n const result = channels.map((c) =>\n CubicPolynomial.fromVector(Matrix4x4.vectorProductLeft(matrix, c)),\n )\n return result as { readonly [K in keyof Channels]: CubicPolynomial.CubicPolynomial }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAeA,MAAa,cAAmCA,KAC9C,GACA,GACA,GACA,GACA,IACA,GACA,GACA,GACA,GACA,IACA,GACA,GACA,IACA,GACA,IACA,EACD;;;;;;;;;AAUD,MAAa,eAAoCA,KAC/C,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,IACA,IACA,GACA,IACA,GACA,GACA,IACA,EACD;;;;;;;;;;;AAYD,MAAa,mBAAwCA,KACnD,IAAI,GACJ,IAAI,GACJ,UAAU,IAAI,EAAE,EAChB,GACA,KACA,GACA,IACA,GACA,IACA,IACA,IACA,GACA,KAAK,GACL,IACA,KACA,IAAI,EACL;AAED,MAAM,gCAAgB,IAAI,KAAkC;;;;;;;;;;;;;;;;;;AAmB5D,MAAa,iBAAiB,YAAyC;CACrE,IAAI,IAAI,cAAc,IAAI,QAAQ;CAClC,IAAI,MAAM,KAAA,GAAW;EACnB,IAAIA,KACF,GACA,GACA,GACA,GACA,CAAC,SACD,GACA,SACA,GACA,IAAI,SACJ,UAAU,GACV,IAAI,IAAI,SACR,CAAC,SACD,CAAC,SACD,IAAI,SACJ,UAAU,GACV,QACD;EACD,cAAc,IAAI,SAAS,EAAE;;CAE/B,OAAO;;;;;;;;;AAUT,MAAa,kBAAuC,cAAc,GAAI;;;;;;;;;;;;;;;;;;;;AAqBtE,MAAa,SACX,QACA,GAAG,aACqE;CAIxE,OAHe,SAAS,KAAK,MAC3BC,WAA2BC,kBAA4B,QAAQ,EAAE,CAAC,CAEvD"}
1
+ {"version":3,"file":"characteristic-Hb7F8SBw.mjs","names":["Matrix4x4.make","CubicPolynomial.fromVector","Matrix4x4.vectorProductLeft"],"sources":["../../src/characteristic/characteristic.ts"],"sourcesContent":["import * as Matrix4x4 from '../matrix/matrix4x4.ts'\nimport * as CubicPolynomial from '../polynomial/cubic.ts'\nimport { roundDown } from '../number.ts'\nimport type * as Vector4 from '../vector/vector4.ts'\n\n/**\n * The cubic Bézier characteristic matrix.\n *\n * Maps Bernstein-basis control points `(P₀, P₁, P₂, P₃)` to monomial cubic\n * coefficients `(c₀, c₁, c₂, c₃)` for `c₀ + c₁·t + c₂·t² + c₃·t³`. The matrix\n * IS the Bézier spline family — combined with control points (via {@link apply}),\n * it produces the cubic polynomial that parameterizes the curve.\n *\n * @since 2.0.0\n */\nexport const cubicBezier: Matrix4x4.Matrix4x4 = Matrix4x4.make(\n 1,\n 0,\n 0,\n 0,\n -3,\n 3,\n 0,\n 0,\n 3,\n -6,\n 3,\n 0,\n -1,\n 3,\n -3,\n 1,\n)\n\n/**\n * The cubic Hermite characteristic matrix.\n *\n * Maps Hermite control data `(P₀, V₀, P₁, V₁)` — two endpoints and two\n * tangent vectors — to monomial cubic coefficients.\n *\n * @since 2.0.0\n */\nexport const cubicHermite: Matrix4x4.Matrix4x4 = Matrix4x4.make(\n 1,\n 0,\n 0,\n 0,\n 0,\n 1,\n 0,\n 0,\n -3,\n -2,\n 3,\n -1,\n 2,\n 1,\n -2,\n 1,\n)\n\n/**\n * The uniform cubic B-spline (basis spline) characteristic matrix.\n *\n * Maps a window of four control points to the monomial cubic coefficients\n * of one segment of the corresponding uniform cubic B-spline. Stride-1\n * application produces a C² piecewise spline; the curve does not generally\n * pass through the control points.\n *\n * @since 2.0.0\n */\nexport const cubicBasisSpline: Matrix4x4.Matrix4x4 = Matrix4x4.make(\n 1 / 6,\n 4 / 6,\n roundDown(1 / 6),\n 0,\n -0.5,\n 0,\n 0.5,\n 0,\n 0.5,\n -1,\n 0.5,\n 0,\n -1 / 6,\n 0.5,\n -0.5,\n 1 / 6,\n)\n\nconst cardinalCache = new Map<number, Matrix4x4.Matrix4x4>()\n\n/**\n * The cubic Cardinal spline characteristic matrix, parameterized by tension.\n *\n * Maps four control points to the monomial cubic coefficients of one\n * Cardinal segment. The tension `s` controls how tightly the curve hugs\n * the control points: `s = 0` produces straight-line segments between\n * adjacent points, `s = 0.5` is the Catmull-Rom variant (see\n * {@link cubicCatmullRom}), and higher values produce looser, more curved\n * shapes.\n *\n * Cached per tension value — repeated calls with the same tension return\n * the same matrix instance.\n *\n * @param tension - The tension parameter.\n * @returns The characteristic matrix for that tension.\n * @since 2.0.0\n */\nexport const cubicCardinal = (tension: number): Matrix4x4.Matrix4x4 => {\n let m = cardinalCache.get(tension)\n if (m === undefined) {\n m = Matrix4x4.make(\n 0,\n 1,\n 0,\n 0,\n -tension,\n 0,\n tension,\n 0,\n 2 * tension,\n tension - 3,\n 3 - 2 * tension,\n -tension,\n -tension,\n 2 - tension,\n tension - 2,\n tension,\n )\n cardinalCache.set(tension, m)\n }\n return m\n}\n\n/**\n * The cubic Catmull-Rom characteristic matrix — Cardinal with tension `0.5`.\n * The most common Cardinal-family variant; reused widely enough to deserve\n * a constant.\n *\n * @since 2.0.0\n */\nexport const cubicCatmullRom: Matrix4x4.Matrix4x4 = cubicCardinal(0.5)\n\n/**\n * Applies a characteristic matrix to N channels of control values, producing\n * N cubic polynomials in monomial form.\n *\n * Each channel is a `Vector4` packing one axis's values across the four\n * control points: `(v₀, v₁, v₂, v₃)`. The result tuple has the same arity\n * as the input.\n *\n * The polynomial 2D spline pipeline applies this with two channels (x, y);\n * the rational 2D pipeline uses three (x, y, w) where `w` is the projective\n * denominator. Higher channel counts generalize to 3D, rational 3D, and\n * beyond — the characteristic matrix doesn't care about the geometric\n * domain, only about how to combine four samples per channel.\n *\n * @param matrix - The characteristic matrix of the spline family.\n * @param channels - One `Vector4` per output polynomial, packing the four control values for that channel.\n * @returns A tuple of cubic polynomials, one per input channel.\n * @since 2.0.0\n */\nexport const apply = <const Channels extends ReadonlyArray<Vector4.Vector4>>(\n matrix: Matrix4x4.Matrix4x4,\n ...channels: Channels\n): { readonly [K in keyof Channels]: CubicPolynomial.CubicPolynomial } => {\n const result = channels.map((c) =>\n CubicPolynomial.fromVector(Matrix4x4.vectorProductLeft(matrix, c)),\n )\n return result as { readonly [K in keyof Channels]: CubicPolynomial.CubicPolynomial }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAeA,MAAa,cAAmCA,KAC9C,GACA,GACA,GACA,GACA,IACA,GACA,GACA,GACA,GACA,IACA,GACA,GACA,IACA,GACA,IACA,EACD;;;;;;;;;AAUD,MAAa,eAAoCA,KAC/C,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,IACA,IACA,GACA,IACA,GACA,GACA,IACA,EACD;;;;;;;;;;;AAYD,MAAa,mBAAwCA,KACnD,IAAI,GACJ,IAAI,GACJ,UAAU,IAAI,EAAE,EAChB,GACA,KACA,GACA,IACA,GACA,IACA,IACA,IACA,GACA,KAAK,GACL,IACA,KACA,IAAI,EACL;AAED,MAAM,gCAAgB,IAAI,KAAkC;;;;;;;;;;;;;;;;;;AAmB5D,MAAa,iBAAiB,YAAyC;CACrE,IAAI,IAAI,cAAc,IAAI,QAAQ;CAClC,IAAI,MAAM,KAAA,GAAW;EACnB,IAAIA,KACF,GACA,GACA,GACA,GACA,CAAC,SACD,GACA,SACA,GACA,IAAI,SACJ,UAAU,GACV,IAAI,IAAI,SACR,CAAC,SACD,CAAC,SACD,IAAI,SACJ,UAAU,GACV,QACD;EACD,cAAc,IAAI,SAAS,EAAE;;CAE/B,OAAO;;;;;;;;;AAUT,MAAa,kBAAuC,cAAc,GAAI;;;;;;;;;;;;;;;;;;;;AAqBtE,MAAa,SACX,QACA,GAAG,aACqE;CAIxE,OAHe,SAAS,KAAK,MAC3BC,WAA2BC,kBAA4B,QAAQ,EAAE,CAAC,CAEvD"}
@@ -2,8 +2,8 @@ import { t as __exportAll } from "./chunk-25Hzd3z8.mjs";
2
2
  import { Pipeable, dual, invariant } from "../utils.mjs";
3
3
  import { clampToZero, epsEquals } from "../number.mjs";
4
4
  import { a as make$4 } from "./vector2-CSkaMXvp.mjs";
5
- import { a as filter, c as make$5, d as toOpen, l as scaleShift, n as contains, o as fromMinMax, t as biunit, u as size } from "./interval-CqC3ZIqj.mjs";
6
- import { a as match, l as two, n as fromArray, o as none, r as isNone, s as one } from "./solution-UKGK826h.mjs";
5
+ import { a as filter, c as make$5, d as toOpen, l as scaleShift, n as contains, o as fromMinMax, p as unit, t as biunit, u as size } from "./interval-Dm35Xhy4.mjs";
6
+ import { a as match, l as two, n as fromArray, o as none, r as isNone, s as one } from "./solution-B6KY1E7M.mjs";
7
7
  //#region src/polynomial/quadratic.internal.circular.ts
8
8
  const QuadraticPolynomialTypeId = Symbol.for("curvy/polynomial/quadratic");
9
9
  /** @internal */
@@ -98,6 +98,8 @@ const domain$3 = dual(2, (p, r) => {
98
98
  /** @internal */
99
99
  const range$3 = dual(2, (p, d) => fromMinMax(solve$3(p, d.start), solve$3(p, d.end)));
100
100
  /** @internal */
101
+ const unitRange$3 = (p) => fromMinMax(p.c0, p.c0 + p.c1);
102
+ /** @internal */
101
103
  const length$3 = dual(2, (p, d) => {
102
104
  if (size(d) === 0) return 0;
103
105
  if (p.c1 === 0) return size(d);
@@ -225,6 +227,8 @@ const range$2 = dual(2, (p, d) => {
225
227
  return e !== null && contains(d, e.x) ? fromMinMax(solve$2(p, d.start), solve$2(p, d.end), e.y) : fromMinMax(solve$2(p, d.start), solve$2(p, d.end));
226
228
  });
227
229
  /** @internal */
230
+ const unitRange$2 = (p) => range$2(p, unit);
231
+ /** @internal */
228
232
  const length$2 = dual(2, (p, dom) => {
229
233
  if (size(dom) === 0) return 0;
230
234
  if (p.c2 === 0) return length$3(make$3(p.c0, p.c1), dom);
@@ -384,6 +388,8 @@ const domain$1 = dual(2, (p, r) => fromMinMax(...solveInverse$1(p, r.start), ...
384
388
  /** @internal */
385
389
  const range$1 = dual(2, (p, d) => fromMinMax(solve$1(p, d.start), solve$1(p, d.end), ...filter(d, [...extrema$1(p)]).map((e) => solve$1(p, e))));
386
390
  /** @internal */
391
+ const unitRange$1 = (p) => range$1(p, unit);
392
+ /** @internal */
387
393
  const length$1 = dual(2, (p, dom) => {
388
394
  if (size(dom) === 0) return 0;
389
395
  if (p.c3 === 0) {
@@ -427,7 +433,8 @@ var cubic_exports = /* @__PURE__ */ __exportAll({
427
433
  solveInverse: () => solveInverse,
428
434
  subdivide: () => subdivide,
429
435
  toInverseSolver: () => toInverseSolver,
430
- toSolver: () => toSolver
436
+ toSolver: () => toSolver,
437
+ unitRange: () => unitRange
431
438
  });
432
439
  /**
433
440
  * Checks if a value is a `CubicPolynomial`.
@@ -567,9 +574,19 @@ const asIncreasing = asIncreasing$1;
567
574
  const asDecreasing = asDecreasing$1;
568
575
  const domain = domain$1;
569
576
  const range = range$1;
577
+ /**
578
+ * Calculates the range of a cubic polynomial over the unit interval `[0, 1]`.
579
+ * Equivalent to `range(p, Interval.unit)` — accounts for up to two interior
580
+ * extrema in `[0, 1]`.
581
+ *
582
+ * @param p - The cubic polynomial.
583
+ * @returns The closed range of the polynomial over `[0, 1]`.
584
+ * @since 2.0.0
585
+ */
586
+ const unitRange = unitRange$1;
570
587
  const length = length$1;
571
588
  const curvature = curvature$1;
572
589
  //#endregion
573
- export { equals$2 as $, GL32_X1 as A, isMonotonic$3 as At, GL32_X5 as B, GL32_W4 as C, equals$3 as Ct, GL32_W8 as D, isDecreasing$3 as Dt, GL32_W7 as E, fromVector$3 as Et, GL32_X14 as F, solve$3 as Ft, antiderivative as G, GL32_X7 as H, GL32_X15 as I, solveInverse$3 as It, asMonotonic$2 as J, asDecreasing$2 as K, GL32_X2 as L, toInverseSolver$3 as Lt, GL32_X11 as M, make$3 as Mt, GL32_X12 as N, monotonicity$3 as Nt, GL32_W9 as O, isIncreasing$3 as Ot, GL32_X13 as P, range$3 as Pt, domain$2 as Q, GL32_X3 as R, toSolver$3 as Rt, GL32_W3 as S, domain$3 as St, GL32_W6 as T, fromPoints$3 as Tt, GL32_X8 as U, GL32_X6 as V, GL32_X9 as W, curvature$2 as X, coefficients$2 as Y, derivative$2 as Z, GL32_W12 as _, asDecreasing$3 as _t, isIncreasing as a, isMonotonic$2 as at, GL32_W15 as b, coefficients$3 as bt, range as c, make$2 as ct, solveInverse as d, roots$2 as dt, extreme as et, subdivide as f, solve$2 as ft, GL32_W11 as g, antiderivative$1 as gt, GL32_W10 as h, toSolver$2 as ht, isDecreasing as i, isIncreasing$2 as it, GL32_X10 as j, length$3 as jt, GL32_X0 as k, isLinearPolynomial as kt, roots as l, monotonicity$2 as lt, GL32_W1 as m, toInverseSolver$2 as mt, derivative as n, fromVector$2 as nt, isMonotonic as o, isQuadraticPolynomial as ot, GL32_W0 as p, solveInverse$2 as pt, asIncreasing$2 as q, fromVector as r, isDecreasing$2 as rt, make as s, length$2 as st, cubic_exports as t, fromPoints$2 as tt, solve as u, range$2 as ut, GL32_W13 as v, asIncreasing$3 as vt, GL32_W5 as w, fromPointSlope as wt, GL32_W2 as x, derivative$3 as xt, GL32_W14 as y, asMonotonic$3 as yt, GL32_X4 as z };
590
+ export { equals$2 as $, GL32_X1 as A, isLinearPolynomial as At, GL32_X5 as B, unitRange$3 as Bt, GL32_W4 as C, domain$3 as Ct, GL32_W8 as D, fromVector$3 as Dt, GL32_W7 as E, fromPoints$3 as Et, GL32_X14 as F, range$3 as Ft, antiderivative as G, GL32_X7 as H, GL32_X15 as I, solve$3 as It, asMonotonic$2 as J, asDecreasing$2 as K, GL32_X2 as L, solveInverse$3 as Lt, GL32_X11 as M, length$3 as Mt, GL32_X12 as N, make$3 as Nt, GL32_W9 as O, isDecreasing$3 as Ot, GL32_X13 as P, monotonicity$3 as Pt, domain$2 as Q, GL32_X3 as R, toInverseSolver$3 as Rt, GL32_W3 as S, derivative$3 as St, GL32_W6 as T, fromPointSlope as Tt, GL32_X8 as U, GL32_X6 as V, GL32_X9 as W, curvature$2 as X, coefficients$2 as Y, derivative$2 as Z, GL32_W12 as _, antiderivative$1 as _t, isIncreasing as a, isMonotonic$2 as at, GL32_W15 as b, asMonotonic$3 as bt, roots as c, make$2 as ct, subdivide as d, roots$2 as dt, extreme as et, unitRange as f, solve$2 as ft, GL32_W11 as g, unitRange$2 as gt, GL32_W10 as h, toSolver$2 as ht, isDecreasing as i, isIncreasing$2 as it, GL32_X10 as j, isMonotonic$3 as jt, GL32_X0 as k, isIncreasing$3 as kt, solve as l, monotonicity$2 as lt, GL32_W1 as m, toInverseSolver$2 as mt, derivative as n, fromVector$2 as nt, isMonotonic as o, isQuadraticPolynomial as ot, GL32_W0 as p, solveInverse$2 as pt, asIncreasing$2 as q, fromVector as r, isDecreasing$2 as rt, make as s, length$2 as st, cubic_exports as t, fromPoints$2 as tt, solveInverse as u, range$2 as ut, GL32_W13 as v, asDecreasing$3 as vt, GL32_W5 as w, equals$3 as wt, GL32_W2 as x, coefficients$3 as xt, GL32_W14 as y, asIncreasing$3 as yt, GL32_X4 as z, toSolver$3 as zt };
574
591
 
575
- //# sourceMappingURL=cubic-NEn7E6V_.mjs.map
592
+ //# sourceMappingURL=cubic-DHJrzZJN.mjs.map