@olwiba/dx 0.0.15 → 0.0.17

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.
@@ -7,6 +7,7 @@ interface GenerateAsciiGifOptions {
7
7
  outputPath: string;
8
8
  color?: string;
9
9
  accentColor?: string;
10
+ rowColors?: string[];
10
11
  backgroundColor?: string;
11
12
  blendColor?: string;
12
13
  fps?: number;
package/dist/ascii-gif.js CHANGED
@@ -1318,6 +1318,48 @@ async function generateAsciiGif(options) {
1318
1318
  const layout = composeAsciiText(font, options.text);
1319
1319
  const bounds = getLayoutBounds(layout);
1320
1320
  const accentColumns = getAsciiAccentColumns(font, options.text, options.accent ?? "");
1321
+ const width = Math.ceil(bounds.cols * ASCII_CHAR_WIDTH * scale) + padding * 2;
1322
+ const height = bounds.rows * ASCII_CHAR_HEIGHT * scale + padding * 2;
1323
+ const frameCount = Math.max(1, Math.round(fps * duration));
1324
+ const delay = Math.max(1, Math.round(100 / fps));
1325
+ const frames = [];
1326
+ if (options.rowColors && options.rowColors.length > 0) {
1327
+ const uniqueRowColors = [...new Set(options.rowColors)];
1328
+ const rowPalette = createRowColorPalette({
1329
+ backgroundColor: options.backgroundColor ?? "#0a0a0a",
1330
+ blendColor: options.blendColor ?? options.backgroundColor ?? "#0a0a0a",
1331
+ rowColors: uniqueRowColors,
1332
+ levels,
1333
+ transparent: options.transparent ?? false
1334
+ });
1335
+ for (let frame = 0; frame < frameCount; frame++) {
1336
+ frames.push(
1337
+ renderIndexedAsciiFrameWithRowColors({
1338
+ layout,
1339
+ phase: frame / frameCount,
1340
+ width,
1341
+ height,
1342
+ scale,
1343
+ levels,
1344
+ bounds,
1345
+ padding,
1346
+ rowColorsInput: options.rowColors,
1347
+ uniqueRowColors
1348
+ })
1349
+ );
1350
+ }
1351
+ const bytes2 = encodeGif({
1352
+ width,
1353
+ height,
1354
+ delay,
1355
+ palette: rowPalette.table,
1356
+ frames,
1357
+ transparent: options.transparent ?? false
1358
+ });
1359
+ mkdirSync(path.dirname(options.outputPath), { recursive: true });
1360
+ writeFileSync(options.outputPath, bytes2);
1361
+ return;
1362
+ }
1321
1363
  const palette = createPalette({
1322
1364
  backgroundColor: options.backgroundColor ?? "#0a0a0a",
1323
1365
  blendColor: options.blendColor ?? options.backgroundColor ?? "#0a0a0a",
@@ -1326,11 +1368,6 @@ async function generateAsciiGif(options) {
1326
1368
  levels,
1327
1369
  transparent: options.transparent ?? false
1328
1370
  });
1329
- const width = Math.ceil(bounds.cols * ASCII_CHAR_WIDTH * scale) + padding * 2;
1330
- const height = bounds.rows * ASCII_CHAR_HEIGHT * scale + padding * 2;
1331
- const frameCount = Math.max(1, Math.round(fps * duration));
1332
- const delay = Math.max(1, Math.round(100 / fps));
1333
- const frames = [];
1334
1371
  for (let frame = 0; frame < frameCount; frame++) {
1335
1372
  frames.push(
1336
1373
  renderIndexedAsciiFrame({
@@ -1379,6 +1416,44 @@ function renderIndexedAsciiFrame(options) {
1379
1416
  }
1380
1417
  return pixels;
1381
1418
  }
1419
+ function renderIndexedAsciiFrameWithRowColors(options) {
1420
+ const pixels = new Uint8Array(options.width * options.height);
1421
+ const charWidth = Math.round(ASCII_CHAR_WIDTH * options.scale);
1422
+ const charHeight = Math.round(ASCII_CHAR_HEIGHT * options.scale);
1423
+ for (const cell of options.layout.cells) {
1424
+ const intensity = getAsciiCellIntensity(cell, { phase: options.phase });
1425
+ const level = Math.max(0, Math.min(options.levels - 1, Math.round(intensity * (options.levels - 1))));
1426
+ const rowColor = options.rowColorsInput[cell.row % options.rowColorsInput.length] ?? options.rowColorsInput[0];
1427
+ const colorSetIndex = Math.max(0, options.uniqueRowColors.indexOf(rowColor));
1428
+ const colorIndex = 1 + colorSetIndex * options.levels + level;
1429
+ const x0 = options.padding + Math.round((cell.col - options.bounds.minCol) * ASCII_CHAR_WIDTH * options.scale);
1430
+ const y0 = options.padding + (cell.row - options.bounds.minRow) * charHeight;
1431
+ const x1 = Math.min(options.width, x0 + charWidth);
1432
+ const y1 = Math.min(options.height, y0 + charHeight);
1433
+ for (let y = y0; y < y1; y++) {
1434
+ const row = y * options.width;
1435
+ for (let x = x0; x < x1; x++) {
1436
+ pixels[row + x] = colorIndex;
1437
+ }
1438
+ }
1439
+ }
1440
+ return pixels;
1441
+ }
1442
+ function createRowColorPalette(options) {
1443
+ const bg = parseColor(options.backgroundColor);
1444
+ const blend = parseColor(options.blendColor);
1445
+ const table = [bg.r, bg.g, bg.b];
1446
+ for (const colorHex of options.rowColors) {
1447
+ const color = parseColor(colorHex);
1448
+ for (let level = 0; level < options.levels; level++) {
1449
+ const alpha = level / (options.levels - 1);
1450
+ const mixed = mix(blend, color, alpha);
1451
+ table.push(mixed.r, mixed.g, mixed.b);
1452
+ }
1453
+ }
1454
+ while (table.length < 256 * 3) table.push(0, 0, 0);
1455
+ return { table: Uint8Array.from(table.slice(0, 256 * 3)) };
1456
+ }
1382
1457
  function getLayoutBounds(layout) {
1383
1458
  if (layout.cells.length === 0) {
1384
1459
  return { minCol: 0, minRow: 0, cols: Math.max(1, layout.cols), rows: Math.max(1, layout.rows) };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ascii/compose.ts","../src/ascii/figlet.ts","../src/ascii/render.ts","../src/ascii/fonts/dosrebel-data.ts","../src/ascii/fonts.ts","../src/ascii-gif.ts"],"names":[],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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","file":"ascii-gif.js","sourcesContent":["import type { FigletFont } from \"./figlet\"\n\nexport interface AsciiCell {\n ch: \"█\" | \"░\"\n col: number\n row: number\n}\n\nexport interface AsciiTextLayout {\n cells: AsciiCell[]\n cols: number\n rows: number\n}\n\nexport function composeAsciiText(font: FigletFont, text: string): AsciiTextLayout {\n const charBlocks: Array<{ lines: string[]; width: number }> = []\n\n for (const ch of text) {\n const code = ch.charCodeAt(0)\n const glyph = font.chars.get(code) ?? font.chars.get(32)\n if (!glyph) continue\n\n const width = Math.max(...glyph.map((line) => line.length))\n charBlocks.push({\n lines: glyph.map((line) => line.padEnd(width)),\n width,\n })\n }\n\n const cols = charBlocks.reduce((sum, block) => sum + block.width, 0)\n const rows = font.height\n const cells: AsciiCell[] = []\n let offsetX = 0\n\n for (const block of charBlocks) {\n for (let row = 0; row < rows; row++) {\n const line = block.lines[row] ?? \"\"\n for (let col = 0; col < line.length; col++) {\n const ch = line[col]\n if (ch === \"█\" || ch === \"░\") {\n cells.push({ ch, col: offsetX + col, row })\n }\n }\n }\n offsetX += block.width\n }\n\n return { cells, cols, rows }\n}\n\nexport function getAsciiAccentColumns(\n font: FigletFont,\n text: string,\n accent: string,\n): Set<number> {\n if (!accent) return new Set<number>()\n\n const columns = new Set<number>()\n const accentRanges: Array<{ start: number; end: number }> = []\n let searchFrom = 0\n while (true) {\n const idx = text.indexOf(accent, searchFrom)\n if (idx === -1) break\n accentRanges.push({ start: idx, end: idx + accent.length })\n searchFrom = idx + 1\n }\n if (accentRanges.length === 0) return columns\n\n let offsetX = 0\n let charIndex = 0\n\n for (const ch of text) {\n const code = ch.charCodeAt(0)\n const glyph = font.chars.get(code) ?? font.chars.get(32)\n if (!glyph) { charIndex++; continue }\n\n const width = Math.max(...glyph.map((line) => line.length))\n if (accentRanges.some((r) => charIndex >= r.start && charIndex < r.end)) {\n for (let col = 0; col < width; col++) columns.add(offsetX + col)\n }\n offsetX += width\n charIndex++\n }\n\n return columns\n}\n","export interface FigletFont {\n height: number\n baseline: number\n hardblank: string\n chars: Map<number, string[]>\n}\n\nexport function parseFigletFont(raw: string): FigletFont {\n const lines = raw.split(\"\\n\")\n\n if (lines[0]?.charCodeAt(0) === 0xfeff) {\n lines[0] = lines[0].slice(1)\n }\n\n const header = lines[0]\n if (!header?.startsWith(\"flf2a\")) {\n throw new Error(\"Invalid FIGlet font: missing flf2a header\")\n }\n\n const hardblank = header[5] ?? \"$\"\n const parts = header.slice(6).trim().split(/\\s+/)\n const height = Number.parseInt(parts[0] ?? \"\", 10)\n const baseline = Number.parseInt(parts[1] ?? \"\", 10)\n const commentLines = Number.parseInt(parts[4] ?? \"\", 10)\n\n if (!Number.isFinite(height) || height <= 0) {\n throw new Error(\"Invalid FIGlet font: missing character height\")\n }\n\n const dataStart = 1 + (Number.isFinite(commentLines) ? commentLines : 0)\n const chars = new Map<number, string[]>()\n let lineIndex = dataStart\n let ascii = 32\n\n while (lineIndex + height <= lines.length && ascii <= 126) {\n const charLines: string[] = []\n for (let row = 0; row < height; row++) {\n const line = (lines[lineIndex + row] ?? \"\")\n .replace(/@+$/, \"\")\n .replaceAll(hardblank, \" \")\n charLines.push(line)\n }\n\n chars.set(ascii, charLines)\n lineIndex += height\n ascii++\n }\n\n return { height, baseline, hardblank, chars }\n}\n","import type { AsciiCell, AsciiTextLayout } from \"./compose\"\n\nexport const ASCII_CHAR_WIDTH = 7.5\nexport const ASCII_CHAR_HEIGHT = 15\n\nexport interface AsciiWave {\n cx: number\n cy: number\n t: number\n}\n\nexport interface AsciiPointer {\n x: number\n y: number\n active: boolean\n}\n\nexport interface AsciiFrameState {\n time?: number\n phase?: number\n pointer?: AsciiPointer\n waves?: AsciiWave[]\n}\n\nexport interface AsciiRenderOptions extends AsciiFrameState {\n accentColumns?: ReadonlySet<number>\n color: string\n accentColor?: string\n charWidth?: number\n charHeight?: number\n}\n\nexport interface AsciiFrameContext {\n clearRect(x: number, y: number, width: number, height: number): void\n fillRect(x: number, y: number, width: number, height: number): void\n globalAlpha: number\n fillStyle: string\n}\n\nexport function getAsciiCanvasSize(\n layout: AsciiTextLayout,\n charWidth = ASCII_CHAR_WIDTH,\n charHeight = ASCII_CHAR_HEIGHT,\n) {\n return {\n width: Math.ceil(layout.cols * charWidth),\n height: layout.rows * charHeight,\n }\n}\n\nexport function getAsciiCellIntensity(cell: AsciiCell, options: AsciiFrameState): number {\n const time = options.time ?? 0\n const loop = options.phase == null ? null : options.phase * Math.PI * 2\n\n if (cell.ch === \"░\") {\n const drift =\n loop == null\n ? Math.sin(time * 0.3 + cell.col * 0.1) * 0.03\n : Math.sin(loop + cell.col * 0.1) * 0.03\n return 0.15 + drift\n }\n\n if (loop != null) {\n return getLoopIntensity(cell, loop)\n }\n\n const noise = getLiveNoise(cell, time)\n\n const seed = cell.col * 7.13 + cell.row * 13.37\n const flickerPhase = Math.sin(seed) * 1000\n const flickerWave = Math.sin(time * 0.8 + flickerPhase)\n const flicker = flickerWave > 0.97 ? 0.15 : 0\n\n let intensity = 0.7 + noise + flicker\n const charWidth = ASCII_CHAR_WIDTH\n const charHeight = ASCII_CHAR_HEIGHT\n\n if (options.pointer?.active) {\n const mdx = cell.col * charWidth + charWidth / 2 - options.pointer.x\n const mdy = cell.row * charHeight + charHeight / 2 - options.pointer.y\n const mDist = Math.sqrt(mdx * mdx + mdy * mdy)\n const radius = 80\n if (mDist < radius) {\n const falloff = 1 - mDist / radius\n const ripple = Math.sin(mDist * 0.08 - time * 4) * 0.12 * falloff * falloff\n intensity = Math.min(1, intensity + falloff * 0.2 + ripple)\n }\n }\n\n const px = cell.col * charWidth + charWidth / 2\n const py = cell.row * charHeight + charHeight / 2\n for (const wave of options.waves ?? []) {\n const wdx = px - wave.cx\n const wdy = py - wave.cy\n const dist = Math.sqrt(wdx * wdx + wdy * wdy)\n const age = time - wave.t\n const waveRadius = age * 200\n const delta = dist - waveRadius\n const fade = Math.exp(-age * 1.5)\n const ring = Math.exp(-delta * delta * 0.002) * fade\n intensity = Math.min(1, intensity + ring * 0.5 * Math.sin(delta * 0.06 + 1.5))\n }\n\n return Math.max(0.5, Math.min(1, intensity))\n}\n\nexport function renderAsciiFrameToContext(\n ctx: AsciiFrameContext,\n layout: AsciiTextLayout,\n options: AsciiRenderOptions,\n) {\n const charWidth = options.charWidth ?? ASCII_CHAR_WIDTH\n const charHeight = options.charHeight ?? ASCII_CHAR_HEIGHT\n const { width, height } = getAsciiCanvasSize(layout, charWidth, charHeight)\n const accentColor = options.accentColor ?? options.color\n\n ctx.clearRect(0, 0, width, height)\n\n for (const cell of layout.cells) {\n const isAccent = options.accentColumns?.has(cell.col) ?? false\n ctx.globalAlpha = getAsciiCellIntensity(cell, options)\n ctx.fillStyle = isAccent ? accentColor : options.color\n ctx.fillRect(cell.col * charWidth, cell.row * charHeight, charWidth, charHeight)\n }\n\n ctx.globalAlpha = 1\n}\n\nfunction getLiveNoise(cell: AsciiCell, time: number): number {\n const nx = cell.col * 0.18 + time * 0.9\n const ny = cell.row * 0.3 + time * 0.55\n return (\n Math.sin(nx) * 0.12 +\n Math.sin(ny * 1.4 + nx * 0.6) * 0.1 +\n Math.sin(nx * 0.4 - ny * 0.8 + time * 1.6) * 0.08 +\n Math.sin((cell.col + cell.row) * 0.15 + time * 0.4) * 0.07\n )\n}\n\nfunction getLoopIntensity(cell: AsciiCell, loop: number): number {\n const flow =\n Math.sin(cell.col * 0.08 + loop) * 0.055 +\n Math.sin(cell.row * 0.22 - loop * 0.75) * 0.04\n const shimmer = (Math.sin(cell.col * 0.16 + cell.row * 0.08 - loop * 2) + 1) / 2\n const highlight = Math.pow(shimmer, 4) * 0.22\n const intensity = 0.68 + flow + highlight\n\n return Math.max(0.55, Math.min(1, intensity))\n}\n","// @generated from dosrebel.flf. Do not edit by hand.\nexport const dosrebelFont: string = \"flf2a$ 11 8 35 -1 15\\nRebel by Valerie Mates (popcorn@cyberspace.org), based on a font by Ron Bliss\\n(who sometimes goes by the name \\\"rebel\\\" because his initials are REB).\\nNOTE: THIS FONT ONLY WORKS IN MS-DOS.\\nMay 27, 1994\\n\\nExplanation of first line:\\nflf2 - \\\"magic number\\\" for file identification\\na - should always be `a', for now\\n$ - the \\\"hardblank\\\" -- prints as a blank, but can't be smushed\\n11 - height of a character\\n8 - height of a character, not including descenders\\n35 - max line length (excluding comment lines) + a fudge factor\\n-1 - default smushmode for this font (like \\\"-m 15\\\" on command line)\\n15 - number of comment lines\\n\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@@\\n ███@\\n░███@\\n░███@\\n░███@\\n░███@\\n░░░ @\\n ███@\\n░░░ @\\n @\\n @\\n @@\\n ██ ██@\\n░██░██@\\n░░ ░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n ███ ███ @\\n ████████████@\\n░░░███░░███░ @\\n ████████████@\\n░░░███░░███░ @\\n ░░░ ░░░ @\\n @\\n @\\n @\\n @\\n @@\\n ███ @\\n ██████ @\\n ███░░░ @\\n ░░█████ @\\n ░░░░███ @\\n ██████ @\\n ░░░███ @\\n ░░░ @\\n @\\n @\\n @@\\n ███ ███@\\n ░░░ ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ ███ @\\n░░░ ░░░ @\\n @\\n @\\n @@\\n ██████ @\\n ███░░███ @\\n ░░██████ @\\n ██████ @\\n░███░░███ @\\n░███ ░░███ @\\n░░█████░███@\\n ░░░░░ ░░░ @\\n @\\n @\\n @@\\n ██@\\n ███@\\n░░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n ███@\\n ███ @\\n ███ @\\n░███ @\\n░███ @\\n░░███ @\\n ░░███@\\n ░░░ @\\n @\\n @\\n @@\\n ███ @\\n░░███ @\\n ░░███@\\n ░███@\\n ░███@\\n ███ @\\n ██░ @\\n░░░ @\\n @\\n @\\n @@\\n ███ @\\n ███ ░███ ███@\\n░░░█████████░ @\\n ░░░█████░ @\\n █████████ @\\n ███░░███░░███@\\n░░░ ░███ ░░░ @\\n ░░░ @\\n @\\n @\\n @@\\n @\\n ███ @\\n ░███ @\\n ███████████@\\n░░░░░███░░░ @\\n ░███ @\\n ░░░ @\\n @\\n @\\n @\\n @@\\n @\\n @\\n @\\n @\\n @\\n @\\n ██@\\n ██ @\\n░░ @\\n @\\n @@\\n @\\n @\\n @\\n ██████████@\\n░░░░░░░░░░ @\\n @\\n @\\n @\\n @\\n @\\n @@\\n @\\n @\\n @\\n @\\n @\\n @\\n ██@\\n░░ @\\n @\\n @\\n @@\\n ███@\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n░░░ @\\n @\\n @\\n @@\\n █████ @\\n ███░░░███ @\\n ███ ░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███ ███ @\\n ░░░█████░ @\\n ░░░░░░ @\\n @\\n @\\n @@\\n ████ @\\n░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███@\\n░░░ ░███@\\n ███████ @\\n ███░░░░ @\\n ███ █@\\n░██████████@\\n░░░░░░░░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███@\\n░░░ ░███@\\n ██████░ @\\n ░░░░░░███@\\n ███ ░███@\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n █████ █████ @\\n░░███ ░░███ @\\n ░███ ░███ █@\\n ░███████████@\\n ░░░░░░░███░█@\\n ░███░ @\\n █████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n ██████████@\\n░███░░░░░░█@\\n░███ ░ @\\n░█████████ @\\n░░░░░░░░███@\\n ███ ░███@\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███@\\n░███ ░░░ @\\n░█████████ @\\n░███░░░░███@\\n░███ ░███@\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n ██████████@\\n░███░░░░███@\\n░░░ ███ @\\n ███ @\\n ███ @\\n ███ @\\n ███ @\\n ░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███ @\\n░███ ░███ @\\n░░████████ @\\n ███░░░░███ @\\n░███ ░███ @\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███@\\n░███ ░███@\\n░░█████████@\\n ░░░░░░░███@\\n ███ ░███@\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ██@\\n░░ @\\n @\\n @\\n ██@\\n░░ @\\n @\\n @\\n @@\\n @\\n @\\n @\\n @\\n ██@\\n ░░ @\\n ██@\\n ██ @\\n░░ @\\n @\\n @@\\n ███@\\n ███░ @\\n ███░ @\\n ███░ @\\n░░░███ @\\n ░░░███ @\\n ░░░███@\\n ░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████████@\\n░░░░░░░░░ @\\n █████████@\\n░░░░░░░░░ @\\n @\\n @\\n @\\n @\\n @@\\n ███ @\\n░░░███ @\\n ░░░███ @\\n ░░░███@\\n ███░ @\\n ███░ @\\n ███░ @\\n░░░ @\\n @\\n @\\n @@\\n ███████ @\\n ███░░░███@\\n░░░ ░███@\\n ███████ @\\n ░███░░░ @\\n ░░░ @\\n ███ @\\n ░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░░ @\\n░███ ██████ @\\n░███░███░███@\\n░███░███░███@\\n░███░░░ ░███@\\n░░█████████ @\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███ @\\n ░███ ░███ @\\n ░███████████ @\\n ░███░░░░░███ @\\n ░███ ░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ███████████ @\\n░░███░░░░░███@\\n ░███ ░███@\\n ░██████████ @\\n ░███░░░░░███@\\n ░███ ░███@\\n ███████████ @\\n░░░░░░░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███@\\n ███ ░░░ @\\n░███ @\\n░███ @\\n░░███ ███@\\n ░░█████████ @\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n ██████████ @\\n░░███░░░░███ @\\n ░███ ░░███@\\n ░███ ░███@\\n ░███ ░███@\\n ░███ ███ @\\n ██████████ @\\n░░░░░░░░░░ @\\n @\\n @\\n @@\\n ██████████@\\n░░███░░░░░█@\\n ░███ █ ░ @\\n ░██████ @\\n ░███░░█ @\\n ░███ ░ █@\\n ██████████@\\n░░░░░░░░░░ @\\n @\\n @\\n @@\\n ███████████@\\n░░███░░░░░░█@\\n ░███ █ ░ @\\n ░███████ @\\n ░███░░░█ @\\n ░███ ░ @\\n █████ @\\n░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███@\\n ███ ░░░ @\\n░███ @\\n░███ █████@\\n░░███ ░░███ @\\n ░░█████████ @\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███████████ @\\n ░███░░░░░███ @\\n ░███ ░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n █████@\\n░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n █████@\\n ░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ███ ░███ @\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n █████ ████@\\n░░███ ███░ @\\n ░███ ███ @\\n ░███████ @\\n ░███░░███ @\\n ░███ ░░███ @\\n █████ ░░████@\\n░░░░░ ░░░░ @\\n @\\n @\\n @@\\n █████ @\\n░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ █@\\n ███████████@\\n░░░░░░░░░░░ @\\n @\\n @\\n @@\\n ██████ ██████@\\n░░██████ ██████ @\\n ░███░█████░███ @\\n ░███░░███ ░███ @\\n ░███ ░░░ ░███ @\\n ░███ ░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ██████ █████@\\n░░██████ ░░███ @\\n ░███░███ ░███ @\\n ░███░░███░███ @\\n ░███ ░░██████ @\\n ░███ ░░█████ @\\n █████ ░░█████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ███████ @\\n ███░░░░░███ @\\n ███ ░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███ ███ @\\n ░░░███████░ @\\n ░░░░░░░ @\\n @\\n @\\n @@\\n ███████████ @\\n░░███░░░░░███@\\n ░███ ░███@\\n ░██████████ @\\n ░███░░░░░░ @\\n ░███ @\\n █████ @\\n░░░░░ @\\n @\\n @\\n @@\\n ██████ @\\n ███░░░░███ @\\n ███ ░░███@\\n░███ ░███@\\n░███ ██░███@\\n░░███ ░░████ @\\n ░░░██████░██@\\n ░░░░░░ ░░ @\\n @\\n @\\n @@\\n ███████████ @\\n░░███░░░░░███ @\\n ░███ ░███ @\\n ░██████████ @\\n ░███░░░░░███ @\\n ░███ ░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███@\\n░███ ░░░ @\\n░░█████████ @\\n ░░░░░░░░███@\\n ███ ░███@\\n░░█████████ @\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n ███████████@\\n░█░░░███░░░█@\\n░ ░███ ░ @\\n ░███ @\\n ░███ @\\n ░███ @\\n █████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░███ ███ @\\n ░░░█████░ @\\n ░░███ @\\n ░░░ @\\n @\\n @\\n @@\\n █████ ███ █████@\\n░░███ ░███ ░░███ @\\n ░███ ░███ ░███ @\\n ░███ ░███ ░███ @\\n ░░███ █████ ███ @\\n ░░░█████░█████░ @\\n ░░███ ░░███ @\\n ░░░ ░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░░███ ███ @\\n ░░█████ @\\n ███░███ @\\n ███ ░░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░░███ ███ @\\n ░░█████ @\\n ░░███ @\\n ░███ @\\n █████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n ███████████@\\n░█░░░░░░███ @\\n░ ███░ @\\n ███ @\\n ███ @\\n ████ █@\\n ███████████@\\n░░░░░░░░░░░ @\\n @\\n @\\n @@\\n █████@\\n░███░ @\\n░███ @\\n░███ @\\n░███ @\\n░███ @\\n░█████@\\n░░░░░ @\\n @\\n @\\n @@\\n ███ @\\n░░███ @\\n ░░███ @\\n ░░███ @\\n ░░███ @\\n ░░███ @\\n ░░███@\\n ░░░ @\\n @\\n @\\n @@\\n █████@\\n░░░███@\\n ░███@\\n ░███@\\n ░███@\\n ░███@\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n ██ @\\n ████ @\\n ██░░██@\\n░░ ░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n @\\n @\\n @\\n @\\n @\\n @\\n █████████@\\n░░░░░░░░░ @\\n @\\n @\\n @@\\n ██ @\\n░███@\\n░░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n @\\n @\\n ██████ @\\n ░░░░░███ @\\n ███████ @\\n ███░░███ @\\n░░████████@\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n █████ @\\n░░███ @\\n ░███████ @\\n ░███░░███@\\n ░███ ░███@\\n ░███ ░███@\\n ████████ @\\n░░░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ██████ @\\n ███░░███@\\n░███ ░░░ @\\n░███ ███@\\n░░██████ @\\n ░░░░░░ @\\n @\\n @\\n @@\\n █████@\\n ░░███ @\\n ███████ @\\n ███░░███ @\\n░███ ░███ @\\n░███ ░███ @\\n░░████████@\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ██████ @\\n ███░░███@\\n░███████ @\\n░███░░░ @\\n░░██████ @\\n ░░░░░░ @\\n @\\n @\\n @@\\n ██████ @\\n ███░░███@\\n ░███ ░░░ @\\n ███████ @\\n░░░███░ @\\n ░███ @\\n █████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ███████@\\n ███░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███████@\\n ░░░░░███@\\n ███ ░███@\\n░░██████ @\\n ░░░░░░ @@\\n █████ @\\n░░███ @\\n ░███████ @\\n ░███░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ████ █████@\\n░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ███ @\\n ░░░ @\\n ████ @\\n░░███ @\\n ░███ @\\n ░███ @\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n ███ @\\n ░░░ @\\n █████@\\n ░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ███ ░███ @\\n░░██████ @\\n ░░░░░░ @@\\n █████ @\\n░░███ @\\n ░███ █████@\\n ░███░░███ @\\n ░██████░ @\\n ░███░░███ @\\n ████ █████@\\n░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ████ @\\n░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████████████ @\\n░░███░░███░░███ @\\n ░███ ░███ ░███ @\\n ░███ ░███ ░███ @\\n █████░███ █████@\\n░░░░░ ░░░ ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ████████ @\\n░░███░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ████ █████@\\n░░░░ ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ██████ @\\n ███░░███@\\n░███ ░███@\\n░███ ░███@\\n░░██████ @\\n ░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ████████ @\\n░░███░░███@\\n ░███ ░███@\\n ░███ ░███@\\n ░███████ @\\n ░███░░░ @\\n ░███ @\\n █████ @\\n░░░░░ @@\\n @\\n @\\n ████████@\\n ███░░███ @\\n░███ ░███ @\\n░███ ░███ @\\n░░███████ @\\n ░░░░░███ @\\n ░███ @\\n █████@\\n ░░░░░ @@\\n @\\n @\\n ████████ @\\n░░███░░███@\\n ░███ ░░░ @\\n ░███ @\\n █████ @\\n░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ @\\n ███░░ @\\n░░█████ @\\n ░░░░███@\\n ██████ @\\n░░░░░░ @\\n @\\n @\\n @@\\n █████ @\\n ░░███ @\\n ███████ @\\n░░░███░ @\\n ░███ @\\n ░███ ███@\\n ░░█████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ ████@\\n░░███ ░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░████████@\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░░███ ███ @\\n ░░█████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ ███ █████@\\n░░███ ░███░░███ @\\n ░███ ░███ ░███ @\\n ░░███████████ @\\n ░░████░████ @\\n ░░░░ ░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ █████@\\n░░███ ░░███ @\\n ░░░█████░ @\\n ███░░░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ ████@\\n░░███ ░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░███████ @\\n ░░░░░███ @\\n ███ ░███ @\\n ░░██████ @\\n ░░░░░░ @@\\n @\\n @\\n █████████@\\n ░█░░░░███ @\\n ░ ███░ @\\n ███░ █@\\n █████████@\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n ███@\\n ██░ @\\n ██ @\\n ███ @\\n░░░██ @\\n ░░██ @\\n ░░███@\\n ░░░ @\\n @\\n @\\n @@\\n ███@\\n░███@\\n░███@\\n░███@\\n░███@\\n░███@\\n░███@\\n░░░ @\\n @\\n @\\n @@\\n ███ @\\n░░░██ @\\n ░░██ @\\n ░░███@\\n ██░ @\\n ██ @\\n ███ @\\n░░░ @\\n @\\n @\\n @@\\n @\\n ███ ███@\\n ███░███░ @\\n░░░ ░░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n ███ ███ @\\n ░░░ ░░░ @\\n ███████ @\\n ███░░░███ @\\n ░█████████ @\\n ░███░░░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n░░░ ░░░ @\\n ███████ @\\n ███░░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███████ @\\n ░░░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n ░░░ ░░░ @\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░███████ @\\n ░░░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n░░░ ░░░ @\\n ██████ @\\n ░░░░░███ @\\n ███████ @\\n ███░░███ @\\n░░████████@\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n░░░ ░░░ @\\n ███████ @\\n ███░░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███████ @\\n ░░░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n ░░░ ░░░ @\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░█████████@\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███@\\n ░███ ░███@\\n ░██████████ @\\n ░███░░░░░███@\\n ░███ ░███@\\n ████ ██████ @\\n░░░░ ░░░░░░ @\\n @\\n @\\n @@\\n\"\n\n","import { dosrebelFont } from \"./fonts/dosrebel-data\"\n\nexport { dosrebelFont }\n\nexport const asciiFonts = {\n dosrebel: dosrebelFont,\n} as const\n\nexport type AsciiFontName = keyof typeof asciiFonts\n\nexport function getAsciiFont(name: AsciiFontName): string {\n return asciiFonts[name]\n}\n","import { mkdirSync, readFileSync, writeFileSync } from \"node:fs\"\nimport path from \"node:path\"\nimport {\n ASCII_CHAR_HEIGHT,\n ASCII_CHAR_WIDTH,\n asciiFonts,\n composeAsciiText,\n getAsciiAccentColumns,\n getAsciiCellIntensity,\n parseFigletFont,\n type AsciiFontName,\n type AsciiTextLayout,\n} from \"./ascii/index\"\n\ninterface RGB {\n r: number\n g: number\n b: number\n}\n\nexport interface GenerateAsciiGifOptions {\n text: string\n accent?: string\n font?: AsciiFontName | string\n outputPath: string\n color?: string\n accentColor?: string\n backgroundColor?: string\n blendColor?: string\n fps?: number\n duration?: number\n scale?: number\n levels?: number\n padding?: number\n transparent?: boolean\n}\n\nexport async function generateAsciiGif(options: GenerateAsciiGifOptions): Promise<void> {\n const fps = options.fps ?? 24\n const duration = options.duration ?? 2.4\n const scale = options.scale ?? 2\n const levels = Math.max(2, Math.min(48, options.levels ?? 32))\n const padding = Math.max(0, Math.round(options.padding ?? 16))\n const fontRaw = resolveFont(options.font ?? \"dosrebel\")\n const font = parseFigletFont(fontRaw)\n const layout = composeAsciiText(font, options.text)\n const bounds = getLayoutBounds(layout)\n const accentColumns = getAsciiAccentColumns(font, options.text, options.accent ?? \"\")\n const palette = createPalette({\n backgroundColor: options.backgroundColor ?? \"#0a0a0a\",\n blendColor: options.blendColor ?? options.backgroundColor ?? \"#0a0a0a\",\n color: options.color ?? \"#e5e5e5\",\n accentColor: options.accentColor ?? options.color ?? \"#38bdf8\",\n levels,\n transparent: options.transparent ?? false,\n })\n const width = Math.ceil(bounds.cols * ASCII_CHAR_WIDTH * scale) + padding * 2\n const height = bounds.rows * ASCII_CHAR_HEIGHT * scale + padding * 2\n const frameCount = Math.max(1, Math.round(fps * duration))\n const delay = Math.max(1, Math.round(100 / fps))\n const frames: Uint8Array[] = []\n\n for (let frame = 0; frame < frameCount; frame++) {\n frames.push(\n renderIndexedAsciiFrame({\n layout,\n accentColumns,\n phase: frame / frameCount,\n width,\n height,\n scale,\n levels,\n bounds,\n padding,\n }),\n )\n }\n\n const bytes = encodeGif({\n width,\n height,\n delay,\n palette: palette.table,\n frames,\n transparent: options.transparent ?? false,\n })\n\n mkdirSync(path.dirname(options.outputPath), { recursive: true })\n writeFileSync(options.outputPath, bytes)\n}\n\ninterface RenderIndexedFrameOptions {\n layout: AsciiTextLayout\n accentColumns: ReadonlySet<number>\n phase: number\n width: number\n height: number\n scale: number\n levels: number\n bounds: LayoutBounds\n padding: number\n}\n\ninterface LayoutBounds {\n minCol: number\n minRow: number\n cols: number\n rows: number\n}\n\nfunction renderIndexedAsciiFrame(options: RenderIndexedFrameOptions): Uint8Array {\n const pixels = new Uint8Array(options.width * options.height)\n const charWidth = Math.round(ASCII_CHAR_WIDTH * options.scale)\n const charHeight = Math.round(ASCII_CHAR_HEIGHT * options.scale)\n\n for (const cell of options.layout.cells) {\n const intensity = getAsciiCellIntensity(cell, { phase: options.phase })\n const level = Math.max(0, Math.min(options.levels - 1, Math.round(intensity * (options.levels - 1))))\n const offset = options.accentColumns.has(cell.col) ? 1 + options.levels : 1\n const colorIndex = offset + level\n const x0 = options.padding + Math.round((cell.col - options.bounds.minCol) * ASCII_CHAR_WIDTH * options.scale)\n const y0 = options.padding + (cell.row - options.bounds.minRow) * charHeight\n const x1 = Math.min(options.width, x0 + charWidth)\n const y1 = Math.min(options.height, y0 + charHeight)\n\n for (let y = y0; y < y1; y++) {\n const row = y * options.width\n for (let x = x0; x < x1; x++) {\n pixels[row + x] = colorIndex\n }\n }\n }\n\n return pixels\n}\n\nfunction getLayoutBounds(layout: AsciiTextLayout): LayoutBounds {\n if (layout.cells.length === 0) {\n return { minCol: 0, minRow: 0, cols: Math.max(1, layout.cols), rows: Math.max(1, layout.rows) }\n }\n\n let minCol = Number.POSITIVE_INFINITY\n let maxCol = Number.NEGATIVE_INFINITY\n let minRow = Number.POSITIVE_INFINITY\n let maxRow = Number.NEGATIVE_INFINITY\n\n for (const cell of layout.cells) {\n minCol = Math.min(minCol, cell.col)\n maxCol = Math.max(maxCol, cell.col)\n minRow = Math.min(minRow, cell.row)\n maxRow = Math.max(maxRow, cell.row)\n }\n\n return {\n minCol,\n minRow,\n cols: maxCol - minCol + 1,\n rows: maxRow - minRow + 1,\n }\n}\n\nfunction resolveFont(font: AsciiFontName | string): string {\n if (font in asciiFonts) return asciiFonts[font as AsciiFontName]\n return readFileSync(font, \"utf-8\")\n}\n\nfunction createPalette(options: {\n backgroundColor: string\n blendColor: string\n color: string\n accentColor: string\n levels: number\n transparent: boolean\n}) {\n const bg = parseColor(options.backgroundColor)\n const blend = parseColor(options.blendColor)\n const base = parseColor(options.color)\n const accent = parseColor(options.accentColor)\n const table: number[] = [bg.r, bg.g, bg.b]\n\n for (let level = 0; level < options.levels; level++) {\n const alpha = level / (options.levels - 1)\n const mixed = mix(blend, base, alpha)\n table.push(mixed.r, mixed.g, mixed.b)\n }\n\n for (let level = 0; level < options.levels; level++) {\n const alpha = level / (options.levels - 1)\n const mixed = mix(blend, accent, alpha)\n table.push(mixed.r, mixed.g, mixed.b)\n }\n\n while (table.length < 256 * 3) table.push(0, 0, 0)\n return { table: Uint8Array.from(table.slice(0, 256 * 3)) }\n}\n\nfunction parseColor(input: string): RGB {\n const color = input.trim()\n const shortHex = /^#([0-9a-f]{3})$/i.exec(color)\n if (shortHex) {\n const [r, g, b] = shortHex[1].split(\"\").map((part) => Number.parseInt(part + part, 16))\n return { r, g, b }\n }\n\n const longHex = /^#([0-9a-f]{6})$/i.exec(color)\n if (longHex) {\n const value = longHex[1]\n return {\n r: Number.parseInt(value.slice(0, 2), 16),\n g: Number.parseInt(value.slice(2, 4), 16),\n b: Number.parseInt(value.slice(4, 6), 16),\n }\n }\n\n const rgb = /^rgb\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i.exec(color)\n if (rgb) {\n return {\n r: clampByte(Number.parseInt(rgb[1], 10)),\n g: clampByte(Number.parseInt(rgb[2], 10)),\n b: clampByte(Number.parseInt(rgb[3], 10)),\n }\n }\n\n throw new Error(`Unsupported color \"${input}\". Use #rgb, #rrggbb, or rgb(r,g,b).`)\n}\n\nfunction mix(a: RGB, b: RGB, amount: number): RGB {\n return {\n r: clampByte(a.r + (b.r - a.r) * amount),\n g: clampByte(a.g + (b.g - a.g) * amount),\n b: clampByte(a.b + (b.b - a.b) * amount),\n }\n}\n\nfunction clampByte(value: number): number {\n return Math.max(0, Math.min(255, Math.round(value)))\n}\n\ninterface EncodeGifOptions {\n width: number\n height: number\n delay: number\n palette: Uint8Array\n frames: Uint8Array[]\n transparent: boolean\n}\n\nfunction encodeGif(options: EncodeGifOptions): Uint8Array {\n const bytes: number[] = []\n writeAscii(bytes, \"GIF89a\")\n writeU16(bytes, options.width)\n writeU16(bytes, options.height)\n bytes.push(0xf7, 0, 0)\n pushBytes(bytes, options.palette)\n bytes.push(0x21, 0xff, 0x0b)\n writeAscii(bytes, \"NETSCAPE2.0\")\n bytes.push(0x03, 0x01)\n writeU16(bytes, 0)\n bytes.push(0)\n\n for (const frame of options.frames) {\n bytes.push(0x21, 0xf9, 0x04, options.transparent ? 0x05 : 0x04)\n writeU16(bytes, options.delay)\n bytes.push(0, 0)\n bytes.push(0x2c)\n writeU16(bytes, 0)\n writeU16(bytes, 0)\n writeU16(bytes, options.width)\n writeU16(bytes, options.height)\n bytes.push(0)\n bytes.push(8)\n writeSubBlocks(bytes, lzwEncode(frame, 8))\n }\n\n bytes.push(0x3b)\n return Uint8Array.from(bytes)\n}\n\nfunction lzwEncode(indices: Uint8Array, minCodeSize: number): Uint8Array {\n const clearCode = 1 << minCodeSize\n const endCode = clearCode + 1\n let codeSize = minCodeSize + 1\n const output: number[] = []\n const writeCode = createBitWriter(output)\n\n writeCode(clearCode, codeSize)\n\n let codesSinceClear = 0\n for (const index of indices) {\n if (codesSinceClear >= 240) {\n writeCode(clearCode, codeSize)\n codeSize = minCodeSize + 1\n codesSinceClear = 0\n }\n writeCode(index, codeSize)\n codesSinceClear++\n }\n\n writeCode(endCode, codeSize)\n writeCode(-1, 0)\n\n return Uint8Array.from(output)\n}\n\nfunction createBitWriter(output: number[]) {\n let buffer = 0\n let bitCount = 0\n\n return (code: number, size: number) => {\n if (code < 0) {\n if (bitCount > 0) output.push(buffer & 0xff)\n buffer = 0\n bitCount = 0\n return\n }\n\n buffer |= code << bitCount\n bitCount += size\n\n while (bitCount >= 8) {\n output.push(buffer & 0xff)\n buffer >>= 8\n bitCount -= 8\n }\n }\n}\n\nfunction writeSubBlocks(bytes: number[], data: Uint8Array) {\n for (let offset = 0; offset < data.length; offset += 255) {\n const chunk = data.slice(offset, offset + 255)\n bytes.push(chunk.length)\n pushBytes(bytes, chunk)\n }\n bytes.push(0)\n}\n\nfunction writeAscii(bytes: number[], value: string) {\n for (let i = 0; i < value.length; i++) bytes.push(value.charCodeAt(i))\n}\n\nfunction writeU16(bytes: number[], value: number) {\n bytes.push(value & 0xff, (value >> 8) & 0xff)\n}\n\nfunction pushBytes(bytes: number[], values: Uint8Array) {\n for (const value of values) bytes.push(value)\n}\n"]}
1
+ {"version":3,"sources":["../src/ascii/compose.ts","../src/ascii/figlet.ts","../src/ascii/render.ts","../src/ascii/fonts/dosrebel-data.ts","../src/ascii/fonts.ts","../src/ascii-gif.ts"],"names":["bytes"],"mappings":";;;;;;AAcO,SAAS,gBAAA,CAAiB,MAAkB,IAAA,EAA+B;AAChF,EAAA,MAAM,aAAwD,EAAC;AAE/D,EAAA,KAAA,MAAW,MAAM,IAAA,EAAM;AACrB,IAAA,MAAM,IAAA,GAAO,EAAA,CAAG,UAAA,CAAW,CAAC,CAAA;AAC5B,IAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA,IAAK,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,EAAE,CAAA;AACvD,IAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,GAAG,KAAA,CAAM,IAAI,CAAC,IAAA,KAAS,IAAA,CAAK,MAAM,CAAC,CAAA;AAC1D,IAAA,UAAA,CAAW,IAAA,CAAK;AAAA,MACd,KAAA,EAAO,MAAM,GAAA,CAAI,CAAC,SAAS,IAAA,CAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MAC7C;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,IAAA,GAAO,WAAW,MAAA,CAAO,CAAC,KAAK,KAAA,KAAU,GAAA,GAAM,KAAA,CAAM,KAAA,EAAO,CAAC,CAAA;AACnE,EAAA,MAAM,OAAO,IAAA,CAAK,MAAA;AAClB,EAAA,MAAM,QAAqB,EAAC;AAC5B,EAAA,IAAI,OAAA,GAAU,CAAA;AAEd,EAAA,KAAA,MAAW,SAAS,UAAA,EAAY;AAC9B,IAAA,KAAA,IAAS,GAAA,GAAM,CAAA,EAAG,GAAA,GAAM,IAAA,EAAM,GAAA,EAAA,EAAO;AACnC,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,IAAK,EAAA;AACjC,MAAA,KAAA,IAAS,GAAA,GAAM,CAAA,EAAG,GAAA,GAAM,IAAA,CAAK,QAAQ,GAAA,EAAA,EAAO;AAC1C,QAAA,MAAM,EAAA,GAAK,KAAK,GAAG,CAAA;AACnB,QAAA,IAAI,EAAA,KAAO,QAAA,IAAO,EAAA,KAAO,QAAA,EAAK;AAC5B,UAAA,KAAA,CAAM,KAAK,EAAE,EAAA,EAAI,KAAK,OAAA,GAAU,GAAA,EAAK,KAAK,CAAA;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAA,IAAW,KAAA,CAAM,KAAA;AAAA,EACnB;AAEA,EAAA,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,IAAA,EAAK;AAC7B;AAEO,SAAS,qBAAA,CACd,IAAA,EACA,IAAA,EACA,MAAA,EACa;AACb,EAAA,IAAI,CAAC,MAAA,EAAQ,uBAAO,IAAI,GAAA,EAAY;AAEpC,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,EAAA,MAAM,eAAsD,EAAC;AAC7D,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,OAAO,IAAA,EAAM;AACX,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,UAAU,CAAA;AAC3C,IAAA,IAAI,QAAQ,EAAA,EAAI;AAChB,IAAA,YAAA,CAAa,IAAA,CAAK,EAAE,KAAA,EAAO,GAAA,EAAK,KAAK,GAAA,GAAM,MAAA,CAAO,QAAQ,CAAA;AAC1D,IAAA,UAAA,GAAa,GAAA,GAAM,CAAA;AAAA,EACrB;AACA,EAAA,IAAI,YAAA,CAAa,MAAA,KAAW,CAAA,EAAG,OAAO,OAAA;AAEtC,EAAA,IAAI,OAAA,GAAU,CAAA;AACd,EAAA,IAAI,SAAA,GAAY,CAAA;AAEhB,EAAA,KAAA,MAAW,MAAM,IAAA,EAAM;AACrB,IAAA,MAAM,IAAA,GAAO,EAAA,CAAG,UAAA,CAAW,CAAC,CAAA;AAC5B,IAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA,IAAK,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,EAAE,CAAA;AACvD,IAAA,IAAI,CAAC,KAAA,EAAO;AAAE,MAAA,SAAA,EAAA;AAAa,MAAA;AAAA,IAAS;AAEpC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,GAAG,KAAA,CAAM,IAAI,CAAC,IAAA,KAAS,IAAA,CAAK,MAAM,CAAC,CAAA;AAC1D,IAAA,IAAI,YAAA,CAAa,IAAA,CAAK,CAAC,CAAA,KAAM,SAAA,IAAa,EAAE,KAAA,IAAS,SAAA,GAAY,CAAA,CAAE,GAAG,CAAA,EAAG;AACvE,MAAA,KAAA,IAAS,GAAA,GAAM,GAAG,GAAA,GAAM,KAAA,EAAO,OAAO,OAAA,CAAQ,GAAA,CAAI,UAAU,GAAG,CAAA;AAAA,IACjE;AACA,IAAA,OAAA,IAAW,KAAA;AACX,IAAA,SAAA,EAAA;AAAA,EACF;AAEA,EAAA,OAAO,OAAA;AACT;;;AC9EO,SAAS,gBAAgB,GAAA,EAAyB;AACvD,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA;AAE5B,EAAA,IAAI,MAAM,CAAC,CAAA,EAAG,UAAA,CAAW,CAAC,MAAM,KAAA,EAAQ;AACtC,IAAA,KAAA,CAAM,CAAC,CAAA,GAAI,KAAA,CAAM,CAAC,CAAA,CAAE,MAAM,CAAC,CAAA;AAAA,EAC7B;AAEA,EAAA,MAAM,MAAA,GAAS,MAAM,CAAC,CAAA;AACtB,EAAA,IAAI,CAAC,MAAA,EAAQ,UAAA,CAAW,OAAO,CAAA,EAAG;AAChC,IAAA,MAAM,IAAI,MAAM,2CAA2C,CAAA;AAAA,EAC7D;AAEA,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,CAAC,CAAA,IAAK,GAAA;AAC/B,EAAA,MAAM,KAAA,GAAQ,OAAO,KAAA,CAAM,CAAC,EAAE,IAAA,EAAK,CAAE,MAAM,KAAK,CAAA;AAChD,EAAA,MAAM,SAAS,MAAA,CAAO,QAAA,CAAS,MAAM,CAAC,CAAA,IAAK,IAAI,EAAE,CAAA;AACjD,EAAA,MAAM,WAAW,MAAA,CAAO,QAAA,CAAS,MAAM,CAAC,CAAA,IAAK,IAAI,EAAE,CAAA;AACnD,EAAA,MAAM,eAAe,MAAA,CAAO,QAAA,CAAS,MAAM,CAAC,CAAA,IAAK,IAAI,EAAE,CAAA;AAEvD,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,IAAK,UAAU,CAAA,EAAG;AAC3C,IAAA,MAAM,IAAI,MAAM,+CAA+C,CAAA;AAAA,EACjE;AAEA,EAAA,MAAM,YAAY,CAAA,IAAK,MAAA,CAAO,QAAA,CAAS,YAAY,IAAI,YAAA,GAAe,CAAA,CAAA;AACtE,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAsB;AACxC,EAAA,IAAI,SAAA,GAAY,SAAA;AAChB,EAAA,IAAI,KAAA,GAAQ,EAAA;AAEZ,EAAA,OAAO,SAAA,GAAY,MAAA,IAAU,KAAA,CAAM,MAAA,IAAU,SAAS,GAAA,EAAK;AACzD,IAAA,MAAM,YAAsB,EAAC;AAC7B,IAAA,KAAA,IAAS,GAAA,GAAM,CAAA,EAAG,GAAA,GAAM,MAAA,EAAQ,GAAA,EAAA,EAAO;AACrC,MAAA,MAAM,IAAA,GAAA,CAAQ,KAAA,CAAM,SAAA,GAAY,GAAG,CAAA,IAAK,EAAA,EACrC,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,CACjB,UAAA,CAAW,SAAA,EAAW,GAAG,CAAA;AAC5B,MAAA,SAAA,CAAU,KAAK,IAAI,CAAA;AAAA,IACrB;AAEA,IAAA,KAAA,CAAM,GAAA,CAAI,OAAO,SAAS,CAAA;AAC1B,IAAA,SAAA,IAAa,MAAA;AACb,IAAA,KAAA,EAAA;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,MAAA,EAAQ,QAAA,EAAU,SAAA,EAAW,KAAA,EAAM;AAC9C;;;AC/CO,IAAM,gBAAA,GAAmB,GAAA;AACzB,IAAM,iBAAA,GAAoB,EAAA;AA+C1B,SAAS,qBAAA,CAAsB,MAAiB,OAAA,EAAkC;AACvF,EAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,IAAQ,CAAA;AAC7B,EAAA,MAAM,IAAA,GAAO,QAAQ,KAAA,IAAS,IAAA,GAAO,OAAO,OAAA,CAAQ,KAAA,GAAQ,KAAK,EAAA,GAAK,CAAA;AAEtE,EAAA,IAAI,IAAA,CAAK,OAAO,QAAA,EAAK;AACnB,IAAA,MAAM,QACJ,IAAA,IAAQ,IAAA,GACJ,KAAK,GAAA,CAAI,IAAA,GAAO,MAAM,IAAA,CAAK,GAAA,GAAM,GAAG,CAAA,GAAI,OACxC,IAAA,CAAK,GAAA,CAAI,OAAO,IAAA,CAAK,GAAA,GAAM,GAAG,CAAA,GAAI,IAAA;AACxC,IAAA,OAAO,IAAA,GAAO,KAAA;AAAA,EAChB;AAEA,EAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,IAAA,OAAO,gBAAA,CAAiB,MAAM,IAAI,CAAA;AAAA,EACpC;AAEA,EAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,IAAA,EAAM,IAAI,CAAA;AAErC,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,GAAM,IAAA,GAAO,KAAK,GAAA,GAAM,KAAA;AAC1C,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,GAAI,GAAA;AACtC,EAAA,MAAM,WAAA,GAAc,IAAA,CAAK,GAAA,CAAI,IAAA,GAAO,MAAM,YAAY,CAAA;AACtD,EAAA,MAAM,OAAA,GAAU,WAAA,GAAc,IAAA,GAAO,IAAA,GAAO,CAAA;AAE5C,EAAA,IAAI,SAAA,GAAY,MAAM,KAAA,GAAQ,OAAA;AAC9B,EAAA,MAAM,SAAA,GAAY,gBAAA;AAClB,EAAA,MAAM,UAAA,GAAa,iBAAA;AAEnB,EAAA,IAAI,OAAA,CAAQ,SAAS,MAAA,EAAQ;AAC3B,IAAA,MAAM,MAAM,IAAA,CAAK,GAAA,GAAM,YAAY,SAAA,GAAY,CAAA,GAAI,QAAQ,OAAA,CAAQ,CAAA;AACnE,IAAA,MAAM,MAAM,IAAA,CAAK,GAAA,GAAM,aAAa,UAAA,GAAa,CAAA,GAAI,QAAQ,OAAA,CAAQ,CAAA;AACrE,IAAA,MAAM,QAAQ,IAAA,CAAK,IAAA,CAAK,GAAA,GAAM,GAAA,GAAM,MAAM,GAAG,CAAA;AAC7C,IAAA,MAAM,MAAA,GAAS,EAAA;AACf,IAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,MAAA,MAAM,OAAA,GAAU,IAAI,KAAA,GAAQ,MAAA;AAC5B,MAAA,MAAM,MAAA,GAAS,KAAK,GAAA,CAAI,KAAA,GAAQ,OAAO,IAAA,GAAO,CAAC,CAAA,GAAI,IAAA,GAAO,OAAA,GAAU,OAAA;AACpE,MAAA,SAAA,GAAY,KAAK,GAAA,CAAI,CAAA,EAAG,SAAA,GAAY,OAAA,GAAU,MAAM,MAAM,CAAA;AAAA,IAC5D;AAAA,EACF;AAEA,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,GAAM,SAAA,GAAY,SAAA,GAAY,CAAA;AAC9C,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,GAAM,UAAA,GAAa,UAAA,GAAa,CAAA;AAChD,EAAA,KAAA,MAAW,IAAA,IAAQ,OAAA,CAAQ,KAAA,IAAS,EAAC,EAAG;AACtC,IAAA,MAAM,GAAA,GAAM,KAAK,IAAA,CAAK,EAAA;AACtB,IAAA,MAAM,GAAA,GAAM,KAAK,IAAA,CAAK,EAAA;AACtB,IAAA,MAAM,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,GAAM,GAAA,GAAM,MAAM,GAAG,CAAA;AAC5C,IAAA,MAAM,GAAA,GAAM,OAAO,IAAA,CAAK,CAAA;AACxB,IAAA,MAAM,aAAa,GAAA,GAAM,GAAA;AACzB,IAAA,MAAM,QAAQ,IAAA,GAAO,UAAA;AACrB,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAC,MAAM,GAAG,CAAA;AAChC,IAAA,MAAM,OAAO,IAAA,CAAK,GAAA,CAAI,CAAC,KAAA,GAAQ,KAAA,GAAQ,IAAK,CAAA,GAAI,IAAA;AAChD,IAAA,SAAA,GAAY,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,SAAA,GAAY,IAAA,GAAO,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,KAAA,GAAQ,IAAA,GAAO,GAAG,CAAC,CAAA;AAAA,EAC/E;AAEA,EAAA,OAAO,KAAK,GAAA,CAAI,GAAA,EAAK,KAAK,GAAA,CAAI,CAAA,EAAG,SAAS,CAAC,CAAA;AAC7C;AAwBA,SAAS,YAAA,CAAa,MAAiB,IAAA,EAAsB;AAC3D,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,GAAM,IAAA,GAAO,IAAA,GAAO,GAAA;AACpC,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,GAAM,GAAA,GAAM,IAAA,GAAO,IAAA;AACnC,EAAA,OACE,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,GAAI,OACf,IAAA,CAAK,GAAA,CAAI,EAAA,GAAK,GAAA,GAAM,EAAA,GAAK,GAAG,CAAA,GAAI,GAAA,GAChC,KAAK,GAAA,CAAI,EAAA,GAAK,GAAA,GAAM,EAAA,GAAK,GAAA,GAAM,IAAA,GAAO,GAAG,CAAA,GAAI,OAC7C,IAAA,CAAK,GAAA,CAAA,CAAK,IAAA,CAAK,GAAA,GAAM,IAAA,CAAK,GAAA,IAAO,IAAA,GAAO,IAAA,GAAO,GAAG,CAAA,GAAI,IAAA;AAE1D;AAEA,SAAS,gBAAA,CAAiB,MAAiB,IAAA,EAAsB;AAC/D,EAAA,MAAM,OACJ,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,GAAM,OAAO,IAAI,CAAA,GAAI,KAAA,GACnC,IAAA,CAAK,IAAI,IAAA,CAAK,GAAA,GAAM,IAAA,GAAO,IAAA,GAAO,IAAI,CAAA,GAAI,IAAA;AAC5C,EAAA,MAAM,OAAA,GAAA,CAAW,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,GAAM,IAAA,GAAO,IAAA,CAAK,GAAA,GAAM,IAAA,GAAO,IAAA,GAAO,CAAC,CAAA,GAAI,CAAA,IAAK,CAAA;AAC/E,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,CAAC,CAAA,GAAI,IAAA;AACzC,EAAA,MAAM,SAAA,GAAY,OAAO,IAAA,GAAO,SAAA;AAEhC,EAAA,OAAO,KAAK,GAAA,CAAI,IAAA,EAAM,KAAK,GAAA,CAAI,CAAA,EAAG,SAAS,CAAC,CAAA;AAC9C;;;ACnJO,IAAM,YAAA,GAAuB,CAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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","file":"ascii-gif.js","sourcesContent":["import type { FigletFont } from \"./figlet\"\n\nexport interface AsciiCell {\n ch: \"█\" | \"░\"\n col: number\n row: number\n}\n\nexport interface AsciiTextLayout {\n cells: AsciiCell[]\n cols: number\n rows: number\n}\n\nexport function composeAsciiText(font: FigletFont, text: string): AsciiTextLayout {\n const charBlocks: Array<{ lines: string[]; width: number }> = []\n\n for (const ch of text) {\n const code = ch.charCodeAt(0)\n const glyph = font.chars.get(code) ?? font.chars.get(32)\n if (!glyph) continue\n\n const width = Math.max(...glyph.map((line) => line.length))\n charBlocks.push({\n lines: glyph.map((line) => line.padEnd(width)),\n width,\n })\n }\n\n const cols = charBlocks.reduce((sum, block) => sum + block.width, 0)\n const rows = font.height\n const cells: AsciiCell[] = []\n let offsetX = 0\n\n for (const block of charBlocks) {\n for (let row = 0; row < rows; row++) {\n const line = block.lines[row] ?? \"\"\n for (let col = 0; col < line.length; col++) {\n const ch = line[col]\n if (ch === \"█\" || ch === \"░\") {\n cells.push({ ch, col: offsetX + col, row })\n }\n }\n }\n offsetX += block.width\n }\n\n return { cells, cols, rows }\n}\n\nexport function getAsciiAccentColumns(\n font: FigletFont,\n text: string,\n accent: string,\n): Set<number> {\n if (!accent) return new Set<number>()\n\n const columns = new Set<number>()\n const accentRanges: Array<{ start: number; end: number }> = []\n let searchFrom = 0\n while (true) {\n const idx = text.indexOf(accent, searchFrom)\n if (idx === -1) break\n accentRanges.push({ start: idx, end: idx + accent.length })\n searchFrom = idx + 1\n }\n if (accentRanges.length === 0) return columns\n\n let offsetX = 0\n let charIndex = 0\n\n for (const ch of text) {\n const code = ch.charCodeAt(0)\n const glyph = font.chars.get(code) ?? font.chars.get(32)\n if (!glyph) { charIndex++; continue }\n\n const width = Math.max(...glyph.map((line) => line.length))\n if (accentRanges.some((r) => charIndex >= r.start && charIndex < r.end)) {\n for (let col = 0; col < width; col++) columns.add(offsetX + col)\n }\n offsetX += width\n charIndex++\n }\n\n return columns\n}\n","export interface FigletFont {\n height: number\n baseline: number\n hardblank: string\n chars: Map<number, string[]>\n}\n\nexport function parseFigletFont(raw: string): FigletFont {\n const lines = raw.split(\"\\n\")\n\n if (lines[0]?.charCodeAt(0) === 0xfeff) {\n lines[0] = lines[0].slice(1)\n }\n\n const header = lines[0]\n if (!header?.startsWith(\"flf2a\")) {\n throw new Error(\"Invalid FIGlet font: missing flf2a header\")\n }\n\n const hardblank = header[5] ?? \"$\"\n const parts = header.slice(6).trim().split(/\\s+/)\n const height = Number.parseInt(parts[0] ?? \"\", 10)\n const baseline = Number.parseInt(parts[1] ?? \"\", 10)\n const commentLines = Number.parseInt(parts[4] ?? \"\", 10)\n\n if (!Number.isFinite(height) || height <= 0) {\n throw new Error(\"Invalid FIGlet font: missing character height\")\n }\n\n const dataStart = 1 + (Number.isFinite(commentLines) ? commentLines : 0)\n const chars = new Map<number, string[]>()\n let lineIndex = dataStart\n let ascii = 32\n\n while (lineIndex + height <= lines.length && ascii <= 126) {\n const charLines: string[] = []\n for (let row = 0; row < height; row++) {\n const line = (lines[lineIndex + row] ?? \"\")\n .replace(/@+$/, \"\")\n .replaceAll(hardblank, \" \")\n charLines.push(line)\n }\n\n chars.set(ascii, charLines)\n lineIndex += height\n ascii++\n }\n\n return { height, baseline, hardblank, chars }\n}\n","import type { AsciiCell, AsciiTextLayout } from \"./compose\"\n\nexport const ASCII_CHAR_WIDTH = 7.5\nexport const ASCII_CHAR_HEIGHT = 15\n\nexport interface AsciiWave {\n cx: number\n cy: number\n t: number\n}\n\nexport interface AsciiPointer {\n x: number\n y: number\n active: boolean\n}\n\nexport interface AsciiFrameState {\n time?: number\n phase?: number\n pointer?: AsciiPointer\n waves?: AsciiWave[]\n}\n\nexport interface AsciiRenderOptions extends AsciiFrameState {\n accentColumns?: ReadonlySet<number>\n color: string\n accentColor?: string\n charWidth?: number\n charHeight?: number\n}\n\nexport interface AsciiFrameContext {\n clearRect(x: number, y: number, width: number, height: number): void\n fillRect(x: number, y: number, width: number, height: number): void\n globalAlpha: number\n fillStyle: string\n}\n\nexport function getAsciiCanvasSize(\n layout: AsciiTextLayout,\n charWidth = ASCII_CHAR_WIDTH,\n charHeight = ASCII_CHAR_HEIGHT,\n) {\n return {\n width: Math.ceil(layout.cols * charWidth),\n height: layout.rows * charHeight,\n }\n}\n\nexport function getAsciiCellIntensity(cell: AsciiCell, options: AsciiFrameState): number {\n const time = options.time ?? 0\n const loop = options.phase == null ? null : options.phase * Math.PI * 2\n\n if (cell.ch === \"░\") {\n const drift =\n loop == null\n ? Math.sin(time * 0.3 + cell.col * 0.1) * 0.03\n : Math.sin(loop + cell.col * 0.1) * 0.03\n return 0.15 + drift\n }\n\n if (loop != null) {\n return getLoopIntensity(cell, loop)\n }\n\n const noise = getLiveNoise(cell, time)\n\n const seed = cell.col * 7.13 + cell.row * 13.37\n const flickerPhase = Math.sin(seed) * 1000\n const flickerWave = Math.sin(time * 0.8 + flickerPhase)\n const flicker = flickerWave > 0.97 ? 0.15 : 0\n\n let intensity = 0.7 + noise + flicker\n const charWidth = ASCII_CHAR_WIDTH\n const charHeight = ASCII_CHAR_HEIGHT\n\n if (options.pointer?.active) {\n const mdx = cell.col * charWidth + charWidth / 2 - options.pointer.x\n const mdy = cell.row * charHeight + charHeight / 2 - options.pointer.y\n const mDist = Math.sqrt(mdx * mdx + mdy * mdy)\n const radius = 80\n if (mDist < radius) {\n const falloff = 1 - mDist / radius\n const ripple = Math.sin(mDist * 0.08 - time * 4) * 0.12 * falloff * falloff\n intensity = Math.min(1, intensity + falloff * 0.2 + ripple)\n }\n }\n\n const px = cell.col * charWidth + charWidth / 2\n const py = cell.row * charHeight + charHeight / 2\n for (const wave of options.waves ?? []) {\n const wdx = px - wave.cx\n const wdy = py - wave.cy\n const dist = Math.sqrt(wdx * wdx + wdy * wdy)\n const age = time - wave.t\n const waveRadius = age * 200\n const delta = dist - waveRadius\n const fade = Math.exp(-age * 1.5)\n const ring = Math.exp(-delta * delta * 0.002) * fade\n intensity = Math.min(1, intensity + ring * 0.5 * Math.sin(delta * 0.06 + 1.5))\n }\n\n return Math.max(0.5, Math.min(1, intensity))\n}\n\nexport function renderAsciiFrameToContext(\n ctx: AsciiFrameContext,\n layout: AsciiTextLayout,\n options: AsciiRenderOptions,\n) {\n const charWidth = options.charWidth ?? ASCII_CHAR_WIDTH\n const charHeight = options.charHeight ?? ASCII_CHAR_HEIGHT\n const { width, height } = getAsciiCanvasSize(layout, charWidth, charHeight)\n const accentColor = options.accentColor ?? options.color\n\n ctx.clearRect(0, 0, width, height)\n\n for (const cell of layout.cells) {\n const isAccent = options.accentColumns?.has(cell.col) ?? false\n ctx.globalAlpha = getAsciiCellIntensity(cell, options)\n ctx.fillStyle = isAccent ? accentColor : options.color\n ctx.fillRect(cell.col * charWidth, cell.row * charHeight, charWidth, charHeight)\n }\n\n ctx.globalAlpha = 1\n}\n\nfunction getLiveNoise(cell: AsciiCell, time: number): number {\n const nx = cell.col * 0.18 + time * 0.9\n const ny = cell.row * 0.3 + time * 0.55\n return (\n Math.sin(nx) * 0.12 +\n Math.sin(ny * 1.4 + nx * 0.6) * 0.1 +\n Math.sin(nx * 0.4 - ny * 0.8 + time * 1.6) * 0.08 +\n Math.sin((cell.col + cell.row) * 0.15 + time * 0.4) * 0.07\n )\n}\n\nfunction getLoopIntensity(cell: AsciiCell, loop: number): number {\n const flow =\n Math.sin(cell.col * 0.08 + loop) * 0.055 +\n Math.sin(cell.row * 0.22 - loop * 0.75) * 0.04\n const shimmer = (Math.sin(cell.col * 0.16 + cell.row * 0.08 - loop * 2) + 1) / 2\n const highlight = Math.pow(shimmer, 4) * 0.22\n const intensity = 0.68 + flow + highlight\n\n return Math.max(0.55, Math.min(1, intensity))\n}\n","// @generated from dosrebel.flf. Do not edit by hand.\nexport const dosrebelFont: string = \"flf2a$ 11 8 35 -1 15\\nRebel by Valerie Mates (popcorn@cyberspace.org), based on a font by Ron Bliss\\n(who sometimes goes by the name \\\"rebel\\\" because his initials are REB).\\nNOTE: THIS FONT ONLY WORKS IN MS-DOS.\\nMay 27, 1994\\n\\nExplanation of first line:\\nflf2 - \\\"magic number\\\" for file identification\\na - should always be `a', for now\\n$ - the \\\"hardblank\\\" -- prints as a blank, but can't be smushed\\n11 - height of a character\\n8 - height of a character, not including descenders\\n35 - max line length (excluding comment lines) + a fudge factor\\n-1 - default smushmode for this font (like \\\"-m 15\\\" on command line)\\n15 - number of comment lines\\n\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@@\\n ███@\\n░███@\\n░███@\\n░███@\\n░███@\\n░░░ @\\n ███@\\n░░░ @\\n @\\n @\\n @@\\n ██ ██@\\n░██░██@\\n░░ ░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n ███ ███ @\\n ████████████@\\n░░░███░░███░ @\\n ████████████@\\n░░░███░░███░ @\\n ░░░ ░░░ @\\n @\\n @\\n @\\n @\\n @@\\n ███ @\\n ██████ @\\n ███░░░ @\\n ░░█████ @\\n ░░░░███ @\\n ██████ @\\n ░░░███ @\\n ░░░ @\\n @\\n @\\n @@\\n ███ ███@\\n ░░░ ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ ███ @\\n░░░ ░░░ @\\n @\\n @\\n @@\\n ██████ @\\n ███░░███ @\\n ░░██████ @\\n ██████ @\\n░███░░███ @\\n░███ ░░███ @\\n░░█████░███@\\n ░░░░░ ░░░ @\\n @\\n @\\n @@\\n ██@\\n ███@\\n░░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n ███@\\n ███ @\\n ███ @\\n░███ @\\n░███ @\\n░░███ @\\n ░░███@\\n ░░░ @\\n @\\n @\\n @@\\n ███ @\\n░░███ @\\n ░░███@\\n ░███@\\n ░███@\\n ███ @\\n ██░ @\\n░░░ @\\n @\\n @\\n @@\\n ███ @\\n ███ ░███ ███@\\n░░░█████████░ @\\n ░░░█████░ @\\n █████████ @\\n ███░░███░░███@\\n░░░ ░███ ░░░ @\\n ░░░ @\\n @\\n @\\n @@\\n @\\n ███ @\\n ░███ @\\n ███████████@\\n░░░░░███░░░ @\\n ░███ @\\n ░░░ @\\n @\\n @\\n @\\n @@\\n @\\n @\\n @\\n @\\n @\\n @\\n ██@\\n ██ @\\n░░ @\\n @\\n @@\\n @\\n @\\n @\\n ██████████@\\n░░░░░░░░░░ @\\n @\\n @\\n @\\n @\\n @\\n @@\\n @\\n @\\n @\\n @\\n @\\n @\\n ██@\\n░░ @\\n @\\n @\\n @@\\n ███@\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n░░░ @\\n @\\n @\\n @@\\n █████ @\\n ███░░░███ @\\n ███ ░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███ ███ @\\n ░░░█████░ @\\n ░░░░░░ @\\n @\\n @\\n @@\\n ████ @\\n░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███@\\n░░░ ░███@\\n ███████ @\\n ███░░░░ @\\n ███ █@\\n░██████████@\\n░░░░░░░░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███@\\n░░░ ░███@\\n ██████░ @\\n ░░░░░░███@\\n ███ ░███@\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n █████ █████ @\\n░░███ ░░███ @\\n ░███ ░███ █@\\n ░███████████@\\n ░░░░░░░███░█@\\n ░███░ @\\n █████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n ██████████@\\n░███░░░░░░█@\\n░███ ░ @\\n░█████████ @\\n░░░░░░░░███@\\n ███ ░███@\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███@\\n░███ ░░░ @\\n░█████████ @\\n░███░░░░███@\\n░███ ░███@\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n ██████████@\\n░███░░░░███@\\n░░░ ███ @\\n ███ @\\n ███ @\\n ███ @\\n ███ @\\n ░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███ @\\n░███ ░███ @\\n░░████████ @\\n ███░░░░███ @\\n░███ ░███ @\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███@\\n░███ ░███@\\n░░█████████@\\n ░░░░░░░███@\\n ███ ░███@\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ██@\\n░░ @\\n @\\n @\\n ██@\\n░░ @\\n @\\n @\\n @@\\n @\\n @\\n @\\n @\\n ██@\\n ░░ @\\n ██@\\n ██ @\\n░░ @\\n @\\n @@\\n ███@\\n ███░ @\\n ███░ @\\n ███░ @\\n░░░███ @\\n ░░░███ @\\n ░░░███@\\n ░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████████@\\n░░░░░░░░░ @\\n █████████@\\n░░░░░░░░░ @\\n @\\n @\\n @\\n @\\n @@\\n ███ @\\n░░░███ @\\n ░░░███ @\\n ░░░███@\\n ███░ @\\n ███░ @\\n ███░ @\\n░░░ @\\n @\\n @\\n @@\\n ███████ @\\n ███░░░███@\\n░░░ ░███@\\n ███████ @\\n ░███░░░ @\\n ░░░ @\\n ███ @\\n ░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░░ @\\n░███ ██████ @\\n░███░███░███@\\n░███░███░███@\\n░███░░░ ░███@\\n░░█████████ @\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███ @\\n ░███ ░███ @\\n ░███████████ @\\n ░███░░░░░███ @\\n ░███ ░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ███████████ @\\n░░███░░░░░███@\\n ░███ ░███@\\n ░██████████ @\\n ░███░░░░░███@\\n ░███ ░███@\\n ███████████ @\\n░░░░░░░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███@\\n ███ ░░░ @\\n░███ @\\n░███ @\\n░░███ ███@\\n ░░█████████ @\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n ██████████ @\\n░░███░░░░███ @\\n ░███ ░░███@\\n ░███ ░███@\\n ░███ ░███@\\n ░███ ███ @\\n ██████████ @\\n░░░░░░░░░░ @\\n @\\n @\\n @@\\n ██████████@\\n░░███░░░░░█@\\n ░███ █ ░ @\\n ░██████ @\\n ░███░░█ @\\n ░███ ░ █@\\n ██████████@\\n░░░░░░░░░░ @\\n @\\n @\\n @@\\n ███████████@\\n░░███░░░░░░█@\\n ░███ █ ░ @\\n ░███████ @\\n ░███░░░█ @\\n ░███ ░ @\\n █████ @\\n░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███@\\n ███ ░░░ @\\n░███ @\\n░███ █████@\\n░░███ ░░███ @\\n ░░█████████ @\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███████████ @\\n ░███░░░░░███ @\\n ░███ ░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n █████@\\n░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n █████@\\n ░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ███ ░███ @\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n █████ ████@\\n░░███ ███░ @\\n ░███ ███ @\\n ░███████ @\\n ░███░░███ @\\n ░███ ░░███ @\\n █████ ░░████@\\n░░░░░ ░░░░ @\\n @\\n @\\n @@\\n █████ @\\n░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ █@\\n ███████████@\\n░░░░░░░░░░░ @\\n @\\n @\\n @@\\n ██████ ██████@\\n░░██████ ██████ @\\n ░███░█████░███ @\\n ░███░░███ ░███ @\\n ░███ ░░░ ░███ @\\n ░███ ░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ██████ █████@\\n░░██████ ░░███ @\\n ░███░███ ░███ @\\n ░███░░███░███ @\\n ░███ ░░██████ @\\n ░███ ░░█████ @\\n █████ ░░█████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ███████ @\\n ███░░░░░███ @\\n ███ ░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███ ███ @\\n ░░░███████░ @\\n ░░░░░░░ @\\n @\\n @\\n @@\\n ███████████ @\\n░░███░░░░░███@\\n ░███ ░███@\\n ░██████████ @\\n ░███░░░░░░ @\\n ░███ @\\n █████ @\\n░░░░░ @\\n @\\n @\\n @@\\n ██████ @\\n ███░░░░███ @\\n ███ ░░███@\\n░███ ░███@\\n░███ ██░███@\\n░░███ ░░████ @\\n ░░░██████░██@\\n ░░░░░░ ░░ @\\n @\\n @\\n @@\\n ███████████ @\\n░░███░░░░░███ @\\n ░███ ░███ @\\n ░██████████ @\\n ░███░░░░░███ @\\n ░███ ░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███@\\n░███ ░░░ @\\n░░█████████ @\\n ░░░░░░░░███@\\n ███ ░███@\\n░░█████████ @\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n ███████████@\\n░█░░░███░░░█@\\n░ ░███ ░ @\\n ░███ @\\n ░███ @\\n ░███ @\\n █████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░███ ███ @\\n ░░░█████░ @\\n ░░███ @\\n ░░░ @\\n @\\n @\\n @@\\n █████ ███ █████@\\n░░███ ░███ ░░███ @\\n ░███ ░███ ░███ @\\n ░███ ░███ ░███ @\\n ░░███ █████ ███ @\\n ░░░█████░█████░ @\\n ░░███ ░░███ @\\n ░░░ ░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░░███ ███ @\\n ░░█████ @\\n ███░███ @\\n ███ ░░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░░███ ███ @\\n ░░█████ @\\n ░░███ @\\n ░███ @\\n █████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n ███████████@\\n░█░░░░░░███ @\\n░ ███░ @\\n ███ @\\n ███ @\\n ████ █@\\n ███████████@\\n░░░░░░░░░░░ @\\n @\\n @\\n @@\\n █████@\\n░███░ @\\n░███ @\\n░███ @\\n░███ @\\n░███ @\\n░█████@\\n░░░░░ @\\n @\\n @\\n @@\\n ███ @\\n░░███ @\\n ░░███ @\\n ░░███ @\\n ░░███ @\\n ░░███ @\\n ░░███@\\n ░░░ @\\n @\\n @\\n @@\\n █████@\\n░░░███@\\n ░███@\\n ░███@\\n ░███@\\n ░███@\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n ██ @\\n ████ @\\n ██░░██@\\n░░ ░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n @\\n @\\n @\\n @\\n @\\n @\\n █████████@\\n░░░░░░░░░ @\\n @\\n @\\n @@\\n ██ @\\n░███@\\n░░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n @\\n @\\n ██████ @\\n ░░░░░███ @\\n ███████ @\\n ███░░███ @\\n░░████████@\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n █████ @\\n░░███ @\\n ░███████ @\\n ░███░░███@\\n ░███ ░███@\\n ░███ ░███@\\n ████████ @\\n░░░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ██████ @\\n ███░░███@\\n░███ ░░░ @\\n░███ ███@\\n░░██████ @\\n ░░░░░░ @\\n @\\n @\\n @@\\n █████@\\n ░░███ @\\n ███████ @\\n ███░░███ @\\n░███ ░███ @\\n░███ ░███ @\\n░░████████@\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ██████ @\\n ███░░███@\\n░███████ @\\n░███░░░ @\\n░░██████ @\\n ░░░░░░ @\\n @\\n @\\n @@\\n ██████ @\\n ███░░███@\\n ░███ ░░░ @\\n ███████ @\\n░░░███░ @\\n ░███ @\\n █████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ███████@\\n ███░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███████@\\n ░░░░░███@\\n ███ ░███@\\n░░██████ @\\n ░░░░░░ @@\\n █████ @\\n░░███ @\\n ░███████ @\\n ░███░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ████ █████@\\n░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ███ @\\n ░░░ @\\n ████ @\\n░░███ @\\n ░███ @\\n ░███ @\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n ███ @\\n ░░░ @\\n █████@\\n ░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ███ ░███ @\\n░░██████ @\\n ░░░░░░ @@\\n █████ @\\n░░███ @\\n ░███ █████@\\n ░███░░███ @\\n ░██████░ @\\n ░███░░███ @\\n ████ █████@\\n░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ████ @\\n░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████████████ @\\n░░███░░███░░███ @\\n ░███ ░███ ░███ @\\n ░███ ░███ ░███ @\\n █████░███ █████@\\n░░░░░ ░░░ ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ████████ @\\n░░███░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ████ █████@\\n░░░░ ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ██████ @\\n ███░░███@\\n░███ ░███@\\n░███ ░███@\\n░░██████ @\\n ░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ████████ @\\n░░███░░███@\\n ░███ ░███@\\n ░███ ░███@\\n ░███████ @\\n ░███░░░ @\\n ░███ @\\n █████ @\\n░░░░░ @@\\n @\\n @\\n ████████@\\n ███░░███ @\\n░███ ░███ @\\n░███ ░███ @\\n░░███████ @\\n ░░░░░███ @\\n ░███ @\\n █████@\\n ░░░░░ @@\\n @\\n @\\n ████████ @\\n░░███░░███@\\n ░███ ░░░ @\\n ░███ @\\n █████ @\\n░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ @\\n ███░░ @\\n░░█████ @\\n ░░░░███@\\n ██████ @\\n░░░░░░ @\\n @\\n @\\n @@\\n █████ @\\n ░░███ @\\n ███████ @\\n░░░███░ @\\n ░███ @\\n ░███ ███@\\n ░░█████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ ████@\\n░░███ ░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░████████@\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░░███ ███ @\\n ░░█████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ ███ █████@\\n░░███ ░███░░███ @\\n ░███ ░███ ░███ @\\n ░░███████████ @\\n ░░████░████ @\\n ░░░░ ░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ █████@\\n░░███ ░░███ @\\n ░░░█████░ @\\n ███░░░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ ████@\\n░░███ ░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░███████ @\\n ░░░░░███ @\\n ███ ░███ @\\n ░░██████ @\\n ░░░░░░ @@\\n @\\n @\\n █████████@\\n ░█░░░░███ @\\n ░ ███░ @\\n ███░ █@\\n █████████@\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n ███@\\n ██░ @\\n ██ @\\n ███ @\\n░░░██ @\\n ░░██ @\\n ░░███@\\n ░░░ @\\n @\\n @\\n @@\\n ███@\\n░███@\\n░███@\\n░███@\\n░███@\\n░███@\\n░███@\\n░░░ @\\n @\\n @\\n @@\\n ███ @\\n░░░██ @\\n ░░██ @\\n ░░███@\\n ██░ @\\n ██ @\\n ███ @\\n░░░ @\\n @\\n @\\n @@\\n @\\n ███ ███@\\n ███░███░ @\\n░░░ ░░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n ███ ███ @\\n ░░░ ░░░ @\\n ███████ @\\n ███░░░███ @\\n ░█████████ @\\n ░███░░░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n░░░ ░░░ @\\n ███████ @\\n ███░░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███████ @\\n ░░░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n ░░░ ░░░ @\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░███████ @\\n ░░░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n░░░ ░░░ @\\n ██████ @\\n ░░░░░███ @\\n ███████ @\\n ███░░███ @\\n░░████████@\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n░░░ ░░░ @\\n ███████ @\\n ███░░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███████ @\\n ░░░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n ░░░ ░░░ @\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░█████████@\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███@\\n ░███ ░███@\\n ░██████████ @\\n ░███░░░░░███@\\n ░███ ░███@\\n ████ ██████ @\\n░░░░ ░░░░░░ @\\n @\\n @\\n @@\\n\"\n\n","import { dosrebelFont } from \"./fonts/dosrebel-data\"\n\nexport { dosrebelFont }\n\nexport const asciiFonts = {\n dosrebel: dosrebelFont,\n} as const\n\nexport type AsciiFontName = keyof typeof asciiFonts\n\nexport function getAsciiFont(name: AsciiFontName): string {\n return asciiFonts[name]\n}\n","import { mkdirSync, readFileSync, writeFileSync } from \"node:fs\"\nimport path from \"node:path\"\nimport {\n ASCII_CHAR_HEIGHT,\n ASCII_CHAR_WIDTH,\n asciiFonts,\n composeAsciiText,\n getAsciiAccentColumns,\n getAsciiCellIntensity,\n parseFigletFont,\n type AsciiFontName,\n type AsciiTextLayout,\n} from \"./ascii/index\"\n\ninterface RGB {\n r: number\n g: number\n b: number\n}\n\nexport interface GenerateAsciiGifOptions {\n text: string\n accent?: string\n font?: AsciiFontName | string\n outputPath: string\n color?: string\n accentColor?: string\n rowColors?: string[]\n backgroundColor?: string\n blendColor?: string\n fps?: number\n duration?: number\n scale?: number\n levels?: number\n padding?: number\n transparent?: boolean\n}\n\nexport async function generateAsciiGif(options: GenerateAsciiGifOptions): Promise<void> {\n const fps = options.fps ?? 24\n const duration = options.duration ?? 2.4\n const scale = options.scale ?? 2\n const levels = Math.max(2, Math.min(48, options.levels ?? 32))\n const padding = Math.max(0, Math.round(options.padding ?? 16))\n const fontRaw = resolveFont(options.font ?? \"dosrebel\")\n const font = parseFigletFont(fontRaw)\n const layout = composeAsciiText(font, options.text)\n const bounds = getLayoutBounds(layout)\n const accentColumns = getAsciiAccentColumns(font, options.text, options.accent ?? \"\")\n const width = Math.ceil(bounds.cols * ASCII_CHAR_WIDTH * scale) + padding * 2\n const height = bounds.rows * ASCII_CHAR_HEIGHT * scale + padding * 2\n const frameCount = Math.max(1, Math.round(fps * duration))\n const delay = Math.max(1, Math.round(100 / fps))\n const frames: Uint8Array[] = []\n\n // Row-colors path — one palette set per unique row color, applied by cell.row\n if (options.rowColors && options.rowColors.length > 0) {\n const uniqueRowColors = [...new Set(options.rowColors)]\n const rowPalette = createRowColorPalette({\n backgroundColor: options.backgroundColor ?? \"#0a0a0a\",\n blendColor: options.blendColor ?? options.backgroundColor ?? \"#0a0a0a\",\n rowColors: uniqueRowColors,\n levels,\n transparent: options.transparent ?? false,\n })\n for (let frame = 0; frame < frameCount; frame++) {\n frames.push(\n renderIndexedAsciiFrameWithRowColors({\n layout,\n phase: frame / frameCount,\n width,\n height,\n scale,\n levels,\n bounds,\n padding,\n rowColorsInput: options.rowColors,\n uniqueRowColors,\n }),\n )\n }\n const bytes = encodeGif({\n width,\n height,\n delay,\n palette: rowPalette.table,\n frames,\n transparent: options.transparent ?? false,\n })\n mkdirSync(path.dirname(options.outputPath), { recursive: true })\n writeFileSync(options.outputPath, bytes)\n return\n }\n\n const palette = createPalette({\n backgroundColor: options.backgroundColor ?? \"#0a0a0a\",\n blendColor: options.blendColor ?? options.backgroundColor ?? \"#0a0a0a\",\n color: options.color ?? \"#e5e5e5\",\n accentColor: options.accentColor ?? options.color ?? \"#38bdf8\",\n levels,\n transparent: options.transparent ?? false,\n })\n\n for (let frame = 0; frame < frameCount; frame++) {\n frames.push(\n renderIndexedAsciiFrame({\n layout,\n accentColumns,\n phase: frame / frameCount,\n width,\n height,\n scale,\n levels,\n bounds,\n padding,\n }),\n )\n }\n\n const bytes = encodeGif({\n width,\n height,\n delay,\n palette: palette.table,\n frames,\n transparent: options.transparent ?? false,\n })\n\n mkdirSync(path.dirname(options.outputPath), { recursive: true })\n writeFileSync(options.outputPath, bytes)\n}\n\ninterface RenderIndexedFrameOptions {\n layout: AsciiTextLayout\n accentColumns: ReadonlySet<number>\n phase: number\n width: number\n height: number\n scale: number\n levels: number\n bounds: LayoutBounds\n padding: number\n}\n\ninterface LayoutBounds {\n minCol: number\n minRow: number\n cols: number\n rows: number\n}\n\nfunction renderIndexedAsciiFrame(options: RenderIndexedFrameOptions): Uint8Array {\n const pixels = new Uint8Array(options.width * options.height)\n const charWidth = Math.round(ASCII_CHAR_WIDTH * options.scale)\n const charHeight = Math.round(ASCII_CHAR_HEIGHT * options.scale)\n\n for (const cell of options.layout.cells) {\n const intensity = getAsciiCellIntensity(cell, { phase: options.phase })\n const level = Math.max(0, Math.min(options.levels - 1, Math.round(intensity * (options.levels - 1))))\n const offset = options.accentColumns.has(cell.col) ? 1 + options.levels : 1\n const colorIndex = offset + level\n const x0 = options.padding + Math.round((cell.col - options.bounds.minCol) * ASCII_CHAR_WIDTH * options.scale)\n const y0 = options.padding + (cell.row - options.bounds.minRow) * charHeight\n const x1 = Math.min(options.width, x0 + charWidth)\n const y1 = Math.min(options.height, y0 + charHeight)\n\n for (let y = y0; y < y1; y++) {\n const row = y * options.width\n for (let x = x0; x < x1; x++) {\n pixels[row + x] = colorIndex\n }\n }\n }\n\n return pixels\n}\n\ninterface RenderWithRowColorsOptions {\n layout: AsciiTextLayout\n phase: number\n width: number\n height: number\n scale: number\n levels: number\n bounds: LayoutBounds\n padding: number\n rowColorsInput: string[]\n uniqueRowColors: string[]\n}\n\nfunction renderIndexedAsciiFrameWithRowColors(options: RenderWithRowColorsOptions): Uint8Array {\n const pixels = new Uint8Array(options.width * options.height)\n const charWidth = Math.round(ASCII_CHAR_WIDTH * options.scale)\n const charHeight = Math.round(ASCII_CHAR_HEIGHT * options.scale)\n\n for (const cell of options.layout.cells) {\n const intensity = getAsciiCellIntensity(cell, { phase: options.phase })\n const level = Math.max(0, Math.min(options.levels - 1, Math.round(intensity * (options.levels - 1))))\n const rowColor = options.rowColorsInput[cell.row % options.rowColorsInput.length] ?? options.rowColorsInput[0]!\n const colorSetIndex = Math.max(0, options.uniqueRowColors.indexOf(rowColor))\n const colorIndex = 1 + colorSetIndex * options.levels + level\n const x0 = options.padding + Math.round((cell.col - options.bounds.minCol) * ASCII_CHAR_WIDTH * options.scale)\n const y0 = options.padding + (cell.row - options.bounds.minRow) * charHeight\n const x1 = Math.min(options.width, x0 + charWidth)\n const y1 = Math.min(options.height, y0 + charHeight)\n for (let y = y0; y < y1; y++) {\n const row = y * options.width\n for (let x = x0; x < x1; x++) {\n pixels[row + x] = colorIndex\n }\n }\n }\n\n return pixels\n}\n\nfunction createRowColorPalette(options: {\n backgroundColor: string\n blendColor: string\n rowColors: string[]\n levels: number\n transparent: boolean\n}) {\n const bg = parseColor(options.backgroundColor)\n const blend = parseColor(options.blendColor)\n const table: number[] = [bg.r, bg.g, bg.b]\n\n for (const colorHex of options.rowColors) {\n const color = parseColor(colorHex)\n for (let level = 0; level < options.levels; level++) {\n const alpha = level / (options.levels - 1)\n const mixed = mix(blend, color, alpha)\n table.push(mixed.r, mixed.g, mixed.b)\n }\n }\n\n while (table.length < 256 * 3) table.push(0, 0, 0)\n return { table: Uint8Array.from(table.slice(0, 256 * 3)) }\n}\n\nfunction getLayoutBounds(layout: AsciiTextLayout): LayoutBounds {\n if (layout.cells.length === 0) {\n return { minCol: 0, minRow: 0, cols: Math.max(1, layout.cols), rows: Math.max(1, layout.rows) }\n }\n\n let minCol = Number.POSITIVE_INFINITY\n let maxCol = Number.NEGATIVE_INFINITY\n let minRow = Number.POSITIVE_INFINITY\n let maxRow = Number.NEGATIVE_INFINITY\n\n for (const cell of layout.cells) {\n minCol = Math.min(minCol, cell.col)\n maxCol = Math.max(maxCol, cell.col)\n minRow = Math.min(minRow, cell.row)\n maxRow = Math.max(maxRow, cell.row)\n }\n\n return {\n minCol,\n minRow,\n cols: maxCol - minCol + 1,\n rows: maxRow - minRow + 1,\n }\n}\n\nfunction resolveFont(font: AsciiFontName | string): string {\n if (font in asciiFonts) return asciiFonts[font as AsciiFontName]\n return readFileSync(font, \"utf-8\")\n}\n\nfunction createPalette(options: {\n backgroundColor: string\n blendColor: string\n color: string\n accentColor: string\n levels: number\n transparent: boolean\n}) {\n const bg = parseColor(options.backgroundColor)\n const blend = parseColor(options.blendColor)\n const base = parseColor(options.color)\n const accent = parseColor(options.accentColor)\n const table: number[] = [bg.r, bg.g, bg.b]\n\n for (let level = 0; level < options.levels; level++) {\n const alpha = level / (options.levels - 1)\n const mixed = mix(blend, base, alpha)\n table.push(mixed.r, mixed.g, mixed.b)\n }\n\n for (let level = 0; level < options.levels; level++) {\n const alpha = level / (options.levels - 1)\n const mixed = mix(blend, accent, alpha)\n table.push(mixed.r, mixed.g, mixed.b)\n }\n\n while (table.length < 256 * 3) table.push(0, 0, 0)\n return { table: Uint8Array.from(table.slice(0, 256 * 3)) }\n}\n\nfunction parseColor(input: string): RGB {\n const color = input.trim()\n const shortHex = /^#([0-9a-f]{3})$/i.exec(color)\n if (shortHex) {\n const [r, g, b] = shortHex[1].split(\"\").map((part) => Number.parseInt(part + part, 16))\n return { r, g, b }\n }\n\n const longHex = /^#([0-9a-f]{6})$/i.exec(color)\n if (longHex) {\n const value = longHex[1]\n return {\n r: Number.parseInt(value.slice(0, 2), 16),\n g: Number.parseInt(value.slice(2, 4), 16),\n b: Number.parseInt(value.slice(4, 6), 16),\n }\n }\n\n const rgb = /^rgb\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i.exec(color)\n if (rgb) {\n return {\n r: clampByte(Number.parseInt(rgb[1], 10)),\n g: clampByte(Number.parseInt(rgb[2], 10)),\n b: clampByte(Number.parseInt(rgb[3], 10)),\n }\n }\n\n throw new Error(`Unsupported color \"${input}\". Use #rgb, #rrggbb, or rgb(r,g,b).`)\n}\n\nfunction mix(a: RGB, b: RGB, amount: number): RGB {\n return {\n r: clampByte(a.r + (b.r - a.r) * amount),\n g: clampByte(a.g + (b.g - a.g) * amount),\n b: clampByte(a.b + (b.b - a.b) * amount),\n }\n}\n\nfunction clampByte(value: number): number {\n return Math.max(0, Math.min(255, Math.round(value)))\n}\n\ninterface EncodeGifOptions {\n width: number\n height: number\n delay: number\n palette: Uint8Array\n frames: Uint8Array[]\n transparent: boolean\n}\n\nfunction encodeGif(options: EncodeGifOptions): Uint8Array {\n const bytes: number[] = []\n writeAscii(bytes, \"GIF89a\")\n writeU16(bytes, options.width)\n writeU16(bytes, options.height)\n bytes.push(0xf7, 0, 0)\n pushBytes(bytes, options.palette)\n bytes.push(0x21, 0xff, 0x0b)\n writeAscii(bytes, \"NETSCAPE2.0\")\n bytes.push(0x03, 0x01)\n writeU16(bytes, 0)\n bytes.push(0)\n\n for (const frame of options.frames) {\n bytes.push(0x21, 0xf9, 0x04, options.transparent ? 0x05 : 0x04)\n writeU16(bytes, options.delay)\n bytes.push(0, 0)\n bytes.push(0x2c)\n writeU16(bytes, 0)\n writeU16(bytes, 0)\n writeU16(bytes, options.width)\n writeU16(bytes, options.height)\n bytes.push(0)\n bytes.push(8)\n writeSubBlocks(bytes, lzwEncode(frame, 8))\n }\n\n bytes.push(0x3b)\n return Uint8Array.from(bytes)\n}\n\nfunction lzwEncode(indices: Uint8Array, minCodeSize: number): Uint8Array {\n const clearCode = 1 << minCodeSize\n const endCode = clearCode + 1\n let codeSize = minCodeSize + 1\n const output: number[] = []\n const writeCode = createBitWriter(output)\n\n writeCode(clearCode, codeSize)\n\n let codesSinceClear = 0\n for (const index of indices) {\n if (codesSinceClear >= 240) {\n writeCode(clearCode, codeSize)\n codeSize = minCodeSize + 1\n codesSinceClear = 0\n }\n writeCode(index, codeSize)\n codesSinceClear++\n }\n\n writeCode(endCode, codeSize)\n writeCode(-1, 0)\n\n return Uint8Array.from(output)\n}\n\nfunction createBitWriter(output: number[]) {\n let buffer = 0\n let bitCount = 0\n\n return (code: number, size: number) => {\n if (code < 0) {\n if (bitCount > 0) output.push(buffer & 0xff)\n buffer = 0\n bitCount = 0\n return\n }\n\n buffer |= code << bitCount\n bitCount += size\n\n while (bitCount >= 8) {\n output.push(buffer & 0xff)\n buffer >>= 8\n bitCount -= 8\n }\n }\n}\n\nfunction writeSubBlocks(bytes: number[], data: Uint8Array) {\n for (let offset = 0; offset < data.length; offset += 255) {\n const chunk = data.slice(offset, offset + 255)\n bytes.push(chunk.length)\n pushBytes(bytes, chunk)\n }\n bytes.push(0)\n}\n\nfunction writeAscii(bytes: number[], value: string) {\n for (let i = 0; i < value.length; i++) bytes.push(value.charCodeAt(i))\n}\n\nfunction writeU16(bytes: number[], value: number) {\n bytes.push(value & 0xff, (value >> 8) & 0xff)\n}\n\nfunction pushBytes(bytes: number[], values: Uint8Array) {\n for (const value of values) bytes.push(value)\n}\n"]}
package/dist/cli.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { mkdirSync, writeFileSync, readFileSync } from 'fs';
3
3
  import path, { join } from 'path';
4
+ import { createRequire } from 'module';
4
5
  import { createInterface } from 'readline/promises';
5
6
  import { stdout, stdin } from 'process';
6
7
 
@@ -1367,6 +1368,48 @@ async function generateAsciiGif(options) {
1367
1368
  const layout = composeAsciiText(font, options.text);
1368
1369
  const bounds = getLayoutBounds(layout);
1369
1370
  const accentColumns = getAsciiAccentColumns(font, options.text, options.accent ?? "");
1371
+ const width = Math.ceil(bounds.cols * ASCII_CHAR_WIDTH * scale) + padding * 2;
1372
+ const height = bounds.rows * ASCII_CHAR_HEIGHT * scale + padding * 2;
1373
+ const frameCount = Math.max(1, Math.round(fps * duration));
1374
+ const delay = Math.max(1, Math.round(100 / fps));
1375
+ const frames = [];
1376
+ if (options.rowColors && options.rowColors.length > 0) {
1377
+ const uniqueRowColors = [...new Set(options.rowColors)];
1378
+ const rowPalette = createRowColorPalette({
1379
+ backgroundColor: options.backgroundColor ?? "#0a0a0a",
1380
+ blendColor: options.blendColor ?? options.backgroundColor ?? "#0a0a0a",
1381
+ rowColors: uniqueRowColors,
1382
+ levels,
1383
+ transparent: options.transparent ?? false
1384
+ });
1385
+ for (let frame = 0; frame < frameCount; frame++) {
1386
+ frames.push(
1387
+ renderIndexedAsciiFrameWithRowColors({
1388
+ layout,
1389
+ phase: frame / frameCount,
1390
+ width,
1391
+ height,
1392
+ scale,
1393
+ levels,
1394
+ bounds,
1395
+ padding,
1396
+ rowColorsInput: options.rowColors,
1397
+ uniqueRowColors
1398
+ })
1399
+ );
1400
+ }
1401
+ const bytes2 = encodeGif({
1402
+ width,
1403
+ height,
1404
+ delay,
1405
+ palette: rowPalette.table,
1406
+ frames,
1407
+ transparent: options.transparent ?? false
1408
+ });
1409
+ mkdirSync(path.dirname(options.outputPath), { recursive: true });
1410
+ writeFileSync(options.outputPath, bytes2);
1411
+ return;
1412
+ }
1370
1413
  const palette = createPalette({
1371
1414
  backgroundColor: options.backgroundColor ?? "#0a0a0a",
1372
1415
  blendColor: options.blendColor ?? options.backgroundColor ?? "#0a0a0a",
@@ -1375,11 +1418,6 @@ async function generateAsciiGif(options) {
1375
1418
  levels,
1376
1419
  transparent: options.transparent ?? false
1377
1420
  });
1378
- const width = Math.ceil(bounds.cols * ASCII_CHAR_WIDTH * scale) + padding * 2;
1379
- const height = bounds.rows * ASCII_CHAR_HEIGHT * scale + padding * 2;
1380
- const frameCount = Math.max(1, Math.round(fps * duration));
1381
- const delay = Math.max(1, Math.round(100 / fps));
1382
- const frames = [];
1383
1421
  for (let frame = 0; frame < frameCount; frame++) {
1384
1422
  frames.push(
1385
1423
  renderIndexedAsciiFrame({
@@ -1428,6 +1466,44 @@ function renderIndexedAsciiFrame(options) {
1428
1466
  }
1429
1467
  return pixels;
1430
1468
  }
1469
+ function renderIndexedAsciiFrameWithRowColors(options) {
1470
+ const pixels = new Uint8Array(options.width * options.height);
1471
+ const charWidth = Math.round(ASCII_CHAR_WIDTH * options.scale);
1472
+ const charHeight = Math.round(ASCII_CHAR_HEIGHT * options.scale);
1473
+ for (const cell of options.layout.cells) {
1474
+ const intensity = getAsciiCellIntensity(cell, { phase: options.phase });
1475
+ const level = Math.max(0, Math.min(options.levels - 1, Math.round(intensity * (options.levels - 1))));
1476
+ const rowColor = options.rowColorsInput[cell.row % options.rowColorsInput.length] ?? options.rowColorsInput[0];
1477
+ const colorSetIndex = Math.max(0, options.uniqueRowColors.indexOf(rowColor));
1478
+ const colorIndex = 1 + colorSetIndex * options.levels + level;
1479
+ const x0 = options.padding + Math.round((cell.col - options.bounds.minCol) * ASCII_CHAR_WIDTH * options.scale);
1480
+ const y0 = options.padding + (cell.row - options.bounds.minRow) * charHeight;
1481
+ const x1 = Math.min(options.width, x0 + charWidth);
1482
+ const y1 = Math.min(options.height, y0 + charHeight);
1483
+ for (let y = y0; y < y1; y++) {
1484
+ const row = y * options.width;
1485
+ for (let x = x0; x < x1; x++) {
1486
+ pixels[row + x] = colorIndex;
1487
+ }
1488
+ }
1489
+ }
1490
+ return pixels;
1491
+ }
1492
+ function createRowColorPalette(options) {
1493
+ const bg = parseColor(options.backgroundColor);
1494
+ const blend = parseColor(options.blendColor);
1495
+ const table = [bg.r, bg.g, bg.b];
1496
+ for (const colorHex of options.rowColors) {
1497
+ const color = parseColor(colorHex);
1498
+ for (let level = 0; level < options.levels; level++) {
1499
+ const alpha = level / (options.levels - 1);
1500
+ const mixed = mix(blend, color, alpha);
1501
+ table.push(mixed.r, mixed.g, mixed.b);
1502
+ }
1503
+ }
1504
+ while (table.length < 256 * 3) table.push(0, 0, 0);
1505
+ return { table: Uint8Array.from(table.slice(0, 256 * 3)) };
1506
+ }
1431
1507
  function getLayoutBounds(layout) {
1432
1508
  if (layout.cells.length === 0) {
1433
1509
  return { minCol: 0, minRow: 0, cols: Math.max(1, layout.cols), rows: Math.max(1, layout.rows) };
@@ -1598,15 +1674,146 @@ var init_ascii_gif = __esm({
1598
1674
  init_ascii();
1599
1675
  }
1600
1676
  });
1677
+
1678
+ // src/generate-assets.ts
1679
+ var generate_assets_exports = {};
1680
+ __export(generate_assets_exports, {
1681
+ generateAssets: () => generateAssets
1682
+ });
1683
+ function toKebabCase(name) {
1684
+ return name.replace(/([A-Z])/g, (_, ch) => `-${ch.toLowerCase()}`).replace(/^-/, "").toLowerCase();
1685
+ }
1686
+ function escapeXml(str) {
1687
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
1688
+ }
1689
+ function getLucideIconInner(iconName) {
1690
+ const kebab = toKebabCase(iconName);
1691
+ const req = createRequire(import.meta.url);
1692
+ let iconPath;
1693
+ try {
1694
+ iconPath = req.resolve(`lucide-static/icons/${kebab}.svg`);
1695
+ } catch {
1696
+ throw new Error(
1697
+ `Unknown Lucide icon: "${iconName}" (tried "${kebab}.svg"). Browse icons at https://lucide.dev/icons`
1698
+ );
1699
+ }
1700
+ const svg = readFileSync(iconPath, "utf-8");
1701
+ return svg.replace(/<svg[^>]*>/, "").replace(/<\/svg>/, "").replace(/\sstroke="currentColor"/g, "").replace(/\sfill="none"/g, "").trim();
1702
+ }
1703
+ function buildIconSvg(inner, color, size) {
1704
+ const pad = Math.round(size * 0.18);
1705
+ const area = size - pad * 2;
1706
+ const scale = area / 24;
1707
+ const rx = Math.round(size * 0.16);
1708
+ const sw = (2 / scale).toFixed(4);
1709
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}">
1710
+ <rect width="${size}" height="${size}" rx="${rx}" fill="${color}"/>
1711
+ <g transform="translate(${pad} ${pad}) scale(${scale})" stroke="white" fill="none" stroke-width="${sw}" stroke-linecap="round" stroke-linejoin="round">
1712
+ ${inner}
1713
+ </g>
1714
+ </svg>`;
1715
+ }
1716
+ function buildOgSvg(inner, name, color) {
1717
+ const iconPx = 180;
1718
+ const iconX = Math.round((1200 - iconPx) / 2);
1719
+ const iconY = 160;
1720
+ const scale = iconPx / 24;
1721
+ const sw = (2.5 / scale).toFixed(4);
1722
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="630">
1723
+ <defs>
1724
+ <radialGradient id="rg" cx="50%" cy="40%" r="65%">
1725
+ <stop offset="0%" stop-color="${color}" stop-opacity="0.22"/>
1726
+ <stop offset="100%" stop-color="#000000" stop-opacity="0"/>
1727
+ </radialGradient>
1728
+ </defs>
1729
+ <rect width="1200" height="630" fill="#09090b"/>
1730
+ <rect width="1200" height="630" fill="url(#rg)"/>
1731
+ <g transform="translate(${iconX} ${iconY}) scale(${scale})" stroke="${color}" fill="none" stroke-width="${sw}" stroke-linecap="round" stroke-linejoin="round">
1732
+ ${inner}
1733
+ </g>
1734
+ <text x="600" y="470" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif" font-size="72" font-weight="700" fill="white" text-anchor="middle" letter-spacing="-1">${escapeXml(name)}</text>
1735
+ </svg>`;
1736
+ }
1737
+ async function generateAssets(config) {
1738
+ const { name, icon, color, outputDir } = config;
1739
+ let sharpFn;
1740
+ try {
1741
+ sharpFn = (await import('sharp')).default;
1742
+ } catch {
1743
+ throw new Error(
1744
+ "sharp is required for asset generation.\nInstall it in your project: bun add sharp lucide-static"
1745
+ );
1746
+ }
1747
+ mkdirSync(outputDir, { recursive: true });
1748
+ const faviconDir = join(outputDir, "favicon");
1749
+ mkdirSync(faviconDir, { recursive: true });
1750
+ const inner = getLucideIconInner(icon);
1751
+ const written = [];
1752
+ for (const size of FAVICON_SIZES) {
1753
+ const svg = buildIconSvg(inner, color, size);
1754
+ const png = await sharpFn(Buffer.from(svg)).png().toBuffer();
1755
+ const dest = join(faviconDir, `favicon-${size}.png`);
1756
+ writeFileSync(dest, png);
1757
+ written.push(dest);
1758
+ }
1759
+ for (const [filename, size] of NAMED_ICONS) {
1760
+ const svg = buildIconSvg(inner, color, size);
1761
+ const png = await sharpFn(Buffer.from(svg)).png().toBuffer();
1762
+ const dest = join(outputDir, filename);
1763
+ writeFileSync(dest, png);
1764
+ written.push(dest);
1765
+ }
1766
+ const ogSvg = buildOgSvg(inner, name, color);
1767
+ const ogPng = await sharpFn(Buffer.from(ogSvg)).png().toBuffer();
1768
+ const ogDest = join(outputDir, "og-image.png");
1769
+ writeFileSync(ogDest, ogPng);
1770
+ written.push(ogDest);
1771
+ const manifest = {
1772
+ name,
1773
+ short_name: name,
1774
+ theme_color: color,
1775
+ background_color: "#09090b",
1776
+ display: "standalone",
1777
+ icons: [
1778
+ { src: "/android-chrome-192x192.png", sizes: "192x192", type: "image/png" },
1779
+ {
1780
+ src: "/android-chrome-512x512.png",
1781
+ sizes: "512x512",
1782
+ type: "image/png",
1783
+ purpose: "maskable"
1784
+ }
1785
+ ]
1786
+ };
1787
+ const manifestDest = join(outputDir, "manifest.json");
1788
+ writeFileSync(manifestDest, JSON.stringify(manifest, null, 2) + "\n");
1789
+ written.push(manifestDest);
1790
+ const robotsDest = join(outputDir, "robots.txt");
1791
+ writeFileSync(robotsDest, "User-agent: *\nAllow: /\n");
1792
+ written.push(robotsDest);
1793
+ return { files: written };
1794
+ }
1795
+ var FAVICON_SIZES, NAMED_ICONS;
1796
+ var init_generate_assets = __esm({
1797
+ "src/generate-assets.ts"() {
1798
+ FAVICON_SIZES = [16, 32, 48, 64];
1799
+ NAMED_ICONS = [
1800
+ ["apple-touch-icon.png", 180],
1801
+ ["android-chrome-192x192.png", 192],
1802
+ ["android-chrome-512x512.png", 512]
1803
+ ];
1804
+ }
1805
+ });
1601
1806
  var DEFAULT_SOURCE = "https://olwiba.com/skills/manifest.json";
1602
1807
  var [command, subcommand] = process.argv.slice(2);
1603
1808
  if (command === "skills" && subcommand === "install") {
1604
1809
  await runSkillsInstall();
1605
1810
  } else if (command === "ascii-gif") {
1606
1811
  await runAsciiGif();
1812
+ } else if (command === "generate-assets") {
1813
+ await runGenerateAssets();
1607
1814
  } else {
1608
1815
  process.stdout.write(
1609
- "Usage:\n dx skills install [--source <url>] [--target claude|amp] [--all] [--name a,b,c]\n dx ascii-gif --text <text> --out <file.gif>\n"
1816
+ "Usage:\n dx skills install [--source <url>] [--target claude|amp] [--all] [--name a,b,c]\n dx ascii-gif --text <text> --out <file.gif>\n dx generate-assets --name <app> --icon <lucide-icon> --color <#hex> [--out <dir>]\n"
1610
1817
  );
1611
1818
  }
1612
1819
  async function runSkillsInstall() {
@@ -1763,6 +1970,35 @@ function parseFlags(args) {
1763
1970
  }
1764
1971
  return flags;
1765
1972
  }
1973
+ async function runGenerateAssets() {
1974
+ const { generateAssets: generateAssets2 } = await Promise.resolve().then(() => (init_generate_assets(), generate_assets_exports));
1975
+ const flags = parseFlags(process.argv.slice(3));
1976
+ const name = flags.name;
1977
+ const icon = flags.icon;
1978
+ const color = flags.color;
1979
+ const outputDir = flags.out ?? flags.output ?? "public";
1980
+ if (!name || !icon || !color) {
1981
+ process.stderr.write(
1982
+ "Usage: dx generate-assets --name <app> --icon <lucide-icon> --color <#hex> [--out <dir>]\n"
1983
+ );
1984
+ process.exitCode = 1;
1985
+ return;
1986
+ }
1987
+ process.stdout.write(`Generating assets for "${name}"\u2026
1988
+ `);
1989
+ try {
1990
+ const result = await generateAssets2({ name, icon, color, outputDir });
1991
+ process.stdout.write(`Generated ${result.files.length} files in ${outputDir}/
1992
+ `);
1993
+ for (const f of result.files) process.stdout.write(` ${f}
1994
+ `);
1995
+ } catch (err) {
1996
+ const message = err instanceof Error ? err.message : String(err);
1997
+ process.stderr.write(`Error: ${message}
1998
+ `);
1999
+ process.exitCode = 1;
2000
+ }
2001
+ }
1766
2002
  function parseNumberFlag(value) {
1767
2003
  if (value == null) return void 0;
1768
2004
  const parsed = Number(value);
@@ -0,0 +1,12 @@
1
+ interface GenerateAssetsConfig {
2
+ name: string;
3
+ icon: string;
4
+ color: string;
5
+ outputDir: string;
6
+ }
7
+ interface GenerateAssetsResult {
8
+ files: string[];
9
+ }
10
+ declare function generateAssets(config: GenerateAssetsConfig): Promise<GenerateAssetsResult>;
11
+
12
+ export { type GenerateAssetsConfig, type GenerateAssetsResult, generateAssets };
@@ -0,0 +1,127 @@
1
+ import { mkdirSync, writeFileSync, readFileSync } from 'fs';
2
+ import { createRequire } from 'module';
3
+ import { join } from 'path';
4
+
5
+ // src/generate-assets.ts
6
+ function toKebabCase(name) {
7
+ return name.replace(/([A-Z])/g, (_, ch) => `-${ch.toLowerCase()}`).replace(/^-/, "").toLowerCase();
8
+ }
9
+ function escapeXml(str) {
10
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
11
+ }
12
+ function getLucideIconInner(iconName) {
13
+ const kebab = toKebabCase(iconName);
14
+ const req = createRequire(import.meta.url);
15
+ let iconPath;
16
+ try {
17
+ iconPath = req.resolve(`lucide-static/icons/${kebab}.svg`);
18
+ } catch {
19
+ throw new Error(
20
+ `Unknown Lucide icon: "${iconName}" (tried "${kebab}.svg"). Browse icons at https://lucide.dev/icons`
21
+ );
22
+ }
23
+ const svg = readFileSync(iconPath, "utf-8");
24
+ return svg.replace(/<svg[^>]*>/, "").replace(/<\/svg>/, "").replace(/\sstroke="currentColor"/g, "").replace(/\sfill="none"/g, "").trim();
25
+ }
26
+ function buildIconSvg(inner, color, size) {
27
+ const pad = Math.round(size * 0.18);
28
+ const area = size - pad * 2;
29
+ const scale = area / 24;
30
+ const rx = Math.round(size * 0.16);
31
+ const sw = (2 / scale).toFixed(4);
32
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}">
33
+ <rect width="${size}" height="${size}" rx="${rx}" fill="${color}"/>
34
+ <g transform="translate(${pad} ${pad}) scale(${scale})" stroke="white" fill="none" stroke-width="${sw}" stroke-linecap="round" stroke-linejoin="round">
35
+ ${inner}
36
+ </g>
37
+ </svg>`;
38
+ }
39
+ function buildOgSvg(inner, name, color) {
40
+ const iconPx = 180;
41
+ const iconX = Math.round((1200 - iconPx) / 2);
42
+ const iconY = 160;
43
+ const scale = iconPx / 24;
44
+ const sw = (2.5 / scale).toFixed(4);
45
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="630">
46
+ <defs>
47
+ <radialGradient id="rg" cx="50%" cy="40%" r="65%">
48
+ <stop offset="0%" stop-color="${color}" stop-opacity="0.22"/>
49
+ <stop offset="100%" stop-color="#000000" stop-opacity="0"/>
50
+ </radialGradient>
51
+ </defs>
52
+ <rect width="1200" height="630" fill="#09090b"/>
53
+ <rect width="1200" height="630" fill="url(#rg)"/>
54
+ <g transform="translate(${iconX} ${iconY}) scale(${scale})" stroke="${color}" fill="none" stroke-width="${sw}" stroke-linecap="round" stroke-linejoin="round">
55
+ ${inner}
56
+ </g>
57
+ <text x="600" y="470" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif" font-size="72" font-weight="700" fill="white" text-anchor="middle" letter-spacing="-1">${escapeXml(name)}</text>
58
+ </svg>`;
59
+ }
60
+ var FAVICON_SIZES = [16, 32, 48, 64];
61
+ var NAMED_ICONS = [
62
+ ["apple-touch-icon.png", 180],
63
+ ["android-chrome-192x192.png", 192],
64
+ ["android-chrome-512x512.png", 512]
65
+ ];
66
+ async function generateAssets(config) {
67
+ const { name, icon, color, outputDir } = config;
68
+ let sharpFn;
69
+ try {
70
+ sharpFn = (await import('sharp')).default;
71
+ } catch {
72
+ throw new Error(
73
+ "sharp is required for asset generation.\nInstall it in your project: bun add sharp lucide-static"
74
+ );
75
+ }
76
+ mkdirSync(outputDir, { recursive: true });
77
+ const faviconDir = join(outputDir, "favicon");
78
+ mkdirSync(faviconDir, { recursive: true });
79
+ const inner = getLucideIconInner(icon);
80
+ const written = [];
81
+ for (const size of FAVICON_SIZES) {
82
+ const svg = buildIconSvg(inner, color, size);
83
+ const png = await sharpFn(Buffer.from(svg)).png().toBuffer();
84
+ const dest = join(faviconDir, `favicon-${size}.png`);
85
+ writeFileSync(dest, png);
86
+ written.push(dest);
87
+ }
88
+ for (const [filename, size] of NAMED_ICONS) {
89
+ const svg = buildIconSvg(inner, color, size);
90
+ const png = await sharpFn(Buffer.from(svg)).png().toBuffer();
91
+ const dest = join(outputDir, filename);
92
+ writeFileSync(dest, png);
93
+ written.push(dest);
94
+ }
95
+ const ogSvg = buildOgSvg(inner, name, color);
96
+ const ogPng = await sharpFn(Buffer.from(ogSvg)).png().toBuffer();
97
+ const ogDest = join(outputDir, "og-image.png");
98
+ writeFileSync(ogDest, ogPng);
99
+ written.push(ogDest);
100
+ const manifest = {
101
+ name,
102
+ short_name: name,
103
+ theme_color: color,
104
+ background_color: "#09090b",
105
+ display: "standalone",
106
+ icons: [
107
+ { src: "/android-chrome-192x192.png", sizes: "192x192", type: "image/png" },
108
+ {
109
+ src: "/android-chrome-512x512.png",
110
+ sizes: "512x512",
111
+ type: "image/png",
112
+ purpose: "maskable"
113
+ }
114
+ ]
115
+ };
116
+ const manifestDest = join(outputDir, "manifest.json");
117
+ writeFileSync(manifestDest, JSON.stringify(manifest, null, 2) + "\n");
118
+ written.push(manifestDest);
119
+ const robotsDest = join(outputDir, "robots.txt");
120
+ writeFileSync(robotsDest, "User-agent: *\nAllow: /\n");
121
+ written.push(robotsDest);
122
+ return { files: written };
123
+ }
124
+
125
+ export { generateAssets };
126
+ //# sourceMappingURL=generate-assets.js.map
127
+ //# sourceMappingURL=generate-assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/generate-assets.ts"],"names":[],"mappings":"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","file":"generate-assets.js","sourcesContent":["import { mkdirSync, readFileSync, writeFileSync } from \"node:fs\"\nimport { createRequire } from \"node:module\"\nimport { join } from \"node:path\"\n\nexport interface GenerateAssetsConfig {\n name: string\n icon: string\n color: string\n outputDir: string\n}\n\nexport interface GenerateAssetsResult {\n files: string[]\n}\n\nfunction toKebabCase(name: string): string {\n return name\n .replace(/([A-Z])/g, (_, ch: string) => `-${ch.toLowerCase()}`)\n .replace(/^-/, \"\")\n .toLowerCase()\n}\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\")\n}\n\nfunction getLucideIconInner(iconName: string): string {\n const kebab = toKebabCase(iconName)\n const req = createRequire(import.meta.url)\n let iconPath: string\n try {\n iconPath = req.resolve(`lucide-static/icons/${kebab}.svg`)\n } catch {\n throw new Error(\n `Unknown Lucide icon: \"${iconName}\" (tried \"${kebab}.svg\"). ` +\n `Browse icons at https://lucide.dev/icons`,\n )\n }\n const svg = readFileSync(iconPath, \"utf-8\")\n // Strip outer <svg> wrapper; clear inherited stroke/fill so parent <g> controls them\n return svg\n .replace(/<svg[^>]*>/, \"\")\n .replace(/<\\/svg>/, \"\")\n .replace(/\\sstroke=\"currentColor\"/g, \"\")\n .replace(/\\sfill=\"none\"/g, \"\")\n .trim()\n}\n\nfunction buildIconSvg(inner: string, color: string, size: number): string {\n const pad = Math.round(size * 0.18)\n const area = size - pad * 2\n const scale = area / 24\n const rx = Math.round(size * 0.16)\n // Inverse-scale stroke so it renders at ~2px regardless of size\n const sw = (2 / scale).toFixed(4)\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${size}\" height=\"${size}\">\n <rect width=\"${size}\" height=\"${size}\" rx=\"${rx}\" fill=\"${color}\"/>\n <g transform=\"translate(${pad} ${pad}) scale(${scale})\" stroke=\"white\" fill=\"none\" stroke-width=\"${sw}\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n ${inner}\n </g>\n</svg>`\n}\n\nfunction buildOgSvg(inner: string, name: string, color: string): string {\n const iconPx = 180\n const iconX = Math.round((1200 - iconPx) / 2) // 510\n const iconY = 160\n const scale = iconPx / 24\n // ~2.5px strokes at final 180px icon size\n const sw = (2.5 / scale).toFixed(4)\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1200\" height=\"630\">\n <defs>\n <radialGradient id=\"rg\" cx=\"50%\" cy=\"40%\" r=\"65%\">\n <stop offset=\"0%\" stop-color=\"${color}\" stop-opacity=\"0.22\"/>\n <stop offset=\"100%\" stop-color=\"#000000\" stop-opacity=\"0\"/>\n </radialGradient>\n </defs>\n <rect width=\"1200\" height=\"630\" fill=\"#09090b\"/>\n <rect width=\"1200\" height=\"630\" fill=\"url(#rg)\"/>\n <g transform=\"translate(${iconX} ${iconY}) scale(${scale})\" stroke=\"${color}\" fill=\"none\" stroke-width=\"${sw}\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n ${inner}\n </g>\n <text x=\"600\" y=\"470\" font-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif\" font-size=\"72\" font-weight=\"700\" fill=\"white\" text-anchor=\"middle\" letter-spacing=\"-1\">${escapeXml(name)}</text>\n</svg>`\n}\n\nconst FAVICON_SIZES = [16, 32, 48, 64] as const\n\nconst NAMED_ICONS: Array<[string, number]> = [\n [\"apple-touch-icon.png\", 180],\n [\"android-chrome-192x192.png\", 192],\n [\"android-chrome-512x512.png\", 512],\n]\n\nexport async function generateAssets(\n config: GenerateAssetsConfig,\n): Promise<GenerateAssetsResult> {\n const { name, icon, color, outputDir } = config\n\n let sharpFn: typeof import(\"sharp\")\n try {\n sharpFn = (await import(\"sharp\")).default\n } catch {\n throw new Error(\n \"sharp is required for asset generation.\\n\" +\n \"Install it in your project: bun add sharp lucide-static\",\n )\n }\n\n mkdirSync(outputDir, { recursive: true })\n\n const faviconDir = join(outputDir, \"favicon\")\n mkdirSync(faviconDir, { recursive: true })\n\n const inner = getLucideIconInner(icon)\n const written: string[] = []\n\n // favicon/favicon-{size}.png\n for (const size of FAVICON_SIZES) {\n const svg = buildIconSvg(inner, color, size)\n const png = await sharpFn(Buffer.from(svg)).png().toBuffer()\n const dest = join(faviconDir, `favicon-${size}.png`)\n writeFileSync(dest, png)\n written.push(dest)\n }\n\n // apple-touch-icon, android-chrome-*\n for (const [filename, size] of NAMED_ICONS) {\n const svg = buildIconSvg(inner, color, size)\n const png = await sharpFn(Buffer.from(svg)).png().toBuffer()\n const dest = join(outputDir, filename)\n writeFileSync(dest, png)\n written.push(dest)\n }\n\n // og-image.png\n const ogSvg = buildOgSvg(inner, name, color)\n const ogPng = await sharpFn(Buffer.from(ogSvg)).png().toBuffer()\n const ogDest = join(outputDir, \"og-image.png\")\n writeFileSync(ogDest, ogPng)\n written.push(ogDest)\n\n // manifest.json\n const manifest = {\n name,\n short_name: name,\n theme_color: color,\n background_color: \"#09090b\",\n display: \"standalone\",\n icons: [\n { src: \"/android-chrome-192x192.png\", sizes: \"192x192\", type: \"image/png\" },\n {\n src: \"/android-chrome-512x512.png\",\n sizes: \"512x512\",\n type: \"image/png\",\n purpose: \"maskable\",\n },\n ],\n }\n const manifestDest = join(outputDir, \"manifest.json\")\n writeFileSync(manifestDest, JSON.stringify(manifest, null, 2) + \"\\n\")\n written.push(manifestDest)\n\n // robots.txt\n const robotsDest = join(outputDir, \"robots.txt\")\n writeFileSync(robotsDest, \"User-agent: *\\nAllow: /\\n\")\n written.push(robotsDest)\n\n return { files: written }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olwiba/dx",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -35,6 +35,10 @@
35
35
  "./ascii-gif": {
36
36
  "import": "./dist/ascii-gif.js",
37
37
  "types": "./dist/ascii-gif.d.ts"
38
+ },
39
+ "./generate-assets": {
40
+ "import": "./dist/generate-assets.js",
41
+ "types": "./dist/generate-assets.d.ts"
38
42
  }
39
43
  },
40
44
  "files": [
@@ -49,6 +53,7 @@
49
53
  "@types/node": "^22.5.4",
50
54
  "eslint": "^9.0.0",
51
55
  "puppeteer-core": "^24.0.0",
56
+ "sharp": "^0.33.0",
52
57
  "tsup": "^8.4.0",
53
58
  "typescript": "^5.7.2"
54
59
  },
@@ -57,7 +62,9 @@
57
62
  "puppeteer-core": ">=22.0.0",
58
63
  "@typescript-eslint/eslint-plugin": ">=8.0.0",
59
64
  "@typescript-eslint/parser": ">=8.0.0",
60
- "eslint-plugin-react-hooks": ">=5.0.0"
65
+ "eslint-plugin-react-hooks": ">=5.0.0",
66
+ "sharp": ">=0.32.0",
67
+ "lucide-static": ">=0.400.0"
61
68
  },
62
69
  "peerDependenciesMeta": {
63
70
  "@typescript-eslint/eslint-plugin": {
@@ -71,6 +78,12 @@
71
78
  },
72
79
  "puppeteer-core": {
73
80
  "optional": true
81
+ },
82
+ "sharp": {
83
+ "optional": true
84
+ },
85
+ "lucide-static": {
86
+ "optional": true
74
87
  }
75
88
  },
76
89
  "homepage": "https://github.com/Olwiba/olwibaDX#readme",