curvy 2.0.0-alpha.12 → 2.0.0-alpha.13

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 (37) hide show
  1. package/dist/characteristic/index.mjs +1 -1
  2. package/dist/curve/index.mjs +1 -1
  3. package/dist/curve/rationalCubic2d.d.ts +195 -11
  4. package/dist/interval/index.mjs +1 -1
  5. package/dist/monotonicity/index.d.ts +4 -0
  6. package/dist/monotonicity/index.mjs +2 -0
  7. package/dist/monotonicity/monotonicity.d.ts +80 -0
  8. package/dist/path/index.mjs +5 -5
  9. package/dist/path/rationalCubic2d.d.ts +27 -0
  10. package/dist/polynomial/cubic.d.ts +2 -2
  11. package/dist/polynomial/index.mjs +2 -2
  12. package/dist/polynomial/linear.d.ts +7 -7
  13. package/dist/polynomial/quadratic.d.ts +2 -2
  14. package/dist/shared/{characteristic-Hb7F8SBw.mjs → characteristic-BkEr-rr8.mjs} +2 -2
  15. package/dist/shared/{characteristic-Hb7F8SBw.mjs.map → characteristic-BkEr-rr8.mjs.map} +1 -1
  16. package/dist/shared/{cubic-DHJrzZJN.mjs → cubic-BL6dpuHh.mjs} +18 -30
  17. package/dist/shared/cubic-BL6dpuHh.mjs.map +1 -0
  18. package/dist/shared/{interval2d-DPmvk_Qe.mjs → interval2d-AtneyI45.mjs} +1 -1
  19. package/dist/shared/{interval2d-DPmvk_Qe.mjs.map → interval2d-AtneyI45.mjs.map} +1 -1
  20. package/dist/shared/monotonicity-BdebFOtv.mjs +34 -0
  21. package/dist/shared/monotonicity-BdebFOtv.mjs.map +1 -0
  22. package/dist/shared/{quadratic-BZmfZE71.mjs → quadratic-DPrUsFCp.mjs} +9 -9
  23. package/dist/shared/quadratic-DPrUsFCp.mjs.map +1 -0
  24. package/dist/shared/{rationalCubic2d-D5g3_hTV.mjs → rationalCubic2d-CeHgpNht.mjs} +373 -79
  25. package/dist/shared/rationalCubic2d-CeHgpNht.mjs.map +1 -0
  26. package/dist/shared/{rationalCubic2d-MojACId0.mjs → rationalCubic2d-H1J2Fjyy.mjs} +25 -16
  27. package/dist/shared/rationalCubic2d-H1J2Fjyy.mjs.map +1 -0
  28. package/dist/shared/{solution-B6KY1E7M.mjs → solution-B2JdOZpe.mjs} +1 -1
  29. package/dist/shared/{solution-B6KY1E7M.mjs.map → solution-B2JdOZpe.mjs.map} +1 -1
  30. package/dist/solution/index.mjs +1 -1
  31. package/dist/splines/index.mjs +4 -4
  32. package/package.json +5 -1
  33. package/dist/polynomial/monotonicity.d.ts +0 -3
  34. package/dist/shared/cubic-DHJrzZJN.mjs.map +0 -1
  35. package/dist/shared/quadratic-BZmfZE71.mjs.map +0 -1
  36. package/dist/shared/rationalCubic2d-D5g3_hTV.mjs.map +0 -1
  37. package/dist/shared/rationalCubic2d-MojACId0.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rationalCubic2d-H1J2Fjyy.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","isCubicPath2d","make","fromArray","append","length","CubicCurve2d.length","Interval.unit","solve","CubicCurve2d.solve","derivative","cubicCurveInternal.derivative","Interval.make","Vector2.magnitude","QuadraticCurve2d.solve","toPathData","isContinuous","asContinuous","isIncreasingX","CubicPolynomial.isIncreasing","isDecreasingX","CubicPolynomial.isDecreasing","isMonotonicX","isIncreasingY","isDecreasingY","isMonotonicY","asIncreasingX","asDecreasingX","asMonotonicX","asIncreasingY","asDecreasingY","asMonotonicY","solveAtX","Solution.one","CubicCurve2d.solveAtX","Solution.isNone","Solution.none","solveAtY","CubicCurve2d.solveAtY","solveByDistance","boundingBox","CubicCurve2d.boundingBox","Interval2d.union","make","internal.make","fromArray","internal.fromArray","internal.isCubicPath2d","append","internal.append","internal.length","solve","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.solveByDistance","boundingBox","internal.boundingBox","isRationalCubicPath2d","make","fromArray","append","solve","RationalCubicCurve2d.solve","boundingBox","RationalCubicCurve2d.boundingBox","Interval2d.union","approximateAsCubicPath","RationalCubicCurve2d.approximateAsCubicCurves","CubicPath2d.fromArray","internal.isRationalCubicPath2d","internal.make","internal.fromArray","internal.append","internal.solve","internal.boundingBox","internal.approximateAsCubicPath"],"sources":["../../src/path/linear2d.internal.ts","../../src/path/linear2d.ts","../../src/path/cubic2d.internal.ts","../../src/path/cubic2d.ts","../../src/path/rationalCubic2d.internal.ts","../../src/path/rationalCubic2d.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 CubicCurve2d from '../curve/cubic2d.ts'\nimport * as cubicCurveInternal from '../curve/cubic2d.internal.ts'\nimport * as QuadraticCurve2d from '../curve/quadratic2d.ts'\nimport * as Interval from '../interval/interval.ts'\nimport * as CubicPolynomial from '../polynomial/cubic.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 * as Vector2 from '../vector/vector2.ts'\nimport type { CubicPath2d } from './cubic2d.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 CubicPath2dTypeId: unique symbol = Symbol('curvy/path/cubic2d')\nexport type CubicPath2dTypeId = typeof CubicPath2dTypeId\n\n/** @internal */\nexport class CubicPath2dImpl extends Pipeable implements CubicPath2d<unknown> {\n readonly [CubicPath2dTypeId]: CubicPath2dTypeId = CubicPath2dTypeId\n declare readonly [PathTraits]: unknown\n\n readonly curves: ReadonlyArray<CubicCurve2d.CubicCurve2d>\n\n constructor(curves: ReadonlyArray<CubicCurve2d.CubicCurve2d>) {\n invariant(curves.length > 0, 'cubic path requires at least one curve')\n super()\n this.curves = curves\n }\n\n [Symbol.iterator](): Iterator<CubicCurve2d.CubicCurve2d> {\n return this.curves[Symbol.iterator]()\n }\n}\n\n/** @internal */\nexport const isCubicPath2d = (p: unknown): p is CubicPath2d =>\n typeof p === 'object' && p !== null && CubicPath2dTypeId in p\n\n/** @internal */\nexport const make = (...curves: ReadonlyArray<CubicCurve2d.CubicCurve2d>): CubicPath2d =>\n new CubicPath2dImpl(curves)\n\n/** @internal */\nexport const fromArray = (curves: ReadonlyArray<CubicCurve2d.CubicCurve2d>): CubicPath2d =>\n new CubicPath2dImpl(curves)\n\n/** @internal */\nexport const append = dual<\n (c: CubicCurve2d.CubicCurve2d) => (p: CubicPath2d) => CubicPath2d,\n (p: CubicPath2d, c: CubicCurve2d.CubicCurve2d) => CubicPath2d\n>(2, (p: CubicPath2d, c: CubicCurve2d.CubicCurve2d) => fromArray([...p, c]))\n\n/** @internal */\nexport const length = (p: CubicPath2d) => {\n let total = 0\n for (const curve of p) {\n total += CubicCurve2d.length(curve, Interval.unit)\n }\n\n return total\n}\n\n/** @internal */\nexport const solve = dual<\n (u: number) => (p: CubicPath2d) => Vector2.Vector2,\n (p: CubicPath2d, u: number) => Vector2.Vector2\n>(2, (p: CubicPath2d, u: number) => {\n const curves = p instanceof CubicPath2dImpl ? p.curves : [...p]\n\n if (u === 1) {\n const last = curves.at(-1) as CubicCurve2d.CubicCurve2d\n return CubicCurve2d.solve(last, 1)\n }\n\n const t = u * curves.length\n const i = Math.floor(t)\n const curve = curves[i] as CubicCurve2d.CubicCurve2d\n return CubicCurve2d.solve(curve, t - i)\n})\n\n// Cumulative segment lengths cache. lengths[k] = total length through segment k.\n// Cached by path identity since paths are immutable.\nconst cumulativeLengthCache = new WeakMap<CubicPath2d, ReadonlyArray<number>>()\n\nconst getCumulativeLengths = (p: CubicPath2d): ReadonlyArray<number> => {\n let cached = cumulativeLengthCache.get(p)\n if (cached === undefined) {\n const lengths: Array<number> = []\n let total = 0\n for (const curve of p) {\n total += CubicCurve2d.length(curve, Interval.unit)\n lengths.push(total)\n }\n cached = lengths\n cumulativeLengthCache.set(p, cached)\n }\n return cached\n}\n\n// Newton's method to find the local parameter t ∈ [0, 1] within `curve` such\n// that the arc length from 0 to t equals `target`. Each iteration costs one\n// GL32 quadrature plus one velocity eval; converges in 3–5 iterations for\n// well-behaved curves. Falls back to bisection on cusps where speed → 0.\nconst solveCurveByDistance = (\n curve: CubicCurve2d.CubicCurve2d,\n target: number,\n segmentLength: number,\n): number => {\n if (target <= 0) {\n return 0\n }\n if (target >= segmentLength) {\n return 1\n }\n\n const derivative = cubicCurveInternal.derivative(curve)\n\n let t = target / segmentLength\n let lo = 0\n let hi = 1\n\n for (let iter = 0; iter < 16; iter++) {\n const currentLength = CubicCurve2d.length(curve, Interval.make(0, t))\n const error = currentLength - target\n\n if (Math.abs(error) < 1e-10) {\n return t\n }\n\n if (error > 0) {\n hi = t\n } else {\n lo = t\n }\n\n const speed = Vector2.magnitude(QuadraticCurve2d.solve(derivative, t))\n if (speed === 0) {\n // cusp — bisect instead\n t = (lo + hi) / 2\n continue\n }\n\n const next = t - error / speed\n // bracket-clamp Newton step; if it leaves the bracket, fall back to bisection\n t = next > lo && next < hi ? next : (lo + hi) / 2\n }\n\n return t\n}\n\n// Cubic Bernstein basis: P(t) = (1-t)³·p0 + 3(1-t)²t·p1 + 3(1-t)t²·p2 + t³·p3\n// expanded gives c0 = p0, c1 = -3p0 + 3p1, c2 = 3p0 - 6p1 + 3p2, c3 = -p0 + 3p1 - 3p2 + p3,\n// so: p0 = c0, p1 = c0 + c1/3, p2 = c0 + 2c1/3 + c2/3, p3 = c0 + c1 + c2 + c3.\n/** @internal */\nexport const toPathData = (p: CubicPath2d): 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 const c3x = curve.x.c3\n const c3y = curve.y.c3\n\n const startX = c0x\n const startY = c0y\n const ctrl1X = c0x + c1x / 3\n const ctrl1Y = c0y + c1y / 3\n const ctrl2X = c0x + (2 * c1x) / 3 + c2x / 3\n const ctrl2Y = c0y + (2 * c1y) / 3 + c2y / 3\n const endX = c0x + c1x + c2x + c3x\n const endY = c0y + c1y + c2y + c3y\n\n if (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY)) {\n result += ` M ${startX},${startY}`\n }\n result += ` C ${ctrl1X},${ctrl1Y} ${ctrl2X},${ctrl2Y} ${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: CubicPath2d<T>): p is CubicPath2d<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 + curve.x.c3\n prevEndY = curve.y.c0 + curve.y.c1 + curve.y.c2 + curve.y.c3\n first = false\n }\n return true\n}\n\n/** @internal */\nexport const asContinuous = <T>(p: CubicPath2d<T>): CubicPath2d<T & Continuous> => {\n invariant(isContinuous(p), 'cubic 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: CubicPath2d<T>): p is CubicPath2d<T & IncreasingX> => {\n let prevEnd = Number.NEGATIVE_INFINITY\n for (const c of p) {\n if (!CubicPolynomial.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 + c.x.c3\n }\n return true\n}\n\n/** @internal */\nexport const isDecreasingX = <T>(p: CubicPath2d<T>): p is CubicPath2d<T & DecreasingX> => {\n let prevEnd = Number.POSITIVE_INFINITY\n for (const c of p) {\n if (!CubicPolynomial.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 + c.x.c3\n }\n return true\n}\n\n/** @internal */\nexport const isMonotonicX = <T>(p: CubicPath2d<T>): p is CubicPath2d<T & MonotonicX> =>\n isIncreasingX(p) || isDecreasingX(p)\n\n/** @internal */\nexport const isIncreasingY = <T>(p: CubicPath2d<T>): p is CubicPath2d<T & IncreasingY> => {\n let prevEnd = Number.NEGATIVE_INFINITY\n for (const c of p) {\n if (!CubicPolynomial.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 + c.y.c3\n }\n return true\n}\n\n/** @internal */\nexport const isDecreasingY = <T>(p: CubicPath2d<T>): p is CubicPath2d<T & DecreasingY> => {\n let prevEnd = Number.POSITIVE_INFINITY\n for (const c of p) {\n if (!CubicPolynomial.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 + c.y.c3\n }\n return true\n}\n\n/** @internal */\nexport const isMonotonicY = <T>(p: CubicPath2d<T>): p is CubicPath2d<T & MonotonicY> =>\n isIncreasingY(p) || isDecreasingY(p)\n\n/** @internal */\nexport const asIncreasingX = <T>(p: CubicPath2d<T>): CubicPath2d<T & IncreasingX> => {\n invariant(isIncreasingX(p), 'cubic path is not increasing in x')\n return p\n}\n\n/** @internal */\nexport const asDecreasingX = <T>(p: CubicPath2d<T>): CubicPath2d<T & DecreasingX> => {\n invariant(isDecreasingX(p), 'cubic path is not decreasing in x')\n return p\n}\n\n/** @internal */\nexport const asMonotonicX = <T>(p: CubicPath2d<T>): CubicPath2d<T & MonotonicX> => {\n invariant(isMonotonicX(p), 'cubic path is not monotonic in x')\n return p\n}\n\n/** @internal */\nexport const asIncreasingY = <T>(p: CubicPath2d<T>): CubicPath2d<T & IncreasingY> => {\n invariant(isIncreasingY(p), 'cubic path is not increasing in y')\n return p\n}\n\n/** @internal */\nexport const asDecreasingY = <T>(p: CubicPath2d<T>): CubicPath2d<T & DecreasingY> => {\n invariant(isDecreasingY(p), 'cubic path is not decreasing in y')\n return p\n}\n\n/** @internal */\nexport const asMonotonicY = <T>(p: CubicPath2d<T>): CubicPath2d<T & MonotonicY> => {\n invariant(isMonotonicY(p), 'cubic path is not monotonic in y')\n return p\n}\n\n// At an interior knot, two adjacent segments both bracket the query — one's\n// right endpoint and the next's left endpoint are (within float drift) the\n// same value. The per-curve cubic-root solver can return `none` for both\n// brackets when the true root sits just outside [0, 1] due to that drift. We\n// handle this two ways:\n// 1. If the query is within EPSILON of a segment's start or end, evaluate y\n// directly at t=0 or t=1 — skips polynomial inversion entirely.\n// 2. Otherwise, if a bracketing segment returns `none`, fall through to the\n// next bracketing segment. `MonotonicX` admits at most one real solution\n// across the path, so retrying after `none` is safe.\n/** @internal */\nexport const solveAtX = dual(2, (p: CubicPath2d, 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 + c.x.c3\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 + c.y.c3)\n }\n const sol = CubicCurve2d.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: CubicPath2d, 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 + c.y.c3\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 + c.x.c3)\n }\n const sol = CubicCurve2d.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 solveByDistance = dual<\n (s: number) => (p: CubicPath2d) => Vector2.Vector2,\n (p: CubicPath2d, s: number) => Vector2.Vector2\n>(2, (p: CubicPath2d, s: number) => {\n if (s <= 0) {\n return solve(p, 0)\n }\n if (s >= 1) {\n return solve(p, 1)\n }\n\n const lengths = getCumulativeLengths(p)\n const total = lengths[lengths.length - 1] as number\n const target = s * total\n\n // find segment k such that lengths[k-1] ≤ target ≤ lengths[k]\n let k = 0\n while (k < lengths.length - 1 && (lengths[k] as number) < target) {\n k++\n }\n\n const segmentStart = k === 0 ? 0 : (lengths[k - 1] as number)\n const segmentEnd = lengths[k] as number\n const segmentLength = segmentEnd - segmentStart\n const segmentTarget = target - segmentStart\n\n const curves = p instanceof CubicPath2dImpl ? p.curves : [...p]\n const curve = curves[k] as CubicCurve2d.CubicCurve2d\n const localT = solveCurveByDistance(curve, segmentTarget, segmentLength)\n\n return CubicCurve2d.solve(curve, localT)\n})\n\n/** @internal */\nexport const boundingBox = (\n p: CubicPath2d,\n): Interval2d.Interval2d<Interval.Closed, Interval.Closed> => {\n const iter = p[Symbol.iterator]()\n const first = iter.next()\n let acc = CubicCurve2d.boundingBox(first.value as CubicCurve2d.CubicCurve2d)\n for (let next = iter.next(); !next.done; next = iter.next()) {\n acc = Interval2d.union(acc, CubicCurve2d.boundingBox(next.value))\n }\n return acc\n}\n","import type { Interval2d } from '../interval/interval2d.ts'\nimport type { CubicCurve2d } from '../curve/cubic2d.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 { CubicPath2dTypeId } from './cubic2d.internal.ts'\nimport * as internal from './cubic2d.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 cubic 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 CubicPath2d<out Trait = unknown> extends Pipeable, Iterable<CubicCurve2d> {\n readonly [CubicPath2dTypeId]: CubicPath2dTypeId\n readonly [PathTraits]: Trait\n}\n\n/**\n * Creates a new `CubicPath2d` instance from a sequence of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `CubicPath2d` instance.\n * @since 2.0.0\n */\nexport const make: (...curves: ReadonlyArray<CubicCurve2d>) => CubicPath2d = internal.make\n\n/**\n * Creates a new `CubicPath2d` instance from an array of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `CubicPath2d` instance.\n * @since 2.0.0\n */\nexport const fromArray: (curves: ReadonlyArray<CubicCurve2d>) => CubicPath2d = internal.fromArray\n\n/**\n * Checks if a value is a `CubicPath2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `CubicPath2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isCubicPath2d: (p: unknown) => p is CubicPath2d = internal.isCubicPath2d\n\nexport const append: {\n /**\n * Appends a cubic curve to a cubic path.\n *\n * @param c - The cubic curve to append.\n * @returns A function that takes a cubic path and returns a new cubic path.\n * @since 1.0.0\n */\n (c: CubicCurve2d): (p: CubicPath2d) => CubicPath2d\n /**\n * Appends a cubic curve to a cubic path.\n *\n * @param p - The cubic path to append to.\n * @param c - The cubic curve to append.\n * @returns A new cubic path.\n * @since 1.0.0\n */\n (p: CubicPath2d, c: CubicCurve2d): CubicPath2d\n} = internal.append\n\n/**\n * Calculates the length of a cubic path.\n *\n * @param p - The cubic path to calculate the length of.\n * @returns The length of the cubic path.\n * @since 1.0.0\n */\nexport const length: (p: CubicPath2d) => number = internal.length\n\nexport const solve: {\n /**\n * Solves a cubic path for a given parameter.\n *\n * @param u - The parameter to solve for.\n * @returns A function that takes a cubic path and returns the solved vector.\n * @since 1.0.0\n */\n (u: number): (p: CubicPath2d) => Vector2\n /**\n * Solves a cubic path for a given parameter.\n *\n * @param p - The cubic path to solve.\n * @param u - The parameter to solve for.\n * @returns The solved vector.\n * @since 1.0.0\n */\n (p: CubicPath2d, u: number): Vector2\n} = internal.solve\n\n/**\n * Serializes a cubic path as an SVG path data string (the value of a `<path>`\n * element's `d` attribute), using `M` and `C` commands. Discontinuities between\n * curves emit a fresh `M` command.\n *\n * @param p - The cubic path to serialize.\n * @returns The SVG path data string.\n * @since 2.0.0\n */\nexport const toPathData: (p: CubicPath2d) => string = internal.toPathData\n\n/**\n * Type-narrowing predicate: refines `CubicPath2d<T>` to\n * `CubicPath2d<T & Continuous>` when adjacent curves connect.\n *\n * @since 2.0.0\n */\nexport const isContinuous: <T>(p: CubicPath2d<T>) => p is CubicPath2d<T & Continuous> =\n internal.isContinuous\n\n/**\n * Asserts that the cubic path is continuous, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asContinuous: <T>(p: CubicPath2d<T>) => CubicPath2d<T & Continuous> =\n internal.asContinuous\n\n/**\n * Type-narrowing predicate: refines `CubicPath2d<T>` to\n * `CubicPath2d<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: CubicPath2d<T>) => p is CubicPath2d<T & IncreasingX> =\n internal.isIncreasingX\n\n/**\n * Type-narrowing predicate: refines `CubicPath2d<T>` to\n * `CubicPath2d<T & DecreasingX>`.\n *\n * @since 2.0.0\n */\nexport const isDecreasingX: <T>(p: CubicPath2d<T>) => p is CubicPath2d<T & DecreasingX> =\n internal.isDecreasingX\n\n/**\n * Type-narrowing predicate: refines `CubicPath2d<T>` to\n * `CubicPath2d<T & MonotonicX>`.\n *\n * @since 2.0.0\n */\nexport const isMonotonicX: <T>(p: CubicPath2d<T>) => p is CubicPath2d<T & MonotonicX> =\n internal.isMonotonicX\n\n/**\n * Type-narrowing predicate: refines `CubicPath2d<T>` to\n * `CubicPath2d<T & IncreasingY>`.\n *\n * @since 2.0.0\n */\nexport const isIncreasingY: <T>(p: CubicPath2d<T>) => p is CubicPath2d<T & IncreasingY> =\n internal.isIncreasingY\n\n/**\n * Type-narrowing predicate: refines `CubicPath2d<T>` to\n * `CubicPath2d<T & DecreasingY>`.\n *\n * @since 2.0.0\n */\nexport const isDecreasingY: <T>(p: CubicPath2d<T>) => p is CubicPath2d<T & DecreasingY> =\n internal.isDecreasingY\n\n/**\n * Type-narrowing predicate: refines `CubicPath2d<T>` to\n * `CubicPath2d<T & MonotonicY>`.\n *\n * @since 2.0.0\n */\nexport const isMonotonicY: <T>(p: CubicPath2d<T>) => p is CubicPath2d<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: CubicPath2d<T>) => CubicPath2d<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: CubicPath2d<T>) => CubicPath2d<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: CubicPath2d<T>) => CubicPath2d<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: CubicPath2d<T>) => CubicPath2d<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: CubicPath2d<T>) => CubicPath2d<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: CubicPath2d<T>) => CubicPath2d<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: CubicPath2d<T>, x: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (x: number): <T extends MonotonicX>(p: CubicPath2d<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: CubicPath2d<T>, y: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (y: number): <T extends MonotonicY>(p: CubicPath2d<T>) => Solution.AtMostOne<number>\n} = internal.solveAtY as never\n\nexport const solveByDistance: {\n /**\n * Solves a cubic path by normalized arc length. Unlike {@link solve}, which\n * is parameterized by curve `u`, this samples points at constant speed along\n * the path — `s = 0.5` returns the point exactly halfway along the curve by\n * arc length, regardless of how the underlying parameterization stretches.\n *\n * Cumulative segment lengths are cached by path identity so repeated calls\n * with the same path are fast.\n *\n * @param p - The cubic path to sample.\n * @param s - Normalized arc length in `[0, 1]`. Values outside the range are\n * clamped to path endpoints.\n * @returns The point on the path at the given normalized arc length.\n * @since 1.1.0\n */\n (p: CubicPath2d, s: number): Vector2\n /**\n * Solves a cubic path by normalized arc length.\n *\n * @param s - Normalized arc length in `[0, 1]`.\n * @returns A function that takes a cubic path and returns the point at that\n * arc length.\n * @since 1.1.0\n */\n (s: number): (p: CubicPath2d) => Vector2\n} = internal.solveByDistance\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 cubic path.\n * @returns A closed `Box2d` enclosing the path.\n * @since 2.0.0\n */\nexport const boundingBox: (p: CubicPath2d) => Interval2d<Closed, Closed> = internal.boundingBox\n","import type * as CubicCurve2d from '../curve/cubic2d.ts'\nimport * as RationalCubicCurve2d from '../curve/rationalCubic2d.ts'\nimport type * as Interval from '../interval/interval.ts'\nimport * as Interval2d from '../interval/interval2d.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport { invariant } from '../utils.ts'\nimport type * as Vector2 from '../vector/vector2.ts'\nimport * as CubicPath2d from './cubic2d.ts'\nimport type { RationalCubicPath2d } from './rationalCubic2d.ts'\n\nexport const RationalCubicPath2dTypeId: unique symbol = Symbol('curvy/path/rationalCubic2d')\nexport type RationalCubicPath2dTypeId = typeof RationalCubicPath2dTypeId\n\n/** @internal */\nexport class RationalCubicPath2dImpl extends Pipeable implements RationalCubicPath2d {\n readonly [RationalCubicPath2dTypeId]: RationalCubicPath2dTypeId = RationalCubicPath2dTypeId\n\n readonly curves: ReadonlyArray<RationalCubicCurve2d.RationalCubicCurve2d>\n\n constructor(curves: ReadonlyArray<RationalCubicCurve2d.RationalCubicCurve2d>) {\n invariant(curves.length > 0, 'rational cubic path requires at least one curve')\n super()\n this.curves = curves\n }\n\n [Symbol.iterator](): Iterator<RationalCubicCurve2d.RationalCubicCurve2d> {\n return this.curves[Symbol.iterator]()\n }\n}\n\n/** @internal */\nexport const isRationalCubicPath2d = (p: unknown): p is RationalCubicPath2d =>\n typeof p === 'object' && p !== null && RationalCubicPath2dTypeId in p\n\n/** @internal */\nexport const make = (\n ...curves: ReadonlyArray<RationalCubicCurve2d.RationalCubicCurve2d>\n): RationalCubicPath2d => new RationalCubicPath2dImpl(curves)\n\n/** @internal */\nexport const fromArray = (\n curves: ReadonlyArray<RationalCubicCurve2d.RationalCubicCurve2d>,\n): RationalCubicPath2d => new RationalCubicPath2dImpl(curves)\n\n/** @internal */\nexport const append = dual<\n (c: RationalCubicCurve2d.RationalCubicCurve2d) => (p: RationalCubicPath2d) => RationalCubicPath2d,\n (p: RationalCubicPath2d, c: RationalCubicCurve2d.RationalCubicCurve2d) => RationalCubicPath2d\n>(2, (p, c) => fromArray([...p, c]))\n\n/** @internal */\nexport const solve = dual<\n (u: number) => (p: RationalCubicPath2d) => Vector2.Vector2,\n (p: RationalCubicPath2d, u: number) => Vector2.Vector2\n>(2, (p: RationalCubicPath2d, u: number) => {\n const curves = p instanceof RationalCubicPath2dImpl ? p.curves : [...p]\n\n if (u === 1) {\n const last = curves.at(-1) as RationalCubicCurve2d.RationalCubicCurve2d\n return RationalCubicCurve2d.solve(last, 1)\n }\n\n const t = u * curves.length\n const i = Math.floor(t)\n const curve = curves[i] as RationalCubicCurve2d.RationalCubicCurve2d\n return RationalCubicCurve2d.solve(curve, t - i)\n})\n\n// Path-level bounding box: per-segment box is delegated to the curve module\n// (subdivision + hull union, tight to within `tolerance` per side); the path\n// box is then their union. Since each segment box's slack is ≤ tolerance per\n// side, the unioned box's slack is also ≤ tolerance per side — the same\n// guarantee holds at the path level.\n/** @internal */\nexport const boundingBox = dual<\n (\n tolerance: number,\n ) => (p: RationalCubicPath2d) => Interval2d.Interval2d<Interval.Closed, Interval.Closed>,\n (\n p: RationalCubicPath2d,\n tolerance: number,\n ) => Interval2d.Interval2d<Interval.Closed, Interval.Closed>\n>(2, (p: RationalCubicPath2d, tolerance: number) => {\n const iter = p[Symbol.iterator]()\n const first = iter.next()\n let acc = RationalCubicCurve2d.boundingBox(\n first.value as RationalCubicCurve2d.RationalCubicCurve2d,\n tolerance,\n )\n for (let next = iter.next(); !next.done; next = iter.next()) {\n acc = Interval2d.union(acc, RationalCubicCurve2d.boundingBox(next.value, tolerance))\n }\n return acc\n})\n\n// Path-level approximation: per-segment approximation is delegated to the\n// curve module; we just concat the results. Segment count grows from N\n// (input) to roughly N × k where k depends on weight magnitude and tolerance —\n// uniform-weight segments stay 1:1.\n/** @internal */\nexport const approximateAsCubicPath = dual<\n (tolerance: number) => (p: RationalCubicPath2d) => CubicPath2d.CubicPath2d,\n (p: RationalCubicPath2d, tolerance: number) => CubicPath2d.CubicPath2d\n>(2, (p: RationalCubicPath2d, tolerance: number) => {\n const curves: Array<CubicCurve2d.CubicCurve2d> = []\n for (const segment of p) {\n for (const approx of RationalCubicCurve2d.approximateAsCubicCurves(segment, tolerance)) {\n curves.push(approx)\n }\n }\n return CubicPath2d.fromArray(curves)\n})\n","import type { RationalCubicCurve2d } from '../curve/rationalCubic2d.ts'\nimport type { Closed } from '../interval/interval.ts'\nimport type { Interval2d } from '../interval/interval2d.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { CubicPath2d } from './cubic2d.ts'\nimport type { RationalCubicPath2dTypeId } from './rationalCubic2d.internal.ts'\nimport * as internal from './rationalCubic2d.internal.ts'\n\n/**\n * A rational cubic path in 2D space.\n *\n * Holds a non-empty sequence of `RationalCubicCurve2d` segments; iteration\n * yields the segments in order. The path parameter `u ∈ [0, 1]` is mapped\n * uniformly across segments — `u = 0` is the start of the first segment,\n * `u = 1` is the end of the last segment, and intermediate values pick a\n * segment by index and a local parameter within it.\n *\n * Counterpart to `CubicPath2d` for curves whose evaluation includes the\n * homogeneous-to-plane projection.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * @since 2.0.0\n */\nexport interface RationalCubicPath2d extends Pipeable, Iterable<RationalCubicCurve2d> {\n readonly [RationalCubicPath2dTypeId]: RationalCubicPath2dTypeId\n}\n\n/**\n * Checks if a value is a `RationalCubicPath2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `RationalCubicPath2d`, `false` otherwise.\n * @since 2.0.0\n */\nexport const isRationalCubicPath2d: (p: unknown) => p is RationalCubicPath2d =\n internal.isRationalCubicPath2d\n\n/**\n * Creates a new `RationalCubicPath2d` from a sequence of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `RationalCubicPath2d` instance.\n * @since 2.0.0\n */\nexport const make: (...curves: ReadonlyArray<RationalCubicCurve2d>) => RationalCubicPath2d =\n internal.make\n\n/**\n * Creates a new `RationalCubicPath2d` from an array of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `RationalCubicPath2d` instance.\n * @since 2.0.0\n */\nexport const fromArray: (curves: ReadonlyArray<RationalCubicCurve2d>) => RationalCubicPath2d =\n internal.fromArray\n\nexport const append: {\n /**\n * Appends a curve to a `RationalCubicPath2d`.\n *\n * @param c - The curve to append.\n * @returns A function that takes a path and returns a new path with the appended curve.\n * @since 2.0.0\n */\n (c: RationalCubicCurve2d): (p: RationalCubicPath2d) => RationalCubicPath2d\n /**\n * Appends a curve to a `RationalCubicPath2d`.\n *\n * @param p - The path to append to.\n * @param c - The curve to append.\n * @returns A new path with the appended curve.\n * @since 2.0.0\n */\n (p: RationalCubicPath2d, c: RationalCubicCurve2d): RationalCubicPath2d\n} = internal.append\n\nexport const solve: {\n /**\n * Evaluates the rational cubic path at parameter `u ∈ [0, 1]`.\n *\n * Picks the segment containing `u` (uniform mapping across segments) and\n * delegates to `RationalCubicCurve2d.solve` on that segment with the local\n * parameter.\n *\n * @param p - The path to evaluate.\n * @param u - The path parameter in `[0, 1]`.\n * @returns The point on the path at parameter `u`.\n * @since 2.0.0\n */\n (p: RationalCubicPath2d, u: number): Vector2\n /**\n * Evaluates the rational cubic path at parameter `u ∈ [0, 1]`.\n *\n * @param u - The path parameter in `[0, 1]`.\n * @returns A function that takes a path and returns the point at `u`.\n * @since 2.0.0\n */\n (u: number): (p: RationalCubicPath2d) => Vector2\n} = internal.solve\n\nexport const boundingBox: {\n /**\n * Computes a closed axis-aligned bounding box for a rational cubic path,\n * tight to within `tolerance` per side.\n *\n * Per-segment delegates to `RationalCubicCurve2d.boundingBox(c, tolerance)`\n * — recursive subdivision producing a hull-AABB union tight to within\n * `tolerance` per side. The path box is the union of segment boxes; since\n * each segment box has slack ≤ tolerance per side, so does the union.\n *\n * @param p - The rational cubic path.\n * @param tolerance - Maximum allowed slack per side; must be positive.\n * @returns A closed `Interval2d` enclosing the path, tight to within `tolerance`.\n * @since 2.0.0\n */\n (p: RationalCubicPath2d, tolerance: number): Interval2d<Closed, Closed>\n /**\n * Computes a closed axis-aligned bounding box for a rational cubic path.\n *\n * @param tolerance - Maximum allowed slack per side; must be positive.\n * @returns A function that takes a path and returns its bounding box.\n * @since 2.0.0\n */\n (tolerance: number): (p: RationalCubicPath2d) => Interval2d<Closed, Closed>\n} = internal.boundingBox\n\nexport const approximateAsCubicPath: {\n /**\n * Approximates the rational cubic path as a `CubicPath2d` via per-segment\n * recursive subdivision. Each input segment is split until its midpoint\n * deviates from a polynomial-cubic candidate by at most `tolerance`; the\n * surviving candidates are concatenated into a new path.\n *\n * Lossy in general — only exact when every input segment has uniform\n * weights, in which case segment count is preserved. Tighter tolerance\n * produces more segments.\n *\n * @param p - The rational cubic path to approximate.\n * @param tolerance - Maximum allowed midpoint deviation per segment; must be positive.\n * @returns A new `CubicPath2d` approximating the input.\n * @since 2.0.0\n */\n (p: RationalCubicPath2d, tolerance: number): CubicPath2d\n /**\n * Approximates the rational cubic path as a `CubicPath2d`.\n *\n * @param tolerance - Maximum allowed midpoint deviation per segment; must be positive.\n * @returns A function that takes a rational path and returns its approximation.\n * @since 2.0.0\n */\n (tolerance: number): (p: RationalCubicPath2d) => CubicPath2d\n} = internal.approximateAsCubicPath\n"],"mappings":"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"}
