curvy 2.0.0-alpha.11 → 2.0.0-alpha.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/characteristic/index.mjs +1 -1
  2. package/dist/curve/index.mjs +1 -1
  3. package/dist/curve/rationalCubic2d.d.ts +195 -11
  4. package/dist/interval/index.mjs +1 -1
  5. package/dist/monotonicity/index.d.ts +4 -0
  6. package/dist/monotonicity/index.mjs +2 -0
  7. package/dist/monotonicity/monotonicity.d.ts +80 -0
  8. package/dist/path/index.mjs +16 -387
  9. package/dist/path/index.mjs.map +1 -1
  10. package/dist/path/rationalCubic2d.d.ts +27 -0
  11. package/dist/polynomial/cubic.d.ts +2 -2
  12. package/dist/polynomial/index.mjs +2 -2
  13. package/dist/polynomial/linear.d.ts +7 -7
  14. package/dist/polynomial/quadratic.d.ts +2 -2
  15. package/dist/shared/{characteristic-Hb7F8SBw.mjs → characteristic-BkEr-rr8.mjs} +2 -2
  16. package/dist/shared/{characteristic-Hb7F8SBw.mjs.map → characteristic-BkEr-rr8.mjs.map} +1 -1
  17. package/dist/shared/{cubic-DHJrzZJN.mjs → cubic-BL6dpuHh.mjs} +18 -30
  18. package/dist/shared/cubic-BL6dpuHh.mjs.map +1 -0
  19. package/dist/shared/{interval2d-DPmvk_Qe.mjs → interval2d-AtneyI45.mjs} +1 -1
  20. package/dist/shared/{interval2d-DPmvk_Qe.mjs.map → interval2d-AtneyI45.mjs.map} +1 -1
  21. package/dist/shared/monotonicity-BdebFOtv.mjs +34 -0
  22. package/dist/shared/monotonicity-BdebFOtv.mjs.map +1 -0
  23. package/dist/shared/{quadratic-BZmfZE71.mjs → quadratic-DPrUsFCp.mjs} +9 -9
  24. package/dist/shared/quadratic-DPrUsFCp.mjs.map +1 -0
  25. package/dist/shared/{rationalCubic2d-IroMR6AA.mjs → rationalCubic2d-CeHgpNht.mjs} +373 -79
  26. package/dist/shared/rationalCubic2d-CeHgpNht.mjs.map +1 -0
  27. package/dist/shared/{rationalCubic2d-nN-oSrLr.mjs → rationalCubic2d-H1J2Fjyy.mjs} +404 -23
  28. package/dist/shared/rationalCubic2d-H1J2Fjyy.mjs.map +1 -0
  29. package/dist/shared/{solution-B6KY1E7M.mjs → solution-B2JdOZpe.mjs} +1 -1
  30. package/dist/shared/{solution-B6KY1E7M.mjs.map → solution-B2JdOZpe.mjs.map} +1 -1
  31. package/dist/solution/index.mjs +1 -1
  32. package/dist/splines/index.d.ts +3 -0
  33. package/dist/splines/index.mjs +218 -120
  34. package/dist/splines/index.mjs.map +1 -1
  35. package/dist/splines/linear2d.d.ts +102 -0
  36. package/dist/splines/linear2d.internal.d.ts +2 -0
  37. package/package.json +5 -1
  38. package/dist/polynomial/monotonicity.d.ts +0 -3
  39. package/dist/shared/cubic-DHJrzZJN.mjs.map +0 -1
  40. package/dist/shared/quadratic-BZmfZE71.mjs.map +0 -1
  41. package/dist/shared/rationalCubic2d-IroMR6AA.mjs.map +0 -1
  42. package/dist/shared/rationalCubic2d-nN-oSrLr.mjs.map +0 -1
@@ -2,382 +2,11 @@ import { t as __exportAll } from "../shared/chunk-25Hzd3z8.mjs";
2
2
  import { Pipeable, dual, invariant } from "../utils.mjs";
3
3
  import { epsEquals } from "../number.mjs";
4
4
  import { p as unit } from "../shared/interval-Dm35Xhy4.mjs";
