curvy 2.0.0-alpha.2 → 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 (63) 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 -3
  6. package/dist/interval/index.mjs +2 -2
  7. package/dist/matrix/index.d.mts +9 -2
  8. package/dist/path/index.d.mts +15 -223
  9. package/dist/path/index.mjs +6 -6
  10. package/dist/path/index.mjs.map +1 -1
  11. package/dist/polynomial/index.d.mts +9 -2
  12. package/dist/polynomial/index.mjs +2 -2
  13. package/dist/shared/{characteristic-B9nCh_cx.mjs → characteristic-DLlhja-I.mjs} +9 -9
  14. package/dist/shared/{characteristic-B9nCh_cx.mjs.map → characteristic-DLlhja-I.mjs.map} +1 -1
  15. package/dist/shared/{cubic-CpHAx8cC.mjs → cubic-CMonq6bg.mjs} +26 -5
  16. package/dist/shared/cubic-CMonq6bg.mjs.map +1 -0
  17. package/dist/shared/cubic-DkBqcZf-.d.mts +121 -0
  18. package/dist/shared/interval-Bhzeqp8M.d.mts +62 -0
  19. package/dist/shared/{interval-05CR6eBf.mjs → interval-X1EYuf-T.mjs} +2 -2
  20. package/dist/shared/{interval-05CR6eBf.mjs.map → interval-X1EYuf-T.mjs.map} +1 -1
  21. package/dist/shared/interval2d-BMk5UYXD.d.mts +29 -0
  22. package/dist/shared/{interval2d-8IBZnUOq.mjs → interval2d-ca0J1NMr.mjs} +8 -8
  23. package/dist/shared/{interval2d-8IBZnUOq.mjs.map → interval2d-ca0J1NMr.mjs.map} +1 -1
  24. package/dist/shared/matrix4x4-CaytTaB_.d.mts +168 -0
  25. package/dist/shared/{quadratic-CamozcFc.mjs → quadratic-DyeMtvET.mjs} +20 -2
  26. package/dist/shared/quadratic-DyeMtvET.mjs.map +1 -0
  27. package/dist/shared/rationalCubic2d-D-UevGKu.d.mts +60 -0
  28. package/dist/shared/{rationalCubic2d-Bys2Uory.mjs → rationalCubic2d-D658ltUM.mjs} +17 -17
  29. package/dist/shared/{rationalCubic2d-Bys2Uory.mjs.map → rationalCubic2d-D658ltUM.mjs.map} +1 -1
  30. package/dist/shared/rationalCubic2d-MgMSJaAU.d.mts +104 -0
  31. package/dist/shared/{rationalCubic2d-BEgUGSFf.mjs → rationalCubic2d-Vw4qGPZj.mjs} +9 -9
  32. package/dist/shared/{rationalCubic2d-BEgUGSFf.mjs.map → rationalCubic2d-Vw4qGPZj.mjs.map} +1 -1
  33. package/dist/shared/{solution-CrtLfqEq.mjs → solution-3TDATEMn.mjs} +28 -2
  34. package/dist/shared/solution-3TDATEMn.mjs.map +1 -0
  35. package/dist/shared/solution-DInDT2Hq.d.mts +60 -0
  36. package/dist/shared/{vector2-CL1HDdPr.mjs → vector2-CCuJx1rX.mjs} +6 -6
  37. package/dist/shared/{vector2-CL1HDdPr.mjs.map → vector2-CCuJx1rX.mjs.map} +1 -1
  38. package/dist/shared/vector2-euuV_bNQ.d.mts +58 -0
  39. package/dist/shared/vector3-3Xx7GVk7.d.mts +37 -0
  40. package/dist/shared/{vector3-D-tv_aKL.mjs → vector3-C-qgKAjR.mjs} +2 -2
  41. package/dist/shared/{vector3-D-tv_aKL.mjs.map → vector3-C-qgKAjR.mjs.map} +1 -1
  42. package/dist/shared/{vector4-5KbjoHVj.mjs → vector4-BhOKDhD5.mjs} +2 -2
  43. package/dist/shared/{vector4-5KbjoHVj.mjs.map → vector4-BhOKDhD5.mjs.map} +1 -1
  44. package/dist/solution/index.d.mts +7 -2
  45. package/dist/solution/index.mjs +1 -1
  46. package/dist/splines/index.d.mts +37 -606
  47. package/dist/splines/index.mjs +193 -35
  48. package/dist/splines/index.mjs.map +1 -1
  49. package/dist/vector/index.d.mts +10 -3
  50. package/dist/vector/index.mjs +3 -3
  51. package/package.json +1 -1
  52. package/dist/shared/cubic-BajUY0JT.d.mts +0 -1100
  53. package/dist/shared/cubic-CpHAx8cC.mjs.map +0 -1
  54. package/dist/shared/interval-Dy-RMEE3.d.mts +0 -533
  55. package/dist/shared/interval2d-C2id9u31.d.mts +0 -172
  56. package/dist/shared/matrix4x4-Dm_tSiH1.d.mts +0 -1183
  57. package/dist/shared/quadratic-CamozcFc.mjs.map +0 -1
  58. package/dist/shared/rationalCubic2d-B6g97ryJ.d.mts +0 -308
  59. package/dist/shared/rationalCubic2d-DlQfBURs.d.mts +0 -818
  60. package/dist/shared/solution-CrtLfqEq.mjs.map +0 -1
  61. package/dist/shared/solution-sNQ-ZVhN.d.mts +0 -251
  62. package/dist/shared/vector2-DPUY3_eA.d.mts +0 -470
  63. package/dist/shared/vector3-DqeOZtOB.d.mts +0 -703
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["Vector2.makeWeighted","isRationalBezier2d","Vector3.make","make","fromArray","fromPoints","fromBezier","toPath","RationalCubicCurve2d.fromBezierPoints","RationalCubicPath2d.fromArray","subdivide","Solution.none","Vector2.make","Solution.one","Vector4.transpose","CubicCurve2d.fromPolynomials","Characteristic.apply","Matrix4x4.inverse","Characteristic.cubicBezier","Matrix4x4.multiply","isCubicBezier2d","make","fromArray","append","Matrix4x4.vectorProductLeft","Vector4.make","Vector2.make","appendTangentAligned","appendCurvatureAligned","appendVelocityAligned","appendAccelerationAligned","toPath","CubicPath2d.make","fromRational","RationalBezier2dInternal.toBezierPoints","Solution.one","subdivide","make","internal.make","fromArray","internal.fromArray","internal.isCubicBezier2d","append","internal.append","internal.appendTangentAligned","internal.appendCurvatureAligned","internal.appendVelocityAligned","internal.appendAccelerationAligned","toPath","internal.toPath","internal.fromRational","subdivide","internal.subdivide","isCardinal2d","make","fromArray","append","prepend","withDuplicatedEndpoints","withReflectedEndpoints","scale","Vector2.subtract","Vector2.scale","Vector2.add","toPath","CubicPath2d.make","Characteristic.cubicCardinal","toBezier","bezierInternal.fromBasis","internal.isCardinal2d","make","internal.make","fromArray","internal.fromArray","append","internal.append","prepend","internal.prepend","internal.withDuplicatedEndpoints","internal.withReflectedEndpoints","toPath","internal.toPath","toBezier","internal.toBezier","isHermite2d","make","fromArray","append","prepend","toPath","CubicPath2d.make","Characteristic.cubicHermite","toBezier","bezierInternal.fromBasis","internal.isHermite2d","make","internal.make","fromArray","internal.fromArray","append","internal.append","prepend","internal.prepend","toPath","internal.toPath","toBezier","internal.toBezier","isBasis2d","make","fromArray","append","prepend","withTriplicatedEndpoints","toPath","CubicPath2d.make","Characteristic.cubicBasisSpline","toBezier","bezierInternal.fromBasis","internal.isBasis2d","make","internal.make","fromArray","internal.fromArray","internal.append","internal.prepend","internal.withTriplicatedEndpoints","toPath","internal.toPath","internal.toBezier","internal.isRationalBezier2d","internal.make","internal.fromArray","internal.fromPoints","internal.fromBezier","internal.toPath","internal.subdivide"],"sources":["../../src/splines/rationalBezier2d.internal.ts","../../src/splines/util.ts","../../src/splines/bezier2d.internal.ts","../../src/splines/bezier2d.ts","../../src/splines/cardinal2d.internal.ts","../../src/splines/cardinal2d.ts","../../src/splines/hermite2d.internal.ts","../../src/splines/hermite2d.ts","../../src/splines/basis2d.internal.ts","../../src/splines/basis2d.ts","../../src/splines/rationalBezier2d.ts"],"sourcesContent":["import * as RationalCubicCurve2d from '../curve/rationalCubic2d'\nimport * as RationalCubicPath2d from '../path/rationalCubic2d'\nimport { dual, Pipeable } from '../utils'\nimport * as Solution from '../solution/solution'\nimport { invariant } from '../utils'\nimport { epsEquals } from '../number'\nimport * as Vector2 from '../vector/vector2'\nimport * as Vector3 from '../vector/vector3'\nimport type { Bezier2d } from './bezier2d'\nimport type { RationalBezier2d } from './rationalBezier2d'\n\nexport const RationalBezier2dTypeId = Symbol('curvy/splines/rationalBezier2d')\nexport type RationalBezier2dTypeId = typeof RationalBezier2dTypeId\n\n// Internally each control point is stored in homogeneous form as\n// `(w·x, w·y, w)`. De Casteljau in 3D plus a final projection (`x/w`, `y/w`)\n// is exactly the rational evaluator, so the homogeneous form keeps the hot\n// paths identical to the non-rational case modulo one division at the end.\n\nclass RationalBezier2dImpl extends Pipeable implements RationalBezier2d {\n readonly [RationalBezier2dTypeId]: RationalBezier2dTypeId = RationalBezier2dTypeId\n\n readonly homogeneous: ReadonlyArray<Vector3.Vector3>\n\n constructor(homogeneous: ReadonlyArray<Vector3.Vector3>) {\n invariant(homogeneous.length >= 4, 'rational cubic splines require 4 or more points')\n invariant(homogeneous.length % 3 === 1, 'rational cubic splines require (n * 3) + 1 points')\n super()\n this.homogeneous = homogeneous\n }\n\n *[Symbol.iterator](): IterableIterator<Vector2.Weighted> {\n for (const h of this.homogeneous) {\n yield Vector2.makeWeighted(h.x / h.z, h.y / h.z, h.z)\n }\n }\n}\n\nexport const isRationalBezier2d = (p: unknown): p is RationalBezier2d =>\n typeof p === 'object' && p !== null && RationalBezier2dTypeId in p\n\nconst lift = (p: Vector2.Weighted): Vector3.Vector3 =>\n Vector3.make(p.x * p.weight, p.y * p.weight, p.weight)\n\nexport const make = (\n p0: Vector2.Weighted,\n p1: Vector2.Weighted,\n p2: Vector2.Weighted,\n p3: Vector2.Weighted,\n): RationalBezier2d => new RationalBezier2dImpl([lift(p0), lift(p1), lift(p2), lift(p3)])\n\nexport const fromArray = (points: ReadonlyArray<Vector2.Weighted>): RationalBezier2d =>\n new RationalBezier2dImpl(points.map(lift))\n\nexport const fromPoints = (\n p0: Vector2.Vector2,\n p1: Vector2.Vector2,\n p2: Vector2.Vector2,\n p3: Vector2.Vector2,\n): RationalBezier2d =>\n new RationalBezier2dImpl([\n Vector3.make(p0.x, p0.y, 1),\n Vector3.make(p1.x, p1.y, 1),\n Vector3.make(p2.x, p2.y, 1),\n Vector3.make(p3.x, p3.y, 1),\n ])\n\nexport const fromBezier = (b: Bezier2d): RationalBezier2d => {\n const homogeneous: Array<Vector3.Vector3> = []\n for (const p of b) {\n homogeneous.push(Vector3.make(p.x, p.y, 1))\n }\n return new RationalBezier2dImpl(homogeneous)\n}\n\nconst homogeneousOf = (r: RationalBezier2d): ReadonlyArray<Vector3.Vector3> =>\n r instanceof RationalBezier2dImpl ? r.homogeneous : Array.from(r, lift)\n\n// Conversion from spline form (piecewise Bernstein weighted control points)\n// to path form (per-segment monomial polynomials with shared denominator).\n// Each segment's four homogeneous control points expand into three cubic\n// polynomials — x, y, w — via the same Bernstein-to-monomial mapping that\n// drives `Bezier2d.toPath`, just running on three channels instead of two.\nexport const toPath = (r: RationalBezier2d): RationalCubicPath2d.RationalCubicPath2d => {\n const homogeneous = homogeneousOf(r)\n const segmentCount = (homogeneous.length - 1) / 3\n const curves: Array<RationalCubicCurve2d.RationalCubicCurve2d> = []\n\n for (let i = 0; i < segmentCount; i++) {\n const base = i * 3\n const h0 = homogeneous[base] as Vector3.Vector3\n const h1 = homogeneous[base + 1] as Vector3.Vector3\n const h2 = homogeneous[base + 2] as Vector3.Vector3\n const h3 = homogeneous[base + 3] as Vector3.Vector3\n\n // Project each homogeneous CP back to its weighted form for the\n // `fromBezierPoints` constructor. The constructor re-lifts internally;\n // the round-trip is exact to within 1–2 ULPs for finite positive weights\n // and the conversion is a one-shot, not a hot path.\n curves.push(\n RationalCubicCurve2d.fromBezierPoints(\n Vector2.makeWeighted(h0.x / h0.z, h0.y / h0.z, h0.z),\n Vector2.makeWeighted(h1.x / h1.z, h1.y / h1.z, h1.z),\n Vector2.makeWeighted(h2.x / h2.z, h2.y / h2.z, h2.z),\n Vector2.makeWeighted(h3.x / h3.z, h3.y / h3.z, h3.z),\n ),\n )\n }\n\n return RationalCubicPath2d.fromArray(curves)\n}\n\nexport const subdivide = dual<\n (u: number) => (r: RationalBezier2d) => [RationalBezier2d, RationalBezier2d],\n (r: RationalBezier2d, u: number) => [RationalBezier2d, RationalBezier2d]\n>(2, (r: RationalBezier2d, u: number): [RationalBezier2d, RationalBezier2d] => {\n invariant(u > 0 && u < 1, 'subdivide parameter u must be in the open interval (0, 1)')\n\n const homogeneous = homogeneousOf(r)\n const segmentCount = (homogeneous.length - 1) / 3\n const t = u * segmentCount\n const i = Math.floor(t)\n const localT = t - i\n\n // exact segment boundary: no de Casteljau needed, just slice\n if (localT === 0) {\n return [\n new RationalBezier2dImpl(homogeneous.slice(0, i * 3 + 1)),\n new RationalBezier2dImpl(homogeneous.slice(i * 3)),\n ]\n }\n\n const p0 = homogeneous[i * 3] as Vector3.Vector3\n const p1 = homogeneous[i * 3 + 1] as Vector3.Vector3\n const p2 = homogeneous[i * 3 + 2] as Vector3.Vector3\n const p3 = homogeneous[i * 3 + 3] as Vector3.Vector3\n\n // de Casteljau split in homogeneous space — the new control points sit on\n // the lifted curve, so projecting them back yields valid rational beziers\n // on each side. The split point is shared by both halves.\n const q0x = p0.x + (p1.x - p0.x) * localT\n const q0y = p0.y + (p1.y - p0.y) * localT\n const q0w = p0.z + (p1.z - p0.z) * localT\n const q1x = p1.x + (p2.x - p1.x) * localT\n const q1y = p1.y + (p2.y - p1.y) * localT\n const q1w = p1.z + (p2.z - p1.z) * localT\n const q2x = p2.x + (p3.x - p2.x) * localT\n const q2y = p2.y + (p3.y - p2.y) * localT\n const q2w = p2.z + (p3.z - p2.z) * localT\n\n const r0x = q0x + (q1x - q0x) * localT\n const r0y = q0y + (q1y - q0y) * localT\n const r0w = q0w + (q1w - q0w) * localT\n const r1x = q1x + (q2x - q1x) * localT\n const r1y = q1y + (q2y - q1y) * localT\n const r1w = q1w + (q2w - q1w) * localT\n\n const sx = r0x + (r1x - r0x) * localT\n const sy = r0y + (r1y - r0y) * localT\n const sw = r0w + (r1w - r0w) * localT\n\n const q0 = Vector3.make(q0x, q0y, q0w)\n const r0 = Vector3.make(r0x, r0y, r0w)\n const sLeft = Vector3.make(sx, sy, sw)\n const sRight = Vector3.make(sx, sy, sw)\n const r1 = Vector3.make(r1x, r1y, r1w)\n const q2 = Vector3.make(q2x, q2y, q2w)\n\n const leftPoints: Array<Vector3.Vector3> = [...homogeneous.slice(0, i * 3 + 1), q0, r0, sLeft]\n const rightPoints: Array<Vector3.Vector3> = [sRight, r1, q2, ...homogeneous.slice(i * 3 + 3)]\n\n return [new RationalBezier2dImpl(leftPoints), new RationalBezier2dImpl(rightPoints)]\n})\n\n// Bridge consumed by `Bezier2d.fromRational`. Lives here (not in the bezier\n// module) so the value-import dependency is one-directional: the rational\n// module pulls only types from `./bezier2d`, never vice versa. Returns the\n// raw control-point array; the bezier module wraps it in its own type.\nexport const toBezierPoints = (\n r: RationalBezier2d,\n): Solution.AtMostOne<ReadonlyArray<Vector2.Vector2>> => {\n const homogeneous = homogeneousOf(r)\n const w0 = (homogeneous[0] as Vector3.Vector3).z\n const points: Array<Vector2.Vector2> = []\n for (const h of homogeneous) {\n if (!epsEquals(h.z, w0)) {\n return Solution.none\n }\n points.push(Vector2.make(h.x / h.z, h.y / h.z))\n }\n return Solution.one(points)\n}\n","import * as Characteristic from '../characteristic/characteristic'\nimport * as CubicCurve2d from '../curve/cubic2d'\nimport type * as Matrix4x4 from '../matrix/matrix4x4'\nimport type { Vector2 } from '../vector/vector2'\nimport * as Vector4 from '../vector/vector4'\n\nexport function* toPointQuads(points: Iterable<Vector2>, stride: 1 | 2 | 3) {\n let p0: Vector2 | undefined\n let p1: Vector2 | undefined\n let p2: Vector2 | undefined\n let p3: Vector2 | undefined\n\n for (const point of points) {\n if (p0 === undefined) {\n p0 = point\n continue\n }\n\n if (p1 === undefined) {\n p1 = point\n continue\n }\n\n if (p2 === undefined) {\n p2 = point\n continue\n }\n\n p3 = point\n\n yield [p0, p1, p2, p3] as const\n\n if (stride === 1) {\n p0 = p1\n p1 = p2\n p2 = p3\n } else if (stride === 2) {\n p0 = p2\n p1 = p3\n p2 = undefined\n } else if (stride === 3) {\n p0 = p3\n p1 = undefined\n p2 = undefined\n }\n }\n}\n\nexport function* toCurves(\n points: Iterable<Vector2>,\n matrix: Matrix4x4.Matrix4x4,\n stride: 1 | 2 | 3,\n) {\n for (const quad of toPointQuads(points, stride)) {\n const channels = Vector4.transpose(quad, (p) => [p.x, p.y])\n yield CubicCurve2d.fromPolynomials(...Characteristic.apply(matrix, ...channels))\n }\n}\n","import * as Characteristic from '../characteristic/characteristic'\nimport * as Matrix4x4 from '../matrix/matrix4x4'\nimport * as CubicPath2d from '../path/cubic2d'\nimport { dual, Pipeable } from '../utils'\nimport * as Solution from '../solution/solution'\nimport { invariant } from '../utils'\nimport * as Vector2 from '../vector/vector2'\nimport * as Vector4 from '../vector/vector4'\nimport type { Bezier2d } from './bezier2d'\nimport type { RationalBezier2d } from './rationalBezier2d'\nimport * as RationalBezier2dInternal from './rationalBezier2d.internal'\nimport { toCurves, toPointQuads } from './util'\n\nconst characteristicInverse = Matrix4x4.inverse(Characteristic.cubicBezier)\n\n// Maps a source spline's characteristic matrix to its precomputed conversion\n// matrix `M_bezier_inverse · M_source`, so each `fromBasis` call is one\n// matrix-vector product per axis instead of running Cramer's rule per quad.\nconst conversionCache = new WeakMap<Matrix4x4.Matrix4x4, Matrix4x4.Matrix4x4>()\n\nconst getConversionMatrix = (source: Matrix4x4.Matrix4x4): Matrix4x4.Matrix4x4 => {\n let combined = conversionCache.get(source)\n if (combined === undefined) {\n combined = Matrix4x4.multiply(characteristicInverse, source)\n conversionCache.set(source, combined)\n }\n return combined\n}\n\nexport const Bezier2dTypeId = Symbol('curvy/splines/bezier2d')\nexport type Bezier2dTypeId = typeof Bezier2dTypeId\n\nclass Bezier2dImpl extends Pipeable implements Bezier2d {\n readonly [Bezier2dTypeId]: Bezier2dTypeId = Bezier2dTypeId\n\n readonly points: ReadonlyArray<Vector2.Vector2>\n\n constructor(points: ReadonlyArray<Vector2.Vector2>) {\n invariant(points.length >= 4, 'cubic splines requires 4 or more points')\n invariant(points.length % 3 === 1, 'cubic splines requires (n * 3) + 1 points')\n super()\n this.points = points\n }\n\n [Symbol.iterator]() {\n return this.points[Symbol.iterator]()\n }\n}\n\nexport const isCubicBezier2d = (p: unknown): p is Bezier2d =>\n typeof p === 'object' && p !== null && Bezier2dTypeId in p\n\nexport const make = (\n p0: Vector2.Vector2,\n p1: Vector2.Vector2,\n p2: Vector2.Vector2,\n p3: Vector2.Vector2,\n) => new Bezier2dImpl([p0, p1, p2, p3])\n\nexport const fromArray = (points: ReadonlyArray<Vector2.Vector2>) => new Bezier2dImpl(points)\n\nexport const append = dual<\n (p1: Vector2.Vector2, p2: Vector2.Vector2, p3: Vector2.Vector2) => (p: Bezier2d) => Bezier2d,\n (p: Bezier2d, p1: Vector2.Vector2, p2: Vector2.Vector2, p3: Vector2.Vector2) => Bezier2d\n>(\n 4,\n (p: Bezier2d, p1: Vector2.Vector2, p2: Vector2.Vector2, p3: Vector2.Vector2) =>\n new Bezier2dImpl((p instanceof Bezier2dImpl ? p.points : Array.from(p)).concat(p1, p2, p3)),\n)\n\nexport const fromBasis = (\n p: Iterable<Vector2.Vector2>,\n matrix: Matrix4x4.Matrix4x4,\n stride: 1 | 2 | 3,\n) => {\n const conversion = getConversionMatrix(matrix)\n\n const points: Array<Vector2.Vector2> = []\n\n let x: Vector4.Vector4 | undefined\n let y: Vector4.Vector4 | undefined\n\n for (const [p0, p1, p2, p3] of toPointQuads(p, stride)) {\n x = Matrix4x4.vectorProductLeft(conversion, Vector4.make(p0.x, p1.x, p2.x, p3.x))\n y = Matrix4x4.vectorProductLeft(conversion, Vector4.make(p0.y, p1.y, p2.y, p3.y))\n\n points.push(Vector2.make(x.x, y.x), Vector2.make(x.y, y.y), Vector2.make(x.z, y.z))\n }\n\n if (x && y) {\n points.push(Vector2.make(x.w, y.w))\n }\n\n return fromArray(points)\n}\n\nexport const appendTangentAligned = dual<\n (a: number, p5: Vector2.Vector2, p6: Vector2.Vector2) => (p: Bezier2d) => Bezier2d,\n (p: Bezier2d, a: number, p5: Vector2.Vector2, p6: Vector2.Vector2) => Bezier2d\n>(4, (p: Bezier2d, a: number, p5: Vector2.Vector2, p6: Vector2.Vector2) => {\n const points = p instanceof Bezier2dImpl ? p.points : Array.from(p)\n const p2 = points[points.length - 2] as Vector2.Vector2\n const p3 = points[points.length - 1] as Vector2.Vector2\n const p4 = Vector2.make(p3.x + (p3.x - p2.x) * a, p3.y + (p3.y - p2.y) * a)\n\n return append(p, p4, p5, p6)\n})\n\nexport const appendCurvatureAligned = dual(\n 4,\n (p: Bezier2d, a: number, b: number, p6: Vector2.Vector2) => {\n const points = p instanceof Bezier2dImpl ? p.points : Array.from(p)\n const p1 = points[points.length - 3] as Vector2.Vector2\n const p2 = points[points.length - 2] as Vector2.Vector2\n const p3 = points[points.length - 1] as Vector2.Vector2\n\n const p4 = Vector2.make(p3.x + (p3.x - p2.x) * a, p3.y + (p3.y - p2.y) * a)\n const p5 = Vector2.make(\n p3.x + (p3.x - p2.x) * (2 * a + a ** 2 + b / 2) + (p1.x - p2.x) * a ** 2,\n p3.y + (p3.y - p2.y) * (2 * a + a ** 2 + b / 2) + (p1.y - p2.y) * a ** 2,\n )\n\n return append(p, p4, p5, p6)\n },\n)\n\nexport const appendVelocityAligned = dual<\n (p5: Vector2.Vector2, p6: Vector2.Vector2) => (p: Bezier2d) => Bezier2d,\n (p: Bezier2d, p5: Vector2.Vector2, p6: Vector2.Vector2) => Bezier2d\n>(3, (p: Bezier2d, p5: Vector2.Vector2, p6: Vector2.Vector2) => appendTangentAligned(p, 1, p5, p6))\n\nexport const appendAccelerationAligned = dual<\n (p6: Vector2.Vector2) => (p: Bezier2d) => Bezier2d,\n (p: Bezier2d, p6: Vector2.Vector2) => Bezier2d\n>(2, (p: Bezier2d, p6: Vector2.Vector2) => {\n const points = p instanceof Bezier2dImpl ? p.points : Array.from(p)\n const p1 = points[points.length - 3] as Vector2.Vector2\n const p2 = points[points.length - 2] as Vector2.Vector2\n const p3 = points[points.length - 1] as Vector2.Vector2\n\n const p4 = Vector2.make(2 * p3.x - p2.x, 2 * p3.y - p2.y)\n const p5 = Vector2.make(p1.x + 4 * (p3.x - p2.x), p1.y + 4 * (p3.y - p2.y))\n\n return append(p, p4, p5, p6)\n})\n\nexport const toPath = (p: Bezier2d) =>\n CubicPath2d.make(...toCurves(p, Characteristic.cubicBezier, 3))\n\nexport const fromRational = (r: RationalBezier2d): Solution.AtMostOne<Bezier2d> => {\n const points = RationalBezier2dInternal.toBezierPoints(r)\n if (points._tag === 'none') {\n return points\n }\n return Solution.one(new Bezier2dImpl(points.value))\n}\n\nexport const subdivide = dual<\n (u: number) => (b: Bezier2d) => [Bezier2d, Bezier2d],\n (b: Bezier2d, u: number) => [Bezier2d, Bezier2d]\n>(2, (b: Bezier2d, u: number): [Bezier2d, Bezier2d] => {\n invariant(u > 0 && u < 1, 'subdivide parameter u must be in the open interval (0, 1)')\n\n const points = b instanceof Bezier2dImpl ? b.points : Array.from(b)\n const segmentCount = (points.length - 1) / 3\n const t = u * segmentCount\n const i = Math.floor(t)\n const localT = t - i\n\n // exact segment boundary: no de Casteljau needed, just slice\n if (localT === 0) {\n return [new Bezier2dImpl(points.slice(0, i * 3 + 1)), new Bezier2dImpl(points.slice(i * 3))]\n }\n\n const p0 = points[i * 3] as Vector2.Vector2\n const p1 = points[i * 3 + 1] as Vector2.Vector2\n const p2 = points[i * 3 + 2] as Vector2.Vector2\n const p3 = points[i * 3 + 3] as Vector2.Vector2\n\n // de Casteljau split — produces five new points between p0 and p3:\n // left half: [p0, q0, r0, s], right half: [s, r1, q2, p3]\n const q0x = p0.x + (p1.x - p0.x) * localT\n const q0y = p0.y + (p1.y - p0.y) * localT\n const q1x = p1.x + (p2.x - p1.x) * localT\n const q1y = p1.y + (p2.y - p1.y) * localT\n const q2x = p2.x + (p3.x - p2.x) * localT\n const q2y = p2.y + (p3.y - p2.y) * localT\n\n const r0x = q0x + (q1x - q0x) * localT\n const r0y = q0y + (q1y - q0y) * localT\n const r1x = q1x + (q2x - q1x) * localT\n const r1y = q1y + (q2y - q1y) * localT\n\n const sx = r0x + (r1x - r0x) * localT\n const sy = r0y + (r1y - r0y) * localT\n\n const q0 = Vector2.make(q0x, q0y)\n const r0 = Vector2.make(r0x, r0y)\n const sLeft = Vector2.make(sx, sy)\n const sRight = Vector2.make(sx, sy)\n const r1 = Vector2.make(r1x, r1y)\n const q2 = Vector2.make(q2x, q2y)\n\n const leftPoints: Array<Vector2.Vector2> = [...points.slice(0, i * 3 + 1), q0, r0, sLeft]\n const rightPoints: Array<Vector2.Vector2> = [sRight, r1, q2, ...points.slice(i * 3 + 3)]\n\n return [new Bezier2dImpl(leftPoints), new Bezier2dImpl(rightPoints)]\n})\n","import type { CubicPath2d } from '../path/cubic2d'\nimport type { Pipeable } from '../utils'\nimport type * as Solution from '../solution/solution'\nimport type { Vector2 } from '../vector/vector2'\nimport type { Bezier2dTypeId } from './bezier2d.internal'\nimport * as internal from './bezier2d.internal'\nimport type { RationalBezier2d } from './rationalBezier2d'\n\n/**\n * A Bézier curve in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The characteristic matrix that identifies this spline family lives in the\n * `characteristic` module as `Characteristic.cubicBezier`.\n *\n * @since 1.0.0\n */\nexport interface Bezier2d extends Pipeable {\n readonly [Bezier2dTypeId]: Bezier2dTypeId\n [Symbol.iterator](): IterableIterator<Vector2>\n}\n\n/**\n * Creates a new `Bezier2d` instance.\n *\n * @param p0 - The first control point.\n * @param p1 - The second control point.\n * @param p2 - The third control point.\n * @param p3 - The fourth control point.\n * @returns A new `Bezier2d` instance.\n * @since 1.0.0\n */\nexport const make: (p0: Vector2, p1: Vector2, p2: Vector2, p3: Vector2) => Bezier2d = internal.make\n\n/**\n * Creates a new `Bezier2d` instance from an array of control points.\n *\n * @param points - The control points.\n * @returns A new `Bezier2d` instance.\n * @since 1.0.0\n */\nexport const fromArray: (points: ReadonlyArray<Vector2>) => Bezier2d = internal.fromArray\n\n/**\n * Checks if a value is a `Bezier2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `Bezier2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isCubicBezier2d: (p: unknown) => p is Bezier2d = internal.isCubicBezier2d\n\nexport const append: {\n /**\n * Appends control points to a `Bezier2d`.\n *\n * @param p1 - The second control point (first tangent).\n * @param p2 - The third control point (second tangent).\n * @param p3 - The fourth control point (end point).\n * @returns A function that takes a `Bezier2d` and returns a new `Bezier2d` instance with the appended control points.\n */\n (p1: Vector2, p2: Vector2, p3: Vector2): (p: Bezier2d) => Bezier2d\n /**\n * Appends control points to a `Bezier2d`.\n *\n * @param p - The `Bezier2d` to append the control points to.\n * @param p1 - The second control point (first tangent).\n * @param p2 - The third control point (second tangent).\n * @param p3 - The fourth control point (end point).\n * @returns A new `Bezier2d` instance with the appended control points.\n */\n (p: Bezier2d, p1: Vector2, p2: Vector2, p3: Vector2): Bezier2d\n} = internal.append\n\nexport const appendTangentAligned: {\n /**\n * Appends control points to a `Bezier2d` with aligned tangents.\n *\n * @param ratio - The ratio of the tangents.\n * @param p2 - The third control point (second tangent).\n * @param p3 - The fourth control point (end point).\n * @returns A function that takes a `Bezier2d` and returns a new `Bezier2d` instance with the appended control points.\n */\n (ratio: number, p2: Vector2, p3: Vector2): (p: Bezier2d) => Bezier2d\n /**\n * Appends control points to a `Bezier2d` with aligned tangents.\n *\n * @param p - The `Bezier2d` to append the control points to.\n * @param ratio - The ratio of the tangents.\n * @param p2 - The third control point (second tangent).\n * @param p3 - The fourth control point (end point).\n * @returns A new `Bezier2d` instance with the appended control points.\n */\n (p: Bezier2d, ratio: number, p2: Vector2, p3: Vector2): Bezier2d\n} = internal.appendTangentAligned\n\nexport const appendCurvatureAligned: {\n /**\n * Appends control points to a `Bezier2d` with aligned curvature (G² continuity).\n *\n * @param a - The first curvature parameter.\n * @param b - The second curvature parameter.\n * @param p6 - The sixth control point (end point).\n * @returns A function that takes a `Bezier2d` and returns a new `Bezier2d` instance with the appended control points.\n */\n (a: number, b: number, p6: Vector2): (p: Bezier2d) => Bezier2d\n /**\n * Appends control points to a `Bezier2d` with aligned curvature (G² continuity).\n *\n * @param p - The `Bezier2d` to append the control points to.\n * @param a - The first curvature parameter.\n * @param b - The second curvature parameter.\n * @param p6 - The sixth control point (end point).\n * @returns A new `Bezier2d` instance with the appended control points.\n */\n (p: Bezier2d, a: number, b: number, p6: Vector2): Bezier2d\n} = internal.appendCurvatureAligned\n\nexport const appendVelocityAligned: {\n /**\n * Appends control points to a `Bezier2d` with aligned velocity.\n *\n * @param p2 - The second control point (first tangent).\n * @param p3 - The third control point (second tangent).\n * @returns A function that takes a `Bezier2d` and returns a new `Bezier2d` instance with the appended control points.\n */\n (p2: Vector2, p3: Vector2): (p: Bezier2d) => Bezier2d\n /**\n * Appends control points to a `Bezier2d` with aligned velocity.\n *\n * @param p - The `Bezier2d` to append the control points to.\n * @param p2 - The second control point (first tangent).\n * @param p3 - The third control point (second tangent).\n * @returns A new `Bezier2d` instance with the appended control points.\n */\n (p: Bezier2d, p2: Vector2, p3: Vector2): Bezier2d\n} = internal.appendVelocityAligned\n\nexport const appendAccelerationAligned: {\n /**\n * Appends control points to a `Bezier2d` with aligned acceleration.\n *\n * @param p3 - The third control point (second tangent).\n * @returns A function that takes a `Bezier2d` and returns a new `Bezier2d` instance with the appended control points.\n */\n (p3: Vector2): (p: Bezier2d) => Bezier2d\n /**\n * Appends control points to a `Bezier2d` with aligned acceleration.\n *\n * @param p - The `Bezier2d` to append the control points to.\n * @param p3 - The third control point (second tangent).\n * @returns A new `Bezier2d` instance with the appended control points.\n */\n (p: Bezier2d, p3: Vector2): Bezier2d\n} = internal.appendAccelerationAligned\n\n/**\n * Converts a `Bezier2d` to a `CubicPath2d`.\n *\n * @param p - The `Bezier2d` to convert.\n * @returns A new `CubicPath2d` instance representing the same curve as the `Bezier2d`.\n * @since 1.0.0\n */\nexport const toPath: (p: Bezier2d) => CubicPath2d = internal.toPath\n\n/**\n * Attempts to lower a `RationalBezier2d` to a non-rational `Bezier2d`.\n *\n * Succeeds with `Solution.one(bezier)` when the rational curve's weights are\n * uniform (the curve is mathematically a polynomial Bézier) and returns\n * `Solution.none` otherwise — the rational curve cannot be represented\n * exactly by a non-rational cubic Bézier.\n *\n * @param r - The rational bezier to convert.\n * @returns Either a `Bezier2d` instance or `Solution.none`.\n * @since 2.1.0\n */\nexport const fromRational: (r: RationalBezier2d) => Solution.AtMostOne<Bezier2d> =\n internal.fromRational\n\nexport const subdivide: {\n /**\n * Splits a `Bezier2d` at the given global parameter `u ∈ (0, 1)` using\n * de Casteljau's algorithm. The two returned beziers together trace the\n * same curve as the input — the left covers `[0, u]`, the right covers\n * `[u, 1]`.\n *\n * @param b - The bezier to split.\n * @param u - The split parameter in the open interval `(0, 1)`.\n * @returns A two-element tuple of the left and right halves.\n * @since 1.1.0\n */\n (b: Bezier2d, u: number): [Bezier2d, Bezier2d]\n /**\n * Splits a `Bezier2d` at the given global parameter `u ∈ (0, 1)`.\n *\n * @param u - The split parameter in the open interval `(0, 1)`.\n * @returns A function that takes a bezier and returns the two halves.\n * @since 1.1.0\n */\n (u: number): (b: Bezier2d) => [Bezier2d, Bezier2d]\n} = internal.subdivide\n","import * as Characteristic from '../characteristic/characteristic'\nimport * as CubicPath2d from '../path/cubic2d'\nimport { dual, Pipeable } from '../utils'\nimport { invariant } from '../utils'\nimport * as Vector2 from '../vector/vector2'\nimport type { Bezier2d } from './bezier2d'\nimport * as bezierInternal from './bezier2d.internal'\nimport type { Cardinal2d } from './cardinal2d'\nimport { toCurves } from './util'\n\nexport const Cardinal2dTypeId: unique symbol = Symbol.for('curvy/splines/cardinal2d')\nexport type Cardinal2dTypeId = typeof Cardinal2dTypeId\n\nexport class Cardinal2dImpl extends Pipeable {\n readonly [Cardinal2dTypeId]: Cardinal2dTypeId = Cardinal2dTypeId\n\n readonly points: ReadonlyArray<Vector2.Vector2>\n\n constructor(points: ReadonlyArray<Vector2.Vector2>) {\n invariant(points.length >= 2, 'cardinal splines requires 2 or more points')\n super()\n this.points = points\n }\n\n [Symbol.iterator]() {\n return this.points[Symbol.iterator]()\n }\n}\n\nexport const isCardinal2d = (p: unknown): p is Cardinal2d =>\n typeof p === 'object' && p !== null && Cardinal2dTypeId in p\n\nexport const make = (...points: ReadonlyArray<Vector2.Vector2>) => new Cardinal2dImpl(points)\n\nexport const fromArray = (points: ReadonlyArray<Vector2.Vector2>) => new Cardinal2dImpl(points)\n\nexport const append = dual<\n (...points: ReadonlyArray<Vector2.Vector2>) => (p: Cardinal2d) => Cardinal2d,\n (p: Cardinal2d, ...points: ReadonlyArray<Vector2.Vector2>) => Cardinal2d\n>(\n (args) => isCardinal2d(args[0]),\n (p: Cardinal2d, ...points: ReadonlyArray<Vector2.Vector2>) =>\n new Cardinal2dImpl([...p, ...points]),\n)\n\nexport const prepend = dual<\n (...points: ReadonlyArray<Vector2.Vector2>) => (p: Cardinal2d) => Cardinal2d,\n (p: Cardinal2d, ...points: ReadonlyArray<Vector2.Vector2>) => Cardinal2d\n>(\n (args) => isCardinal2d(args[0]),\n (p: Cardinal2d, ...points: ReadonlyArray<Vector2.Vector2>) =>\n new Cardinal2dImpl([...points, ...p]),\n)\n\nexport const withDuplicatedEndpoints = (p: Cardinal2d) => {\n const points = p instanceof Cardinal2dImpl ? p.points : [...p]\n return new Cardinal2dImpl([\n points[0] as Vector2.Vector2,\n ...points,\n points[points.length - 1] as Vector2.Vector2,\n ])\n}\n\nexport const withReflectedEndpoints = dual(\n (args) => isCardinal2d(args[0]),\n (p: Cardinal2d, scale = 1) => {\n if (scale === 0) {\n return withDuplicatedEndpoints(p)\n }\n\n const points = p instanceof Cardinal2dImpl ? p.points : [...p]\n const p0 = points[0] as Vector2.Vector2\n const p1 = points[1] as Vector2.Vector2\n\n const p2 = points[points.length - 2] as Vector2.Vector2\n const p3 = points[points.length - 1] as Vector2.Vector2\n\n return new Cardinal2dImpl([\n Vector2.subtract(p1, p0).pipe(Vector2.scale(scale), Vector2.add(p0)),\n ...points,\n Vector2.subtract(p2, p3).pipe(Vector2.scale(scale), Vector2.add(p3)),\n ])\n },\n)\n\n// `cubicCardinal(0.5)` returns the cached Catmull-Rom matrix from a shared\n// per-tension cache in the `characteristic` module — no need to special-case\n// the 0.5 path here.\nexport const toPath = dual(\n (args) => isCardinal2d(args[0]),\n (p: Cardinal2d, scale = 0.5) =>\n CubicPath2d.make(...toCurves(p, Characteristic.cubicCardinal(scale), 1)),\n)\n\nexport const toBezier = (p: Cardinal2d, scale = 0.5): Bezier2d =>\n bezierInternal.fromBasis(p, Characteristic.cubicCardinal(scale), 1)\n","import type { CubicPath2d } from '../path/cubic2d'\nimport type { Pipeable } from '../utils'\nimport type { Vector2 } from '../vector/vector2'\nimport type { Bezier2d } from './bezier2d'\nimport type { Cardinal2dTypeId } from './cardinal2d.internal'\nimport * as internal from './cardinal2d.internal'\n\n/**\n * A Cardinal spline in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The characteristic matrix that identifies this spline family lives in the\n * `characteristic` module as `Characteristic.cubicCardinal(tension)` (and\n * the Catmull-Rom variant as `Characteristic.cubicCatmullRom`).\n *\n * @since 1.0.0\n */\nexport interface Cardinal2d extends Pipeable {\n readonly [Cardinal2dTypeId]: Cardinal2dTypeId\n [Symbol.iterator](): IterableIterator<Vector2>\n}\n\n/**\n * Checks if a value is a `Cardinal2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `Cardinal2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isCardinal2d: (p: unknown) => p is Cardinal2d = internal.isCardinal2d\n\n/**\n * Creates a new `Cardinal2d` instance.\n *\n * @param p0 - The first control point.\n * @param p1 - The second control point.\n * @param points - The remaining control points.\n * @returns A new `Cardinal2d` instance.\n * @since 1.0.0\n */\nexport const make: (p0: Vector2, p1: Vector2, ...points: ReadonlyArray<Vector2>) => Cardinal2d =\n internal.make\n\n/**\n * Creates a new `Cardinal2d` instance from an array of control points.\n *\n * @param points - The control points.\n * @returns A new `Cardinal2d` instance.\n * @since 1.0.0\n */\nexport const fromArray: (points: ReadonlyArray<Vector2>) => Cardinal2d = internal.fromArray\n\nexport const append: {\n /**\n * Appends control points to a `Cardinal2d`.\n *\n * @param points - The control points to append.\n * @returns A function that takes a `Cardinal2d` and returns a new `Cardinal2d` instance with the appended control points.\n * @since 1.0.0\n */\n (...points: ReadonlyArray<Vector2>): (c: Cardinal2d) => Cardinal2d\n /**\n * Appends control points to a `Cardinal2d`.\n *\n * @param c - The `Cardinal2d` to append the control points to.\n * @param points - The control points to append.\n * @returns A new `Cardinal2d` instance with the appended control points.\n * @since 1.0.0\n */\n (c: Cardinal2d, ...points: ReadonlyArray<Vector2>): Cardinal2d\n} = internal.append\n\nexport const prepend: {\n /**\n * Prepends control points to a `Cardinal2d`.\n *\n * @param points - The control points to prepend.\n * @returns A function that takes a `Cardinal2d` and returns a new `Cardinal2d` instance with the prepended control points.\n * @since 1.0.0\n */\n (...points: ReadonlyArray<Vector2>): (c: Cardinal2d) => Cardinal2d\n /**\n * Prepends control points to a `Cardinal2d`.\n *\n * @param c - The `Cardinal2d` to prepend the control points to.\n * @param points - The control points to prepend.\n * @returns A new `Cardinal2d` instance with the prepended control points.\n * @since 1.0.0\n */\n (c: Cardinal2d, ...points: ReadonlyArray<Vector2>): Cardinal2d\n} = internal.prepend\n\n/**\n * Doubles the endpoints of a `Cardinal2d` spline.\n *\n * @param c - The `Cardinal2d` to duplicate the endpoints of.\n * @returns A new `Cardinal2d` instance with the duplicated endpoints.\n * @since 1.0.0\n */\nexport const withDuplicatedEndpoints: (c: Cardinal2d) => Cardinal2d =\n internal.withDuplicatedEndpoints\n\nexport const withReflectedEndpoints: {\n /**\n * Reflects the endpoints of a `Cardinal2d` spline.\n *\n * @param scale - The scale factor for the reflection.\n * @returns A function that takes a `Cardinal2d` and returns a new `Cardinal2d` instance with the reflected endpoints.\n * @since 1.0.0\n */\n (scale: number): (c: Cardinal2d) => Cardinal2d\n /**\n * Reflects the endpoints of a `Cardinal2d` spline.\n *\n * @param c - The `Cardinal2d` to reflect the endpoints of.\n * @param scale - The scale factor for the reflection.\n * @returns A new `Cardinal2d` instance with the reflected endpoints.\n * @since 1.0.0\n */\n (c: Cardinal2d, scale?: number): Cardinal2d\n} = internal.withReflectedEndpoints\n\nexport const toPath: {\n /**\n * Converts a `Cardinal2d` to a `CubicPath2d`.\n *\n * @param scale - The scale factor for the conversion.\n * @returns A Function that takes a `Cardinal2d` and returns a new `CubicPath2d` instance.\n * @since 1.0.0\n */\n (scale: number): (c: Cardinal2d) => CubicPath2d\n /**\n * Converts a `Cardinal2d` to a `CubicPath2d`.\n *\n * @param c - The `Cardinal2d` to convert.\n * @param scale - The scale factor for the conversion.\n * @returns A new `CubicPath2d` instance representing the same curve as the `Cardinal2d`.\n * @since 1.0.0\n */\n (c: Cardinal2d, scale?: number): CubicPath2d\n} = internal.toPath\n\nexport const toBezier: {\n /**\n * Converts a `Cardinal2d` to a `Bezier2d`.\n *\n * @param p - The `Cardinal2d` to convert.\n * @returns A new `Bezier2d` instance representing the same curve as the `Cardinal2d`.\n * @since 1.0.0\n */\n (p: Cardinal2d): Bezier2d\n /**\n * Converts a `Cardinal2d` to a `Bezier2d`.\n *\n * @param p - The `Cardinal2d` to convert.\n * @param scale - The scale factor for the conversion.\n * @returns A new `Bezier2d` instance representing the same curve as the `Cardinal2d`.\n * @since 1.0.0\n */\n (p: Cardinal2d, scale: number): Bezier2d\n} = internal.toBezier\n","import * as Characteristic from '../characteristic/characteristic'\nimport * as CubicPath2d from '../path/cubic2d'\nimport { dual, Pipeable } from '../utils'\nimport { invariant } from '../utils'\nimport type * as Vector2 from '../vector/vector2'\nimport type { Bezier2d } from './bezier2d'\nimport * as bezierInternal from './bezier2d.internal'\nimport type { Hermite2d } from './hermite2d'\nimport { toCurves } from './util'\n\nexport const Hermite2dTypeId = Symbol('curvy/splines/hermite2d')\nexport type Hermite2dTypeId = typeof Hermite2dTypeId\n\nclass Hermite2dImpl extends Pipeable implements Hermite2d {\n readonly [Hermite2dTypeId]: Hermite2dTypeId = Hermite2dTypeId\n\n readonly points: ReadonlyArray<Vector2.Vector2>\n\n constructor(points: ReadonlyArray<Vector2.Vector2>) {\n invariant(points.length >= 4, 'hermite splines requires 4 or more points')\n invariant(points.length % 2 === 0, 'hermite splines requires (n * 2) points')\n\n super()\n this.points = points\n }\n\n [Symbol.iterator]() {\n return this.points[Symbol.iterator]()\n }\n}\n\nexport const isHermite2d = (p: unknown): p is Hermite2d =>\n typeof p === 'object' && p !== null && Hermite2dTypeId in p\n\nexport const make = (\n p0: Vector2.Vector2,\n v0: Vector2.Vector2,\n p1: Vector2.Vector2,\n v1: Vector2.Vector2,\n) => new Hermite2dImpl([p0, v0, p1, v1])\n\nexport const fromArray = (points: ReadonlyArray<Vector2.Vector2>) => new Hermite2dImpl(points)\n\nexport const append = dual<\n (p1: Vector2.Vector2, v1: Vector2.Vector2) => (p: Hermite2d) => Hermite2d,\n (p: Hermite2d, p1: Vector2.Vector2, v1: Vector2.Vector2) => Hermite2d\n>(3, (p: Hermite2d, p1: Vector2.Vector2, v1: Vector2.Vector2) => {\n const points = p instanceof Hermite2dImpl ? p.points : Array.from(p)\n return new Hermite2dImpl(points.concat(p1, v1))\n})\n\nexport const prepend = dual<\n (p0: Vector2.Vector2, v0: Vector2.Vector2) => (p: Hermite2d) => Hermite2d,\n (p: Hermite2d, p0: Vector2.Vector2, v0: Vector2.Vector2) => Hermite2d\n>(3, (p: Hermite2d, p0: Vector2.Vector2, v0: Vector2.Vector2) => {\n const points = p instanceof Hermite2dImpl ? p.points : Array.from(p)\n return new Hermite2dImpl([p0, v0].concat(points))\n})\n\nexport const toPath = (p: Hermite2d) =>\n CubicPath2d.make(...toCurves(p, Characteristic.cubicHermite, 2))\n\nexport const toBezier = (p: Hermite2d): Bezier2d =>\n bezierInternal.fromBasis(p, Characteristic.cubicHermite, 2)\n","import type { CubicPath2d } from '../path/cubic2d'\nimport type { Pipeable } from '../utils'\nimport type { Vector2 } from '../vector/vector2'\nimport type { Bezier2d } from './bezier2d'\nimport * as internal from './hermite2d.internal'\nimport type { Hermite2dTypeId } from './hermite2d.internal'\n\n/**\n * A Hermite spline in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The characteristic matrix that identifies this spline family lives in the\n * `characteristic` module as `Characteristic.cubicHermite`.\n *\n * @since 1.0.0\n */\nexport interface Hermite2d extends Pipeable {\n readonly [Hermite2dTypeId]: Hermite2dTypeId\n\n [Symbol.iterator](): IterableIterator<Vector2>\n}\n\n/**\n * Checks if a value is a `Hermite2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `Hermite2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isHermite2d: (p: unknown) => p is Hermite2d = internal.isHermite2d\n\n/**\n * Creates a new `Hermite2d` instance.\n *\n * @param p0 - The first control point.\n * @param v0 - The first tangent vector.\n * @param p1 - The second control point.\n * @param v1 - The second tangent vector.\n * @returns A new `Hermite2d` instance.\n * @since 1.0.0\n */\nexport const make: (p0: Vector2, v0: Vector2, p1: Vector2, v1: Vector2) => Hermite2d = internal.make\n\n/**\n * Creates a new `Hermite2d` instance from an array of control points.\n *\n * @param points - The control points.\n * @returns A new `Hermite2d` instance.\n * @since 1.0.0\n */\nexport const fromArray: (points: ReadonlyArray<Vector2>) => Hermite2d = internal.fromArray\n\nexport const append: {\n /**\n * Appends a new control point and tangent vector to the Hermite spline.\n *\n * @param p1 - The new control point.\n * @param v1 - The new tangent vector.\n * @returns A new `Hermite2d` instance with the appended control point and tangent vector.\n * @since 1.0.0\n */\n (p1: Vector2, v1: Vector2): (p: Hermite2d) => Hermite2d\n /**\n * Appends a new control point and tangent vector to the Hermite spline.\n *\n * @param p - The `Hermite2d` to append the control point and tangent vector to.\n * @param p1 - The new control point.\n * @param v1 - The new tangent vector.\n * @returns A new `Hermite2d` instance with the appended control point and tangent vector.\n * @since 1.0.0\n */\n (p: Hermite2d, p1: Vector2, v1: Vector2): Hermite2d\n} = internal.append\n\nexport const prepend: {\n /**\n * Prepends a new control point and tangent vector to the Hermite spline.\n *\n * @param p0 - The new control point.\n * @param v0 - The new tangent vector.\n * @returns A new `Hermite2d` instance with the prepended control point and tangent vector.\n * @since 1.0.0\n */\n (p0: Vector2, v0: Vector2): (p: Hermite2d) => Hermite2d\n /**\n * Prepends a new control point and tangent vector to the Hermite spline.\n *\n * @param p - The `Hermite2d` to prepend the control point and tangent vector to.\n * @param p0 - The new control point.\n * @param v0 - The new tangent vector.\n * @returns A new `Hermite2d` instance with the prepended control point and tangent vector.\n * @since 1.0.0\n */\n (p: Hermite2d, p0: Vector2, v0: Vector2): Hermite2d\n} = internal.prepend\n\n/**\n * Creates a new `CubicPath2d` instance from a `Hermite2d`.\n *\n * @param p - The `Hermite2d` to convert.\n * @returns A new `CubicPath2d` instance.\n * @since 1.0.0\n */\nexport const toPath: (p: Hermite2d) => CubicPath2d = internal.toPath\n\n/**\n * Converts a `Hermite2d` to a `Bezier2d`.\n *\n * @param p - The `Hermite2d` to convert.\n * @returns A new `Bezier2d` instance.\n * @since 1.0.0\n */\nexport const toBezier: (p: Hermite2d) => Bezier2d = internal.toBezier\n","import * as Characteristic from '../characteristic/characteristic'\nimport * as CubicPath2d from '../path/cubic2d'\nimport { dual, Pipeable } from '../utils'\nimport { invariant } from '../utils'\nimport type * as Vector2 from '../vector/vector2'\nimport type { Basis2d } from './basis2d'\nimport type { Bezier2d } from './bezier2d'\nimport * as bezierInternal from './bezier2d.internal'\nimport { toCurves } from './util'\n\nexport const Basis2dTypeId = Symbol('curvy/splines/basis2d')\nexport type Basis2dTypeId = typeof Basis2dTypeId\n\nclass Basis2dImpl extends Pipeable implements Basis2d {\n readonly [Basis2dTypeId]: Basis2dTypeId = Basis2dTypeId\n\n readonly points: ReadonlyArray<Vector2.Vector2>\n\n constructor(points: ReadonlyArray<Vector2.Vector2>) {\n invariant(points.length >= 4, 'basis splines requires 4 or more points')\n super()\n this.points = points\n }\n\n [Symbol.iterator]() {\n return this.points[Symbol.iterator]()\n }\n}\n\nexport const isBasis2d = (p: unknown): p is Basis2d =>\n typeof p === 'object' && p !== null && Basis2dTypeId in p\n\nexport const make = (\n p0: Vector2.Vector2,\n p1: Vector2.Vector2,\n p2: Vector2.Vector2,\n p3: Vector2.Vector2,\n) => new Basis2dImpl([p0, p1, p2, p3])\n\nexport const fromArray = (points: ReadonlyArray<Vector2.Vector2>) => new Basis2dImpl(points)\n\nexport const append = dual<\n (...points: ReadonlyArray<Vector2.Vector2>) => (p: Basis2d) => Basis2d,\n (p: Basis2d, ...points: ReadonlyArray<Vector2.Vector2>) => Basis2d\n>(\n (args) => isBasis2d(args[0]),\n (p: Basis2d, ...points: ReadonlyArray<Vector2.Vector2>) => new Basis2dImpl([...p, ...points]),\n)\n\nexport const prepend = dual<\n (...points: ReadonlyArray<Vector2.Vector2>) => (p: Basis2d) => Basis2d,\n (p: Basis2d, ...points: ReadonlyArray<Vector2.Vector2>) => Basis2d\n>(\n (args) => isBasis2d(args[0]),\n (p: Basis2d, ...points: ReadonlyArray<Vector2.Vector2>) => new Basis2dImpl([...points, ...p]),\n)\n\nexport const withTriplicatedEndpoints = (p: Basis2d) => {\n const points = p instanceof Basis2dImpl ? p.points : [...p]\n return new Basis2dImpl([\n points[0] as Vector2.Vector2,\n points[0] as Vector2.Vector2,\n ...points,\n points[points.length - 1] as Vector2.Vector2,\n points[points.length - 1] as Vector2.Vector2,\n ])\n}\n\nexport const toPath = (p: Basis2d) =>\n CubicPath2d.make(...toCurves(p, Characteristic.cubicBasisSpline, 1))\n\nexport const toBezier = (p: Basis2d): Bezier2d =>\n bezierInternal.fromBasis(p, Characteristic.cubicBasisSpline, 1)\n","import type { CubicPath2d } from '../path/cubic2d'\nimport type { Pipeable } from '../utils'\nimport type { Vector2 } from '../vector/vector2'\nimport type { Basis2dTypeId } from './basis2d.internal'\nimport * as internal from './basis2d.internal'\nimport type { Bezier2d } from './bezier2d'\n\n/**\n * A Basis Spline (uniform cubic B-spline) in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The characteristic matrix that identifies this spline family lives in the\n * `characteristic` module as `Characteristic.cubicBasisSpline`.\n *\n * @since 1.0.0\n */\nexport interface Basis2d extends Pipeable {\n readonly [Basis2dTypeId]: Basis2dTypeId\n [Symbol.iterator](): Iterator<Vector2>\n}\n\n/**\n * Checks if a value is a `Basis2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `Basis2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isBasis2d: (p: unknown) => p is Basis2d = internal.isBasis2d\n\n/**\n * Creates a new `Basis2d` instance.\n *\n * @param p0 - The first control point.\n * @param p1 - The second control point.\n * @param p2 - The third control point.\n * @param p3 - The fourth control point.\n * @returns A new `Basis2d` instance.\n * @since 1.0.0\n */\nexport const make: (p0: Vector2, p1: Vector2, p2: Vector2, p3: Vector2) => Basis2d = internal.make\n\n/**\n * Creates a new `Basis2d` instance from an array of control points.\n *\n * @param points - The control points.\n * @returns A new `Basis2d` instance.\n * @since 1.0.0\n */\nexport const fromArray: (points: ReadonlyArray<Vector2>) => Basis2d = internal.fromArray\n\nexport const append: {\n /**\n * Appends control points to a `Basis2d`.\n *\n * @param points - The control points to append.\n * @returns A function that takes a `Basis2d` and returns a new `Basis2d` instance with the appended control points.\n * @since 1.0.0\n */\n (...points: ReadonlyArray<Vector2>): (p: Basis2d) => Basis2d\n /**\n * Appends control points to a `Basis2d`.\n *\n * @param p - The `Basis2d` to append the control points to.\n * @param points - The control points to append.\n * @returns A new `Basis2d` instance with the appended control points.\n * @since 1.0.0\n */\n (p: Basis2d, ...points: ReadonlyArray<Vector2>): Basis2d\n} = internal.append\n\nexport const prepend: {\n /**\n * Prepends control points to a `Basis2d`.\n *\n * @param points - The control points to prepend.\n * @returns A function that takes a `Basis2d` and returns a new `Basis2d` instance with the prepended control points.\n * @since 1.0.0\n */\n (...points: ReadonlyArray<Vector2>): (p: Basis2d) => Basis2d\n /**\n * Prepends control points to a `Basis2d`.\n *\n * @param p - The `Basis2d` to prepend the control points to.\n * @param points - The control points to prepend.\n * @returns A new `Basis2d` instance with the prepended control points.\n * @since 1.0.0\n */\n (p: Basis2d, ...points: ReadonlyArray<Vector2>): Basis2d\n} = internal.prepend\n\n/**\n * Triplicates the endpoints of a `Basis2d`.\n *\n * This is useful for creating a closed loop spline.\n *\n * @param p - The `Basis2d` to triplicate the endpoints of.\n * @returns A new `Basis2d` instance with the triplicated endpoints.\n * @since 1.0.0\n */\nexport const withTriplicatedEndpoints: (p: Basis2d) => Basis2d = internal.withTriplicatedEndpoints\n\n/**\n * Creates a new `Path2d` from a `Basis2d`.\n *\n * @param p - The `Basis2d` to convert to a `Path2d`.\n * @returns A new `Path2d` instance.\n * @since 1.0.0\n */\nexport const toPath: (p: Basis2d) => CubicPath2d = internal.toPath\n\n/**\n * Converts a `Basis2d` to a `Bezier2d`.\n *\n * @param p - The `Basis2d` to convert.\n * @returns A new `Bezier2d` instance.\n * @since 1.0.0\n */\nexport const toBezier: (p: Basis2d) => Bezier2d = internal.toBezier\n","import type { RationalCubicPath2d } from '../path/rationalCubic2d'\nimport type { Pipeable } from '../utils'\nimport type { Vector2, Weighted } from '../vector/vector2'\nimport type { Bezier2d } from './bezier2d'\nimport type { RationalBezier2dTypeId } from './rationalBezier2d.internal'\nimport * as internal from './rationalBezier2d.internal'\n\n/**\n * A piecewise rational cubic Bézier curve in 2D space.\n *\n * Each control point is a `Vector2.Weighted` carrying a positive scalar\n * weight; the curve evaluates to `Σ w_i · N_i(t) · P_i / Σ w_i · N_i(t)`,\n * where `N_i` are the cubic Bernstein basis functions. With all weights\n * equal, the curve coincides with a non-rational `Bezier2d`. With unequal\n * weights, the curve can exactly represent conic sections — circles,\n * ellipses, parabolas, and hyperbolas — that polynomial Béziers can only\n * approximate.\n *\n * Internally each control point is stored in homogeneous form `(w·x, w·y, w)`,\n * so de Casteljau evaluation is three independent linear interpolations\n * followed by a single division. Iteration projects back to `Vector2.Weighted`\n * — the same shape accepted by {@link make}.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * @since 2.1.0\n */\nexport interface RationalBezier2d extends Pipeable {\n readonly [RationalBezier2dTypeId]: RationalBezier2dTypeId\n [Symbol.iterator](): IterableIterator<Weighted>\n}\n\n/**\n * Checks if a value is a `RationalBezier2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `RationalBezier2d`, `false` otherwise.\n * @since 2.1.0\n */\nexport const isRationalBezier2d: (p: unknown) => p is RationalBezier2d = internal.isRationalBezier2d\n\n/**\n * Creates a new single-segment `RationalBezier2d` from four weighted control points.\n *\n * Equal weights produce a curve coincident with the corresponding polynomial\n * cubic Bézier; unequal weights produce a true rational curve capable of\n * representing conics exactly.\n *\n * @param p0 - The first weighted control point (curve start).\n * @param p1 - The second weighted control point (start handle).\n * @param p2 - The third weighted control point (end handle).\n * @param p3 - The fourth weighted control point (curve end).\n * @returns A new `RationalBezier2d` instance.\n * @since 2.1.0\n */\nexport const make: (p0: Weighted, p1: Weighted, p2: Weighted, p3: Weighted) => RationalBezier2d =\n internal.make\n\n/**\n * Creates a new `RationalBezier2d` from an array of weighted control points.\n *\n * The array must contain `(n * 3) + 1` entries to describe `n` joined cubic\n * segments.\n *\n * @param points - The weighted control points.\n * @returns A new `RationalBezier2d` instance.\n * @since 2.1.0\n */\nexport const fromArray: (points: ReadonlyArray<Weighted>) => RationalBezier2d = internal.fromArray\n\n/**\n * Creates a new single-segment `RationalBezier2d` from four points with all\n * weights equal to one.\n *\n * Convenience constructor for callers who want the rational evaluator but\n * don't yet have non-unit weights — the resulting curve is mathematically\n * equivalent to the corresponding `Bezier2d.make(p0, p1, p2, p3)` and can\n * later be subdivided or recombined using the rational machinery without\n * conversion overhead.\n *\n * @param p0 - The first control point (curve start).\n * @param p1 - The second control point (start handle).\n * @param p2 - The third control point (end handle).\n * @param p3 - The fourth control point (curve end).\n * @returns A new `RationalBezier2d` with unit weights.\n * @since 2.1.0\n */\nexport const fromPoints: (p0: Vector2, p1: Vector2, p2: Vector2, p3: Vector2) => RationalBezier2d =\n internal.fromPoints\n\n/**\n * Lifts a non-rational `Bezier2d` into a `RationalBezier2d` by assigning\n * unit weight to every control point. The two curves trace the same path.\n *\n * @param b - The non-rational bezier to lift.\n * @returns A new `RationalBezier2d` with unit weights.\n * @since 2.1.0\n */\nexport const fromBezier: (b: Bezier2d) => RationalBezier2d = internal.fromBezier\n\n/**\n * Converts a `RationalBezier2d` to a `RationalCubicPath2d`.\n *\n * Each segment's four homogeneous control points are expanded into three\n * per-segment monomial cubic polynomials — `x`, `y`, and the shared\n * denominator `w` — yielding a path whose evaluator is three Horner passes\n * plus two divisions per call.\n *\n * Mirrors `Bezier2d.toPath`: spline construction is converted to path\n * evaluation form, and forward evaluation thereafter routes through the\n * path's `solve`.\n *\n * @param r - The rational bezier to convert.\n * @returns A new `RationalCubicPath2d` instance representing the same curve.\n * @since 2.1.0\n */\nexport const toPath: (r: RationalBezier2d) => RationalCubicPath2d = internal.toPath\n\nexport const subdivide: {\n /**\n * Splits a `RationalBezier2d` at the given global parameter `u ∈ (0, 1)`\n * using de Casteljau's algorithm in homogeneous coordinates. The two\n * returned beziers together trace the same curve as the input — the left\n * covers `[0, u]`, the right covers `[u, 1]`.\n *\n * The subdivided halves' control-point weights generally differ from the\n * original's even at unit input weights; this is expected and preserves\n * the curve shape exactly.\n *\n * @param r - The rational bezier to split.\n * @param u - The split parameter in the open interval `(0, 1)`.\n * @returns A two-element tuple of the left and right halves.\n * @since 2.1.0\n */\n (r: RationalBezier2d, u: number): [RationalBezier2d, RationalBezier2d]\n /**\n * Splits a `RationalBezier2d` at the given global parameter `u ∈ (0, 1)`.\n *\n * @param u - The split parameter in the open interval `(0, 1)`.\n * @returns A function that takes a rational bezier and returns the halves.\n * @since 2.1.0\n */\n (u: number): (r: RationalBezier2d) => [RationalBezier2d, RationalBezier2d]\n} = internal.subdivide\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["Vector2.makeWeighted","isRationalBezier2d","Vector3.make","make","fromArray","fromTuples","fromPoints","fromBezier","toPath","RationalCubicCurve2d.fromBezierPoints","RationalCubicPath2d.fromArray","subdivide","Solution.none","Vector2.make","Solution.one","Vector4.transpose","CubicCurve2d.fromPolynomials","Characteristic.apply","Matrix4x4.inverse","Characteristic.cubicBezier","Matrix4x4.multiply","isCubicBezier2d","make","fromArray","fromTuples","Vector2.make","append","Matrix4x4.vectorProductLeft","Vector4.make","appendTangentAligned","appendCurvatureAligned","appendVelocityAligned","appendAccelerationAligned","toPath","CubicPath2d.make","fromRational","RationalBezier2dInternal.toBezierPoints","Solution.one","subdivide","make","internal.make","fromArray","internal.fromArray","fromTuples","internal.fromTuples","internal.isCubicBezier2d","append","internal.append","internal.appendTangentAligned","internal.appendCurvatureAligned","internal.appendVelocityAligned","internal.appendAccelerationAligned","toPath","internal.toPath","internal.fromRational","subdivide","internal.subdivide","isCardinal2d","make","Vector2.isVector2","fromArray","fromTuples","Vector2.make","append","prepend","withDuplicatedEndpoints","withInterpolatedEndpoints","withReflectedEndpoints","scale","Vector2.subtract","Vector2.scale","Vector2.add","withTension","withAlpha","withOptions","Vector2.magnitude","CubicCurve2d.fromCoefficients","toPath","CubicPath2d.make","toBezier","bezierInternal.fromArray","internal.isCardinal2d","make","internal.make","fromArray","internal.fromArray","fromTuples","internal.fromTuples","append","internal.append","prepend","internal.prepend","internal.withDuplicatedEndpoints","internal.withInterpolatedEndpoints","internal.withReflectedEndpoints","internal.withTension","internal.withAlpha","internal.withOptions","toPath","internal.toPath","toBezier","internal.toBezier","isHermite2d","make","fromArray","fromTuples","Vector2.make","append","prepend","toPath","CubicPath2d.make","Characteristic.cubicHermite","toBezier","bezierInternal.fromBasis","internal.isHermite2d","make","internal.make","fromArray","internal.fromArray","fromTuples","internal.fromTuples","append","internal.append","prepend","internal.prepend","toPath","internal.toPath","toBezier","internal.toBezier","isBasis2d","make","fromArray","fromTuples","Vector2.make","append","prepend","withTriplicatedEndpoints","toPath","CubicPath2d.make","Characteristic.cubicBasisSpline","toBezier","bezierInternal.fromBasis","internal.isBasis2d","make","internal.make","fromArray","internal.fromArray","fromTuples","internal.fromTuples","internal.append","internal.prepend","internal.withTriplicatedEndpoints","toPath","internal.toPath","internal.toBezier","internal.isRationalBezier2d","internal.make","internal.fromArray","internal.fromTuples","internal.fromPoints","internal.fromBezier","internal.toPath","internal.subdivide"],"sources":["../../src/splines/rationalBezier2d.internal.ts","../../src/splines/util.ts","../../src/splines/bezier2d.internal.ts","../../src/splines/bezier2d.ts","../../src/splines/cardinal2d.internal.ts","../../src/splines/cardinal2d.ts","../../src/splines/hermite2d.internal.ts","../../src/splines/hermite2d.ts","../../src/splines/basis2d.internal.ts","../../src/splines/basis2d.ts","../../src/splines/rationalBezier2d.ts"],"sourcesContent":["import * as RationalCubicCurve2d from '../curve/rationalCubic2d'\nimport * as RationalCubicPath2d from '../path/rationalCubic2d'\nimport { dual, Pipeable } from '../utils'\nimport * as Solution from '../solution/solution'\nimport { invariant } from '../utils'\nimport { epsEquals } from '../number'\nimport * as Vector2 from '../vector/vector2'\nimport * as Vector3 from '../vector/vector3'\nimport type { Bezier2d } from './bezier2d'\nimport type { RationalBezier2d } from './rationalBezier2d'\n\nexport const RationalBezier2dTypeId = Symbol('curvy/splines/rationalBezier2d')\nexport type RationalBezier2dTypeId = typeof RationalBezier2dTypeId\n\n// Internally each control point is stored in homogeneous form as\n// `(w·x, w·y, w)`. De Casteljau in 3D plus a final projection (`x/w`, `y/w`)\n// is exactly the rational evaluator, so the homogeneous form keeps the hot\n// paths identical to the non-rational case modulo one division at the end.\n\nclass RationalBezier2dImpl extends Pipeable implements RationalBezier2d {\n readonly [RationalBezier2dTypeId]: RationalBezier2dTypeId = RationalBezier2dTypeId\n\n readonly homogeneous: ReadonlyArray<Vector3.Vector3>\n\n constructor(homogeneous: ReadonlyArray<Vector3.Vector3>) {\n invariant(homogeneous.length >= 4, 'rational cubic splines require 4 or more points')\n invariant(homogeneous.length % 3 === 1, 'rational cubic splines require (n * 3) + 1 points')\n super()\n this.homogeneous = homogeneous\n }\n\n *[Symbol.iterator](): IterableIterator<Vector2.Weighted> {\n for (const h of this.homogeneous) {\n yield Vector2.makeWeighted(h.x / h.z, h.y / h.z, h.z)\n }\n }\n}\n\nexport const isRationalBezier2d = (p: unknown): p is RationalBezier2d =>\n typeof p === 'object' && p !== null && RationalBezier2dTypeId in p\n\nconst lift = (p: Vector2.Weighted): Vector3.Vector3 =>\n Vector3.make(p.x * p.weight, p.y * p.weight, p.weight)\n\nexport const make = (\n p0: Vector2.Weighted,\n p1: Vector2.Weighted,\n p2: Vector2.Weighted,\n p3: Vector2.Weighted,\n): RationalBezier2d => new RationalBezier2dImpl([lift(p0), lift(p1), lift(p2), lift(p3)])\n\nexport const fromArray = (points: ReadonlyArray<Vector2.Weighted>): RationalBezier2d =>\n new RationalBezier2dImpl(points.map(lift))\n\nexport const fromTuples = (\n tuples: ReadonlyArray<readonly [number, number, number]>,\n): RationalBezier2d =>\n new RationalBezier2dImpl(\n tuples.map(([x, y, weight]) => Vector3.make(x * weight, y * weight, weight)),\n )\n\nexport const fromPoints = (\n p0: Vector2.Vector2,\n p1: Vector2.Vector2,\n p2: Vector2.Vector2,\n p3: Vector2.Vector2,\n): RationalBezier2d =>\n new RationalBezier2dImpl([\n Vector3.make(p0.x, p0.y, 1),\n Vector3.make(p1.x, p1.y, 1),\n Vector3.make(p2.x, p2.y, 1),\n Vector3.make(p3.x, p3.y, 1),\n ])\n\nexport const fromBezier = (b: Bezier2d): RationalBezier2d => {\n const homogeneous: Array<Vector3.Vector3> = []\n for (const p of b) {\n homogeneous.push(Vector3.make(p.x, p.y, 1))\n }\n return new RationalBezier2dImpl(homogeneous)\n}\n\nconst homogeneousOf = (r: RationalBezier2d): ReadonlyArray<Vector3.Vector3> =>\n r instanceof RationalBezier2dImpl ? r.homogeneous : Array.from(r, lift)\n\n// Conversion from spline form (piecewise Bernstein weighted control points)\n// to path form (per-segment monomial polynomials with shared denominator).\n// Each segment's four homogeneous control points expand into three cubic\n// polynomials — x, y, w — via the same Bernstein-to-monomial mapping that\n// drives `Bezier2d.toPath`, just running on three channels instead of two.\nexport const toPath = (r: RationalBezier2d): RationalCubicPath2d.RationalCubicPath2d => {\n const homogeneous = homogeneousOf(r)\n const segmentCount = (homogeneous.length - 1) / 3\n const curves: Array<RationalCubicCurve2d.RationalCubicCurve2d> = []\n\n for (let i = 0; i < segmentCount; i++) {\n const base = i * 3\n const h0 = homogeneous[base] as Vector3.Vector3\n const h1 = homogeneous[base + 1] as Vector3.Vector3\n const h2 = homogeneous[base + 2] as Vector3.Vector3\n const h3 = homogeneous[base + 3] as Vector3.Vector3\n\n // Project each homogeneous CP back to its weighted form for the\n // `fromBezierPoints` constructor. The constructor re-lifts internally;\n // the round-trip is exact to within 1–2 ULPs for finite positive weights\n // and the conversion is a one-shot, not a hot path.\n curves.push(\n RationalCubicCurve2d.fromBezierPoints(\n Vector2.makeWeighted(h0.x / h0.z, h0.y / h0.z, h0.z),\n Vector2.makeWeighted(h1.x / h1.z, h1.y / h1.z, h1.z),\n Vector2.makeWeighted(h2.x / h2.z, h2.y / h2.z, h2.z),\n Vector2.makeWeighted(h3.x / h3.z, h3.y / h3.z, h3.z),\n ),\n )\n }\n\n return RationalCubicPath2d.fromArray(curves)\n}\n\nexport const subdivide = dual<\n (u: number) => (r: RationalBezier2d) => [RationalBezier2d, RationalBezier2d],\n (r: RationalBezier2d, u: number) => [RationalBezier2d, RationalBezier2d]\n>(2, (r: RationalBezier2d, u: number): [RationalBezier2d, RationalBezier2d] => {\n invariant(u > 0 && u < 1, 'subdivide parameter u must be in the open interval (0, 1)')\n\n const homogeneous = homogeneousOf(r)\n const segmentCount = (homogeneous.length - 1) / 3\n const t = u * segmentCount\n const i = Math.floor(t)\n const localT = t - i\n\n // exact segment boundary: no de Casteljau needed, just slice\n if (localT === 0) {\n return [\n new RationalBezier2dImpl(homogeneous.slice(0, i * 3 + 1)),\n new RationalBezier2dImpl(homogeneous.slice(i * 3)),\n ]\n }\n\n const p0 = homogeneous[i * 3] as Vector3.Vector3\n const p1 = homogeneous[i * 3 + 1] as Vector3.Vector3\n const p2 = homogeneous[i * 3 + 2] as Vector3.Vector3\n const p3 = homogeneous[i * 3 + 3] as Vector3.Vector3\n\n // de Casteljau split in homogeneous space — the new control points sit on\n // the lifted curve, so projecting them back yields valid rational beziers\n // on each side. The split point is shared by both halves.\n const q0x = p0.x + (p1.x - p0.x) * localT\n const q0y = p0.y + (p1.y - p0.y) * localT\n const q0w = p0.z + (p1.z - p0.z) * localT\n const q1x = p1.x + (p2.x - p1.x) * localT\n const q1y = p1.y + (p2.y - p1.y) * localT\n const q1w = p1.z + (p2.z - p1.z) * localT\n const q2x = p2.x + (p3.x - p2.x) * localT\n const q2y = p2.y + (p3.y - p2.y) * localT\n const q2w = p2.z + (p3.z - p2.z) * localT\n\n const r0x = q0x + (q1x - q0x) * localT\n const r0y = q0y + (q1y - q0y) * localT\n const r0w = q0w + (q1w - q0w) * localT\n const r1x = q1x + (q2x - q1x) * localT\n const r1y = q1y + (q2y - q1y) * localT\n const r1w = q1w + (q2w - q1w) * localT\n\n const sx = r0x + (r1x - r0x) * localT\n const sy = r0y + (r1y - r0y) * localT\n const sw = r0w + (r1w - r0w) * localT\n\n const q0 = Vector3.make(q0x, q0y, q0w)\n const r0 = Vector3.make(r0x, r0y, r0w)\n const sLeft = Vector3.make(sx, sy, sw)\n const sRight = Vector3.make(sx, sy, sw)\n const r1 = Vector3.make(r1x, r1y, r1w)\n const q2 = Vector3.make(q2x, q2y, q2w)\n\n const leftPoints: Array<Vector3.Vector3> = [...homogeneous.slice(0, i * 3 + 1), q0, r0, sLeft]\n const rightPoints: Array<Vector3.Vector3> = [sRight, r1, q2, ...homogeneous.slice(i * 3 + 3)]\n\n return [new RationalBezier2dImpl(leftPoints), new RationalBezier2dImpl(rightPoints)]\n})\n\n// Bridge consumed by `Bezier2d.fromRational`. Lives here (not in the bezier\n// module) so the value-import dependency is one-directional: the rational\n// module pulls only types from `./bezier2d`, never vice versa. Returns the\n// raw control-point array; the bezier module wraps it in its own type.\nexport const toBezierPoints = (\n r: RationalBezier2d,\n): Solution.AtMostOne<ReadonlyArray<Vector2.Vector2>> => {\n const homogeneous = homogeneousOf(r)\n const w0 = (homogeneous[0] as Vector3.Vector3).z\n const points: Array<Vector2.Vector2> = []\n for (const h of homogeneous) {\n if (!epsEquals(h.z, w0)) {\n return Solution.none\n }\n points.push(Vector2.make(h.x / h.z, h.y / h.z))\n }\n return Solution.one(points)\n}\n","import * as Characteristic from '../characteristic/characteristic'\nimport * as CubicCurve2d from '../curve/cubic2d'\nimport type * as Matrix4x4 from '../matrix/matrix4x4'\nimport type { Vector2 } from '../vector/vector2'\nimport * as Vector4 from '../vector/vector4'\n\nexport function* toPointQuads(points: Iterable<Vector2>, stride: 1 | 2 | 3) {\n let p0: Vector2 | undefined\n let p1: Vector2 | undefined\n let p2: Vector2 | undefined\n let p3: Vector2 | undefined\n\n for (const point of points) {\n if (p0 === undefined) {\n p0 = point\n continue\n }\n\n if (p1 === undefined) {\n p1 = point\n continue\n }\n\n if (p2 === undefined) {\n p2 = point\n continue\n }\n\n p3 = point\n\n yield [p0, p1, p2, p3] as const\n\n if (stride === 1) {\n p0 = p1\n p1 = p2\n p2 = p3\n } else if (stride === 2) {\n p0 = p2\n p1 = p3\n p2 = undefined\n } else if (stride === 3) {\n p0 = p3\n p1 = undefined\n p2 = undefined\n }\n }\n}\n\nexport function* toCurves(\n points: Iterable<Vector2>,\n matrix: Matrix4x4.Matrix4x4,\n stride: 1 | 2 | 3,\n) {\n for (const quad of toPointQuads(points, stride)) {\n const channels = Vector4.transpose(quad, (p) => [p.x, p.y])\n yield CubicCurve2d.fromPolynomials(...Characteristic.apply(matrix, ...channels))\n }\n}\n","import * as Characteristic from '../characteristic/characteristic'\nimport * as Matrix4x4 from '../matrix/matrix4x4'\nimport * as CubicPath2d from '../path/cubic2d'\nimport { dual, Pipeable } from '../utils'\nimport * as Solution from '../solution/solution'\nimport { invariant } from '../utils'\nimport * as Vector2 from '../vector/vector2'\nimport * as Vector4 from '../vector/vector4'\nimport type { Bezier2d } from './bezier2d'\nimport type { RationalBezier2d } from './rationalBezier2d'\nimport * as RationalBezier2dInternal from './rationalBezier2d.internal'\nimport { toCurves, toPointQuads } from './util'\n\nconst characteristicInverse = Matrix4x4.inverse(Characteristic.cubicBezier)\n\n// Maps a source spline's characteristic matrix to its precomputed conversion\n// matrix `M_bezier_inverse · M_source`, so each `fromBasis` call is one\n// matrix-vector product per axis instead of running Cramer's rule per quad.\nconst conversionCache = new WeakMap<Matrix4x4.Matrix4x4, Matrix4x4.Matrix4x4>()\n\nconst getConversionMatrix = (source: Matrix4x4.Matrix4x4): Matrix4x4.Matrix4x4 => {\n let combined = conversionCache.get(source)\n if (combined === undefined) {\n combined = Matrix4x4.multiply(characteristicInverse, source)\n conversionCache.set(source, combined)\n }\n return combined\n}\n\nexport const Bezier2dTypeId = Symbol('curvy/splines/bezier2d')\nexport type Bezier2dTypeId = typeof Bezier2dTypeId\n\nclass Bezier2dImpl extends Pipeable implements Bezier2d {\n readonly [Bezier2dTypeId]: Bezier2dTypeId = Bezier2dTypeId\n\n readonly points: ReadonlyArray<Vector2.Vector2>\n\n constructor(points: ReadonlyArray<Vector2.Vector2>) {\n invariant(points.length >= 4, 'cubic splines requires 4 or more points')\n invariant(points.length % 3 === 1, 'cubic splines requires (n * 3) + 1 points')\n super()\n this.points = points\n }\n\n [Symbol.iterator]() {\n return this.points[Symbol.iterator]()\n }\n}\n\nexport const isCubicBezier2d = (p: unknown): p is Bezier2d =>\n typeof p === 'object' && p !== null && Bezier2dTypeId in p\n\nexport const make = (\n p0: Vector2.Vector2,\n p1: Vector2.Vector2,\n p2: Vector2.Vector2,\n p3: Vector2.Vector2,\n) => new Bezier2dImpl([p0, p1, p2, p3])\n\nexport const fromArray = (points: ReadonlyArray<Vector2.Vector2>) => new Bezier2dImpl(points)\n\nexport const fromTuples = (tuples: ReadonlyArray<readonly [number, number]>) =>\n new Bezier2dImpl(tuples.map(([x, y]) => Vector2.make(x, y)))\n\nexport const append = dual<\n (p1: Vector2.Vector2, p2: Vector2.Vector2, p3: Vector2.Vector2) => (p: Bezier2d) => Bezier2d,\n (p: Bezier2d, p1: Vector2.Vector2, p2: Vector2.Vector2, p3: Vector2.Vector2) => Bezier2d\n>(\n 4,\n (p: Bezier2d, p1: Vector2.Vector2, p2: Vector2.Vector2, p3: Vector2.Vector2) =>\n new Bezier2dImpl((p instanceof Bezier2dImpl ? p.points : Array.from(p)).concat(p1, p2, p3)),\n)\n\nexport const fromBasis = (\n p: Iterable<Vector2.Vector2>,\n matrix: Matrix4x4.Matrix4x4,\n stride: 1 | 2 | 3,\n) => {\n const conversion = getConversionMatrix(matrix)\n\n const points: Array<Vector2.Vector2> = []\n\n let x: Vector4.Vector4 | undefined\n let y: Vector4.Vector4 | undefined\n\n for (const [p0, p1, p2, p3] of toPointQuads(p, stride)) {\n x = Matrix4x4.vectorProductLeft(conversion, Vector4.make(p0.x, p1.x, p2.x, p3.x))\n y = Matrix4x4.vectorProductLeft(conversion, Vector4.make(p0.y, p1.y, p2.y, p3.y))\n\n points.push(Vector2.make(x.x, y.x), Vector2.make(x.y, y.y), Vector2.make(x.z, y.z))\n }\n\n if (x && y) {\n points.push(Vector2.make(x.w, y.w))\n }\n\n return fromArray(points)\n}\n\nexport const appendTangentAligned = dual<\n (a: number, p5: Vector2.Vector2, p6: Vector2.Vector2) => (p: Bezier2d) => Bezier2d,\n (p: Bezier2d, a: number, p5: Vector2.Vector2, p6: Vector2.Vector2) => Bezier2d\n>(4, (p: Bezier2d, a: number, p5: Vector2.Vector2, p6: Vector2.Vector2) => {\n const points = p instanceof Bezier2dImpl ? p.points : Array.from(p)\n const p2 = points[points.length - 2] as Vector2.Vector2\n const p3 = points[points.length - 1] as Vector2.Vector2\n const p4 = Vector2.make(p3.x + (p3.x - p2.x) * a, p3.y + (p3.y - p2.y) * a)\n\n return append(p, p4, p5, p6)\n})\n\nexport const appendCurvatureAligned = dual(\n 4,\n (p: Bezier2d, a: number, b: number, p6: Vector2.Vector2) => {\n const points = p instanceof Bezier2dImpl ? p.points : Array.from(p)\n const p1 = points[points.length - 3] as Vector2.Vector2\n const p2 = points[points.length - 2] as Vector2.Vector2\n const p3 = points[points.length - 1] as Vector2.Vector2\n\n const p4 = Vector2.make(p3.x + (p3.x - p2.x) * a, p3.y + (p3.y - p2.y) * a)\n const p5 = Vector2.make(\n p3.x + (p3.x - p2.x) * (2 * a + a ** 2 + b / 2) + (p1.x - p2.x) * a ** 2,\n p3.y + (p3.y - p2.y) * (2 * a + a ** 2 + b / 2) + (p1.y - p2.y) * a ** 2,\n )\n\n return append(p, p4, p5, p6)\n },\n)\n\nexport const appendVelocityAligned = dual<\n (p5: Vector2.Vector2, p6: Vector2.Vector2) => (p: Bezier2d) => Bezier2d,\n (p: Bezier2d, p5: Vector2.Vector2, p6: Vector2.Vector2) => Bezier2d\n>(3, (p: Bezier2d, p5: Vector2.Vector2, p6: Vector2.Vector2) => appendTangentAligned(p, 1, p5, p6))\n\nexport const appendAccelerationAligned = dual<\n (p6: Vector2.Vector2) => (p: Bezier2d) => Bezier2d,\n (p: Bezier2d, p6: Vector2.Vector2) => Bezier2d\n>(2, (p: Bezier2d, p6: Vector2.Vector2) => {\n const points = p instanceof Bezier2dImpl ? p.points : Array.from(p)\n const p1 = points[points.length - 3] as Vector2.Vector2\n const p2 = points[points.length - 2] as Vector2.Vector2\n const p3 = points[points.length - 1] as Vector2.Vector2\n\n const p4 = Vector2.make(2 * p3.x - p2.x, 2 * p3.y - p2.y)\n const p5 = Vector2.make(p1.x + 4 * (p3.x - p2.x), p1.y + 4 * (p3.y - p2.y))\n\n return append(p, p4, p5, p6)\n})\n\nexport const toPath = (p: Bezier2d) =>\n CubicPath2d.make(...toCurves(p, Characteristic.cubicBezier, 3))\n\nexport const fromRational = (r: RationalBezier2d): Solution.AtMostOne<Bezier2d> => {\n const points = RationalBezier2dInternal.toBezierPoints(r)\n if (points._tag === 'none') {\n return points\n }\n return Solution.one(new Bezier2dImpl(points.value))\n}\n\nexport const subdivide = dual<\n (u: number) => (b: Bezier2d) => [Bezier2d, Bezier2d],\n (b: Bezier2d, u: number) => [Bezier2d, Bezier2d]\n>(2, (b: Bezier2d, u: number): [Bezier2d, Bezier2d] => {\n invariant(u > 0 && u < 1, 'subdivide parameter u must be in the open interval (0, 1)')\n\n const points = b instanceof Bezier2dImpl ? b.points : Array.from(b)\n const segmentCount = (points.length - 1) / 3\n const t = u * segmentCount\n const i = Math.floor(t)\n const localT = t - i\n\n // exact segment boundary: no de Casteljau needed, just slice\n if (localT === 0) {\n return [new Bezier2dImpl(points.slice(0, i * 3 + 1)), new Bezier2dImpl(points.slice(i * 3))]\n }\n\n const p0 = points[i * 3] as Vector2.Vector2\n const p1 = points[i * 3 + 1] as Vector2.Vector2\n const p2 = points[i * 3 + 2] as Vector2.Vector2\n const p3 = points[i * 3 + 3] as Vector2.Vector2\n\n // de Casteljau split — produces five new points between p0 and p3:\n // left half: [p0, q0, r0, s], right half: [s, r1, q2, p3]\n const q0x = p0.x + (p1.x - p0.x) * localT\n const q0y = p0.y + (p1.y - p0.y) * localT\n const q1x = p1.x + (p2.x - p1.x) * localT\n const q1y = p1.y + (p2.y - p1.y) * localT\n const q2x = p2.x + (p3.x - p2.x) * localT\n const q2y = p2.y + (p3.y - p2.y) * localT\n\n const r0x = q0x + (q1x - q0x) * localT\n const r0y = q0y + (q1y - q0y) * localT\n const r1x = q1x + (q2x - q1x) * localT\n const r1y = q1y + (q2y - q1y) * localT\n\n const sx = r0x + (r1x - r0x) * localT\n const sy = r0y + (r1y - r0y) * localT\n\n const q0 = Vector2.make(q0x, q0y)\n const r0 = Vector2.make(r0x, r0y)\n const sLeft = Vector2.make(sx, sy)\n const sRight = Vector2.make(sx, sy)\n const r1 = Vector2.make(r1x, r1y)\n const q2 = Vector2.make(q2x, q2y)\n\n const leftPoints: Array<Vector2.Vector2> = [...points.slice(0, i * 3 + 1), q0, r0, sLeft]\n const rightPoints: Array<Vector2.Vector2> = [sRight, r1, q2, ...points.slice(i * 3 + 3)]\n\n return [new Bezier2dImpl(leftPoints), new Bezier2dImpl(rightPoints)]\n})\n","import type { CubicPath2d } from '../path/cubic2d'\nimport type { Pipeable } from '../utils'\nimport type * as Solution from '../solution/solution'\nimport type { Vector2 } from '../vector/vector2'\nimport type { Bezier2dTypeId } from './bezier2d.internal'\nimport * as internal from './bezier2d.internal'\nimport type { RationalBezier2d } from './rationalBezier2d'\n\n/**\n * A Bézier curve in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The characteristic matrix that identifies this spline family lives in the\n * `characteristic` module as `Characteristic.cubicBezier`.\n *\n * @since 1.0.0\n */\nexport interface Bezier2d extends Pipeable {\n readonly [Bezier2dTypeId]: Bezier2dTypeId\n [Symbol.iterator](): IterableIterator<Vector2>\n}\n\n/**\n * Creates a new `Bezier2d` instance.\n *\n * @param p0 - The first control point.\n * @param p1 - The second control point.\n * @param p2 - The third control point.\n * @param p3 - The fourth control point.\n * @returns A new `Bezier2d` instance.\n * @since 1.0.0\n */\nexport const make: (p0: Vector2, p1: Vector2, p2: Vector2, p3: Vector2) => Bezier2d = internal.make\n\n/**\n * Creates a new `Bezier2d` instance from an array of control points.\n *\n * @param points - The control points.\n * @returns A new `Bezier2d` instance.\n * @since 1.0.0\n */\nexport const fromArray: (points: ReadonlyArray<Vector2>) => Bezier2d = internal.fromArray\n\n/**\n * Creates a new `Bezier2d` from an array of `[x, y]` tuples. Convenient for\n * data sourced from JSON, CSV, or other tuple-shaped formats.\n *\n * @param tuples - The control points as `[x, y]` tuples.\n * @returns A new `Bezier2d` instance.\n * @since 2.0.0\n */\nexport const fromTuples: (tuples: ReadonlyArray<readonly [number, number]>) => Bezier2d =\n internal.fromTuples\n\n/**\n * Checks if a value is a `Bezier2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `Bezier2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isCubicBezier2d: (p: unknown) => p is Bezier2d = internal.isCubicBezier2d\n\nexport const append: {\n /**\n * Appends control points to a `Bezier2d`.\n *\n * @param p1 - The second control point (first tangent).\n * @param p2 - The third control point (second tangent).\n * @param p3 - The fourth control point (end point).\n * @returns A function that takes a `Bezier2d` and returns a new `Bezier2d` instance with the appended control points.\n */\n (p1: Vector2, p2: Vector2, p3: Vector2): (p: Bezier2d) => Bezier2d\n /**\n * Appends control points to a `Bezier2d`.\n *\n * @param p - The `Bezier2d` to append the control points to.\n * @param p1 - The second control point (first tangent).\n * @param p2 - The third control point (second tangent).\n * @param p3 - The fourth control point (end point).\n * @returns A new `Bezier2d` instance with the appended control points.\n */\n (p: Bezier2d, p1: Vector2, p2: Vector2, p3: Vector2): Bezier2d\n} = internal.append\n\nexport const appendTangentAligned: {\n /**\n * Appends control points to a `Bezier2d` with aligned tangents.\n *\n * @param ratio - The ratio of the tangents.\n * @param p2 - The third control point (second tangent).\n * @param p3 - The fourth control point (end point).\n * @returns A function that takes a `Bezier2d` and returns a new `Bezier2d` instance with the appended control points.\n */\n (ratio: number, p2: Vector2, p3: Vector2): (p: Bezier2d) => Bezier2d\n /**\n * Appends control points to a `Bezier2d` with aligned tangents.\n *\n * @param p - The `Bezier2d` to append the control points to.\n * @param ratio - The ratio of the tangents.\n * @param p2 - The third control point (second tangent).\n * @param p3 - The fourth control point (end point).\n * @returns A new `Bezier2d` instance with the appended control points.\n */\n (p: Bezier2d, ratio: number, p2: Vector2, p3: Vector2): Bezier2d\n} = internal.appendTangentAligned\n\nexport const appendCurvatureAligned: {\n /**\n * Appends control points to a `Bezier2d` with aligned curvature (G² continuity).\n *\n * @param a - The first curvature parameter.\n * @param b - The second curvature parameter.\n * @param p6 - The sixth control point (end point).\n * @returns A function that takes a `Bezier2d` and returns a new `Bezier2d` instance with the appended control points.\n */\n (a: number, b: number, p6: Vector2): (p: Bezier2d) => Bezier2d\n /**\n * Appends control points to a `Bezier2d` with aligned curvature (G² continuity).\n *\n * @param p - The `Bezier2d` to append the control points to.\n * @param a - The first curvature parameter.\n * @param b - The second curvature parameter.\n * @param p6 - The sixth control point (end point).\n * @returns A new `Bezier2d` instance with the appended control points.\n */\n (p: Bezier2d, a: number, b: number, p6: Vector2): Bezier2d\n} = internal.appendCurvatureAligned\n\nexport const appendVelocityAligned: {\n /**\n * Appends control points to a `Bezier2d` with aligned velocity.\n *\n * @param p2 - The second control point (first tangent).\n * @param p3 - The third control point (second tangent).\n * @returns A function that takes a `Bezier2d` and returns a new `Bezier2d` instance with the appended control points.\n */\n (p2: Vector2, p3: Vector2): (p: Bezier2d) => Bezier2d\n /**\n * Appends control points to a `Bezier2d` with aligned velocity.\n *\n * @param p - The `Bezier2d` to append the control points to.\n * @param p2 - The second control point (first tangent).\n * @param p3 - The third control point (second tangent).\n * @returns A new `Bezier2d` instance with the appended control points.\n */\n (p: Bezier2d, p2: Vector2, p3: Vector2): Bezier2d\n} = internal.appendVelocityAligned\n\nexport const appendAccelerationAligned: {\n /**\n * Appends control points to a `Bezier2d` with aligned acceleration.\n *\n * @param p3 - The third control point (second tangent).\n * @returns A function that takes a `Bezier2d` and returns a new `Bezier2d` instance with the appended control points.\n */\n (p3: Vector2): (p: Bezier2d) => Bezier2d\n /**\n * Appends control points to a `Bezier2d` with aligned acceleration.\n *\n * @param p - The `Bezier2d` to append the control points to.\n * @param p3 - The third control point (second tangent).\n * @returns A new `Bezier2d` instance with the appended control points.\n */\n (p: Bezier2d, p3: Vector2): Bezier2d\n} = internal.appendAccelerationAligned\n\n/**\n * Converts a `Bezier2d` to a `CubicPath2d`.\n *\n * @param p - The `Bezier2d` to convert.\n * @returns A new `CubicPath2d` instance representing the same curve as the `Bezier2d`.\n * @since 1.0.0\n */\nexport const toPath: (p: Bezier2d) => CubicPath2d = internal.toPath\n\n/**\n * Attempts to lower a `RationalBezier2d` to a non-rational `Bezier2d`.\n *\n * Succeeds with `Solution.one(bezier)` when the rational curve's weights are\n * uniform (the curve is mathematically a polynomial Bézier) and returns\n * `Solution.none` otherwise — the rational curve cannot be represented\n * exactly by a non-rational cubic Bézier.\n *\n * @param r - The rational bezier to convert.\n * @returns Either a `Bezier2d` instance or `Solution.none`.\n * @since 2.0.0\n */\nexport const fromRational: (r: RationalBezier2d) => Solution.AtMostOne<Bezier2d> =\n internal.fromRational\n\nexport const subdivide: {\n /**\n * Splits a `Bezier2d` at the given global parameter `u ∈ (0, 1)` using\n * de Casteljau's algorithm. The two returned beziers together trace the\n * same curve as the input — the left covers `[0, u]`, the right covers\n * `[u, 1]`.\n *\n * @param b - The bezier to split.\n * @param u - The split parameter in the open interval `(0, 1)`.\n * @returns A two-element tuple of the left and right halves.\n * @since 1.1.0\n */\n (b: Bezier2d, u: number): [Bezier2d, Bezier2d]\n /**\n * Splits a `Bezier2d` at the given global parameter `u ∈ (0, 1)`.\n *\n * @param u - The split parameter in the open interval `(0, 1)`.\n * @returns A function that takes a bezier and returns the two halves.\n * @since 1.1.0\n */\n (u: number): (b: Bezier2d) => [Bezier2d, Bezier2d]\n} = internal.subdivide\n","import * as CubicCurve2d from '../curve/cubic2d'\nimport * as CubicPath2d from '../path/cubic2d'\nimport { dual, invariant, Pipeable } from '../utils'\nimport * as Vector2 from '../vector/vector2'\nimport type { Bezier2d } from './bezier2d'\nimport * as bezierInternal from './bezier2d.internal'\nimport type { Cardinal2d, Options } from './cardinal2d'\nimport { toPointQuads } from './util'\n\nexport const Cardinal2dTypeId: unique symbol = Symbol.for('curvy/splines/cardinal2d')\nexport type Cardinal2dTypeId = typeof Cardinal2dTypeId\n\nconst DEFAULT_TENSION = 0.5\nconst DEFAULT_ALPHA = 0.5\n\nexport class Cardinal2dImpl extends Pipeable implements Cardinal2d {\n readonly [Cardinal2dTypeId]: Cardinal2dTypeId = Cardinal2dTypeId\n\n readonly points: ReadonlyArray<Vector2.Vector2>\n readonly tension: number\n readonly alpha: number\n\n constructor(points: ReadonlyArray<Vector2.Vector2>, tension: number, alpha: number) {\n invariant(points.length >= 2, 'cardinal splines requires 2 or more points')\n super()\n this.points = points\n this.tension = tension\n this.alpha = alpha\n }\n\n [Symbol.iterator]() {\n return this.points[Symbol.iterator]()\n }\n}\n\nexport const isCardinal2d = (p: unknown): p is Cardinal2d =>\n typeof p === 'object' && p !== null && Cardinal2dTypeId in p\n\nconst resolveOptions = (options?: Options): { tension: number; alpha: number } => ({\n tension: options?.tension ?? DEFAULT_TENSION,\n alpha: options?.alpha ?? DEFAULT_ALPHA,\n})\n\n// Overload: `make(options, p0, p1, ...points)` vs `make(p0, p1, ...points)`.\n// First-arg-is-Vector2 ⇒ no options, defaults apply.\nexport const make = (\n ...args:\n | [Vector2.Vector2, Vector2.Vector2, ...Array<Vector2.Vector2>]\n | [Options, Vector2.Vector2, Vector2.Vector2, ...Array<Vector2.Vector2>]\n): Cardinal2d => {\n if (Vector2.isVector2(args[0])) {\n return new Cardinal2dImpl(\n args as ReadonlyArray<Vector2.Vector2>,\n DEFAULT_TENSION,\n DEFAULT_ALPHA,\n )\n }\n const [options, ...points] = args as [Options, ...Array<Vector2.Vector2>]\n const { tension, alpha } = resolveOptions(options)\n return new Cardinal2dImpl(points, tension, alpha)\n}\n\nexport const fromArray = (\n points: ReadonlyArray<Vector2.Vector2>,\n options?: Options,\n): Cardinal2d => {\n const { tension, alpha } = resolveOptions(options)\n return new Cardinal2dImpl(points, tension, alpha)\n}\n\nexport const fromTuples = (\n tuples: ReadonlyArray<readonly [number, number]>,\n options?: Options,\n): Cardinal2d => {\n const { tension, alpha } = resolveOptions(options)\n return new Cardinal2dImpl(\n tuples.map(([x, y]) => Vector2.make(x, y)),\n tension,\n alpha,\n )\n}\n\nexport const append = dual<\n (...points: ReadonlyArray<Vector2.Vector2>) => (p: Cardinal2d) => Cardinal2d,\n (p: Cardinal2d, ...points: ReadonlyArray<Vector2.Vector2>) => Cardinal2d\n>(\n (args) => isCardinal2d(args[0]),\n (p: Cardinal2d, ...points: ReadonlyArray<Vector2.Vector2>) =>\n new Cardinal2dImpl([...p, ...points], p.tension, p.alpha),\n)\n\nexport const prepend = dual<\n (...points: ReadonlyArray<Vector2.Vector2>) => (p: Cardinal2d) => Cardinal2d,\n (p: Cardinal2d, ...points: ReadonlyArray<Vector2.Vector2>) => Cardinal2d\n>(\n (args) => isCardinal2d(args[0]),\n (p: Cardinal2d, ...points: ReadonlyArray<Vector2.Vector2>) =>\n new Cardinal2dImpl([...points, ...p], p.tension, p.alpha),\n)\n\nexport const withDuplicatedEndpoints = (p: Cardinal2d) => {\n const points = p instanceof Cardinal2dImpl ? p.points : [...p]\n return new Cardinal2dImpl(\n [\n points[0] as Vector2.Vector2,\n ...points,\n points[points.length - 1] as Vector2.Vector2,\n ],\n p.tension,\n p.alpha,\n )\n}\n\n// Pinned alias for `withReflectedEndpoints(c, 0)`. The semantics — the spline\n// now interpolates its first and last control points — read more directly\n// than either of the mechanism-named helpers.\nexport const withInterpolatedEndpoints = (p: Cardinal2d) => withDuplicatedEndpoints(p)\n\nexport const withReflectedEndpoints = dual(\n (args) => isCardinal2d(args[0]),\n (p: Cardinal2d, scale = 1) => {\n if (scale === 0) {\n return withDuplicatedEndpoints(p)\n }\n\n const points = p instanceof Cardinal2dImpl ? p.points : [...p]\n const p0 = points[0] as Vector2.Vector2\n const p1 = points[1] as Vector2.Vector2\n\n const p2 = points[points.length - 2] as Vector2.Vector2\n const p3 = points[points.length - 1] as Vector2.Vector2\n\n return new Cardinal2dImpl(\n [\n Vector2.subtract(p1, p0).pipe(Vector2.scale(scale), Vector2.add(p0)),\n ...points,\n Vector2.subtract(p2, p3).pipe(Vector2.scale(scale), Vector2.add(p3)),\n ],\n p.tension,\n p.alpha,\n )\n },\n)\n\nexport const withTension = dual<\n (tension: number) => (p: Cardinal2d) => Cardinal2d,\n (p: Cardinal2d, tension: number) => Cardinal2d\n>(2, (p: Cardinal2d, tension: number) => new Cardinal2dImpl(p.points, tension, p.alpha))\n\nexport const withAlpha = dual<\n (alpha: number) => (p: Cardinal2d) => Cardinal2d,\n (p: Cardinal2d, alpha: number) => Cardinal2d\n>(2, (p: Cardinal2d, alpha: number) => new Cardinal2dImpl(p.points, p.tension, alpha))\n\nexport const withOptions = dual<\n (options: Options) => (p: Cardinal2d) => Cardinal2d,\n (p: Cardinal2d, options: Options) => Cardinal2d\n>(\n 2,\n (p: Cardinal2d, options: Options) =>\n new Cardinal2dImpl(p.points, options.tension ?? p.tension, options.alpha ?? p.alpha),\n)\n\n// Builds one segment from P1 to P2, using P0 and P3 as the surrounding\n// neighbors for tangent computation. Math: standard non-uniform Catmull-Rom\n// tangents, generalized to a tension τ such that τ=0.5 recovers classical\n// Catmull-Rom and τ=0 produces zero tangents (smoothstep-shaped segments).\n// For each endpoint, the local-parameter velocity is the alpha-weighted\n// Hermite tangent scaled by 2τ. When alpha = 0 the chord-length terms\n// collapse to 1 and the formula reduces algebraically to the cached\n// `cubicCardinal` matrix output.\nconst buildCardinalSegment = (\n p0: Vector2.Vector2,\n p1: Vector2.Vector2,\n p2: Vector2.Vector2,\n p3: Vector2.Vector2,\n tension: number,\n alpha: number,\n): CubicCurve2d.CubicCurve2d => {\n const d01 = Vector2.magnitude(Vector2.subtract(p1, p0)) ** alpha\n const d12 = Vector2.magnitude(Vector2.subtract(p2, p1)) ** alpha\n const d23 = Vector2.magnitude(Vector2.subtract(p3, p2)) ** alpha\n\n invariant(\n Number.isFinite(d01) && Number.isFinite(d12) && Number.isFinite(d23),\n 'cardinal: non-finite chord length',\n )\n\n const factor = 2 * tension\n\n // Coincident-point handling: when `d01 = 0` (P0 = P1) and `alpha > 0`, the\n // first tangent term contains `0 × ∞`. The mathematical limit is 0 — the\n // phantom side doesn't contribute — so we drop the term explicitly rather\n // than propagate NaN. Same at the trailing edge with `d23 = 0`.\n // When `alpha = 0`, `d = 1` regardless of chord, so no special-casing.\n const lead = d01 === 0 ? 0 : d12 / d01\n const trail = d23 === 0 ? 0 : d12 / d23\n const mid01 = d01 + d12 === 0 ? 0 : d12 / (d01 + d12)\n const mid23 = d12 + d23 === 0 ? 0 : d12 / (d12 + d23)\n\n // Local-parameter tangent at p1.\n const v1x = factor * ((p1.x - p0.x) * lead - (p2.x - p0.x) * mid01 + (p2.x - p1.x))\n const v1y = factor * ((p1.y - p0.y) * lead - (p2.y - p0.y) * mid01 + (p2.y - p1.y))\n\n // Local-parameter tangent at p2.\n const v2x = factor * ((p2.x - p1.x) - (p3.x - p1.x) * mid23 + (p3.x - p2.x) * trail)\n const v2y = factor * ((p2.y - p1.y) - (p3.y - p1.y) * mid23 + (p3.y - p2.y) * trail)\n\n // Monomial cubic from Hermite (P1, v1, P2, v2):\n // c0 = P1\n // c1 = v1\n // c2 = 3·(P2 - P1) - 2·v1 - v2\n // c3 = 2·(P1 - P2) + v1 + v2\n const dx = p2.x - p1.x\n const dy = p2.y - p1.y\n\n return CubicCurve2d.fromCoefficients(\n Vector2.make(p1.x, p1.y),\n Vector2.make(v1x, v1y),\n Vector2.make(3 * dx - 2 * v1x - v2x, 3 * dy - 2 * v1y - v2y),\n Vector2.make(-2 * dx + v1x + v2x, -2 * dy + v1y + v2y),\n )\n}\n\nfunction* cardinalCurves(p: Cardinal2d): IterableIterator<CubicCurve2d.CubicCurve2d> {\n for (const [p0, p1, p2, p3] of toPointQuads(p, 1)) {\n yield buildCardinalSegment(p0, p1, p2, p3, p.tension, p.alpha)\n }\n}\n\nexport const toPath = (p: Cardinal2d) => CubicPath2d.make(...cardinalCurves(p))\n\n// Converts each segment's monomial cubic to four Bézier control points and\n// stitches them, dropping the shared endpoint between adjacent segments.\n//\n// p0 = c0\n// p1 = c0 + c1/3\n// p2 = c0 + 2c1/3 + c2/3\n// p3 = c0 + c1 + c2 + c3 (== next segment's p0 — shared)\nexport const toBezier = (p: Cardinal2d): Bezier2d => {\n const points: Array<Vector2.Vector2> = []\n let first = true\n\n for (const curve of cardinalCurves(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 if (first) {\n points.push(Vector2.make(c0x, c0y))\n first = false\n }\n points.push(Vector2.make(c0x + c1x / 3, c0y + c1y / 3))\n points.push(Vector2.make(c0x + (2 * c1x) / 3 + c2x / 3, c0y + (2 * c1y) / 3 + c2y / 3))\n points.push(Vector2.make(c0x + c1x + c2x + c3x, c0y + c1y + c2y + c3y))\n }\n\n return bezierInternal.fromArray(points)\n}\n","import type { CubicPath2d } from '../path/cubic2d'\nimport type { Pipeable } from '../utils'\nimport type { Vector2 } from '../vector/vector2'\nimport type { Bezier2d } from './bezier2d'\nimport type { Cardinal2dTypeId } from './cardinal2d.internal'\nimport * as internal from './cardinal2d.internal'\n\n/**\n * A Cardinal spline in 2D space.\n *\n * Carries its parameterization (`tension` and `alpha`) as part of the spline's\n * identity rather than as evaluation arguments — the same control points with\n * different tensions describe different curves, so the spline TYPE includes\n * them. See {@link Options} for parameter semantics.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The classical Cardinal characteristic matrix (uniform parameterization,\n * arbitrary tension) is exposed as `Characteristic.cubicCardinal(tension)`.\n * For non-uniform parameterization (any `alpha != 0`), the per-segment cubic\n * is computed directly from chord-length-weighted tangents.\n *\n * @since 1.0.0\n */\nexport interface Cardinal2d extends Pipeable {\n readonly [Cardinal2dTypeId]: Cardinal2dTypeId\n readonly points: ReadonlyArray<Vector2>\n readonly tension: number\n readonly alpha: number\n [Symbol.iterator](): IterableIterator<Vector2>\n}\n\n/**\n * Configuration for a Cardinal spline. Both fields are optional and carry\n * sensible defaults.\n *\n * - **`tension`** controls how loose or tight the curve is at each interior\n * control point. `tension = 0.5` is classical Catmull-Rom; `tension = 0`\n * produces zero-tangent endpoints (smoothstep-shaped segments between\n * consecutive control points); higher values produce looser, more curved\n * shapes. Default: `0.5`.\n *\n * - **`alpha`** controls how chord lengths between control points scale the\n * tangents. `alpha = 0` is uniform parameterization (classical Catmull-Rom),\n * which can produce cusps and self-intersections when control points\n * cluster. `alpha = 0.5` is centripetal parameterization — Yuksel's\n * recommended default, eliminating those failure modes at minimal shape\n * cost. `alpha = 1` is chordal parameterization. Default: `0.5`\n * (centripetal).\n *\n * @since 2.0.0\n */\nexport interface Options {\n readonly tension?: number\n readonly alpha?: number\n}\n\n/**\n * Checks if a value is a `Cardinal2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `Cardinal2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isCardinal2d: (p: unknown) => p is Cardinal2d = internal.isCardinal2d\n\nexport const make: {\n /**\n * Creates a new `Cardinal2d` with default tension and alpha.\n *\n * @param p0 - The first control point.\n * @param p1 - The second control point.\n * @param points - The remaining control points.\n * @returns A new `Cardinal2d` instance.\n * @since 1.0.0\n */\n (p0: Vector2, p1: Vector2, ...points: ReadonlyArray<Vector2>): Cardinal2d\n /**\n * Creates a new `Cardinal2d` with the given options.\n *\n * @param options - Tension and alpha. See {@link Options}.\n * @param p0 - The first control point.\n * @param p1 - The second control point.\n * @param points - The remaining control points.\n * @returns A new `Cardinal2d` instance.\n * @since 2.0.0\n */\n (options: Options, p0: Vector2, p1: Vector2, ...points: ReadonlyArray<Vector2>): Cardinal2d\n} = internal.make\n\n/**\n * Creates a new `Cardinal2d` from an array of control points.\n *\n * @param points - The control points.\n * @param options - Tension and alpha. See {@link Options}. Defaults to centripetal Catmull-Rom.\n * @returns A new `Cardinal2d` instance.\n * @since 1.0.0\n */\nexport const fromArray: (points: ReadonlyArray<Vector2>, options?: Options) => Cardinal2d =\n internal.fromArray\n\n/**\n * Creates a new `Cardinal2d` from an array of `[x, y]` tuples.\n *\n * @param tuples - The control points as `[x, y]` tuples.\n * @param options - Tension and alpha. See {@link Options}. Defaults to centripetal Catmull-Rom.\n * @returns A new `Cardinal2d` instance.\n * @since 2.0.0\n */\nexport const fromTuples: (\n tuples: ReadonlyArray<readonly [number, number]>,\n options?: Options,\n) => Cardinal2d = internal.fromTuples\n\nexport const append: {\n /**\n * Appends control points to a `Cardinal2d`. Tension and alpha are preserved.\n *\n * @param points - The control points to append.\n * @returns A function that takes a `Cardinal2d` and returns a new instance.\n * @since 1.0.0\n */\n (...points: ReadonlyArray<Vector2>): (c: Cardinal2d) => Cardinal2d\n /**\n * Appends control points to a `Cardinal2d`. Tension and alpha are preserved.\n *\n * @param c - The `Cardinal2d` to append to.\n * @param points - The control points to append.\n * @returns A new `Cardinal2d` instance.\n * @since 1.0.0\n */\n (c: Cardinal2d, ...points: ReadonlyArray<Vector2>): Cardinal2d\n} = internal.append\n\nexport const prepend: {\n /**\n * Prepends control points to a `Cardinal2d`. Tension and alpha are preserved.\n *\n * @param points - The control points to prepend.\n * @returns A function that takes a `Cardinal2d` and returns a new instance.\n * @since 1.0.0\n */\n (...points: ReadonlyArray<Vector2>): (c: Cardinal2d) => Cardinal2d\n /**\n * Prepends control points to a `Cardinal2d`. Tension and alpha are preserved.\n *\n * @param c - The `Cardinal2d` to prepend to.\n * @param points - The control points to prepend.\n * @returns A new `Cardinal2d` instance.\n * @since 1.0.0\n */\n (c: Cardinal2d, ...points: ReadonlyArray<Vector2>): Cardinal2d\n} = internal.prepend\n\n/**\n * Doubles the endpoints of a `Cardinal2d` spline. Tension and alpha are\n * preserved.\n *\n * @param c - The `Cardinal2d` to duplicate the endpoints of.\n * @returns A new `Cardinal2d` instance with duplicated endpoints.\n * @since 1.0.0\n */\nexport const withDuplicatedEndpoints: (c: Cardinal2d) => Cardinal2d =\n internal.withDuplicatedEndpoints\n\n/**\n * Pads the spline so that it interpolates its first and last control points.\n * The resulting path passes through `points[0]` at `u = 0` and `points[points.length - 1]`\n * at `u = 1`. Equivalent to {@link withReflectedEndpoints} called with\n * `scale = 0` (and to {@link withDuplicatedEndpoints}), but reads more\n * directly as the user-facing intent.\n *\n * Tension and alpha are preserved.\n *\n * @param c - The `Cardinal2d` to pad.\n * @returns A new `Cardinal2d` instance whose first and last control points are interpolated.\n * @since 2.0.0\n */\nexport const withInterpolatedEndpoints: (c: Cardinal2d) => Cardinal2d =\n internal.withInterpolatedEndpoints\n\nexport const withReflectedEndpoints: {\n /**\n * Reflects the endpoints of a `Cardinal2d` spline. Tension and alpha are\n * preserved.\n *\n * @param scale - The scale factor for the reflection.\n * @returns A function that takes a `Cardinal2d` and returns a new instance.\n * @since 1.0.0\n */\n (scale: number): (c: Cardinal2d) => Cardinal2d\n /**\n * Reflects the endpoints of a `Cardinal2d` spline. Tension and alpha are\n * preserved.\n *\n * @param c - The `Cardinal2d` to reflect the endpoints of.\n * @param scale - The scale factor for the reflection.\n * @returns A new `Cardinal2d` instance with reflected endpoints.\n * @since 1.0.0\n */\n (c: Cardinal2d, scale?: number): Cardinal2d\n} = internal.withReflectedEndpoints\n\nexport const withTension: {\n /**\n * Returns a new `Cardinal2d` with the given tension; control points and\n * alpha are preserved.\n *\n * @param tension - The new tension value.\n * @returns A function that takes a `Cardinal2d` and returns a new instance.\n * @since 2.0.0\n */\n (tension: number): (c: Cardinal2d) => Cardinal2d\n /**\n * Returns a new `Cardinal2d` with the given tension; control points and\n * alpha are preserved.\n *\n * @param c - The `Cardinal2d` to update.\n * @param tension - The new tension value.\n * @returns A new `Cardinal2d` instance.\n * @since 2.0.0\n */\n (c: Cardinal2d, tension: number): Cardinal2d\n} = internal.withTension\n\nexport const withAlpha: {\n /**\n * Returns a new `Cardinal2d` with the given alpha; control points and\n * tension are preserved.\n *\n * @param alpha - The new alpha value.\n * @returns A function that takes a `Cardinal2d` and returns a new instance.\n * @since 2.0.0\n */\n (alpha: number): (c: Cardinal2d) => Cardinal2d\n /**\n * Returns a new `Cardinal2d` with the given alpha; control points and\n * tension are preserved.\n *\n * @param c - The `Cardinal2d` to update.\n * @param alpha - The new alpha value.\n * @returns A new `Cardinal2d` instance.\n * @since 2.0.0\n */\n (c: Cardinal2d, alpha: number): Cardinal2d\n} = internal.withAlpha\n\nexport const withOptions: {\n /**\n * Returns a new `Cardinal2d` with the given options merged into the\n * existing tension/alpha. Omitted fields are preserved from the input.\n *\n * @param options - The options to merge.\n * @returns A function that takes a `Cardinal2d` and returns a new instance.\n * @since 2.0.0\n */\n (options: Options): (c: Cardinal2d) => Cardinal2d\n /**\n * Returns a new `Cardinal2d` with the given options merged in.\n *\n * @param c - The `Cardinal2d` to update.\n * @param options - The options to merge.\n * @returns A new `Cardinal2d` instance.\n * @since 2.0.0\n */\n (c: Cardinal2d, options: Options): Cardinal2d\n} = internal.withOptions\n\n/**\n * Converts a `Cardinal2d` to a `CubicPath2d` using the spline's `tension` and\n * `alpha`. With the default options (`{ tension: 0.5, alpha: 0.5 }`) the\n * result is a centripetal Catmull-Rom path — the canonical recommended\n * Catmull-Rom variant, which avoids the cusps and self-intersections that\n * uniform Catmull-Rom can produce when control points cluster.\n *\n * @param c - The Cardinal spline.\n * @returns A new `CubicPath2d` representing the spline.\n * @since 1.0.0\n */\nexport const toPath: (c: Cardinal2d) => CubicPath2d = internal.toPath\n\n/**\n * Converts a `Cardinal2d` to a `Bezier2d`. Equivalent to {@link toPath}\n * followed by per-segment monomial-to-Bernstein conversion — same underlying\n * curve, expressed in cubic Bézier control-point form. Uses the spline's\n * `tension` and `alpha`.\n *\n * @param c - The Cardinal spline.\n * @returns A new `Bezier2d` representing the spline.\n * @since 1.0.0\n */\nexport const toBezier: (c: Cardinal2d) => Bezier2d = internal.toBezier\n","import * as Characteristic from '../characteristic/characteristic'\nimport * as CubicPath2d from '../path/cubic2d'\nimport { dual, Pipeable } from '../utils'\nimport { invariant } from '../utils'\nimport * as Vector2 from '../vector/vector2'\nimport type { Bezier2d } from './bezier2d'\nimport * as bezierInternal from './bezier2d.internal'\nimport type { Hermite2d } from './hermite2d'\nimport { toCurves } from './util'\n\nexport const Hermite2dTypeId = Symbol('curvy/splines/hermite2d')\nexport type Hermite2dTypeId = typeof Hermite2dTypeId\n\nclass Hermite2dImpl extends Pipeable implements Hermite2d {\n readonly [Hermite2dTypeId]: Hermite2dTypeId = Hermite2dTypeId\n\n readonly points: ReadonlyArray<Vector2.Vector2>\n\n constructor(points: ReadonlyArray<Vector2.Vector2>) {\n invariant(points.length >= 4, 'hermite splines requires 4 or more points')\n invariant(points.length % 2 === 0, 'hermite splines requires (n * 2) points')\n\n super()\n this.points = points\n }\n\n [Symbol.iterator]() {\n return this.points[Symbol.iterator]()\n }\n}\n\nexport const isHermite2d = (p: unknown): p is Hermite2d =>\n typeof p === 'object' && p !== null && Hermite2dTypeId in p\n\nexport const make = (\n p0: Vector2.Vector2,\n v0: Vector2.Vector2,\n p1: Vector2.Vector2,\n v1: Vector2.Vector2,\n) => new Hermite2dImpl([p0, v0, p1, v1])\n\nexport const fromArray = (points: ReadonlyArray<Vector2.Vector2>) => new Hermite2dImpl(points)\n\nexport const fromTuples = (tuples: ReadonlyArray<readonly [number, number]>) =>\n new Hermite2dImpl(tuples.map(([x, y]) => Vector2.make(x, y)))\n\nexport const append = dual<\n (p1: Vector2.Vector2, v1: Vector2.Vector2) => (p: Hermite2d) => Hermite2d,\n (p: Hermite2d, p1: Vector2.Vector2, v1: Vector2.Vector2) => Hermite2d\n>(3, (p: Hermite2d, p1: Vector2.Vector2, v1: Vector2.Vector2) => {\n const points = p instanceof Hermite2dImpl ? p.points : Array.from(p)\n return new Hermite2dImpl(points.concat(p1, v1))\n})\n\nexport const prepend = dual<\n (p0: Vector2.Vector2, v0: Vector2.Vector2) => (p: Hermite2d) => Hermite2d,\n (p: Hermite2d, p0: Vector2.Vector2, v0: Vector2.Vector2) => Hermite2d\n>(3, (p: Hermite2d, p0: Vector2.Vector2, v0: Vector2.Vector2) => {\n const points = p instanceof Hermite2dImpl ? p.points : Array.from(p)\n return new Hermite2dImpl([p0, v0].concat(points))\n})\n\nexport const toPath = (p: Hermite2d) =>\n CubicPath2d.make(...toCurves(p, Characteristic.cubicHermite, 2))\n\nexport const toBezier = (p: Hermite2d): Bezier2d =>\n bezierInternal.fromBasis(p, Characteristic.cubicHermite, 2)\n","import type { CubicPath2d } from '../path/cubic2d'\nimport type { Pipeable } from '../utils'\nimport type { Vector2 } from '../vector/vector2'\nimport type { Bezier2d } from './bezier2d'\nimport * as internal from './hermite2d.internal'\nimport type { Hermite2dTypeId } from './hermite2d.internal'\n\n/**\n * A Hermite spline in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The characteristic matrix that identifies this spline family lives in the\n * `characteristic` module as `Characteristic.cubicHermite`.\n *\n * @since 1.0.0\n */\nexport interface Hermite2d extends Pipeable {\n readonly [Hermite2dTypeId]: Hermite2dTypeId\n\n [Symbol.iterator](): IterableIterator<Vector2>\n}\n\n/**\n * Checks if a value is a `Hermite2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `Hermite2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isHermite2d: (p: unknown) => p is Hermite2d = internal.isHermite2d\n\n/**\n * Creates a new `Hermite2d` instance.\n *\n * @param p0 - The first control point.\n * @param v0 - The first tangent vector.\n * @param p1 - The second control point.\n * @param v1 - The second tangent vector.\n * @returns A new `Hermite2d` instance.\n * @since 1.0.0\n */\nexport const make: (p0: Vector2, v0: Vector2, p1: Vector2, v1: Vector2) => Hermite2d = internal.make\n\n/**\n * Creates a new `Hermite2d` instance from an array of control points.\n *\n * @param points - The control points.\n * @returns A new `Hermite2d` instance.\n * @since 1.0.0\n */\nexport const fromArray: (points: ReadonlyArray<Vector2>) => Hermite2d = internal.fromArray\n\n/**\n * Creates a new `Hermite2d` from an array of `[x, y]` tuples, alternating\n * `[position, velocity]` pairs.\n *\n * @param tuples - The point/velocity pairs as `[x, y]` tuples.\n * @returns A new `Hermite2d` instance.\n * @since 2.0.0\n */\nexport const fromTuples: (tuples: ReadonlyArray<readonly [number, number]>) => Hermite2d =\n internal.fromTuples\n\nexport const append: {\n /**\n * Appends a new control point and tangent vector to the Hermite spline.\n *\n * @param p1 - The new control point.\n * @param v1 - The new tangent vector.\n * @returns A new `Hermite2d` instance with the appended control point and tangent vector.\n * @since 1.0.0\n */\n (p1: Vector2, v1: Vector2): (p: Hermite2d) => Hermite2d\n /**\n * Appends a new control point and tangent vector to the Hermite spline.\n *\n * @param p - The `Hermite2d` to append the control point and tangent vector to.\n * @param p1 - The new control point.\n * @param v1 - The new tangent vector.\n * @returns A new `Hermite2d` instance with the appended control point and tangent vector.\n * @since 1.0.0\n */\n (p: Hermite2d, p1: Vector2, v1: Vector2): Hermite2d\n} = internal.append\n\nexport const prepend: {\n /**\n * Prepends a new control point and tangent vector to the Hermite spline.\n *\n * @param p0 - The new control point.\n * @param v0 - The new tangent vector.\n * @returns A new `Hermite2d` instance with the prepended control point and tangent vector.\n * @since 1.0.0\n */\n (p0: Vector2, v0: Vector2): (p: Hermite2d) => Hermite2d\n /**\n * Prepends a new control point and tangent vector to the Hermite spline.\n *\n * @param p - The `Hermite2d` to prepend the control point and tangent vector to.\n * @param p0 - The new control point.\n * @param v0 - The new tangent vector.\n * @returns A new `Hermite2d` instance with the prepended control point and tangent vector.\n * @since 1.0.0\n */\n (p: Hermite2d, p0: Vector2, v0: Vector2): Hermite2d\n} = internal.prepend\n\n/**\n * Creates a new `CubicPath2d` instance from a `Hermite2d`.\n *\n * @param p - The `Hermite2d` to convert.\n * @returns A new `CubicPath2d` instance.\n * @since 1.0.0\n */\nexport const toPath: (p: Hermite2d) => CubicPath2d = internal.toPath\n\n/**\n * Converts a `Hermite2d` to a `Bezier2d`.\n *\n * @param p - The `Hermite2d` to convert.\n * @returns A new `Bezier2d` instance.\n * @since 1.0.0\n */\nexport const toBezier: (p: Hermite2d) => Bezier2d = internal.toBezier\n","import * as Characteristic from '../characteristic/characteristic'\nimport * as CubicPath2d from '../path/cubic2d'\nimport { dual, Pipeable } from '../utils'\nimport { invariant } from '../utils'\nimport * as Vector2 from '../vector/vector2'\nimport type { Basis2d } from './basis2d'\nimport type { Bezier2d } from './bezier2d'\nimport * as bezierInternal from './bezier2d.internal'\nimport { toCurves } from './util'\n\nexport const Basis2dTypeId = Symbol('curvy/splines/basis2d')\nexport type Basis2dTypeId = typeof Basis2dTypeId\n\nclass Basis2dImpl extends Pipeable implements Basis2d {\n readonly [Basis2dTypeId]: Basis2dTypeId = Basis2dTypeId\n\n readonly points: ReadonlyArray<Vector2.Vector2>\n\n constructor(points: ReadonlyArray<Vector2.Vector2>) {\n invariant(points.length >= 4, 'basis splines requires 4 or more points')\n super()\n this.points = points\n }\n\n [Symbol.iterator]() {\n return this.points[Symbol.iterator]()\n }\n}\n\nexport const isBasis2d = (p: unknown): p is Basis2d =>\n typeof p === 'object' && p !== null && Basis2dTypeId in p\n\nexport const make = (\n p0: Vector2.Vector2,\n p1: Vector2.Vector2,\n p2: Vector2.Vector2,\n p3: Vector2.Vector2,\n) => new Basis2dImpl([p0, p1, p2, p3])\n\nexport const fromArray = (points: ReadonlyArray<Vector2.Vector2>) => new Basis2dImpl(points)\n\nexport const fromTuples = (tuples: ReadonlyArray<readonly [number, number]>) =>\n new Basis2dImpl(tuples.map(([x, y]) => Vector2.make(x, y)))\n\nexport const append = dual<\n (...points: ReadonlyArray<Vector2.Vector2>) => (p: Basis2d) => Basis2d,\n (p: Basis2d, ...points: ReadonlyArray<Vector2.Vector2>) => Basis2d\n>(\n (args) => isBasis2d(args[0]),\n (p: Basis2d, ...points: ReadonlyArray<Vector2.Vector2>) => new Basis2dImpl([...p, ...points]),\n)\n\nexport const prepend = dual<\n (...points: ReadonlyArray<Vector2.Vector2>) => (p: Basis2d) => Basis2d,\n (p: Basis2d, ...points: ReadonlyArray<Vector2.Vector2>) => Basis2d\n>(\n (args) => isBasis2d(args[0]),\n (p: Basis2d, ...points: ReadonlyArray<Vector2.Vector2>) => new Basis2dImpl([...points, ...p]),\n)\n\nexport const withTriplicatedEndpoints = (p: Basis2d) => {\n const points = p instanceof Basis2dImpl ? p.points : [...p]\n return new Basis2dImpl([\n points[0] as Vector2.Vector2,\n points[0] as Vector2.Vector2,\n ...points,\n points[points.length - 1] as Vector2.Vector2,\n points[points.length - 1] as Vector2.Vector2,\n ])\n}\n\nexport const toPath = (p: Basis2d) =>\n CubicPath2d.make(...toCurves(p, Characteristic.cubicBasisSpline, 1))\n\nexport const toBezier = (p: Basis2d): Bezier2d =>\n bezierInternal.fromBasis(p, Characteristic.cubicBasisSpline, 1)\n","import type { CubicPath2d } from '../path/cubic2d'\nimport type { Pipeable } from '../utils'\nimport type { Vector2 } from '../vector/vector2'\nimport type { Basis2dTypeId } from './basis2d.internal'\nimport * as internal from './basis2d.internal'\nimport type { Bezier2d } from './bezier2d'\n\n/**\n * A Basis Spline (uniform cubic B-spline) in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The characteristic matrix that identifies this spline family lives in the\n * `characteristic` module as `Characteristic.cubicBasisSpline`.\n *\n * @since 1.0.0\n */\nexport interface Basis2d extends Pipeable {\n readonly [Basis2dTypeId]: Basis2dTypeId\n [Symbol.iterator](): Iterator<Vector2>\n}\n\n/**\n * Checks if a value is a `Basis2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `Basis2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isBasis2d: (p: unknown) => p is Basis2d = internal.isBasis2d\n\n/**\n * Creates a new `Basis2d` instance.\n *\n * @param p0 - The first control point.\n * @param p1 - The second control point.\n * @param p2 - The third control point.\n * @param p3 - The fourth control point.\n * @returns A new `Basis2d` instance.\n * @since 1.0.0\n */\nexport const make: (p0: Vector2, p1: Vector2, p2: Vector2, p3: Vector2) => Basis2d = internal.make\n\n/**\n * Creates a new `Basis2d` instance from an array of control points.\n *\n * @param points - The control points.\n * @returns A new `Basis2d` instance.\n * @since 1.0.0\n */\nexport const fromArray: (points: ReadonlyArray<Vector2>) => Basis2d = internal.fromArray\n\n/**\n * Creates a new `Basis2d` from an array of `[x, y]` tuples.\n *\n * @param tuples - The control points as `[x, y]` tuples.\n * @returns A new `Basis2d` instance.\n * @since 2.0.0\n */\nexport const fromTuples: (tuples: ReadonlyArray<readonly [number, number]>) => Basis2d =\n internal.fromTuples\n\nexport const append: {\n /**\n * Appends control points to a `Basis2d`.\n *\n * @param points - The control points to append.\n * @returns A function that takes a `Basis2d` and returns a new `Basis2d` instance with the appended control points.\n * @since 1.0.0\n */\n (...points: ReadonlyArray<Vector2>): (p: Basis2d) => Basis2d\n /**\n * Appends control points to a `Basis2d`.\n *\n * @param p - The `Basis2d` to append the control points to.\n * @param points - The control points to append.\n * @returns A new `Basis2d` instance with the appended control points.\n * @since 1.0.0\n */\n (p: Basis2d, ...points: ReadonlyArray<Vector2>): Basis2d\n} = internal.append\n\nexport const prepend: {\n /**\n * Prepends control points to a `Basis2d`.\n *\n * @param points - The control points to prepend.\n * @returns A function that takes a `Basis2d` and returns a new `Basis2d` instance with the prepended control points.\n * @since 1.0.0\n */\n (...points: ReadonlyArray<Vector2>): (p: Basis2d) => Basis2d\n /**\n * Prepends control points to a `Basis2d`.\n *\n * @param p - The `Basis2d` to prepend the control points to.\n * @param points - The control points to prepend.\n * @returns A new `Basis2d` instance with the prepended control points.\n * @since 1.0.0\n */\n (p: Basis2d, ...points: ReadonlyArray<Vector2>): Basis2d\n} = internal.prepend\n\n/**\n * Triplicates the endpoints of a `Basis2d`.\n *\n * This is useful for creating a closed loop spline.\n *\n * @param p - The `Basis2d` to triplicate the endpoints of.\n * @returns A new `Basis2d` instance with the triplicated endpoints.\n * @since 1.0.0\n */\nexport const withTriplicatedEndpoints: (p: Basis2d) => Basis2d = internal.withTriplicatedEndpoints\n\n/**\n * Creates a new `Path2d` from a `Basis2d`.\n *\n * @param p - The `Basis2d` to convert to a `Path2d`.\n * @returns A new `Path2d` instance.\n * @since 1.0.0\n */\nexport const toPath: (p: Basis2d) => CubicPath2d = internal.toPath\n\n/**\n * Converts a `Basis2d` to a `Bezier2d`.\n *\n * @param p - The `Basis2d` to convert.\n * @returns A new `Bezier2d` instance.\n * @since 1.0.0\n */\nexport const toBezier: (p: Basis2d) => Bezier2d = internal.toBezier\n","import type { RationalCubicPath2d } from '../path/rationalCubic2d'\nimport type { Pipeable } from '../utils'\nimport type { Vector2, Weighted } from '../vector/vector2'\nimport type { Bezier2d } from './bezier2d'\nimport type { RationalBezier2dTypeId } from './rationalBezier2d.internal'\nimport * as internal from './rationalBezier2d.internal'\n\n/**\n * A piecewise rational cubic Bézier curve in 2D space.\n *\n * Each control point is a `Vector2.Weighted` carrying a positive scalar\n * weight; the curve evaluates to `Σ w_i · N_i(t) · P_i / Σ w_i · N_i(t)`,\n * where `N_i` are the cubic Bernstein basis functions. With all weights\n * equal, the curve coincides with a non-rational `Bezier2d`. With unequal\n * weights, the curve can exactly represent conic sections — circles,\n * ellipses, parabolas, and hyperbolas — that polynomial Béziers can only\n * approximate.\n *\n * Internally each control point is stored in homogeneous form `(w·x, w·y, w)`,\n * so de Casteljau evaluation is three independent linear interpolations\n * followed by a single division. Iteration projects back to `Vector2.Weighted`\n * — the same shape accepted by {@link make}.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * @since 2.0.0\n */\nexport interface RationalBezier2d extends Pipeable {\n readonly [RationalBezier2dTypeId]: RationalBezier2dTypeId\n [Symbol.iterator](): IterableIterator<Weighted>\n}\n\n/**\n * Checks if a value is a `RationalBezier2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `RationalBezier2d`, `false` otherwise.\n * @since 2.0.0\n */\nexport const isRationalBezier2d: (p: unknown) => p is RationalBezier2d = internal.isRationalBezier2d\n\n/**\n * Creates a new single-segment `RationalBezier2d` from four weighted control points.\n *\n * Equal weights produce a curve coincident with the corresponding polynomial\n * cubic Bézier; unequal weights produce a true rational curve capable of\n * representing conics exactly.\n *\n * @param p0 - The first weighted control point (curve start).\n * @param p1 - The second weighted control point (start handle).\n * @param p2 - The third weighted control point (end handle).\n * @param p3 - The fourth weighted control point (curve end).\n * @returns A new `RationalBezier2d` instance.\n * @since 2.0.0\n */\nexport const make: (p0: Weighted, p1: Weighted, p2: Weighted, p3: Weighted) => RationalBezier2d =\n internal.make\n\n/**\n * Creates a new `RationalBezier2d` from an array of weighted control points.\n *\n * The array must contain `(n * 3) + 1` entries to describe `n` joined cubic\n * segments.\n *\n * @param points - The weighted control points.\n * @returns A new `RationalBezier2d` instance.\n * @since 2.0.0\n */\nexport const fromArray: (points: ReadonlyArray<Weighted>) => RationalBezier2d = internal.fromArray\n\n/**\n * Creates a new `RationalBezier2d` from an array of `[x, y, weight]` tuples.\n * Weight is the projective denominator at each control point — `1` everywhere\n * yields the polynomial Bézier; varying weights bend the curve toward the\n * heavier control points.\n *\n * @param tuples - The weighted control points as `[x, y, weight]` tuples.\n * @returns A new `RationalBezier2d` instance.\n * @since 2.0.0\n */\nexport const fromTuples: (\n tuples: ReadonlyArray<readonly [number, number, number]>,\n) => RationalBezier2d = internal.fromTuples\n\n/**\n * Creates a new single-segment `RationalBezier2d` from four points with all\n * weights equal to one.\n *\n * Convenience constructor for callers who want the rational evaluator but\n * don't yet have non-unit weights — the resulting curve is mathematically\n * equivalent to the corresponding `Bezier2d.make(p0, p1, p2, p3)` and can\n * later be subdivided or recombined using the rational machinery without\n * conversion overhead.\n *\n * @param p0 - The first control point (curve start).\n * @param p1 - The second control point (start handle).\n * @param p2 - The third control point (end handle).\n * @param p3 - The fourth control point (curve end).\n * @returns A new `RationalBezier2d` with unit weights.\n * @since 2.0.0\n */\nexport const fromPoints: (p0: Vector2, p1: Vector2, p2: Vector2, p3: Vector2) => RationalBezier2d =\n internal.fromPoints\n\n/**\n * Lifts a non-rational `Bezier2d` into a `RationalBezier2d` by assigning\n * unit weight to every control point. The two curves trace the same path.\n *\n * @param b - The non-rational bezier to lift.\n * @returns A new `RationalBezier2d` with unit weights.\n * @since 2.0.0\n */\nexport const fromBezier: (b: Bezier2d) => RationalBezier2d = internal.fromBezier\n\n/**\n * Converts a `RationalBezier2d` to a `RationalCubicPath2d`.\n *\n * Each segment's four homogeneous control points are expanded into three\n * per-segment monomial cubic polynomials — `x`, `y`, and the shared\n * denominator `w` — yielding a path whose evaluator is three Horner passes\n * plus two divisions per call.\n *\n * Mirrors `Bezier2d.toPath`: spline construction is converted to path\n * evaluation form, and forward evaluation thereafter routes through the\n * path's `solve`.\n *\n * @param r - The rational bezier to convert.\n * @returns A new `RationalCubicPath2d` instance representing the same curve.\n * @since 2.0.0\n */\nexport const toPath: (r: RationalBezier2d) => RationalCubicPath2d = internal.toPath\n\nexport const subdivide: {\n /**\n * Splits a `RationalBezier2d` at the given global parameter `u ∈ (0, 1)`\n * using de Casteljau's algorithm in homogeneous coordinates. The two\n * returned beziers together trace the same curve as the input — the left\n * covers `[0, u]`, the right covers `[u, 1]`.\n *\n * The subdivided halves' control-point weights generally differ from the\n * original's even at unit input weights; this is expected and preserves\n * the curve shape exactly.\n *\n * @param r - The rational bezier to split.\n * @param u - The split parameter in the open interval `(0, 1)`.\n * @returns A two-element tuple of the left and right halves.\n * @since 2.0.0\n */\n (r: RationalBezier2d, u: number): [RationalBezier2d, RationalBezier2d]\n /**\n * Splits a `RationalBezier2d` at the given global parameter `u ∈ (0, 1)`.\n *\n * @param u - The split parameter in the open interval `(0, 1)`.\n * @returns A function that takes a rational bezier and returns the halves.\n * @since 2.0.0\n */\n (u: number): (r: RationalBezier2d) => [RationalBezier2d, RationalBezier2d]\n} = internal.subdivide\n"],"mappings":"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"}
@@ -1,3 +1,10 @@
1
- import { r as vector2_d_exports } from "../shared/vector2-DPUY3_eA.mjs";
2
- import { i as vector4_d_exports, n as vector3_d_exports } from "../shared/vector3-DqeOZtOB.mjs";
3
- export { vector2_d_exports as Vector2, vector3_d_exports as Vector3, vector4_d_exports as Vector4 };
1
+ import { t as Vector2$1 } from "../shared/vector2-euuV_bNQ.mjs";
2
+ import { n as Vector4$1, t as Vector3$1 } from "../shared/vector3-3Xx7GVk7.mjs";
3
+
4
+ //#region src/vector/index.d.ts
5
+ type Vector2 = Vector2$1;
6
+ type Vector3 = Vector3$1;
7
+ type Vector4 = Vector4$1;
8
+ //#endregion
9
+ export { Vector2, Vector3, Vector4 };
10
+ //# sourceMappingURL=index.d.mts.map
@@ -1,4 +1,4 @@
1
- import { c as vector2_exports } from "../shared/vector2-CL1HDdPr.mjs";
2
- import { n as vector3_exports } from "../shared/vector3-D-tv_aKL.mjs";
3
- import { r as vector4_exports } from "../shared/vector4-5KbjoHVj.mjs";
1
+ import { l as vector2_exports } from "../shared/vector2-CCuJx1rX.mjs";
2
+ import { n as vector3_exports } from "../shared/vector3-C-qgKAjR.mjs";
3
+ import { r as vector4_exports } from "../shared/vector4-BhOKDhD5.mjs";
4
4
  export { vector2_exports as Vector2, vector3_exports as Vector3, vector4_exports as Vector4 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "curvy",
3
- "version": "2.0.0-alpha.2",
3
+ "version": "2.0.0-alpha.4",
4
4
  "description": "Spline and Curve utilities",
5
5
  "homepage": "https://github.com/tkofh/curvy#readme",
6
6
  "bugs": {