@emasoft/svg-matrix 1.1.0 → 1.2.0

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 (55) hide show
  1. package/bin/svg-matrix.js +7 -6
  2. package/bin/svgm.js +109 -40
  3. package/dist/svg-matrix.min.js +7 -7
  4. package/dist/svg-toolbox.min.js +148 -228
  5. package/dist/svgm.min.js +152 -232
  6. package/dist/version.json +5 -5
  7. package/package.json +1 -1
  8. package/scripts/postinstall.js +72 -41
  9. package/scripts/test-postinstall.js +18 -16
  10. package/scripts/version-sync.js +78 -60
  11. package/src/animation-optimization.js +190 -98
  12. package/src/animation-references.js +11 -3
  13. package/src/arc-length.js +23 -20
  14. package/src/bezier-analysis.js +9 -13
  15. package/src/bezier-intersections.js +18 -4
  16. package/src/browser-verify.js +35 -8
  17. package/src/clip-path-resolver.js +285 -114
  18. package/src/convert-path-data.js +20 -8
  19. package/src/css-specificity.js +33 -9
  20. package/src/douglas-peucker.js +272 -141
  21. package/src/geometry-to-path.js +79 -22
  22. package/src/gjk-collision.js +287 -126
  23. package/src/index.js +56 -21
  24. package/src/inkscape-support.js +122 -101
  25. package/src/logger.js +43 -27
  26. package/src/marker-resolver.js +201 -121
  27. package/src/mask-resolver.js +231 -98
  28. package/src/matrix.js +9 -5
  29. package/src/mesh-gradient.js +22 -14
  30. package/src/off-canvas-detection.js +53 -17
  31. package/src/path-optimization.js +356 -171
  32. package/src/path-simplification.js +671 -256
  33. package/src/pattern-resolver.js +1 -3
  34. package/src/polygon-clip.js +396 -78
  35. package/src/svg-boolean-ops.js +90 -23
  36. package/src/svg-collections.js +1546 -667
  37. package/src/svg-flatten.js +152 -38
  38. package/src/svg-matrix-lib.js +2 -2
  39. package/src/svg-parser.js +5 -1
  40. package/src/svg-rendering-context.js +3 -1
  41. package/src/svg-toolbox-lib.js +2 -2
  42. package/src/svg-toolbox.js +99 -457
  43. package/src/svg-validation-data.js +513 -345
  44. package/src/svg2-polyfills.js +156 -93
  45. package/src/svgm-lib.js +8 -4
  46. package/src/transform-optimization.js +168 -51
  47. package/src/transforms2d.js +73 -40
  48. package/src/transforms3d.js +34 -27
  49. package/src/use-symbol-resolver.js +175 -76
  50. package/src/vector.js +80 -44
  51. package/src/vendor/inkscape-hatch-polyfill.js +143 -108
  52. package/src/vendor/inkscape-hatch-polyfill.min.js +291 -1
  53. package/src/vendor/inkscape-mesh-polyfill.js +953 -766
  54. package/src/vendor/inkscape-mesh-polyfill.min.js +896 -1
  55. package/src/verification.js +3 -4
@@ -29,16 +29,16 @@
29
29
  * @module gjk-collision
30
30
  */
31
31
 
32
- import Decimal from 'decimal.js';
32
+ import Decimal from "decimal.js";
33
33
 
34
34
  // Set high precision for all calculations
35
35
  Decimal.set({ precision: 80 });
36
36
 
37
37
  // Helper to convert to Decimal
38
- const D = x => (x instanceof Decimal ? x : new Decimal(x));
38
+ const D = (x) => (x instanceof Decimal ? x : new Decimal(x));
39
39
 
40
40
  // Near-zero threshold for comparisons
41
- const EPSILON = new Decimal('1e-40');
41
+ const EPSILON = new Decimal("1e-40");
42
42
 
43
43
  // Maximum iterations to prevent infinite loops
44
44
  const MAX_ITERATIONS = 100;
@@ -55,8 +55,10 @@ const MAX_ITERATIONS = 100;
55
55
  * @throws {TypeError} If x or y is null or undefined
56
56
  */
57
57
  export function point(x, y) {
58
- if (x == null) throw new TypeError('point: x coordinate cannot be null or undefined');
59
- if (y == null) throw new TypeError('point: y coordinate cannot be null or undefined');
58
+ if (x == null)
59
+ throw new TypeError("point: x coordinate cannot be null or undefined");
60
+ if (y == null)
61
+ throw new TypeError("point: y coordinate cannot be null or undefined");
60
62
  return { x: D(x), y: D(y) };
61
63
  }
62
64
 