5
- import { o as none, r as isNone, s as one } from "../shared/solution-B6KY1E7M.mjs";
6
- import { d as isIncreasing, n as isDecreasing$1, r as isIncreasing$1, u as isDecreasing } from "../shared/quadratic-BZmfZE71.mjs";
7
- import { a as union } from "../shared/interval2d-DPmvk_Qe.mjs";
8
- import { C as solve$4, T as solveAtY$4, _ as solve$5, b as boundingBox$4, h as length$5, m as boundingBox$5, v as solveAtX$5, w as solveAtX$4, x as length$4, y as solveAtY$5 } from "../shared/rationalCubic2d-IroMR6AA.mjs";
9
- import { n as rationalCubic2d_exports, r as cubic2d_exports } from "../shared/rationalCubic2d-nN-oSrLr.mjs";
10
- //#region src/path/linear2d.internal.ts
11
- const LinearPath2dTypeId = Symbol("curvy/path/linear2d");
12
- /** @internal */
13
- var LinearPath2dImpl = class extends Pipeable {
14
- [LinearPath2dTypeId] = LinearPath2dTypeId;
15
- curves;
16
- constructor(curves) {
17
- super();
18
- this.curves = curves;
19
- }
20
- [Symbol.iterator]() {
21
- return this.curves[Symbol.iterator]();
22
- }
23
- };
24
- /** @internal */
25
- const isLinearPath2d$1 = (p) => typeof p === "object" && p !== null && LinearPath2dTypeId in p;
26
- /** @internal */
27
- const make$3 = (...curves) => new LinearPath2dImpl(curves);
28
- /** @internal */
29
- const fromArray$3 = (curves) => new LinearPath2dImpl(curves);
30
- /** @internal */
31
- const append$3 = dual(2, (p, c) => fromArray$3([...p, c]));
32
- /** @internal */
33
- const length$3 = (p) => {
34
- let total = 0;
35
- for (const curve of p) total += length$4(curve, unit);
36
- return total;
37
- };
38
- /** @internal */
39
- const solve$3 = dual(2, (p, u) => {
40
- const curves = p instanceof LinearPath2dImpl ? p.curves : [...p];
41
- if (u === 1) return solve$4(curves.at(-1), 1);
42
- const t = u * curves.length;
43
- const i = Math.floor(t);
44
- const curve = curves[i];
45
- return solve$4(curve, t - i);
46
- });
47
- /** @internal */
48
- const toPathData$3 = (p) => {
49
- let result = "";
50
- let prevEndX = NaN;
51
- let prevEndY = NaN;
52
- for (const curve of p) {
53
- const startX = curve.x.c0;
54
- const startY = curve.y.c0;
55
- const endX = curve.x.c0 + curve.x.c1;
56
- const endY = curve.y.c0 + curve.y.c1;
57
- if (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY)) result += ` M ${startX},${startY}`;
58
- result += ` L ${endX},${endY}`;
59
- prevEndX = endX;
60
- prevEndY = endY;
61
- }
62
- return result.slice(1);
63
- };
64
- /** @internal */
65
- const isContinuous$3 = (p) => {
66
- let prevEndX = NaN;
67
- let prevEndY = NaN;
68
- let first = true;
69
- for (const curve of p) {
70
- const startX = curve.x.c0;
71
- const startY = curve.y.c0;
72
- if (!first && (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY))) return false;
73
- prevEndX = curve.x.c0 + curve.x.c1;
74
- prevEndY = curve.y.c0 + curve.y.c1;
75
- first = false;
76
- }
77
- return true;
78
- };
79
- /** @internal */
80
- const asContinuous$3 = (p) => {
81
- invariant(isContinuous$3(p), "linear path is not continuous");
82
- return p;
83
- };
84
- /** @internal */
85
- const isIncreasingX$3 = (p) => {
86
- let prevEnd = Number.NEGATIVE_INFINITY;
87
- for (const c of p) {
88
- if (!isIncreasing(c.x)) return false;
89
- if (c.x.c0 < prevEnd - 1e-10) return false;
90
- prevEnd = c.x.c0 + c.x.c1;
91
- }
92
- return true;
93
- };
94
- /** @internal */
95
- const isDecreasingX$3 = (p) => {
96
- let prevEnd = Number.POSITIVE_INFINITY;
97
- for (const c of p) {
98
- if (!isDecreasing(c.x)) return false;
99
- if (c.x.c0 > prevEnd + 1e-10) return false;
100
- prevEnd = c.x.c0 + c.x.c1;
101
- }
102
- return true;
103
- };
104
- /** @internal */
105
- const isMonotonicX$3 = (p) => isIncreasingX$3(p) || isDecreasingX$3(p);
106
- /** @internal */
107
- const isIncreasingY$3 = (p) => {
108
- let prevEnd = Number.NEGATIVE_INFINITY;
109
- for (const c of p) {
110
- if (!isIncreasing(c.y)) return false;
111
- if (c.y.c0 < prevEnd - 1e-10) return false;
112
- prevEnd = c.y.c0 + c.y.c1;
113
- }
114
- return true;
115
- };
116
- /** @internal */
117
- const isDecreasingY$3 = (p) => {
118
- let prevEnd = Number.POSITIVE_INFINITY;
119
- for (const c of p) {
120
- if (!isDecreasing(c.y)) return false;
121
- if (c.y.c0 > prevEnd + 1e-10) return false;
122
- prevEnd = c.y.c0 + c.y.c1;
123
- }
124
- return true;
125
- };
126
- /** @internal */
127
- const isMonotonicY$3 = (p) => isIncreasingY$3(p) || isDecreasingY$3(p);
128
- /** @internal */
129
- const asIncreasingX$3 = (p) => {
130
- invariant(isIncreasingX$3(p), "linear path is not increasing in x");
131
- return p;
132
- };
133
- /** @internal */
134
- const asDecreasingX$3 = (p) => {
135
- invariant(isDecreasingX$3(p), "linear path is not decreasing in x");
136
- return p;
137
- };
138
- /** @internal */
139
- const asMonotonicX$3 = (p) => {
140
- invariant(isMonotonicX$3(p), "linear path is not monotonic in x");
141
- return p;
142
- };
143
- /** @internal */
144
- const asIncreasingY$3 = (p) => {
145
- invariant(isIncreasingY$3(p), "linear path is not increasing in y");
146
- return p;
147
- };
148
- /** @internal */
149
- const asDecreasingY$3 = (p) => {
150
- invariant(isDecreasingY$3(p), "linear path is not decreasing in y");
151
- return p;
152
- };
153
- /** @internal */
154
- const asMonotonicY$3 = (p) => {
155
- invariant(isMonotonicY$3(p), "linear path is not monotonic in y");
156
- return p;
157
- };
158
- /** @internal */
159
- const solveAtX$3 = dual(2, (p, x) => {
160
- for (const c of p) {
161
- const sx = c.x.c0;
162
- const ex = c.x.c0 + c.x.c1;
163
- const lo = Math.min(sx, ex);
164
- const hi = Math.max(sx, ex);
165
- if (x >= lo - 1e-10 && x <= hi + 1e-10) {
166
- if (epsEquals(x, sx)) return one(c.y.c0);
167
- if (epsEquals(x, ex)) return one(c.y.c0 + c.y.c1);
168
- const sol = solveAtX$4(c, x);
169
- if (!isNone(sol)) return sol;
170
- }
171
- }
172
- return none;
173
- });
174
- /** @internal */
175
- const solveAtY$3 = dual(2, (p, y) => {
176
- for (const c of p) {
177
- const sy = c.y.c0;
178
- const ey = c.y.c0 + c.y.c1;
179
- const lo = Math.min(sy, ey);
180
- const hi = Math.max(sy, ey);
181
- if (y >= lo - 1e-10 && y <= hi + 1e-10) {
182
- if (epsEquals(y, sy)) return one(c.x.c0);
183
- if (epsEquals(y, ey)) return one(c.x.c0 + c.x.c1);
184
- const sol = solveAtY$4(c, y);
185
- if (!isNone(sol)) return sol;
186
- }
187
- }
188
- return none;
189
- });
190
- /** @internal */
191
- const boundingBox$3 = (p) => {
192
- const iter = p[Symbol.iterator]();
193
- let acc = boundingBox$4(iter.next().value);
194
- for (let next = iter.next(); !next.done; next = iter.next()) acc = union(acc, boundingBox$4(next.value));
195
- return acc;
196
- };
197
- //#endregion
198
- //#region src/path/linear2d.ts
199
- var linear2d_exports = /* @__PURE__ */ __exportAll({
200
- append: () => append$2,
201
- asContinuous: () => asContinuous$2,
202
- asDecreasingX: () => asDecreasingX$2,
203
- asDecreasingY: () => asDecreasingY$2,
204
- asIncreasingX: () => asIncreasingX$2,
205
- asIncreasingY: () => asIncreasingY$2,
206
- asMonotonicX: () => asMonotonicX$2,
207
- asMonotonicY: () => asMonotonicY$2,
208
- boundingBox: () => boundingBox$2,
209
- fromArray: () => fromArray$2,
210
- isContinuous: () => isContinuous$2,
211
- isDecreasingX: () => isDecreasingX$2,
212
- isDecreasingY: () => isDecreasingY$2,
213
- isIncreasingX: () => isIncreasingX$2,
214
- isIncreasingY: () => isIncreasingY$2,
215
- isLinearPath2d: () => isLinearPath2d,
216
- isMonotonicX: () => isMonotonicX$2,
217
- isMonotonicY: () => isMonotonicY$2,
218
- length: () => length$2,
219
- make: () => make$2,
220
- solve: () => solve$2,
221
- solveAtX: () => solveAtX$2,
222
- solveAtY: () => solveAtY$2,
223
- toPathData: () => toPathData$2
224
- });
225
- /**
226
- * Creates a new `LinearPath2d` instance from a sequence of curves.
227
- *
228
- * @param curves - The curves to create the path from.
229
- * @returns A new `LinearPath2d` instance.
230
- * @since 2.0.0
231
- */
232
- const make$2 = make$3;
233
- /**
234
- * Creates a new `LinearPath2d` instance from an array of curves.
235
- *
236
- * @param curves - The curves to create the path from.
237
- * @returns A new `LinearPath2d` instance.
238
- * @since 2.0.0
239
- */
240
- const fromArray$2 = fromArray$3;
241
- /**
242
- * Checks if a value is a `LinearPath2d`.
243
- *
244
- * @param p - The value to check.
245
- * @returns `true` if the value is a `LinearPath2d`, `false` otherwise.
246
- * @since 1.0.0
247
- */
248
- const isLinearPath2d = isLinearPath2d$1;
249
- const append$2 = append$3;
250
- /**
251
- * Calculates the length of a linear path.
252
- *
253
- * @param p - The linear path to calculate the length of.
254
- * @returns The length of the linear path.
255
- * @since 1.0.0
256
- */
257
- const length$2 = length$3;
258
- const solve$2 = solve$3;
259
- /**
260
- * Serializes a linear path as an SVG path data string (the value of a `<path>`
261
- * element's `d` attribute), using `M` and `L` commands. Discontinuities between
262
- * curves emit a fresh `M` command.
263
- *
264
- * @param p - The linear path to serialize.
265
- * @returns The SVG path data string.
266
- * @since 2.0.0
267
- */
268
- const toPathData$2 = toPathData$3;
269
- /**
270
- * Type-narrowing predicate: refines `LinearPath2d<T>` to
271
- * `LinearPath2d<T & Continuous>` when adjacent curves connect at their join
272
- * points.
273
- *
274
- * @param p - The linear path to check.
275
- * @returns `true` when the path is continuous (G⁰).
276
- * @since 2.0.0
277
- */
278
- const isContinuous$2 = isContinuous$3;
279
- /**
280
- * Asserts that the linear path is continuous, throwing on failure.
281
- *
282
- * @param p - The linear path to assert against.
283
- * @returns The same path, typed with the `Continuous` brand.
284
- * @throws When the path has a discontinuity between adjacent curves.
285
- * @since 2.0.0
286
- */
287
- const asContinuous$2 = asContinuous$3;
288
- /**
289
- * Type-narrowing predicate: refines `LinearPath2d<T>` to
290
- * `LinearPath2d<T & IncreasingX>` when every segment's x-polynomial is
291
- * strictly increasing and adjacent segments' x-ranges don't overlap.
292
- *
293
- * @since 2.0.0
294
- */
295
- const isIncreasingX$2 = isIncreasingX$3;
296
- /**
297
- * Type-narrowing predicate: refines `LinearPath2d<T>` to
298
- * `LinearPath2d<T & DecreasingX>` when every segment's x-polynomial is
299
- * strictly decreasing and adjacent segments' x-ranges don't overlap.
300
- *
301
- * @since 2.0.0
302
- */
303
- const isDecreasingX$2 = isDecreasingX$3;
304
- /**
305
- * Type-narrowing predicate: refines `LinearPath2d<T>` to
306
- * `LinearPath2d<T & MonotonicX>` when the path is either increasing or
307
- * decreasing in x along its full parameter domain.
308
- *
309
- * @since 2.0.0
310
- */
311
- const isMonotonicX$2 = isMonotonicX$3;
312
- /**
313
- * Type-narrowing predicate: refines `LinearPath2d<T>` to
314
- * `LinearPath2d<T & IncreasingY>`. The y-axis analog of {@link isIncreasingX}.
315
- *
316
- * @since 2.0.0
317
- */
318
- const isIncreasingY$2 = isIncreasingY$3;
319
- /**
320
- * Type-narrowing predicate: refines `LinearPath2d<T>` to
321
- * `LinearPath2d<T & DecreasingY>`. The y-axis analog of {@link isDecreasingX}.
322
- *
323
- * @since 2.0.0
324
- */
325
- const isDecreasingY$2 = isDecreasingY$3;
326
- /**
327
- * Type-narrowing predicate: refines `LinearPath2d<T>` to
328
- * `LinearPath2d<T & MonotonicY>`. The y-axis analog of {@link isMonotonicX}.
329
- *
330
- * @since 2.0.0
331
- */
332
- const isMonotonicY$2 = isMonotonicY$3;
333
- /**
334
- * Asserts that the path is strictly increasing in x, throwing on failure.
335
- *
336
- * @since 2.0.0
337
- */
338
- const asIncreasingX$2 = asIncreasingX$3;
339
- /**
340
- * Asserts that the path is strictly decreasing in x, throwing on failure.
341
- *
342
- * @since 2.0.0
343
- */
344
- const asDecreasingX$2 = asDecreasingX$3;
345
- /**
346
- * Asserts that the path is monotonic in x, throwing on failure.
347
- *
348
- * @since 2.0.0
349
- */
350
- const asMonotonicX$2 = asMonotonicX$3;
351
- /**
352
- * Asserts that the path is strictly increasing in y, throwing on failure.
353
- *
354
- * @since 2.0.0
355
- */
356
- const asIncreasingY$2 = asIncreasingY$3;
357
- /**
358
- * Asserts that the path is strictly decreasing in y, throwing on failure.
359
- *
360
- * @since 2.0.0
361
- */
362
- const asDecreasingY$2 = asDecreasingY$3;
363
- /**
364
- * Asserts that the path is monotonic in y, throwing on failure.
365
- *
366
- * @since 2.0.0
367
- */
368
- const asMonotonicY$2 = asMonotonicY$3;
369
- const solveAtX$2 = solveAtX$3;
370
- const solveAtY$2 = solveAtY$3;
371
- /**
372
- * Computes the axis-aligned bounding box of the path — the smallest closed
373
- * `Box2d` enclosing every segment.
374
- *
375
- * @param p - The linear path.
376
- * @returns A closed `Box2d` enclosing the path.
377
- * @since 2.0.0
378
- */
379
- const boundingBox$2 = boundingBox$3;
380
- //#endregion
5
+ import { o as none, r as isNone, s as one } from "../shared/solution-B2JdOZpe.mjs";
6
+ import { n as isDecreasing, r as isIncreasing } from "../shared/quadratic-DPrUsFCp.mjs";
7
+ import { a as union } from "../shared/interval2d-AtneyI45.mjs";
8
+ import { b as solveAtY$2, g as length$2, h as boundingBox$2, v as solve$2, y as solveAtX$2 } from "../shared/rationalCubic2d-CeHgpNht.mjs";
9
+ import { n as rationalCubic2d_exports, o as linear2d_exports, r as cubic2d_exports } from "../shared/rationalCubic2d-H1J2Fjyy.mjs";
381
10
  //#region src/path/quadratic2d.internal.ts
382
11
  const QuadraticPath2dTypeId = Symbol("curvy/path/quadratic2d");
383
12
  /** @internal */
@@ -403,17 +32,17 @@ const append$1 = dual(2, (p, c) => fromArray$1([...p, c]));
403
32
  /** @internal */
404
33
  const length$1 = (p) => {
405
34
  let total = 0;
406
- for (const curve of p) total += length$5(curve, unit);
35
+ for (const curve of p) total += length$2(curve, unit);
407
36
  return total;
408
37
  };
409
38
  /** @internal */
410
39
  const solve$1 = dual(2, (p, u) => {
411
40
  const curves = p instanceof QuadraticPath2dImpl ? p.curves : [...p];
412
- if (u === 1) return solve$5(curves.at(-1), 1);
41
+ if (u === 1) return solve$2(curves.at(-1), 1);
413
42
  const t = u * curves.length;
414
43
  const i = Math.floor(t);
415
44
  const curve = curves[i];
416
- return solve$5(curve, t - i);
45
+ return solve$2(curve, t - i);
417
46
  });
418
47
  /** @internal */
