@sarmal/core 0.27.0 → 0.28.1

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