@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.
- package/dist/auto-init.cjs +106 -145
- package/dist/auto-init.js +105 -144
- package/dist/cli.js +103 -145
- package/dist/cli.js.map +1 -1
- package/dist/curves/artemis2.cjs +10 -16
- package/dist/curves/artemis2.d.cts +1 -1
- package/dist/curves/artemis2.d.ts +1 -1
- package/dist/curves/artemis2.js +9 -15
- package/dist/curves/astroid.cjs +4 -4
- package/dist/curves/astroid.d.cts +1 -1
- package/dist/curves/astroid.d.ts +1 -1
- package/dist/curves/astroid.js +3 -3
- package/dist/curves/deltoid.cjs +4 -4
- package/dist/curves/deltoid.d.cts +1 -1
- package/dist/curves/deltoid.d.ts +1 -1
- package/dist/curves/deltoid.js +3 -3
- package/dist/curves/epicycloid3.cjs +4 -4
- package/dist/curves/epicycloid3.d.cts +1 -1
- package/dist/curves/epicycloid3.d.ts +1 -1
- package/dist/curves/epicycloid3.js +3 -3
- package/dist/curves/epitrochoid7.cjs +5 -5
- package/dist/curves/epitrochoid7.d.cts +1 -1
- package/dist/curves/epitrochoid7.d.ts +1 -1
- package/dist/curves/epitrochoid7.js +4 -4
- package/dist/curves/index.cjs +43 -59
- package/dist/curves/index.d.cts +29 -29
- package/dist/curves/index.d.ts +29 -29
- package/dist/curves/index.js +43 -75
- package/dist/curves/lame.cjs +5 -6
- package/dist/curves/lame.d.cts +1 -1
- package/dist/curves/lame.d.ts +1 -1
- package/dist/curves/lame.js +4 -5
- package/dist/curves/lissajous32.cjs +4 -4
- package/dist/curves/lissajous32.d.cts +1 -1
- package/dist/curves/lissajous32.d.ts +1 -1
- package/dist/curves/lissajous32.js +3 -3
- package/dist/curves/lissajous43.cjs +4 -4
- package/dist/curves/lissajous43.d.cts +1 -1
- package/dist/curves/lissajous43.d.ts +1 -1
- package/dist/curves/lissajous43.js +3 -3
- package/dist/curves/rose3.cjs +4 -4
- package/dist/curves/rose3.d.cts +1 -1
- package/dist/curves/rose3.d.ts +1 -1
- package/dist/curves/rose3.js +3 -3
- package/dist/curves/rose5.cjs +4 -4
- package/dist/curves/rose5.d.cts +1 -1
- package/dist/curves/rose5.d.ts +1 -1
- package/dist/curves/rose5.js +3 -3
- package/dist/curves/rose52.cjs +5 -5
- package/dist/curves/rose52.d.cts +1 -1
- package/dist/curves/rose52.d.ts +1 -1
- package/dist/curves/rose52.js +4 -4
- package/dist/curves/star.cjs +5 -8
- package/dist/curves/star.d.cts +1 -1
- package/dist/curves/star.d.ts +1 -1
- package/dist/curves/star.js +4 -7
- package/dist/curves/star4.cjs +5 -8
- package/dist/curves/star4.d.cts +1 -1
- package/dist/curves/star4.d.ts +1 -1
- package/dist/curves/star4.js +4 -7
- package/dist/curves/star7.cjs +5 -8
- package/dist/curves/star7.d.cts +1 -1
- package/dist/curves/star7.d.ts +1 -1
- package/dist/curves/star7.js +4 -7
- package/dist/index.cjs +94 -131
- package/dist/index.d.cts +30 -78
- package/dist/index.d.ts +30 -78
- package/dist/index.js +94 -152
- package/dist/renderer-shared-OR--cv-t.d.ts +15 -26
- package/dist/renderer-shared-jqw_Q1WO.d.cts +15 -26
- package/dist/terminal.cjs +52 -75
- package/dist/terminal.cjs.map +1 -1
- package/dist/terminal.d.cts +14 -31
- package/dist/terminal.d.ts +14 -31
- package/dist/terminal.js +51 -74
- package/dist/terminal.js.map +1 -1
- package/dist/types-zbxUgcmZ.d.cts +266 -280
- package/dist/types-zbxUgcmZ.d.ts +266 -280
- package/package.json +9 -3
- package/skills/core/SKILL.md +151 -0
package/dist/cli.js
CHANGED
|
@@ -62,13 +62,13 @@ function resolveCurve(curveDef) {
|
|
|
62
62
|
period,
|
|
63
63
|
speed,
|
|
64
64
|
skeleton: curveDef.skeleton,
|
|
65
|
-
skeletonFn: curveDef.skeletonFn
|
|
65
|
+
skeletonFn: curveDef.skeletonFn
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
function createEngine(curveDef, trailLength = 120) {
|
|
69
69
|
if (!Number.isFinite(trailLength) || trailLength <= 0) {
|
|
70
70
|
throw new RangeError(
|
|
71
|
-
`[sarmal] trailLength must be a positive finite number, got ${trailLength}
|
|
71
|
+
`[sarmal] trailLength must be a positive finite number, got ${trailLength}`
|
|
72
72
|
);
|
|
73
73
|
}
|
|
74
74
|
let curve = resolveCurve(curveDef);
|
|
@@ -109,8 +109,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
109
109
|
actualTime += deltaTime;
|
|
110
110
|
if (morphCurveB !== null && _morphAlpha !== null) {
|
|
111
111
|
const a = curve.fn(phase, actualTime, EMPTY_PARAMS);
|
|
112
|
-
const phaseB =
|
|
113
|
-
_morphStrategy === "normalized" ? (phase / curve.period) * morphCurveB.period : phase;
|
|
112
|
+
const phaseB = _morphStrategy === "normalized" ? phase / curve.period * morphCurveB.period : phase;
|
|
114
113
|
const b = morphCurveB.fn(phaseB, actualTime, EMPTY_PARAMS);
|
|
115
114
|
trail.push(a.x + (b.x - a.x) * _morphAlpha, a.y + (b.y - a.y) * _morphAlpha);
|
|
116
115
|
} else {
|
|
@@ -137,14 +136,14 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
137
136
|
trail.clear();
|
|
138
137
|
},
|
|
139
138
|
jump(newPhase, { clearTrail = false } = {}) {
|
|
140
|
-
phase = (
|
|
139
|
+
phase = (newPhase % curve.period + curve.period) % curve.period;
|
|
141
140
|
if (clearTrail) {
|
|
142
141
|
trail.clear();
|
|
143
142
|
}
|
|
144
143
|
},
|
|
145
144
|
seek(targetPhase, { wrap = false, step = curve.period / trailLength } = {}) {
|
|
146
145
|
const advance = curve.speed * step;
|
|
147
|
-
const target = (
|
|
146
|
+
const target = (targetPhase % curve.period + curve.period) % curve.period;
|
|
148
147
|
const targetTime = target / curve.speed;
|
|
149
148
|
phase = target;
|
|
150
149
|
actualTime = targetTime;
|
|
@@ -153,7 +152,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
153
152
|
const count = wrap ? trailLength : Math.min(trailLength, pointsFromStart);
|
|
154
153
|
for (let i = count - 1; i >= 0; i--) {
|
|
155
154
|
const samplePhase = target - i * advance;
|
|
156
|
-
const wrappedPhase = (
|
|
155
|
+
const wrappedPhase = (samplePhase % curve.period + curve.period) % curve.period;
|
|
157
156
|
const elapsed = targetTime - i * step;
|
|
158
157
|
const point = curve.fn(wrappedPhase, elapsed, EMPTY_PARAMS);
|
|
159
158
|
trail.push(point.x, point.y);
|
|
@@ -170,16 +169,13 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
170
169
|
...frozenB,
|
|
171
170
|
fn: (samplePhase, elapsed, params) => {
|
|
172
171
|
const a = frozenA.fn(samplePhase, elapsed, params);
|
|
173
|
-
const phaseB =
|
|
174
|
-
frozenStrategy === "normalized"
|
|
175
|
-
? (samplePhase / frozenA.period) * frozenB.period
|
|
176
|
-
: samplePhase;
|
|
172
|
+
const phaseB = frozenStrategy === "normalized" ? samplePhase / frozenA.period * frozenB.period : samplePhase;
|
|
177
173
|
const b = frozenB.fn(phaseB, elapsed, params);
|
|
178
174
|
return {
|
|
179
175
|
x: a.x + (b.x - a.x) * frozenAlpha,
|
|
180
|
-
y: a.y + (b.y - a.y) * frozenAlpha
|
|
176
|
+
y: a.y + (b.y - a.y) * frozenAlpha
|
|
181
177
|
};
|
|
182
|
-
}
|
|
178
|
+
}
|
|
183
179
|
};
|
|
184
180
|
}
|
|
185
181
|
_morphStrategy = strategy;
|
|
@@ -192,7 +188,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
192
188
|
completeMorph() {
|
|
193
189
|
if (morphCurveB !== null) {
|
|
194
190
|
if (_morphStrategy === "normalized" && curve.period !== morphCurveB.period) {
|
|
195
|
-
phase =
|
|
191
|
+
phase = phase / curve.period * morphCurveB.period;
|
|
196
192
|
}
|
|
197
193
|
curve = morphCurveB;
|
|
198
194
|
}
|
|
@@ -204,22 +200,19 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
204
200
|
const points2 = new Array(steps);
|
|
205
201
|
if (morphCurveB !== null && _morphAlpha !== null) {
|
|
206
202
|
for (let i = 0; i < steps; i++) {
|
|
207
|
-
const samplePhase =
|
|
203
|
+
const samplePhase = i / (steps - 1) * curve.period;
|
|
208
204
|
const a = sampleSkeleton(curve, samplePhase);
|
|
209
|
-
const phaseB =
|
|
210
|
-
_morphStrategy === "normalized"
|
|
211
|
-
? (samplePhase / curve.period) * morphCurveB.period
|
|
212
|
-
: samplePhase;
|
|
205
|
+
const phaseB = _morphStrategy === "normalized" ? samplePhase / curve.period * morphCurveB.period : samplePhase;
|
|
213
206
|
const b = sampleSkeleton(morphCurveB, phaseB);
|
|
214
207
|
points2[i] = {
|
|
215
208
|
x: a.x + (b.x - a.x) * _morphAlpha,
|
|
216
|
-
y: a.y + (b.y - a.y) * _morphAlpha
|
|
209
|
+
y: a.y + (b.y - a.y) * _morphAlpha
|
|
217
210
|
};
|
|
218
211
|
}
|
|
219
212
|
return points2;
|
|
220
213
|
}
|
|
221
214
|
for (let i = 0; i < steps; i++) {
|
|
222
|
-
const samplePhase =
|
|
215
|
+
const samplePhase = i / (steps - 1) * curve.period;
|
|
223
216
|
points2[i] = sampleSkeleton(curve, samplePhase);
|
|
224
217
|
}
|
|
225
218
|
return points2;
|
|
@@ -261,7 +254,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
261
254
|
_speedTransition.reject(new Error("Speed transition cancelled"));
|
|
262
255
|
_speedTransition = null;
|
|
263
256
|
}
|
|
264
|
-
}
|
|
257
|
+
}
|
|
265
258
|
};
|
|
266
259
|
}
|
|
267
260
|
|
|
@@ -271,10 +264,7 @@ var FIT_PADDING_MIN = 4;
|
|
|
271
264
|
function computeBoundaries(pts, logicalWidth, logicalHeight, minPaddingPx = FIT_PADDING_MIN) {
|
|
272
265
|
if (pts.length === 0) return null;
|
|
273
266
|
const first = pts[0];
|
|
274
|
-
let minX = first.x,
|
|
275
|
-
maxX = first.x,
|
|
276
|
-
minY = first.y,
|
|
277
|
-
maxY = first.y;
|
|
267
|
+
let minX = first.x, maxX = first.x, minY = first.y, maxY = first.y;
|
|
278
268
|
for (const p of pts) {
|
|
279
269
|
if (p.x < minX) {
|
|
280
270
|
minX = p.x;
|
|
@@ -293,7 +283,7 @@ function computeBoundaries(pts, logicalWidth, logicalHeight, minPaddingPx = FIT_
|
|
|
293
283
|
const h = maxY - minY;
|
|
294
284
|
if (w === 0 && h === 0) {
|
|
295
285
|
throw new Error(
|
|
296
|
-
"[sarmal] Degenerate curve: all skeleton points are identical. Check that your curve fn returns distinct points for different values of t."
|
|
286
|
+
"[sarmal] Degenerate curve: all skeleton points are identical. Check that your curve fn returns distinct points for different values of t."
|
|
297
287
|
);
|
|
298
288
|
}
|
|
299
289
|
const scaleXProportional = logicalWidth / (w * (1 + FIT_PADDING * 2));
|
|
@@ -304,17 +294,17 @@ function computeBoundaries(pts, logicalWidth, logicalHeight, minPaddingPx = FIT_
|
|
|
304
294
|
scaleXProportional,
|
|
305
295
|
scaleYProportional,
|
|
306
296
|
scaleXMinPadding,
|
|
307
|
-
scaleYMinPadding
|
|
297
|
+
scaleYMinPadding
|
|
308
298
|
);
|
|
309
299
|
return {
|
|
310
300
|
scale,
|
|
311
301
|
offsetX: (logicalWidth - w * scale) / 2 - minX * scale,
|
|
312
|
-
offsetY: (logicalHeight - h * scale) / 2 - minY * scale
|
|
302
|
+
offsetY: (logicalHeight - h * scale) / 2 - minY * scale
|
|
313
303
|
};
|
|
314
304
|
}
|
|
315
305
|
function hexToRgb(hex) {
|
|
316
306
|
const n = parseInt(hex.slice(1), 16);
|
|
317
|
-
return { r: n >> 16, g:
|
|
307
|
+
return { r: n >> 16, g: n >> 8 & 255, b: n & 255 };
|
|
318
308
|
}
|
|
319
309
|
|
|
320
310
|
// src/terminal.ts
|
|
@@ -328,7 +318,7 @@ var BRAILLE_BIT = [
|
|
|
328
318
|
[1, 8],
|
|
329
319
|
[2, 16],
|
|
330
320
|
[4, 32],
|
|
331
|
-
[64, 128]
|
|
321
|
+
[64, 128]
|
|
332
322
|
];
|
|
333
323
|
function brailleChar(bits) {
|
|
334
324
|
return String.fromCodePoint(BRAILLE_BASE + (bits & 255));
|
|
@@ -338,7 +328,7 @@ function dotToCell(dotCol, dotRow) {
|
|
|
338
328
|
charCol: Math.floor(dotCol / 2),
|
|
339
329
|
charRow: Math.floor(dotRow / 4),
|
|
340
330
|
dotColInCell: dotCol % 2,
|
|
341
|
-
dotRowInCell: dotRow % 4
|
|
331
|
+
dotRowInCell: dotRow % 4
|
|
342
332
|
};
|
|
343
333
|
}
|
|
344
334
|
function detectColor() {
|
|
@@ -353,13 +343,10 @@ function detectColor() {
|
|
|
353
343
|
if (term.includes("truecolor") || term.includes("24bit")) {
|
|
354
344
|
return "truecolor";
|
|
355
345
|
}
|
|
356
|
-
if (
|
|
357
|
-
return "
|
|
358
|
-
}
|
|
359
|
-
if (term !== "" && term !== "linux" && term !== "dumb") {
|
|
360
|
-
return "256-color";
|
|
346
|
+
if (term === "" || term === "linux" || term === "dumb") {
|
|
347
|
+
return "monochrome";
|
|
361
348
|
}
|
|
362
|
-
return "
|
|
349
|
+
return "256-color";
|
|
363
350
|
}
|
|
364
351
|
function rgbTo256(r, g, b) {
|
|
365
352
|
const avg = Math.round((r + g + b) / 3);
|
|
@@ -369,9 +356,9 @@ function rgbTo256(r, g, b) {
|
|
|
369
356
|
}
|
|
370
357
|
return 232 + Math.min(23, Math.round((avg - 8) / 10));
|
|
371
358
|
}
|
|
372
|
-
const ri = Math.round(
|
|
373
|
-
const gi = Math.round(
|
|
374
|
-
const bi = Math.round(
|
|
359
|
+
const ri = Math.round(r / 255 * 5);
|
|
360
|
+
const gi = Math.round(g / 255 * 5);
|
|
361
|
+
const bi = Math.round(b / 255 * 5);
|
|
375
362
|
return 16 + 36 * ri + 6 * gi + bi;
|
|
376
363
|
}
|
|
377
364
|
var AR = "\x1B[0m";
|
|
@@ -396,25 +383,18 @@ function snapCol(col, max) {
|
|
|
396
383
|
function applyBoundary(x, y, scale, offsetX, offsetY) {
|
|
397
384
|
return {
|
|
398
385
|
screenX: x * scale + offsetX,
|
|
399
|
-
screenY: y * scale + offsetY
|
|
386
|
+
screenY: y * scale + offsetY
|
|
400
387
|
};
|
|
401
388
|
}
|
|
402
|
-
function renderFrame(
|
|
403
|
-
trail,
|
|
404
|
-
trailCount,
|
|
405
|
-
charWidth,
|
|
406
|
-
charHeight,
|
|
407
|
-
scale,
|
|
408
|
-
offsetX,
|
|
409
|
-
offsetY,
|
|
410
|
-
trailRgb,
|
|
411
|
-
headRgb,
|
|
412
|
-
colorCap,
|
|
413
|
-
) {
|
|
389
|
+
function renderFrame(trail, trailCount, charWidth, charHeight, scale, offsetX, offsetY, trailRgb, headRgb, colorCap) {
|
|
414
390
|
const dotWidth = charWidth * 2;
|
|
415
391
|
const dotHeight = charHeight * 4;
|
|
416
|
-
const grid = Array.from(
|
|
417
|
-
|
|
392
|
+
const grid = Array.from(
|
|
393
|
+
{ length: charHeight },
|
|
394
|
+
() => Array.from(
|
|
395
|
+
{ length: charWidth },
|
|
396
|
+
() => ({ bits: 0, brightness: 0, isHead: false })
|
|
397
|
+
)
|
|
418
398
|
);
|
|
419
399
|
for (let i = 0; i < trailCount; i++) {
|
|
420
400
|
const pt = trail[i];
|
|
@@ -424,12 +404,7 @@ function renderFrame(
|
|
|
424
404
|
const dotCol = snapCol(screenX, dotWidth);
|
|
425
405
|
const dotRow = snapCol(screenY, dotHeight);
|
|
426
406
|
const cell = dotToCell(dotCol, dotRow);
|
|
427
|
-
if (
|
|
428
|
-
cell.charRow < 0 ||
|
|
429
|
-
cell.charRow >= charHeight ||
|
|
430
|
-
cell.charCol < 0 ||
|
|
431
|
-
cell.charCol >= charWidth
|
|
432
|
-
) {
|
|
407
|
+
if (cell.charRow < 0 || cell.charRow >= charHeight || cell.charCol < 0 || cell.charCol >= charWidth) {
|
|
433
408
|
continue;
|
|
434
409
|
}
|
|
435
410
|
const c = grid[cell.charRow][cell.charCol];
|
|
@@ -480,11 +455,7 @@ function renderMonochromeFrame(grid, charWidth, charHeight) {
|
|
|
480
455
|
line += " ";
|
|
481
456
|
continue;
|
|
482
457
|
}
|
|
483
|
-
|
|
484
|
-
line += "\u28FF";
|
|
485
|
-
} else {
|
|
486
|
-
line += brailleChar(cell.bits);
|
|
487
|
-
}
|
|
458
|
+
line += brailleChar(cell.bits);
|
|
488
459
|
}
|
|
489
460
|
lines.push(line);
|
|
490
461
|
}
|
|
@@ -492,7 +463,8 @@ function renderMonochromeFrame(grid, charWidth, charHeight) {
|
|
|
492
463
|
}
|
|
493
464
|
function terminalSarmal(stream, curveDef, options) {
|
|
494
465
|
if (!stream.isTTY) {
|
|
495
|
-
return () => {
|
|
466
|
+
return () => {
|
|
467
|
+
};
|
|
496
468
|
}
|
|
497
469
|
const size = options?.size ?? DEFAULT_SIZE;
|
|
498
470
|
const fps = options?.fps ?? DEFAULT_FPS;
|
|
@@ -511,7 +483,8 @@ function terminalSarmal(stream, curveDef, options) {
|
|
|
511
483
|
const skeleton = engine.getSarmalSkeleton();
|
|
512
484
|
const b = computeBoundaries(skeleton, charWidth * 2, charHeight * 4, 1);
|
|
513
485
|
if (!b) {
|
|
514
|
-
return () => {
|
|
486
|
+
return () => {
|
|
487
|
+
};
|
|
515
488
|
}
|
|
516
489
|
const { scale, offsetX, offsetY } = b;
|
|
517
490
|
let running = true;
|
|
@@ -541,7 +514,7 @@ function terminalSarmal(stream, curveDef, options) {
|
|
|
541
514
|
offsetY,
|
|
542
515
|
trailRgb,
|
|
543
516
|
headRgb,
|
|
544
|
-
colorCap
|
|
517
|
+
colorCap
|
|
545
518
|
);
|
|
546
519
|
if (firstFrame) {
|
|
547
520
|
firstFrame = false;
|
|
@@ -575,13 +548,7 @@ var PERIOD = 2 * Math.PI;
|
|
|
575
548
|
function catmullRom1D(p0, p1, p2, p3, u) {
|
|
576
549
|
const u2 = u * u;
|
|
577
550
|
const u3 = u2 * u;
|
|
578
|
-
return (
|
|
579
|
-
0.5 *
|
|
580
|
-
(2 * p1 +
|
|
581
|
-
(-p0 + p2) * u +
|
|
582
|
-
(2 * p0 - 5 * p1 + 4 * p2 - p3) * u2 +
|
|
583
|
-
(-p0 + 3 * p1 - 3 * p2 + p3) * u3)
|
|
584
|
-
);
|
|
551
|
+
return 0.5 * (2 * p1 + (-p0 + p2) * u + (2 * p0 - 5 * p1 + 4 * p2 - p3) * u2 + (-p0 + 3 * p1 - 3 * p2 + p3) * u3);
|
|
585
552
|
}
|
|
586
553
|
function evaluateCatmullRom(points2, phase) {
|
|
587
554
|
const N = points2.length;
|
|
@@ -591,7 +558,7 @@ function evaluateCatmullRom(points2, phase) {
|
|
|
591
558
|
if (N === 1) {
|
|
592
559
|
return { x: points2[0][0], y: points2[0][1] };
|
|
593
560
|
}
|
|
594
|
-
phase = (
|
|
561
|
+
phase = (phase % PERIOD + PERIOD) % PERIOD;
|
|
595
562
|
const segmentSize = PERIOD / N;
|
|
596
563
|
let i = Math.floor(phase / segmentSize);
|
|
597
564
|
if (i >= N) {
|
|
@@ -605,7 +572,7 @@ function evaluateCatmullRom(points2, phase) {
|
|
|
605
572
|
const p3 = points2[(i + 2) % N];
|
|
606
573
|
return {
|
|
607
574
|
x: catmullRom1D(p0[0], p1[0], p2[0], p3[0], u),
|
|
608
|
-
y: catmullRom1D(p0[1], p1[1], p2[1], p3[1], u)
|
|
575
|
+
y: catmullRom1D(p0[1], p1[1], p2[1], p3[1], u)
|
|
609
576
|
};
|
|
610
577
|
}
|
|
611
578
|
function drawCurve(points2, opts) {
|
|
@@ -615,20 +582,20 @@ function drawCurve(points2, opts) {
|
|
|
615
582
|
const first = points2[0];
|
|
616
583
|
if (points2.every((p) => p[0] === first[0] && p[1] === first[1])) {
|
|
617
584
|
console.warn(
|
|
618
|
-
"[sarmal].drawCurve: all control points are identical. The curve will be a single point."
|
|
585
|
+
"[sarmal].drawCurve: all control points are identical. The curve will be a single point."
|
|
619
586
|
);
|
|
620
587
|
}
|
|
621
588
|
const maxAbs = points2.reduce((m, p) => Math.max(m, Math.abs(p[0]), Math.abs(p[1])), 0);
|
|
622
589
|
if (maxAbs > 2) {
|
|
623
590
|
console.warn(
|
|
624
|
-
`[sarmal].drawCurve: control points extend to \xB1${maxAbs.toFixed(1)}, which may render off-screen. Coordinates should be in [-1, 1]
|
|
591
|
+
`[sarmal].drawCurve: control points extend to \xB1${maxAbs.toFixed(1)}, which may render off-screen. Coordinates should be in [-1, 1].`
|
|
625
592
|
);
|
|
626
593
|
}
|
|
627
594
|
const pts = points2.map(([x, y]) => [x, y]);
|
|
628
595
|
return {
|
|
629
596
|
name: opts?.name ?? "drawn",
|
|
630
597
|
fn: (phase) => evaluateCatmullRom(pts, phase),
|
|
631
|
-
period: PERIOD
|
|
598
|
+
period: PERIOD
|
|
632
599
|
};
|
|
633
600
|
}
|
|
634
601
|
|
|
@@ -654,11 +621,11 @@ var points = [
|
|
|
654
621
|
[-0.69, -0.84],
|
|
655
622
|
[-0.87, -0.66],
|
|
656
623
|
[-0.9, -0.47],
|
|
657
|
-
[-0.76, -0.35]
|
|
624
|
+
[-0.76, -0.35]
|
|
658
625
|
];
|
|
659
626
|
var artemis2 = {
|
|
660
627
|
...drawCurve(points, { name: "Artemis II" }),
|
|
661
|
-
speed: 0.7
|
|
628
|
+
speed: 0.7
|
|
662
629
|
};
|
|
663
630
|
|
|
664
631
|
// src/curves/astroid.ts
|
|
@@ -668,14 +635,14 @@ function astroidFn(phase, _elapsed, _params) {
|
|
|
668
635
|
const s = Math.sin(phase);
|
|
669
636
|
return {
|
|
670
637
|
x: c * c * c,
|
|
671
|
-
y: s * s * s
|
|
638
|
+
y: s * s * s
|
|
672
639
|
};
|
|
673
640
|
}
|
|
674
641
|
var astroid = {
|
|
675
642
|
name: "Astroid",
|
|
676
643
|
fn: astroidFn,
|
|
677
644
|
period: TWO_PI2,
|
|
678
|
-
speed: 1.1
|
|
645
|
+
speed: 1.1
|
|
679
646
|
};
|
|
680
647
|
|
|
681
648
|
// src/curves/deltoid.ts
|
|
@@ -683,14 +650,14 @@ var TWO_PI3 = Math.PI * 2;
|
|
|
683
650
|
function deltoidFn(phase, _elapsed, _params) {
|
|
684
651
|
return {
|
|
685
652
|
x: 2 * Math.cos(phase) + Math.cos(2 * phase),
|
|
686
|
-
y: 2 * Math.sin(phase) - Math.sin(2 * phase)
|
|
653
|
+
y: 2 * Math.sin(phase) - Math.sin(2 * phase)
|
|
687
654
|
};
|
|
688
655
|
}
|
|
689
656
|
var deltoid = {
|
|
690
657
|
name: "Deltoid",
|
|
691
658
|
fn: deltoidFn,
|
|
692
659
|
period: TWO_PI3,
|
|
693
|
-
speed: 0.9
|
|
660
|
+
speed: 0.9
|
|
694
661
|
};
|
|
695
662
|
|
|
696
663
|
// src/curves/epicycloid3.ts
|
|
@@ -698,14 +665,14 @@ var TWO_PI4 = Math.PI * 2;
|
|
|
698
665
|
function epicycloid3Fn(phase, _elapsed, _params) {
|
|
699
666
|
return {
|
|
700
667
|
x: 4 * Math.cos(phase) - Math.cos(4 * phase),
|
|
701
|
-
y: 4 * Math.sin(phase) - Math.sin(4 * phase)
|
|
668
|
+
y: 4 * Math.sin(phase) - Math.sin(4 * phase)
|
|
702
669
|
};
|
|
703
670
|
}
|
|
704
671
|
var epicycloid3 = {
|
|
705
672
|
name: "Epicycloid (n=3)",
|
|
706
673
|
fn: epicycloid3Fn,
|
|
707
674
|
period: TWO_PI4,
|
|
708
|
-
speed: 0.75
|
|
675
|
+
speed: 0.75
|
|
709
676
|
};
|
|
710
677
|
|
|
711
678
|
// src/curves/epitrochoid7.ts
|
|
@@ -714,14 +681,14 @@ function epitrochoid7Fn(phase, _elapsed, _params) {
|
|
|
714
681
|
const d = 1 + 0.55 * Math.sin(phase * 0.5);
|
|
715
682
|
return {
|
|
716
683
|
x: 7 * Math.cos(phase) - d * Math.cos(7 * phase),
|
|
717
|
-
y: 7 * Math.sin(phase) - d * Math.sin(7 * phase)
|
|
684
|
+
y: 7 * Math.sin(phase) - d * Math.sin(7 * phase)
|
|
718
685
|
};
|
|
719
686
|
}
|
|
720
687
|
function epitrochoid7SkeletonFn(phase) {
|
|
721
688
|
const d = 1.275;
|
|
722
689
|
return {
|
|
723
690
|
x: 7 * Math.cos(phase) - d * Math.cos(7 * phase),
|
|
724
|
-
y: 7 * Math.sin(phase) - d * Math.sin(7 * phase)
|
|
691
|
+
y: 7 * Math.sin(phase) - d * Math.sin(7 * phase)
|
|
725
692
|
};
|
|
726
693
|
}
|
|
727
694
|
var epitrochoid7 = {
|
|
@@ -729,7 +696,7 @@ var epitrochoid7 = {
|
|
|
729
696
|
fn: epitrochoid7Fn,
|
|
730
697
|
period: TWO_PI5,
|
|
731
698
|
speed: 1.4,
|
|
732
|
-
skeletonFn: epitrochoid7SkeletonFn
|
|
699
|
+
skeletonFn: epitrochoid7SkeletonFn
|
|
733
700
|
};
|
|
734
701
|
|
|
735
702
|
// src/curves/lissajous32.ts
|
|
@@ -738,7 +705,7 @@ function lissajous32Fn(phase, elapsed, _params) {
|
|
|
738
705
|
const phi = elapsed * 0.45;
|
|
739
706
|
return {
|
|
740
707
|
x: Math.sin(3 * phase + phi),
|
|
741
|
-
y: Math.sin(2 * phase)
|
|
708
|
+
y: Math.sin(2 * phase)
|
|
742
709
|
};
|
|
743
710
|
}
|
|
744
711
|
var lissajous32 = {
|
|
@@ -746,7 +713,7 @@ var lissajous32 = {
|
|
|
746
713
|
fn: lissajous32Fn,
|
|
747
714
|
period: TWO_PI6,
|
|
748
715
|
speed: 2,
|
|
749
|
-
skeleton: "live"
|
|
716
|
+
skeleton: "live"
|
|
750
717
|
};
|
|
751
718
|
|
|
752
719
|
// src/curves/lissajous43.ts
|
|
@@ -755,7 +722,7 @@ function lissajous43Fn(phase, elapsed, _params) {
|
|
|
755
722
|
const phi = elapsed * 0.38;
|
|
756
723
|
return {
|
|
757
724
|
x: Math.sin(4 * phase + phi),
|
|
758
|
-
y: Math.sin(3 * phase)
|
|
725
|
+
y: Math.sin(3 * phase)
|
|
759
726
|
};
|
|
760
727
|
}
|
|
761
728
|
var lissajous43 = {
|
|
@@ -763,18 +730,17 @@ var lissajous43 = {
|
|
|
763
730
|
fn: lissajous43Fn,
|
|
764
731
|
period: TWO_PI7,
|
|
765
732
|
speed: 1.8,
|
|
766
|
-
skeleton: "live"
|
|
733
|
+
skeleton: "live"
|
|
767
734
|
};
|
|
768
735
|
|
|
769
736
|
// src/curves/lame.ts
|
|
770
737
|
var TWO_PI8 = Math.PI * 2;
|
|
771
738
|
function lameFn(phase, elapsed, _params) {
|
|
772
739
|
const p = 1.75 + 1.25 * Math.sin(elapsed * 0.48);
|
|
773
|
-
const c = Math.cos(phase),
|
|
774
|
-
s = Math.sin(phase);
|
|
740
|
+
const c = Math.cos(phase), s = Math.sin(phase);
|
|
775
741
|
return {
|
|
776
742
|
x: Math.sign(c) * Math.pow(Math.abs(c), p),
|
|
777
|
-
y: Math.sign(s) * Math.pow(Math.abs(s), p)
|
|
743
|
+
y: Math.sign(s) * Math.pow(Math.abs(s), p)
|
|
778
744
|
};
|
|
779
745
|
}
|
|
780
746
|
var lame = {
|
|
@@ -782,7 +748,7 @@ var lame = {
|
|
|
782
748
|
fn: lameFn,
|
|
783
749
|
period: TWO_PI8,
|
|
784
750
|
speed: 1,
|
|
785
|
-
skeleton: "live"
|
|
751
|
+
skeleton: "live"
|
|
786
752
|
};
|
|
787
753
|
|
|
788
754
|
// src/curves/rose3.ts
|
|
@@ -791,14 +757,14 @@ function rose3Fn(phase, _elapsed, _params) {
|
|
|
791
757
|
const r = Math.cos(3 * phase);
|
|
792
758
|
return {
|
|
793
759
|
x: r * Math.cos(phase),
|
|
794
|
-
y: r * Math.sin(phase)
|
|
760
|
+
y: r * Math.sin(phase)
|
|
795
761
|
};
|
|
796
762
|
}
|
|
797
763
|
var rose3 = {
|
|
798
764
|
name: "Rose (n=3)",
|
|
799
765
|
fn: rose3Fn,
|
|
800
766
|
period: TWO_PI9,
|
|
801
|
-
speed: 1.15
|
|
767
|
+
speed: 1.15
|
|
802
768
|
};
|
|
803
769
|
|
|
804
770
|
// src/curves/rose5.ts
|
|
@@ -807,87 +773,78 @@ function rose5Fn(phase, _elapsed, _params) {
|
|
|
807
773
|
const r = Math.cos(5 * phase);
|
|
808
774
|
return {
|
|
809
775
|
x: r * Math.cos(phase),
|
|
810
|
-
y: r * Math.sin(phase)
|
|
776
|
+
y: r * Math.sin(phase)
|
|
811
777
|
};
|
|
812
778
|
}
|
|
813
779
|
var rose5 = {
|
|
814
780
|
name: "Rose (n=5)",
|
|
815
781
|
fn: rose5Fn,
|
|
816
782
|
period: TWO_PI10,
|
|
817
|
-
speed: 1
|
|
783
|
+
speed: 1
|
|
818
784
|
};
|
|
819
785
|
|
|
820
786
|
// src/curves/rose52.ts
|
|
821
787
|
var FOUR_PI = Math.PI * 4;
|
|
822
788
|
function rose52Fn(phase, _elapsed, _params) {
|
|
823
|
-
const r = Math.cos(
|
|
789
|
+
const r = Math.cos(5 / 2 * phase);
|
|
824
790
|
return {
|
|
825
791
|
x: r * Math.cos(phase),
|
|
826
|
-
y: r * Math.sin(phase)
|
|
792
|
+
y: r * Math.sin(phase)
|
|
827
793
|
};
|
|
828
794
|
}
|
|
829
795
|
var rose52 = {
|
|
830
796
|
name: "Rose (n=5/2)",
|
|
831
797
|
fn: rose52Fn,
|
|
832
798
|
period: FOUR_PI,
|
|
833
|
-
speed: 0.8
|
|
799
|
+
speed: 0.8
|
|
834
800
|
};
|
|
835
801
|
|
|
836
802
|
// src/curves/star.ts
|
|
837
803
|
var TWO_PI11 = Math.PI * 2;
|
|
838
804
|
function starFn(phase, _elapsed, _params) {
|
|
839
|
-
const r =
|
|
840
|
-
Math.abs(Math.cos((5 / 2) * phase)) +
|
|
841
|
-
0.35 * Math.abs(Math.cos((15 / 2) * phase)) +
|
|
842
|
-
0.15 * Math.abs(Math.cos((25 / 2) * phase));
|
|
805
|
+
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));
|
|
843
806
|
return {
|
|
844
807
|
x: r * Math.cos(phase),
|
|
845
|
-
y: r * Math.sin(phase)
|
|
808
|
+
y: r * Math.sin(phase)
|
|
846
809
|
};
|
|
847
810
|
}
|
|
848
811
|
var star = {
|
|
849
812
|
name: "Star",
|
|
850
813
|
fn: starFn,
|
|
851
814
|
period: TWO_PI11,
|
|
852
|
-
speed: 1
|
|
815
|
+
speed: 1
|
|
853
816
|
};
|
|
854
817
|
|
|
855
818
|
// src/curves/star4.ts
|
|
856
819
|
var TWO_PI12 = Math.PI * 2;
|
|
857
820
|
function star4Fn(phase, _elapsed, _params) {
|
|
858
|
-
const r =
|
|
859
|
-
Math.abs(Math.cos(2 * phase)) +
|
|
860
|
-
0.35 * Math.abs(Math.cos(6 * phase)) +
|
|
861
|
-
0.15 * Math.abs(Math.cos(10 * phase));
|
|
821
|
+
const r = Math.abs(Math.cos(2 * phase)) + 0.35 * Math.abs(Math.cos(6 * phase)) + 0.15 * Math.abs(Math.cos(10 * phase));
|
|
862
822
|
return {
|
|
863
823
|
x: r * Math.cos(phase),
|
|
864
|
-
y: r * Math.sin(phase)
|
|
824
|
+
y: r * Math.sin(phase)
|
|
865
825
|
};
|
|
866
826
|
}
|
|
867
827
|
var star4 = {
|
|
868
828
|
name: "Star (4-arm)",
|
|
869
829
|
fn: star4Fn,
|
|
870
830
|
period: TWO_PI12,
|
|
871
|
-
speed: 1
|
|
831
|
+
speed: 1
|
|
872
832
|
};
|
|
873
833
|
|
|
874
834
|
// src/curves/star7.ts
|
|
875
835
|
var TWO_PI13 = Math.PI * 2;
|
|
876
836
|
function star7Fn(phase, _elapsed, _params) {
|
|
877
|
-
const r =
|
|
878
|
-
Math.abs(Math.cos((7 / 2) * phase)) +
|
|
879
|
-
0.35 * Math.abs(Math.cos((21 / 2) * phase)) +
|
|
880
|
-
0.15 * Math.abs(Math.cos((35 / 2) * phase));
|
|
837
|
+
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));
|
|
881
838
|
return {
|
|
882
839
|
x: r * Math.cos(phase),
|
|
883
|
-
y: r * Math.sin(phase)
|
|
840
|
+
y: r * Math.sin(phase)
|
|
884
841
|
};
|
|
885
842
|
}
|
|
886
843
|
var star7 = {
|
|
887
844
|
name: "Star (7-arm)",
|
|
888
845
|
fn: star7Fn,
|
|
889
846
|
period: TWO_PI13,
|
|
890
|
-
speed: 1
|
|
847
|
+
speed: 1
|
|
891
848
|
};
|
|
892
849
|
|
|
893
850
|
// src/curves/index.ts
|
|
@@ -905,7 +862,7 @@ var curves = {
|
|
|
905
862
|
lissajous32,
|
|
906
863
|
lissajous43,
|
|
907
864
|
epicycloid3,
|
|
908
|
-
lame
|
|
865
|
+
lame
|
|
909
866
|
};
|
|
910
867
|
|
|
911
868
|
// src/cli.ts
|
|
@@ -915,7 +872,7 @@ function usage() {
|
|
|
915
872
|
"Usage: npx @sarmal/core [options]",
|
|
916
873
|
"",
|
|
917
874
|
"Options:",
|
|
918
|
-
" --
|
|
875
|
+
" --curve <id> Curve name (e.g. deltoid, rose3). Random if omitted.",
|
|
919
876
|
" --fps <num> Frame rate (default: 30).",
|
|
920
877
|
" --speed <num> Animation speed multiplier (default: curve default).",
|
|
921
878
|
" --size <num> Spinner width in characters (default: 16).",
|
|
@@ -925,10 +882,10 @@ function usage() {
|
|
|
925
882
|
"",
|
|
926
883
|
"Examples:",
|
|
927
884
|
" npx @sarmal/core",
|
|
928
|
-
" npx @sarmal/core --
|
|
929
|
-
" npx @sarmal/core --
|
|
930
|
-
""
|
|
931
|
-
].join("\n") + "\n"
|
|
885
|
+
" npx @sarmal/core --curve deltoid --verbose",
|
|
886
|
+
" npx @sarmal/core --curve rose3 --fps 15 --speed 3",
|
|
887
|
+
""
|
|
888
|
+
].join("\n") + "\n"
|
|
932
889
|
);
|
|
933
890
|
}
|
|
934
891
|
function matchArg(argv, i, flag) {
|
|
@@ -942,7 +899,7 @@ function matchArg(argv, i, flag) {
|
|
|
942
899
|
}
|
|
943
900
|
function main() {
|
|
944
901
|
const args = process.argv.slice(2);
|
|
945
|
-
let
|
|
902
|
+
let curveName;
|
|
946
903
|
let verbose = false;
|
|
947
904
|
let fps;
|
|
948
905
|
let speed;
|
|
@@ -951,8 +908,8 @@ function main() {
|
|
|
951
908
|
for (let i = 0; i < args.length; i++) {
|
|
952
909
|
const arg = args[i];
|
|
953
910
|
switch (arg) {
|
|
954
|
-
case "--
|
|
955
|
-
|
|
911
|
+
case "--curve": {
|
|
912
|
+
curveName = matchArg(args, i, "--curve");
|
|
956
913
|
i++;
|
|
957
914
|
break;
|
|
958
915
|
}
|
|
@@ -1018,14 +975,15 @@ function main() {
|
|
|
1018
975
|
}
|
|
1019
976
|
const allCurves = Object.values(curves);
|
|
1020
977
|
let curve = allCurves[Math.floor(Math.random() * allCurves.length)];
|
|
1021
|
-
if (
|
|
1022
|
-
const
|
|
1023
|
-
const
|
|
978
|
+
if (curveName) {
|
|
979
|
+
const availableCurves = Object.keys(curves);
|
|
980
|
+
const lower = curveName.toLowerCase();
|
|
981
|
+
const key = availableCurves.find((k) => k.toLowerCase() === lower);
|
|
1024
982
|
const found = key ? curves[key] : void 0;
|
|
1025
983
|
if (!found) {
|
|
1026
984
|
process.stderr.write(
|
|
1027
|
-
`[sarmal] Unknown curve: "${
|
|
1028
|
-
|
|
985
|
+
`[sarmal] Unknown curve: "${curveName}". Available: ${availableCurves.join(", ")}
|
|
986
|
+
`
|
|
1029
987
|
);
|
|
1030
988
|
process.exit(1);
|
|
1031
989
|
}
|
|
@@ -1037,12 +995,12 @@ function main() {
|
|
|
1037
995
|
`);
|
|
1038
996
|
}
|
|
1039
997
|
terminalSarmal(process.stdout, curve, {
|
|
1040
|
-
...
|
|
1041
|
-
...
|
|
1042
|
-
...
|
|
1043
|
-
...
|
|
998
|
+
...fps !== void 0 ? { fps } : {},
|
|
999
|
+
...speed !== void 0 ? { speed } : {},
|
|
1000
|
+
...size !== void 0 ? { size } : {},
|
|
1001
|
+
...color !== void 0 ? { trailColor: color } : {}
|
|
1044
1002
|
});
|
|
1045
1003
|
}
|
|
1046
1004
|
main();
|
|
1047
1005
|
//# sourceMappingURL=cli.js.map
|
|
1048
|
-
//# sourceMappingURL=cli.js.map
|
|
1006
|
+
//# sourceMappingURL=cli.js.map
|