419
48
  const toPathData$1 = (p) => {
@@ -464,7 +93,7 @@ const asContinuous$1 = (p) => {
464
93
  const isIncreasingX$1 = (p) => {
465
94
  let prevEnd = Number.NEGATIVE_INFINITY;
466
95
  for (const c of p) {
467
- if (!isIncreasing$1(c.x, unit)) return false;
96
+ if (!isIncreasing(c.x, unit)) return false;
468
97
  if (c.x.c0 < prevEnd - 1e-10) return false;
469
98
  prevEnd = c.x.c0 + c.x.c1 + c.x.c2;
470
99
  }
@@ -474,7 +103,7 @@ const isIncreasingX$1 = (p) => {
474
103
  const isDecreasingX$1 = (p) => {
475
104
  let prevEnd = Number.POSITIVE_INFINITY;
476
105
  for (const c of p) {
477
- if (!isDecreasing$1(c.x, unit)) return false;
106
+ if (!isDecreasing(c.x, unit)) return false;
478
107
  if (c.x.c0 > prevEnd + 1e-10) return false;
479
108
  prevEnd = c.x.c0 + c.x.c1 + c.x.c2;
480
109
  }
@@ -486,7 +115,7 @@ const isMonotonicX$1 = (p) => isIncreasingX$1(p) || isDecreasingX$1(p);
486
115
  const isIncreasingY$1 = (p) => {
487
116
  let prevEnd = Number.NEGATIVE_INFINITY;
488
117
  for (const c of p) {
489
- if (!isIncreasing$1(c.y, unit)) return false;
118
+ if (!isIncreasing(c.y, unit)) return false;
490
119
  if (c.y.c0 < prevEnd - 1e-10) return false;
491
120
  prevEnd = c.y.c0 + c.y.c1 + c.y.c2;
492
121
  }
@@ -496,7 +125,7 @@ const isIncreasingY$1 = (p) => {
496
125
  const isDecreasingY$1 = (p) => {
497
126
  let prevEnd = Number.POSITIVE_INFINITY;
498
127
  for (const c of p) {
499
- if (!isDecreasing$1(c.y, unit)) return false;
128
+ if (!isDecreasing(c.y, unit)) return false;
500
129
  if (c.y.c0 > prevEnd + 1e-10) return false;
501
130
  prevEnd = c.y.c0 + c.y.c1 + c.y.c2;
502
131
  }
@@ -544,7 +173,7 @@ const solveAtX$1 = dual(2, (p, x) => {
544
173
  if (x >= lo - 1e-10 && x <= hi + 1e-10) {
545
174
  if (epsEquals(x, sx)) return one(c.y.c0);
546
175
  if (epsEquals(x, ex)) return one(c.y.c0 + c.y.c1 + c.y.c2);
547
- const sol = solveAtX$5(c, x);
176
+ const sol = solveAtX$2(c, x);
548
177
  if (!isNone(sol)) return sol;
549
178
  }
550
179
  }
@@ -560,7 +189,7 @@ const solveAtY$1 = dual(2, (p, y) => {
560
189
  if (y >= lo - 1e-10 && y <= hi + 1e-10) {
561
190
  if (epsEquals(y, sy)) return one(c.x.c0);
562
191
  if (epsEquals(y, ey)) return one(c.x.c0 + c.x.c1 + c.x.c2);
563
- const sol = solveAtY$5(c, y);
192
+ const sol = solveAtY$2(c, y);
564
193
  if (!isNone(sol)) return sol;
565
194
  }
566
195
  }
@@ -569,8 +198,8 @@ const solveAtY$1 = dual(2, (p, y) => {
569
198
  /** @internal */
570
199
  const boundingBox$1 = (p) => {
571
200
  const iter = p[Symbol.iterator]();
572
- let acc = boundingBox$5(iter.next().value);
573
- for (let next = iter.next(); !next.done; next = iter.next()) acc = union(acc, boundingBox$5(next.value));
201
+ let acc = boundingBox$2(iter.next().value);
202
+ for (let next = iter.next(); !next.done; next = iter.next()) acc = union(acc, boundingBox$2(next.value));
574
203
  return acc;
575
204
  };
576
205
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["isLinearPath2d","make","fromArray","append","length","LinearCurve2d.length","Interval.unit","solve","LinearCurve2d.solve","toPathData","isContinuous","asContinuous","isIncreasingX","LinearPolynomial.isIncreasing","isDecreasingX","LinearPolynomial.isDecreasing","isMonotonicX","isIncreasingY","isDecreasingY","isMonotonicY","asIncreasingX","asDecreasingX","asMonotonicX","asIncreasingY","asDecreasingY","asMonotonicY","solveAtX","Solution.one","LinearCurve2d.solveAtX","Solution.isNone","Solution.none","solveAtY","LinearCurve2d.solveAtY","boundingBox","LinearCurve2d.boundingBox","Interval2d.union","make","internal.make","fromArray","internal.fromArray","internal.isLinearPath2d","append","internal.append","length","internal.length","solve","internal.solve","toPathData","internal.toPathData","isContinuous","internal.isContinuous","asContinuous","internal.asContinuous","isIncreasingX","internal.isIncreasingX","isDecreasingX","internal.isDecreasingX","isMonotonicX","internal.isMonotonicX","isIncreasingY","internal.isIncreasingY","isDecreasingY","internal.isDecreasingY","isMonotonicY","internal.isMonotonicY","asIncreasingX","internal.asIncreasingX","asDecreasingX","internal.asDecreasingX","asMonotonicX","internal.asMonotonicX","asIncreasingY","internal.asIncreasingY","asDecreasingY","internal.asDecreasingY","asMonotonicY","internal.asMonotonicY","solveAtX","internal.solveAtX","solveAtY","internal.solveAtY","boundingBox","internal.boundingBox","isQuadraticPath2d","make","fromArray","append","length","QuadraticCurve2d.length","Interval.unit","solve","QuadraticCurve2d.solve","toPathData","isContinuous","asContinuous","isIncreasingX","QuadraticPolynomial.isIncreasing","isDecreasingX","QuadraticPolynomial.isDecreasing","isMonotonicX","isIncreasingY","isDecreasingY","isMonotonicY","asIncreasingX","asDecreasingX","asMonotonicX","asIncreasingY","asDecreasingY","asMonotonicY","solveAtX","Solution.one","QuadraticCurve2d.solveAtX","Solution.isNone","Solution.none","solveAtY","QuadraticCurve2d.solveAtY","boundingBox","QuadraticCurve2d.boundingBox","Interval2d.union","internal.make","internal.fromArray","internal.isQuadraticPath2d","internal.append","internal.length","internal.solve","internal.toPathData","internal.isContinuous","internal.asContinuous","internal.isIncreasingX","internal.isDecreasingX","internal.isMonotonicX","internal.isIncreasingY","internal.isDecreasingY","internal.isMonotonicY","internal.asIncreasingX","internal.asDecreasingX","internal.asMonotonicX","internal.asIncreasingY","internal.asDecreasingY","internal.asMonotonicY","internal.solveAtX","internal.solveAtY","internal.boundingBox"],"sources":["../../src/path/linear2d.internal.ts","../../src/path/linear2d.ts","../../src/path/quadratic2d.internal.ts","../../src/path/quadratic2d.ts"],"sourcesContent":["import * as Interval2d from '../interval/interval2d.ts'\nimport * as LinearCurve2d from '../curve/linear2d.ts'\nimport * as Interval from '../interval/interval.ts'\nimport * as LinearPolynomial from '../polynomial/linear.ts'\nimport * as Solution from '../solution/solution.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport { invariant } from '../utils.ts'\nimport { EPSILON, epsEquals } from '../number.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { LinearPath2d } from './linear2d.ts'\nimport {\n PathTraits,\n type Continuous,\n type DecreasingX,\n type DecreasingY,\n type IncreasingX,\n type IncreasingY,\n type MonotonicX,\n type MonotonicY,\n} from './traits.ts'\n\nexport const LinearPath2dTypeId: unique symbol = Symbol('curvy/path/linear2d')\nexport type LinearPath2dTypeId = typeof LinearPath2dTypeId\n\n/** @internal */\nexport class LinearPath2dImpl extends Pipeable implements LinearPath2d<unknown> {\n readonly [LinearPath2dTypeId]: LinearPath2dTypeId = LinearPath2dTypeId\n declare readonly [PathTraits]: unknown\n\n readonly curves: ReadonlyArray<LinearCurve2d.LinearCurve2d>\n\n constructor(curves: ReadonlyArray<LinearCurve2d.LinearCurve2d>) {\n super()\n this.curves = curves\n }\n\n [Symbol.iterator](): Iterator<LinearCurve2d.LinearCurve2d> {\n return this.curves[Symbol.iterator]()\n }\n}\n\n/** @internal */\nexport const isLinearPath2d = (p: unknown): p is LinearPath2d =>\n typeof p === 'object' && p !== null && LinearPath2dTypeId in p\n\n/** @internal */\nexport const make = (...curves: ReadonlyArray<LinearCurve2d.LinearCurve2d>): LinearPath2d =>\n new LinearPath2dImpl(curves)\n\n/** @internal */\nexport const fromArray = (curves: ReadonlyArray<LinearCurve2d.LinearCurve2d>) =>\n new LinearPath2dImpl(curves)\n\n/** @internal */\nexport const append = dual<\n (c: LinearCurve2d.LinearCurve2d) => (p: LinearPath2d) => LinearPath2d,\n (p: LinearPath2d, c: LinearCurve2d.LinearCurve2d) => LinearPath2d\n>(2, (p: LinearPath2d, c: LinearCurve2d.LinearCurve2d) => fromArray([...p, c]))\n\n/** @internal */\nexport const length = (p: LinearPath2d) => {\n let total = 0\n for (const curve of p) {\n total += LinearCurve2d.length(curve, Interval.unit)\n }\n\n return total\n}\n\n/** @internal */\nexport const solve = dual<\n (u: number) => (p: LinearPath2d) => Vector2,\n (p: LinearPath2d, u: number) => Vector2\n>(2, (p: LinearPath2d, u: number) => {\n const curves = p instanceof LinearPath2dImpl ? p.curves : [...p]\n\n if (u === 1) {\n const last = curves.at(-1) as LinearCurve2d.LinearCurve2d\n return LinearCurve2d.solve(last, 1)\n }\n\n const t = u * curves.length\n const i = Math.floor(t)\n const curve = curves[i] as LinearCurve2d.LinearCurve2d\n return LinearCurve2d.solve(curve, t - i)\n})\n\n/** @internal */\nexport const toPathData = (p: LinearPath2d): string => {\n let result = ''\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n\n for (const curve of p) {\n const startX = curve.x.c0\n const startY = curve.y.c0\n const endX = curve.x.c0 + curve.x.c1\n const endY = curve.y.c0 + curve.y.c1\n\n if (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY)) {\n result += ` M ${startX},${startY}`\n }\n result += ` L ${endX},${endY}`\n\n prevEndX = endX\n prevEndY = endY\n }\n\n return result.slice(1)\n}\n\n/** @internal */\nexport const isContinuous = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & Continuous> => {\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n let first = true\n\n for (const curve of p) {\n const startX = curve.x.c0\n const startY = curve.y.c0\n if (!first && (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY))) {\n return false\n }\n prevEndX = curve.x.c0 + curve.x.c1\n prevEndY = curve.y.c0 + curve.y.c1\n first = false\n }\n return true\n}\n\n/** @internal */\nexport const asContinuous = <T>(p: LinearPath2d<T>): LinearPath2d<T & Continuous> => {\n invariant(isContinuous(p), 'linear path is not continuous')\n return p\n}\n\n// Per-axis monotonicity refiners. A path is monotonic-on-an-axis when every\n// segment's per-axis polynomial is strictly monotonic in the same direction\n// AND adjacent segments' ranges on that axis don't overlap (modulo float\n// tolerance) — so the path's u → axis mapping is monotonic across joins.\n\n/** @internal */\nexport const isIncreasingX = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & IncreasingX> => {\n let prevEnd = Number.NEGATIVE_INFINITY\n for (const c of p) {\n if (!LinearPolynomial.isIncreasing(c.x)) {\n return false\n }\n if (c.x.c0 < prevEnd - EPSILON) {\n return false\n }\n prevEnd = c.x.c0 + c.x.c1\n }\n return true\n}\n\n/** @internal */\nexport const isDecreasingX = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & DecreasingX> => {\n let prevEnd = Number.POSITIVE_INFINITY\n for (const c of p) {\n if (!LinearPolynomial.isDecreasing(c.x)) {\n return false\n }\n if (c.x.c0 > prevEnd + EPSILON) {\n return false\n }\n prevEnd = c.x.c0 + c.x.c1\n }\n return true\n}\n\n/** @internal */\nexport const isMonotonicX = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & MonotonicX> =>\n isIncreasingX(p) || isDecreasingX(p)\n\n/** @internal */\nexport const isIncreasingY = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & IncreasingY> => {\n let prevEnd = Number.NEGATIVE_INFINITY\n for (const c of p) {\n if (!LinearPolynomial.isIncreasing(c.y)) {\n return false\n }\n if (c.y.c0 < prevEnd - EPSILON) {\n return false\n }\n prevEnd = c.y.c0 + c.y.c1\n }\n return true\n}\n\n/** @internal */\nexport const isDecreasingY = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & DecreasingY> => {\n let prevEnd = Number.POSITIVE_INFINITY\n for (const c of p) {\n if (!LinearPolynomial.isDecreasing(c.y)) {\n return false\n }\n if (c.y.c0 > prevEnd + EPSILON) {\n return false\n }\n prevEnd = c.y.c0 + c.y.c1\n }\n return true\n}\n\n/** @internal */\nexport const isMonotonicY = <T>(p: LinearPath2d<T>): p is LinearPath2d<T & MonotonicY> =>\n isIncreasingY(p) || isDecreasingY(p)\n\n/** @internal */\nexport const asIncreasingX = <T>(p: LinearPath2d<T>): LinearPath2d<T & IncreasingX> => {\n invariant(isIncreasingX(p), 'linear path is not increasing in x')\n return p\n}\n\n/** @internal */\nexport const asDecreasingX = <T>(p: LinearPath2d<T>): LinearPath2d<T & DecreasingX> => {\n invariant(isDecreasingX(p), 'linear path is not decreasing in x')\n return p\n}\n\n/** @internal */\nexport const asMonotonicX = <T>(p: LinearPath2d<T>): LinearPath2d<T & MonotonicX> => {\n invariant(isMonotonicX(p), 'linear path is not monotonic in x')\n return p\n}\n\n/** @internal */\nexport const asIncreasingY = <T>(p: LinearPath2d<T>): LinearPath2d<T & IncreasingY> => {\n invariant(isIncreasingY(p), 'linear path is not increasing in y')\n return p\n}\n\n/** @internal */\nexport const asDecreasingY = <T>(p: LinearPath2d<T>): LinearPath2d<T & DecreasingY> => {\n invariant(isDecreasingY(p), 'linear path is not decreasing in y')\n return p\n}\n\n/** @internal */\nexport const asMonotonicY = <T>(p: LinearPath2d<T>): LinearPath2d<T & MonotonicY> => {\n invariant(isMonotonicY(p), 'linear path is not monotonic in y')\n return p\n}\n\n// solveAtX/solveAtY for `Monotonic{X,Y}` paths. Two defenses against float\n// drift at interior knots (where adjacent segments both bracket the query):\n// 1. Snap to t=0/t=1 endpoint y when the query is within EPSILON of a\n// segment's start or end.\n// 2. Fall through to the next bracketing segment on `none`. Linear paths\n// don't currently surface drift (degree-1 `c0 + c1 = x` is stable), but\n// the same shape applies for symmetry with quadratic / cubic.\n/** @internal */\nexport const solveAtX = dual(2, (p: LinearPath2d, x: number): Solution.AtMostOne<number> => {\n for (const c of p) {\n const sx = c.x.c0\n const ex = c.x.c0 + c.x.c1\n const lo = Math.min(sx, ex)\n const hi = Math.max(sx, ex)\n if (x >= lo - EPSILON && x <= hi + EPSILON) {\n if (epsEquals(x, sx)) {\n return Solution.one(c.y.c0)\n }\n if (epsEquals(x, ex)) {\n return Solution.one(c.y.c0 + c.y.c1)\n }\n const sol = LinearCurve2d.solveAtX(c, x)\n if (!Solution.isNone(sol)) {\n return sol\n }\n }\n }\n return Solution.none\n})\n\n/** @internal */\nexport const solveAtY = dual(2, (p: LinearPath2d, y: number): Solution.AtMostOne<number> => {\n for (const c of p) {\n const sy = c.y.c0\n const ey = c.y.c0 + c.y.c1\n const lo = Math.min(sy, ey)\n const hi = Math.max(sy, ey)\n if (y >= lo - EPSILON && y <= hi + EPSILON) {\n if (epsEquals(y, sy)) {\n return Solution.one(c.x.c0)\n }\n if (epsEquals(y, ey)) {\n return Solution.one(c.x.c0 + c.x.c1)\n }\n const sol = LinearCurve2d.solveAtY(c, y)\n if (!Solution.isNone(sol)) {\n return sol\n }\n }\n }\n return Solution.none\n})\n\n/** @internal */\nexport const boundingBox = (\n p: LinearPath2d,\n): Interval2d.Interval2d<Interval.Closed, Interval.Closed> => {\n const iter = p[Symbol.iterator]()\n const first = iter.next()\n // path invariant: at least one curve, so first.value is defined\n let acc = LinearCurve2d.boundingBox(first.value as LinearCurve2d.LinearCurve2d)\n for (let next = iter.next(); !next.done; next = iter.next()) {\n acc = Interval2d.union(acc, LinearCurve2d.boundingBox(next.value))\n }\n return acc\n}\n","import type { Interval2d } from '../interval/interval2d.ts'\nimport type { LinearCurve2d } from '../curve/linear2d.ts'\nimport type { Closed } from '../interval/interval.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { LinearPath2dTypeId } from './linear2d.internal.ts'\nimport * as internal from './linear2d.internal.ts'\nimport type {\n Continuous,\n DecreasingX,\n DecreasingY,\n IncreasingX,\n IncreasingY,\n MonotonicX,\n MonotonicY,\n PathTraits,\n} from './traits.ts'\n\nexport type {\n Continuous,\n DecreasingX,\n DecreasingY,\n IncreasingX,\n IncreasingY,\n MonotonicX,\n MonotonicY,\n} from './traits.ts'\n\n/**\n * A linear path in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The `Trait` type parameter accumulates trait brands as the path is refined\n * via `isContinuous` / `asContinuous`. A `Continuous` path's `toPathData`\n * skips the per-segment discontinuity check.\n *\n * @since 1.0.0\n */\nexport interface LinearPath2d<out Trait = unknown> extends Pipeable, Iterable<LinearCurve2d> {\n readonly [LinearPath2dTypeId]: LinearPath2dTypeId\n readonly [PathTraits]: Trait\n}\n\n/**\n * Creates a new `LinearPath2d` instance from a sequence of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `LinearPath2d` instance.\n * @since 2.0.0\n */\nexport const make: (...curves: ReadonlyArray<LinearCurve2d>) => LinearPath2d = internal.make\n\n/**\n * Creates a new `LinearPath2d` instance from an array of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `LinearPath2d` instance.\n * @since 2.0.0\n */\nexport const fromArray: (curves: ReadonlyArray<LinearCurve2d>) => LinearPath2d = internal.fromArray\n\n/**\n * Checks if a value is a `LinearPath2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `LinearPath2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isLinearPath2d: (p: unknown) => p is LinearPath2d = internal.isLinearPath2d\n\nexport const append: {\n /**\n * Appends a linear curve to a linear path.\n *\n * @param c - The linear curve to append.\n * @returns A function that takes a linear path and returns a new linear path.\n * @since 1.0.0\n */\n (c: LinearCurve2d): (p: LinearPath2d) => LinearPath2d\n /**\n * Appends a linear curve to a linear path.\n *\n * @param p - The linear path to append to.\n * @param c - The linear curve to append.\n * @returns A new `LinearPath2d` instance with the appended curve.\n * @since 1.0.0\n */\n (p: LinearPath2d, c: LinearCurve2d): LinearPath2d\n} = internal.append\n\n/**\n * Calculates the length of a linear path.\n *\n * @param p - The linear path to calculate the length of.\n * @returns The length of the linear path.\n * @since 1.0.0\n */\nexport const length: (p: LinearPath2d) => number = internal.length\n\nexport const solve: {\n /**\n * Solves a linear path for a given parameter.\n *\n * @param u - The parameter to solve for.\n * @returns A function that takes a linear path and returns the solved point.\n * @since 1.0.0\n */\n (u: number): (p: LinearPath2d) => Vector2\n /**\n * Solves a linear path for a given parameter.\n *\n * @param p - The linear path to solve.\n * @param u - The parameter to solve for.\n * @returns The solved point on the linear path.\n * @since 1.0.0\n */\n (p: LinearPath2d, u: number): Vector2\n} = internal.solve\n\n/**\n * Serializes a linear path as an SVG path data string (the value of a `<path>`\n * element's `d` attribute), using `M` and `L` commands. Discontinuities between\n * curves emit a fresh `M` command.\n *\n * @param p - The linear path to serialize.\n * @returns The SVG path data string.\n * @since 2.0.0\n */\nexport const toPathData: (p: LinearPath2d) => string = internal.toPathData\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & Continuous>` when adjacent curves connect at their join\n * points.\n *\n * @param p - The linear path to check.\n * @returns `true` when the path is continuous (G⁰).\n * @since 2.0.0\n */\nexport const isContinuous: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & Continuous> =\n internal.isContinuous\n\n/**\n * Asserts that the linear path is continuous, throwing on failure.\n *\n * @param p - The linear path to assert against.\n * @returns The same path, typed with the `Continuous` brand.\n * @throws When the path has a discontinuity between adjacent curves.\n * @since 2.0.0\n */\nexport const asContinuous: <T>(p: LinearPath2d<T>) => LinearPath2d<T & Continuous> =\n internal.asContinuous\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & IncreasingX>` when every segment's x-polynomial is\n * strictly increasing and adjacent segments' x-ranges don't overlap.\n *\n * @since 2.0.0\n */\nexport const isIncreasingX: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & IncreasingX> =\n internal.isIncreasingX\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & DecreasingX>` when every segment's x-polynomial is\n * strictly decreasing and adjacent segments' x-ranges don't overlap.\n *\n * @since 2.0.0\n */\nexport const isDecreasingX: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & DecreasingX> =\n internal.isDecreasingX\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & MonotonicX>` when the path is either increasing or\n * decreasing in x along its full parameter domain.\n *\n * @since 2.0.0\n */\nexport const isMonotonicX: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & MonotonicX> =\n internal.isMonotonicX\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & IncreasingY>`. The y-axis analog of {@link isIncreasingX}.\n *\n * @since 2.0.0\n */\nexport const isIncreasingY: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & IncreasingY> =\n internal.isIncreasingY\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & DecreasingY>`. The y-axis analog of {@link isDecreasingX}.\n *\n * @since 2.0.0\n */\nexport const isDecreasingY: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & DecreasingY> =\n internal.isDecreasingY\n\n/**\n * Type-narrowing predicate: refines `LinearPath2d<T>` to\n * `LinearPath2d<T & MonotonicY>`. The y-axis analog of {@link isMonotonicX}.\n *\n * @since 2.0.0\n */\nexport const isMonotonicY: <T>(p: LinearPath2d<T>) => p is LinearPath2d<T & MonotonicY> =\n internal.isMonotonicY\n\n/**\n * Asserts that the path is strictly increasing in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasingX: <T>(p: LinearPath2d<T>) => LinearPath2d<T & IncreasingX> =\n internal.asIncreasingX\n\n/**\n * Asserts that the path is strictly decreasing in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasingX: <T>(p: LinearPath2d<T>) => LinearPath2d<T & DecreasingX> =\n internal.asDecreasingX\n\n/**\n * Asserts that the path is monotonic in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asMonotonicX: <T>(p: LinearPath2d<T>) => LinearPath2d<T & MonotonicX> =\n internal.asMonotonicX\n\n/**\n * Asserts that the path is strictly increasing in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasingY: <T>(p: LinearPath2d<T>) => LinearPath2d<T & IncreasingY> =\n internal.asIncreasingY\n\n/**\n * Asserts that the path is strictly decreasing in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasingY: <T>(p: LinearPath2d<T>) => LinearPath2d<T & DecreasingY> =\n internal.asDecreasingY\n\n/**\n * Asserts that the path is monotonic in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asMonotonicY: <T>(p: LinearPath2d<T>) => LinearPath2d<T & MonotonicY> =\n internal.asMonotonicY\n\nexport const solveAtX: {\n /**\n * Evaluates the path's y value at a given x. Requires the path to carry the\n * `MonotonicX` brand — without it, an x query could match multiple\n * segments and the return cardinality would be unbounded.\n *\n * Returns `Solution.none` when x falls outside the path's x-range.\n *\n * @param p - A path branded `MonotonicX`.\n * @param x - The x coordinate.\n * @returns The y value at x, or `none` when x is outside the path's range.\n * @since 2.0.0\n */\n <T extends MonotonicX>(p: LinearPath2d<T>, x: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (x: number): <T extends MonotonicX>(p: LinearPath2d<T>) => Solution.AtMostOne<number>\n} = internal.solveAtX as never\n\nexport const solveAtY: {\n /**\n * Evaluates the path's x value at a given y. Requires the path to carry the\n * `MonotonicY` brand. Returns `Solution.none` when y is outside the path's\n * y-range.\n *\n * @param p - A path branded `MonotonicY`.\n * @param y - The y coordinate.\n * @returns The x value at y, or `none` when y is outside the path's range.\n * @since 2.0.0\n */\n <T extends MonotonicY>(p: LinearPath2d<T>, y: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (y: number): <T extends MonotonicY>(p: LinearPath2d<T>) => Solution.AtMostOne<number>\n} = internal.solveAtY as never\n\n/**\n * Computes the axis-aligned bounding box of the path — the smallest closed\n * `Box2d` enclosing every segment.\n *\n * @param p - The linear path.\n * @returns A closed `Box2d` enclosing the path.\n * @since 2.0.0\n */\nexport const boundingBox: (p: LinearPath2d) => Interval2d<Closed, Closed> = internal.boundingBox\n","import * as Interval2d from '../interval/interval2d.ts'\nimport * as QuadraticCurve2d from '../curve/quadratic2d.ts'\nimport * as Interval from '../interval/interval.ts'\nimport * as QuadraticPolynomial from '../polynomial/quadratic.ts'\nimport * as Solution from '../solution/solution.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport { invariant } from '../utils.ts'\nimport { EPSILON, epsEquals } from '../number.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { QuadraticPath2d } from './quadratic2d.ts'\nimport {\n PathTraits,\n type Continuous,\n type DecreasingX,\n type DecreasingY,\n type IncreasingX,\n type IncreasingY,\n type MonotonicX,\n type MonotonicY,\n} from './traits.ts'\n\nexport const QuadraticPath2dTypeId: unique symbol = Symbol('curvy/path/quadratic2d')\nexport type QuadraticPath2dTypeId = typeof QuadraticPath2dTypeId\n\n/** @internal */\nexport class QuadraticPath2dImpl extends Pipeable implements QuadraticPath2d<unknown> {\n readonly [QuadraticPath2dTypeId]: QuadraticPath2dTypeId = QuadraticPath2dTypeId\n declare readonly [PathTraits]: unknown\n\n readonly curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>\n\n constructor(curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>) {\n super()\n this.curves = curves\n }\n\n [Symbol.iterator](): Iterator<QuadraticCurve2d.QuadraticCurve2d> {\n return this.curves[Symbol.iterator]()\n }\n}\n\n/** @internal */\nexport const isQuadraticPath2d = (p: unknown): p is QuadraticPath2d =>\n typeof p === 'object' && p !== null && QuadraticPath2dTypeId in p\n\n/** @internal */\nexport const make = (\n ...curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>\n): QuadraticPath2d => new QuadraticPath2dImpl(curves)\n\n/** @internal */\nexport const fromArray = (\n curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>,\n): QuadraticPath2d => new QuadraticPath2dImpl(curves)\n\n/** @internal */\nexport const append = dual<\n (c: QuadraticCurve2d.QuadraticCurve2d) => (p: QuadraticPath2d) => QuadraticPath2d,\n (p: QuadraticPath2d, c: QuadraticCurve2d.QuadraticCurve2d) => QuadraticPath2d\n>(2, (p: QuadraticPath2d, c: QuadraticCurve2d.QuadraticCurve2d) => fromArray([...p, c]))\n\n/** @internal */\nexport const length = (p: QuadraticPath2d) => {\n let total = 0\n for (const curve of p) {\n total += QuadraticCurve2d.length(curve, Interval.unit)\n }\n\n return total\n}\n\n/** @internal */\nexport const solve = dual<\n (u: number) => (p: QuadraticPath2d) => Vector2,\n (p: QuadraticPath2d, u: number) => Vector2\n>(2, (p: QuadraticPath2d, u: number) => {\n const curves = p instanceof QuadraticPath2dImpl ? p.curves : [...p]\n\n if (u === 1) {\n const last = curves.at(-1) as QuadraticCurve2d.QuadraticCurve2d\n return QuadraticCurve2d.solve(last, 1)\n }\n\n const t = u * curves.length\n const i = Math.floor(t)\n const curve = curves[i] as QuadraticCurve2d.QuadraticCurve2d\n return QuadraticCurve2d.solve(curve, t - i)\n})\n\n// Quadratic Bernstein basis: P(t) = (1-t)²·p0 + 2(1-t)t·p1 + t²·p2\n// expanded gives c0 = p0, c1 = -2p0 + 2p1, c2 = p0 - 2p1 + p2, so:\n// p0 = c0, p1 = c0 + c1/2, p2 = c0 + c1 + c2.\n/** @internal */\nexport const toPathData = (p: QuadraticPath2d): string => {\n let result = ''\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n\n for (const curve of p) {\n const c0x = curve.x.c0\n const c0y = curve.y.c0\n const c1x = curve.x.c1\n const c1y = curve.y.c1\n const c2x = curve.x.c2\n const c2y = curve.y.c2\n\n const startX = c0x\n const startY = c0y\n const ctrlX = c0x + c1x / 2\n const ctrlY = c0y + c1y / 2\n const endX = c0x + c1x + c2x\n const endY = c0y + c1y + c2y\n\n if (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY)) {\n result += ` M ${startX},${startY}`\n }\n result += ` Q ${ctrlX},${ctrlY} ${endX},${endY}`\n\n prevEndX = endX\n prevEndY = endY\n }\n\n return result.slice(1)\n}\n\n/** @internal */\nexport const isContinuous = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & Continuous> => {\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n let first = true\n\n for (const curve of p) {\n const startX = curve.x.c0\n const startY = curve.y.c0\n if (!first && (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY))) {\n return false\n }\n prevEndX = curve.x.c0 + curve.x.c1 + curve.x.c2\n prevEndY = curve.y.c0 + curve.y.c1 + curve.y.c2\n first = false\n }\n return true\n}\n\n/** @internal */\nexport const asContinuous = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & Continuous> => {\n invariant(isContinuous(p), 'quadratic path is not continuous')\n return p\n}\n\n// Per-axis monotonicity for the path: every segment's axis polynomial must be\n// strictly monotonic over the unit interval AND adjacent segments' axis\n// ranges must not overlap (modulo EPSILON for float drift).\n/** @internal */\nexport const isIncreasingX = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & IncreasingX> => {\n let prevEnd = Number.NEGATIVE_INFINITY\n for (const c of p) {\n if (!QuadraticPolynomial.isIncreasing(c.x, Interval.unit)) {\n return false\n }\n if (c.x.c0 < prevEnd - EPSILON) {\n return false\n }\n prevEnd = c.x.c0 + c.x.c1 + c.x.c2\n }\n return true\n}\n\n/** @internal */\nexport const isDecreasingX = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & DecreasingX> => {\n let prevEnd = Number.POSITIVE_INFINITY\n for (const c of p) {\n if (!QuadraticPolynomial.isDecreasing(c.x, Interval.unit)) {\n return false\n }\n if (c.x.c0 > prevEnd + EPSILON) {\n return false\n }\n prevEnd = c.x.c0 + c.x.c1 + c.x.c2\n }\n return true\n}\n\n/** @internal */\nexport const isMonotonicX = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & MonotonicX> =>\n isIncreasingX(p) || isDecreasingX(p)\n\n/** @internal */\nexport const isIncreasingY = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & IncreasingY> => {\n let prevEnd = Number.NEGATIVE_INFINITY\n for (const c of p) {\n if (!QuadraticPolynomial.isIncreasing(c.y, Interval.unit)) {\n return false\n }\n if (c.y.c0 < prevEnd - EPSILON) {\n return false\n }\n prevEnd = c.y.c0 + c.y.c1 + c.y.c2\n }\n return true\n}\n\n/** @internal */\nexport const isDecreasingY = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & DecreasingY> => {\n let prevEnd = Number.POSITIVE_INFINITY\n for (const c of p) {\n if (!QuadraticPolynomial.isDecreasing(c.y, Interval.unit)) {\n return false\n }\n if (c.y.c0 > prevEnd + EPSILON) {\n return false\n }\n prevEnd = c.y.c0 + c.y.c1 + c.y.c2\n }\n return true\n}\n\n/** @internal */\nexport const isMonotonicY = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & MonotonicY> =>\n isIncreasingY(p) || isDecreasingY(p)\n\n/** @internal */\nexport const asIncreasingX = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & IncreasingX> => {\n invariant(isIncreasingX(p), 'quadratic path is not increasing in x')\n return p\n}\n\n/** @internal */\nexport const asDecreasingX = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & DecreasingX> => {\n invariant(isDecreasingX(p), 'quadratic path is not decreasing in x')\n return p\n}\n\n/** @internal */\nexport const asMonotonicX = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & MonotonicX> => {\n invariant(isMonotonicX(p), 'quadratic path is not monotonic in x')\n return p\n}\n\n/** @internal */\nexport const asIncreasingY = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & IncreasingY> => {\n invariant(isIncreasingY(p), 'quadratic path is not increasing in y')\n return p\n}\n\n/** @internal */\nexport const asDecreasingY = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & DecreasingY> => {\n invariant(isDecreasingY(p), 'quadratic path is not decreasing in y')\n return p\n}\n\n/** @internal */\nexport const asMonotonicY = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & MonotonicY> => {\n invariant(isMonotonicY(p), 'quadratic path is not monotonic in y')\n return p\n}\n\n// solveAtX/Y on a monotonic-axis path. Two defenses against float drift at\n// interior knots, where two adjacent segments both bracket the query and the\n// polynomial-inverse solver may return `none` for both:\n// 1. Snap to t=0/t=1 endpoint y when the query is within EPSILON of a\n// segment's start or end — bypasses polynomial inversion at knots.\n// 2. Fall through to the next bracketing segment on `none`. `MonotonicX/Y`\n// admits at most one real solution across the path, so retrying is safe.\n/** @internal */\nexport const solveAtX = dual(2, (p: QuadraticPath2d, x: number): Solution.AtMostOne<number> => {\n for (const c of p) {\n const sx = c.x.c0\n const ex = c.x.c0 + c.x.c1 + c.x.c2\n const lo = Math.min(sx, ex)\n const hi = Math.max(sx, ex)\n if (x >= lo - EPSILON && x <= hi + EPSILON) {\n if (epsEquals(x, sx)) {\n return Solution.one(c.y.c0)\n }\n if (epsEquals(x, ex)) {\n return Solution.one(c.y.c0 + c.y.c1 + c.y.c2)\n }\n const sol = QuadraticCurve2d.solveAtX(c, x) as Solution.AtMostOne<number>\n if (!Solution.isNone(sol)) {\n return sol\n }\n }\n }\n return Solution.none\n})\n\n/** @internal */\nexport const solveAtY = dual(2, (p: QuadraticPath2d, y: number): Solution.AtMostOne<number> => {\n for (const c of p) {\n const sy = c.y.c0\n const ey = c.y.c0 + c.y.c1 + c.y.c2\n const lo = Math.min(sy, ey)\n const hi = Math.max(sy, ey)\n if (y >= lo - EPSILON && y <= hi + EPSILON) {\n if (epsEquals(y, sy)) {\n return Solution.one(c.x.c0)\n }\n if (epsEquals(y, ey)) {\n return Solution.one(c.x.c0 + c.x.c1 + c.x.c2)\n }\n const sol = QuadraticCurve2d.solveAtY(c, y) as Solution.AtMostOne<number>\n if (!Solution.isNone(sol)) {\n return sol\n }\n }\n }\n return Solution.none\n})\n\n/** @internal */\nexport const boundingBox = (\n p: QuadraticPath2d,\n): Interval2d.Interval2d<Interval.Closed, Interval.Closed> => {\n const iter = p[Symbol.iterator]()\n const first = iter.next()\n let acc = QuadraticCurve2d.boundingBox(first.value as QuadraticCurve2d.QuadraticCurve2d)\n for (let next = iter.next(); !next.done; next = iter.next()) {\n acc = Interval2d.union(acc, QuadraticCurve2d.boundingBox(next.value))\n }\n return acc\n}\n","import type { Interval2d } from '../interval/interval2d.ts'\nimport type { QuadraticCurve2d } from '../curve/quadratic2d.ts'\nimport type { Closed } from '../interval/interval.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { QuadraticPath2dTypeId } from './quadratic2d.internal.ts'\nimport * as internal from './quadratic2d.internal.ts'\nimport type {\n Continuous,\n DecreasingX,\n DecreasingY,\n IncreasingX,\n IncreasingY,\n MonotonicX,\n MonotonicY,\n PathTraits,\n} from './traits.ts'\n\nexport type {\n Continuous,\n DecreasingX,\n DecreasingY,\n IncreasingX,\n IncreasingY,\n MonotonicX,\n MonotonicY,\n} from './traits.ts'\n\n/**\n * A quadratic path in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The `Trait` type parameter accumulates trait brands as the path is refined\n * via `isContinuous` / `asContinuous`.\n *\n * @since 1.0.0\n */\nexport interface QuadraticPath2d<out Trait = unknown> extends Pipeable, Iterable<QuadraticCurve2d> {\n readonly [QuadraticPath2dTypeId]: QuadraticPath2dTypeId\n readonly [PathTraits]: Trait\n}\n\n/**\n * Creates a new `QuadraticPath2d` instance from a sequence of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `QuadraticPath2d` instance.\n * @since 2.0.0\n */\nexport const make: (...curves: ReadonlyArray<QuadraticCurve2d>) => QuadraticPath2d = internal.make\n\n/**\n * Creates a new `QuadraticPath2d` instance from an array of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `QuadraticPath2d` instance.\n * @since 2.0.0\n */\nexport const fromArray: (curves: ReadonlyArray<QuadraticCurve2d>) => QuadraticPath2d =\n internal.fromArray\n\n/**\n * Checks if a value is a `QuadraticPath2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `QuadraticPath2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isQuadraticPath2d: (p: unknown) => p is QuadraticPath2d = internal.isQuadraticPath2d\n\nexport const append: {\n /**\n * Appends a quadratic curve to a quadratic path.\n *\n * @param c - The quadratic curve to append.\n * @returns A function that takes a quadratic path and returns a new quadratic path.\n * @since 1.0.0\n */\n (c: QuadraticCurve2d): (p: QuadraticPath2d) => QuadraticPath2d\n /**\n * Appends a quadratic curve to a quadratic path.\n *\n * @param p - The quadratic path to append to.\n * @param c - The quadratic curve to append.\n * @returns A new `QuadraticPath2d` instance with the appended curve.\n * @since 1.0.0\n */\n (p: QuadraticPath2d, c: QuadraticCurve2d): QuadraticPath2d\n} = internal.append\n\n/**\n * Calculates the length of a quadratic path.\n *\n * @param p - The quadratic path to calculate the length of.\n * @returns The length of the path.\n */\nexport const length: (p: QuadraticPath2d) => number = internal.length\n\nexport const solve: {\n /**\n * Solves a quadratic path at a given parameter.\n *\n * @param u - The parameter to solve for.\n * @returns A function that takes a quadratic path and returns the solved point.\n * @since 1.0.0\n */\n (u: number): (p: QuadraticPath2d) => Vector2\n /**\n * Solves a quadratic path at a given parameter.\n *\n * @param p - The quadratic path to solve.\n * @param u - The parameter to solve for.\n * @returns The solved point.\n * @since 1.0.0\n */\n (p: QuadraticPath2d, u: number): Vector2\n} = internal.solve\n\n/**\n * Serializes a quadratic path as an SVG path data string (the value of a\n * `<path>` element's `d` attribute), using `M` and `Q` commands. Discontinuities\n * between curves emit a fresh `M` command.\n *\n * @param p - The quadratic path to serialize.\n * @returns The SVG path data string.\n * @since 2.0.0\n */\nexport const toPathData: (p: QuadraticPath2d) => string = internal.toPathData\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & Continuous>` when adjacent curves connect.\n *\n * @since 2.0.0\n */\nexport const isContinuous: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & Continuous> =\n internal.isContinuous\n\n/**\n * Asserts that the quadratic path is continuous, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asContinuous: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & Continuous> =\n internal.asContinuous\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & IncreasingX>` when every segment's x-polynomial is\n * strictly increasing on `[0, 1]` and adjacent segments' x-ranges don't\n * overlap.\n *\n * @since 2.0.0\n */\nexport const isIncreasingX: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & IncreasingX> =\n internal.isIncreasingX\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & DecreasingX>`.\n *\n * @since 2.0.0\n */\nexport const isDecreasingX: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & DecreasingX> =\n internal.isDecreasingX\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & MonotonicX>`.\n *\n * @since 2.0.0\n */\nexport const isMonotonicX: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & MonotonicX> =\n internal.isMonotonicX\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & IncreasingY>`.\n *\n * @since 2.0.0\n */\nexport const isIncreasingY: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & IncreasingY> =\n internal.isIncreasingY\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & DecreasingY>`.\n *\n * @since 2.0.0\n */\nexport const isDecreasingY: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & DecreasingY> =\n internal.isDecreasingY\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & MonotonicY>`.\n *\n * @since 2.0.0\n */\nexport const isMonotonicY: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & MonotonicY> =\n internal.isMonotonicY\n\n/**\n * Asserts that the path is strictly increasing in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasingX: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & IncreasingX> =\n internal.asIncreasingX\n\n/**\n * Asserts that the path is strictly decreasing in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasingX: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & DecreasingX> =\n internal.asDecreasingX\n\n/**\n * Asserts that the path is monotonic in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asMonotonicX: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & MonotonicX> =\n internal.asMonotonicX\n\n/**\n * Asserts that the path is strictly increasing in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasingY: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & IncreasingY> =\n internal.asIncreasingY\n\n/**\n * Asserts that the path is strictly decreasing in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasingY: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & DecreasingY> =\n internal.asDecreasingY\n\n/**\n * Asserts that the path is monotonic in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asMonotonicY: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & MonotonicY> =\n internal.asMonotonicY\n\nexport const solveAtX: {\n /**\n * Evaluates the path's y value at a given x. Requires the path to carry\n * the `MonotonicX` brand. Returns `Solution.none` when x is outside the\n * path's x-range.\n *\n * @param p - A path branded `MonotonicX`.\n * @param x - The x coordinate.\n * @returns The y value at x, or `none` when x is outside the path's range.\n * @since 2.0.0\n */\n <T extends MonotonicX>(p: QuadraticPath2d<T>, x: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (x: number): <T extends MonotonicX>(p: QuadraticPath2d<T>) => Solution.AtMostOne<number>\n} = internal.solveAtX as never\n\nexport const solveAtY: {\n /**\n * Evaluates the path's x value at a given y. Requires the path to carry\n * the `MonotonicY` brand. Returns `Solution.none` when y is outside the\n * path's y-range.\n *\n * @param p - A path branded `MonotonicY`.\n * @param y - The y coordinate.\n * @returns The x value at y, or `none` when y is outside the path's range.\n * @since 2.0.0\n */\n <T extends MonotonicY>(p: QuadraticPath2d<T>, y: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (y: number): <T extends MonotonicY>(p: QuadraticPath2d<T>) => Solution.AtMostOne<number>\n} = internal.solveAtY as never\n\n/**\n * Computes the axis-aligned bounding box of the path — the smallest closed\n * `Box2d` enclosing every segment.\n *\n * @param p - The quadratic path.\n * @returns A closed `Box2d` enclosing the path.\n * @since 2.0.0\n */\nexport const boundingBox: (p: QuadraticPath2d) => Interval2d<Closed, Closed> = internal.boundingBox\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["isQuadraticPath2d","make","fromArray","append","length","QuadraticCurve2d.length","Interval.unit","solve","QuadraticCurve2d.solve","toPathData","isContinuous","asContinuous","isIncreasingX","QuadraticPolynomial.isIncreasing","isDecreasingX","QuadraticPolynomial.isDecreasing","isMonotonicX","isIncreasingY","isDecreasingY","isMonotonicY","asIncreasingX","asDecreasingX","asMonotonicX","asIncreasingY","asDecreasingY","asMonotonicY","solveAtX","Solution.one","QuadraticCurve2d.solveAtX","Solution.isNone","Solution.none","solveAtY","QuadraticCurve2d.solveAtY","boundingBox","QuadraticCurve2d.boundingBox","Interval2d.union","internal.make","internal.fromArray","internal.isQuadraticPath2d","internal.append","internal.length","internal.solve","internal.toPathData","internal.isContinuous","internal.asContinuous","internal.isIncreasingX","internal.isDecreasingX","internal.isMonotonicX","internal.isIncreasingY","internal.isDecreasingY","internal.isMonotonicY","internal.asIncreasingX","internal.asDecreasingX","internal.asMonotonicX","internal.asIncreasingY","internal.asDecreasingY","internal.asMonotonicY","internal.solveAtX","internal.solveAtY","internal.boundingBox"],"sources":["../../src/path/quadratic2d.internal.ts","../../src/path/quadratic2d.ts"],"sourcesContent":["import * as Interval2d from '../interval/interval2d.ts'\nimport * as QuadraticCurve2d from '../curve/quadratic2d.ts'\nimport * as Interval from '../interval/interval.ts'\nimport * as QuadraticPolynomial from '../polynomial/quadratic.ts'\nimport * as Solution from '../solution/solution.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport { invariant } from '../utils.ts'\nimport { EPSILON, epsEquals } from '../number.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { QuadraticPath2d } from './quadratic2d.ts'\nimport {\n PathTraits,\n type Continuous,\n type DecreasingX,\n type DecreasingY,\n type IncreasingX,\n type IncreasingY,\n type MonotonicX,\n type MonotonicY,\n} from './traits.ts'\n\nexport const QuadraticPath2dTypeId: unique symbol = Symbol('curvy/path/quadratic2d')\nexport type QuadraticPath2dTypeId = typeof QuadraticPath2dTypeId\n\n/** @internal */\nexport class QuadraticPath2dImpl extends Pipeable implements QuadraticPath2d<unknown> {\n readonly [QuadraticPath2dTypeId]: QuadraticPath2dTypeId = QuadraticPath2dTypeId\n declare readonly [PathTraits]: unknown\n\n readonly curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>\n\n constructor(curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>) {\n super()\n this.curves = curves\n }\n\n [Symbol.iterator](): Iterator<QuadraticCurve2d.QuadraticCurve2d> {\n return this.curves[Symbol.iterator]()\n }\n}\n\n/** @internal */\nexport const isQuadraticPath2d = (p: unknown): p is QuadraticPath2d =>\n typeof p === 'object' && p !== null && QuadraticPath2dTypeId in p\n\n/** @internal */\nexport const make = (\n ...curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>\n): QuadraticPath2d => new QuadraticPath2dImpl(curves)\n\n/** @internal */\nexport const fromArray = (\n curves: ReadonlyArray<QuadraticCurve2d.QuadraticCurve2d>,\n): QuadraticPath2d => new QuadraticPath2dImpl(curves)\n\n/** @internal */\nexport const append = dual<\n (c: QuadraticCurve2d.QuadraticCurve2d) => (p: QuadraticPath2d) => QuadraticPath2d,\n (p: QuadraticPath2d, c: QuadraticCurve2d.QuadraticCurve2d) => QuadraticPath2d\n>(2, (p: QuadraticPath2d, c: QuadraticCurve2d.QuadraticCurve2d) => fromArray([...p, c]))\n\n/** @internal */\nexport const length = (p: QuadraticPath2d) => {\n let total = 0\n for (const curve of p) {\n total += QuadraticCurve2d.length(curve, Interval.unit)\n }\n\n return total\n}\n\n/** @internal */\nexport const solve = dual<\n (u: number) => (p: QuadraticPath2d) => Vector2,\n (p: QuadraticPath2d, u: number) => Vector2\n>(2, (p: QuadraticPath2d, u: number) => {\n const curves = p instanceof QuadraticPath2dImpl ? p.curves : [...p]\n\n if (u === 1) {\n const last = curves.at(-1) as QuadraticCurve2d.QuadraticCurve2d\n return QuadraticCurve2d.solve(last, 1)\n }\n\n const t = u * curves.length\n const i = Math.floor(t)\n const curve = curves[i] as QuadraticCurve2d.QuadraticCurve2d\n return QuadraticCurve2d.solve(curve, t - i)\n})\n\n// Quadratic Bernstein basis: P(t) = (1-t)²·p0 + 2(1-t)t·p1 + t²·p2\n// expanded gives c0 = p0, c1 = -2p0 + 2p1, c2 = p0 - 2p1 + p2, so:\n// p0 = c0, p1 = c0 + c1/2, p2 = c0 + c1 + c2.\n/** @internal */\nexport const toPathData = (p: QuadraticPath2d): string => {\n let result = ''\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n\n for (const curve of p) {\n const c0x = curve.x.c0\n const c0y = curve.y.c0\n const c1x = curve.x.c1\n const c1y = curve.y.c1\n const c2x = curve.x.c2\n const c2y = curve.y.c2\n\n const startX = c0x\n const startY = c0y\n const ctrlX = c0x + c1x / 2\n const ctrlY = c0y + c1y / 2\n const endX = c0x + c1x + c2x\n const endY = c0y + c1y + c2y\n\n if (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY)) {\n result += ` M ${startX},${startY}`\n }\n result += ` Q ${ctrlX},${ctrlY} ${endX},${endY}`\n\n prevEndX = endX\n prevEndY = endY\n }\n\n return result.slice(1)\n}\n\n/** @internal */\nexport const isContinuous = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & Continuous> => {\n let prevEndX = Number.NaN\n let prevEndY = Number.NaN\n let first = true\n\n for (const curve of p) {\n const startX = curve.x.c0\n const startY = curve.y.c0\n if (!first && (!epsEquals(startX, prevEndX) || !epsEquals(startY, prevEndY))) {\n return false\n }\n prevEndX = curve.x.c0 + curve.x.c1 + curve.x.c2\n prevEndY = curve.y.c0 + curve.y.c1 + curve.y.c2\n first = false\n }\n return true\n}\n\n/** @internal */\nexport const asContinuous = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & Continuous> => {\n invariant(isContinuous(p), 'quadratic path is not continuous')\n return p\n}\n\n// Per-axis monotonicity for the path: every segment's axis polynomial must be\n// strictly monotonic over the unit interval AND adjacent segments' axis\n// ranges must not overlap (modulo EPSILON for float drift).\n/** @internal */\nexport const isIncreasingX = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & IncreasingX> => {\n let prevEnd = Number.NEGATIVE_INFINITY\n for (const c of p) {\n if (!QuadraticPolynomial.isIncreasing(c.x, Interval.unit)) {\n return false\n }\n if (c.x.c0 < prevEnd - EPSILON) {\n return false\n }\n prevEnd = c.x.c0 + c.x.c1 + c.x.c2\n }\n return true\n}\n\n/** @internal */\nexport const isDecreasingX = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & DecreasingX> => {\n let prevEnd = Number.POSITIVE_INFINITY\n for (const c of p) {\n if (!QuadraticPolynomial.isDecreasing(c.x, Interval.unit)) {\n return false\n }\n if (c.x.c0 > prevEnd + EPSILON) {\n return false\n }\n prevEnd = c.x.c0 + c.x.c1 + c.x.c2\n }\n return true\n}\n\n/** @internal */\nexport const isMonotonicX = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & MonotonicX> =>\n isIncreasingX(p) || isDecreasingX(p)\n\n/** @internal */\nexport const isIncreasingY = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & IncreasingY> => {\n let prevEnd = Number.NEGATIVE_INFINITY\n for (const c of p) {\n if (!QuadraticPolynomial.isIncreasing(c.y, Interval.unit)) {\n return false\n }\n if (c.y.c0 < prevEnd - EPSILON) {\n return false\n }\n prevEnd = c.y.c0 + c.y.c1 + c.y.c2\n }\n return true\n}\n\n/** @internal */\nexport const isDecreasingY = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & DecreasingY> => {\n let prevEnd = Number.POSITIVE_INFINITY\n for (const c of p) {\n if (!QuadraticPolynomial.isDecreasing(c.y, Interval.unit)) {\n return false\n }\n if (c.y.c0 > prevEnd + EPSILON) {\n return false\n }\n prevEnd = c.y.c0 + c.y.c1 + c.y.c2\n }\n return true\n}\n\n/** @internal */\nexport const isMonotonicY = <T>(p: QuadraticPath2d<T>): p is QuadraticPath2d<T & MonotonicY> =>\n isIncreasingY(p) || isDecreasingY(p)\n\n/** @internal */\nexport const asIncreasingX = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & IncreasingX> => {\n invariant(isIncreasingX(p), 'quadratic path is not increasing in x')\n return p\n}\n\n/** @internal */\nexport const asDecreasingX = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & DecreasingX> => {\n invariant(isDecreasingX(p), 'quadratic path is not decreasing in x')\n return p\n}\n\n/** @internal */\nexport const asMonotonicX = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & MonotonicX> => {\n invariant(isMonotonicX(p), 'quadratic path is not monotonic in x')\n return p\n}\n\n/** @internal */\nexport const asIncreasingY = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & IncreasingY> => {\n invariant(isIncreasingY(p), 'quadratic path is not increasing in y')\n return p\n}\n\n/** @internal */\nexport const asDecreasingY = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & DecreasingY> => {\n invariant(isDecreasingY(p), 'quadratic path is not decreasing in y')\n return p\n}\n\n/** @internal */\nexport const asMonotonicY = <T>(p: QuadraticPath2d<T>): QuadraticPath2d<T & MonotonicY> => {\n invariant(isMonotonicY(p), 'quadratic path is not monotonic in y')\n return p\n}\n\n// solveAtX/Y on a monotonic-axis path. Two defenses against float drift at\n// interior knots, where two adjacent segments both bracket the query and the\n// polynomial-inverse solver may return `none` for both:\n// 1. Snap to t=0/t=1 endpoint y when the query is within EPSILON of a\n// segment's start or end — bypasses polynomial inversion at knots.\n// 2. Fall through to the next bracketing segment on `none`. `MonotonicX/Y`\n// admits at most one real solution across the path, so retrying is safe.\n/** @internal */\nexport const solveAtX = dual(2, (p: QuadraticPath2d, x: number): Solution.AtMostOne<number> => {\n for (const c of p) {\n const sx = c.x.c0\n const ex = c.x.c0 + c.x.c1 + c.x.c2\n const lo = Math.min(sx, ex)\n const hi = Math.max(sx, ex)\n if (x >= lo - EPSILON && x <= hi + EPSILON) {\n if (epsEquals(x, sx)) {\n return Solution.one(c.y.c0)\n }\n if (epsEquals(x, ex)) {\n return Solution.one(c.y.c0 + c.y.c1 + c.y.c2)\n }\n const sol = QuadraticCurve2d.solveAtX(c, x) as Solution.AtMostOne<number>\n if (!Solution.isNone(sol)) {\n return sol\n }\n }\n }\n return Solution.none\n})\n\n/** @internal */\nexport const solveAtY = dual(2, (p: QuadraticPath2d, y: number): Solution.AtMostOne<number> => {\n for (const c of p) {\n const sy = c.y.c0\n const ey = c.y.c0 + c.y.c1 + c.y.c2\n const lo = Math.min(sy, ey)\n const hi = Math.max(sy, ey)\n if (y >= lo - EPSILON && y <= hi + EPSILON) {\n if (epsEquals(y, sy)) {\n return Solution.one(c.x.c0)\n }\n if (epsEquals(y, ey)) {\n return Solution.one(c.x.c0 + c.x.c1 + c.x.c2)\n }\n const sol = QuadraticCurve2d.solveAtY(c, y) as Solution.AtMostOne<number>\n if (!Solution.isNone(sol)) {\n return sol\n }\n }\n }\n return Solution.none\n})\n\n/** @internal */\nexport const boundingBox = (\n p: QuadraticPath2d,\n): Interval2d.Interval2d<Interval.Closed, Interval.Closed> => {\n const iter = p[Symbol.iterator]()\n const first = iter.next()\n let acc = QuadraticCurve2d.boundingBox(first.value as QuadraticCurve2d.QuadraticCurve2d)\n for (let next = iter.next(); !next.done; next = iter.next()) {\n acc = Interval2d.union(acc, QuadraticCurve2d.boundingBox(next.value))\n }\n return acc\n}\n","import type { Interval2d } from '../interval/interval2d.ts'\nimport type { QuadraticCurve2d } from '../curve/quadratic2d.ts'\nimport type { Closed } from '../interval/interval.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { QuadraticPath2dTypeId } from './quadratic2d.internal.ts'\nimport * as internal from './quadratic2d.internal.ts'\nimport type {\n Continuous,\n DecreasingX,\n DecreasingY,\n IncreasingX,\n IncreasingY,\n MonotonicX,\n MonotonicY,\n PathTraits,\n} from './traits.ts'\n\nexport type {\n Continuous,\n DecreasingX,\n DecreasingY,\n IncreasingX,\n IncreasingY,\n MonotonicX,\n MonotonicY,\n} from './traits.ts'\n\n/**\n * A quadratic path in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The `Trait` type parameter accumulates trait brands as the path is refined\n * via `isContinuous` / `asContinuous`.\n *\n * @since 1.0.0\n */\nexport interface QuadraticPath2d<out Trait = unknown> extends Pipeable, Iterable<QuadraticCurve2d> {\n readonly [QuadraticPath2dTypeId]: QuadraticPath2dTypeId\n readonly [PathTraits]: Trait\n}\n\n/**\n * Creates a new `QuadraticPath2d` instance from a sequence of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `QuadraticPath2d` instance.\n * @since 2.0.0\n */\nexport const make: (...curves: ReadonlyArray<QuadraticCurve2d>) => QuadraticPath2d = internal.make\n\n/**\n * Creates a new `QuadraticPath2d` instance from an array of curves.\n *\n * @param curves - The curves to create the path from.\n * @returns A new `QuadraticPath2d` instance.\n * @since 2.0.0\n */\nexport const fromArray: (curves: ReadonlyArray<QuadraticCurve2d>) => QuadraticPath2d =\n internal.fromArray\n\n/**\n * Checks if a value is a `QuadraticPath2d`.\n *\n * @param p - The value to check.\n * @returns `true` if the value is a `QuadraticPath2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isQuadraticPath2d: (p: unknown) => p is QuadraticPath2d = internal.isQuadraticPath2d\n\nexport const append: {\n /**\n * Appends a quadratic curve to a quadratic path.\n *\n * @param c - The quadratic curve to append.\n * @returns A function that takes a quadratic path and returns a new quadratic path.\n * @since 1.0.0\n */\n (c: QuadraticCurve2d): (p: QuadraticPath2d) => QuadraticPath2d\n /**\n * Appends a quadratic curve to a quadratic path.\n *\n * @param p - The quadratic path to append to.\n * @param c - The quadratic curve to append.\n * @returns A new `QuadraticPath2d` instance with the appended curve.\n * @since 1.0.0\n */\n (p: QuadraticPath2d, c: QuadraticCurve2d): QuadraticPath2d\n} = internal.append\n\n/**\n * Calculates the length of a quadratic path.\n *\n * @param p - The quadratic path to calculate the length of.\n * @returns The length of the path.\n */\nexport const length: (p: QuadraticPath2d) => number = internal.length\n\nexport const solve: {\n /**\n * Solves a quadratic path at a given parameter.\n *\n * @param u - The parameter to solve for.\n * @returns A function that takes a quadratic path and returns the solved point.\n * @since 1.0.0\n */\n (u: number): (p: QuadraticPath2d) => Vector2\n /**\n * Solves a quadratic path at a given parameter.\n *\n * @param p - The quadratic path to solve.\n * @param u - The parameter to solve for.\n * @returns The solved point.\n * @since 1.0.0\n */\n (p: QuadraticPath2d, u: number): Vector2\n} = internal.solve\n\n/**\n * Serializes a quadratic path as an SVG path data string (the value of a\n * `<path>` element's `d` attribute), using `M` and `Q` commands. Discontinuities\n * between curves emit a fresh `M` command.\n *\n * @param p - The quadratic path to serialize.\n * @returns The SVG path data string.\n * @since 2.0.0\n */\nexport const toPathData: (p: QuadraticPath2d) => string = internal.toPathData\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & Continuous>` when adjacent curves connect.\n *\n * @since 2.0.0\n */\nexport const isContinuous: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & Continuous> =\n internal.isContinuous\n\n/**\n * Asserts that the quadratic path is continuous, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asContinuous: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & Continuous> =\n internal.asContinuous\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & IncreasingX>` when every segment's x-polynomial is\n * strictly increasing on `[0, 1]` and adjacent segments' x-ranges don't\n * overlap.\n *\n * @since 2.0.0\n */\nexport const isIncreasingX: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & IncreasingX> =\n internal.isIncreasingX\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & DecreasingX>`.\n *\n * @since 2.0.0\n */\nexport const isDecreasingX: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & DecreasingX> =\n internal.isDecreasingX\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & MonotonicX>`.\n *\n * @since 2.0.0\n */\nexport const isMonotonicX: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & MonotonicX> =\n internal.isMonotonicX\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & IncreasingY>`.\n *\n * @since 2.0.0\n */\nexport const isIncreasingY: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & IncreasingY> =\n internal.isIncreasingY\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & DecreasingY>`.\n *\n * @since 2.0.0\n */\nexport const isDecreasingY: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & DecreasingY> =\n internal.isDecreasingY\n\n/**\n * Type-narrowing predicate: refines `QuadraticPath2d<T>` to\n * `QuadraticPath2d<T & MonotonicY>`.\n *\n * @since 2.0.0\n */\nexport const isMonotonicY: <T>(p: QuadraticPath2d<T>) => p is QuadraticPath2d<T & MonotonicY> =\n internal.isMonotonicY\n\n/**\n * Asserts that the path is strictly increasing in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasingX: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & IncreasingX> =\n internal.asIncreasingX\n\n/**\n * Asserts that the path is strictly decreasing in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasingX: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & DecreasingX> =\n internal.asDecreasingX\n\n/**\n * Asserts that the path is monotonic in x, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asMonotonicX: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & MonotonicX> =\n internal.asMonotonicX\n\n/**\n * Asserts that the path is strictly increasing in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasingY: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & IncreasingY> =\n internal.asIncreasingY\n\n/**\n * Asserts that the path is strictly decreasing in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasingY: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & DecreasingY> =\n internal.asDecreasingY\n\n/**\n * Asserts that the path is monotonic in y, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asMonotonicY: <T>(p: QuadraticPath2d<T>) => QuadraticPath2d<T & MonotonicY> =\n internal.asMonotonicY\n\nexport const solveAtX: {\n /**\n * Evaluates the path's y value at a given x. Requires the path to carry\n * the `MonotonicX` brand. Returns `Solution.none` when x is outside the\n * path's x-range.\n *\n * @param p - A path branded `MonotonicX`.\n * @param x - The x coordinate.\n * @returns The y value at x, or `none` when x is outside the path's range.\n * @since 2.0.0\n */\n <T extends MonotonicX>(p: QuadraticPath2d<T>, x: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (x: number): <T extends MonotonicX>(p: QuadraticPath2d<T>) => Solution.AtMostOne<number>\n} = internal.solveAtX as never\n\nexport const solveAtY: {\n /**\n * Evaluates the path's x value at a given y. Requires the path to carry\n * the `MonotonicY` brand. Returns `Solution.none` when y is outside the\n * path's y-range.\n *\n * @param p - A path branded `MonotonicY`.\n * @param y - The y coordinate.\n * @returns The x value at y, or `none` when y is outside the path's range.\n * @since 2.0.0\n */\n <T extends MonotonicY>(p: QuadraticPath2d<T>, y: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (y: number): <T extends MonotonicY>(p: QuadraticPath2d<T>) => Solution.AtMostOne<number>\n} = internal.solveAtY as never\n\n/**\n * Computes the axis-aligned bounding box of the path — the smallest closed\n * `Box2d` enclosing every segment.\n *\n * @param p - The quadratic path.\n * @returns A closed `Box2d` enclosing the path.\n * @since 2.0.0\n */\nexport const boundingBox: (p: QuadraticPath2d) => Interval2d<Closed, Closed> = internal.boundingBox\n"],"mappings":"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"}