curvy 2.0.0-alpha.0 → 2.0.0-alpha.4

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 (67) hide show
  1. package/dist/characteristic/index.d.mts +9 -9
  2. package/dist/characteristic/index.mjs +1 -1
  3. package/dist/curve/index.d.mts +10 -2
  4. package/dist/curve/index.mjs +1 -1
  5. package/dist/interval/index.d.mts +9 -2
  6. package/dist/interval/index.mjs +3 -2
  7. package/dist/matrix/index.d.mts +9 -2
  8. package/dist/number.mjs.map +1 -1
  9. package/dist/path/index.d.mts +16 -204
  10. package/dist/path/index.mjs +36 -3
  11. package/dist/path/index.mjs.map +1 -1
  12. package/dist/polynomial/index.d.mts +9 -2
  13. package/dist/polynomial/index.mjs +2 -2
  14. package/dist/shared/{characteristic-BGRxcxUH.mjs → characteristic-DLlhja-I.mjs} +9 -9
  15. package/dist/shared/{characteristic-BGRxcxUH.mjs.map → characteristic-DLlhja-I.mjs.map} +1 -1
  16. package/dist/shared/{cubic-CYYEUHNm.mjs → cubic-CMonq6bg.mjs} +27 -6
  17. package/dist/shared/cubic-CMonq6bg.mjs.map +1 -0
  18. package/dist/shared/cubic-DkBqcZf-.d.mts +121 -0
  19. package/dist/shared/interval-Bhzeqp8M.d.mts +62 -0
  20. package/dist/shared/{interval-CCEqzPgA.mjs → interval-X1EYuf-T.mjs} +48 -3
  21. package/dist/shared/interval-X1EYuf-T.mjs.map +1 -0
  22. package/dist/shared/interval2d-BMk5UYXD.d.mts +29 -0
  23. package/dist/shared/interval2d-ca0J1NMr.mjs +108 -0
  24. package/dist/shared/interval2d-ca0J1NMr.mjs.map +1 -0
  25. package/dist/shared/matrix4x4-CaytTaB_.d.mts +168 -0
  26. package/dist/shared/{quadratic-DEhuAKuE.mjs → quadratic-DyeMtvET.mjs} +21 -3
  27. package/dist/shared/quadratic-DyeMtvET.mjs.map +1 -0
  28. package/dist/shared/rationalCubic2d-D-UevGKu.d.mts +60 -0
  29. package/dist/shared/{rationalCubic2d-CP4oGpnk.mjs → rationalCubic2d-D658ltUM.mjs} +50 -13
  30. package/dist/shared/rationalCubic2d-D658ltUM.mjs.map +1 -0
  31. package/dist/shared/rationalCubic2d-MgMSJaAU.d.mts +104 -0
  32. package/dist/shared/{rationalCubic2d-CXa7Yren.mjs → rationalCubic2d-Vw4qGPZj.mjs} +24 -7
  33. package/dist/shared/rationalCubic2d-Vw4qGPZj.mjs.map +1 -0
  34. package/dist/shared/{solution-CbSWzXCn.mjs → solution-3TDATEMn.mjs} +28 -2
  35. package/dist/shared/solution-3TDATEMn.mjs.map +1 -0
  36. package/dist/shared/solution-DInDT2Hq.d.mts +60 -0
  37. package/dist/shared/{utils-DqTGyXrP.d.mts → utils-MCckigYk.d.mts} +1 -1
  38. package/dist/shared/{vector2-CL1HDdPr.mjs → vector2-CCuJx1rX.mjs} +6 -6
  39. package/dist/shared/{vector2-CL1HDdPr.mjs.map → vector2-CCuJx1rX.mjs.map} +1 -1
  40. package/dist/shared/vector2-euuV_bNQ.d.mts +58 -0
  41. package/dist/shared/vector3-3Xx7GVk7.d.mts +37 -0
  42. package/dist/shared/{vector3-D-tv_aKL.mjs → vector3-C-qgKAjR.mjs} +2 -2
  43. package/dist/shared/{vector3-D-tv_aKL.mjs.map → vector3-C-qgKAjR.mjs.map} +1 -1
  44. package/dist/shared/{vector4-5KbjoHVj.mjs → vector4-BhOKDhD5.mjs} +2 -2
  45. package/dist/shared/{vector4-5KbjoHVj.mjs.map → vector4-BhOKDhD5.mjs.map} +1 -1
  46. package/dist/solution/index.d.mts +7 -2
  47. package/dist/solution/index.mjs +1 -1
  48. package/dist/splines/index.d.mts +38 -607
  49. package/dist/splines/index.mjs +193 -35
  50. package/dist/splines/index.mjs.map +1 -1
  51. package/dist/utils.d.mts +1 -1
  52. package/dist/vector/index.d.mts +10 -2
  53. package/dist/vector/index.mjs +3 -3
  54. package/package.json +1 -1
  55. package/dist/shared/cubic-CYYEUHNm.mjs.map +0 -1
  56. package/dist/shared/cubic-Dfn6DB02.d.mts +0 -1099
  57. package/dist/shared/interval-CCEqzPgA.mjs.map +0 -1
  58. package/dist/shared/interval-hQDiKqj0.d.mts +0 -494
  59. package/dist/shared/matrix4x4-Bt_DBlP0.d.mts +0 -1182
  60. package/dist/shared/quadratic-DEhuAKuE.mjs.map +0 -1
  61. package/dist/shared/rationalCubic2d-BPLohNuI.d.mts +0 -787
  62. package/dist/shared/rationalCubic2d-CP4oGpnk.mjs.map +0 -1
  63. package/dist/shared/rationalCubic2d-CXa7Yren.mjs.map +0 -1
  64. package/dist/shared/rationalCubic2d-D_-XWxcm.d.mts +0 -297
  65. package/dist/shared/solution-BjoW7ov4.d.mts +0 -251
  66. package/dist/shared/solution-CbSWzXCn.mjs.map +0 -1
  67. package/dist/shared/vector2-TV0UnlxY.d.mts +0 -1168
@@ -1,6 +1,6 @@
1
- import { o as Vector4 } from "../shared/vector2-TV0UnlxY.mjs";
2
- import { t as Matrix4x4 } from "../shared/matrix4x4-Bt_DBlP0.mjs";
3
- import { t as CubicPolynomial } from "../shared/cubic-Dfn6DB02.mjs";
1
+ import { n as Vector4 } from "../shared/vector3-3Xx7GVk7.mjs";
2
+ import { t as Matrix4x4 } from "../shared/matrix4x4-CaytTaB_.mjs";
3
+ import { t as CubicPolynomial } from "../shared/cubic-DkBqcZf-.mjs";
4
4
 
5
5
  //#region src/characteristic/characteristic.d.ts