@@ -349,4 +349,4 @@ const match = match$1;
349
349
  //#endregion
350
350
  export { match as a, solution_exports as c, map as i, two as l, fromArray as n, none as o, isNone as r, one as s, clip as t };
351
351
 
352
- //# sourceMappingURL=solution-B6KY1E7M.mjs.map
352
+ //# sourceMappingURL=solution-B2JdOZpe.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"solution-B6KY1E7M.mjs","names":["none","one","two","three","fromArray","isNone","isSome","valueOrUndefined","last","min","max","unsafeValue","unsafeLast","unsafeMin","unsafeMax","filter","clip","Interval.contains","map","match","internal.none","internal.one","internal.two","internal.three","internal.fromArray","internal.isNone","internal.isSome","internal.valueOrUndefined","internal.last","internal.min","internal.max","internal.unsafeValue","internal.unsafeLast","internal.unsafeMin","internal.unsafeMax","internal.filter","internal.clip","internal.map","internal.match"],"sources":["../../src/solution/solution.internal.ts","../../src/solution/solution.ts"],"sourcesContent":["import * as Interval from '../interval/interval.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport type {\n AtMostOne,\n AtMostThree,\n AtMostTwo,\n None,\n One,\n Solution,\n Some,\n Three,\n Two,\n} from './solution.ts'\nimport { invariant } from '../utils.ts'\n\n// Empty iterator — shared across all None instances since None has no data.\nconst EMPTY_ITERATOR: Iterator<never> = {\n next: () => ({ done: true, value: undefined as never }),\n}\n\nclass NoneImpl extends Pipeable implements None {\n readonly _tag = 'none' as const\n readonly length = 0 as const;\n\n [Symbol.iterator](): Iterator<never> {\n return EMPTY_ITERATOR\n }\n}\n\nclass OneImpl<T> extends Pipeable implements One<T> {\n readonly _tag = 'one' as const\n readonly length = 1 as const\n\n constructor(readonly value: T) {\n super()\n }\n\n [Symbol.iterator](): Iterator<T> {\n return [this.value][Symbol.iterator]()\n }\n}\n\nclass TwoImpl<T> extends Pipeable implements Two<T> {\n readonly _tag = 'two' as const\n readonly length = 2 as const\n\n constructor(readonly values: readonly [T, T]) {\n super()\n }\n\n get value(): T {\n return this.values[0]\n }\n\n [Symbol.iterator](): Iterator<T> {\n return this.values[Symbol.iterator]()\n }\n}\n\nclass ThreeImpl<T> extends Pipeable implements Three<T> {\n readonly _tag = 'three' as const\n readonly length = 3 as const\n\n constructor(readonly values: readonly [T, T, T]) {\n super()\n }\n\n get value(): T {\n return this.values[0]\n }\n\n [Symbol.iterator](): Iterator<T> {\n return this.values[Symbol.iterator]()\n }\n}\n\n/** @internal */\nexport const NONE_INSTANCE: None = new NoneImpl()\n\n/** @internal */\nexport const none: None = NONE_INSTANCE\n\n/** @internal */\nexport const one = <T>(value: T): One<T> => new OneImpl(value)\n\n/** @internal */\nexport const two = <T>(a: T, b: T): Two<T> => new TwoImpl([a, b])\n\n/** @internal */\nexport const three = <T>(a: T, b: T, c: T): Three<T> => new ThreeImpl([a, b, c])\n\n/** @internal */\nexport const fromArray = <T>(arr: ReadonlyArray<T>): Solution<T> => {\n switch (arr.length) {\n case 0:\n return NONE_INSTANCE\n case 1:\n return one(arr[0] as T)\n case 2:\n return two(arr[0] as T, arr[1] as T)\n case 3:\n return three(arr[0] as T, arr[1] as T, arr[2] as T)\n default:\n invariant(false, `Solution can hold at most 3 values, got ${arr.length}`)\n }\n}\n\n/** @internal */\nexport const isNone = <T>(s: Solution<T>): s is None => s._tag === 'none'\n\n/** @internal */\nexport const isSome = <T>(s: Solution<T>): s is Some<T> => s._tag !== 'none'\n\n/** @internal */\nexport const valueOrUndefined = <T>(s: Solution<T>): T | undefined =>\n isNone(s) ? undefined : s.value\n\n/** @internal */\nexport const last: {\n <T>(s: Some<T>): T\n <T>(s: Solution<T>): T | undefined\n} = (<T>(s: Solution<T>): T | undefined => {\n switch (s._tag) {\n case 'none':\n return undefined\n case 'one':\n return s.value\n case 'two':\n return s.values[1]\n case 'three':\n return s.values[2]\n }\n}) as never\n\n/** @internal */\nexport const min: {\n (s: Some<number>): number\n (s: Solution<number>): number | undefined\n} = ((s: Solution<number>): number | undefined => {\n switch (s._tag) {\n case 'none':\n return undefined\n case 'one':\n return s.value\n case 'two':\n return Math.min(s.values[0], s.values[1])\n case 'three':\n return Math.min(s.values[0], s.values[1], s.values[2])\n }\n}) as never\n\n/** @internal */\nexport const max: {\n (s: Some<number>): number\n (s: Solution<number>): number | undefined\n} = ((s: Solution<number>): number | undefined => {\n switch (s._tag) {\n case 'none':\n return undefined\n case 'one':\n return s.value\n case 'two':\n return Math.max(s.values[0], s.values[1])\n case 'three':\n return Math.max(s.values[0], s.values[1], s.values[2])\n }\n}) as never\n\n/** @internal */\nexport const unsafeValue = <T>(s: Solution<T>, message?: string): T => {\n invariant(isSome(s), message ?? 'Solution.unsafeValue on empty Solution')\n return s.value\n}\n\n/** @internal */\nexport const unsafeLast = <T>(s: Solution<T>): T => {\n invariant(isSome(s), 'Solution.unsafeLast on empty Solution')\n return last(s)\n}\n\n/** @internal */\nexport const unsafeMin = (s: Solution<number>): number => {\n invariant(isSome(s), 'Solution.unsafeMin on empty Solution')\n return min(s)\n}\n\n/** @internal */\nexport const unsafeMax = (s: Solution<number>): number => {\n invariant(isSome(s), 'Solution.unsafeMax on empty Solution')\n return max(s)\n}\n\n/** @internal */\nexport const filter = <T>(s: Solution<T>, predicate: (v: T) => boolean): Solution<T> => {\n switch (s._tag) {\n case 'none':\n return s\n case 'one':\n return predicate(s.value) ? s : NONE_INSTANCE\n case 'two': {\n const a = predicate(s.values[0])\n const b = predicate(s.values[1])\n if (a && b) {\n return s\n }\n if (a) {\n return one(s.values[0])\n }\n if (b) {\n return one(s.values[1])\n }\n return NONE_INSTANCE\n }\n case 'three': {\n const survivors: Array<T> = []\n if (predicate(s.values[0])) {\n survivors.push(s.values[0])\n }\n if (predicate(s.values[1])) {\n survivors.push(s.values[1])\n }\n if (predicate(s.values[2])) {\n survivors.push(s.values[2])\n }\n return fromArray(survivors)\n }\n }\n}\n\n/** @internal */\nexport const clip = dual(\n 2,\n (s: Solution<number>, i: Interval.Interval): Solution<number> =>\n filter(s, (v) => Interval.contains(i, v)),\n)\n\n/** @internal */\nexport const map = dual(2, <A, B>(s: Solution<A>, f: (v: A) => B): Solution<B> => {\n switch (s._tag) {\n case 'none':\n return s\n case 'one':\n return one(f(s.value))\n case 'two':\n return two(f(s.values[0]), f(s.values[1]))\n case 'three':\n return three(f(s.values[0]), f(s.values[1]), f(s.values[2]))\n }\n})\n\n/** @internal */\nexport const match = dual(\n 2,\n <T, A, B>(\n self: Solution<T>,\n matcher: { readonly onNone: () => A; readonly onSome: (s: Some<T>) => B },\n ): A | B => (isNone(self) ? matcher.onNone() : matcher.onSome(self)),\n)\n\n// Re-export type aliases that the namespace consumers expect to see at runtime.\n// (Pure type re-exports — no runtime cost.)\nexport type { AtMostOne, AtMostThree, AtMostTwo, None, One, Solution, Some, Three, Two }\n","import type { Interval } from '../interval/interval.ts'\nimport type { Pipeable } from '../utils.ts'\nimport * as internal from './solution.internal.ts'\n\n/**\n * A `Solution<T>` represents the result of an operation that may produce\n * between zero and three values of `T`. It generalizes the zoo of \"0 or 1\",\n * \"0 to 2\", \"0 to 3\" return shapes used throughout curvy under one type, and\n * provides a small namespace of operations (`value`, `last`, `min`, `max`,\n * `filter`, `map`, `match`, …) for working with the result.\n *\n * Each variant carries a `_tag` discriminator and a `length` field, is\n * iterable via `Symbol.iterator` (so existing `for..of` and spread patterns\n * keep working), and is `Pipeable` (so a `Solution` value can be the head of\n * a `pipe` chain).\n *\n * Variant-specific accessors:\n * - `One<T>`, `Two<T>`, and `Three<T>` all expose `.value: T` (the first /\n * primary value).\n * - `Two<T>` and `Three<T>` additionally expose `.values: readonly [T, ...]`\n * for explicit positional access.\n *\n * Operations that return narrower cardinalities (e.g. inverse-solving a\n * monotonic polynomial) use the `AtMost{One,Two,Three}` aliases to express\n * \"this could be empty, but it'll have at most N values.\"\n *\n * @since 2.0.0\n */\nexport type Solution<T> = None | One<T> | Two<T> | Three<T>\n\n/**\n * The empty solution.\n *\n * @since 2.0.0\n */\nexport interface None extends Pipeable, Iterable<never> {\n readonly _tag: 'none'\n readonly length: 0\n}\n\n/** @since 2.0.0 */\nexport interface One<T> extends Pipeable, Iterable<T> {\n readonly _tag: 'one'\n readonly length: 1\n readonly value: T\n}\n\n/** @since 2.0.0 */\nexport interface Two<T> extends Pipeable, Iterable<T> {\n readonly _tag: 'two'\n readonly length: 2\n readonly value: T\n readonly values: readonly [T, T]\n}\n\n/** @since 2.0.0 */\nexport interface Three<T> extends Pipeable, Iterable<T> {\n readonly _tag: 'three'\n readonly length: 3\n readonly value: T\n readonly values: readonly [T, T, T]\n}\n\n/**\n * Any non-empty solution. All `Some<T>` values expose `.value: T` directly —\n * no narrowing required to read the primary value.\n *\n * @since 2.0.0\n */\nexport type Some<T> = One<T> | Two<T> | Three<T>\n\n/**\n * `None | One<T>` — return type of operations that produce at most one value\n * (e.g. inverse-solving a strictly monotonic polynomial).\n *\n * @since 2.0.0\n */\nexport type AtMostOne<T> = None | One<T>\n\n/**\n * `None | One<T> | Two<T>` — return type of operations that produce at most\n * two values (e.g. inverse-solving an unrestricted quadratic polynomial).\n *\n * @since 2.0.0\n */\nexport type AtMostTwo<T> = None | One<T> | Two<T>\n\n/**\n * `None | One<T> | Two<T> | Three<T>` — equivalent to `Solution<T>`.\n *\n * @since 2.0.0\n */\nexport type AtMostThree<T> = Solution<T>\n\n/**\n * The empty solution. Reused across calls — never reallocated.\n *\n * @since 2.0.0\n */\nexport const none: None = internal.none\n\n/**\n * Constructs a single-value solution.\n *\n * @since 2.0.0\n */\nexport const one: <T>(value: T) => One<T> = internal.one\n\n/**\n * Constructs a two-value solution.\n *\n * @since 2.0.0\n */\nexport const two: <T>(a: T, b: T) => Two<T> = internal.two\n\n/**\n * Constructs a three-value solution.\n *\n * @since 2.0.0\n */\nexport const three: <T>(a: T, b: T, c: T) => Three<T> = internal.three\n\n/**\n * Constructs a `Solution<T>` from a runtime array. Throws if the array has\n * more than three elements.\n *\n * @since 2.0.0\n */\nexport const fromArray: <T>(arr: ReadonlyArray<T>) => Solution<T> = internal.fromArray\n\n/**\n * Type-narrowing predicate: refines `Solution<T>` to `None`.\n *\n * @since 2.0.0\n */\nexport const isNone: <T>(s: Solution<T>) => s is None = internal.isNone\n\n/**\n * Type-narrowing predicate: refines `Solution<T>` to `Some<T>` (non-empty).\n * After narrowing, `.value` is directly accessible without further checks.\n *\n * @since 2.0.0\n */\nexport const isSome: <T>(s: Solution<T>) => s is Some<T> = internal.isSome\n\n/**\n * Returns the primary (first) value if the solution is non-empty, or\n * `undefined` if empty. Pair with `.value` access on `Some<T>`-narrowed\n * inputs to avoid the `undefined` possibility.\n *\n * @since 2.0.0\n */\nexport const valueOrUndefined: <T>(s: Solution<T>) => T | undefined = internal.valueOrUndefined\n\n/**\n * Returns the last value in the solution, or `undefined` if empty. When\n * called on a `Some<T>`, the result is guaranteed to be `T`.\n *\n * @since 2.0.0\n */\nexport const last: {\n <T>(s: Some<T>): T\n <T>(s: Solution<T>): T | undefined\n} = internal.last\n\n/**\n * Returns the smallest numeric value in the solution, or `undefined` if empty.\n * When called on a `Some<number>`, the result is guaranteed to be `number`.\n *\n * @since 2.0.0\n */\nexport const min: {\n (s: Some<number>): number\n (s: Solution<number>): number | undefined\n} = internal.min\n\n/**\n * Returns the largest numeric value in the solution, or `undefined` if empty.\n * When called on a `Some<number>`, the result is guaranteed to be `number`.\n *\n * @since 2.0.0\n */\nexport const max: {\n (s: Some<number>): number\n (s: Solution<number>): number | undefined\n} = internal.max\n\n/**\n * Returns the primary value of the solution (i.e. `s.value`). Throws on\n * `None`, optionally with a caller-provided message.\n *\n * Useful when the type system can't prove non-emptiness but you have a domain\n * reason to assert it — e.g. inverting a polynomial you know to be monotonic\n * without going through the trait refiner first:\n *\n * ```ts\n * const x = CubicPolynomial.solveInverse(p, y).pipe(\n * Solution.unsafeValue('expected a monotonic inverse'),\n * )\n * ```\n *\n * @since 2.0.0\n */\nexport const unsafeValue: {\n <T>(s: Solution<T>, message?: string): T\n (message: string): <T>(s: Solution<T>) => T\n} = ((...args: ReadonlyArray<unknown>) => {\n if (args.length >= 1 && typeof args[0] === 'object' && args[0] !== null) {\n return internal.unsafeValue(args[0] as Solution<unknown>, args[1] as string | undefined)\n }\n const message = args[0] as string\n return <T>(s: Solution<T>) => internal.unsafeValue(s, message)\n}) as never\n\n/**\n * Returns the last value in the solution. Throws if empty.\n *\n * @since 2.0.0\n */\nexport const unsafeLast: <T>(s: Solution<T>) => T = internal.unsafeLast\n\n/**\n * Returns the smallest numeric value in the solution. Throws on empty.\n *\n * @since 2.0.0\n */\nexport const unsafeMin: (s: Solution<number>) => number = internal.unsafeMin\n\n/**\n * Returns the largest numeric value in the solution. Throws on empty.\n *\n * @since 2.0.0\n */\nexport const unsafeMax: (s: Solution<number>) => number = internal.unsafeMax\n\n/**\n * Filters the solution by a predicate. Result cardinality is at most that of\n * the input.\n *\n * @since 2.0.0\n */\nexport const filter: <T>(s: Solution<T>, predicate: (v: T) => boolean) => Solution<T> =\n internal.filter\n\n/**\n * Restricts the solution to values contained within an interval. Endpoint\n * inclusivity follows the interval's `kind` — pass an open variant (e.g.\n * `Interval.makeOpen(0, 1)` or `Interval.unitOpen`) for strict containment.\n *\n * @param s - The solution to clip.\n * @param i - The interval to retain values within.\n * @since 2.0.0\n */\nexport const clip: {\n (i: Interval): (s: Solution<number>) => Solution<number>\n (s: Solution<number>, i: Interval): Solution<number>\n} = internal.clip\n\n/**\n * Maps every value in the solution to a new value. Result cardinality matches\n * the input.\n *\n * @since 2.0.0\n */\nexport const map: {\n <A, B>(s: Solution<A>, f: (v: A) => B): Solution<B>\n <A, B>(f: (v: A) => B): (s: Solution<A>) => Solution<B>\n} = internal.map\n\n// Drops `None` from the union of the input solution type — used by `match` to\n// give `onSome` a tighter parameter type. Distributive: a `Solution.AtMostOne<T>`\n// becomes `One<T>`; a full `Solution<T>` keeps `Some<T>`.\ntype SomeOf<S> = S extends None ? never : S\n\n/**\n * Pattern matches on a solution, calling `onNone` for the empty case and\n * `onSome` for any non-empty case. The `onSome` parameter is typed against\n * the input's narrowed shape — for an `AtMostOne<T>` input, `onSome` receives\n * `One<T>` and can read `.value` directly.\n *\n * @example\n * ```ts\n * const result = polynomial.pipe(\n * LinearPolynomial.solveInverse(0),\n * Solution.match({\n * onNone: () => null,\n * onSome: ({ value }) => Math.abs(value),\n * }),\n * )\n * ```\n *\n * @since 2.0.0\n */\nexport const match: {\n <S extends Solution<unknown>, A, B>(\n self: S,\n matcher: { readonly onNone: () => A; readonly onSome: (s: SomeOf<S>) => B },\n ): A | B\n <S extends Solution<unknown>, A, B>(matcher: {\n readonly onNone: () => A\n readonly onSome: (s: SomeOf<S>) => B\n }): (self: S) => A | B\n} = internal.match as never\n"],"mappings":";;;;AAgBA,MAAM,iBAAkC,EACtC,aAAa;CAAE,MAAM;CAAM,OAAO,KAAA;CAAoB,GACvD;AAED,IAAM,WAAN,cAAuB,SAAyB;CAC9C,OAAgB;CAChB,SAAkB;CAElB,CAAC,OAAO,YAA6B;EACnC,OAAO;;;AAIX,IAAM,UAAN,cAAyB,SAA2B;CAI7B;CAHrB,OAAgB;CAChB,SAAkB;CAElB,YAAY,OAAmB;EAC7B,OAAO;EADY,KAAA,QAAA;;CAIrB,CAAC,OAAO,YAAyB;EAC/B,OAAO,CAAC,KAAK,MAAM,CAAC,OAAO,WAAW;;;AAI1C,IAAM,UAAN,cAAyB,SAA2B;CAI7B;CAHrB,OAAgB;CAChB,SAAkB;CAElB,YAAY,QAAkC;EAC5C,OAAO;EADY,KAAA,SAAA;;CAIrB,IAAI,QAAW;EACb,OAAO,KAAK,OAAO;;CAGrB,CAAC,OAAO,YAAyB;EAC/B,OAAO,KAAK,OAAO,OAAO,WAAW;;;AAIzC,IAAM,YAAN,cAA2B,SAA6B;CAIjC;CAHrB,OAAgB;CAChB,SAAkB;CAElB,YAAY,QAAqC;EAC/C,OAAO;EADY,KAAA,SAAA;;CAIrB,IAAI,QAAW;EACb,OAAO,KAAK,OAAO;;CAGrB,CAAC,OAAO,YAAyB;EAC/B,OAAO,KAAK,OAAO,OAAO,WAAW;;;;AAKzC,MAAa,gBAAsB,IAAI,UAAU;;AAGjD,MAAaA,SAAa;;AAG1B,MAAaC,SAAU,UAAqB,IAAI,QAAQ,MAAM;;AAG9D,MAAaC,SAAU,GAAM,MAAiB,IAAI,QAAQ,CAAC,GAAG,EAAE,CAAC;;AAGjE,MAAaC,WAAY,GAAM,GAAM,MAAmB,IAAI,UAAU;CAAC;CAAG;CAAG;CAAE,CAAC;;AAGhF,MAAaC,eAAgB,QAAuC;CAClE,QAAQ,IAAI,QAAZ;EACE,KAAK,GACH,OAAO;EACT,KAAK,GACH,OAAOH,MAAI,IAAI,GAAQ;EACzB,KAAK,GACH,OAAOC,MAAI,IAAI,IAAS,IAAI,GAAQ;EACtC,KAAK,GACH,OAAOC,QAAM,IAAI,IAAS,IAAI,IAAS,IAAI,GAAQ;EACrD,SACE,UAAU,OAAO,2CAA2C,IAAI,SAAS;;;;AAK/E,MAAaE,YAAa,MAA8B,EAAE,SAAS;;AAGnE,MAAaC,YAAa,MAAiC,EAAE,SAAS;;AAGtE,MAAaC,sBAAuB,MAClCF,SAAO,EAAE,GAAG,KAAA,IAAY,EAAE;;AAG5B,MAAaG,WAGJ,MAAkC;CACzC,QAAQ,EAAE,MAAV;EACE,KAAK,QACH;EACF,KAAK,OACH,OAAO,EAAE;EACX,KAAK,OACH,OAAO,EAAE,OAAO;EAClB,KAAK,SACH,OAAO,EAAE,OAAO;;;;AAKtB,MAAaC,UAGP,MAA4C;CAChD,QAAQ,EAAE,MAAV;EACE,KAAK,QACH;EACF,KAAK,OACH,OAAO,EAAE;EACX,KAAK,OACH,OAAO,KAAK,IAAI,EAAE,OAAO,IAAI,EAAE,OAAO,GAAG;EAC3C,KAAK,SACH,OAAO,KAAK,IAAI,EAAE,OAAO,IAAI,EAAE,OAAO,IAAI,EAAE,OAAO,GAAG;;;;AAK5D,MAAaC,UAGP,MAA4C;CAChD,QAAQ,EAAE,MAAV;EACE,KAAK,QACH;EACF,KAAK,OACH,OAAO,EAAE;EACX,KAAK,OACH,OAAO,KAAK,IAAI,EAAE,OAAO,IAAI,EAAE,OAAO,GAAG;EAC3C,KAAK,SACH,OAAO,KAAK,IAAI,EAAE,OAAO,IAAI,EAAE,OAAO,IAAI,EAAE,OAAO,GAAG;;;;AAK5D,MAAaC,iBAAkB,GAAgB,YAAwB;CACrE,UAAUL,SAAO,EAAE,EAAE,WAAW,yCAAyC;CACzE,OAAO,EAAE;;;AAIX,MAAaM,gBAAiB,MAAsB;CAClD,UAAUN,SAAO,EAAE,EAAE,wCAAwC;CAC7D,OAAOE,OAAK,EAAE;;;AAIhB,MAAaK,eAAa,MAAgC;CACxD,UAAUP,SAAO,EAAE,EAAE,uCAAuC;CAC5D,OAAOG,MAAI,EAAE;;;AAIf,MAAaK,eAAa,MAAgC;CACxD,UAAUR,SAAO,EAAE,EAAE,uCAAuC;CAC5D,OAAOI,MAAI,EAAE;;;AAIf,MAAaK,YAAa,GAAgB,cAA8C;CACtF,QAAQ,EAAE,MAAV;EACE,KAAK,QACH,OAAO;EACT,KAAK,OACH,OAAO,UAAU,EAAE,MAAM,GAAG,IAAI;EAClC,KAAK,OAAO;GACV,MAAM,IAAI,UAAU,EAAE,OAAO,GAAG;GAChC,MAAM,IAAI,UAAU,EAAE,OAAO,GAAG;GAChC,IAAI,KAAK,GACP,OAAO;GAET,IAAI,GACF,OAAOd,MAAI,EAAE,OAAO,GAAG;GAEzB,IAAI,GACF,OAAOA,MAAI,EAAE,OAAO,GAAG;GAEzB,OAAO;;EAET,KAAK,SAAS;GACZ,MAAM,YAAsB,EAAE;GAC9B,IAAI,UAAU,EAAE,OAAO,GAAG,EACxB,UAAU,KAAK,EAAE,OAAO,GAAG;GAE7B,IAAI,UAAU,EAAE,OAAO,GAAG,EACxB,UAAU,KAAK,EAAE,OAAO,GAAG;GAE7B,IAAI,UAAU,EAAE,OAAO,GAAG,EACxB,UAAU,KAAK,EAAE,OAAO,GAAG;GAE7B,OAAOG,YAAU,UAAU;;;;;AAMjC,MAAaY,SAAO,KAClB,IACC,GAAqB,MACpBD,SAAO,IAAI,MAAME,SAAkB,GAAG,EAAE,CAAC,CAC5C;;AAGD,MAAaC,QAAM,KAAK,IAAU,GAAgB,MAAgC;CAChF,QAAQ,EAAE,MAAV;EACE,KAAK,QACH,OAAO;EACT,KAAK,OACH,OAAOjB,MAAI,EAAE,EAAE,MAAM,CAAC;EACxB,KAAK,OACH,OAAOC,MAAI,EAAE,EAAE,OAAO,GAAG,EAAE,EAAE,EAAE,OAAO,GAAG,CAAC;EAC5C,KAAK,SACH,OAAOC,QAAM,EAAE,EAAE,OAAO,GAAG,EAAE,EAAE,EAAE,OAAO,GAAG,EAAE,EAAE,EAAE,OAAO,GAAG,CAAC;;EAEhE;;AAGF,MAAagB,UAAQ,KACnB,IAEE,MACA,YACWd,SAAO,KAAK,GAAG,QAAQ,QAAQ,GAAG,QAAQ,OAAO,KAAK,CACpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9JD,MAAa,OAAae;;;;;;AAO1B,MAAa,MAA+BC;;;;;;AAO5C,MAAa,MAAiCC;;;;;;AAO9C,MAAa,QAA2CC;;;;;;;AAQxD,MAAa,YAAuDC;;;;;;AAOpE,MAAa,SAA2CC;;;;;;;AAQxD,MAAa,SAA8CC;;;;;;;;AAS3D,MAAa,mBAAyDC;;;;;;;AAQtE,MAAa,OAGTC;;;;;;;AAQJ,MAAa,MAGTC;;;;;;;AAQJ,MAAa,MAGTC;;;;;;;;;;;;;;;;;AAkBJ,MAAa,gBAGP,GAAG,SAAiC;CACxC,IAAI,KAAK,UAAU,KAAK,OAAO,KAAK,OAAO,YAAY,KAAK,OAAO,MACjE,OAAOC,cAAqB,KAAK,IAAyB,KAAK,GAAyB;CAE1F,MAAM,UAAU,KAAK;CACrB,QAAW,MAAmBA,cAAqB,GAAG,QAAQ;;;;;;;AAQhE,MAAa,aAAuCC;;;;;;AAOpD,MAAa,YAA6CC;;;;;;AAO1D,MAAa,YAA6CC;;;;;;;AAQ1D,MAAa,SACXC;;;;;;;;;;AAWF,MAAa,OAGTC;;;;;;;AAQJ,MAAa,MAGTC;;;;;;;;;;;;;;;;;;;;AA0BJ,MAAa,QASTC"}
1
+ {"version":3,"file":"solution-B2JdOZpe.mjs","names":["none","one","two","three","fromArray","isNone","isSome","valueOrUndefined","last","min","max","unsafeValue","unsafeLast","unsafeMin","unsafeMax","filter","clip","Interval.contains","map","match","internal.none","internal.one","internal.two","internal.three","internal.fromArray","internal.isNone","internal.isSome","internal.valueOrUndefined","internal.last","internal.min","internal.max","internal.unsafeValue","internal.unsafeLast","internal.unsafeMin","internal.unsafeMax","internal.filter","internal.clip","internal.map","internal.match"],"sources":["../../src/solution/solution.internal.ts","../../src/solution/solution.ts"],"sourcesContent":["import * as Interval from '../interval/interval.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport type {\n AtMostOne,\n AtMostThree,\n AtMostTwo,\n None,\n One,\n Solution,\n Some,\n Three,\n Two,\n} from './solution.ts'\nimport { invariant } from '../utils.ts'\n\n// Empty iterator — shared across all None instances since None has no data.\nconst EMPTY_ITERATOR: Iterator<never> = {\n next: () => ({ done: true, value: undefined as never }),\n}\n\nclass NoneImpl extends Pipeable implements None {\n readonly _tag = 'none' as const\n readonly length = 0 as const;\n\n [Symbol.iterator](): Iterator<never> {\n return EMPTY_ITERATOR\n }\n}\n\nclass OneImpl<T> extends Pipeable implements One<T> {\n readonly _tag = 'one' as const\n readonly length = 1 as const\n\n constructor(readonly value: T) {\n super()\n }\n\n [Symbol.iterator](): Iterator<T> {\n return [this.value][Symbol.iterator]()\n }\n}\n\nclass TwoImpl<T> extends Pipeable implements Two<T> {\n readonly _tag = 'two' as const\n readonly length = 2 as const\n\n constructor(readonly values: readonly [T, T]) {\n super()\n }\n\n get value(): T {\n return this.values[0]\n }\n\n [Symbol.iterator](): Iterator<T> {\n return this.values[Symbol.iterator]()\n }\n}\n\nclass ThreeImpl<T> extends Pipeable implements Three<T> {\n readonly _tag = 'three' as const\n readonly length = 3 as const\n\n constructor(readonly values: readonly [T, T, T]) {\n super()\n }\n\n get value(): T {\n return this.values[0]\n }\n\n [Symbol.iterator](): Iterator<T> {\n return this.values[Symbol.iterator]()\n }\n}\n\n/** @internal */\nexport const NONE_INSTANCE: None = new NoneImpl()\n\n/** @internal */\nexport const none: None = NONE_INSTANCE\n\n/** @internal */\nexport const one = <T>(value: T): One<T> => new OneImpl(value)\n\n/** @internal */\nexport const two = <T>(a: T, b: T): Two<T> => new TwoImpl([a, b])\n\n/** @internal */\nexport const three = <T>(a: T, b: T, c: T): Three<T> => new ThreeImpl([a, b, c])\n\n/** @internal */\nexport const fromArray = <T>(arr: ReadonlyArray<T>): Solution<T> => {\n switch (arr.length) {\n case 0:\n return NONE_INSTANCE\n case 1:\n return one(arr[0] as T)\n case 2:\n return two(arr[0] as T, arr[1] as T)\n case 3:\n return three(arr[0] as T, arr[1] as T, arr[2] as T)\n default:\n invariant(false, `Solution can hold at most 3 values, got ${arr.length}`)\n }\n}\n\n/** @internal */\nexport const isNone = <T>(s: Solution<T>): s is None => s._tag === 'none'\n\n/** @internal */\nexport const isSome = <T>(s: Solution<T>): s is Some<T> => s._tag !== 'none'\n\n/** @internal */\nexport const valueOrUndefined = <T>(s: Solution<T>): T | undefined =>\n isNone(s) ? undefined : s.value\n\n/** @internal */\nexport const last: {\n <T>(s: Some<T>): T\n <T>(s: Solution<T>): T | undefined\n} = (<T>(s: Solution<T>): T | undefined => {\n switch (s._tag) {\n case 'none':\n return undefined\n case 'one':\n return s.value\n case 'two':\n return s.values[1]\n case 'three':\n return s.values[2]\n }\n}) as never\n\n/** @internal */\nexport const min: {\n (s: Some<number>): number\n (s: Solution<number>): number | undefined\n} = ((s: Solution<number>): number | undefined => {\n switch (s._tag) {\n case 'none':\n return undefined\n case 'one':\n return s.value\n case 'two':\n return Math.min(s.values[0], s.values[1])\n case 'three':\n return Math.min(s.values[0], s.values[1], s.values[2])\n }\n}) as never\n\n/** @internal */\nexport const max: {\n (s: Some<number>): number\n (s: Solution<number>): number | undefined\n} = ((s: Solution<number>): number | undefined => {\n switch (s._tag) {\n case 'none':\n return undefined\n case 'one':\n return s.value\n case 'two':\n return Math.max(s.values[0], s.values[1])\n case 'three':\n return Math.max(s.values[0], s.values[1], s.values[2])\n }\n}) as never\n\n/** @internal */\nexport const unsafeValue = <T>(s: Solution<T>, message?: string): T => {\n invariant(isSome(s), message ?? 'Solution.unsafeValue on empty Solution')\n return s.value\n}\n\n/** @internal */\nexport const unsafeLast = <T>(s: Solution<T>): T => {\n invariant(isSome(s), 'Solution.unsafeLast on empty Solution')\n return last(s)\n}\n\n/** @internal */\nexport const unsafeMin = (s: Solution<number>): number => {\n invariant(isSome(s), 'Solution.unsafeMin on empty Solution')\n return min(s)\n}\n\n/** @internal */\nexport const unsafeMax = (s: Solution<number>): number => {\n invariant(isSome(s), 'Solution.unsafeMax on empty Solution')\n return max(s)\n}\n\n/** @internal */\nexport const filter = <T>(s: Solution<T>, predicate: (v: T) => boolean): Solution<T> => {\n switch (s._tag) {\n case 'none':\n return s\n case 'one':\n return predicate(s.value) ? s : NONE_INSTANCE\n case 'two': {\n const a = predicate(s.values[0])\n const b = predicate(s.values[1])\n if (a && b) {\n return s\n }\n if (a) {\n return one(s.values[0])\n }\n if (b) {\n return one(s.values[1])\n }\n return NONE_INSTANCE\n }\n case 'three': {\n const survivors: Array<T> = []\n if (predicate(s.values[0])) {\n survivors.push(s.values[0])\n }\n if (predicate(s.values[1])) {\n survivors.push(s.values[1])\n }\n if (predicate(s.values[2])) {\n survivors.push(s.values[2])\n }\n return fromArray(survivors)\n }\n }\n}\n\n/** @internal */\nexport const clip = dual(\n 2,\n (s: Solution<number>, i: Interval.Interval): Solution<number> =>\n filter(s, (v) => Interval.contains(i, v)),\n)\n\n/** @internal */\nexport const map = dual(2, <A, B>(s: Solution<A>, f: (v: A) => B): Solution<B> => {\n switch (s._tag) {\n case 'none':\n return s\n case 'one':\n return one(f(s.value))\n case 'two':\n return two(f(s.values[0]), f(s.values[1]))\n case 'three':\n return three(f(s.values[0]), f(s.values[1]), f(s.values[2]))\n }\n})\n\n/** @internal */\nexport const match = dual(\n 2,\n <T, A, B>(\n self: Solution<T>,\n matcher: { readonly onNone: () => A; readonly onSome: (s: Some<T>) => B },\n ): A | B => (isNone(self) ? matcher.onNone() : matcher.onSome(self)),\n)\n\n// Re-export type aliases that the namespace consumers expect to see at runtime.\n// (Pure type re-exports — no runtime cost.)\nexport type { AtMostOne, AtMostThree, AtMostTwo, None, One, Solution, Some, Three, Two }\n","import type { Interval } from '../interval/interval.ts'\nimport type { Pipeable } from '../utils.ts'\nimport * as internal from './solution.internal.ts'\n\n/**\n * A `Solution<T>` represents the result of an operation that may produce\n * between zero and three values of `T`. It generalizes the zoo of \"0 or 1\",\n * \"0 to 2\", \"0 to 3\" return shapes used throughout curvy under one type, and\n * provides a small namespace of operations (`value`, `last`, `min`, `max`,\n * `filter`, `map`, `match`, …) for working with the result.\n *\n * Each variant carries a `_tag` discriminator and a `length` field, is\n * iterable via `Symbol.iterator` (so existing `for..of` and spread patterns\n * keep working), and is `Pipeable` (so a `Solution` value can be the head of\n * a `pipe` chain).\n *\n * Variant-specific accessors:\n * - `One<T>`, `Two<T>`, and `Three<T>` all expose `.value: T` (the first /\n * primary value).\n * - `Two<T>` and `Three<T>` additionally expose `.values: readonly [T, ...]`\n * for explicit positional access.\n *\n * Operations that return narrower cardinalities (e.g. inverse-solving a\n * monotonic polynomial) use the `AtMost{One,Two,Three}` aliases to express\n * \"this could be empty, but it'll have at most N values.\"\n *\n * @since 2.0.0\n */\nexport type Solution<T> = None | One<T> | Two<T> | Three<T>\n\n/**\n * The empty solution.\n *\n * @since 2.0.0\n */\nexport interface None extends Pipeable, Iterable<never> {\n readonly _tag: 'none'\n readonly length: 0\n}\n\n/** @since 2.0.0 */\nexport interface One<T> extends Pipeable, Iterable<T> {\n readonly _tag: 'one'\n readonly length: 1\n readonly value: T\n}\n\n/** @since 2.0.0 */\nexport interface Two<T> extends Pipeable, Iterable<T> {\n readonly _tag: 'two'\n readonly length: 2\n readonly value: T\n readonly values: readonly [T, T]\n}\n\n/** @since 2.0.0 */\nexport interface Three<T> extends Pipeable, Iterable<T> {\n readonly _tag: 'three'\n readonly length: 3\n readonly value: T\n readonly values: readonly [T, T, T]\n}\n\n/**\n * Any non-empty solution. All `Some<T>` values expose `.value: T` directly —\n * no narrowing required to read the primary value.\n *\n * @since 2.0.0\n */\nexport type Some<T> = One<T> | Two<T> | Three<T>\n\n/**\n * `None | One<T>` — return type of operations that produce at most one value\n * (e.g. inverse-solving a strictly monotonic polynomial).\n *\n * @since 2.0.0\n */\nexport type AtMostOne<T> = None | One<T>\n\n/**\n * `None | One<T> | Two<T>` — return type of operations that produce at most\n * two values (e.g. inverse-solving an unrestricted quadratic polynomial).\n *\n * @since 2.0.0\n */\nexport type AtMostTwo<T> = None | One<T> | Two<T>\n\n/**\n * `None | One<T> | Two<T> | Three<T>` — equivalent to `Solution<T>`.\n *\n * @since 2.0.0\n */\nexport type AtMostThree<T> = Solution<T>\n\n/**\n * The empty solution. Reused across calls — never reallocated.\n *\n * @since 2.0.0\n */\nexport const none: None = internal.none\n\n/**\n * Constructs a single-value solution.\n *\n * @since 2.0.0\n */\nexport const one: <T>(value: T) => One<T> = internal.one\n\n/**\n * Constructs a two-value solution.\n *\n * @since 2.0.0\n */\nexport const two: <T>(a: T, b: T) => Two<T> = internal.two\n\n/**\n * Constructs a three-value solution.\n *\n * @since 2.0.0\n */\nexport const three: <T>(a: T, b: T, c: T) => Three<T> = internal.three\n\n/**\n * Constructs a `Solution<T>` from a runtime array. Throws if the array has\n * more than three elements.\n *\n * @since 2.0.0\n */\nexport const fromArray: <T>(arr: ReadonlyArray<T>) => Solution<T> = internal.fromArray\n\n/**\n * Type-narrowing predicate: refines `Solution<T>` to `None`.\n *\n * @since 2.0.0\n */\nexport const isNone: <T>(s: Solution<T>) => s is None = internal.isNone\n\n/**\n * Type-narrowing predicate: refines `Solution<T>` to `Some<T>` (non-empty).\n * After narrowing, `.value` is directly accessible without further checks.\n *\n * @since 2.0.0\n */\nexport const isSome: <T>(s: Solution<T>) => s is Some<T> = internal.isSome\n\n/**\n * Returns the primary (first) value if the solution is non-empty, or\n * `undefined` if empty. Pair with `.value` access on `Some<T>`-narrowed\n * inputs to avoid the `undefined` possibility.\n *\n * @since 2.0.0\n */\nexport const valueOrUndefined: <T>(s: Solution<T>) => T | undefined = internal.valueOrUndefined\n\n/**\n * Returns the last value in the solution, or `undefined` if empty. When\n * called on a `Some<T>`, the result is guaranteed to be `T`.\n *\n * @since 2.0.0\n */\nexport const last: {\n <T>(s: Some<T>): T\n <T>(s: Solution<T>): T | undefined\n} = internal.last\n\n/**\n * Returns the smallest numeric value in the solution, or `undefined` if empty.\n * When called on a `Some<number>`, the result is guaranteed to be `number`.\n *\n * @since 2.0.0\n */\nexport const min: {\n (s: Some<number>): number\n (s: Solution<number>): number | undefined\n} = internal.min\n\n/**\n * Returns the largest numeric value in the solution, or `undefined` if empty.\n * When called on a `Some<number>`, the result is guaranteed to be `number`.\n *\n * @since 2.0.0\n */\nexport const max: {\n (s: Some<number>): number\n (s: Solution<number>): number | undefined\n} = internal.max\n\n/**\n * Returns the primary value of the solution (i.e. `s.value`). Throws on\n * `None`, optionally with a caller-provided message.\n *\n * Useful when the type system can't prove non-emptiness but you have a domain\n * reason to assert it — e.g. inverting a polynomial you know to be monotonic\n * without going through the trait refiner first:\n *\n * ```ts\n * const x = CubicPolynomial.solveInverse(p, y).pipe(\n * Solution.unsafeValue('expected a monotonic inverse'),\n * )\n * ```\n *\n * @since 2.0.0\n */\nexport const unsafeValue: {\n <T>(s: Solution<T>, message?: string): T\n (message: string): <T>(s: Solution<T>) => T\n} = ((...args: ReadonlyArray<unknown>) => {\n if (args.length >= 1 && typeof args[0] === 'object' && args[0] !== null) {\n return internal.unsafeValue(args[0] as Solution<unknown>, args[1] as string | undefined)\n }\n const message = args[0] as string\n return <T>(s: Solution<T>) => internal.unsafeValue(s, message)\n}) as never\n\n/**\n * Returns the last value in the solution. Throws if empty.\n *\n * @since 2.0.0\n */\nexport const unsafeLast: <T>(s: Solution<T>) => T = internal.unsafeLast\n\n/**\n * Returns the smallest numeric value in the solution. Throws on empty.\n *\n * @since 2.0.0\n */\nexport const unsafeMin: (s: Solution<number>) => number = internal.unsafeMin\n\n/**\n * Returns the largest numeric value in the solution. Throws on empty.\n *\n * @since 2.0.0\n */\nexport const unsafeMax: (s: Solution<number>) => number = internal.unsafeMax\n\n/**\n * Filters the solution by a predicate. Result cardinality is at most that of\n * the input.\n *\n * @since 2.0.0\n */\nexport const filter: <T>(s: Solution<T>, predicate: (v: T) => boolean) => Solution<T> =\n internal.filter\n\n/**\n * Restricts the solution to values contained within an interval. Endpoint\n * inclusivity follows the interval's `kind` — pass an open variant (e.g.\n * `Interval.makeOpen(0, 1)` or `Interval.unitOpen`) for strict containment.\n *\n * @param s - The solution to clip.\n * @param i - The interval to retain values within.\n * @since 2.0.0\n */\nexport const clip: {\n (i: Interval): (s: Solution<number>) => Solution<number>\n (s: Solution<number>, i: Interval): Solution<number>\n} = internal.clip\n\n/**\n * Maps every value in the solution to a new value. Result cardinality matches\n * the input.\n *\n * @since 2.0.0\n */\nexport const map: {\n <A, B>(s: Solution<A>, f: (v: A) => B): Solution<B>\n <A, B>(f: (v: A) => B): (s: Solution<A>) => Solution<B>\n} = internal.map\n\n// Drops `None` from the union of the input solution type — used by `match` to\n// give `onSome` a tighter parameter type. Distributive: a `Solution.AtMostOne<T>`\n// becomes `One<T>`; a full `Solution<T>` keeps `Some<T>`.\ntype SomeOf<S> = S extends None ? never : S\n\n/**\n * Pattern matches on a solution, calling `onNone` for the empty case and\n * `onSome` for any non-empty case. The `onSome` parameter is typed against\n * the input's narrowed shape — for an `AtMostOne<T>` input, `onSome` receives\n * `One<T>` and can read `.value` directly.\n *\n * @example\n * ```ts\n * const result = polynomial.pipe(\n * LinearPolynomial.solveInverse(0),\n * Solution.match({\n * onNone: () => null,\n * onSome: ({ value }) => Math.abs(value),\n * }),\n * )\n * ```\n *\n * @since 2.0.0\n */\nexport const match: {\n <S extends Solution<unknown>, A, B>(\n self: S,\n matcher: { readonly onNone: () => A; readonly onSome: (s: SomeOf<S>) => B },\n ): A | B\n <S extends Solution<unknown>, A, B>(matcher: {\n readonly onNone: () => A\n readonly onSome: (s: SomeOf<S>) => B\n }): (self: S) => A | B\n} = internal.match as never\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { c as solution_exports } from "../shared/solution-B6KY1E7M.mjs";
1
+ import { c as solution_exports } from "../shared/solution-B2JdOZpe.mjs";
2
2
  export { solution_exports as Solution };
@@ -5,10 +5,10 @@ import { a as make$12, c as subtract, i as magnitude, o as makeWeighted, r as is
5
5
  import { t as make$13 } from "../shared/vector3-CR2LPV03.mjs";
6
6
  import { n as transpose, t as make$14 } from "../shared/vector4-PO_7EYd-.mjs";
7
7
  import { a as vectorProductLeft, i as multiply, t as inverse } from "../shared/matrix4x4-BWmf4lZM.mjs";
8
- import { o as none, s as one } from "../shared/solution-B6KY1E7M.mjs";
9
- import { c as fromPolynomials, n as fromBezierPoints, s as fromCoefficients, x as fromEndpoints } from "../shared/rationalCubic2d-D5g3_hTV.mjs";
10
- import { a as cubicHermite, i as cubicBezier, r as cubicBasisSpline, t as apply } from "../shared/characteristic-Hb7F8SBw.mjs";
11
- import { a as fromArray$13, i as make$15, t as fromArray$12 } from "../shared/rationalCubic2d-MojACId0.mjs";
8
+ import { o as none, s as one } from "../shared/solution-B2JdOZpe.mjs";
9
+ import { S as fromEndpoints, c as fromCoefficients, l as fromPolynomials, r as fromBezierPoints } from "../shared/rationalCubic2d-CeHgpNht.mjs";
10
+ import { a as cubicHermite, i as cubicBezier, r as cubicBasisSpline, t as apply } from "../shared/characteristic-BkEr-rr8.mjs";
11
+ import { a as fromArray$13, i as make$15, t as fromArray$12 } from "../shared/rationalCubic2d-H1J2Fjyy.mjs";
12
12
  //#region src/splines/rationalBezier2d.internal.ts
13
13
  const RationalBezier2dTypeId = Symbol("curvy/splines/rationalBezier2d");
14
14
  var RationalBezier2dImpl = class extends Pipeable {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "curvy",
3
- "version": "2.0.0-alpha.12",
3
+ "version": "2.0.0-alpha.13",
4
4
  "description": "Spline and Curve utilities",
5
5
  "homepage": "https://github.com/tkofh/curvy#readme",
6
6
  "bugs": {
@@ -46,6 +46,10 @@
46
46
  "types": "./dist/interval/index.d.ts",
47
47
  "import": "./dist/interval/index.mjs"
48
48
  },
49
+ "./monotonicity": {
50
+ "types": "./dist/monotonicity/index.d.ts",
51
+ "import": "./dist/monotonicity/index.mjs"
52
+ },
49
53
  "./solution": {
50
54
  "types": "./dist/solution/index.d.ts",
51
55
  "import": "./dist/solution/index.mjs"
@@ -1,3 +0,0 @@
1
- export type Monotonicity = 'none' | 'increasing' | 'decreasing' | 'constant';
2
- export type GuaranteedMonotonicity = 'increasing' | 'decreasing' | 'constant';
3
- export declare function guaranteedMonotonicityFromComparison(s0: number, s1: number): GuaranteedMonotonicity;
@@ -1 +0,0 @@
1
- {"version":3,"file":"cubic-DHJrzZJN.mjs","names":["equals","make","fromVector","fromPoints","solve","toSolver","solveInverse","Solution.none","Solution.one","toInverseSolver","monotonicity","isMonotonic","isIncreasing","isDecreasing","asMonotonic","asIncreasing","asDecreasing","coefficients","derivative","antiderivative","domain","Interval.make","Solution.isNone","range","Interval.fromMinMax","unitRange","length","Interval.size","fromPoints","make","equals","fromVector","solve","toSolver","solveInverse","Linear.solveInverse","Linear.make","Solution.none","Solution.one","Solution.two","toInverseSolver","coefficients","derivative","roots","Solution.match","Vector2.make","monotonicity","Interval.size","Linear.monotonicity","Interval.contains","Interval.toOpen","isMonotonic","isIncreasing","isDecreasing","asMonotonic","asIncreasing","asDecreasing","domain","Interval.fromMinMax","range","Linear.range","unitRange","Interval.unit","length","Linear.length","Linear.solve","curvature","make","isCubicPolynomial","equals","fromVector","fromPoints","solve","toSolver","solveInverse","Quadratic.solveInverse","Quadratic.make","Solution.fromArray","toInverseSolver","coefficients","derivative","subdivide","roots","extrema","Quadratic.roots","monotonicity","Interval.size","Linear.monotonicity","Linear.make","Quadratic.monotonicity","Interval.filter","Interval.toOpen","isMonotonic","isIncreasing","isDecreasing","asMonotonic","asIncreasing","asDecreasing","domain","Interval.fromMinMax","range","unitRange","Interval.unit","length","Linear.length","Quadratic.length","Interval.scaleShift","Interval.biunit","Quadratic.solve","curvature","Quadratic.derivative","Linear.solve","internal.isCubicPolynomial","internal.equals","internal.make","internal.fromVector","internal.fromPoints","internal.solve","internal.toSolver","internal.solveInverse","internal.toInverseSolver","internal.coefficients","internal.derivative","internal.subdivide","internal.roots","internal.extrema","internal.monotonicity","internal.isMonotonic","internal.isIncreasing","internal.isDecreasing","internal.asMonotonic","internal.asIncreasing","internal.asDecreasing","internal.domain","internal.range","internal.unitRange","internal.length","internal.curvature"],"sources":["../../src/polynomial/quadratic.internal.circular.ts","../../src/polynomial/linear.internal.ts","../../src/polynomial/cubic.internal.circular.ts","../../src/polynomial/monotonicity.ts","../../src/polynomial/quadratic.internal.ts","../../src/length.ts","../../src/polynomial/cubic.internal.ts","../../src/polynomial/cubic.ts"],"sourcesContent":["import { Pipeable } from '../utils.ts'\nimport type { QuadraticPolynomial } from './quadratic.ts'\nimport { PolynomialTraits } from './traits.ts'\n\nexport const QuadraticPolynomialTypeId: unique symbol = Symbol.for('curvy/polynomial/quadratic')\nexport type QuadraticPolynomialTypeId = typeof QuadraticPolynomialTypeId\n\n/** @internal */\nexport class QuadraticPolynomialImpl extends Pipeable implements QuadraticPolynomial<unknown> {\n readonly [QuadraticPolynomialTypeId]: QuadraticPolynomialTypeId = QuadraticPolynomialTypeId\n declare readonly [PolynomialTraits]: unknown\n\n readonly c0: number\n readonly c1: number\n readonly c2: number\n\n constructor(c0 = 0, c1 = 0, c2 = 0) {\n super()\n\n this.c0 = c0\n this.c1 = c1\n this.c2 = c2\n }\n}\n","import * as Interval from '../interval/interval.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport * as Solution from '../solution/solution.ts'\nimport { invariant } from '../utils.ts'\nimport { epsEquals } from '../number.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { LinearPolynomial } from './linear.ts'\nimport type { Decreasing, Increasing, Monotonic } from './traits.ts'\nimport { PolynomialTraits } from './traits.ts'\nimport type { QuadraticPolynomial } from './quadratic.ts'\nimport { QuadraticPolynomialImpl } from './quadratic.internal.circular.ts'\n\nexport const LinearPolynomialTypeId: unique symbol = Symbol.for('curvy/linear')\nexport type LinearPolynomialTypeId = typeof LinearPolynomialTypeId\n\nclass LinearPolynomialImpl extends Pipeable implements LinearPolynomial<unknown> {\n readonly [LinearPolynomialTypeId]: LinearPolynomialTypeId = LinearPolynomialTypeId\n declare readonly [PolynomialTraits]: unknown\n\n readonly c0: number\n readonly c1: number\n\n constructor(c0 = 0, c1 = 0) {\n super()\n\n this.c0 = c0\n this.c1 = c1\n }\n}\n\n/** @internal */\nexport const isLinearPolynomial = (v: unknown): v is LinearPolynomial =>\n typeof v === 'object' && v !== null && LinearPolynomialTypeId in v\n\n/** @internal */\nexport const equals = dual<\n (b: LinearPolynomial) => (a: LinearPolynomial) => boolean,\n (a: LinearPolynomial, b: LinearPolynomial) => boolean\n>(2, (a: LinearPolynomial, b: LinearPolynomial) => epsEquals(a.c0, b.c0) && epsEquals(a.c1, b.c1))\n\n/** @internal */\nexport const make = (c0 = 0, c1 = 0): LinearPolynomial => new LinearPolynomialImpl(c0, c1)\n\n/** @internal */\nexport const fromVector = (v: Vector2) => new LinearPolynomialImpl(v.x, v.y)\n\n/** @internal */\nexport const fromPointSlope = (p: Vector2, slope: number) =>\n new LinearPolynomialImpl(p.y - slope * p.x, slope)\n\n/** @internal */\nexport const fromPoints = (p1: Vector2, p2: Vector2) =>\n fromPointSlope(p1, (p2.y - p1.y) / (p2.x - p1.x))\n\n/** @internal */\nexport const solve = dual<\n (x: number) => (p: LinearPolynomial) => number,\n (p: LinearPolynomial, x: number) => number\n>(2, (p: LinearPolynomial, x: number) => p.c0 + x * p.c1)\n\n/** @internal */\nexport const toSolver = (p: LinearPolynomial) => (x: number) => solve(p, x)\n\n/** @internal */\nexport const solveInverse = dual<\n (y: number) => (p: LinearPolynomial) => Solution.AtMostOne<number>,\n (p: LinearPolynomial, y: number) => Solution.AtMostOne<number>\n>(2, (p: LinearPolynomial, y: number) => {\n if (p.c1 === 0) {\n return Solution.none\n }\n return Solution.one((y - p.c0) / p.c1)\n})\n\n/** @internal */\nexport const toInverseSolver = (p: LinearPolynomial) => (y: number) => solveInverse(p, y)\n\n/** @internal */\nexport const monotonicity = (p: LinearPolynomial) =>\n p.c1 === 0 ? 'constant' : p.c1 > 0 ? 'increasing' : 'decreasing'\n\n/** @internal */\nexport const isMonotonic = <T>(p: LinearPolynomial<T>): p is LinearPolynomial<T & Monotonic> =>\n p.c1 !== 0\n\n/** @internal */\nexport const isIncreasing = <T>(p: LinearPolynomial<T>): p is LinearPolynomial<T & Increasing> =>\n p.c1 > 0\n\n/** @internal */\nexport const isDecreasing = <T>(p: LinearPolynomial<T>): p is LinearPolynomial<T & Decreasing> =>\n p.c1 < 0\n\n/** @internal */\nexport const asMonotonic = <T>(p: LinearPolynomial<T>): LinearPolynomial<T & Monotonic> => {\n invariant(isMonotonic(p), 'linear polynomial is not monotonic')\n return p\n}\n\n/** @internal */\nexport const asIncreasing = <T>(p: LinearPolynomial<T>): LinearPolynomial<T & Increasing> => {\n invariant(isIncreasing(p), 'linear polynomial is not increasing')\n return p\n}\n\n/** @internal */\nexport const asDecreasing = <T>(p: LinearPolynomial<T>): LinearPolynomial<T & Decreasing> => {\n invariant(isDecreasing(p), 'linear polynomial is not decreasing')\n return p\n}\n\n/** @internal */\nexport const coefficients = (p: LinearPolynomial): readonly [number, number] => [p.c0, p.c1]\n\n/** @internal */\nexport const derivative = (p: LinearPolynomial) => p.c1\n\n/** @internal */\nexport const antiderivative = dual<\n (integrationConstant: number) => (p: LinearPolynomial) => QuadraticPolynomial,\n (p: LinearPolynomial, integrationConstant?: number) => QuadraticPolynomial\n>(\n (args) => isLinearPolynomial(args[0]),\n (p: LinearPolynomial, integrationConstant = 0) =>\n new QuadraticPolynomialImpl(integrationConstant, p.c0, p.c1 / 2),\n)\n\n/** @internal */\nexport const domain = dual<\n (range: Interval.Interval) => (p: LinearPolynomial) => Solution.AtMostOne<Interval.Interval>,\n (p: LinearPolynomial, range: Interval.Interval) => Solution.AtMostOne<Interval.Interval>\n>(2, (p: LinearPolynomial, r: Interval.Interval) => {\n if (p.c1 === 0) {\n if (r.start === p.c0 && r.end === p.c0) {\n return Solution.one(Interval.make(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY))\n }\n return Solution.none\n }\n\n const start = solveInverse(p, r.start)\n const end = solveInverse(p, r.end)\n\n if (Solution.isNone(start) || Solution.isNone(end)) {\n return Solution.none\n }\n\n return Solution.one(Interval.make(start.value, end.value))\n})\n\n/** @internal */\nexport const range = dual<\n (domain: Interval.Interval) => (p: LinearPolynomial) => Interval.Closed,\n (p: LinearPolynomial, domain: Interval.Interval) => Interval.Closed\n>(2, (p: LinearPolynomial, d: Interval.Interval) =>\n Interval.fromMinMax(solve(p, d.start), solve(p, d.end)),\n)\n\n/** @internal */\nexport const unitRange = (p: LinearPolynomial): Interval.Closed =>\n Interval.fromMinMax(p.c0, p.c0 + p.c1)\n\n/** @internal */\nexport const length = dual<\n (domain: Interval.Interval) => (p: LinearPolynomial) => number,\n (p: LinearPolynomial, domain: Interval.Interval) => number\n>(2, (p: LinearPolynomial, d: Interval.Interval) => {\n if (Interval.size(d) === 0) {\n return 0\n }\n\n if (p.c1 === 0) {\n return Interval.size(d)\n }\n\n return Math.sqrt(1 + p.c1 ** 2) * Interval.size(d)\n})\n","import { Pipeable } from '../utils.ts'\nimport type { CubicPolynomial } from './cubic.ts'\nimport { PolynomialTraits } from './traits.ts'\n\nexport const CubicPolynomialTypeId: unique symbol = Symbol.for('curvy/polynomial/cubic')\nexport type CubicPolynomialTypeId = typeof CubicPolynomialTypeId\n\n/** @internal */\nexport class CubicPolynomialImpl extends Pipeable implements CubicPolynomial<unknown> {\n readonly [CubicPolynomialTypeId]: CubicPolynomialTypeId = CubicPolynomialTypeId\n declare readonly [PolynomialTraits]: unknown\n\n readonly c0: number\n readonly c1: number\n readonly c2: number\n readonly c3: number\n\n constructor(c0 = 0, c1 = 0, c2 = 0, c3 = 0) {\n super()\n\n this.c0 = c0\n this.c1 = c1\n this.c2 = c2\n this.c3 = c3\n }\n}\n","export type Monotonicity = 'none' | 'increasing' | 'decreasing' | 'constant'\nexport type GuaranteedMonotonicity = 'increasing' | 'decreasing' | 'constant'\n\nexport function guaranteedMonotonicityFromComparison(\n s0: number,\n s1: number,\n): GuaranteedMonotonicity {\n if (s0 < s1) {\n return 'increasing'\n }\n\n if (s0 > s1) {\n return 'decreasing'\n }\n\n return 'constant'\n}\n","import * as Interval from '../interval/interval.ts'\nimport { dual } from '../utils.ts'\nimport * as Solution from '../solution/solution.ts'\nimport { invariant } from '../utils.ts'\nimport { epsEquals } from '../number.ts'\nimport * as Vector2 from '../vector/vector2.ts'\nimport type { Vector3 } from '../vector/vector3.ts'\nimport type { CubicPolynomial } from './cubic.ts'\nimport { CubicPolynomialImpl } from './cubic.internal.circular.ts'\nimport * as Linear from './linear.internal.ts'\nimport { guaranteedMonotonicityFromComparison, type Monotonicity } from './monotonicity.ts'\nimport type { QuadraticPolynomial } from './quadratic.ts'\nimport {\n QuadraticPolynomialImpl,\n QuadraticPolynomialTypeId,\n} from './quadratic.internal.circular.ts'\nimport type { Decreasing, Increasing, Monotonic } from './traits.ts'\n\n/** @internal */\nexport const fromPoints = (\n p0: Vector2.Vector2,\n p1: Vector2.Vector2,\n p2: Vector2.Vector2,\n): QuadraticPolynomial => {\n // Newton's divided differences, then collected to monomial form.\n const f01 = (p1.y - p0.y) / (p1.x - p0.x)\n const f12 = (p2.y - p1.y) / (p2.x - p1.x)\n const f012 = (f12 - f01) / (p2.x - p0.x)\n\n return new QuadraticPolynomialImpl(\n p0.y - f01 * p0.x + f012 * p0.x * p1.x,\n f01 - f012 * (p0.x + p1.x),\n f012,\n )\n}\n\n/** @internal */\nexport const make = (c0 = 0, c1 = 0, c2 = 0): QuadraticPolynomial =>\n new QuadraticPolynomialImpl(c0, c1, c2)\n\n/** @internal */\nexport const isQuadraticPolynomial = (v: unknown): v is QuadraticPolynomial =>\n typeof v === 'object' && v !== null && QuadraticPolynomialTypeId in v\n\n/** @internal */\nexport const equals = dual<\n (b: QuadraticPolynomial) => (a: QuadraticPolynomial) => boolean,\n (a: QuadraticPolynomial, b: QuadraticPolynomial) => boolean\n>(\n 2,\n (a: QuadraticPolynomial, b: QuadraticPolynomial) =>\n epsEquals(a.c0, b.c0) && epsEquals(a.c1, b.c1) && epsEquals(a.c2, b.c2),\n)\n\n/** @internal */\nexport const fromVector = (v: Vector3) => new QuadraticPolynomialImpl(v.x, v.y, v.z)\n\n/** @internal */\nexport const solve = dual<\n (x: number) => (p: QuadraticPolynomial) => number,\n (p: QuadraticPolynomial, x: number) => number\n>(2, (p: QuadraticPolynomial, x: number) => p.c0 + x * p.c1 + x ** 2 * p.c2)\n\n/** @internal */\nexport const toSolver = (p: QuadraticPolynomial) => (x: number) => solve(p, x)\n\n/** @internal */\nexport const solveInverse: {\n (p: QuadraticPolynomial, y: number): Solution.AtMostTwo<number>\n (y: number): (p: QuadraticPolynomial) => Solution.AtMostTwo<number>\n} = dual<\n (y: number) => (p: QuadraticPolynomial) => Solution.AtMostTwo<number>,\n (p: QuadraticPolynomial, y: number) => Solution.AtMostTwo<number>\n>(2, (p: QuadraticPolynomial, y: number) => {\n // c2 = 0: the polynomial is actually linear in disguise. Defer rather than\n // dividing by zero in the quadratic formula.\n if (p.c2 === 0) {\n return Linear.solveInverse(Linear.make(p.c0, p.c1), y)\n }\n\n const discriminant = p.c1 ** 2 - 4 * p.c2 * (p.c0 - y)\n\n if (discriminant < 0) {\n return Solution.none\n }\n\n if (discriminant === 0) {\n return Solution.one(-p.c1 / (2 * p.c2))\n }\n\n const sqrtDiscriminant = Math.sqrt(discriminant)\n const a = (-p.c1 + sqrtDiscriminant) / (2 * p.c2)\n const b = (-p.c1 - sqrtDiscriminant) / (2 * p.c2)\n return a < b ? Solution.two(a, b) : Solution.two(b, a)\n})\n\n/** @internal */\nexport const toInverseSolver =\n (p: QuadraticPolynomial) =>\n (y: number): Solution.AtMostTwo<number> =>\n solveInverse(p, y)\n\n/** @internal */\nexport const coefficients = (p: QuadraticPolynomial): readonly [number, number, number] => [\n p.c0,\n p.c1,\n p.c2,\n]\n\n/** @internal */\nexport const derivative = (p: QuadraticPolynomial) => Linear.make(p.c1, p.c2 * 2)\n\n/** @internal */\nexport const roots = (p: QuadraticPolynomial) => solveInverse(p, 0)\n\n/** @internal */\nexport const extreme = (p: QuadraticPolynomial) =>\n derivative(p).pipe(\n Linear.solveInverse(0),\n Solution.match({\n onNone: () => null,\n onSome: ({ value: t }) => Vector2.make(t, solve(p, t)),\n }),\n )\n\n/** @internal */\nexport const monotonicity = dual<\n (i: Interval.Interval) => (p: QuadraticPolynomial) => Monotonicity,\n (p: QuadraticPolynomial, i?: Interval.Interval) => Monotonicity\n>(\n (args) => isQuadraticPolynomial(args[0]),\n (p: QuadraticPolynomial, i?: Interval.Interval) => {\n invariant(\n i === undefined || Interval.size(i) > 0,\n 'monotonicity is undefined over a zero-width interval',\n )\n\n if (p.c2 === 0 && p.c1 === 0) {\n return 'constant'\n }\n\n if (p.c2 === 0) {\n return Linear.monotonicity(Linear.make(p.c0, p.c1))\n }\n\n // c2 is non-zero, so the extreme is guaranteed to be non-null\n const e = extreme(p) as Vector2.Vector2\n\n // if there is no interval, or the extreme is within the interval,\n // the monotonicity is none\n if (i === undefined || Interval.contains(Interval.toOpen(i), e.x)) {\n return 'none'\n }\n\n return guaranteedMonotonicityFromComparison(solve(p, i.start), solve(p, i.end))\n },\n)\n\n/** @internal */\nexport const isMonotonic = dual<\n (\n i: Interval.Interval,\n ) => <T>(p: QuadraticPolynomial<T>) => p is QuadraticPolynomial<T & Monotonic>,\n <T>(p: QuadraticPolynomial<T>, i?: Interval.Interval) => p is QuadraticPolynomial<T & Monotonic>\n>((args) => isQuadraticPolynomial(args[0]), ((p: QuadraticPolynomial, i?: Interval.Interval) => {\n const m = monotonicity(p, i as Interval.Interval)\n return m === 'increasing' || m === 'decreasing'\n}) as never)\n\n/** @internal */\nexport const isIncreasing = dual<\n (\n i: Interval.Interval,\n ) => <T>(p: QuadraticPolynomial<T>) => p is QuadraticPolynomial<T & Increasing>,\n <T>(p: QuadraticPolynomial<T>, i?: Interval.Interval) => p is QuadraticPolynomial<T & Increasing>\n>(\n (args) => isQuadraticPolynomial(args[0]),\n ((p: QuadraticPolynomial, i?: Interval.Interval) =>\n monotonicity(p, i as Interval.Interval) === 'increasing') as never,\n)\n\n/** @internal */\nexport const isDecreasing = dual<\n (\n i: Interval.Interval,\n ) => <T>(p: QuadraticPolynomial<T>) => p is QuadraticPolynomial<T & Decreasing>,\n <T>(p: QuadraticPolynomial<T>, i?: Interval.Interval) => p is QuadraticPolynomial<T & Decreasing>\n>(\n (args) => isQuadraticPolynomial(args[0]),\n ((p: QuadraticPolynomial, i?: Interval.Interval) =>\n monotonicity(p, i as Interval.Interval) === 'decreasing') as never,\n)\n\n/** @internal */\nexport const asMonotonic = <T>(\n p: QuadraticPolynomial<T>,\n i?: Interval.Interval,\n): QuadraticPolynomial<T & Monotonic> => {\n invariant(isMonotonic(p, i as Interval.Interval), 'quadratic polynomial is not monotonic')\n return p\n}\n\n/** @internal */\nexport const asIncreasing = <T>(\n p: QuadraticPolynomial<T>,\n i?: Interval.Interval,\n): QuadraticPolynomial<T & Increasing> => {\n invariant(isIncreasing(p, i as Interval.Interval), 'quadratic polynomial is not increasing')\n return p\n}\n\n/** @internal */\nexport const asDecreasing = <T>(\n p: QuadraticPolynomial<T>,\n i?: Interval.Interval,\n): QuadraticPolynomial<T & Decreasing> => {\n invariant(isDecreasing(p, i as Interval.Interval), 'quadratic polynomial is not decreasing')\n return p\n}\n\n/** @internal */\nexport const antiderivative = dual<\n (integrationConstant: number) => (p: QuadraticPolynomial) => CubicPolynomial,\n (p: QuadraticPolynomial, integrationConstant?: number) => CubicPolynomial\n>(\n 2,\n (p: QuadraticPolynomial, integrationConstant = 0) =>\n new CubicPolynomialImpl(integrationConstant, p.c0, p.c1 / 2, p.c2 / 3),\n)\n\n/** @internal */\nexport const domain = dual<\n (range: Interval.Interval) => (p: QuadraticPolynomial) => Solution.AtMostOne<Interval.Interval>,\n (p: QuadraticPolynomial, range: Interval.Interval) => Solution.AtMostOne<Interval.Interval>\n>(2, (p: QuadraticPolynomial, r: Interval.Interval) => {\n const start = solveInverse(p, r.start)\n const end = solveInverse(p, r.end)\n\n if (start.length === 0 && end.length === 0) {\n return Solution.none\n }\n\n return Solution.one(Interval.fromMinMax(...start, ...end))\n})\n\n/** @internal */\nexport const range = dual<\n (domain: Interval.Interval) => (p: QuadraticPolynomial) => Interval.Closed,\n (p: QuadraticPolynomial, domain: Interval.Interval) => Interval.Closed\n>(2, (p: QuadraticPolynomial, d: Interval.Interval) => {\n if (p.c2 === 0) {\n return Linear.range(Linear.make(p.c0, p.c1), d)\n }\n\n const e = extreme(p)\n\n return e !== null && Interval.contains(d, e.x)\n ? Interval.fromMinMax(solve(p, d.start), solve(p, d.end), e.y)\n : Interval.fromMinMax(solve(p, d.start), solve(p, d.end))\n})\n\n/** @internal */\nexport const unitRange = (p: QuadraticPolynomial): Interval.Closed => range(p, Interval.unit)\n\n/** @internal */\nexport const length = dual<\n (domain: Interval.Interval) => (p: QuadraticPolynomial) => number,\n (p: QuadraticPolynomial, domain: Interval.Interval) => number\n>(2, (p: QuadraticPolynomial, dom: Interval.Interval) => {\n if (Interval.size(dom) === 0) {\n return 0\n }\n\n if (p.c2 === 0) {\n return Linear.length(Linear.make(p.c0, p.c1), dom)\n }\n\n const dp = derivative(p)\n\n const derivativeStart = Linear.solve(dp, dom.start)\n const sqrtStart = Math.sqrt(1 + derivativeStart ** 2)\n const evalStart =\n (derivativeStart * sqrtStart + Math.log(Math.abs(derivativeStart + sqrtStart))) / (4 * p.c2)\n\n const derivativeEnd = Linear.solve(dp, dom.end)\n const sqrtEnd = Math.sqrt(1 + derivativeEnd ** 2)\n const evalEnd =\n (derivativeEnd * sqrtEnd + Math.log(Math.abs(derivativeEnd + sqrtEnd))) / (4 * p.c2)\n\n return evalEnd - evalStart\n})\n\n/** @internal */\nexport const curvature = dual<\n (x: number) => (p: QuadraticPolynomial) => number,\n (p: QuadraticPolynomial, x: number) => number\n>(\n 2,\n (p: QuadraticPolynomial, x: number) =>\n Math.abs(2 * p.c2) / (1 + (Linear.solve(derivative(p), x) ** 2) ** 1.5),\n)\n","export const GL32_X0 = 0.9972638618494816\nexport const GL32_X1 = 0.9856115115452684\nexport const GL32_X2 = 0.9647622555875064\nexport const GL32_X3 = 0.9349060759377397\nexport const GL32_X4 = 0.8963211557660521\nexport const GL32_X5 = 0.84936761373257\nexport const GL32_X6 = 0.7944837959679424\nexport const GL32_X7 = 0.7321821187402897\nexport const GL32_X8 = 0.6630442669302152\nexport const GL32_X9 = 0.5877157572407623\nexport const GL32_X10 = 0.5068999089322294\nexport const GL32_X11 = 0.42135127613063533\nexport const GL32_X12 = 0.33186860228212767\nexport const GL32_X13 = 0.23928736225213706\nexport const GL32_X14 = 0.1444719615827965\nexport const GL32_X15 = 0.04830766568773831\nexport const GL32_W0 = 0.007018610009470136\nexport const GL32_W1 = 0.01627439473090571\nexport const GL32_W2 = 0.02539206530926214\nexport const GL32_W3 = 0.03427386291302141\nexport const GL32_W4 = 0.042835898022226704\nexport const GL32_W5 = 0.050998059262376154\nexport const GL32_W6 = 0.05868409347853558\nexport const GL32_W7 = 0.06582222277636195\nexport const GL32_W8 = 0.07234579410884862\nexport const GL32_W9 = 0.07819389578707044\nexport const GL32_W10 = 0.08331192422694672\nexport const GL32_W11 = 0.08765209300440374\nexport const GL32_W12 = 0.0911738786957639\nexport const GL32_W13 = 0.09384439908080454\nexport const GL32_W14 = 0.09563872007927485\nexport const GL32_W15 = 0.09654008851472785\n","import * as Interval from '../interval/interval.ts'\nimport {\n GL32_W0,\n GL32_W1,\n GL32_W2,\n GL32_W3,\n GL32_W4,\n GL32_W5,\n GL32_W6,\n GL32_W7,\n GL32_W8,\n GL32_W9,\n GL32_W10,\n GL32_W11,\n GL32_W12,\n GL32_W13,\n GL32_W14,\n GL32_W15,\n GL32_X0,\n GL32_X1,\n GL32_X2,\n GL32_X3,\n GL32_X4,\n GL32_X5,\n GL32_X6,\n GL32_X7,\n GL32_X8,\n GL32_X9,\n GL32_X10,\n GL32_X11,\n GL32_X12,\n GL32_X13,\n GL32_X14,\n GL32_X15,\n} from '../length.ts'\nimport { dual } from '../utils.ts'\nimport * as Solution from '../solution/solution.ts'\nimport { invariant } from '../utils.ts'\nimport { clampToZero, epsEquals } from '../number.ts'\nimport type * as Vector2 from '../vector/vector2.ts'\nimport type { Vector4 } from '../vector/vector4.ts'\nimport type { CubicPolynomial } from './cubic.ts'\nimport { CubicPolynomialImpl, CubicPolynomialTypeId } from './cubic.internal.circular.ts'\nimport type { Decreasing, Increasing, Monotonic } from './traits.ts'\nimport * as Linear from './linear.internal.ts'\nimport { guaranteedMonotonicityFromComparison, type Monotonicity } from './monotonicity.ts'\nimport * as Quadratic from './quadratic.internal.ts'\n\n/** @internal */\nexport const make = (c0 = 0, c1 = 0, c2 = 0, c3 = 0): CubicPolynomial =>\n new CubicPolynomialImpl(c0, c1, c2, c3)\n\n/** @internal */\nexport const isCubicPolynomial = (v: unknown): v is CubicPolynomial =>\n typeof v === 'object' && v !== null && CubicPolynomialTypeId in v\n\n/** @internal */\nexport const equals = dual<\n (b: CubicPolynomial) => (a: CubicPolynomial) => boolean,\n (a: CubicPolynomial, b: CubicPolynomial) => boolean\n>(\n 2,\n (a: CubicPolynomial, b: CubicPolynomial) =>\n epsEquals(a.c0, b.c0) &&\n epsEquals(a.c1, b.c1) &&\n epsEquals(a.c2, b.c2) &&\n epsEquals(a.c3, b.c3),\n)\n\n/** @internal */\nexport const fromVector = (v: Vector4) => new CubicPolynomialImpl(v.x, v.y, v.z, v.w)\n\n/** @internal */\nexport const fromPoints = (\n p0: Vector2.Vector2,\n p1: Vector2.Vector2,\n p2: Vector2.Vector2,\n p3: Vector2.Vector2,\n): CubicPolynomial => {\n // Newton's divided differences, then collected to monomial form.\n const f01 = (p1.y - p0.y) / (p1.x - p0.x)\n const f12 = (p2.y - p1.y) / (p2.x - p1.x)\n const f23 = (p3.y - p2.y) / (p3.x - p2.x)\n const f012 = (f12 - f01) / (p2.x - p0.x)\n const f123 = (f23 - f12) / (p3.x - p1.x)\n const f0123 = (f123 - f012) / (p3.x - p0.x)\n\n return new CubicPolynomialImpl(\n p0.y - f01 * p0.x + f012 * p0.x * p1.x - f0123 * p0.x * p1.x * p2.x,\n f01 - f012 * (p0.x + p1.x) + f0123 * (p0.x * p1.x + p0.x * p2.x + p1.x * p2.x),\n f012 - f0123 * (p0.x + p1.x + p2.x),\n f0123,\n )\n}\n\n/** @internal */\nexport const solve = dual<\n (x: number) => (p: CubicPolynomial) => number,\n (p: CubicPolynomial, x: number) => number\n>(2, (p: CubicPolynomial, x: number) => p.c0 + x * p.c1 + x ** 2 * p.c2 + x ** 3 * p.c3)\n\n/** @internal */\nexport const toSolver = (p: CubicPolynomial) => (x: number) => solve(p, x)\n\n/** @internal */\nexport const solveInverse = dual<\n (y: number) => (p: CubicPolynomial) => Solution.AtMostThree<number>,\n (p: CubicPolynomial, y: number) => Solution.AtMostThree<number>\n>(2, (self: CubicPolynomial, y: number) => {\n // c3 = 0: the polynomial is actually quadratic-or-less in disguise. Defer to\n // the quadratic solver (which itself handles c2 = 0 by deferring to linear).\n if (self.c3 === 0) {\n return Quadratic.solveInverse(Quadratic.make(self.c0, self.c1, self.c2), y)\n }\n\n const shift = self.c2 / (3 * self.c3)\n\n const d0 = self.c2 ** 2 - 3 * self.c3 * self.c1\n const d1 = 2 * self.c2 ** 3 - 9 * self.c3 * self.c2 * self.c1 + 27 * self.c3 ** 2 * (self.c0 - y)\n\n const p = -d0 / (3 * self.c3 ** 2)\n const q = d1 / (27 * self.c3 ** 3)\n\n const discriminant = clampToZero(-(4 * p ** 3 + 27 * q ** 2), 1e-12)\n\n const roots = new Set<number>()\n\n if (discriminant > 0) {\n const r = 2 * Math.sqrt(-p / 3)\n const theta = Math.acos(((3 * q) / (2 * p)) * Math.sqrt(-3 / p)) / 3\n const offset = (2 * Math.PI) / 3\n\n roots.add(r * Math.cos(theta + offset) - shift)\n roots.add(r * Math.cos(theta) - shift)\n roots.add(r * Math.cos(theta - offset) - shift)\n } else if (discriminant < 0) {\n const u = Math.sqrt(q ** 2 / 4 + p ** 3 / 27)\n\n const u1 = Math.cbrt(-q / 2 + u)\n const u2 = Math.cbrt(-q / 2 - u)\n\n roots.add(u1 + u2 - shift)\n } else if (d0 === 0) {\n roots.add(-shift)\n } else {\n roots.add((9 * self.c3 * (self.c0 - y) - self.c2 * self.c1) / (2 * d0))\n roots.add(\n (4 * self.c3 * self.c2 * self.c1 - 9 * self.c3 ** 2 * (self.c0 - y) - self.c2 ** 3) /\n (self.c3 * d0),\n )\n }\n\n return Solution.fromArray(Array.from(roots).toSorted((a, b) => a - b))\n})\n\n/** @internal */\nexport const toInverseSolver = (p: CubicPolynomial) => (y: number) => solveInverse(p, y)\n\n/** @internal */\nexport const coefficients = (p: CubicPolynomial): readonly [number, number, number, number] => [\n p.c0,\n p.c1,\n p.c2,\n p.c3,\n]\n\n/** @internal */\nexport const derivative = (p: CubicPolynomial) => Quadratic.make(p.c1, p.c2 * 2, p.c3 * 3)\n\n// Subdivides a cubic polynomial at parameter `t ∈ (0, 1)` into two new cubic\n// polynomials. The first polynomial's evaluation on `[0, 1]` matches the\n// original's evaluation on `[0, t]`; the second matches the original's\n// evaluation on `[t, 1]`. Concretely: `left(u) = p(t·u)` and\n// `right(u) = p(t + (1-t)·u)`. The left half is a uniform scale of the input\n// parameter by powers of `t`; the right half is a binomial expansion in\n// `(s + r·u)` with `s = t` and `r = 1 - t`.\n/** @internal */\nexport const subdivide = dual<\n (t: number) => (p: CubicPolynomial) => [CubicPolynomial, CubicPolynomial],\n (p: CubicPolynomial, t: number) => [CubicPolynomial, CubicPolynomial]\n>(2, (p: CubicPolynomial, t: number): [CubicPolynomial, CubicPolynomial] => {\n invariant(t > 0 && t < 1, 'subdivide parameter t must be in the open interval (0, 1)')\n\n const r = 1 - t\n const left = make(p.c0, p.c1 * t, p.c2 * t * t, p.c3 * t * t * t)\n const right = make(\n p.c0 + p.c1 * t + p.c2 * t * t + p.c3 * t * t * t,\n p.c1 * r + 2 * p.c2 * t * r + 3 * p.c3 * t * t * r,\n p.c2 * r * r + 3 * p.c3 * t * r * r,\n p.c3 * r * r * r,\n )\n return [left, right]\n})\n\n/** @internal */\nexport const roots = (p: CubicPolynomial): Solution.AtMostThree<number> => solveInverse(p, 0)\n\n/** @internal */\nexport const extrema = (p: CubicPolynomial): Solution.AtMostTwo<number> =>\n Quadratic.roots(derivative(p))\n\n/** @internal */\nexport const monotonicity = dual<\n (i: Interval.Interval) => (p: CubicPolynomial) => Monotonicity,\n (p: CubicPolynomial, i?: Interval.Interval) => Monotonicity\n>(\n (args) => isCubicPolynomial(args[0]),\n (p: CubicPolynomial, i?: Interval.Interval) => {\n invariant(\n i === undefined || Interval.size(i) > 0,\n 'monotonicity is undefined over a zero-width interval',\n )\n\n // shortcut to check for a horizontal line\n if (p.c3 === 0 && p.c2 === 0 && p.c1 === 0) {\n return 'constant'\n }\n\n // shortcut to check for a non-horizontal line\n if (p.c3 === 0 && p.c2 === 0) {\n return Linear.monotonicity(Linear.make(p.c0, p.c1))\n }\n\n // without an interval, the monotonicity will be none if c3 or c2 are nonzero\n if (i === undefined) {\n return 'none'\n }\n\n if (p.c3 === 0) {\n return Quadratic.monotonicity(Quadratic.make(p.c0, p.c1, p.c2), i)\n }\n\n const e = Interval.filter(Interval.toOpen(i), [...extrema(p)])\n\n if (e.length > 0) {\n return 'none'\n }\n\n return guaranteedMonotonicityFromComparison(solve(p, i.start), solve(p, i.end))\n },\n)\n\n/** @internal */\nexport const isMonotonic = dual<\n (i: Interval.Interval) => <T>(p: CubicPolynomial<T>) => p is CubicPolynomial<T & Monotonic>,\n <T>(p: CubicPolynomial<T>, i?: Interval.Interval) => p is CubicPolynomial<T & Monotonic>\n>((args) => isCubicPolynomial(args[0]), ((p: CubicPolynomial, i?: Interval.Interval) => {\n const m = monotonicity(p, i as Interval.Interval)\n return m === 'increasing' || m === 'decreasing'\n}) as never)\n\n/** @internal */\nexport const isIncreasing = dual<\n (i: Interval.Interval) => <T>(p: CubicPolynomial<T>) => p is CubicPolynomial<T & Increasing>,\n <T>(p: CubicPolynomial<T>, i?: Interval.Interval) => p is CubicPolynomial<T & Increasing>\n>(\n (args) => isCubicPolynomial(args[0]),\n ((p: CubicPolynomial, i?: Interval.Interval) =>\n monotonicity(p, i as Interval.Interval) === 'increasing') as never,\n)\n\n/** @internal */\nexport const isDecreasing = dual<\n (i: Interval.Interval) => <T>(p: CubicPolynomial<T>) => p is CubicPolynomial<T & Decreasing>,\n <T>(p: CubicPolynomial<T>, i?: Interval.Interval) => p is CubicPolynomial<T & Decreasing>\n>(\n (args) => isCubicPolynomial(args[0]),\n ((p: CubicPolynomial, i?: Interval.Interval) =>\n monotonicity(p, i as Interval.Interval) === 'decreasing') as never,\n)\n\n/** @internal */\nexport const asMonotonic = <T>(\n p: CubicPolynomial<T>,\n i?: Interval.Interval,\n): CubicPolynomial<T & Monotonic> => {\n invariant(isMonotonic(p, i as Interval.Interval), 'cubic polynomial is not monotonic')\n return p\n}\n\n/** @internal */\nexport const asIncreasing = <T>(\n p: CubicPolynomial<T>,\n i?: Interval.Interval,\n): CubicPolynomial<T & Increasing> => {\n invariant(isIncreasing(p, i as Interval.Interval), 'cubic polynomial is not increasing')\n return p\n}\n\n/** @internal */\nexport const asDecreasing = <T>(\n p: CubicPolynomial<T>,\n i?: Interval.Interval,\n): CubicPolynomial<T & Decreasing> => {\n invariant(isDecreasing(p, i as Interval.Interval), 'cubic polynomial is not decreasing')\n return p\n}\n\n/** @internal */\nexport const domain = dual<\n (range: Interval.Interval) => (p: CubicPolynomial) => Interval.Interval,\n (p: CubicPolynomial, range: Interval.Interval) => Interval.Interval\n>(2, (p: CubicPolynomial, r: Interval.Interval) =>\n Interval.fromMinMax(...solveInverse(p, r.start), ...solveInverse(p, r.end)),\n)\n\n/** @internal */\nexport const range = dual<\n (domain: Interval.Interval) => (p: CubicPolynomial) => Interval.Closed,\n (p: CubicPolynomial, domain: Interval.Interval) => Interval.Closed\n>(2, (p: CubicPolynomial, d: Interval.Interval) =>\n Interval.fromMinMax(\n solve(p, d.start),\n solve(p, d.end),\n ...Interval.filter(d, [...extrema(p)]).map((e) => solve(p, e)),\n ),\n)\n\n/** @internal */\nexport const unitRange = (p: CubicPolynomial): Interval.Closed => range(p, Interval.unit)\n\n/** @internal */\nexport const length = dual<\n (domain: Interval.Interval) => (p: CubicPolynomial) => number,\n (p: CubicPolynomial, domain: Interval.Interval) => number\n>(2, (p: CubicPolynomial, dom: Interval.Interval) => {\n if (Interval.size(dom) === 0) {\n return 0\n }\n\n if (p.c3 === 0) {\n if (p.c2 === 0) {\n return Linear.length(Linear.make(p.c0, p.c1), dom)\n }\n\n return Quadratic.length(Quadratic.make(p.c0, p.c1, p.c2), dom)\n }\n\n const d = derivative(p)\n\n const { scale, shift } = Interval.scaleShift(Interval.biunit, dom)\n\n return (\n (GL32_W0 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * -GL32_X0) ** 2) +\n GL32_W0 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * GL32_X0) ** 2) +\n GL32_W1 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * -GL32_X1) ** 2) +\n GL32_W1 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * GL32_X1) ** 2) +\n GL32_W2 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * -GL32_X2) ** 2) +\n GL32_W2 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * GL32_X2) ** 2) +\n GL32_W3 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * -GL32_X3) ** 2) +\n GL32_W3 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * GL32_X3) ** 2) +\n GL32_W4 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * -GL32_X4) ** 2) +\n GL32_W4 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * GL32_X4) ** 2) +\n GL32_W5 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * -GL32_X5) ** 2) +\n GL32_W5 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * GL32_X5) ** 2) +\n GL32_W6 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * -GL32_X6) ** 2) +\n GL32_W6 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * GL32_X6) ** 2) +\n GL32_W7 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * -GL32_X7) ** 2) +\n GL32_W7 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * GL32_X7) ** 2) +\n GL32_W8 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * -GL32_X8) ** 2) +\n GL32_W8 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * GL32_X8) ** 2) +\n GL32_W9 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * -GL32_X9) ** 2) +\n GL32_W9 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * GL32_X9) ** 2) +\n GL32_W10 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * -GL32_X10) ** 2) +\n GL32_W10 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * GL32_X10) ** 2) +\n GL32_W11 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * -GL32_X11) ** 2) +\n GL32_W11 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * GL32_X11) ** 2) +\n GL32_W12 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * -GL32_X12) ** 2) +\n GL32_W12 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * GL32_X12) ** 2) +\n GL32_W13 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * -GL32_X13) ** 2) +\n GL32_W13 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * GL32_X13) ** 2) +\n GL32_W14 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * -GL32_X14) ** 2) +\n GL32_W14 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * GL32_X14) ** 2) +\n GL32_W15 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * -GL32_X15) ** 2) +\n GL32_W15 * Math.sqrt(1 + Quadratic.solve(d, shift + scale * GL32_X15) ** 2)) *\n scale\n )\n})\n\n/** @internal */\nexport const curvature = dual(2, (p: CubicPolynomial, x: number) => {\n const d = derivative(p)\n const dd = Quadratic.derivative(d)\n\n return Math.abs(Linear.solve(dd, x)) / (1 + Quadratic.solve(d, x) ** 2) ** 1.5\n})\n","import type { Closed, Interval } from '../interval/interval.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { Vector4 } from '../vector/vector4.ts'\nimport * as internal from './cubic.internal.ts'\nimport type { CubicPolynomialTypeId } from './cubic.internal.circular.ts'\nimport type { Monotonicity } from './monotonicity.ts'\nimport type { QuadraticPolynomial } from './quadratic.ts'\nimport type { Decreasing, Increasing, Monotonic, PolynomialTraits } from './traits.ts'\n\nexport type { Monotonic, Increasing, Decreasing } from './traits.ts'\n\n/**\n * A cubic polynomial.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The `Traits` type parameter is a phantom marker that accumulates trait\n * brands as the polynomial is refined via `isMonotonic` / `asMonotonic` and\n * friends. A cubic is monotonic only over an interval that avoids both of its\n * extrema (or globally, when c2 = c3 = 0 and c1 ≠ 0).\n *\n * @since 1.0.0\n */\nexport interface CubicPolynomial<out Traits = unknown> extends Pipeable {\n readonly [CubicPolynomialTypeId]: CubicPolynomialTypeId\n readonly [PolynomialTraits]: Traits\n\n /**\n * The coefficient of the x^0 term.\n */\n readonly c0: number\n /**\n * The coefficient of the x^1 term.\n */\n readonly c1: number\n /**\n * The coefficient of the x^2 term.\n */\n readonly c2: number\n /**\n * The coefficient of the x^3 term.\n */\n readonly c3: number\n}\n\n/**\n * Checks if a value is a `CubicPolynomial`.\n *\n * @param value - The value to check.\n * @returns `true` if the value is a `CubicPolynomial`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isCubicPolynomial: (value: unknown) => value is CubicPolynomial =\n internal.isCubicPolynomial\n\nexport const equals: {\n /**\n * Checks if two `CubicPolynomial` instances are approximately equal within\n * the default absolute tolerance ({@link EPSILON}).\n *\n * @param a - The first polynomial.\n * @param b - The second polynomial.\n * @returns `true` when each pair of coefficients is within tolerance.\n * @since 1.1.0\n */\n (a: CubicPolynomial, b: CubicPolynomial): boolean\n /**\n * Checks if two `CubicPolynomial` instances are approximately equal within\n * the default absolute tolerance ({@link EPSILON}).\n *\n * @param b - The second polynomial.\n * @returns A function that takes the first polynomial and returns the comparison result.\n * @since 1.1.0\n */\n (b: CubicPolynomial): (a: CubicPolynomial) => boolean\n} = internal.equals\n\n/**\n * Creates a new `CubicPolynomial` instance.\n *\n * @param c0 - The coefficient of the x^0 term.\n * @param c1 - The coefficient of the x^1 term.\n * @param c2 - The coefficient of the x^2 term.\n * @param c3 - The coefficient of the x^3 term.\n */\nexport const make: (c0: number, c1: number, c2: number, c3: number) => CubicPolynomial =\n internal.make\n\n/**\n * Creates a new `CubicPolynomial` instance from a vector.\n *\n * @param v - The vector to convert.\n * @returns A new `CubicPolynomial` instance.\n * @since 1.0.0\n */\nexport const fromVector: (v: Vector4) => CubicPolynomial = internal.fromVector\n\n/**\n * Creates a new `CubicPolynomial` that interpolates the four given points,\n * treating each `Vector2` as an `(x, y)` pair. The four input `x` values must\n * be distinct.\n *\n * @param p0 - The first point.\n * @param p1 - The second point.\n * @param p2 - The third point.\n * @param p3 - The fourth point.\n * @returns The unique cubic polynomial passing through the four points.\n * @since 2.0.0\n */\nexport const fromPoints: (p0: Vector2, p1: Vector2, p2: Vector2, p3: Vector2) => CubicPolynomial =\n internal.fromPoints\n\nexport const solve: {\n /**\n * Solves a cubic polynomial for a given value of x.\n *\n * @param p - The cubic polynomial to solve.\n * @param x - The value of x to solve for.\n * @returns The result of the polynomial evaluation at x.\n * @since 1.0.0\n */\n (p: CubicPolynomial, x: number): number\n /**\n * Solves a cubic polynomial for a given value of x.\n *\n * @param x - The value of x to solve for.\n * @returns A function that takes a cubic polynomial and returns the result of the polynomial evaluation at x.\n * @since 1.0.0\n */\n (x: number): (p: CubicPolynomial) => number\n} = internal.solve\n\n/**\n * Converts a cubic polynomial to a solver function.\n *\n * @param p - The cubic polynomial to convert.\n * @returns A function that takes a value of x and returns the result of the polynomial evaluation at x.\n * @since 1.0.0\n */\nexport const toSolver: (p: CubicPolynomial) => (x: number) => number = internal.toSolver\n\nexport const solveInverse: {\n /**\n * Solves a monotonic cubic polynomial for a given value of y. Because the\n * polynomial is strictly monotonic, the inverse has at most one solution.\n *\n * @param p - The monotonic cubic polynomial.\n * @param y - The value of y to solve for.\n * @returns Zero or one solutions.\n * @since 2.0.0\n */\n <T extends Monotonic>(p: CubicPolynomial<T>, y: number): Solution.AtMostOne<number>\n /**\n * Solves a cubic polynomial for a given value of y.\n *\n * @param p - The cubic polynomial to solve.\n * @param y - The value of y to solve for.\n * @returns The roots of the polynomial equation p(x) = y.\n * @since 1.0.0\n */\n <T>(p: CubicPolynomial<T>, y: number): Solution.AtMostThree<number>\n /**\n * Solves a cubic polynomial for a given value of y.\n *\n * @param y - The value of y to solve for.\n * @returns A function that takes a cubic polynomial and returns the roots\n * of the polynomial equation p(x) = y. Tightens to `Solution.AtMostOne<number>` for\n * monotonic inputs.\n * @since 1.0.0\n */\n (y: number): {\n <T extends Monotonic>(p: CubicPolynomial<T>): Solution.AtMostOne<number>\n <T>(p: CubicPolynomial<T>): Solution.AtMostThree<number>\n }\n} = internal.solveInverse as never\n\n/**\n * Converts a cubic polynomial to an inverse solver function.\n *\n * @param p - The cubic polynomial to convert.\n * @returns A function that takes a value of y and returns the roots of the polynomial equation p(x) = y.\n * @since 1.0.0\n */\nexport const toInverseSolver: (p: CubicPolynomial) => (y: number) => Solution.AtMostThree<number> =\n internal.toInverseSolver\n\n/**\n * Returns the polynomial's coefficients as a tuple `[c0, c1, c2, c3]`.\n *\n * @param p - The cubic polynomial.\n * @returns The coefficients in monomial order.\n * @since 2.0.0\n */\nexport const coefficients: (p: CubicPolynomial) => readonly [number, number, number, number] =\n internal.coefficients\n\n/**\n * Calculates the derivative of a cubic polynomial.\n *\n * @param p - The cubic polynomial to differentiate.\n * @returns The derivative of the cubic polynomial.\n * @since 1.0.0\n */\nexport const derivative: (p: CubicPolynomial) => QuadraticPolynomial = internal.derivative\n\nexport const subdivide: {\n /**\n * Subdivides a cubic polynomial at parameter `t ∈ (0, 1)` into two new\n * cubic polynomials. The first polynomial's evaluation on `[0, 1]` matches\n * the original's on `[0, t]`; the second matches the original's on\n * `[t, 1]`. Equivalent to de Casteljau subdivision in Bernstein form,\n * performed directly in monomial form.\n *\n * @param p - The cubic polynomial to subdivide.\n * @param t - The split parameter; must be in the open interval `(0, 1)`.\n * @returns A `[left, right]` tuple of cubic polynomials.\n * @since 2.0.0\n */\n (p: CubicPolynomial, t: number): [CubicPolynomial, CubicPolynomial]\n /**\n * Subdivides a cubic polynomial at parameter `t ∈ (0, 1)`.\n *\n * @param t - The split parameter; must be in the open interval `(0, 1)`.\n * @returns A function that takes a polynomial and returns its `[left, right]` halves.\n * @since 2.0.0\n */\n (t: number): (p: CubicPolynomial) => [CubicPolynomial, CubicPolynomial]\n} = internal.subdivide\n\n/**\n * Calculates the roots of a cubic polynomial.\n *\n * @param p - The cubic polynomial to find the roots of.\n * @returns The roots of the cubic polynomial.\n * @since 1.0.0\n */\nexport const roots: (p: CubicPolynomial) => Solution.AtMostThree<number> = internal.roots\n\n/**\n * Calculates the extrema of a cubic polynomial.\n *\n * @param p - The cubic polynomial to find the extrema of.\n * @returns The extrema of the cubic polynomial.\n * @since 1.0.0\n */\nexport const extrema: (p: CubicPolynomial) => Solution.AtMostTwo<number> = internal.extrema\n\nexport const monotonicity: {\n /**\n * Calculates the monotonicity of a cubic polynomial. Throws when the\n * interval has zero width — the question is undefined at a single point.\n *\n * @param p - The cubic polynomial to analyze.\n * @param i - The interval to restrict the analysis to.\n * @returns The monotonicity of the cubic polynomial in the specified interval.\n * @since 1.0.0\n */\n (p: CubicPolynomial, i?: Interval): Monotonicity\n /**\n * Calculates the monotonicity of a cubic polynomial. Throws when the\n * interval has zero width.\n *\n * @param i - The interval to restrict the analysis to.\n * @returns A function that takes a cubic polynomial and returns the\n * monotonicity of the cubic polynomial in the specified interval.\n * @since 1.0.0\n */\n (i: Interval): (p: CubicPolynomial) => Monotonicity\n} = internal.monotonicity\n\n/**\n * Type-narrowing predicate: refines a `CubicPolynomial<T>` to\n * `CubicPolynomial<T & Monotonic>` when the polynomial is strictly monotonic\n * over the given interval (or globally, when no interval is given).\n *\n * @param p - The cubic polynomial to check.\n * @param i - Optional interval over which to check monotonicity.\n * @returns `true` when monotonicity is `'increasing'` or `'decreasing'`.\n * @since 2.0.0\n */\nexport const isMonotonic: {\n <T>(p: CubicPolynomial<T>, i?: Interval): p is CubicPolynomial<T & Monotonic>\n (i: Interval): <T>(p: CubicPolynomial<T>) => p is CubicPolynomial<T & Monotonic>\n} = internal.isMonotonic\n\n/**\n * Type-narrowing predicate: refines to `CubicPolynomial<T & Increasing>`.\n *\n * @since 2.0.0\n */\nexport const isIncreasing: {\n <T>(p: CubicPolynomial<T>, i?: Interval): p is CubicPolynomial<T & Increasing>\n (i: Interval): <T>(p: CubicPolynomial<T>) => p is CubicPolynomial<T & Increasing>\n} = internal.isIncreasing\n\n/**\n * Type-narrowing predicate: refines to `CubicPolynomial<T & Decreasing>`.\n *\n * @since 2.0.0\n */\nexport const isDecreasing: {\n <T>(p: CubicPolynomial<T>, i?: Interval): p is CubicPolynomial<T & Decreasing>\n (i: Interval): <T>(p: CubicPolynomial<T>) => p is CubicPolynomial<T & Decreasing>\n} = internal.isDecreasing\n\n/**\n * Asserts that the cubic polynomial is monotonic, throwing on failure.\n *\n * @param p - The cubic polynomial to assert against.\n * @param i - Optional interval over which to check monotonicity.\n * @returns The same polynomial, typed with the `Monotonic` brand.\n * @throws When the polynomial is not monotonic over the given (or global) interval.\n * @since 2.0.0\n */\nexport const asMonotonic: <T>(\n p: CubicPolynomial<T>,\n i?: Interval,\n) => CubicPolynomial<T & Monotonic> = internal.asMonotonic\n\n/**\n * Asserts that the cubic polynomial is increasing, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasing: <T>(\n p: CubicPolynomial<T>,\n i?: Interval,\n) => CubicPolynomial<T & Increasing> = internal.asIncreasing\n\n/**\n * Asserts that the cubic polynomial is decreasing, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasing: <T>(\n p: CubicPolynomial<T>,\n i?: Interval,\n) => CubicPolynomial<T & Decreasing> = internal.asDecreasing\n\nexport const domain: {\n /**\n * Calculates the domain of a cubic polynomial.\n *\n * @param p - The cubic polynomial to analyze.\n * @param range - The range to restrict the analysis to.\n * @returns The domain of the cubic polynomial in the specified range.\n * @since 1.0.0\n */\n (p: CubicPolynomial, range: Interval): Interval\n /**\n * Calculates the domain of a cubic polynomial.\n *\n * @param range - The range to restrict the analysis to.\n * @returns A function that takes a cubic polynomial and returns the domain of the cubic polynomial in the specified range.\n * @since 1.0.0\n */\n (range: Interval): (p: CubicPolynomial) => Interval\n} = internal.domain\n\nexport const range: {\n /**\n * Calculates the range of a cubic polynomial.\n *\n * @param p - The cubic polynomial to analyze.\n * @param domain - The domain to restrict the analysis to.\n * @returns The range of the cubic polynomial in the specified domain.\n * @since 1.0.0\n */\n (p: CubicPolynomial, domain: Interval): Closed\n /**\n * Calculates the range of a cubic polynomial.\n *\n * @param domain - The domain to restrict the analysis to.\n * @returns A function that takes a cubic polynomial and returns the range of the cubic polynomial in the specified domain.\n * @since 1.0.0\n */\n (domain: Interval): (p: CubicPolynomial) => Closed\n} = internal.range\n\n/**\n * Calculates the range of a cubic polynomial over the unit interval `[0, 1]`.\n * Equivalent to `range(p, Interval.unit)` — accounts for up to two interior\n * extrema in `[0, 1]`.\n *\n * @param p - The cubic polynomial.\n * @returns The closed range of the polynomial over `[0, 1]`.\n * @since 2.0.0\n */\nexport const unitRange: (p: CubicPolynomial) => Closed = internal.unitRange\n\nexport const length: {\n /**\n * Calculates the length of a cubic polynomial.\n *\n * @param p - The cubic polynomial to analyze.\n * @param domain - The domain to restrict the analysis to.\n * @returns The length of the cubic polynomial in the specified domain.\n * @since 1.0.0\n */\n (p: CubicPolynomial, domain: Interval): number\n /**\n * Calculates the length of a cubic polynomial.\n *\n * @param domain - The domain to restrict the analysis to.\n * @returns A function that takes a cubic polynomial and returns the length of the cubic polynomial in the specified domain.\n * @since 1.0.0\n */\n (domain: Interval): (p: CubicPolynomial) => number\n} = internal.length\n\nexport const curvature: {\n /**\n * Calculates the curvature of a cubic polynomial.\n *\n * @param p - The cubic polynomial to analyze.\n * @param x - The value of x to calculate the curvature at.\n * @returns The curvature of the cubic polynomial at the specified value of x.\n * @since 1.0.0\n */\n (p: CubicPolynomial, x: number): number\n /**\n * Calculates the curvature of a cubic polynomial.\n *\n * @param x - The value of x to calculate the curvature at.\n * @returns A function that takes a cubic polynomial and returns the curvature of the cubic polynomial at the specified value of x.\n * @since 1.0.0\n */\n (x: number): (p: CubicPolynomial) => number\n} = internal.curvature\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"quadratic-BZmfZE71.mjs","names":["internal.isLinearPolynomial","equals","internal.equals","make","internal.make","fromVector","internal.fromVector","internal.fromPointSlope","fromPoints","internal.fromPoints","solve","internal.solve","toSolver","internal.toSolver","solveInverse","internal.solveInverse","toInverseSolver","internal.toInverseSolver","monotonicity","internal.monotonicity","isMonotonic","internal.isMonotonic","isIncreasing","internal.isIncreasing","isDecreasing","internal.isDecreasing","asMonotonic","internal.asMonotonic","asIncreasing","internal.asIncreasing","asDecreasing","internal.asDecreasing","coefficients","internal.coefficients","derivative","internal.derivative","antiderivative","internal.antiderivative","domain","internal.domain","range","internal.range","unitRange","internal.unitRange","length","internal.length","internal.isQuadraticPolynomial","internal.equals","internal.make","internal.fromVector","internal.fromPoints","internal.solve","internal.toSolver","internal.solveInverse","internal.toInverseSolver","internal.coefficients","internal.derivative","internal.roots","internal.extreme","internal.monotonicity","internal.isMonotonic","internal.isIncreasing","internal.isDecreasing","internal.asMonotonic","internal.asIncreasing","internal.asDecreasing","internal.antiderivative","internal.domain","internal.range","internal.unitRange","internal.length","internal.curvature"],"sources":["../../src/polynomial/linear.ts","../../src/polynomial/quadratic.ts"],"sourcesContent":["import type { Closed, Interval } from '../interval/interval.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { LinearPolynomialTypeId } from './linear.internal.ts'\nimport * as internal from './linear.internal.ts'\nimport type { GuaranteedMonotonicity } from './monotonicity.ts'\nimport type { QuadraticPolynomial } from './quadratic.ts'\nimport type { Decreasing, Increasing, Monotonic, PolynomialTraits } from './traits.ts'\n\nexport type { Monotonic, Increasing, Decreasing } from './traits.ts'\n\n/**\n * A linear polynomial.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The `Traits` type parameter is a phantom marker that accumulates trait\n * brands as the polynomial is refined via `isMonotonic` / `asMonotonic` and\n * friends. The runtime value carries no trait data — `Traits` only flows\n * through the type system to enable tighter return types on operations like\n * `solveInverse`.\n *\n * @since 1.0.0\n */\nexport interface LinearPolynomial<out Traits = unknown> extends Pipeable {\n readonly [LinearPolynomialTypeId]: LinearPolynomialTypeId\n readonly [PolynomialTraits]: Traits\n\n /**\n * The coefficient of the x^0 term.\n */\n readonly c0: number\n\n /**\n * The coefficient of the x^1 term.\n */\n readonly c1: number\n}\n\n/**\n * Checks if a value is a `LinearPolynomial`.\n *\n * @param v - The value to check.\n * @returns `true` if the value is a `LinearPolynomial`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isLinearPolynomial: (v: unknown) => v is LinearPolynomial = internal.isLinearPolynomial\n\nexport const equals: {\n /**\n * Checks if two `LinearPolynomial` instances are approximately equal within\n * the default absolute tolerance ({@link EPSILON}).\n *\n * @param a - The first polynomial.\n * @param b - The second polynomial.\n * @returns `true` when each pair of coefficients is within tolerance.\n * @since 1.1.0\n */\n (a: LinearPolynomial, b: LinearPolynomial): boolean\n /**\n * Checks if two `LinearPolynomial` instances are approximately equal within\n * the default absolute tolerance ({@link EPSILON}).\n *\n * @param b - The second polynomial.\n * @returns A function that takes the first polynomial and returns the comparison result.\n * @since 1.1.0\n */\n (b: LinearPolynomial): (a: LinearPolynomial) => boolean\n} = internal.equals\n\n/**\n * Creates a new `LinearPolynomial` instance.\n *\n * @param c0 - The coefficient of the x^0 term. Defaults to 0.\n * @param c1 - The coefficient of the x^1 term. Defaults to 0.\n * @returns A new `LinearPolynomial` instance.\n * @since 1.0.0\n */\nexport const make: (c0?: number, c1?: number) => LinearPolynomial = internal.make\n\n/**\n * Creates a new `LinearPolynomial` instance from a vector.\n *\n * @param v - The vector to create the polynomial from.\n * @returns A new `LinearPolynomial` instance.\n * @since 1.0.0\n */\nexport const fromVector: (v: Vector2) => LinearPolynomial = internal.fromVector\n\n/**\n * Creates a new `LinearPolynomial` instance from a point and slope.\n *\n * @param p - The point on the line.\n * @param slope - The slope of the line.\n * @returns A new `LinearPolynomial` instance.\n * @since 1.0.0\n */\nexport const fromPointSlope: (p: Vector2, slope: number) => LinearPolynomial =\n internal.fromPointSlope\n\n/**\n * Creates a new `LinearPolynomial` instance from two points.\n *\n * @param p1 - The first point.\n * @param p2 - The second point.\n * @returns A new `LinearPolynomial` instance.\n * @since 1.0.0\n */\nexport const fromPoints: (p1: Vector2, p2: Vector2) => LinearPolynomial = internal.fromPoints\n\nexport const solve: {\n /**\n * Solves a linear polynomial for a given value of x.\n *\n * @param p - The linear polynomial to solve.\n * @param x - The value of x to solve for.\n * @returns The result of the polynomial evaluated at x.\n * @since 1.0.0\n */\n (p: LinearPolynomial, x: number): number\n /**\n * Solves a linear polynomial for a given value of x.\n *\n * @param x - The value of x to solve for.\n * @returns A function that takes a `LinearPolynomial` and returns the result of the polynomial evaluated at x.\n * @since 1.0.0\n */\n (x: number): (p: LinearPolynomial) => number\n} = internal.solve\n\n/**\n * Converts a linear polynomial to a solver function.\n *\n * @param p - The linear polynomial to convert.\n * @returns A function that takes a value of x and returns the result of the polynomial evaluated at x.\n * @since 1.0.0\n */\nexport const toSolver: (p: LinearPolynomial) => (x: number) => number = internal.toSolver\n\n// The implementation always runs the same `c1 === 0 ? Solution.none : ...`\n// branch. For `Monotonic`-branded polynomials the empty branch is provably\n// unreachable, but TS can't see that — the cast pairs the type-level promise\n// with the runtime brand check.\nexport const solveInverse: {\n /**\n * Solves a monotonic linear polynomial for a given value of y. Because the\n * polynomial is strictly monotonic, the inverse always has exactly one\n * solution — wrapped in `Solution.One`.\n *\n * @param p - The monotonic linear polynomial to solve.\n * @param y - The value of y to solve for.\n * @since 2.0.0\n */\n <T extends Monotonic>(p: LinearPolynomial<T>, y: number): Solution.One<number>\n /**\n * Solves a linear polynomial for a given value of y. Returns `Solution.none`\n * for constant polynomials (no inverse).\n *\n * @param p - The linear polynomial to solve.\n * @param y - The value of y to solve for.\n * @since 1.0.0\n */\n <T>(p: LinearPolynomial<T>, y: number): Solution.AtMostOne<number>\n /** @since 1.0.0 */\n (y: number): {\n <T extends Monotonic>(p: LinearPolynomial<T>): Solution.One<number>\n <T>(p: LinearPolynomial<T>): Solution.AtMostOne<number>\n }\n} = internal.solveInverse as never\n\n/**\n * Converts a linear polynomial to an inverse solver function.\n *\n * @param p - The linear polynomial to convert.\n * @since 1.0.0\n */\nexport const toInverseSolver: (p: LinearPolynomial) => (y: number) => Solution.AtMostOne<number> =\n internal.toInverseSolver\n\n/**\n * Finds the roots of a linear polynomial.\n *\n * @param p - The linear polynomial to find the roots of.\n * @since 1.0.0\n */\nexport const root: (p: LinearPolynomial) => Solution.AtMostOne<number> = (p) =>\n internal.solveInverse(p, 0)\n\n/**\n * Calculates the monotonicity of a linear polynomial.\n *\n * @param p - The linear polynomial to check.\n * @returns The guaranteed monotonicity of the polynomial.\n * @since 1.0.0\n */\nexport const monotonicity: (p: LinearPolynomial) => GuaranteedMonotonicity = internal.monotonicity\n\n/**\n * Type-narrowing predicate: refines a `LinearPolynomial<T>` to\n * `LinearPolynomial<T & Monotonic>` when the polynomial is strictly monotonic.\n *\n * @param p - The linear polynomial to check.\n * @returns `true` when `monotonicity(p)` is `'increasing'` or `'decreasing'`.\n * @since 2.0.0\n */\nexport const isMonotonic: <T>(p: LinearPolynomial<T>) => p is LinearPolynomial<T & Monotonic> =\n internal.isMonotonic\n\n/**\n * Type-narrowing predicate: refines to `LinearPolynomial<T & Increasing>`.\n *\n * @param p - The linear polynomial to check.\n * @returns `true` when `monotonicity(p)` is `'increasing'`.\n * @since 2.0.0\n */\nexport const isIncreasing: <T>(p: LinearPolynomial<T>) => p is LinearPolynomial<T & Increasing> =\n internal.isIncreasing\n\n/**\n * Type-narrowing predicate: refines to `LinearPolynomial<T & Decreasing>`.\n *\n * @param p - The linear polynomial to check.\n * @returns `true` when `monotonicity(p)` is `'decreasing'`.\n * @since 2.0.0\n */\nexport const isDecreasing: <T>(p: LinearPolynomial<T>) => p is LinearPolynomial<T & Decreasing> =\n internal.isDecreasing\n\n/**\n * Asserts that the linear polynomial is monotonic, throwing on failure.\n *\n * @param p - The linear polynomial to assert against.\n * @returns The same polynomial, typed with the `Monotonic` brand.\n * @throws When `monotonicity(p)` is `'constant'`.\n * @since 2.0.0\n */\nexport const asMonotonic: <T>(p: LinearPolynomial<T>) => LinearPolynomial<T & Monotonic> =\n internal.asMonotonic\n\n/**\n * Asserts that the linear polynomial is increasing, throwing on failure.\n *\n * @param p - The linear polynomial to assert against.\n * @returns The same polynomial, typed with the `Increasing` brand.\n * @throws When `monotonicity(p)` is not `'increasing'`.\n * @since 2.0.0\n */\nexport const asIncreasing: <T>(p: LinearPolynomial<T>) => LinearPolynomial<T & Increasing> =\n internal.asIncreasing\n\n/**\n * Asserts that the linear polynomial is decreasing, throwing on failure.\n *\n * @param p - The linear polynomial to assert against.\n * @returns The same polynomial, typed with the `Decreasing` brand.\n * @throws When `monotonicity(p)` is not `'decreasing'`.\n * @since 2.0.0\n */\nexport const asDecreasing: <T>(p: LinearPolynomial<T>) => LinearPolynomial<T & Decreasing> =\n internal.asDecreasing\n\n/**\n * Returns the polynomial's coefficients as a tuple `[c0, c1]`.\n *\n * @param p - The linear polynomial.\n * @returns The coefficients in monomial order.\n * @since 2.0.0\n */\nexport const coefficients: (p: LinearPolynomial) => readonly [number, number] =\n internal.coefficients\n\n/**\n * Calculates the derivative of a linear polynomial.\n *\n * @param p - The linear polynomial to differentiate.\n * @returns The derivative of the linear polynomial.\n * @since 1.0.0\n */\nexport const derivative: (p: LinearPolynomial) => number = internal.derivative\n\nexport const antiderivative: {\n /**\n * Calculates the antiderivative of a linear polynomial.\n *\n * @param p - The linear polynomial to integrate.\n * @param constant - The constant of integration. Defaults to 0.\n * @returns The antiderivative of the linear polynomial.\n * @since 1.0.0\n */\n (p: LinearPolynomial, constant?: number): QuadraticPolynomial\n /**\n * Calculates the antiderivative of a linear polynomial.\n *\n * @param constant - The constant of integration. Defaults to 0.\n * @returns A function that takes a `LinearPolynomial` and returns the antiderivative of the polynomial.\n * @since 1.0.0\n */\n (constant: number): (p: LinearPolynomial) => QuadraticPolynomial\n} = internal.antiderivative\n\nexport const domain: {\n /**\n * Calculates the domain of a linear polynomial.\n *\n * @param p - The linear polynomial to check.\n * @param range - The range to check against.\n * @returns The domain of the polynomial within the given range.\n * @since 1.0.0\n */\n (p: LinearPolynomial, range: Interval): Solution.AtMostOne<Interval>\n /**\n * Calculates the domain of a linear polynomial.\n *\n * @param range - The range to check against.\n * @returns A function that takes a `LinearPolynomial` and returns the domain of the polynomial within the given range.\n * @since 1.0.0\n */\n (range: Interval): (p: LinearPolynomial) => Solution.AtMostOne<Interval>\n} = internal.domain\n\nexport const range: {\n /**\n * Calculates the range of a linear polynomial.\n *\n * @param p - The linear polynomial to check.\n * @param domain - The domain to check against.\n * @returns The range of the polynomial within the given domain.\n * @since 1.0.0\n */\n (p: LinearPolynomial, domain: Interval): Closed\n /**\n * Calculates the range of a linear polynomial.\n *\n * @param domain - The domain to check against.\n * @returns A function that takes a `LinearPolynomial` and returns the range of the polynomial within the given domain.\n * @since 1.0.0\n */\n (domain: Interval): (p: LinearPolynomial) => Closed\n} = internal.range\n\n/**\n * Calculates the range of a linear polynomial over the unit interval `[0, 1]`.\n * Equivalent to `range(p, Interval.unit)` but without the import and call\n * overhead — directly evaluates the endpoints.\n *\n * @param p - The linear polynomial.\n * @returns The closed range of the polynomial over `[0, 1]`.\n * @since 2.0.0\n */\nexport const unitRange: (p: LinearPolynomial) => Closed = internal.unitRange\n\nexport const length: {\n /**\n * Calculates the length of a linear polynomial within a particular domain `Interval`.\n *\n * @param p - The linear polynomial to analyze.\n * @param domain - The domain to restrict the analysis to.\n * @returns The length of the linear polynomial in the specified domain.\n * @since 1.0.0\n */\n (p: LinearPolynomial, domain: Interval): number\n /**\n * Calculates the length of a linear polynomial within a particular domain `Interval`.\n *\n * @param domain - The domain to restrict the analysis to.\n * @returns A function that takes a `LinearPolynomial` and returns the length of the polynomial in the specified domain.\n * @since 1.0.0\n */\n (domain: Interval): (p: LinearPolynomial) => number\n} = internal.length\n","import type { Closed, Interval } from '../interval/interval.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { Vector3 } from '../vector/vector3.ts'\nimport type { CubicPolynomial } from './cubic.ts'\nimport type { LinearPolynomial } from './linear.ts'\nimport type { Monotonicity } from './monotonicity.ts'\nimport * as internal from './quadratic.internal.ts'\nimport type { QuadraticPolynomialTypeId } from './quadratic.internal.circular.ts'\nimport type { Decreasing, Increasing, Monotonic, PolynomialTraits } from './traits.ts'\n\nexport type { Monotonic, Increasing, Decreasing } from './traits.ts'\n\n/**\n * A quadratic polynomial.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The `Traits` type parameter is a phantom marker that accumulates trait\n * brands as the polynomial is refined via `isMonotonic` / `asMonotonic` and\n * friends. Refinements may be parameterized by an `Interval` — a quadratic is\n * monotonic on an interval that avoids its extremum, even though it is not\n * monotonic globally.\n *\n * @since 1.0.0\n */\nexport interface QuadraticPolynomial<out Traits = unknown> extends Pipeable {\n readonly [QuadraticPolynomialTypeId]: QuadraticPolynomialTypeId\n readonly [PolynomialTraits]: Traits\n\n /**\n * The coefficient of the x^0 term.\n */\n readonly c0: number\n /**\n * The coefficient of the x^1 term.\n */\n readonly c1: number\n /**\n * The coefficient of the x^2 term.\n */\n readonly c2: number\n}\n\n/**\n * Checks if a value is a `QuadraticPolynomial`.\n *\n * @param v - The value to check.\n * @returns `true` if the value is a `QuadraticPolynomial`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isQuadraticPolynomial: (v: unknown) => v is QuadraticPolynomial =\n internal.isQuadraticPolynomial\n\nexport const equals: {\n /**\n * Checks if two `QuadraticPolynomial` instances are approximately equal\n * within the default absolute tolerance ({@link EPSILON}).\n *\n * @param a - The first polynomial.\n * @param b - The second polynomial.\n * @returns `true` when each pair of coefficients is within tolerance.\n * @since 1.1.0\n */\n (a: QuadraticPolynomial, b: QuadraticPolynomial): boolean\n /**\n * Checks if two `QuadraticPolynomial` instances are approximately equal\n * within the default absolute tolerance ({@link EPSILON}).\n *\n * @param b - The second polynomial.\n * @returns A function that takes the first polynomial and returns the comparison result.\n * @since 1.1.0\n */\n (b: QuadraticPolynomial): (a: QuadraticPolynomial) => boolean\n} = internal.equals\n\n/**\n * Creates a new `QuadraticPolynomial` instance.\n *\n * @param c0 - The coefficient of the x^0 term. Defaults to 0.\n * @param c1 - The coefficient of the x^1 term. Defaults to 0.\n * @param c2 - The coefficient of the x^2 term. Defaults to 1.\n * @returns A new `QuadraticPolynomial` instance.\n * @since 1.0.0\n */\nexport const make: (c0?: number, c1?: number, c2?: number) => QuadraticPolynomial = internal.make\n\n/**\n * Creates a new `QuadraticPolynomial` instance from a vector.\n *\n * @param v - The vector to create the polynomial from.\n * @returns A new `QuadraticPolynomial` instance.\n * @since 1.0.0\n */\nexport const fromVector: (v: Vector3) => QuadraticPolynomial = internal.fromVector\n\n/**\n * Creates a new `QuadraticPolynomial` that interpolates the three given\n * points, treating each `Vector2` as an `(x, y)` pair. The three input `x`\n * values must be distinct.\n *\n * @param p0 - The first point.\n * @param p1 - The second point.\n * @param p2 - The third point.\n * @returns The unique quadratic polynomial passing through the three points.\n * @since 2.0.0\n */\nexport const fromPoints: (p0: Vector2, p1: Vector2, p2: Vector2) => QuadraticPolynomial =\n internal.fromPoints\n\nexport const solve: {\n /**\n * Solves the quadratic polynomial for a given x value.\n *\n * @param p - The quadratic polynomial.\n * @param x - The x value to solve for.\n * @returns The result of the polynomial at the given x value.\n * @since 1.0.0\n */\n (p: QuadraticPolynomial, x: number): number\n /**\n * Solves the quadratic polynomial for a given x value.\n *\n * @param x - The x value to solve for.\n * @returns A function that takes a quadratic polynomial and returns the result of the polynomial at the given x value.\n * @since 1.0.0\n */\n (x: number): (p: QuadraticPolynomial) => number\n} = internal.solve\n\n/**\n * Creates a solver function for the quadratic polynomial.\n *\n * @param p - The quadratic polynomial.\n * @returns A function that takes an x value and returns the result of the polynomial at that x value.\n */\nexport const toSolver: (p: QuadraticPolynomial) => (x: number) => number = internal.toSolver\n\nexport const solveInverse: {\n /**\n * Solves a monotonic quadratic polynomial for a given y value. Because the\n * polynomial is strictly monotonic (either globally, or over the interval\n * the `Monotonic` brand was attached for), the inverse has at most one\n * solution.\n *\n * @param p - The monotonic quadratic polynomial.\n * @param y - The y value to solve for.\n * @returns Zero or one solutions.\n * @since 2.0.0\n */\n <T extends Monotonic>(p: QuadraticPolynomial<T>, y: number): Solution.AtMostOne<number>\n /**\n * Solves the quadratic polynomial for a given y value.\n *\n * @param p - The quadratic polynomial.\n * @param y - The y value to solve for.\n * @returns The solutions to the polynomial at the given y value.\n * @since 1.0.0\n */\n <T>(p: QuadraticPolynomial<T>, y: number): Solution.AtMostTwo<number>\n /**\n * Solves the quadratic polynomial for a given y value.\n *\n * @param y - The y value to solve for.\n * @returns A function that takes a quadratic polynomial and returns the\n * solutions. Tightens to `Solution.AtMostOne<number>` for monotonic inputs.\n * @since 1.0.0\n */\n (y: number): {\n <T extends Monotonic>(p: QuadraticPolynomial<T>): Solution.AtMostOne<number>\n <T>(p: QuadraticPolynomial<T>): Solution.AtMostTwo<number>\n }\n} = internal.solveInverse as never\n\n/**\n * Creates an inverse solver function for the quadratic polynomial.\n *\n * @param p - The quadratic polynomial.\n * @returns A function that takes a y value and returns the solutions to the polynomial at that y value.\n */\nexport const toInverseSolver: (\n p: QuadraticPolynomial,\n) => (y: number) => Solution.AtMostTwo<number> = internal.toInverseSolver\n\n/**\n * Returns the polynomial's coefficients as a tuple `[c0, c1, c2]`.\n *\n * @param p - The quadratic polynomial.\n * @returns The coefficients in monomial order.\n * @since 2.0.0\n */\nexport const coefficients: (p: QuadraticPolynomial) => readonly [number, number, number] =\n internal.coefficients\n\n/**\n * Computes the derivative of the quadratic polynomial.\n *\n * @param p - The quadratic polynomial.\n * @returns The derivative of the polynomial as a linear polynomial.\n * @since 1.0.0\n */\nexport const derivative: (p: QuadraticPolynomial) => LinearPolynomial = internal.derivative\n\n/**\n * Finds the roots of the quadratic polynomial.\n *\n * @param p - The quadratic polynomial.\n * @returns The roots of the polynomial as a tuple of solutions.\n * @since 1.0.0\n */\nexport const roots: (p: QuadraticPolynomial) => Solution.AtMostTwo<number> = internal.roots\n\n/**\n * Finds the extreme point of the quadratic polynomial.\n *\n * @param p - The quadratic polynomial.\n * @returns The extreme point of the polynomial as a solution.\n * @since 1.0.0\n */\nexport const extreme: (p: QuadraticPolynomial) => Vector2 | null = internal.extreme\n\nexport const monotonicity: {\n /**\n * Computes the monotonicity of the quadratic polynomial over a given\n * interval. Throws when the interval has zero width — the question is\n * undefined at a single point.\n *\n * @param p - The quadratic polynomial.\n * @param i - The interval to compute the monotonicity over.\n * @returns The monotonicity of the polynomial over the interval.\n * @since 1.0.0\n */\n (p: QuadraticPolynomial, i?: Interval): Monotonicity\n /**\n * Computes the monotonicity of the quadratic polynomial over a given\n * interval. Throws when the interval has zero width.\n *\n * @param i - The interval to compute the monotonicity over.\n * @returns A function that takes a quadratic polynomial and returns the\n * monotonicity of the polynomial over the interval.\n * @since 1.0.0\n */\n (i: Interval): (p: QuadraticPolynomial) => Monotonicity\n} = internal.monotonicity\n\n/**\n * Type-narrowing predicate: refines a `QuadraticPolynomial<T>` to\n * `QuadraticPolynomial<T & Monotonic>` when the polynomial is strictly\n * monotonic over the given interval (or globally, when no interval is given).\n *\n * @param p - The quadratic polynomial to check.\n * @param i - Optional interval over which to check monotonicity.\n * @returns `true` when monotonicity is `'increasing'` or `'decreasing'`.\n * @since 2.0.0\n */\nexport const isMonotonic: {\n <T>(p: QuadraticPolynomial<T>, i?: Interval): p is QuadraticPolynomial<T & Monotonic>\n (i: Interval): <T>(p: QuadraticPolynomial<T>) => p is QuadraticPolynomial<T & Monotonic>\n} = internal.isMonotonic\n\n/**\n * Type-narrowing predicate: refines to `QuadraticPolynomial<T & Increasing>`.\n *\n * @since 2.0.0\n */\nexport const isIncreasing: {\n <T>(p: QuadraticPolynomial<T>, i?: Interval): p is QuadraticPolynomial<T & Increasing>\n (i: Interval): <T>(p: QuadraticPolynomial<T>) => p is QuadraticPolynomial<T & Increasing>\n} = internal.isIncreasing\n\n/**\n * Type-narrowing predicate: refines to `QuadraticPolynomial<T & Decreasing>`.\n *\n * @since 2.0.0\n */\nexport const isDecreasing: {\n <T>(p: QuadraticPolynomial<T>, i?: Interval): p is QuadraticPolynomial<T & Decreasing>\n (i: Interval): <T>(p: QuadraticPolynomial<T>) => p is QuadraticPolynomial<T & Decreasing>\n} = internal.isDecreasing\n\n/**\n * Asserts that the quadratic polynomial is monotonic, throwing on failure.\n *\n * @param p - The quadratic polynomial to assert against.\n * @param i - Optional interval over which to check monotonicity.\n * @returns The same polynomial, typed with the `Monotonic` brand.\n * @throws When the polynomial is not monotonic over the given (or global) interval.\n * @since 2.0.0\n */\nexport const asMonotonic: <T>(\n p: QuadraticPolynomial<T>,\n i?: Interval,\n) => QuadraticPolynomial<T & Monotonic> = internal.asMonotonic\n\n/**\n * Asserts that the quadratic polynomial is increasing, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasing: <T>(\n p: QuadraticPolynomial<T>,\n i?: Interval,\n) => QuadraticPolynomial<T & Increasing> = internal.asIncreasing\n\n/**\n * Asserts that the quadratic polynomial is decreasing, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasing: <T>(\n p: QuadraticPolynomial<T>,\n i?: Interval,\n) => QuadraticPolynomial<T & Decreasing> = internal.asDecreasing\n\nexport const antiderivative: {\n /**\n * Computes the antiderivative of the quadratic polynomial.\n *\n * @param p - The quadratic polynomial.\n * @param constant - The constant of integration. Defaults to 0.\n * @returns The antiderivative of the polynomial as a cubic polynomial.\n * @since 1.0.0\n */\n (p: QuadraticPolynomial, constant?: number): CubicPolynomial\n /**\n * Computes the antiderivative of the quadratic polynomial.\n *\n * @param constant - The constant of integration. Defaults to 0.\n * @returns A function that takes a quadratic polynomial and returns the antiderivative of the polynomial as a cubic polynomial.\n * @since 1.0.0\n */\n (constant: number): (p: QuadraticPolynomial) => CubicPolynomial\n} = internal.antiderivative\n\nexport const domain: {\n /**\n * Computes the domain of the quadratic polynomial over a given range.\n *\n * @param p - The quadratic polynomial.\n * @param range - The range to compute the domain over.\n * @returns The domain of the polynomial over the range.\n * @since 1.0.0\n */\n (p: QuadraticPolynomial, range: Interval): Solution.AtMostOne<Interval>\n /**\n * Computes the domain of the quadratic polynomial over a given range.\n *\n * @param range - The range to compute the domain over.\n * @returns A function that takes a quadratic polynomial and returns the domain of the polynomial over the range.\n * @since 1.0.0\n */\n (range: Interval): (p: QuadraticPolynomial) => Solution.AtMostOne<Interval>\n} = internal.domain\n\nexport const range: {\n /**\n * Computes the range of the quadratic polynomial over a given domain.\n *\n * @param p - The quadratic polynomial.\n * @param domain - The domain to compute the range over.\n * @returns The range of the polynomial over the domain.\n * @since 1.0.0\n */\n (p: QuadraticPolynomial, domain: Interval): Closed\n /**\n * Computes the range of the quadratic polynomial over a given domain.\n *\n * @param domain - The domain to compute the range over.\n * @returns A function that takes a quadratic polynomial and returns the range of the polynomial over the domain.\n * @since 1.0.0\n */\n (domain: Interval): (p: QuadraticPolynomial) => Closed\n} = internal.range\n\n/**\n * Computes the range of the quadratic polynomial over the unit interval\n * `[0, 1]`. Equivalent to `range(p, Interval.unit)` — accounts for any\n * interior extremum in `[0, 1]`.\n *\n * @param p - The quadratic polynomial.\n * @returns The closed range of the polynomial over `[0, 1]`.\n * @since 2.0.0\n */\nexport const unitRange: (p: QuadraticPolynomial) => Closed = internal.unitRange\n\nexport const length: {\n /**\n * Computes the length of the quadratic polynomial over a given interval.\n *\n * @param p - The quadratic polynomial.\n * @param i - The interval to compute the length over.\n * @returns The length of the polynomial over the interval.\n * @since 1.0.0\n */\n (p: QuadraticPolynomial, i: Interval): number\n /**\n * Computes the length of the quadratic polynomial over a given interval.\n *\n * @param i - The interval to compute the length over.\n * @returns A function that takes a quadratic polynomial and returns the length of the polynomial over the interval.\n * @since 1.0.0\n */\n (i: Interval): (p: QuadraticPolynomial) => number\n} = internal.length\n\nexport const curvature: {\n /**\n * Computes the curvature of the quadratic polynomial at a given x value.\n *\n * @param p - The quadratic polynomial.\n * @param x - The x value to compute the curvature at.\n * @returns The curvature of the polynomial at the given x value.\n * @since 1.0.0\n */\n (p: QuadraticPolynomial, x: number): number\n /**\n * Computes the curvature of the quadratic polynomial at a given x value.\n *\n * @param x - The x value to compute the curvature at.\n * @returns A function that takes a quadratic polynomial and returns the curvature of the polynomial at the given x value.\n * @since 1.0.0\n */\n (x: number): (p: QuadraticPolynomial) => number\n} = internal.curvature\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CA,MAAa,qBAA4DA;AAEzE,MAAaC,WAoBTC;;;;;;;;;AAUJ,MAAaC,SAAuDC;;;;;;;;AASpE,MAAaC,eAA+CC;;;;;;;;;AAU5D,MAAa,iBACXC;;;;;;;;;AAUF,MAAaC,eAA6DC;AAE1E,MAAaC,UAkBTC;;;;;;;;AASJ,MAAaC,aAA2DC;AAMxE,MAAaC,iBAyBTC;;;;;;;AAQJ,MAAaC,oBACXC;;;;;;;AAQF,MAAa,QAA6D,MACxEF,eAAsB,GAAG,EAAE;;;;;;;;AAS7B,MAAaG,iBAAgEC;;;;;;;;;AAU7E,MAAaC,gBACXC;;;;;;;;AASF,MAAaC,iBACXC;;;;;;;;AASF,MAAaC,iBACXC;;;;;;;;;AAUF,MAAaC,gBACXC;;;;;;;;;AAUF,MAAaC,iBACXC;;;;;;;;;AAUF,MAAaC,iBACXC;;;;;;;;AASF,MAAaC,iBACXC;;;;;;;;AASF,MAAaC,eAA8CC;AAE3D,MAAaC,mBAkBTC;AAEJ,MAAaC,WAkBTC;AAEJ,MAAaC,UAkBTC;;;;;;;;;;AAWJ,MAAaC,cAA6CC;AAE1D,MAAaC,WAkBTC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9TJ,MAAa,wBACXC;AAEF,MAAa,SAoBTC;;;;;;;;;;AAWJ,MAAa,OAAuEC;;;;;;;;AASpF,MAAa,aAAkDC;;;;;;;;;;;;AAa/D,MAAa,aACXC;AAEF,MAAa,QAkBTC;;;;;;;AAQJ,MAAa,WAA8DC;AAE3E,MAAa,eAkCTC;;;;;;;AAQJ,MAAa,kBAEoCC;;;;;;;;AASjD,MAAa,eACXC;;;;;;;;AASF,MAAa,aAA2DC;;;;;;;;AASxE,MAAa,QAAgEC;;;;;;;;AAS7E,MAAa,UAAsDC;AAEnE,MAAa,eAsBTC;;;;;;;;;;;AAYJ,MAAa,cAGTC;;;;;;AAOJ,MAAa,eAGTC;;;;;;AAOJ,MAAa,eAGTC;;;;;;;;;;AAWJ,MAAa,cAG6BC;;;;;;AAO1C,MAAa,eAG8BC;;;;;;AAO3C,MAAa,eAG8BC;AAE3C,MAAa,iBAkBTC;AAEJ,MAAa,SAkBTC;AAEJ,MAAa,QAkBTC;;;;;;;;;;AAWJ,MAAa,YAAgDC;AAE7D,MAAa,SAkBTC;AAEJ,MAAa,YAkBTC"}