@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
@@ -177,9 +177,7 @@ export function parsePath(d) {
177
177
 
178
178
  // BUG FIX #6: Validate command exists in COMMAND_PARAMS
179
179
  if (paramCount === undefined) {
180
- console.warn(
181
- `Unknown SVG path command '${cmd}' - skipping`,
182
- );
180
+ console.warn(`Unknown SVG path command '${cmd}' - skipping`);
183
181
  continue;
184
182
  }
185
183
 
@@ -218,7 +216,9 @@ export function parsePath(d) {
218
216
  export function formatNumber(num, precision = 3) {
219
217
  // Parameter validation: num must be a number
220
218
  if (typeof num !== "number") {
221
- throw new TypeError(`formatNumber: num must be a number, got ${typeof num}`);
219
+ throw new TypeError(
220
+ `formatNumber: num must be a number, got ${typeof num}`,
221
+ );
222
222
  }
223
223
  // Parameter validation: precision must be a non-negative integer
224
224
  if (
@@ -568,10 +568,14 @@ export function lineToZ(cmd, cx, cy, startX, startY, tolerance = 1e-6) {
568
568
  throw new TypeError(`lineToZ: cy must be a finite number, got ${cy}`);
569
569
  }
570
570
  if (typeof startX !== "number" || !isFinite(startX)) {
571
- throw new TypeError(`lineToZ: startX must be a finite number, got ${startX}`);
571
+ throw new TypeError(
572
+ `lineToZ: startX must be a finite number, got ${startX}`,
573
+ );
572
574
  }
573
575
  if (typeof startY !== "number" || !isFinite(startY)) {
574
- throw new TypeError(`lineToZ: startY must be a finite number, got ${startY}`);
576
+ throw new TypeError(
577
+ `lineToZ: startY must be a finite number, got ${startY}`,
578
+ );
575
579
  }
576
580
  if (typeof tolerance !== "number" || !isFinite(tolerance) || tolerance < 0) {
577
581
  throw new TypeError(
@@ -919,7 +923,11 @@ export function convertPathData(d, options = {}) {
919
923
  throw new TypeError(`convertPathData: d must be a string, got ${typeof d}`);
920
924
  }
921
925
  // Parameter validation: options must be an object
922
- if (typeof options !== "object" || options === null || Array.isArray(options)) {
926
+ if (
927
+ typeof options !== "object" ||
928
+ options === null ||
929
+ Array.isArray(options)
930
+ ) {
923
931
  throw new TypeError(
924
932
  `convertPathData: options must be an object, got ${typeof options}`,
925
933
  );
@@ -1119,7 +1127,11 @@ export function optimizeDocumentPaths(root, options = {}) {
1119
1127
  );
1120
1128
  }
1121
1129
  // Parameter validation: options must be an object
1122
- if (typeof options !== "object" || options === null || Array.isArray(options)) {
1130
+ if (
1131
+ typeof options !== "object" ||
1132
+ options === null ||
1133
+ Array.isArray(options)
1134
+ ) {
1123
1135
  throw new TypeError(
1124
1136
  `optimizeDocumentPaths: options must be an object, got ${typeof options}`,
1125
1137
  );
@@ -229,11 +229,18 @@ function parseSimpleSelector(selector) {
229
229
 
230
230
  // Handle legacy pseudo-elements (CSS2 syntax with single colon)
231
231
  // These should be treated as pseudo-elements, not pseudo-classes
232
- const legacyPseudoElements = ["before", "after", "first-line", "first-letter"];
232
+ const legacyPseudoElements = [
233
+ "before",
234
+ "after",
235
+ "first-line",
236
+ "first-letter",
237
+ ];
233
238
  const isPseudoElement = legacyPseudoElements.includes(pseudoValue);
234
239
 
235
240
  components.push({
236
- type: isPseudoElement ? SELECTOR_TYPES.PSEUDO_ELEMENT : SELECTOR_TYPES.PSEUDO_CLASS,
241
+ type: isPseudoElement
242
+ ? SELECTOR_TYPES.PSEUDO_ELEMENT
243
+ : SELECTOR_TYPES.PSEUDO_CLASS,
237
244
  value: pseudoValue,
238
245
  });
239
246
  }
@@ -268,7 +275,9 @@ function parseSimpleSelector(selector) {
268
275
  // This is a namespace prefix, skip it for specificity purposes
269
276
  // The actual element name follows the |
270
277
  nextIdx++; // Skip the |
271
- const elementMatch = selector.slice(nextIdx).match(/^([a-zA-Z*][\w-]*)/);
278
+ const elementMatch = selector
279
+ .slice(nextIdx)
280
+ .match(/^([a-zA-Z*][\w-]*)/);
272
281
  if (elementMatch) {
273
282
  value = elementMatch[1]; // Use the element name after namespace
274
283
  nextIdx += elementMatch[0].length;
@@ -443,7 +452,9 @@ export function calculateSpecificity(selector) {
443
452
 
444
453
  // :not(), :is(), :has() don't count themselves, but their arguments do
445
454
  if (
446
- (value.startsWith("not(") || value.startsWith("is(") || value.startsWith("has(")) &&
455
+ (value.startsWith("not(") ||
456
+ value.startsWith("is(") ||
457
+ value.startsWith("has(")) &&
447
458
  value.endsWith(")")
448
459
  ) {
449
460
  const funcName = value.match(/^(\w+)\(/)[1];
@@ -473,7 +484,8 @@ export function calculateSpecificity(selector) {
473
484
 
474
485
  // :nth-child() and :nth-last-child() with "of S" clause
475
486
  if (
476
- (value.startsWith("nth-child(") || value.startsWith("nth-last-child(")) &&
487
+ (value.startsWith("nth-child(") ||
488
+ value.startsWith("nth-last-child(")) &&
477
489
  value.endsWith(")")
478
490
  ) {
479
491
  const funcName = value.match(/^([\w-]+)\(/)[1];
@@ -596,10 +608,18 @@ export function compareSpecificity(spec1, spec2) {
596
608
 
597
609
  // Validate all elements are valid numbers
598
610
  for (let i = 0; i < 3; i++) {
599
- if (typeof spec1[i] !== "number" || !Number.isFinite(spec1[i]) || spec1[i] < 0) {
611
+ if (
612
+ typeof spec1[i] !== "number" ||
613
+ !Number.isFinite(spec1[i]) ||
614
+ spec1[i] < 0
615
+ ) {
600
616
  throw new Error(`spec1[${i}] must be a non-negative finite number`);
601
617
  }
602
- if (typeof spec2[i] !== "number" || !Number.isFinite(spec2[i]) || spec2[i] < 0) {
618
+ if (
619
+ typeof spec2[i] !== "number" ||
620
+ !Number.isFinite(spec2[i]) ||
621
+ spec2[i] < 0
622
+ ) {
603
623
  throw new Error(`spec2[${i}] must be a non-negative finite number`);
604
624
  }
605
625
  }
@@ -669,10 +689,14 @@ export function stringifySelector(components) {
669
689
  return components
670
690
  .map((component, index) => {
671
691
  if (!component || typeof component.type !== "string") {
672
- throw new Error(`Component at index ${index} must have a 'type' property`);
692
+ throw new Error(
693
+ `Component at index ${index} must have a 'type' property`,
694
+ );
673
695
  }
674
696
  if (component.value === undefined) {
675
- throw new Error(`Component at index ${index} must have a 'value' property`);
697
+ throw new Error(
698
+ `Component at index ${index} must have a 'value' property`,
699
+ );
676
700
  }
677
701
  switch (component.type) {
678
702
  case SELECTOR_TYPES.ID: