@sarmal/core 0.26.0 → 0.27.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 (79) hide show
  1. package/dist/auto-init.cjs +145 -106
  2. package/dist/auto-init.js +144 -105
  3. package/dist/cli.js +1048 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/curves/artemis2.cjs +16 -10
  6. package/dist/curves/artemis2.d.cts +1 -1
  7. package/dist/curves/artemis2.d.ts +1 -1
  8. package/dist/curves/artemis2.js +15 -9
  9. package/dist/curves/astroid.cjs +4 -4
  10. package/dist/curves/astroid.d.cts +1 -1
  11. package/dist/curves/astroid.d.ts +1 -1
  12. package/dist/curves/astroid.js +3 -3
  13. package/dist/curves/deltoid.cjs +4 -4
  14. package/dist/curves/deltoid.d.cts +1 -1
  15. package/dist/curves/deltoid.d.ts +1 -1
  16. package/dist/curves/deltoid.js +3 -3
  17. package/dist/curves/epicycloid3.cjs +4 -4
  18. package/dist/curves/epicycloid3.d.cts +1 -1
  19. package/dist/curves/epicycloid3.d.ts +1 -1
  20. package/dist/curves/epicycloid3.js +3 -3
  21. package/dist/curves/epitrochoid7.cjs +5 -5
  22. package/dist/curves/epitrochoid7.d.cts +1 -1
  23. package/dist/curves/epitrochoid7.d.ts +1 -1
  24. package/dist/curves/epitrochoid7.js +4 -4
  25. package/dist/curves/index.cjs +59 -43
  26. package/dist/curves/index.d.cts +29 -29
  27. package/dist/curves/index.d.ts +29 -29
  28. package/dist/curves/index.js +75 -43
  29. package/dist/curves/lame.cjs +6 -5
  30. package/dist/curves/lame.d.cts +1 -1
  31. package/dist/curves/lame.d.ts +1 -1
  32. package/dist/curves/lame.js +5 -4
  33. package/dist/curves/lissajous32.cjs +4 -4
  34. package/dist/curves/lissajous32.d.cts +1 -1
  35. package/dist/curves/lissajous32.d.ts +1 -1
  36. package/dist/curves/lissajous32.js +3 -3
  37. package/dist/curves/lissajous43.cjs +4 -4
  38. package/dist/curves/lissajous43.d.cts +1 -1
  39. package/dist/curves/lissajous43.d.ts +1 -1
  40. package/dist/curves/lissajous43.js +3 -3
  41. package/dist/curves/rose3.cjs +4 -4
  42. package/dist/curves/rose3.d.cts +1 -1
  43. package/dist/curves/rose3.d.ts +1 -1
  44. package/dist/curves/rose3.js +3 -3
  45. package/dist/curves/rose5.cjs +4 -4
  46. package/dist/curves/rose5.d.cts +1 -1
  47. package/dist/curves/rose5.d.ts +1 -1
  48. package/dist/curves/rose5.js +3 -3
  49. package/dist/curves/rose52.cjs +5 -5
  50. package/dist/curves/rose52.d.cts +1 -1
  51. package/dist/curves/rose52.d.ts +1 -1
  52. package/dist/curves/rose52.js +4 -4
  53. package/dist/curves/star.cjs +8 -5
  54. package/dist/curves/star.d.cts +1 -1
  55. package/dist/curves/star.d.ts +1 -1
  56. package/dist/curves/star.js +7 -4
  57. package/dist/curves/star4.cjs +8 -5
  58. package/dist/curves/star4.d.cts +1 -1
  59. package/dist/curves/star4.d.ts +1 -1
  60. package/dist/curves/star4.js +7 -4
  61. package/dist/curves/star7.cjs +8 -5
  62. package/dist/curves/star7.d.cts +1 -1
  63. package/dist/curves/star7.d.ts +1 -1
  64. package/dist/curves/star7.js +7 -4
  65. package/dist/index.cjs +131 -94
  66. package/dist/index.d.cts +78 -58
  67. package/dist/index.d.ts +78 -58
  68. package/dist/index.js +152 -94
  69. package/dist/renderer-shared-OR--cv-t.d.ts +49 -0
  70. package/dist/renderer-shared-jqw_Q1WO.d.cts +49 -0
  71. package/dist/terminal.cjs +593 -0
  72. package/dist/terminal.cjs.map +1 -0
  73. package/dist/terminal.d.cts +44 -0
  74. package/dist/terminal.d.ts +44 -0
  75. package/dist/terminal.js +585 -0
  76. package/dist/terminal.js.map +1 -0
  77. package/dist/types-zbxUgcmZ.d.cts +280 -266
  78. package/dist/types-zbxUgcmZ.d.ts +280 -266
  79. package/package.json +11 -1
package/dist/auto-init.js CHANGED
@@ -61,13 +61,13 @@ function resolveCurve(curveDef) {
61
61
  period,
62
62
  speed,
63
63
  skeleton: curveDef.skeleton,
64
- skeletonFn: curveDef.skeletonFn
64
+ skeletonFn: curveDef.skeletonFn,
65
65
  };
66
66
  }