@@ -68,8 +70,12 @@ export function point(x, y) {
68
70
  * @throws {TypeError} If a or b is invalid or missing x/y properties
69
71
  */
70
72
  export function vectorAdd(a, b) {
71
- if (!a || a.x == null || a.y == null) throw new TypeError('vectorAdd: first vector must have x and y properties');
72
- if (!b || b.x == null || b.y == null) throw new TypeError('vectorAdd: second vector must have x and y properties');
73
+ if (!a || a.x == null || a.y == null)
74
+ throw new TypeError("vectorAdd: first vector must have x and y properties");
75
+ if (!b || b.x == null || b.y == null)
76
+ throw new TypeError(
77
+ "vectorAdd: second vector must have x and y properties",
78
+ );
73
79
  return { x: a.x.plus(b.x), y: a.y.plus(b.y) };
74
80
  }
75
81
 
@@ -81,8 +87,12 @@ export function vectorAdd(a, b) {
81
87
  * @throws {TypeError} If a or b is invalid or missing x/y properties
82
88
  */
83
89
  export function vectorSub(a, b) {
84
- if (!a || a.x == null || a.y == null) throw new TypeError('vectorSub: first vector must have x and y properties');
85
- if (!b || b.x == null || b.y == null) throw new TypeError('vectorSub: second vector must have x and y properties');
90
+ if (!a || a.x == null || a.y == null)
91
+ throw new TypeError("vectorSub: first vector must have x and y properties");
92
+ if (!b || b.x == null || b.y == null)
93
+ throw new TypeError(
94
+ "vectorSub: second vector must have x and y properties",
95
+ );
86
96
  return { x: a.x.minus(b.x), y: a.y.minus(b.y) };
87
97
  }
88
98
 
@@ -93,7 +103,8 @@ export function vectorSub(a, b) {
93
103
  * @throws {TypeError} If v is invalid or missing x/y properties
94
104
  */
95
105
  export function vectorNeg(v) {
96
- if (!v || v.x == null || v.y == null) throw new TypeError('vectorNeg: vector must have x and y properties');
106
+ if (!v || v.x == null || v.y == null)
107
+ throw new TypeError("vectorNeg: vector must have x and y properties");
97
108
  return { x: v.x.neg(), y: v.y.neg() };
98
109
  }
99
110
 
@@ -105,8 +116,12 @@ export function vectorNeg(v) {
105
116
  * @throws {TypeError} If v is invalid, missing x/y properties, or s is null/undefined
106
117
  */
107
118
  export function vectorScale(v, s) {
108
- if (!v || v.x == null || v.y == null) throw new TypeError('vectorScale: vector must have x and y properties');
109
- if (s == null) throw new TypeError('vectorScale: scale factor cannot be null or undefined');
119
+ if (!v || v.x == null || v.y == null)
120
+ throw new TypeError("vectorScale: vector must have x and y properties");
121
+ if (s == null)
122
+ throw new TypeError(
123
+ "vectorScale: scale factor cannot be null or undefined",
124
+ );
110
125
  const sd = D(s);
111
126
  return { x: v.x.mul(sd), y: v.y.mul(sd) };
112
127
  }
@@ -119,8 +134,10 @@ export function vectorScale(v, s) {
119
134
  * @throws {TypeError} If a or b is invalid or missing x/y properties
120
135
  */
121
136
  export function dot(a, b) {
122
- if (!a || a.x == null || a.y == null) throw new TypeError('dot: first vector must have x and y properties');
123
- if (!b || b.x == null || b.y == null) throw new TypeError('dot: second vector must have x and y properties');
137
+ if (!a || a.x == null || a.y == null)
138
+ throw new TypeError("dot: first vector must have x and y properties");
139
+ if (!b || b.x == null || b.y == null)
140
+ throw new TypeError("dot: second vector must have x and y properties");
124
141
  return a.x.mul(b.x).plus(a.y.mul(b.y));
125
142
  }
126
143
 
@@ -132,8 +149,10 @@ export function dot(a, b) {
132
149
  * @throws {TypeError} If a or b is invalid or missing x/y properties
133
150
  */
134
151
  export function cross(a, b) {
135
- if (!a || a.x == null || a.y == null) throw new TypeError('cross: first vector must have x and y properties');
136
- if (!b || b.x == null || b.y == null) throw new TypeError('cross: second vector must have x and y properties');
152
+ if (!a || a.x == null || a.y == null)
153
+ throw new TypeError("cross: first vector must have x and y properties");
154
+ if (!b || b.x == null || b.y == null)
155
+ throw new TypeError("cross: second vector must have x and y properties");
137
156
  return a.x.mul(b.y).minus(a.y.mul(b.x));
138
157
  }
139
158
 
@@ -144,7 +163,10 @@ export function cross(a, b) {
144
163
  * @throws {TypeError} If v is invalid or missing x/y properties
145
164
  */
146
165
  export function magnitudeSquared(v) {
147
- if (!v || v.x == null || v.y == null) throw new TypeError('magnitudeSquared: vector must have x and y properties');
166
+ if (!v || v.x == null || v.y == null)
167
+ throw new TypeError(
168
+ "magnitudeSquared: vector must have x and y properties",
169
+ );
148
170
  return v.x.mul(v.x).plus(v.y.mul(v.y));
149
171
  }
150
172
 
@@ -155,7 +177,8 @@ export function magnitudeSquared(v) {
155
177
  * @throws {TypeError} If v is invalid or missing x/y properties
156
178
  */
157
179
  export function magnitude(v) {
158
- if (!v || v.x == null || v.y == null) throw new TypeError('magnitude: vector must have x and y properties');
180
+ if (!v || v.x == null || v.y == null)
181
+ throw new TypeError("magnitude: vector must have x and y properties");
159
182
  return magnitudeSquared(v).sqrt();
160
183
  }
161
184
 
@@ -166,7 +189,8 @@ export function magnitude(v) {
166
189
  * @throws {TypeError} If v is invalid or missing x/y properties
167
190
  */
168
191
  export function normalize(v) {
169
- if (!v || v.x == null || v.y == null) throw new TypeError('normalize: vector must have x and y properties');
192
+ if (!v || v.x == null || v.y == null)
193
+ throw new TypeError("normalize: vector must have x and y properties");
170
194
  const mag = magnitude(v);
171
195
  if (mag.lessThan(EPSILON)) {
172
196
  return { x: D(0), y: D(0) };
@@ -181,7 +205,8 @@ export function normalize(v) {
181
205
  * @throws {TypeError} If v is invalid or missing x/y properties
182
206
  */
183
207
  export function perpendicular(v) {
184
- if (!v || v.x == null || v.y == null) throw new TypeError('perpendicular: vector must have x and y properties');
208
+ if (!v || v.x == null || v.y == null)
209
+ throw new TypeError("perpendicular: vector must have x and y properties");
185
210
  return { x: v.y.neg(), y: v.x };
186
211
  }
187
212
 
@@ -195,9 +220,18 @@ export function perpendicular(v) {
195
220
  * @throws {TypeError} If any vector is invalid or missing x/y properties
196
221
  */
197
222
  export function tripleProduct(a, b, c) {
198
- if (!a || a.x == null || a.y == null) throw new TypeError('tripleProduct: first vector must have x and y properties');
199
- if (!b || b.x == null || b.y == null) throw new TypeError('tripleProduct: second vector must have x and y properties');
200
- if (!c || c.x == null || c.y == null) throw new TypeError('tripleProduct: third vector must have x and y properties');
223
+ if (!a || a.x == null || a.y == null)
224
+ throw new TypeError(
225
+ "tripleProduct: first vector must have x and y properties",
226
+ );
227
+ if (!b || b.x == null || b.y == null)
228
+ throw new TypeError(
229
+ "tripleProduct: second vector must have x and y properties",
230
+ );
231
+ if (!c || c.x == null || c.y == null)
232
+ throw new TypeError(
233
+ "tripleProduct: third vector must have x and y properties",
234
+ );
201
235
  // In 2D: (A × B) × C = B(A·C) - A(B·C)
202
236
  const ac = dot(a, c);
203
237
  const bc = dot(b, c);
@@ -220,15 +254,19 @@ export function tripleProduct(a, b, c) {
220
254
  * @throws {TypeError} If polygon is not an array or direction is invalid
221
255
  */
222
256
  export function supportPoint(polygon, direction) {
223
- if (!Array.isArray(polygon)) throw new TypeError('supportPoint: polygon must be an array');
224
- if (!direction || direction.x == null || direction.y == null) throw new TypeError('supportPoint: direction must have x and y properties');
257
+ if (!Array.isArray(polygon))
258
+ throw new TypeError("supportPoint: polygon must be an array");
259
+ if (!direction || direction.x == null || direction.y == null)
260
+ throw new TypeError("supportPoint: direction must have x and y properties");
225
261
  if (polygon.length === 0) {
226
- throw new TypeError('supportPoint: polygon cannot be empty');
262
+ throw new TypeError("supportPoint: polygon cannot be empty");
227
263
  }
228
264
 
229
265
  // Validate first point
230
266
  if (!polygon[0] || polygon[0].x == null || polygon[0].y == null) {
231
- throw new TypeError('supportPoint: polygon[0] must have x and y properties');
267
+ throw new TypeError(
268
+ "supportPoint: polygon[0] must have x and y properties",
269
+ );
232
270
  }
233
271
 
234
272
  let maxDot = dot(polygon[0], direction);
@@ -236,7 +274,9 @@ export function supportPoint(polygon, direction) {
236
274
 
237
275
  for (let i = 1; i < polygon.length; i++) {
238
276
  if (!polygon[i] || polygon[i].x == null || polygon[i].y == null) {
239
- throw new TypeError(`supportPoint: polygon[${i}] must have x and y properties`);
277
+ throw new TypeError(
278
+ `supportPoint: polygon[${i}] must have x and y properties`,
279
+ );
240
280
  }
241
281
  const d = dot(polygon[i], direction);
242
282
  if (d.greaterThan(maxDot)) {
@@ -261,9 +301,14 @@ export function supportPoint(polygon, direction) {
261
301
  * @throws {TypeError} If polygons are not arrays or direction is invalid
262
302
  */
263
303
  export function minkowskiSupport(polygonA, polygonB, direction) {
264
- if (!Array.isArray(polygonA)) throw new TypeError('minkowskiSupport: polygonA must be an array');
265
- if (!Array.isArray(polygonB)) throw new TypeError('minkowskiSupport: polygonB must be an array');
266
- if (!direction || direction.x == null || direction.y == null) throw new TypeError('minkowskiSupport: direction must have x and y properties');
304
+ if (!Array.isArray(polygonA))
305
+ throw new TypeError("minkowskiSupport: polygonA must be an array");
306
+ if (!Array.isArray(polygonB))
307
+ throw new TypeError("minkowskiSupport: polygonB must be an array");
308
+ if (!direction || direction.x == null || direction.y == null)
309
+ throw new TypeError(
310
+ "minkowskiSupport: direction must have x and y properties",
311
+ );
267
312
  const pointA = supportPoint(polygonA, direction);
268
313
  const pointB = supportPoint(polygonB, vectorNeg(direction));
269
314
  return vectorSub(pointA, pointB);
@@ -286,11 +331,24 @@ export function minkowskiSupport(polygonA, polygonB, direction) {
286
331
  * @throws {TypeError} If simplex is not an array, has wrong length, or direction is invalid
287
332
  */
288
333
  export function processLineSimplex(simplex, direction) {
289
- if (!Array.isArray(simplex)) throw new TypeError('processLineSimplex: simplex must be an array');
290
- if (simplex.length !== 2) throw new TypeError('processLineSimplex: simplex must have exactly 2 points');
291
- if (!direction || direction.x == null || direction.y == null) throw new TypeError('processLineSimplex: direction must have x and y properties');
292
- if (!simplex[0] || simplex[0].x == null || simplex[0].y == null) throw new TypeError('processLineSimplex: simplex[0] must have x and y properties');
293
- if (!simplex[1] || simplex[1].x == null || simplex[1].y == null) throw new TypeError('processLineSimplex: simplex[1] must have x and y properties');
334
+ if (!Array.isArray(simplex))
335
+ throw new TypeError("processLineSimplex: simplex must be an array");
336
+ if (simplex.length !== 2)
337
+ throw new TypeError(
338
+ "processLineSimplex: simplex must have exactly 2 points",
339
+ );
340
+ if (!direction || direction.x == null || direction.y == null)
341
+ throw new TypeError(
342
+ "processLineSimplex: direction must have x and y properties",
343
+ );
344
+ if (!simplex[0] || simplex[0].x == null || simplex[0].y == null)
345
+ throw new TypeError(
346
+ "processLineSimplex: simplex[0] must have x and y properties",
347
+ );
348
+ if (!simplex[1] || simplex[1].x == null || simplex[1].y == null)
349
+ throw new TypeError(
350
+ "processLineSimplex: simplex[1] must have x and y properties",
351
+ );
294
352
  const A = simplex[0]; // Newest point
295
353
  const B = simplex[1];
296
354
 
@@ -317,7 +375,10 @@ export function processLineSimplex(simplex, direction) {
317
375
  // Origin is on the line - check if between A and B
318
376
  const dotAB_AO = dot(AB, AO);
319
377
 
320
- if (dotAB_AO.greaterThanOrEqualTo(0) && dotAB_AO.lessThanOrEqualTo(ABmagSq)) {
378
+ if (
379
+ dotAB_AO.greaterThanOrEqualTo(0) &&
380
+ dotAB_AO.lessThanOrEqualTo(ABmagSq)
381
+ ) {
321
382
  // Origin is on the segment - we have intersection
322
383
  return { contains: true, newDirection: direction };
323
384
  }
@@ -343,12 +404,28 @@ export function processLineSimplex(simplex, direction) {
343
404
  * @throws {TypeError} If simplex is not an array, has wrong length, or direction is invalid
344
405
  */
345
406
  export function processTriangleSimplex(simplex, direction) {
346
- if (!Array.isArray(simplex)) throw new TypeError('processTriangleSimplex: simplex must be an array');
347
- if (simplex.length !== 3) throw new TypeError('processTriangleSimplex: simplex must have exactly 3 points');
348
- if (!direction || direction.x == null || direction.y == null) throw new TypeError('processTriangleSimplex: direction must have x and y properties');
349
- if (!simplex[0] || simplex[0].x == null || simplex[0].y == null) throw new TypeError('processTriangleSimplex: simplex[0] must have x and y properties');
350
- if (!simplex[1] || simplex[1].x == null || simplex[1].y == null) throw new TypeError('processTriangleSimplex: simplex[1] must have x and y properties');
351
- if (!simplex[2] || simplex[2].x == null || simplex[2].y == null) throw new TypeError('processTriangleSimplex: simplex[2] must have x and y properties');
407
+ if (!Array.isArray(simplex))
408
+ throw new TypeError("processTriangleSimplex: simplex must be an array");
409
+ if (simplex.length !== 3)
410
+ throw new TypeError(
411
+ "processTriangleSimplex: simplex must have exactly 3 points",
412
+ );
413
+ if (!direction || direction.x == null || direction.y == null)
414
+ throw new TypeError(
415
+ "processTriangleSimplex: direction must have x and y properties",
416
+ );
417
+ if (!simplex[0] || simplex[0].x == null || simplex[0].y == null)
418
+ throw new TypeError(
419
+ "processTriangleSimplex: simplex[0] must have x and y properties",
420
+ );
421
+ if (!simplex[1] || simplex[1].x == null || simplex[1].y == null)
422
+ throw new TypeError(
423
+ "processTriangleSimplex: simplex[1] must have x and y properties",
424
+ );
425
+ if (!simplex[2] || simplex[2].x == null || simplex[2].y == null)
426
+ throw new TypeError(
427
+ "processTriangleSimplex: simplex[2] must have x and y properties",
428
+ );
352
429
  const A = simplex[0]; // Newest point
353
430
  const B = simplex[1];
354
431
  const C = simplex[2];
@@ -366,7 +443,7 @@ export function processTriangleSimplex(simplex, direction) {
366
443
  return {
367
444
  contains: false,
368
445
  newDirection: tripleProduct(AC, AO, AC),
369
- newSimplex: [A, C]
446
+ newSimplex: [A, C],
370
447
  };
371
448
  }
372
449
 
@@ -375,7 +452,7 @@ export function processTriangleSimplex(simplex, direction) {
375
452
  return {
376
453
  contains: false,
377
454
  newDirection: tripleProduct(AB, AO, AB),
378
- newSimplex: [A, B]
455
+ newSimplex: [A, B],
379
456
  };
380
457
  }
381
458
 
@@ -384,7 +461,10 @@ export function processTriangleSimplex(simplex, direction) {
384
461
  const ACperp = tripleProduct(AB, AC, AC);
385
462
 
386
463
  // Check if perpendiculars are degenerate (collinear points)
387
- if (magnitudeSquared(ABperp).lessThan(EPSILON) && magnitudeSquared(ACperp).lessThan(EPSILON)) {
464
+ if (
465
+ magnitudeSquared(ABperp).lessThan(EPSILON) &&
466
+ magnitudeSquared(ACperp).lessThan(EPSILON)
467
+ ) {
388
468
  // All three points are collinear - reduce to line segment
389
469
  // Choose the two points farthest apart
390
470
  const BC = vectorSub(C, B);
@@ -393,19 +473,19 @@ export function processTriangleSimplex(simplex, direction) {
393
473
  return {
394
474
  contains: false,
395
475
  newDirection: tripleProduct(BC, vectorNeg(B), BC),
396
- newSimplex: [B, C]
476
+ newSimplex: [B, C],
397
477
  };
398
478
  } else if (ABmagSq.greaterThan(ACmagSq)) {
399
479
  return {
400
480
  contains: false,
401
481
  newDirection: tripleProduct(AB, AO, AB),
402
- newSimplex: [A, B]
482
+ newSimplex: [A, B],
403
483
  };
404
484
  } else {
405
485
  return {
406
486
  contains: false,
407
487
  newDirection: tripleProduct(AC, AO, AC),
408
- newSimplex: [A, C]
488
+ newSimplex: [A, C],
409
489
  };
410
490
  }
411
491
  }
@@ -417,7 +497,7 @@ export function processTriangleSimplex(simplex, direction) {
417
497
  return {
418
498
  contains: false,
419
499
  newDirection: ABperp,
420
- newSimplex: [A, B]
500
+ newSimplex: [A, B],
421
501
  };
422
502
  }
423
503
 
@@ -428,7 +508,7 @@ export function processTriangleSimplex(simplex, direction) {
428
508
  return {
429
509
  contains: false,
430
510
  newDirection: ACperp,
431
- newSimplex: [A, C]
511
+ newSimplex: [A, C],
432
512
  };
433
513
  }
434
514
 
@@ -436,7 +516,7 @@ export function processTriangleSimplex(simplex, direction) {
436
516
  return {
437
517
  contains: true,
438
518
  newDirection: direction,
439
- newSimplex: simplex
519
+ newSimplex: simplex,
440
520
  };
441
521
  }
442
522
 
@@ -459,8 +539,10 @@ export function processTriangleSimplex(simplex, direction) {
459
539
  * @throws {TypeError} If polygons are not arrays
460
540
  */
461
541
  export function gjkIntersects(polygonA, polygonB) {
462
- if (!Array.isArray(polygonA)) throw new TypeError('gjkIntersects: polygonA must be an array');
463
- if (!Array.isArray(polygonB)) throw new TypeError('gjkIntersects: polygonB must be an array');
542
+ if (!Array.isArray(polygonA))
543
+ throw new TypeError("gjkIntersects: polygonA must be an array");
544
+ if (!Array.isArray(polygonB))
545
+ throw new TypeError("gjkIntersects: polygonB must be an array");
464
546
  // Handle empty polygons
465
547
  if (polygonA.length === 0 || polygonB.length === 0) {
466
548
  return { intersects: false, iterations: 0, simplex: [], verified: true };
@@ -469,25 +551,26 @@ export function gjkIntersects(polygonA, polygonB) {
469
551
  // Handle single points
470
552
  if (polygonA.length === 1 && polygonB.length === 1) {
471
553
  if (!polygonA[0] || polygonA[0].x == null || polygonA[0].y == null) {
472
- throw new TypeError('gjkIntersects: polygonA[0] must have x and y properties');
554
+ throw new TypeError(
555
+ "gjkIntersects: polygonA[0] must have x and y properties",
556
+ );
473
557
  }
474
558
  if (!polygonB[0] || polygonB[0].x == null || polygonB[0].y == null) {
475
- throw new TypeError('gjkIntersects: polygonB[0] must have x and y properties');
559
+ throw new TypeError(
560
+ "gjkIntersects: polygonB[0] must have x and y properties",
561
+ );
476
562
  }
477
563
  const dist = magnitude(vectorSub(polygonA[0], polygonB[0]));
478
564
  return {
479
565
  intersects: dist.lessThan(EPSILON),
480
566
  iterations: 1,
481
567
  simplex: [],
482
- verified: true
568
+ verified: true,
483
569
  };
484
570
  }
485
571
 
486
572
  // Initial direction: from center of A to center of B
487
- let direction = vectorSub(
488
- centroid(polygonB),
489
- centroid(polygonA)
490
- );
573
+ let direction = vectorSub(centroid(polygonB), centroid(polygonA));
491
574
 
492
575
  // If centers are the same, use arbitrary direction
493
576
  if (magnitudeSquared(direction).lessThan(EPSILON)) {
@@ -506,7 +589,7 @@ export function gjkIntersects(polygonA, polygonB) {
506
589
  intersects: true,
507
590
  iterations: 1,
508
591
  simplex,
509
- verified: verifyIntersection(polygonA, polygonB)
592
+ verified: verifyIntersection(polygonA, polygonB),
510
593
  };
511
594
  }
512
595
 
@@ -523,7 +606,7 @@ export function gjkIntersects(polygonA, polygonB) {
523
606
  intersects: false,
524
607
  iterations: iteration + 1,
525
608
  simplex,
526
- verified: true
609
+ verified: true,
527
610
  };
528
611
  }
529
612
 
@@ -539,7 +622,7 @@ export function gjkIntersects(polygonA, polygonB) {
539
622
  intersects: true,
540
623
  iterations: iteration + 1,
541
624
  simplex,
542
- verified: verifyIntersection(polygonA, polygonB)
625
+ verified: verifyIntersection(polygonA, polygonB),
543
626
  };
544
627
  }
545
628
  direction = result.newDirection;
@@ -551,7 +634,7 @@ export function gjkIntersects(polygonA, polygonB) {
551
634
  intersects: true,
552
635
  iterations: iteration + 1,
553
636
  simplex: result.newSimplex,
554
- verified: verifyIntersection(polygonA, polygonB)
637
+ verified: verifyIntersection(polygonA, polygonB),
555
638
  };
556
639
  }
557
640
  simplex = result.newSimplex;
@@ -566,7 +649,7 @@ export function gjkIntersects(polygonA, polygonB) {
566
649
  intersects: false,
567
650
  iterations: iteration + 1,
568
651
  simplex,
569
- verified: false
652
+ verified: false,
570
653
  };
571
654
  }
572
655
 
@@ -579,7 +662,7 @@ export function gjkIntersects(polygonA, polygonB) {
579
662
  intersects: false,
580
663
  iterations: MAX_ITERATIONS,
581
664
  simplex,
582
- verified: false
665
+ verified: false,
583
666
  };
584
667
  }
585
668
 
@@ -594,9 +677,10 @@ export function gjkIntersects(polygonA, polygonB) {
594
677
  * @throws {TypeError} If polygon is not an array
595
678
  */
596
679
  export function centroid(polygon) {
597
- if (!Array.isArray(polygon)) throw new TypeError('centroid: polygon must be an array');
680
+ if (!Array.isArray(polygon))
681
+ throw new TypeError("centroid: polygon must be an array");
598
682
  if (polygon.length === 0) {
599
- throw new TypeError('centroid: polygon cannot be empty');
683
+ throw new TypeError("centroid: polygon cannot be empty");
600
684
  }
601
685
 
602
686
  let sumX = D(0);
@@ -604,7 +688,9 @@ export function centroid(polygon) {
604
688
 
605
689
  for (let i = 0; i < polygon.length; i++) {
606
690
  if (!polygon[i] || polygon[i].x == null || polygon[i].y == null) {
607
- throw new TypeError(`centroid: polygon[${i}] must have x and y properties`);
691
+ throw new TypeError(
692
+ `centroid: polygon[${i}] must have x and y properties`,
693
+ );
608
694
  }
609
695
  sumX = sumX.plus(polygon[i].x);
610
696
  sumY = sumY.plus(polygon[i].y);
@@ -626,8 +712,12 @@ export function centroid(polygon) {
626
712
  * @throws {TypeError} If pt is invalid or polygon is not an array
627
713
  */
628
714
  export function pointInConvexPolygon(pt, polygon) {
629
- if (!pt || pt.x == null || pt.y == null) throw new TypeError('pointInConvexPolygon: point must have x and y properties');
630
- if (!Array.isArray(polygon)) throw new TypeError('pointInConvexPolygon: polygon must be an array');
715
+ if (!pt || pt.x == null || pt.y == null)
716
+ throw new TypeError(
717
+ "pointInConvexPolygon: point must have x and y properties",
718
+ );
719
+ if (!Array.isArray(polygon))
720
+ throw new TypeError("pointInConvexPolygon: polygon must be an array");
631
721
  if (polygon.length < 3) {
632
722
  return false;
633
723
  }
@@ -639,10 +729,14 @@ export function pointInConvexPolygon(pt, polygon) {
639
729
  const p2 = polygon[(i + 1) % polygon.length];
640
730
 
641
731
  if (!p1 || p1.x == null || p1.y == null) {
642
- throw new TypeError(`pointInConvexPolygon: polygon[${i}] must have x and y properties`);
732
+ throw new TypeError(
733
+ `pointInConvexPolygon: polygon[${i}] must have x and y properties`,
734
+ );
643
735
  }
644
736
  if (!p2 || p2.x == null || p2.y == null) {
645
- throw new TypeError(`pointInConvexPolygon: polygon[${(i + 1) % polygon.length}] must have x and y properties`);
737
+ throw new TypeError(
738
+ `pointInConvexPolygon: polygon[${(i + 1) % polygon.length}] must have x and y properties`,
739
+ );
646
740
  }
647
741
 
648
742
  const edge = vectorSub(p2, p1);
@@ -679,12 +773,16 @@ export function pointInConvexPolygon(pt, polygon) {
679
773
  * @throws {TypeError} If polygons are not arrays
680
774
  */
681
775
  export function verifyIntersection(polygonA, polygonB) {
682
- if (!Array.isArray(polygonA)) throw new TypeError('verifyIntersection: polygonA must be an array');
683
- if (!Array.isArray(polygonB)) throw new TypeError('verifyIntersection: polygonB must be an array');
776
+ if (!Array.isArray(polygonA))
777
+ throw new TypeError("verifyIntersection: polygonA must be an array");
778
+ if (!Array.isArray(polygonB))
779
+ throw new TypeError("verifyIntersection: polygonB must be an array");
684
780
  // Check if any vertex of A is inside B
685
781
  for (let i = 0; i < polygonA.length; i++) {
686
782
  if (!polygonA[i] || polygonA[i].x == null || polygonA[i].y == null) {
687
- throw new TypeError(`verifyIntersection: polygonA[${i}] must have x and y properties`);
783
+ throw new TypeError(
784
+ `verifyIntersection: polygonA[${i}] must have x and y properties`,
785
+ );
688
786
  }
689
787
  if (pointInConvexPolygon(polygonA[i], polygonB)) {
690
788
  return true;
@@ -694,7 +792,9 @@ export function verifyIntersection(polygonA, polygonB) {
694
792
  // Check if any vertex of B is inside A
695
793
  for (let i = 0; i < polygonB.length; i++) {
696
794
  if (!polygonB[i] || polygonB[i].x == null || polygonB[i].y == null) {
697
- throw new TypeError(`verifyIntersection: polygonB[${i}] must have x and y properties`);
795
+ throw new TypeError(
796
+ `verifyIntersection: polygonB[${i}] must have x and y properties`,
797
+ );
698
798
  }
699
799
  if (pointInConvexPolygon(polygonB[i], polygonA)) {
700
800
  return true;
@@ -707,10 +807,14 @@ export function verifyIntersection(polygonA, polygonB) {
707
807
  const a2 = polygonA[(i + 1) % polygonA.length];
708
808
 
709
809
  if (!a1 || a1.x == null || a1.y == null) {
710
- throw new TypeError(`verifyIntersection: polygonA[${i}] must have x and y properties`);
810
+ throw new TypeError(
811
+ `verifyIntersection: polygonA[${i}] must have x and y properties`,
812
+ );
711
813
  }
712
814
  if (!a2 || a2.x == null || a2.y == null) {
713
- throw new TypeError(`verifyIntersection: polygonA[${(i + 1) % polygonA.length}] must have x and y properties`);
815
+ throw new TypeError(
816
+ `verifyIntersection: polygonA[${(i + 1) % polygonA.length}] must have x and y properties`,
817
+ );
714
818
  }
715
819
 
716
820
  for (let j = 0; j < polygonB.length; j++) {
@@ -718,10 +822,14 @@ export function verifyIntersection(polygonA, polygonB) {
718
822
  const b2 = polygonB[(j + 1) % polygonB.length];
719
823
 
720
824
  if (!b1 || b1.x == null || b1.y == null) {
721
- throw new TypeError(`verifyIntersection: polygonB[${j}] must have x and y properties`);
825
+ throw new TypeError(
826
+ `verifyIntersection: polygonB[${j}] must have x and y properties`,
827
+ );
722
828
  }
723
829
  if (!b2 || b2.x == null || b2.y == null) {
724
- throw new TypeError(`verifyIntersection: polygonB[${(j + 1) % polygonB.length}] must have x and y properties`);
830
+ throw new TypeError(
831
+ `verifyIntersection: polygonB[${(j + 1) % polygonB.length}] must have x and y properties`,
832
+ );
725
833
  }
726
834
 
727
835
  if (segmentsIntersect(a1, a2, b1, b2)) {
@@ -744,10 +852,14 @@ export function verifyIntersection(polygonA, polygonB) {
744
852
  * @throws {TypeError} If any point is invalid or missing x/y properties
745
853
  */
746
854
  export function segmentsIntersect(a1, a2, b1, b2) {
747
- if (!a1 || a1.x == null || a1.y == null) throw new TypeError('segmentsIntersect: a1 must have x and y properties');
748
- if (!a2 || a2.x == null || a2.y == null) throw new TypeError('segmentsIntersect: a2 must have x and y properties');
749
- if (!b1 || b1.x == null || b1.y == null) throw new TypeError('segmentsIntersect: b1 must have x and y properties');
750
- if (!b2 || b2.x == null || b2.y == null) throw new TypeError('segmentsIntersect: b2 must have x and y properties');
855
+ if (!a1 || a1.x == null || a1.y == null)
856
+ throw new TypeError("segmentsIntersect: a1 must have x and y properties");
857
+ if (!a2 || a2.x == null || a2.y == null)
858
+ throw new TypeError("segmentsIntersect: a2 must have x and y properties");
859
+ if (!b1 || b1.x == null || b1.y == null)
860
+ throw new TypeError("segmentsIntersect: b1 must have x and y properties");
861
+ if (!b2 || b2.x == null || b2.y == null)
862
+ throw new TypeError("segmentsIntersect: b2 must have x and y properties");
751
863
 
752
864
  const d1 = vectorSub(a2, a1);
753
865
  const d2 = vectorSub(b2, b1);
@@ -791,8 +903,12 @@ export function segmentsIntersect(a1, a2, b1, b2) {
791
903
  const u = cross(d3, d1).div(crossD);
792
904
 
793
905
  // Check if intersection is within both segments
794
- return t.greaterThanOrEqualTo(0) && t.lessThanOrEqualTo(1) &&
795
- u.greaterThanOrEqualTo(0) && u.lessThanOrEqualTo(1);
906
+ return (
907
+ t.greaterThanOrEqualTo(0) &&
908
+ t.lessThanOrEqualTo(1) &&
909
+ u.greaterThanOrEqualTo(0) &&
910
+ u.lessThanOrEqualTo(1)
911
+ );
796
912
  }
797
913
 
798
914
  // ============================================================================
@@ -811,10 +927,14 @@ export function segmentsIntersect(a1, a2, b1, b2) {
811
927
  * @throws {TypeError} If polygons are not arrays or are empty
812
928
  */
813
929
  export function gjkDistance(polygonA, polygonB) {
814
- if (!Array.isArray(polygonA)) throw new TypeError('gjkDistance: polygonA must be an array');
815
- if (!Array.isArray(polygonB)) throw new TypeError('gjkDistance: polygonB must be an array');
816
- if (polygonA.length === 0) throw new TypeError('gjkDistance: polygonA cannot be empty');
817
- if (polygonB.length === 0) throw new TypeError('gjkDistance: polygonB cannot be empty');
930
+ if (!Array.isArray(polygonA))
931
+ throw new TypeError("gjkDistance: polygonA must be an array");
932
+ if (!Array.isArray(polygonB))
933
+ throw new TypeError("gjkDistance: polygonB must be an array");
934
+ if (polygonA.length === 0)
935
+ throw new TypeError("gjkDistance: polygonA cannot be empty");
936
+ if (polygonB.length === 0)
937
+ throw new TypeError("gjkDistance: polygonB cannot be empty");
818
938
 
819
939
  // First check if they intersect
820
940
  const intersection = gjkIntersects(polygonA, polygonB);
@@ -824,7 +944,7 @@ export function gjkDistance(polygonA, polygonB) {
824
944
  distance: D(0),
825
945
  closestA: centroid(polygonA),
826
946
  closestB: centroid(polygonB),
827
- verified: true
947
+ verified: true,
828
948
  };
829
949
  }
830
950
 
@@ -836,10 +956,14 @@ export function gjkDistance(polygonA, polygonB) {
836
956
 
837
957
  // Validate first points before using them as initial values
838
958
  if (!polygonA[0] || polygonA[0].x == null || polygonA[0].y == null) {
839
- throw new TypeError('gjkDistance: polygonA[0] must have x and y properties');
959
+ throw new TypeError(
960
+ "gjkDistance: polygonA[0] must have x and y properties",
961
+ );
840
962
  }
841
963
  if (!polygonB[0] || polygonB[0].x == null || polygonB[0].y == null) {
842
- throw new TypeError('gjkDistance: polygonB[0] must have x and y properties');
964
+ throw new TypeError(
965
+ "gjkDistance: polygonB[0] must have x and y properties",
966
+ );
843
967
  }
844
968
 
845
969
  let minDist = D(Infinity);
@@ -849,11 +973,15 @@ export function gjkDistance(polygonA, polygonB) {
849
973
  // Check all pairs of vertices
850
974
  for (let i = 0; i < polygonA.length; i++) {
851
975
  if (!polygonA[i] || polygonA[i].x == null || polygonA[i].y == null) {
852
- throw new TypeError(`gjkDistance: polygonA[${i}] must have x and y properties`);
976
+ throw new TypeError(
977
+ `gjkDistance: polygonA[${i}] must have x and y properties`,
978
+ );
853
979
  }
854
980
  for (let j = 0; j < polygonB.length; j++) {
855
981
  if (!polygonB[j] || polygonB[j].x == null || polygonB[j].y == null) {
856
- throw new TypeError(`gjkDistance: polygonB[${j}] must have x and y properties`);
982
+ throw new TypeError(
983
+ `gjkDistance: polygonB[${j}] must have x and y properties`,
984
+ );
857
985
  }
858
986
  const dist = magnitude(vectorSub(polygonA[i], polygonB[j]));
859
987
  if (dist.lessThan(minDist)) {
@@ -867,16 +995,22 @@ export function gjkDistance(polygonA, polygonB) {
867
995
  // Check vertex-to-edge distances
868
996
  for (let i = 0; i < polygonA.length; i++) {
869
997
  if (!polygonA[i] || polygonA[i].x == null || polygonA[i].y == null) {
870
- throw new TypeError(`gjkDistance: polygonA[${i}] must have x and y properties`);
998
+ throw new TypeError(
999
+ `gjkDistance: polygonA[${i}] must have x and y properties`,
1000
+ );
871
1001
  }
872
1002
  for (let j = 0; j < polygonB.length; j++) {
873
1003
  const e1 = polygonB[j];
874
1004
  const e2 = polygonB[(j + 1) % polygonB.length];
875
1005
  if (!e1 || e1.x == null || e1.y == null) {
876
- throw new TypeError(`gjkDistance: polygonB[${j}] must have x and y properties`);
1006
+ throw new TypeError(
1007
+ `gjkDistance: polygonB[${j}] must have x and y properties`,
1008
+ );
877
1009
  }
878
1010
  if (!e2 || e2.x == null || e2.y == null) {
879
- throw new TypeError(`gjkDistance: polygonB[${(j + 1) % polygonB.length}] must have x and y properties`);
1011
+ throw new TypeError(
1012
+ `gjkDistance: polygonB[${(j + 1) % polygonB.length}] must have x and y properties`,
1013
+ );
880
1014
  }
881
1015
  const closest = closestPointOnSegment(polygonA[i], e1, e2);
882
1016
  const dist = magnitude(vectorSub(polygonA[i], closest));
@@ -890,16 +1024,22 @@ export function gjkDistance(polygonA, polygonB) {
890
1024
 
891
1025
  for (let i = 0; i < polygonB.length; i++) {
892
1026
  if (!polygonB[i] || polygonB[i].x == null || polygonB[i].y == null) {
893
- throw new TypeError(`gjkDistance: polygonB[${i}] must have x and y properties`);
1027
+ throw new TypeError(
1028
+ `gjkDistance: polygonB[${i}] must have x and y properties`,
1029
+ );
894
1030
  }
895
1031
  for (let j = 0; j < polygonA.length; j++) {
896
1032
  const e1 = polygonA[j];
897
1033
  const e2 = polygonA[(j + 1) % polygonA.length];
898
1034
  if (!e1 || e1.x == null || e1.y == null) {
899
- throw new TypeError(`gjkDistance: polygonA[${j}] must have x and y properties`);
1035
+ throw new TypeError(
1036
+ `gjkDistance: polygonA[${j}] must have x and y properties`,
1037
+ );
900
1038
  }
901
1039
  if (!e2 || e2.x == null || e2.y == null) {
902
- throw new TypeError(`gjkDistance: polygonA[${(j + 1) % polygonA.length}] must have x and y properties`);
1040
+ throw new TypeError(
1041
+ `gjkDistance: polygonA[${(j + 1) % polygonA.length}] must have x and y properties`,
1042
+ );
903
1043
  }
904
1044
  const closest = closestPointOnSegment(polygonB[i], e1, e2);
905
1045
  const dist = magnitude(vectorSub(polygonB[i], closest));
@@ -919,7 +1059,7 @@ export function gjkDistance(polygonA, polygonB) {
919
1059
  distance: minDist,
920
1060
  closestA,
921
1061
  closestB,
922
- verified
1062
+ verified,
923
1063
  };
924
1064
  }
925
1065
 
@@ -933,9 +1073,18 @@ export function gjkDistance(polygonA, polygonB) {
933
1073
  * @throws {TypeError} If any point is invalid or missing x/y properties
934
1074
  */
935
1075
  export function closestPointOnSegment(pt, a, b) {
936
- if (!pt || pt.x == null || pt.y == null) throw new TypeError('closestPointOnSegment: pt must have x and y properties');
937
- if (!a || a.x == null || a.y == null) throw new TypeError('closestPointOnSegment: a must have x and y properties');
938
- if (!b || b.x == null || b.y == null) throw new TypeError('closestPointOnSegment: b must have x and y properties');
1076
+ if (!pt || pt.x == null || pt.y == null)
1077
+ throw new TypeError(
1078
+ "closestPointOnSegment: pt must have x and y properties",
1079
+ );
1080
+ if (!a || a.x == null || a.y == null)
1081
+ throw new TypeError(
1082
+ "closestPointOnSegment: a must have x and y properties",
1083
+ );
1084
+ if (!b || b.x == null || b.y == null)
1085
+ throw new TypeError(
1086
+ "closestPointOnSegment: b must have x and y properties",
1087
+ );
939
1088
 
940
1089
  const ab = vectorSub(b, a);
941
1090
  const ap = vectorSub(pt, a);
@@ -969,18 +1118,24 @@ export function closestPointOnSegment(pt, a, b) {
969
1118
  * @throws {TypeError} If polygons are not arrays
970
1119
  */
971
1120
  export function polygonsOverlap(polygonA, polygonB) {
972
- if (!Array.isArray(polygonA)) throw new TypeError('polygonsOverlap: polygonA must be an array');
973
- if (!Array.isArray(polygonB)) throw new TypeError('polygonsOverlap: polygonB must be an array');
1121
+ if (!Array.isArray(polygonA))
1122
+ throw new TypeError("polygonsOverlap: polygonA must be an array");
1123
+ if (!Array.isArray(polygonB))
1124
+ throw new TypeError("polygonsOverlap: polygonB must be an array");
974
1125
  // Normalize input to Decimal
975
1126
  const normA = polygonA.map((p, i) => {
976
1127
  if (!p || p.x == null || p.y == null) {
977
- throw new TypeError(`polygonsOverlap: polygonA[${i}] must have x and y properties`);
1128
+ throw new TypeError(
1129
+ `polygonsOverlap: polygonA[${i}] must have x and y properties`,
1130
+ );
978
1131
  }
979
1132
  return point(p.x, p.y);
980
1133
  });
981
1134
  const normB = polygonB.map((p, i) => {
982
1135
  if (!p || p.x == null || p.y == null) {
983
- throw new TypeError(`polygonsOverlap: polygonB[${i}] must have x and y properties`);
1136
+ throw new TypeError(
1137
+ `polygonsOverlap: polygonB[${i}] must have x and y properties`,
1138
+ );
984
1139
  }
985
1140
  return point(p.x, p.y);
986
1141
  });
@@ -989,7 +1144,7 @@ export function polygonsOverlap(polygonA, polygonB) {
989
1144
 
990
1145
  return {
991
1146
  overlaps: result.intersects,
992
- verified: result.verified
1147
+ verified: result.verified,
993
1148
  };
994
1149
  }
995
1150
 
@@ -1002,18 +1157,24 @@ export function polygonsOverlap(polygonA, polygonB) {
1002
1157
  * @throws {TypeError} If polygons are not arrays
1003
1158
  */
1004
1159
  export function polygonsDistance(polygonA, polygonB) {
1005
- if (!Array.isArray(polygonA)) throw new TypeError('polygonsDistance: polygonA must be an array');
1006
- if (!Array.isArray(polygonB)) throw new TypeError('polygonsDistance: polygonB must be an array');
1160
+ if (!Array.isArray(polygonA))
1161
+ throw new TypeError("polygonsDistance: polygonA must be an array");
1162
+ if (!Array.isArray(polygonB))
1163
+ throw new TypeError("polygonsDistance: polygonB must be an array");
1007
1164
  // Normalize input to Decimal
1008
1165
  const normA = polygonA.map((p, i) => {
1009
1166
  if (!p || p.x == null || p.y == null) {
1010
- throw new TypeError(`polygonsDistance: polygonA[${i}] must have x and y properties`);
1167
+ throw new TypeError(
1168
+ `polygonsDistance: polygonA[${i}] must have x and y properties`,
1169
+ );
1011
1170
  }
1012
1171
  return point(p.x, p.y);
1013
1172
  });
1014
1173
  const normB = polygonB.map((p, i) => {
1015
1174
  if (!p || p.x == null || p.y == null) {
1016
- throw new TypeError(`polygonsDistance: polygonB[${i}] must have x and y properties`);
1175
+ throw new TypeError(
1176
+ `polygonsDistance: polygonB[${i}] must have x and y properties`,
1177
+ );
1017
1178
  }
1018
1179
  return point(p.x, p.y);
1019
1180
  });
@@ -1024,7 +1185,7 @@ export function polygonsDistance(polygonA, polygonB) {
1024
1185
  distance: result.distance,
1025
1186
  closestA: result.closestA,
1026
1187
  closestB: result.closestB,
1027
- verified: result.verified
1188
+ verified: result.verified,
1028
1189
  };
1029
1190
  }
1030
1191
 
@@ -1037,12 +1198,16 @@ export function polygonsDistance(polygonA, polygonB) {
1037
1198
  * @throws {TypeError} If pt is invalid or polygon is not an array
1038
1199
  */
1039
1200
  export function isPointInPolygon(pt, polygon) {
1040
- if (!pt || pt.x == null || pt.y == null) throw new TypeError('isPointInPolygon: pt must have x and y properties');
1041
- if (!Array.isArray(polygon)) throw new TypeError('isPointInPolygon: polygon must be an array');
1201
+ if (!pt || pt.x == null || pt.y == null)
1202
+ throw new TypeError("isPointInPolygon: pt must have x and y properties");
1203
+ if (!Array.isArray(polygon))
1204
+ throw new TypeError("isPointInPolygon: polygon must be an array");
1042
1205
  const normPt = point(pt.x, pt.y);
1043
1206
  const normPoly = polygon.map((p, i) => {
1044
1207
  if (!p || p.x == null || p.y == null) {
1045
- throw new TypeError(`isPointInPolygon: polygon[${i}] must have x and y properties`);
1208
+ throw new TypeError(
1209
+ `isPointInPolygon: polygon[${i}] must have x and y properties`,
1210
+ );
1046
1211
  }
1047
1212
  return point(p.x, p.y);
1048
1213
  });
@@ -1054,11 +1219,7 @@ export function isPointInPolygon(pt, polygon) {
1054
1219
  // Exports
1055
1220
  // ============================================================================
1056
1221
 
1057
- export {
1058
- EPSILON,
1059
- MAX_ITERATIONS,
1060
- D
1061
- };
1222
+ export { EPSILON, MAX_ITERATIONS, D };
1062
1223
 
1063
1224
  export default {
1064
1225
  // Point/vector utilities
@@ -1101,5 +1262,5 @@ export default {
1101
1262
 
1102
1263
  // Constants
1103
1264
  EPSILON,
1104
- MAX_ITERATIONS
1265
+ MAX_ITERATIONS,
1105
1266
  };