6
6
  declare namespace characteristic_d_exports {
@@ -14,7 +14,7 @@ declare namespace characteristic_d_exports {
14
14
  * IS the Bézier spline family — combined with control points (via {@link apply}),
15
15
  * it produces the cubic polynomial that parameterizes the curve.
16
16
  *
17
- * @since 2.1.0
17
+ * @since 2.0.0
18
18
  */
19
19
  declare const cubicBezier: Matrix4x4;
20
20
  /**
@@ -23,7 +23,7 @@ declare const cubicBezier: Matrix4x4;
23
23
  * Maps Hermite control data `(P₀, V₀, P₁, V₁)` — two endpoints and two
24
24
  * tangent vectors — to monomial cubic coefficients.
25
25
  *
26
- * @since 2.1.0
26
+ * @since 2.0.0
27
27
  */
28
28
  declare const cubicHermite: Matrix4x4;
29
29
  /**
@@ -34,7 +34,7 @@ declare const cubicHermite: Matrix4x4;
34
34
  * application produces a C² piecewise spline; the curve does not generally
35
35
  * pass through the control points.
36
36
  *
37
- * @since 2.1.0
37
+ * @since 2.0.0
38
38
  */
39
39
  declare const cubicBasisSpline: Matrix4x4;
40
40
  /**
@@ -52,7 +52,7 @@ declare const cubicBasisSpline: Matrix4x4;
52
52
  *
53
53
  * @param tension - The tension parameter.
54
54
  * @returns The characteristic matrix for that tension.
55
- * @since 2.1.0
55
+ * @since 2.0.0
56
56
  */
57
57
  declare const cubicCardinal: (tension: number) => Matrix4x4;
58
58
  /**
@@ -60,7 +60,7 @@ declare const cubicCardinal: (tension: number) => Matrix4x4;
60
60
  * The most common Cardinal-family variant; reused widely enough to deserve
61
61
  * a constant.
62
62
  *
63
- * @since 2.1.0
63
+ * @since 2.0.0
64
64
  */
65
65
  declare const cubicCatmullRom: Matrix4x4;
66
66
  /**
@@ -80,7 +80,7 @@ declare const cubicCatmullRom: Matrix4x4;
80
80
  * @param matrix - The characteristic matrix of the spline family.
81
81
  * @param channels - One `Vector4` per output polynomial, packing the four control values for that channel.
82
82
  * @returns A tuple of cubic polynomials, one per input channel.
83
- * @since 2.1.0
83
+ * @since 2.0.0
84
84
  */
85
85
  declare const apply: <const Channels extends ReadonlyArray<Vector4>>(matrix: Matrix4x4, ...channels: Channels) => { readonly [K in keyof Channels]: CubicPolynomial };
86
86
  //#endregion
@@ -1,2 +1,2 @@
1
- import { n as characteristic_exports } from "../shared/characteristic-BGRxcxUH.mjs";
1
+ import { n as characteristic_exports } from "../shared/characteristic-DLlhja-I.mjs";
2
2
  export { characteristic_exports as Characteristic };
@@ -1,2 +1,10 @@
1
- import { c as linear2d_d_exports, i as cubic2d_d_exports, n as rationalCubic2d_d_exports, o as quadratic2d_d_exports } from "../shared/rationalCubic2d-BPLohNuI.mjs";
2
- export { cubic2d_d_exports as CubicCurve2d, linear2d_d_exports as LinearCurve2d, quadratic2d_d_exports as QuadraticCurve2d, rationalCubic2d_d_exports as RationalCubicCurve2d };
1
+ import { i as LinearCurve2d$1, n as CubicCurve2d$1, r as QuadraticCurve2d$1, t as RationalCubicCurve2d$1 } from "../shared/rationalCubic2d-MgMSJaAU.mjs";
2
+
3
+ //#region src/curve/index.d.ts
4
+ type LinearCurve2d = LinearCurve2d$1;
5
+ type QuadraticCurve2d = QuadraticCurve2d$1;
6
+ type CubicCurve2d = CubicCurve2d$1;
7
+ type RationalCubicCurve2d = RationalCubicCurve2d$1;
8
+ //#endregion
9
+ export { CubicCurve2d, LinearCurve2d, QuadraticCurve2d, RationalCubicCurve2d };
10
+ //# sourceMappingURL=index.d.mts.map
@@ -1,2 +1,2 @@
1
- import { a as cubic2d_exports, d as quadratic2d_exports, m as linear2d_exports, r as rationalCubic2d_exports } from "../shared/rationalCubic2d-CP4oGpnk.mjs";
1
+ import { m as quadratic2d_exports, o as cubic2d_exports, r as rationalCubic2d_exports, v as linear2d_exports } from "../shared/rationalCubic2d-D658ltUM.mjs";
2
2
  export { cubic2d_exports as CubicCurve2d, linear2d_exports as LinearCurve2d, quadratic2d_exports as QuadraticCurve2d, rationalCubic2d_exports as RationalCubicCurve2d };
@@ -1,2 +1,9 @@
1
- import { n as interval_d_exports } from "../shared/interval-hQDiKqj0.mjs";
2
- export { interval_d_exports as Interval };
1
+ import { t as Interval$1 } from "../shared/interval-Bhzeqp8M.mjs";
2
+ import { t as Interval2d$1 } from "../shared/interval2d-BMk5UYXD.mjs";
3
+
4
+ //#region src/interval/index.d.ts
5
+ type Interval = Interval$1;
6
+ type Interval2d = Interval2d$1;
7
+ //#endregion
8
+ export { Interval, Interval2d };
9
+ //# sourceMappingURL=index.d.mts.map
@@ -1,2 +1,3 @@
1
- import { a as interval_exports } from "../shared/interval-CCEqzPgA.mjs";
2
- export { interval_exports as Interval };
1
+ import { s as interval_exports } from "../shared/interval-X1EYuf-T.mjs";
2
+ import { t as interval2d_exports } from "../shared/interval2d-ca0J1NMr.mjs";
3
+ export { interval_exports as Interval, interval2d_exports as Interval2d };
@@ -1,2 +1,9 @@
1
- import { i as matrix2x2_d_exports, n as matrix4x4_d_exports, r as matrix3x3_d_exports } from "../shared/matrix4x4-Bt_DBlP0.mjs";
2
- export { matrix2x2_d_exports as Matrix2x2, matrix3x3_d_exports as Matrix3x3, matrix4x4_d_exports as Matrix4x4 };
1
+ import { n as Matrix3x3$1, r as Matrix2x2$1, t as Matrix4x4$1 } from "../shared/matrix4x4-CaytTaB_.mjs";
2
+
3
+ //#region src/matrix/index.d.ts
4
+ type Matrix2x2 = Matrix2x2$1;
5
+ type Matrix3x3 = Matrix3x3$1;
6
+ type Matrix4x4 = Matrix4x4$1;
7
+ //#endregion
8
+ export { Matrix2x2, Matrix3x3, Matrix4x4 };
9
+ //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"number.mjs","names":[],"sources":["../src/number.ts"],"sourcesContent":["import { dual } from './utils'\n\nconst PRECISION = 8\n\n/**\n * Default tolerance for approximate equality between floating-point numbers.\n *\n * @since 1.1.0\n */\nexport const EPSILON = 1e-10\n\n/**\n * Approximate equality between two numbers, within an absolute tolerance.\n *\n * @param a - The first value.\n * @param b - The second value.\n * @param eps - The maximum allowed absolute difference. Defaults to {@link EPSILON}.\n * @returns `true` when `|a - b| <= eps`.\n * @since 1.1.0\n */\nexport function epsEquals(a: number, b: number, eps: number = EPSILON): boolean {\n return Math.abs(a - b) <= eps\n}\n\n/**\n * Snaps near-zero values to exactly zero for stable sign tests.\n *\n * @param value - The value to test.\n * @param eps - The threshold below which `value` is considered zero.\n * @returns `0` when `|value| < eps`, otherwise `value` unchanged.\n * @since 1.1.0\n */\nexport function clampToZero(value: number, eps: number): number {\n return Math.abs(value) < eps ? 0 : value\n}\n\n/**\n * Rounding function that rounds a number to a specified precision.\n *\n * @param value - The number to round.\n * @param precision - The number of decimal places to round to (default is 8).\n * @returns The rounded number.\n * @example\n * ```ts\n * import { round } from 'curvy/utils'\n *\n * const roundedValue = round(1.23456789, 4) // 1.2346\n * const roundedValue2 = round(1.23456789) // 1.23456789\n * ```\n * @since 1.0.0\n */\nexport function round(value: number, precision = PRECISION): number {\n const scale = 10 ** precision\n const result = Math.round(value * scale) / scale\n if (result === 0) {\n return 0\n }\n return result\n}\n\n/**\n * Rounding function that rounds a number down to a specified precision.\n *\n * @param value - The number to round down.\n * @param precision - The number of decimal places to round down to (default is 8).\n * @returns The rounded down number.\n * @example\n * ```ts\n * import { roundDown } from 'curvy/utils'\n *\n * const roundedDownValue = roundDown(1.23456789, 4) // 1.2345\n * const roundedDownValue2 = roundDown(1.23456789) // 1.23456789\n * ```\n * @since 1.0.0\n */\nexport function roundDown(value: number, precision = PRECISION): number {\n const scale = 10 ** precision\n const result = Math.floor(value * scale) / scale\n if (result === 0) {\n return 0\n }\n return result\n}\n\n/**\n * Rounding function that rounds a number up to a specified precision.\n *\n * @param value - The number to round up.\n * @param precision - The number of decimal places to round up to (default is 8).\n * @returns The rounded up number.\n * @example\n * ```ts\n * import { roundUp } from 'curvy/utils'\n *\n * const roundedUpValue = roundUp(1.23456789, 4) // 1.2346\n * const roundedUpValue2 = roundUp(1.23456789) // 1.23456789\n * ```\n * @since 1.0.0\n */\nexport function roundUp(value: number, precision = PRECISION): number {\n const scale = 10 ** precision\n const result = Math.ceil(value * scale) / scale\n if (result === 0) {\n return 0\n }\n return result\n}\n\nexport const lerp: {\n /**\n * Linearly interpolates between two values.\n *\n * @param t - The interpolation factor (between 0 and 1).\n * @param a - The start value.\n * @param b - The end value.\n * @returns The interpolated value.\n * @example\n * ```ts\n * import { lerp } from 'curvy/utils'\n *\n * lerp(0.5, 10, 20) // 15\n * ```\n * @since 1.0.0\n */\n (t: number, a: number, b: number): number\n /**\n * Linearly interpolates between two values.\n *\n * @param a - The start value.\n * @param b - The end value.\n * @returns A function that takes the interpolation factor and returns the interpolated value.\n * @example\n * ```ts\n * import { lerp } from 'curvy/utils'\n *\n * lerp(10, 20)(0.5) // 15\n * ```\n * @since 1.0.0\n */\n (a: number, b: number): (t: number) => number\n} = dual(3, (t: number, a: number, b: number) => b * t + a * (1 - t))\n\nexport const normalize: {\n /**\n * Normalizes a value between two bounds to the unit interval.\n *\n * @param x - The value to normalize.\n * @param a - The lower bound.\n * @param b - The upper bound.\n * @returns The normalized value.\n * @example\n * ```ts\n * import { normalize } from 'curvy/utils'\n *\n * normalize(15, 10, 20) // 0.5\n * ```\n * @since 1.0.0\n */\n (x: number, a: number, b: number): number\n /**\n * Normalizes a value between two bounds to the unit interval.\n *\n * @param a - The lower bound.\n * @param b - The upper bound.\n * @returns A function that takes a value and returns the normalized value.\n * @example\n * ```ts\n * import { normalize } from 'curvy/utils'\n *\n * normalize(10, 20)(15) // 0.5\n * ```\n * @since 1.0.0\n */\n (a: number, b: number): (x: number) => number\n} = dual(3, (x: number, a: number, b: number) => (x - a) / (b - a))\n\nexport const remap: {\n /**\n * Remaps a value from one range to another.\n *\n * @param x - The value to remap.\n * @param x1 - The lower bound of the original range.\n * @param x2 - The upper bound of the original range.\n * @param y1 - The lower bound of the new range.\n * @param y2 - The upper bound of the new range.\n * @returns The remapped value.\n * @example\n * ```ts\n * import { remap } from 'curvy/utils'\n *\n * remap(15, 10, 20, 0, 100) // 50\n * ```\n * @since 1.0.0\n */\n (x: number, x1: number, x2: number, y1: number, y2: number): number\n /**\n * Remaps a value from one range to another.\n *\n * @param x1 - The lower bound of the original range.\n * @param x2 - The upper bound of the original range.\n * @param y1 - The lower bound of the new range.\n * @param y2 - The upper bound of the new range.\n * @returns A function that takes a value and returns the remapped value.\n * @example\n * ```ts\n * import { remap } from 'curvy/utils'\n *\n * remap(10, 20, 0, 100)(15) // 50\n * ```\n * @since 1.0.0\n */\n (x1: number, x2: number, y1: number, y2: number): (x: number) => number\n} = dual(\n 5,\n (x: number, x1: number, x2: number, y1: number, y2: number) =>\n y1 + ((x - x1) / (x2 - x1)) * (y2 - y1),\n)\n\nexport const clamp: {\n /**\n * Clamps a value between two bounds.\n *\n * @param value - The value to clamp.\n * @param min - The lower bound.\n * @param max - The upper bound.\n * @returns The clamped value.\n * @example\n * ```ts\n * import { clamp } from 'curvy/utils'\n *\n * clamp(25, 10, 20) // 20\n * ```\n * @since 1.0.0\n */\n (value: number, min: number, max: number): number\n /**\n * Clamps a value between two bounds.\n *\n * @param min - The lower bound.\n * @param max - The upper bound.\n * @returns A function that takes a value and returns the clamped value.\n * @example\n * ```ts\n * import { clamp } from 'curvy/utils'\n *\n * clamp(10, 20)(25) // 20\n * ```\n * @since 1.0.0\n */\n (min: number, max: number): (value: number) => number\n} = dual(3, (value: number, min: number, max: number) =>\n value < min ? min : value > max ? max : value,\n)\n\nexport const clip: {\n /**\n * Clips a value to a specified range, returning a fallback value if the value is outside the range.\n *\n * @param value - The value to clip.\n * @param min - The lower bound.\n * @param max - The upper bound.\n * @param onClip - The fallback value to return if the value is outside the range.\n * @returns The original value if within range, otherwise the fallback.\n * @example\n * ```ts\n * import { clip } from 'curvy/utils'\n *\n * clip(25, 10, 20, 15) // 15\n * ```\n * @since 1.0.0\n */\n <T>(value: number, min: number, max: number, onClip: T): T | number\n /**\n * Clips a value to a specified range, returning a fallback value if the value is outside the range.\n *\n * @param min - The lower bound.\n * @param max - The upper bound.\n * @param onClip - The fallback value to return if the value is outside the range.\n * @returns A function that takes a value and returns it if within range, otherwise the fallback.\n * @example\n * ```ts\n * import { clip } from 'curvy/utils'\n *\n * clip(10, 20, 15)(25) // 15\n * ```\n * @since 1.0.0\n */\n <T>(min: number, max: number, onClip: T): (value: number) => T | number\n} = dual(4, (value: number, min: number, max: number, onClip: unknown) =>\n value < min ? onClip : value > max ? onClip : value,\n)\n\n/**\n * Returns the minimum and maximum of two numbers.\n *\n * @param a - The first number.\n * @param b - The second number.\n * @returns A tuple containing the minimum and maximum values.\n * @example\n * ```ts\n * import { minMax } from 'curvy/utils'\n *\n * const [minValue, maxValue] = minMax(10, 20) // [10, 20]\n * const [minValue2, maxValue2] = minMax(20, 10) // [10, 20]\n * ```\n * @since 1.0.0\n */\nexport function minMax(a: number, b: number): [number, number] {\n return a < b ? [a, b] : [b, a]\n}\n\n/**\n * Calculates the modulus of a number.\n *\n * @param n - The number to calculate the modulus of.\n * @param m - The modulus.\n * @returns The modulus of the number.\n * @example\n * ```ts\n * import { mod } from 'curvy/utils'\n *\n * const modulus = mod(10, 3) // 1\n * const modulus2 = mod(-10, 3) // 2\n * ```\n * @since 1.0.0\n */\nexport function mod(n: number, m: number): number {\n return ((n % m) + m) % m\n}\n\n"],"mappings":";;AAEA,MAAM,YAAY;;;;;;AAOlB,MAAa,UAAU;;;;;;;;;;AAWvB,SAAgB,UAAU,GAAW,GAAW,MAAc,SAAkB;CAC9E,OAAO,KAAK,IAAI,IAAI,EAAE,IAAI;;;;;;;;;;AAW5B,SAAgB,YAAY,OAAe,KAAqB;CAC9D,OAAO,KAAK,IAAI,MAAM,GAAG,MAAM,IAAI;;;;;;;;;;;;;;;;;AAkBrC,SAAgB,MAAM,OAAe,YAAY,WAAmB;CAClE,MAAM,QAAQ,MAAM;CACpB,MAAM,SAAS,KAAK,MAAM,QAAQ,MAAM,GAAG;CAC3C,IAAI,WAAW,GACb,OAAO;CAET,OAAO;;;;;;;;;;;;;;;;;AAkBT,SAAgB,UAAU,OAAe,YAAY,WAAmB;CACtE,MAAM,QAAQ,MAAM;CACpB,MAAM,SAAS,KAAK,MAAM,QAAQ,MAAM,GAAG;CAC3C,IAAI,WAAW,GACb,OAAO;CAET,OAAO;;;;;;;;;;;;;;;;;AAkBT,SAAgB,QAAQ,OAAe,YAAY,WAAmB;CACpE,MAAM,QAAQ,MAAM;CACpB,MAAM,SAAS,KAAK,KAAK,QAAQ,MAAM,GAAG;CAC1C,IAAI,WAAW,GACb,OAAO;CAET,OAAO;;AAGT,MAAa,OAgCT,KAAK,IAAI,GAAW,GAAW,MAAc,IAAI,IAAI,KAAK,IAAI,GAAG;AAErE,MAAa,YAgCT,KAAK,IAAI,GAAW,GAAW,OAAe,IAAI,MAAM,IAAI,GAAG;AAEnE,MAAa,QAoCT,KACF,IACC,GAAW,IAAY,IAAY,IAAY,OAC9C,MAAO,IAAI,OAAO,KAAK,OAAQ,KAAK,IACvC;AAED,MAAa,QAgCT,KAAK,IAAI,OAAe,KAAa,QACvC,QAAQ,MAAM,MAAM,QAAQ,MAAM,MAAM,MACzC;AAED,MAAa,OAkCT,KAAK,IAAI,OAAe,KAAa,KAAa,WACpD,QAAQ,MAAM,SAAS,QAAQ,MAAM,SAAS,MAC/C;;;;;;;;;;;;;;;;AAiBD,SAAgB,OAAO,GAAW,GAA6B;CAC7D,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE;;;;;;;;;;;;;;;;;AAkBhC,SAAgB,IAAI,GAAW,GAAmB;CAChD,QAAS,IAAI,IAAK,KAAK"}
1
+ {"version":3,"file":"number.mjs","names":[],"sources":["../src/number.ts"],"sourcesContent":["import { dual } from './utils'\n\nconst PRECISION = 8\n\n/**\n * Default tolerance for approximate equality between floating-point numbers.\n *\n * @since 1.1.0\n */\nexport const EPSILON = 1e-10\n\n/**\n * Approximate equality between two numbers, within an absolute tolerance.\n *\n * @param a - The first value.\n * @param b - The second value.\n * @param eps - The maximum allowed absolute difference. Defaults to {@link EPSILON}.\n * @returns `true` when `|a - b| <= eps`.\n * @since 1.1.0\n */\nexport function epsEquals(a: number, b: number, eps: number = EPSILON): boolean {\n return Math.abs(a - b) <= eps\n}\n\n/**\n * Snaps near-zero values to exactly zero for stable sign tests.\n *\n * @param value - The value to test.\n * @param eps - The threshold below which `value` is considered zero.\n * @returns `0` when `|value| < eps`, otherwise `value` unchanged.\n * @since 1.1.0\n */\nexport function clampToZero(value: number, eps: number): number {\n return Math.abs(value) < eps ? 0 : value\n}\n\n/**\n * Rounding function that rounds a number to a specified precision.\n *\n * @param value - The number to round.\n * @param precision - The number of decimal places to round to (default is 8).\n * @returns The rounded number.\n * @example\n * ```ts\n * import { round } from 'curvy/utils'\n *\n * const roundedValue = round(1.23456789, 4) // 1.2346\n * const roundedValue2 = round(1.23456789) // 1.23456789\n * ```\n * @since 1.0.0\n */\nexport function round(value: number, precision = PRECISION): number {\n const scale = 10 ** precision\n const result = Math.round(value * scale) / scale\n if (result === 0) {\n return 0\n }\n return result\n}\n\n/**\n * Rounding function that rounds a number down to a specified precision.\n *\n * @param value - The number to round down.\n * @param precision - The number of decimal places to round down to (default is 8).\n * @returns The rounded down number.\n * @example\n * ```ts\n * import { roundDown } from 'curvy/utils'\n *\n * const roundedDownValue = roundDown(1.23456789, 4) // 1.2345\n * const roundedDownValue2 = roundDown(1.23456789) // 1.23456789\n * ```\n * @since 1.0.0\n */\nexport function roundDown(value: number, precision = PRECISION): number {\n const scale = 10 ** precision\n const result = Math.floor(value * scale) / scale\n if (result === 0) {\n return 0\n }\n return result\n}\n\n/**\n * Rounding function that rounds a number up to a specified precision.\n *\n * @param value - The number to round up.\n * @param precision - The number of decimal places to round up to (default is 8).\n * @returns The rounded up number.\n * @example\n * ```ts\n * import { roundUp } from 'curvy/utils'\n *\n * const roundedUpValue = roundUp(1.23456789, 4) // 1.2346\n * const roundedUpValue2 = roundUp(1.23456789) // 1.23456789\n * ```\n * @since 1.0.0\n */\nexport function roundUp(value: number, precision = PRECISION): number {\n const scale = 10 ** precision\n const result = Math.ceil(value * scale) / scale\n if (result === 0) {\n return 0\n }\n return result\n}\n\nexport const lerp: {\n /**\n * Linearly interpolates between two values.\n *\n * @param t - The interpolation factor (between 0 and 1).\n * @param a - The start value.\n * @param b - The end value.\n * @returns The interpolated value.\n * @example\n * ```ts\n * import { lerp } from 'curvy/utils'\n *\n * lerp(0.5, 10, 20) // 15\n * ```\n * @since 1.0.0\n */\n (t: number, a: number, b: number): number\n /**\n * Linearly interpolates between two values.\n *\n * @param a - The start value.\n * @param b - The end value.\n * @returns A function that takes the interpolation factor and returns the interpolated value.\n * @example\n * ```ts\n * import { lerp } from 'curvy/utils'\n *\n * lerp(10, 20)(0.5) // 15\n * ```\n * @since 1.0.0\n */\n (a: number, b: number): (t: number) => number\n} = dual(3, (t: number, a: number, b: number) => b * t + a * (1 - t))\n\nexport const normalize: {\n /**\n * Normalizes a value between two bounds to the unit interval.\n *\n * @param x - The value to normalize.\n * @param a - The lower bound.\n * @param b - The upper bound.\n * @returns The normalized value.\n * @example\n * ```ts\n * import { normalize } from 'curvy/utils'\n *\n * normalize(15, 10, 20) // 0.5\n * ```\n * @since 1.0.0\n */\n (x: number, a: number, b: number): number\n /**\n * Normalizes a value between two bounds to the unit interval.\n *\n * @param a - The lower bound.\n * @param b - The upper bound.\n * @returns A function that takes a value and returns the normalized value.\n * @example\n * ```ts\n * import { normalize } from 'curvy/utils'\n *\n * normalize(10, 20)(15) // 0.5\n * ```\n * @since 1.0.0\n */\n (a: number, b: number): (x: number) => number\n} = dual(3, (x: number, a: number, b: number) => (x - a) / (b - a))\n\nexport const remap: {\n /**\n * Remaps a value from one range to another.\n *\n * @param x - The value to remap.\n * @param x1 - The lower bound of the original range.\n * @param x2 - The upper bound of the original range.\n * @param y1 - The lower bound of the new range.\n * @param y2 - The upper bound of the new range.\n * @returns The remapped value.\n * @example\n * ```ts\n * import { remap } from 'curvy/utils'\n *\n * remap(15, 10, 20, 0, 100) // 50\n * ```\n * @since 1.0.0\n */\n (x: number, x1: number, x2: number, y1: number, y2: number): number\n /**\n * Remaps a value from one range to another.\n *\n * @param x1 - The lower bound of the original range.\n * @param x2 - The upper bound of the original range.\n * @param y1 - The lower bound of the new range.\n * @param y2 - The upper bound of the new range.\n * @returns A function that takes a value and returns the remapped value.\n * @example\n * ```ts\n * import { remap } from 'curvy/utils'\n *\n * remap(10, 20, 0, 100)(15) // 50\n * ```\n * @since 1.0.0\n */\n (x1: number, x2: number, y1: number, y2: number): (x: number) => number\n} = dual(\n 5,\n (x: number, x1: number, x2: number, y1: number, y2: number) =>\n y1 + ((x - x1) / (x2 - x1)) * (y2 - y1),\n)\n\nexport const clamp: {\n /**\n * Clamps a value between two bounds.\n *\n * @param value - The value to clamp.\n * @param min - The lower bound.\n * @param max - The upper bound.\n * @returns The clamped value.\n * @example\n * ```ts\n * import { clamp } from 'curvy/utils'\n *\n * clamp(25, 10, 20) // 20\n * ```\n * @since 1.0.0\n */\n (value: number, min: number, max: number): number\n /**\n * Clamps a value between two bounds.\n *\n * @param min - The lower bound.\n * @param max - The upper bound.\n * @returns A function that takes a value and returns the clamped value.\n * @example\n * ```ts\n * import { clamp } from 'curvy/utils'\n *\n * clamp(10, 20)(25) // 20\n * ```\n * @since 1.0.0\n */\n (min: number, max: number): (value: number) => number\n} = dual(3, (value: number, min: number, max: number) =>\n value < min ? min : value > max ? max : value,\n)\n\nexport const clip: {\n /**\n * Clips a value to a specified range, returning a fallback value if the value is outside the range.\n *\n * @param value - The value to clip.\n * @param min - The lower bound.\n * @param max - The upper bound.\n * @param onClip - The fallback value to return if the value is outside the range.\n * @returns The original value if within range, otherwise the fallback.\n * @example\n * ```ts\n * import { clip } from 'curvy/utils'\n *\n * clip(25, 10, 20, 15) // 15\n * ```\n * @since 1.0.0\n */\n <T>(value: number, min: number, max: number, onClip: T): T | number\n /**\n * Clips a value to a specified range, returning a fallback value if the value is outside the range.\n *\n * @param min - The lower bound.\n * @param max - The upper bound.\n * @param onClip - The fallback value to return if the value is outside the range.\n * @returns A function that takes a value and returns it if within range, otherwise the fallback.\n * @example\n * ```ts\n * import { clip } from 'curvy/utils'\n *\n * clip(10, 20, 15)(25) // 15\n * ```\n * @since 1.0.0\n */\n <T>(min: number, max: number, onClip: T): (value: number) => T | number\n} = dual(4, (value: number, min: number, max: number, onClip: unknown) =>\n value < min ? onClip : value > max ? onClip : value,\n)\n\n/**\n * Returns the minimum and maximum of two numbers.\n *\n * @param a - The first number.\n * @param b - The second number.\n * @returns A tuple containing the minimum and maximum values.\n * @example\n * ```ts\n * import { minMax } from 'curvy/utils'\n *\n * const [minValue, maxValue] = minMax(10, 20) // [10, 20]\n * const [minValue2, maxValue2] = minMax(20, 10) // [10, 20]\n * ```\n * @since 1.0.0\n */\nexport function minMax(a: number, b: number): [number, number] {\n return a < b ? [a, b] : [b, a]\n}\n\n/**\n * Calculates the modulus of a number.\n *\n * @param n - The number to calculate the modulus of.\n * @param m - The modulus.\n * @returns The modulus of the number.\n * @example\n * ```ts\n * import { mod } from 'curvy/utils'\n *\n * const modulus = mod(10, 3) // 1\n * const modulus2 = mod(-10, 3) // 2\n * ```\n * @since 1.0.0\n */\nexport function mod(n: number, m: number): number {\n return ((n % m) + m) % m\n}\n"],"mappings":";;AAEA,MAAM,YAAY;;;;;;AAOlB,MAAa,UAAU;;;;;;;;;;AAWvB,SAAgB,UAAU,GAAW,GAAW,MAAc,SAAkB;CAC9E,OAAO,KAAK,IAAI,IAAI,EAAE,IAAI;;;;;;;;;;AAW5B,SAAgB,YAAY,OAAe,KAAqB;CAC9D,OAAO,KAAK,IAAI,MAAM,GAAG,MAAM,IAAI;;;;;;;;;;;;;;;;;AAkBrC,SAAgB,MAAM,OAAe,YAAY,WAAmB;CAClE,MAAM,QAAQ,MAAM;CACpB,MAAM,SAAS,KAAK,MAAM,QAAQ,MAAM,GAAG;CAC3C,IAAI,WAAW,GACb,OAAO;CAET,OAAO;;;;;;;;;;;;;;;;;AAkBT,SAAgB,UAAU,OAAe,YAAY,WAAmB;CACtE,MAAM,QAAQ,MAAM;CACpB,MAAM,SAAS,KAAK,MAAM,QAAQ,MAAM,GAAG;CAC3C,IAAI,WAAW,GACb,OAAO;CAET,OAAO;;;;;;;;;;;;;;;;;AAkBT,SAAgB,QAAQ,OAAe,YAAY,WAAmB;CACpE,MAAM,QAAQ,MAAM;CACpB,MAAM,SAAS,KAAK,KAAK,QAAQ,MAAM,GAAG;CAC1C,IAAI,WAAW,GACb,OAAO;CAET,OAAO;;AAGT,MAAa,OAgCT,KAAK,IAAI,GAAW,GAAW,MAAc,IAAI,IAAI,KAAK,IAAI,GAAG;AAErE,MAAa,YAgCT,KAAK,IAAI,GAAW,GAAW,OAAe,IAAI,MAAM,IAAI,GAAG;AAEnE,MAAa,QAoCT,KACF,IACC,GAAW,IAAY,IAAY,IAAY,OAC9C,MAAO,IAAI,OAAO,KAAK,OAAQ,KAAK,IACvC;AAED,MAAa,QAgCT,KAAK,IAAI,OAAe,KAAa,QACvC,QAAQ,MAAM,MAAM,QAAQ,MAAM,MAAM,MACzC;AAED,MAAa,OAkCT,KAAK,IAAI,OAAe,KAAa,KAAa,WACpD,QAAQ,MAAM,SAAS,QAAQ,MAAM,SAAS,MAC/C;;;;;;;;;;;;;;;;AAiBD,SAAgB,OAAO,GAAW,GAA6B;CAC7D,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE;;;;;;;;;;;;;;;;;AAkBhC,SAAgB,IAAI,GAAW,GAAmB;CAChD,QAAS,IAAI,IAAK,KAAK"}
@@ -1,14 +1,12 @@
1
- import { t as Vector2 } from "../shared/vector2-TV0UnlxY.mjs";
2
- import { t as Pipeable } from "../shared/utils-DqTGyXrP.mjs";
3
- import { a as QuadraticCurve2d, s as LinearCurve2d } from "../shared/rationalCubic2d-BPLohNuI.mjs";
4
- import { a as Continuous, i as cubic2d_d_exports, n as rationalCubic2d_d_exports, o as PathTraits } from "../shared/rationalCubic2d-D_-XWxcm.mjs";
1
+ import { t as Pipeable } from "../shared/utils-MCckigYk.mjs";
2
+ import { i as LinearCurve2d, r as QuadraticCurve2d } from "../shared/rationalCubic2d-MgMSJaAU.mjs";
3
+ import { n as CubicPath2d$1, r as PathTraits, t as RationalCubicPath2d$1 } from "../shared/rationalCubic2d-D-UevGKu.mjs";
5
4
 
6
5
  //#region src/path/linear2d.internal.d.ts
7
6
  declare const LinearPath2dTypeId: unique symbol;
8
7
  type LinearPath2dTypeId = typeof LinearPath2dTypeId;
9
- declare namespace linear2d_d_exports {
10
- export { Continuous, LinearPath2d, append$1 as append, asContinuous$1 as asContinuous, fromArray$1 as fromArray, isContinuous$1 as isContinuous, isLinearPath2d, length$1 as length, make$1 as make, solve$1 as solve, toPathData$1 as toPathData };
11
- }
8
+ //#endregion
9
+ //#region src/path/linear2d.d.ts
12
10
  /**
13
11
  * A linear path in 2D space.
14
12
  *
@@ -20,116 +18,16 @@ declare namespace linear2d_d_exports {
20
18
  *
21
19
  * @since 1.0.0
22
20
  */
23
- interface LinearPath2d<out Trait = unknown> extends Pipeable, Iterable<LinearCurve2d> {
21
+ interface LinearPath2d$1<out Trait = unknown> extends Pipeable, Iterable<LinearCurve2d> {
24
22
  readonly [LinearPath2dTypeId]: LinearPath2dTypeId;
25
23
  readonly [PathTraits]: Trait;
26
24
  }
27
- /**
28
- * Creates a new `LinearPath2d` instance from a sequence of curves.
29
- *
30
- * @param curves - The curves to create the path from.
31
- * @returns A new `LinearPath2d` instance.
32
- * @since 2.0.0
33
- */
34
- declare const make$1: (...curves: ReadonlyArray<LinearCurve2d>) => LinearPath2d;
35
- /**
36
- * Creates a new `LinearPath2d` instance from an array of curves.
37
- *
38
- * @param curves - The curves to create the path from.
39
- * @returns A new `LinearPath2d` instance.
40
- * @since 2.0.0
41
- */
42
- declare const fromArray$1: (curves: ReadonlyArray<LinearCurve2d>) => LinearPath2d;
43
- /**
44
- * Checks if a value is a `LinearPath2d`.
45
- *
46
- * @param p - The value to check.
47
- * @returns `true` if the value is a `LinearPath2d`, `false` otherwise.
48
- * @since 1.0.0
49
- */
50
- declare const isLinearPath2d: (p: unknown) => p is LinearPath2d;
51
- declare const append$1: {
52
- /**
53
- * Appends a linear curve to a linear path.
54
- *
55
- * @param c - The linear curve to append.
56
- * @returns A function that takes a linear path and returns a new linear path.
57
- * @since 1.0.0
58
- */
59
- (c: LinearCurve2d): (p: LinearPath2d) => LinearPath2d;
60
- /**
61
- * Appends a linear curve to a linear path.
62
- *
63
- * @param p - The linear path to append to.
64
- * @param c - The linear curve to append.
65
- * @returns A new `LinearPath2d` instance with the appended curve.
66
- * @since 1.0.0
67
- */
68
- (p: LinearPath2d, c: LinearCurve2d): LinearPath2d;
69
- };
70
- /**
71
- * Calculates the length of a linear path.
72
- *
73
- * @param p - The linear path to calculate the length of.
74
- * @returns The length of the linear path.
75
- * @since 1.0.0
76
- */
77
- declare const length$1: (p: LinearPath2d) => number;
78
- declare const solve$1: {
79
- /**
80
- * Solves a linear path for a given parameter.
81
- *
82
- * @param u - The parameter to solve for.
83
- * @returns A function that takes a linear path and returns the solved point.
84
- * @since 1.0.0
85
- */
86
- (u: number): (p: LinearPath2d) => Vector2;
87
- /**
88
- * Solves a linear path for a given parameter.
89
- *
90
- * @param p - The linear path to solve.
91
- * @param u - The parameter to solve for.
92
- * @returns The solved point on the linear path.
93
- * @since 1.0.0
94
- */
95
- (p: LinearPath2d, u: number): Vector2;
96
- };
97
- /**
98
- * Serializes a linear path as an SVG path data string (the value of a `<path>`
99
- * element's `d` attribute), using `M` and `L` commands. Discontinuities between
100
- * curves emit a fresh `M` command.
101
- *
102
- * @param p - The linear path to serialize.
103
- * @returns The SVG path data string.
104
- * @since 2.0.0
105
- */
106
- declare const toPathData$1: (p: LinearPath2d) => string;
107
- /**
108
- * Type-narrowing predicate: refines `LinearPath2d<T>` to
109
- * `LinearPath2d<T & Continuous>` when adjacent curves connect at their join
110
- * points.
111
- *
112
- * @param p - The linear path to check.
113
- * @returns `true` when the path is continuous (G⁰).
114
- * @since 2.0.0
115
- */
116
- declare const isContinuous$1: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & Continuous>;
117
- /**
118
- * Asserts that the linear path is continuous, throwing on failure.
119
- *
120
- * @param p - The linear path to assert against.
121
- * @returns The same path, typed with the `Continuous` brand.
122
- * @throws When the path has a discontinuity between adjacent curves.
123
- * @since 2.0.0
124
- */
125
- declare const asContinuous$1: <T>(p: LinearPath2d<T>) => LinearPath2d<T & Continuous>;
126
25
  //#endregion
127
26
  //#region src/path/quadratic2d.internal.d.ts
128
27
  declare const QuadraticPath2dTypeId: unique symbol;
129
28
  type QuadraticPath2dTypeId = typeof QuadraticPath2dTypeId;
130
- declare namespace quadratic2d_d_exports {
131
- export { Continuous, QuadraticPath2d, append, asContinuous, fromArray, isContinuous, isQuadraticPath2d, length, make, solve, toPathData };
132
- }
29
+ //#endregion
30
+ //#region src/path/quadratic2d.d.ts
133
31
  /**
134
32
  * A quadratic path in 2D space.
135
33
  *
@@ -140,102 +38,16 @@ declare namespace quadratic2d_d_exports {
140
38
  *
141
39
  * @since 1.0.0
142
40
  */
143
- interface QuadraticPath2d<out Trait = unknown> extends Pipeable, Iterable<QuadraticCurve2d> {
41
+ interface QuadraticPath2d$1<out Trait = unknown> extends Pipeable, Iterable<QuadraticCurve2d> {
144
42
  readonly [QuadraticPath2dTypeId]: QuadraticPath2dTypeId;
145
43
  readonly [PathTraits]: Trait;
146
44
  }
147
- /**
148
- * Creates a new `QuadraticPath2d` instance from a sequence of curves.
149
- *
150
- * @param curves - The curves to create the path from.
151
- * @returns A new `QuadraticPath2d` instance.
152
- * @since 2.0.0
153
- */
154
- declare const make: (...curves: ReadonlyArray<QuadraticCurve2d>) => QuadraticPath2d;
155
- /**
156
- * Creates a new `QuadraticPath2d` instance from an array of curves.
157
- *
158
- * @param curves - The curves to create the path from.
159
- * @returns A new `QuadraticPath2d` instance.
160
- * @since 2.0.0
161
- */
162
- declare const fromArray: (curves: ReadonlyArray<QuadraticCurve2d>) => QuadraticPath2d;
163
- /**
164
- * Checks if a value is a `QuadraticPath2d`.
165
- *
166
- * @param p - The value to check.
167
- * @returns `true` if the value is a `QuadraticPath2d`, `false` otherwise.
168
- * @since 1.0.0
169
- */
170
- declare const isQuadraticPath2d: (p: unknown) => p is QuadraticPath2d;
171
- declare const append: {
172
- /**
173
- * Appends a quadratic curve to a quadratic path.
174
- *
175
- * @param c - The quadratic curve to append.
176
- * @returns A function that takes a quadratic path and returns a new quadratic path.
177
- * @since 1.0.0
178
- */
179
- (c: QuadraticCurve2d): (p: QuadraticPath2d) => QuadraticPath2d;
180
- /**
181
- * Appends a quadratic curve to a quadratic path.
182
- *
183
- * @param p - The quadratic path to append to.
184
- * @param c - The quadratic curve to append.
185
- * @returns A new `QuadraticPath2d` instance with the appended curve.
186
- * @since 1.0.0
187
- */
188
- (p: QuadraticPath2d, c: QuadraticCurve2d): QuadraticPath2d;
189
- };
190
- /**
191
- * Calculates the length of a quadratic path.
192
- *
193
- * @param p - The quadratic path to calculate the length of.
194
- * @returns The length of the path.
195
- */
196
- declare const length: (p: QuadraticPath2d) => number;
197
- declare const solve: {
198
- /**
199
- * Solves a quadratic path at a given parameter.
200
- *
201
- * @param u - The parameter to solve for.
202
- * @returns A function that takes a quadratic path and returns the solved point.
203
- * @since 1.0.0
204
- */
205
- (u: number): (p: QuadraticPath2d) => Vector2;
206
- /**
207
- * Solves a quadratic path at a given parameter.
208
- *
209
- * @param p - The quadratic path to solve.
210
- * @param u - The parameter to solve for.
211
- * @returns The solved point.
212
- * @since 1.0.0
213
- */
214
- (p: QuadraticPath2d, u: number): Vector2;
215
- };
216
- /**
217
- * Serializes a quadratic path as an SVG path data string (the value of a
218
- * `<path>` element's `d` attribute), using `M` and `Q` commands. Discontinuities
219
- * between curves emit a fresh `M` command.
220
- *
221
- * @param p - The quadratic path to serialize.
222
- * @returns The SVG path data string.
223
- * @since 2.0.0
224
- */
225
- declare const toPathData: (p: QuadraticPath2d) => string;
226
- /**
227
- * Type-narrowing predicate: refines `QuadraticPath2d<T>` to
228
- * `QuadraticPath2d<T & Continuous>` when adjacent curves connect.
229
- *
230
- * @since 2.0.0
231
- */
232
- declare const isContinuous: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & Continuous>;
233
- /**
234
- * Asserts that the quadratic path is continuous, throwing on failure.
235
- *
236
- * @since 2.0.0
237
- */
238
- declare const asContinuous: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & Continuous>;
239
45
  //#endregion
240
- export { cubic2d_d_exports as CubicPath2d, linear2d_d_exports as LinearPath2d, quadratic2d_d_exports as QuadraticPath2d, rationalCubic2d_d_exports as RationalCubicPath2d };
46
+ //#region src/path/index.d.ts
47
+ type LinearPath2d = LinearPath2d$1;
48
+ type QuadraticPath2d = QuadraticPath2d$1;
49
+ type CubicPath2d = CubicPath2d$1;
50
+ type RationalCubicPath2d = RationalCubicPath2d$1;
51
+ //#endregion
52
+ export { CubicPath2d, LinearPath2d, QuadraticPath2d, RationalCubicPath2d };
241
53
  //# sourceMappingURL=index.d.mts.map
@@ -1,9 +1,10 @@
1
1
  import { t as __exportAll } from "../shared/chunk-25Hzd3z8.mjs";
2
2
  import { Pipeable, dual, invariant } from "../utils.mjs";
3
3
  import { epsEquals } from "../number.mjs";
4
- import { u as unit } from "../shared/interval-CCEqzPgA.mjs";
5
- import { f as solve$5, h as solve$4, p as length$4, u as length$5 } from "../shared/rationalCubic2d-CP4oGpnk.mjs";
6
- import { n as rationalCubic2d_exports, r as cubic2d_exports } from "../shared/rationalCubic2d-CXa7Yren.mjs";
4
+ import { p as unit } from "../shared/interval-X1EYuf-T.mjs";
5
+ import { r as union } from "../shared/interval2d-ca0J1NMr.mjs";
6
+ import { _ as length$4, f as boundingBox$5, g as boundingBox$4, h as solve$5, p as length$5, y as solve$4 } from "../shared/rationalCubic2d-D658ltUM.mjs";
7
+ import { n as rationalCubic2d_exports, r as cubic2d_exports } from "../shared/rationalCubic2d-Vw4qGPZj.mjs";
7
8
  //#region src/path/linear2d.internal.ts
8
9
  const LinearPath2dTypeId = Symbol("curvy/path/linear2d");
9
10
  var LinearPath2dImpl = class extends Pipeable {
@@ -68,11 +69,18 @@ const asContinuous$3 = (p) => {
68
69
  invariant(isContinuous$3(p), "linear path is not continuous");
69
70
  return p;
70
71
  };
72
+ const boundingBox$3 = (p) => {
73
+ const iter = p[Symbol.iterator]();
74
+ let acc = boundingBox$4(iter.next().value);
75
+ for (let next = iter.next(); !next.done; next = iter.next()) acc = union(acc, boundingBox$4(next.value));
76
+ return acc;
77
+ };
71
78
  //#endregion
72
79
  //#region src/path/linear2d.ts
73
80
  var linear2d_exports = /* @__PURE__ */ __exportAll({
74
81
  append: () => append$2,
75
82
  asContinuous: () => asContinuous$2,
83
+ boundingBox: () => boundingBox$2,
76
84
  fromArray: () => fromArray$2,
77
85
  isContinuous: () => isContinuous$2,
78
86
  isLinearPath2d: () => isLinearPath2d,
@@ -144,6 +152,15 @@ const isContinuous$2 = isContinuous$3;
144
152
  * @since 2.0.0
145
153
  */
146
154
  const asContinuous$2 = asContinuous$3;
155
+ /**
156
+ * Computes the axis-aligned bounding box of the path — the smallest closed
157
+ * `Box2d` enclosing every segment.
158
+ *
159
+ * @param p - The linear path.
160
+ * @returns A closed `Box2d` enclosing the path.
161
+ * @since 2.0.0
162
+ */
163
+ const boundingBox$2 = boundingBox$3;
147
164
  //#endregion
148
165
  //#region src/path/quadratic2d.internal.ts
149
166
  const QuadraticPath2dTypeId = Symbol("curvy/path/quadratic2d");
@@ -217,11 +234,18 @@ const asContinuous$1 = (p) => {
217
234
  invariant(isContinuous$1(p), "quadratic path is not continuous");
218
235
  return p;
219
236
  };
237
+ const boundingBox$1 = (p) => {
238
+ const iter = p[Symbol.iterator]();
239
+ let acc = boundingBox$5(iter.next().value);
240
+ for (let next = iter.next(); !next.done; next = iter.next()) acc = union(acc, boundingBox$5(next.value));
241
+ return acc;
242
+ };
220
243
  //#endregion
221
244
  //#region src/path/quadratic2d.ts
222
245
  var quadratic2d_exports = /* @__PURE__ */ __exportAll({
223
246
  append: () => append,
224
247
  asContinuous: () => asContinuous,
248
+ boundingBox: () => boundingBox,
225
249
  fromArray: () => fromArray,
226
250
  isContinuous: () => isContinuous,
227
251
  isQuadraticPath2d: () => isQuadraticPath2d,
@@ -286,6 +310,15 @@ const isContinuous = isContinuous$1;
286
310
  * @since 2.0.0
287
311
  */
288
312
  const asContinuous = asContinuous$1;
313
+ /**
314
+ * Computes the axis-aligned bounding box of the path — the smallest closed
315
+ * `Box2d` enclosing every segment.
316
+ *
317
+ * @param p - The quadratic path.
318
+ * @returns A closed `Box2d` enclosing the path.
319
+ * @since 2.0.0
320
+ */
321
+ const boundingBox = boundingBox$1;
289
322
  //#endregion
290
323
  export { cubic2d_exports as CubicPath2d, linear2d_exports as LinearPath2d, quadratic2d_exports as QuadraticPath2d, rationalCubic2d_exports as RationalCubicPath2d };
291
324
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["isLinearPath2d","make","fromArray","append","length","LinearCurve2d.length","Interval.unit","solve","LinearCurve2d.solve","toPathData","isContinuous","asContinuous","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","isQuadraticPath2d","make","fromArray","append","length","QuadraticCurve2d.length","Interval.unit","solve","QuadraticCurve2d.solve","toPathData","isContinuous","asContinuous","internal.make","internal.fromArray","internal.isQuadraticPath2d","internal.append","internal.length","internal.solve","internal.toPathData","internal.isContinuous","internal.asContinuous"],"sources":["../../src/path/linear2d.internal.ts","../../src/path/linear2d.ts","../../src/path/quadratic2d.internal.ts","../../src/path/quadratic2d.ts"],"sourcesContent":["import * as LinearCurve2d from '../curve/linear2d'\nimport * as Interval from '../interval/interval'\nimport { dual, Pipeable } from '../utils'\nimport { invariant } from '../utils'\nimport { epsEquals } from '../number'\nimport type { Vector2 } from '../vector/vector2'\nimport type { LinearPath2d } from './linear2d'\nimport { PathTraits, type Continuous } from './traits'\n\nexport const LinearPath2dTypeId: unique symbol = Symbol('curvy/path/linear2d')\nexport type LinearPath2dTypeId = typeof LinearPath2dTypeId\n\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\nexport const isLinearPath2d = (p: unknown): p is LinearPath2d =>\n typeof p === 'object' && p !== null && LinearPath2dTypeId in p\n\nexport const make = (...curves: ReadonlyArray<LinearCurve2d.LinearCurve2d>): LinearPath2d =>\n new LinearPath2dImpl(curves)\n\nexport const fromArray = (curves: ReadonlyArray<LinearCurve2d.LinearCurve2d>) =>\n new LinearPath2dImpl(curves)\n\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\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\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\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\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\nexport const asContinuous = <T>(p: LinearPath2d<T>): LinearPath2d<T & Continuous> => {\n invariant(isContinuous(p), 'linear path is not continuous')\n return p\n}\n","import type { LinearCurve2d } from '../curve/linear2d'\nimport type { Pipeable } from '../utils'\nimport type { Vector2 } from '../vector/vector2'\nimport type { LinearPath2dTypeId } from './linear2d.internal'\nimport * as internal from './linear2d.internal'\nimport type { Continuous, PathTraits } from './traits'\n\nexport type { Continuous } from './traits'\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","import * as QuadraticCurve2d from '../curve/quadratic2d'\nimport * as Interval from '../interval/interval'\nimport { dual, Pipeable } from '../utils'\nimport { invariant } from '../utils'\nimport { epsEquals } from '../number'\nimport type { Vector2 } from '../vector/vector2'\nimport type { QuadraticPath2d } from './quadratic2d'\nimport { PathTraits, type Continuous } from './traits'\n\nexport const QuadraticPath2dTypeId: unique symbol = Symbol('curvy/path/quadratic2d')\nexport type QuadraticPath2dTypeId = typeof QuadraticPath2dTypeId\n\nexport class QuadraticPath2dImpl extends Pipeable implements QuadraticPath2d<unknown> {\n readonly [QuadraticPath2dTypeId]: QuadraticPath2dTypeId = QuadraticPath2dTypeId\n declare readonly [PathTraits]: unknown\n\n readonly curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>\n\n constructor(curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>) {\n super()\n this.curves = curves\n }\n\n [Symbol.iterator](): Iterator<QuadraticCurve2d.QuadraticCurve2d> {\n return this.curves[Symbol.iterator]()\n }\n}\n\nexport const isQuadraticPath2d = (p: unknown): p is QuadraticPath2d =>\n typeof p === 'object' && p !== null && QuadraticPath2dTypeId in p\n\nexport const make = (\n ...curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>\n): QuadraticPath2d => new QuadraticPath2dImpl(curves)\n\nexport const fromArray = (\n curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>,\n): QuadraticPath2d => new QuadraticPath2dImpl(curves)\n\nexport const append = dual<\n (c: QuadraticCurve2d.QuadraticCurve2d) => (p: QuadraticPath2d) => QuadraticPath2d,\n (p: QuadraticPath2d, c: QuadraticCurve2d.QuadraticCurve2d) => QuadraticPath2d\n>(2, (p: QuadraticPath2d, c: QuadraticCurve2d.QuadraticCurve2d) => fromArray([...p, c]))\n\nexport const length = (p: QuadraticPath2d) => {\n let total = 0\n for (const curve of p) {\n total += QuadraticCurve2d.length(curve, Interval.unit)\n }\n\n return total\n}\n\nexport const solve = dual<\n (u: number) => (p: QuadraticPath2d) => Vector2,\n (p: QuadraticPath2d, u: number) => Vector2\n>(2, (p: QuadraticPath2d, u: number) => {\n const curves = p instanceof QuadraticPath2dImpl ? p.curves : [...p]\n\n if (u === 1) {\n const last = curves.at(-1) as QuadraticCurve2d.QuadraticCurve2d\n return QuadraticCurve2d.solve(last, 1)\n }\n\n const t = u * curves.length\n const i = Math.floor(t)\n const curve = curves[i] as QuadraticCurve2d.QuadraticCurve2d\n return QuadraticCurve2d.solve(curve, t - i)\n})\n\n// Quadratic Bernstein basis: P(t) = (1-t)²·p0 + 2(1-t)t·p1 + t²·p2\n// expanded gives c0 = p0, c1 = -2p0 + 2p1, c2 = p0 - 2p1 + p2, so:\n// p0 = c0, p1 = c0 + c1/2, p2 = c0 + c1 + c2.\nexport const toPathData = (p: QuadraticPath2d): string => {\n let result = ''\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n\n for (const curve of p) {\n const c0x = curve.x.c0\n const c0y = curve.y.c0\n const c1x = curve.x.c1\n const c1y = curve.y.c1\n const c2x = curve.x.c2\n const c2y = curve.y.c2\n\n const startX = c0x\n const startY = c0y\n const ctrlX = c0x + c1x / 2\n const ctrlY = c0y + c1y / 2\n const endX = c0x + c1x + c2x\n const endY = c0y + c1y + c2y\n\n if (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY)) {\n result += ` M ${startX},${startY}`\n }\n result += ` Q ${ctrlX},${ctrlY} ${endX},${endY}`\n\n prevEndX = endX\n prevEndY = endY\n }\n\n return result.slice(1)\n}\n\nexport const isContinuous = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & Continuous> => {\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n let first = true\n\n for (const curve of p) {\n const startX = curve.x.c0\n const startY = curve.y.c0\n if (!first && (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY))) {\n return false\n }\n prevEndX = curve.x.c0 + curve.x.c1 + curve.x.c2\n prevEndY = curve.y.c0 + curve.y.c1 + curve.y.c2\n first = false\n }\n return true\n}\n\nexport const asContinuous = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & Continuous> => {\n invariant(isContinuous(p), 'quadratic path is not continuous')\n return p\n}\n","import type { QuadraticCurve2d } from '../curve/quadratic2d'\nimport type { Pipeable } from '../utils'\nimport type { Vector2 } from '../vector/vector2'\nimport type { QuadraticPath2dTypeId } from './quadratic2d.internal'\nimport * as internal from './quadratic2d.internal'\nimport type { Continuous, PathTraits } from './traits'\n\nexport type { Continuous } from './traits'\n\n/**\n * A quadratic path in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The `Trait` type parameter accumulates trait brands as the path is refined\n * via `isContinuous` / `asContinuous`.\n *\n * @since 1.0.0\n */\nexport interface QuadraticPath2d<out Trait = unknown> extends Pipeable, Iterable<QuadraticCurve2d> {\n readonly [QuadraticPath2dTypeId]: QuadraticPath2dTypeId\n readonly [PathTraits]: Trait\n}\n\n/**\n * Creates a new `QuadraticPath2d` instance from a sequence of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `QuadraticPath2d` instance.\n * @since 2.0.0\n */\nexport const make: (...curves: ReadonlyArray<QuadraticCurve2d>) => QuadraticPath2d = internal.make\n\n/**\n * Creates a new `QuadraticPath2d` instance from an array of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `QuadraticPath2d` instance.\n * @since 2.0.0\n */\nexport const fromArray: (curves: ReadonlyArray<QuadraticCurve2d>) => QuadraticPath2d =\n internal.fromArray\n\n/**\n * Checks if a value is a `QuadraticPath2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `QuadraticPath2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isQuadraticPath2d: (p: unknown) => p is QuadraticPath2d = internal.isQuadraticPath2d\n\nexport const append: {\n /**\n * Appends a quadratic curve to a quadratic path.\n *\n * @param c - The quadratic curve to append.\n * @returns A function that takes a quadratic path and returns a new quadratic path.\n * @since 1.0.0\n */\n (c: QuadraticCurve2d): (p: QuadraticPath2d) => QuadraticPath2d\n /**\n * Appends a quadratic curve to a quadratic path.\n *\n * @param p - The quadratic path to append to.\n * @param c - The quadratic curve to append.\n * @returns A new `QuadraticPath2d` instance with the appended curve.\n * @since 1.0.0\n */\n (p: QuadraticPath2d, c: QuadraticCurve2d): QuadraticPath2d\n} = internal.append\n\n/**\n * Calculates the length of a quadratic path.\n *\n * @param p - The quadratic path to calculate the length of.\n * @returns The length of the path.\n */\nexport const length: (p: QuadraticPath2d) => number = internal.length\n\nexport const solve: {\n /**\n * Solves a quadratic path at a given parameter.\n *\n * @param u - The parameter to solve for.\n * @returns A function that takes a quadratic path and returns the solved point.\n * @since 1.0.0\n */\n (u: number): (p: QuadraticPath2d) => Vector2\n /**\n * Solves a quadratic path at a given parameter.\n *\n * @param p - The quadratic path to solve.\n * @param u - The parameter to solve for.\n * @returns The solved point.\n * @since 1.0.0\n */\n (p: QuadraticPath2d, u: number): Vector2\n} = internal.solve\n\n/**\n * Serializes a quadratic path as an SVG path data string (the value of a\n * `<path>` element's `d` attribute), using `M` and `Q` commands. Discontinuities\n * between curves emit a fresh `M` command.\n *\n * @param p - The quadratic path to serialize.\n * @returns The SVG path data string.\n * @since 2.0.0\n */\nexport const toPathData: (p: QuadraticPath2d) => string = internal.toPathData\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & Continuous>` when adjacent curves connect.\n *\n * @since 2.0.0\n */\nexport const isContinuous: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & Continuous> =\n internal.isContinuous\n\n/**\n * Asserts that the quadratic path is continuous, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asContinuous: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & Continuous> =\n internal.asContinuous\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["isLinearPath2d","make","fromArray","append","length","LinearCurve2d.length","Interval.unit","solve","LinearCurve2d.solve","toPathData","isContinuous","asContinuous","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","boundingBox","internal.boundingBox","isQuadraticPath2d","make","fromArray","append","length","QuadraticCurve2d.length","Interval.unit","solve","QuadraticCurve2d.solve","toPathData","isContinuous","asContinuous","boundingBox","QuadraticCurve2d.boundingBox","Interval2d.union","internal.make","internal.fromArray","internal.isQuadraticPath2d","internal.append","internal.length","internal.solve","internal.toPathData","internal.isContinuous","internal.asContinuous","internal.boundingBox"],"sources":["../../src/path/linear2d.internal.ts","../../src/path/linear2d.ts","../../src/path/quadratic2d.internal.ts","../../src/path/quadratic2d.ts"],"sourcesContent":["import * as Interval2d from '../interval/interval2d'\nimport * as LinearCurve2d from '../curve/linear2d'\nimport * as Interval from '../interval/interval'\nimport { dual, Pipeable } from '../utils'\nimport { invariant } from '../utils'\nimport { epsEquals } from '../number'\nimport type { Vector2 } from '../vector/vector2'\nimport type { LinearPath2d } from './linear2d'\nimport { PathTraits, type Continuous } from './traits'\n\nexport const LinearPath2dTypeId: unique symbol = Symbol('curvy/path/linear2d')\nexport type LinearPath2dTypeId = typeof LinearPath2dTypeId\n\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\nexport const isLinearPath2d = (p: unknown): p is LinearPath2d =>\n typeof p === 'object' && p !== null && LinearPath2dTypeId in p\n\nexport const make = (...curves: ReadonlyArray<LinearCurve2d.LinearCurve2d>): LinearPath2d =>\n new LinearPath2dImpl(curves)\n\nexport const fromArray = (curves: ReadonlyArray<LinearCurve2d.LinearCurve2d>) =>\n new LinearPath2dImpl(curves)\n\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\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\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\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\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\nexport const asContinuous = <T>(p: LinearPath2d<T>): LinearPath2d<T & Continuous> => {\n invariant(isContinuous(p), 'linear path is not continuous')\n return p\n}\n\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'\nimport type { LinearCurve2d } from '../curve/linear2d'\nimport type { Closed } from '../interval/interval'\nimport type { Pipeable } from '../utils'\nimport type { Vector2 } from '../vector/vector2'\nimport type { LinearPath2dTypeId } from './linear2d.internal'\nimport * as internal from './linear2d.internal'\nimport type { Continuous, PathTraits } from './traits'\n\nexport type { Continuous } from './traits'\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 * 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'\nimport * as QuadraticCurve2d from '../curve/quadratic2d'\nimport * as Interval from '../interval/interval'\nimport { dual, Pipeable } from '../utils'\nimport { invariant } from '../utils'\nimport { epsEquals } from '../number'\nimport type { Vector2 } from '../vector/vector2'\nimport type { QuadraticPath2d } from './quadratic2d'\nimport { PathTraits, type Continuous } from './traits'\n\nexport const QuadraticPath2dTypeId: unique symbol = Symbol('curvy/path/quadratic2d')\nexport type QuadraticPath2dTypeId = typeof QuadraticPath2dTypeId\n\nexport class QuadraticPath2dImpl extends Pipeable implements QuadraticPath2d<unknown> {\n readonly [QuadraticPath2dTypeId]: QuadraticPath2dTypeId = QuadraticPath2dTypeId\n declare readonly [PathTraits]: unknown\n\n readonly curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>\n\n constructor(curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>) {\n super()\n this.curves = curves\n }\n\n [Symbol.iterator](): Iterator<QuadraticCurve2d.QuadraticCurve2d> {\n return this.curves[Symbol.iterator]()\n }\n}\n\nexport const isQuadraticPath2d = (p: unknown): p is QuadraticPath2d =>\n typeof p === 'object' && p !== null && QuadraticPath2dTypeId in p\n\nexport const make = (\n ...curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>\n): QuadraticPath2d => new QuadraticPath2dImpl(curves)\n\nexport const fromArray = (\n curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>,\n): QuadraticPath2d => new QuadraticPath2dImpl(curves)\n\nexport const append = dual<\n (c: QuadraticCurve2d.QuadraticCurve2d) => (p: QuadraticPath2d) => QuadraticPath2d,\n (p: QuadraticPath2d, c: QuadraticCurve2d.QuadraticCurve2d) => QuadraticPath2d\n>(2, (p: QuadraticPath2d, c: QuadraticCurve2d.QuadraticCurve2d) => fromArray([...p, c]))\n\nexport const length = (p: QuadraticPath2d) => {\n let total = 0\n for (const curve of p) {\n total += QuadraticCurve2d.length(curve, Interval.unit)\n }\n\n return total\n}\n\nexport const solve = dual<\n (u: number) => (p: QuadraticPath2d) => Vector2,\n (p: QuadraticPath2d, u: number) => Vector2\n>(2, (p: QuadraticPath2d, u: number) => {\n const curves = p instanceof QuadraticPath2dImpl ? p.curves : [...p]\n\n if (u === 1) {\n const last = curves.at(-1) as QuadraticCurve2d.QuadraticCurve2d\n return QuadraticCurve2d.solve(last, 1)\n }\n\n const t = u * curves.length\n const i = Math.floor(t)\n const curve = curves[i] as QuadraticCurve2d.QuadraticCurve2d\n return QuadraticCurve2d.solve(curve, t - i)\n})\n\n// Quadratic Bernstein basis: P(t) = (1-t)²·p0 + 2(1-t)t·p1 + t²·p2\n// expanded gives c0 = p0, c1 = -2p0 + 2p1, c2 = p0 - 2p1 + p2, so:\n// p0 = c0, p1 = c0 + c1/2, p2 = c0 + c1 + c2.\nexport const toPathData = (p: QuadraticPath2d): string => {\n let result = ''\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n\n for (const curve of p) {\n const c0x = curve.x.c0\n const c0y = curve.y.c0\n const c1x = curve.x.c1\n const c1y = curve.y.c1\n const c2x = curve.x.c2\n const c2y = curve.y.c2\n\n const startX = c0x\n const startY = c0y\n const ctrlX = c0x + c1x / 2\n const ctrlY = c0y + c1y / 2\n const endX = c0x + c1x + c2x\n const endY = c0y + c1y + c2y\n\n if (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY)) {\n result += ` M ${startX},${startY}`\n }\n result += ` Q ${ctrlX},${ctrlY} ${endX},${endY}`\n\n prevEndX = endX\n prevEndY = endY\n }\n\n return result.slice(1)\n}\n\nexport const isContinuous = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & Continuous> => {\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n let first = true\n\n for (const curve of p) {\n const startX = curve.x.c0\n const startY = curve.y.c0\n if (!first && (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY))) {\n return false\n }\n prevEndX = curve.x.c0 + curve.x.c1 + curve.x.c2\n prevEndY = curve.y.c0 + curve.y.c1 + curve.y.c2\n first = false\n }\n return true\n}\n\nexport const asContinuous = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & Continuous> => {\n invariant(isContinuous(p), 'quadratic path is not continuous')\n return p\n}\n\nexport const boundingBox = (\n p: QuadraticPath2d,\n): Interval2d.Interval2d<Interval.Closed, Interval.Closed> => {\n const iter = p[Symbol.iterator]()\n const first = iter.next()\n let acc = QuadraticCurve2d.boundingBox(first.value as QuadraticCurve2d.QuadraticCurve2d)\n for (let next = iter.next(); !next.done; next = iter.next()) {\n acc = Interval2d.union(acc, QuadraticCurve2d.boundingBox(next.value))\n }\n return acc\n}\n","import type { Interval2d } from '../interval/interval2d'\nimport type { QuadraticCurve2d } from '../curve/quadratic2d'\nimport type { Closed } from '../interval/interval'\nimport type { Pipeable } from '../utils'\nimport type { Vector2 } from '../vector/vector2'\nimport type { QuadraticPath2dTypeId } from './quadratic2d.internal'\nimport * as internal from './quadratic2d.internal'\nimport type { Continuous, PathTraits } from './traits'\n\nexport type { Continuous } from './traits'\n\n/**\n * A quadratic path in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The `Trait` type parameter accumulates trait brands as the path is refined\n * via `isContinuous` / `asContinuous`.\n *\n * @since 1.0.0\n */\nexport interface QuadraticPath2d<out Trait = unknown> extends Pipeable, Iterable<QuadraticCurve2d> {\n readonly [QuadraticPath2dTypeId]: QuadraticPath2dTypeId\n readonly [PathTraits]: Trait\n}\n\n/**\n * Creates a new `QuadraticPath2d` instance from a sequence of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `QuadraticPath2d` instance.\n * @since 2.0.0\n */\nexport const make: (...curves: ReadonlyArray<QuadraticCurve2d>) => QuadraticPath2d = internal.make\n\n/**\n * Creates a new `QuadraticPath2d` instance from an array of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `QuadraticPath2d` instance.\n * @since 2.0.0\n */\nexport const fromArray: (curves: ReadonlyArray<QuadraticCurve2d>) => QuadraticPath2d =\n internal.fromArray\n\n/**\n * Checks if a value is a `QuadraticPath2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `QuadraticPath2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isQuadraticPath2d: (p: unknown) => p is QuadraticPath2d = internal.isQuadraticPath2d\n\nexport const append: {\n /**\n * Appends a quadratic curve to a quadratic path.\n *\n * @param c - The quadratic curve to append.\n * @returns A function that takes a quadratic path and returns a new quadratic path.\n * @since 1.0.0\n */\n (c: QuadraticCurve2d): (p: QuadraticPath2d) => QuadraticPath2d\n /**\n * Appends a quadratic curve to a quadratic path.\n *\n * @param p - The quadratic path to append to.\n * @param c - The quadratic curve to append.\n * @returns A new `QuadraticPath2d` instance with the appended curve.\n * @since 1.0.0\n */\n (p: QuadraticPath2d, c: QuadraticCurve2d): QuadraticPath2d\n} = internal.append\n\n/**\n * Calculates the length of a quadratic path.\n *\n * @param p - The quadratic path to calculate the length of.\n * @returns The length of the path.\n */\nexport const length: (p: QuadraticPath2d) => number = internal.length\n\nexport const solve: {\n /**\n * Solves a quadratic path at a given parameter.\n *\n * @param u - The parameter to solve for.\n * @returns A function that takes a quadratic path and returns the solved point.\n * @since 1.0.0\n */\n (u: number): (p: QuadraticPath2d) => Vector2\n /**\n * Solves a quadratic path at a given parameter.\n *\n * @param p - The quadratic path to solve.\n * @param u - The parameter to solve for.\n * @returns The solved point.\n * @since 1.0.0\n */\n (p: QuadraticPath2d, u: number): Vector2\n} = internal.solve\n\n/**\n * Serializes a quadratic path as an SVG path data string (the value of a\n * `<path>` element's `d` attribute), using `M` and `Q` commands. Discontinuities\n * between curves emit a fresh `M` command.\n *\n * @param p - The quadratic path to serialize.\n * @returns The SVG path data string.\n * @since 2.0.0\n */\nexport const toPathData: (p: QuadraticPath2d) => string = internal.toPathData\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & Continuous>` when adjacent curves connect.\n *\n * @since 2.0.0\n */\nexport const isContinuous: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & Continuous> =\n internal.isContinuous\n\n/**\n * Asserts that the quadratic path is continuous, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asContinuous: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & Continuous> =\n internal.asContinuous\n\n/**\n * Computes the axis-aligned bounding box of the path — the smallest closed\n * `Box2d` enclosing every segment.\n *\n * @param p - The quadratic path.\n * @returns A closed `Box2d` enclosing the path.\n * @since 2.0.0\n */\nexport const boundingBox: (p: QuadraticPath2d) => Interval2d<Closed, Closed> = internal.boundingBox\n"],"mappings":"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"}
@@ -1,2 +1,9 @@
1
- import { i as quadratic_d_exports, n as cubic_d_exports, o as linear_d_exports } from "../shared/cubic-Dfn6DB02.mjs";
2
- export { cubic_d_exports as CubicPolynomial, linear_d_exports as LinearPolynomial, quadratic_d_exports as QuadraticPolynomial };
1
+ import { n as QuadraticPolynomial$1, r as LinearPolynomial$1, t as CubicPolynomial$1 } from "../shared/cubic-DkBqcZf-.mjs";
2
+
3
+ //#region src/polynomial/index.d.ts
4
+ type LinearPolynomial = LinearPolynomial$1;
5
+ type QuadraticPolynomial = QuadraticPolynomial$1;
6
+ type CubicPolynomial = CubicPolynomial$1;
7
+ //#endregion
8
+ export { CubicPolynomial, LinearPolynomial, QuadraticPolynomial };
9
+ //# sourceMappingURL=index.d.mts.map
@@ -1,3 +1,3 @@
1
- import { t as cubic_exports } from "../shared/cubic-CYYEUHNm.mjs";
2
- import { f as linear_exports, o as quadratic_exports } from "../shared/quadratic-DEhuAKuE.mjs";
1
+ import { t as cubic_exports } from "../shared/cubic-CMonq6bg.mjs";
2
+ import { o as quadratic_exports, p as linear_exports } from "../shared/quadratic-DyeMtvET.mjs";
3
3
  export { cubic_exports as CubicPolynomial, linear_exports as LinearPolynomial, quadratic_exports as QuadraticPolynomial };