67
67
  function createEngine(curveDef, trailLength = 120) {
68
68
  if (!Number.isFinite(trailLength) || trailLength <= 0) {
69
69
  throw new RangeError(
70
- `[sarmal] trailLength must be a positive finite number, got ${trailLength}`
70
+ `[sarmal] trailLength must be a positive finite number, got ${trailLength}`,
71
71
  );
72
72
  }
73
73
  let curve = resolveCurve(curveDef);
@@ -108,7 +108,8 @@ function createEngine(curveDef, trailLength = 120) {
108
108
  actualTime += deltaTime;
109
109
  if (morphCurveB !== null && _morphAlpha !== null) {
110
110
  const a = curve.fn(phase, actualTime, EMPTY_PARAMS);
111
- const phaseB = _morphStrategy === "normalized" ? phase / curve.period * morphCurveB.period : phase;
111
+ const phaseB =
112
+ _morphStrategy === "normalized" ? (phase / curve.period) * morphCurveB.period : phase;
112
113
  const b = morphCurveB.fn(phaseB, actualTime, EMPTY_PARAMS);
113
114
  trail.push(a.x + (b.x - a.x) * _morphAlpha, a.y + (b.y - a.y) * _morphAlpha);
114
115
  } else {
@@ -135,14 +136,14 @@ function createEngine(curveDef, trailLength = 120) {
135
136
  trail.clear();
136
137
  },
137
138
  jump(newPhase, { clearTrail = false } = {}) {
138
- phase = (newPhase % curve.period + curve.period) % curve.period;
139
+ phase = ((newPhase % curve.period) + curve.period) % curve.period;
139
140
  if (clearTrail) {
140
141
  trail.clear();
141
142
  }
142
143
  },
143
144
  seek(targetPhase, { wrap = false, step = curve.period / trailLength } = {}) {
144
145
  const advance = curve.speed * step;
145
- const target = (targetPhase % curve.period + curve.period) % curve.period;
146
+ const target = ((targetPhase % curve.period) + curve.period) % curve.period;
146
147
  const targetTime = target / curve.speed;
147
148
  phase = target;
148
149
  actualTime = targetTime;
@@ -151,7 +152,7 @@ function createEngine(curveDef, trailLength = 120) {
151
152
  const count = wrap ? trailLength : Math.min(trailLength, pointsFromStart);
152
153
  for (let i = count - 1; i >= 0; i--) {
153
154
  const samplePhase = target - i * advance;
154
- const wrappedPhase = (samplePhase % curve.period + curve.period) % curve.period;
155
+ const wrappedPhase = ((samplePhase % curve.period) + curve.period) % curve.period;
155
156
  const elapsed = targetTime - i * step;
156
157
  const point = curve.fn(wrappedPhase, elapsed, EMPTY_PARAMS);
157
158
  trail.push(point.x, point.y);
@@ -168,13 +169,16 @@ function createEngine(curveDef, trailLength = 120) {
168
169
  ...frozenB,
169
170
  fn: (samplePhase, elapsed, params) => {
170
171
  const a = frozenA.fn(samplePhase, elapsed, params);
171
- const phaseB = frozenStrategy === "normalized" ? samplePhase / frozenA.period * frozenB.period : samplePhase;
172
+ const phaseB =
173
+ frozenStrategy === "normalized"
174
+ ? (samplePhase / frozenA.period) * frozenB.period
175
+ : samplePhase;
172
176
  const b = frozenB.fn(phaseB, elapsed, params);
173
177
  return {
174
178
  x: a.x + (b.x - a.x) * frozenAlpha,
175
- y: a.y + (b.y - a.y) * frozenAlpha
179
+ y: a.y + (b.y - a.y) * frozenAlpha,
176
180
  };
177
- }
181
+ },
178
182
  };
179
183
  }
180
184
  _morphStrategy = strategy;
@@ -187,7 +191,7 @@ function createEngine(curveDef, trailLength = 120) {
187
191
  completeMorph() {
188
192
  if (morphCurveB !== null) {
189
193
  if (_morphStrategy === "normalized" && curve.period !== morphCurveB.period) {
190
- phase = phase / curve.period * morphCurveB.period;
194
+ phase = (phase / curve.period) * morphCurveB.period;
191
195
  }
192
196
  curve = morphCurveB;
193
197
  }
@@ -199,19 +203,22 @@ function createEngine(curveDef, trailLength = 120) {
199
203
  const points2 = new Array(steps);
200
204
  if (morphCurveB !== null && _morphAlpha !== null) {
201
205
  for (let i = 0; i < steps; i++) {
202
- const samplePhase = i / (steps - 1) * curve.period;
206
+ const samplePhase = (i / (steps - 1)) * curve.period;
203
207
  const a = sampleSkeleton(curve, samplePhase);
204
- const phaseB = _morphStrategy === "normalized" ? samplePhase / curve.period * morphCurveB.period : samplePhase;
208
+ const phaseB =
209
+ _morphStrategy === "normalized"
210
+ ? (samplePhase / curve.period) * morphCurveB.period
211
+ : samplePhase;
205
212
  const b = sampleSkeleton(morphCurveB, phaseB);
206
213
  points2[i] = {
207
214
  x: a.x + (b.x - a.x) * _morphAlpha,
208
- y: a.y + (b.y - a.y) * _morphAlpha
215
+ y: a.y + (b.y - a.y) * _morphAlpha,
209
216
  };
210
217
  }
211
218
  return points2;
212
219
  }
213
220
  for (let i = 0; i < steps; i++) {
214
- const samplePhase = i / (steps - 1) * curve.period;
221
+ const samplePhase = (i / (steps - 1)) * curve.period;
215
222
  points2[i] = sampleSkeleton(curve, samplePhase);
216
223
  }
217
224
  return points2;
@@ -253,7 +260,7 @@ function createEngine(curveDef, trailLength = 120) {
253
260
  _speedTransition.reject(new Error("Speed transition cancelled"));
254
261
  _speedTransition = null;
255
262
  }
256
- }
263
+ },
257
264
  };
258
265
  }
259
266
 
@@ -292,7 +299,15 @@ function computeNormal(trail, i) {
292
299
  const tangent = computeTangent(trail, i);
293
300
  return { x: -tangent.y, y: tangent.x };
294
301
  }
295
- function computeTrailQuad(trail, i, trailCount, toX, toY, minWidth = TRAIL_MIN_WIDTH, maxWidth = TRAIL_MAX_WIDTH) {
302
+ function computeTrailQuad(
303
+ trail,
304
+ i,
305
+ trailCount,
306
+ toX,
307
+ toY,
308
+ minWidth = TRAIL_MIN_WIDTH,
309
+ maxWidth = TRAIL_MAX_WIDTH,
310
+ ) {
296
311
  const progress = i / (trailCount - 1);
297
312
  const nextProgress = (i + 1) / (trailCount - 1);
298
313
  const opacity = Math.pow(progress, TRAIL_FADE_CURVE) * TRAIL_MAX_OPACITY;
@@ -316,13 +331,16 @@ function computeTrailQuad(trail, i, trailCount, toX, toY, minWidth = TRAIL_MIN_W
316
331
  r1x: nx - n1.x * w1,
317
332
  r1y: ny - n1.y * w1,
318
333
  opacity,
319
- progress
334
+ progress,
320
335
  };
321
336
  }
322
337
  function computeBoundaries(pts, logicalWidth, logicalHeight, minPaddingPx = FIT_PADDING_MIN) {
323
338
  if (pts.length === 0) return null;
324
339
  const first = pts[0];
325
- let minX = first.x, maxX = first.x, minY = first.y, maxY = first.y;
340
+ let minX = first.x,
341
+ maxX = first.x,
342
+ minY = first.y,
343
+ maxY = first.y;
326
344
  for (const p of pts) {
327
345
  if (p.x < minX) {
328
346
  minX = p.x;
@@ -341,7 +359,7 @@ function computeBoundaries(pts, logicalWidth, logicalHeight, minPaddingPx = FIT_
341
359
  const h = maxY - minY;
342
360
  if (w === 0 && h === 0) {
343
361
  throw new Error(
344
- "[sarmal] Degenerate curve: all skeleton points are identical. Check that your curve fn returns distinct points for different values of t."
362
+ "[sarmal] Degenerate curve: all skeleton points are identical. Check that your curve fn returns distinct points for different values of t.",
345
363
  );
346
364
  }
347
365
  const scaleXProportional = logicalWidth / (w * (1 + FIT_PADDING * 2));
@@ -352,12 +370,12 @@ function computeBoundaries(pts, logicalWidth, logicalHeight, minPaddingPx = FIT_
352
370
  scaleXProportional,
353
371
  scaleYProportional,
354
372
  scaleXMinPadding,
355
- scaleYMinPadding
373
+ scaleYMinPadding,
356
374
  );
357
375
  return {
358
376
  scale,
359
377
  offsetX: (logicalWidth - w * scale) / 2 - minX * scale,
360
- offsetY: (logicalHeight - h * scale) / 2 - minY * scale
378
+ offsetY: (logicalHeight - h * scale) / 2 - minY * scale,
361
379
  };
362
380
  }
363
381
  function enginePassthroughs(engine) {
@@ -368,17 +386,17 @@ function enginePassthroughs(engine) {
368
386
  getSpeed: engine.getSpeed,
369
387
  resetSpeed: engine.resetSpeed,
370
388
  setSpeedOver: engine.setSpeedOver,
371
- getSarmalSkeleton: engine.getSarmalSkeleton
389
+ getSarmalSkeleton: engine.getSarmalSkeleton,
372
390
  };
373
391
  }
374
392
  function hexToRgb(hex) {
375
393
  const n = parseInt(hex.slice(1), 16);
376
- return { r: n >> 16, g: n >> 8 & 255, b: n & 255 };
394
+ return { r: n >> 16, g: (n >> 8) & 255, b: n & 255 };
377
395
  }
378
396
  var lerpRgb = (a, b, t) => ({
379
397
  r: Math.round(a.r + (b.r - a.r) * t),
380
398
  g: Math.round(a.g + (b.g - a.g) * t),
381
- b: Math.round(a.b + (b.b - a.b) * t)
399
+ b: Math.round(a.b + (b.b - a.b) * t),
382
400
  });
383
401
  function getPaletteColor(palette, position, timeOffset = 0) {
384
402
  if (palette.length === 0) {
@@ -387,7 +405,7 @@ function getPaletteColor(palette, position, timeOffset = 0) {
387
405
  if (palette.length === 1) {
388
406
  return hexToRgb(palette[0]);
389
407
  }
390
- const cyclePos = ((position + timeOffset) % 1 + 1) % 1;
408
+ const cyclePos = (((position + timeOffset) % 1) + 1) % 1;
391
409
  const scaled = cyclePos * palette.length;
392
410
  const idx = Math.floor(scaled);
393
411
  const t = scaled - idx;
@@ -402,7 +420,7 @@ var RENDER_OPTION_KEYS = /* @__PURE__ */ new Set([
402
420
  "headColor",
403
421
  "skeletonColor",
404
422
  "trailStyle",
405
- "headRadius"
423
+ "headRadius",
406
424
  ]);
407
425
  function validateRenderOptions(partial) {
408
426
  for (const key of Object.keys(partial)) {
@@ -430,7 +448,7 @@ function assertTrailColor(value) {
430
448
  if (typeof value === "string") {
431
449
  if (!HEX_COLOR_RE.test(value)) {
432
450
  throw new TypeError(
433
- `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string, got "${value}"`
451
+ `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string, got "${value}"`,
434
452
  );
435
453
  }
436
454
  return;
@@ -438,21 +456,21 @@ function assertTrailColor(value) {
438
456
  if (Array.isArray(value)) {
439
457
  if (value.length < 2) {
440
458
  throw new RangeError(
441
- `[sarmal] setRenderOptions: trailColor array must have at least 2 entries, got ${value.length}`
459
+ `[sarmal] setRenderOptions: trailColor array must have at least 2 entries, got ${value.length}`,
442
460
  );
443
461
  }
444
462
  for (let i = 0; i < value.length; i++) {
445
463
  const entry = value[i];
446
464
  if (typeof entry !== "string" || !HEX_COLOR_RE.test(entry)) {
447
465
  throw new TypeError(
448
- `[sarmal] setRenderOptions: trailColor[${i}] must be a 6-digit hex string, got ${JSON.stringify(entry)}`
466
+ `[sarmal] setRenderOptions: trailColor[${i}] must be a 6-digit hex string, got ${JSON.stringify(entry)}`,
449
467
  );
450
468
  }
451
469
  }
452
470
  return;
453
471
  }
454
472
  throw new TypeError(
455
- `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string or an array of hex strings, got ${JSON.stringify(value)}`
473
+ `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string or an array of hex strings, got ${JSON.stringify(value)}`,
456
474
  );
457
475
  }
458
476
  function assertHeadColor(value) {
@@ -461,7 +479,7 @@ function assertHeadColor(value) {
461
479
  }
462
480
  if (typeof value !== "string" || !HEX_COLOR_RE.test(value)) {
463
481
  throw new TypeError(
464
- `[sarmal] setRenderOptions: headColor must be a 6-digit hex string or null, got ${JSON.stringify(value)}`
482
+ `[sarmal] setRenderOptions: headColor must be a 6-digit hex string or null, got ${JSON.stringify(value)}`,
465
483
  );
466
484
  }
467
485
  }
@@ -471,26 +489,26 @@ function assertSkeletonColor(value) {
471
489
  }
472
490
  if (typeof value !== "string" || !HEX_COLOR_RE.test(value)) {
473
491
  throw new TypeError(
474
- `[sarmal] setRenderOptions: skeletonColor must be a 6-digit hex string or "transparent", got ${JSON.stringify(value)}`
492
+ `[sarmal] setRenderOptions: skeletonColor must be a 6-digit hex string or "transparent", got ${JSON.stringify(value)}`,
475
493
  );
476
494
  }
477
495
  }
478
496
  function assertTrailStyle(value) {
479
497
  if (!TRAIL_STYLES.includes(value)) {
480
498
  throw new RangeError(
481
- `[sarmal] setRenderOptions: trailStyle must be one of "default", "gradient-static", "gradient-animated", got ${JSON.stringify(value)}`
499
+ `[sarmal] setRenderOptions: trailStyle must be one of "default", "gradient-static", "gradient-animated", got ${JSON.stringify(value)}`,
482
500
  );
483
501
  }
484
502
  }
485
503
  function assertHeadRadius(value) {
486
504
  if (typeof value !== "number") {
487
505
  throw new TypeError(
488
- `[sarmal] setRenderOptions: headRadius must be a number, got ${JSON.stringify(value)}`
506
+ `[sarmal] setRenderOptions: headRadius must be a number, got ${JSON.stringify(value)}`,
489
507
  );
490
508
  }
491
509
  if (!Number.isFinite(value) || value <= 0) {
492
510
  throw new TypeError(
493
- `[sarmal] setRenderOptions: headRadius must be a finite positive number, got ${value}`
511
+ `[sarmal] setRenderOptions: headRadius must be a finite positive number, got ${value}`,
494
512
  );
495
513
  }
496
514
  }
@@ -512,13 +530,13 @@ function resolveHeadColor(trailColor, trailStyle) {
512
530
  function warnIfTrailColorMismatch(trailColor, trailStyle) {
513
531
  if (trailStyle === "default" && Array.isArray(trailColor)) {
514
532
  console.warn(
515
- '[sarmal] trailColor is an array but trailStyle is "default"; only the first color will be used. Pass a gradient trailStyle to use the whole palette.'
533
+ '[sarmal] trailColor is an array but trailStyle is "default"; only the first color will be used. Pass a gradient trailStyle to use the whole palette.',
516
534
  );
517
535
  return;
518
536
  }
519
537
  if (trailStyle !== "default" && typeof trailColor === "string") {
520
538
  console.warn(
521
- `[sarmal] trailColor is a single color but trailStyle is "${trailStyle}"; the trail will render as a solid color. Pass an array of hex colors to use a real gradient.`
539
+ `[sarmal] trailColor is a single color but trailStyle is "${trailStyle}"; the trail will render as a solid color. Pass an array of hex colors to use a real gradient.`,
522
540
  );
523
541
  }
524
542
  }
@@ -528,7 +546,7 @@ var getHeadDotRadius = (w, h) => Math.max(1, 3 * Math.sqrt(Math.min(w, h) / 160)
528
546
  var WHITE_HEX = "#ffffff";
529
547
  function hexToRgbComponents(hex) {
530
548
  const n = parseInt(hex.slice(1), 16);
531
- return `${n >> 16},${n >> 8 & 255},${n & 255}`;
549
+ return `${n >> 16},${(n >> 8) & 255},${n & 255}`;
532
550
  }
533
551
  function applyDprSizing(target, logicalWidth, logicalHeight, dpr) {
534
552
  target.style.width = `${logicalWidth}px`;
@@ -655,7 +673,7 @@ function createRenderer(options) {
655
673
  i,
656
674
  trailCount,
657
675
  toX,
658
- toY
676
+ toY,
659
677
  );
660
678
  if (trailStyle === "default") {
661
679
  ctx.fillStyle = `rgba(${trailSolidRgb},${opacity})`;
@@ -820,7 +838,7 @@ function createRenderer(options) {
820
838
  if (partial.trailColor !== void 0 || partial.trailStyle !== void 0) {
821
839
  warnIfTrailColorMismatch(trailColor, trailStyle);
822
840
  }
823
- }
841
+ },
824
842
  };
825
843
  const pauseOnHidden = options.pauseOnHidden !== false;
826
844
  function handleVisibilityChange() {
@@ -870,8 +888,10 @@ function sampleCurveSkeleton(curveDef) {
870
888
  const samples = Math.ceil(period * 50);
871
889
  const pts = Array.from({ length: samples });
872
890
  for (let i = 0; i < samples; i++) {
873
- const phase = i / (samples - 1) * period;
874
- pts[i] = curveDef.skeletonFn ? curveDef.skeletonFn(phase) : curveDef.fn(phase, 0, EMPTY_PARAMS2);
891
+ const phase = (i / (samples - 1)) * period;
892
+ pts[i] = curveDef.skeletonFn
893
+ ? curveDef.skeletonFn(phase)
894
+ : curveDef.fn(phase, 0, EMPTY_PARAMS2);
875
895
  }
876
896
  return pts;
877
897
  }
@@ -883,7 +903,7 @@ function createSVGRenderer(options) {
883
903
  const poolSize = engine.trailLength;
884
904
  if (poolSize > HIGH_TRAIL_LENGTH_THRESHOLD) {
885
905
  console.warn(
886
- `[sarmal] High trailLength in SVG renderer (${poolSize}). Consider using the canvas renderer for long trails.`
906
+ `[sarmal] High trailLength in SVG renderer (${poolSize}). Consider using the canvas renderer for long trails.`,
887
907
  );
888
908
  }
889
909
  let trailStyle = options.trailStyle ?? "default";
@@ -902,9 +922,9 @@ function createSVGRenderer(options) {
902
922
  return rect.width && rect.height ? Math.min(rect.width, rect.height) : 200;
903
923
  }
904
924
  const containerPx = getContainerPixelSize();
905
- const svgTrailMinWidth = TRAIL_MIN_WIDTH * viewSize / containerPx;
906
- const svgTrailMaxWidth = TRAIL_MAX_WIDTH * viewSize / containerPx;
907
- const svgSkeletonStrokeWidth = String(SKELETON_STROKE_WIDTH_PX * viewSize / containerPx);
925
+ const svgTrailMinWidth = (TRAIL_MIN_WIDTH * viewSize) / containerPx;
926
+ const svgTrailMaxWidth = (TRAIL_MAX_WIDTH * viewSize) / containerPx;
927
+ const svgSkeletonStrokeWidth = String((SKELETON_STROKE_WIDTH_PX * viewSize) / containerPx);
908
928
  headRadius = options.headRadius ?? SVG_DEFAULT_HEAD_RADIUS;
909
929
  container.setAttribute("viewBox", `0 0 ${viewSize} ${viewSize}`);
910
930
  container.setAttribute("role", "img");
@@ -992,7 +1012,7 @@ function createSVGRenderer(options) {
992
1012
  px,
993
1013
  py,
994
1014
  svgTrailMinWidth,
995
- svgTrailMaxWidth
1015
+ svgTrailMaxWidth,
996
1016
  );
997
1017
  const d = `M${l0x.toFixed(2)} ${l0y.toFixed(2)} L${l1x.toFixed(2)} ${l1y.toFixed(2)} L${r1x.toFixed(2)} ${r1y.toFixed(2)} L${r0x.toFixed(2)} ${r0y.toFixed(2)} Z`;
998
1018
  trailPaths[i].setAttribute("d", d);
@@ -1020,7 +1040,8 @@ function createSVGRenderer(options) {
1020
1040
  let animationId = null;
1021
1041
  let lastTime = 0;
1022
1042
  let pausedByVisibility = false;
1023
- const prefersReducedMotion = typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
1043
+ const prefersReducedMotion =
1044
+ typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
1024
1045
  let morphResolve = null;
1025
1046
  let morphReject = null;
1026
1047
  let morphDurationMs = DEFAULT_MORPH_DURATION_MS;
@@ -1038,7 +1059,7 @@ function createSVGRenderer(options) {
1038
1059
  skeletonPathA.setAttribute("visibility", "visible");
1039
1060
  skeletonPathA.setAttribute(
1040
1061
  "stroke-opacity",
1041
- String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY)
1062
+ String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY),
1042
1063
  );
1043
1064
  }
1044
1065
  if (morphPathBBuilt) {
@@ -1192,7 +1213,7 @@ function createSVGRenderer(options) {
1192
1213
  if (partial.trailColor !== void 0 || partial.trailStyle !== void 0) {
1193
1214
  warnIfTrailColorMismatch(trailColor, trailStyle);
1194
1215
  }
1195
- }
1216
+ },
1196
1217
  };
1197
1218
  const pauseOnHidden = options.pauseOnHidden !== false;
1198
1219
  function handleVisibilityChange() {
@@ -1230,7 +1251,13 @@ var PERIOD = 2 * Math.PI;
1230
1251
  function catmullRom1D(p0, p1, p2, p3, u) {
1231
1252
  const u2 = u * u;
1232
1253
  const u3 = u2 * u;
1233
- return 0.5 * (2 * p1 + (-p0 + p2) * u + (2 * p0 - 5 * p1 + 4 * p2 - p3) * u2 + (-p0 + 3 * p1 - 3 * p2 + p3) * u3);
1254
+ return (
1255
+ 0.5 *
1256
+ (2 * p1 +
1257
+ (-p0 + p2) * u +
1258
+ (2 * p0 - 5 * p1 + 4 * p2 - p3) * u2 +
1259
+ (-p0 + 3 * p1 - 3 * p2 + p3) * u3)
1260
+ );
1234
1261
  }
1235
1262
  function evaluateCatmullRom(points2, phase) {
1236
1263
  const N = points2.length;
@@ -1240,7 +1267,7 @@ function evaluateCatmullRom(points2, phase) {
1240
1267
  if (N === 1) {
1241
1268
  return { x: points2[0][0], y: points2[0][1] };
1242
1269
  }
1243
- phase = (phase % PERIOD + PERIOD) % PERIOD;
1270
+ phase = ((phase % PERIOD) + PERIOD) % PERIOD;
1244
1271
  const segmentSize = PERIOD / N;
1245
1272
  let i = Math.floor(phase / segmentSize);
1246
1273
  if (i >= N) {
@@ -1254,7 +1281,7 @@ function evaluateCatmullRom(points2, phase) {
1254
1281
  const p3 = points2[(i + 2) % N];
1255
1282
  return {
1256
1283
  x: catmullRom1D(p0[0], p1[0], p2[0], p3[0], u),
1257
- y: catmullRom1D(p0[1], p1[1], p2[1], p3[1], u)
1284
+ y: catmullRom1D(p0[1], p1[1], p2[1], p3[1], u),
1258
1285
  };
1259
1286
  }
1260
1287
  function drawCurve(points2, opts) {
@@ -1264,20 +1291,20 @@ function drawCurve(points2, opts) {
1264
1291
  const first = points2[0];
1265
1292
  if (points2.every((p) => p[0] === first[0] && p[1] === first[1])) {
1266
1293
  console.warn(
1267
- "[sarmal].drawCurve: all control points are identical. The curve will be a single point."
1294
+ "[sarmal].drawCurve: all control points are identical. The curve will be a single point.",
1268
1295
  );
1269
1296
  }
1270
1297
  const maxAbs = points2.reduce((m, p) => Math.max(m, Math.abs(p[0]), Math.abs(p[1])), 0);
1271
1298
  if (maxAbs > 2) {
1272
1299
  console.warn(
1273
- `[sarmal].drawCurve: control points extend to \xB1${maxAbs.toFixed(1)}, which may render off-screen. Coordinates should be in [-1, 1].`
1300
+ `[sarmal].drawCurve: control points extend to \xB1${maxAbs.toFixed(1)}, which may render off-screen. Coordinates should be in [-1, 1].`,
1274
1301
  );
1275
1302
  }
1276
1303
  const pts = points2.map(([x, y]) => [x, y]);
1277
1304
  return {
1278
1305
  name: opts?.name ?? "drawn",
1279
1306
  fn: (phase) => evaluateCatmullRom(pts, phase),
1280
- period: PERIOD
1307
+ period: PERIOD,
1281
1308
  };
1282
1309
  }
1283
1310
 
@@ -1303,11 +1330,11 @@ var points = [
1303
1330
  [-0.69, -0.84],
1304
1331
  [-0.87, -0.66],
1305
1332
  [-0.9, -0.47],
1306
- [-0.76, -0.35]
1333
+ [-0.76, -0.35],
1307
1334
  ];
1308
1335
  var artemis2 = {
1309
1336
  ...drawCurve(points, { name: "Artemis II" }),
1310
- speed: 0.7
1337
+ speed: 0.7,
1311
1338
  };
1312
1339
 
1313
1340
  // src/curves/astroid.ts
@@ -1317,14 +1344,14 @@ function astroidFn(phase, _elapsed, _params) {
1317
1344
  const s = Math.sin(phase);
1318
1345
  return {
1319
1346
  x: c * c * c,
1320
- y: s * s * s
1347
+ y: s * s * s,
1321
1348
  };
1322
1349
  }
1323
1350
  var astroid = {
1324
1351
  name: "Astroid",
1325
1352
  fn: astroidFn,
1326
1353
  period: TWO_PI2,
1327
- speed: 1.1
1354
+ speed: 1.1,
1328
1355
  };
1329
1356
 
1330
1357
  // src/curves/deltoid.ts
@@ -1332,14 +1359,14 @@ var TWO_PI3 = Math.PI * 2;
1332
1359
  function deltoidFn(phase, _elapsed, _params) {
1333
1360
  return {
1334
1361
  x: 2 * Math.cos(phase) + Math.cos(2 * phase),
1335
- y: 2 * Math.sin(phase) - Math.sin(2 * phase)
1362
+ y: 2 * Math.sin(phase) - Math.sin(2 * phase),
1336
1363
  };
1337
1364
  }
1338
1365
  var deltoid = {
1339
1366
  name: "Deltoid",
1340
1367
  fn: deltoidFn,
1341
1368
  period: TWO_PI3,
1342
- speed: 0.9
1369
+ speed: 0.9,
1343
1370
  };
1344
1371
 
1345
1372
  // src/curves/epicycloid3.ts
@@ -1347,14 +1374,14 @@ var TWO_PI4 = Math.PI * 2;
1347
1374
  function epicycloid3Fn(phase, _elapsed, _params) {
1348
1375
  return {
1349
1376
  x: 4 * Math.cos(phase) - Math.cos(4 * phase),
1350
- y: 4 * Math.sin(phase) - Math.sin(4 * phase)
1377
+ y: 4 * Math.sin(phase) - Math.sin(4 * phase),
1351
1378
  };
1352
1379
  }
1353
1380
  var epicycloid3 = {
1354
1381
  name: "Epicycloid (n=3)",
1355
1382
  fn: epicycloid3Fn,
1356
1383
  period: TWO_PI4,
1357
- speed: 0.75
1384
+ speed: 0.75,
1358
1385
  };
1359
1386
 
1360
1387
  // src/curves/epitrochoid7.ts
@@ -1363,14 +1390,14 @@ function epitrochoid7Fn(phase, _elapsed, _params) {
1363
1390
  const d = 1 + 0.55 * Math.sin(phase * 0.5);
1364
1391
  return {
1365
1392
  x: 7 * Math.cos(phase) - d * Math.cos(7 * phase),
1366
- y: 7 * Math.sin(phase) - d * Math.sin(7 * phase)
1393
+ y: 7 * Math.sin(phase) - d * Math.sin(7 * phase),
1367
1394
  };
1368
1395
  }
1369
1396
  function epitrochoid7SkeletonFn(phase) {
1370
1397
  const d = 1.275;
1371
1398
  return {
1372
1399
  x: 7 * Math.cos(phase) - d * Math.cos(7 * phase),
1373
- y: 7 * Math.sin(phase) - d * Math.sin(7 * phase)
1400
+ y: 7 * Math.sin(phase) - d * Math.sin(7 * phase),
1374
1401
  };
1375
1402
  }
1376
1403
  var epitrochoid7 = {
@@ -1378,7 +1405,7 @@ var epitrochoid7 = {
1378
1405
  fn: epitrochoid7Fn,
1379
1406
  period: TWO_PI5,
1380
1407
  speed: 1.4,
1381
- skeletonFn: epitrochoid7SkeletonFn
1408
+ skeletonFn: epitrochoid7SkeletonFn,
1382
1409
  };
1383
1410
 
1384
1411
  // src/curves/lissajous32.ts
@@ -1387,7 +1414,7 @@ function lissajous32Fn(phase, elapsed, _params) {
1387
1414
  const phi = elapsed * 0.45;
1388
1415
  return {
1389
1416
  x: Math.sin(3 * phase + phi),
1390
- y: Math.sin(2 * phase)
1417
+ y: Math.sin(2 * phase),
1391
1418
  };
1392
1419
  }
1393
1420
  var lissajous32 = {
@@ -1395,7 +1422,7 @@ var lissajous32 = {
1395
1422
  fn: lissajous32Fn,
1396
1423
  period: TWO_PI6,
1397
1424
  speed: 2,
1398
- skeleton: "live"
1425
+ skeleton: "live",
1399
1426
  };
1400
1427
 
1401
1428
  // src/curves/lissajous43.ts
@@ -1404,7 +1431,7 @@ function lissajous43Fn(phase, elapsed, _params) {
1404
1431
  const phi = elapsed * 0.38;
1405
1432
  return {
1406
1433
  x: Math.sin(4 * phase + phi),
1407
- y: Math.sin(3 * phase)
1434
+ y: Math.sin(3 * phase),
1408
1435
  };
1409
1436
  }
1410
1437
  var lissajous43 = {
@@ -1412,17 +1439,18 @@ var lissajous43 = {
1412
1439
  fn: lissajous43Fn,
1413
1440
  period: TWO_PI7,
1414
1441
  speed: 1.8,
1415
- skeleton: "live"
1442
+ skeleton: "live",
1416
1443
  };
1417
1444
 
1418
1445
  // src/curves/lame.ts
1419
1446
  var TWO_PI8 = Math.PI * 2;
1420
1447
  function lameFn(phase, elapsed, _params) {
1421
1448
  const p = 1.75 + 1.25 * Math.sin(elapsed * 0.48);
1422
- const c = Math.cos(phase), s = Math.sin(phase);
1449
+ const c = Math.cos(phase),
1450
+ s = Math.sin(phase);
1423
1451
  return {
1424
1452
  x: Math.sign(c) * Math.pow(Math.abs(c), p),
1425
- y: Math.sign(s) * Math.pow(Math.abs(s), p)
1453
+ y: Math.sign(s) * Math.pow(Math.abs(s), p),
1426
1454
  };
1427
1455
  }
1428
1456
  var lame = {
@@ -1430,7 +1458,7 @@ var lame = {
1430
1458
  fn: lameFn,
1431
1459
  period: TWO_PI8,
1432
1460
  speed: 1,
1433
- skeleton: "live"
1461
+ skeleton: "live",
1434
1462
  };
1435
1463
 
1436
1464
  // src/curves/rose3.ts
@@ -1439,14 +1467,14 @@ function rose3Fn(phase, _elapsed, _params) {
1439
1467
  const r = Math.cos(3 * phase);
1440
1468
  return {
1441
1469
  x: r * Math.cos(phase),
1442
- y: r * Math.sin(phase)
1470
+ y: r * Math.sin(phase),
1443
1471
  };
1444
1472
  }
1445
1473
  var rose3 = {
1446
1474
  name: "Rose (n=3)",
1447
1475
  fn: rose3Fn,
1448
1476
  period: TWO_PI9,
1449
- speed: 1.15
1477
+ speed: 1.15,
1450
1478
  };
1451
1479
 
1452
1480
  // src/curves/rose5.ts
@@ -1455,78 +1483,87 @@ function rose5Fn(phase, _elapsed, _params) {
1455
1483
  const r = Math.cos(5 * phase);
1456
1484
  return {
1457
1485
  x: r * Math.cos(phase),
1458
- y: r * Math.sin(phase)
1486
+ y: r * Math.sin(phase),
1459
1487
  };
1460
1488
  }
1461
1489
  var rose5 = {
1462
1490
  name: "Rose (n=5)",
1463
1491
  fn: rose5Fn,
1464
1492
  period: TWO_PI10,
1465
- speed: 1
1493
+ speed: 1,
1466
1494
  };
1467
1495
 
1468
1496
  // src/curves/rose52.ts
1469
1497
  var FOUR_PI = Math.PI * 4;
1470
1498
  function rose52Fn(phase, _elapsed, _params) {
1471
- const r = Math.cos(5 / 2 * phase);
1499
+ const r = Math.cos((5 / 2) * phase);
1472
1500
  return {
1473
1501
  x: r * Math.cos(phase),
1474
- y: r * Math.sin(phase)
1502
+ y: r * Math.sin(phase),
1475
1503
  };
1476
1504
  }
1477
1505
  var rose52 = {
1478
1506
  name: "Rose (n=5/2)",
1479
1507
  fn: rose52Fn,
1480
1508
  period: FOUR_PI,
1481
- speed: 0.8
1509
+ speed: 0.8,
1482
1510
  };
1483
1511
 
1484
1512
  // src/curves/star.ts
1485
1513
  var TWO_PI11 = Math.PI * 2;
1486
1514
  function starFn(phase, _elapsed, _params) {
1487
- const r = Math.abs(Math.cos(5 / 2 * phase)) + 0.35 * Math.abs(Math.cos(15 / 2 * phase)) + 0.15 * Math.abs(Math.cos(25 / 2 * phase));
1515
+ const r =
1516
+ Math.abs(Math.cos((5 / 2) * phase)) +
1517
+ 0.35 * Math.abs(Math.cos((15 / 2) * phase)) +
1518
+ 0.15 * Math.abs(Math.cos((25 / 2) * phase));
1488
1519
  return {
1489
1520
  x: r * Math.cos(phase),
1490
- y: r * Math.sin(phase)
1521
+ y: r * Math.sin(phase),
1491
1522
  };
1492
1523
  }
1493
1524
  var star = {
1494
1525
  name: "Star",
1495
1526
  fn: starFn,
1496
1527
  period: TWO_PI11,
1497
- speed: 1
1528
+ speed: 1,
1498
1529
  };
1499
1530
 
1500
1531
  // src/curves/star4.ts
1501
1532
  var TWO_PI12 = Math.PI * 2;
1502
1533
  function star4Fn(phase, _elapsed, _params) {
1503
- const r = Math.abs(Math.cos(2 * phase)) + 0.35 * Math.abs(Math.cos(6 * phase)) + 0.15 * Math.abs(Math.cos(10 * phase));
1534
+ const r =
1535
+ Math.abs(Math.cos(2 * phase)) +
1536
+ 0.35 * Math.abs(Math.cos(6 * phase)) +
1537
+ 0.15 * Math.abs(Math.cos(10 * phase));
1504
1538
  return {
1505
1539
  x: r * Math.cos(phase),
1506
- y: r * Math.sin(phase)
1540
+ y: r * Math.sin(phase),
1507
1541
  };
1508
1542
  }
1509
1543
  var star4 = {
1510
1544
  name: "Star (4-arm)",
1511
1545
  fn: star4Fn,
1512
1546
  period: TWO_PI12,
1513
- speed: 1
1547
+ speed: 1,
1514
1548
  };
1515
1549
 
1516
1550
  // src/curves/star7.ts
1517
1551
  var TWO_PI13 = Math.PI * 2;
1518
1552
  function star7Fn(phase, _elapsed, _params) {
1519
- const r = Math.abs(Math.cos(7 / 2 * phase)) + 0.35 * Math.abs(Math.cos(21 / 2 * phase)) + 0.15 * Math.abs(Math.cos(35 / 2 * phase));
1553
+ const r =
1554
+ Math.abs(Math.cos((7 / 2) * phase)) +
1555
+ 0.35 * Math.abs(Math.cos((21 / 2) * phase)) +
1556
+ 0.15 * Math.abs(Math.cos((35 / 2) * phase));
1520
1557
  return {
1521
1558
  x: r * Math.cos(phase),
1522
- y: r * Math.sin(phase)
1559
+ y: r * Math.sin(phase),
1523
1560
  };
1524
1561
  }
1525
1562
  var star7 = {
1526
1563
  name: "Star (7-arm)",
1527
1564
  fn: star7Fn,
1528
1565
  period: TWO_PI13,
1529
- speed: 1
1566
+ speed: 1,
1530
1567
  };
1531
1568
 
1532
1569
  // src/curves/index.ts
@@ -1544,7 +1581,7 @@ var curves = {
1544
1581
  lissajous32,
1545
1582
  lissajous43,
1546
1583
  epicycloid3,
1547
- lame
1584
+ lame,
1548
1585
  };
1549
1586
 
1550
1587
  // src/index.ts
@@ -1561,22 +1598,21 @@ function parseTrailColor(value) {
1561
1598
  if (Array.isArray(parsed)) {
1562
1599
  return parsed;
1563
1600
  }
1564
- } catch {
1565
- }
1601
+ } catch {}
1566
1602
  return value;
1567
1603
  }
1568
1604
  function buildOptions(el2) {
1569
1605
  return {
1570
- ...el2.dataset.trailColor && {
1571
- trailColor: parseTrailColor(el2.dataset.trailColor)
1572
- },
1573
- ...el2.dataset.skeletonColor && { skeletonColor: el2.dataset.skeletonColor },
1574
- ...el2.dataset.headColor && { headColor: el2.dataset.headColor },
1575
- ...el2.dataset.headRadius && { headRadius: parseFloat(el2.dataset.headRadius) },
1576
- ...el2.dataset.trailLength && { trailLength: parseInt(el2.dataset.trailLength, 10) },
1577
- ...el2.dataset.trailStyle && {
1578
- trailStyle: el2.dataset.trailStyle
1579
- }
1606
+ ...(el2.dataset.trailColor && {
1607
+ trailColor: parseTrailColor(el2.dataset.trailColor),
1608
+ }),
1609
+ ...(el2.dataset.skeletonColor && { skeletonColor: el2.dataset.skeletonColor }),
1610
+ ...(el2.dataset.headColor && { headColor: el2.dataset.headColor }),
1611
+ ...(el2.dataset.headRadius && { headRadius: parseFloat(el2.dataset.headRadius) }),
1612
+ ...(el2.dataset.trailLength && { trailLength: parseInt(el2.dataset.trailLength, 10) }),
1613
+ ...(el2.dataset.trailStyle && {
1614
+ trailStyle: el2.dataset.trailStyle,
1615
+ }),
1580
1616
  };
1581
1617
  }
1582
1618
  function init() {
@@ -1591,7 +1627,10 @@ function init() {
1591
1627
  return console.error(`[sarmal] "${curveName}" is not a valid curve name`);
1592
1628
  }
1593
1629
  const options = buildOptions(el2);
1594
- const instance = el2 instanceof HTMLCanvasElement ? createSarmal(el2, curveDef, options) : createSarmalSVG(el2, curveDef, options);
1630
+ const instance =
1631
+ el2 instanceof HTMLCanvasElement
1632
+ ? createSarmal(el2, curveDef, options)
1633
+ : createSarmalSVG(el2, curveDef, options);
1595
1634
  if (el2.dataset.speed) {
1596
1635
  instance.setSpeed(parseFloat(el2.dataset.speed));
1597
1636
  }
@@ -1607,4 +1646,4 @@ if (document.readyState === "loading") {
1607
1646
 
1608
1647
  export { init };
1609
1648
  //# sourceMappingURL=auto-init.js.map
1610
- //# sourceMappingURL=auto-init.js.map
1649
+ //# sourceMappingURL=auto-init.js.map