ansimax 1.4.0 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -62,7 +62,9 @@ __export(index_exports, {
62
62
  clamp: () => clamp,
63
63
  clampByte: () => clampByte2,
64
64
  clampInt: () => clampInt,
65
+ clampNonNeg: () => clampNonNeg,
65
66
  clampPercent: () => clampPercent,
67
+ clampPositiveInt: () => clampPositiveInt,
66
68
  clearAnsiCache: () => clearAnsiCache,
67
69
  clearColorCache: () => clearColorCache,
68
70
  clearLine: () => clearLine,
@@ -84,6 +86,7 @@ __export(index_exports, {
84
86
  default: () => index_default,
85
87
  diffLines: () => diffLines,
86
88
  easings: () => easings,
89
+ ensureString: () => ensureString2,
87
90
  escapeForRegex: () => escapeForRegex,
88
91
  escapeRegex: () => escapeRegex,
89
92
  fg256: () => fg256,
@@ -624,6 +627,15 @@ var clampInt = (value, min, max, fallback = 0) => {
624
627
  }
625
628
  return Math.max(min, Math.min(max, Math.floor(value)));
626
629
  };
630
+ var ensureString2 = (v) => typeof v === "string" ? v : String(v ?? "");
631
+ var clampNonNeg = (n, fallback = 0) => {
632
+ if (!isFiniteNumber2(n)) return Math.max(0, Math.floor(fallback));
633
+ return Math.max(0, Math.floor(n));
634
+ };
635
+ var clampPositiveInt = (n, fallback = 1) => {
636
+ if (!isFiniteNumber2(n)) return Math.max(1, Math.floor(fallback));
637
+ return Math.max(1, Math.floor(n));
638
+ };
627
639
  var HEX_RE = /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
628
640
  var isHexColor = (hex) => typeof hex === "string" && HEX_RE.test(hex.trim());
629
641
  var hexToRgb = (hex) => {
@@ -2576,7 +2588,7 @@ var clearRenderCache = () => {
2576
2588
  _renderCache.clear();
2577
2589
  };
2578
2590
  var getRenderCacheSize = () => _renderCache.size;
2579
- var ensureString2 = (value, paramName) => {
2591
+ var ensureString3 = (value, paramName) => {
2580
2592
  if (typeof value !== "string") {
2581
2593
  throw new TypeError(
2582
2594
  `ascii: ${paramName} must be a string, got ${typeof value}`
@@ -2715,15 +2727,15 @@ var BOX_STYLES = {
2715
2727
  ascii: { tl: "+", tr: "+", bl: "+", br: "+", h: "-", v: "|" }
2716
2728
  };
2717
2729
  var big = (text) => {
2718
- const safe = ensureString2(text, "big(text)");
2730
+ const safe = ensureString3(text, "big(text)");
2719
2731
  return renderFont(safe, BLOCK, { _fontKey: "big" });
2720
2732
  };
2721
2733
  var small = (text) => {
2722
- const safe = ensureString2(text, "small(text)");
2734
+ const safe = ensureString3(text, "small(text)");
2723
2735
  return renderFont(safe, SMALL, { _fontKey: "small" });
2724
2736
  };
2725
2737
  var figlet = (text, opts = {}) => {
2726
- const safe = ensureString2(text, "figlet(text)");
2738
+ const safe = ensureString3(text, "figlet(text)");
2727
2739
  const fontName = opts.font ?? "big";
2728
2740
  const fontMap = FONTS[fontName] ?? BLOCK;
2729
2741
  return renderFont(safe, fontMap, {
@@ -2733,7 +2745,7 @@ var figlet = (text, opts = {}) => {
2733
2745
  });
2734
2746
  };
2735
2747
  var stageRender = (text, font, letterSpacing) => {
2736
- const safe = ensureString2(text, "stageRender(text)");
2748
+ const safe = ensureString3(text, "stageRender(text)");
2737
2749
  const fontMap = FONTS[font] ?? BLOCK;
2738
2750
  const renderOpts = { _fontKey: typeof font === "string" ? font : "big" };
2739
2751
  if (letterSpacing !== void 0) renderOpts.letterSpacing = letterSpacing;
@@ -2775,7 +2787,7 @@ var stageColorize = (rendered, colorFn, perCharColor) => {
2775
2787
  return rendered.split("\n").map(colorFn).join("\n");
2776
2788
  };
2777
2789
  var banner = (text, opts = {}) => {
2778
- const safe = ensureString2(text, "banner(text)");
2790
+ const safe = ensureString3(text, "banner(text)");
2779
2791
  const {
2780
2792
  font = "big",
2781
2793
  colorFn = null,
@@ -2789,7 +2801,7 @@ var banner = (text, opts = {}) => {
2789
2801
  return result;
2790
2802
  };
2791
2803
  var box = (text, opts = {}) => {
2792
- const safe = ensureString2(text, "box(text)");
2804
+ const safe = ensureString3(text, "box(text)");
2793
2805
  const {
2794
2806
  padding = 1,
2795
2807
  borderStyle = "rounded",
@@ -2870,7 +2882,7 @@ var divider = (opts = {}) => {
2870
2882
  return fill.repeat(w);
2871
2883
  };
2872
2884
  var logo = (text, opts = {}) => {
2873
- const safe = ensureString2(text, "logo(text)");
2885
+ const safe = ensureString3(text, "logo(text)");
2874
2886
  const { gradient: gfn = null, boxStyle = "double", centered = true } = opts;
2875
2887
  if (!safe.length) return box("", { borderStyle: boxStyle, padding: 1 });
2876
2888
  const art = big(safe);
@@ -2884,7 +2896,7 @@ var logo = (text, opts = {}) => {
2884
2896
  return box(lines.join("\n"), { borderStyle: boxStyle, padding: 1 });
2885
2897
  };
2886
2898
  var measure = (text, font = "big", letterSpacing) => {
2887
- const safe = ensureString2(text, "measure(text)");
2899
+ const safe = ensureString3(text, "measure(text)");
2888
2900
  if (!safe.length) return { width: 0, height: 0 };
2889
2901
  const rendered = stageRender(safe, font, letterSpacing);
2890
2902
  const lines = rendered.split("\n");
@@ -2892,7 +2904,7 @@ var measure = (text, font = "big", letterSpacing) => {
2892
2904
  return { width, height: lines.length };
2893
2905
  };
2894
2906
  var stream = async function* (text, opts = {}) {
2895
- const safe = ensureString2(text, "stream(text)");
2907
+ const safe = ensureString3(text, "stream(text)");
2896
2908
  const { font = "big", letterSpacing, granularity = "row", signal } = opts;
2897
2909
  if (!safe.length) return;
2898
2910
  if (signal?.aborted) return;
@@ -3258,11 +3270,6 @@ var ascii = {
3258
3270
 
3259
3271
  // src/loaders/index.ts
3260
3272
  var canAnimate2 = () => Boolean(process.stdout?.isTTY) && supportsColor() !== "none";
3261
- var ensureString3 = (v) => typeof v === "string" ? v : String(v ?? "");
3262
- var clampPositiveInt = (n, fallback) => {
3263
- if (!isFiniteNumber2(n)) return fallback;
3264
- return Math.max(1, Math.floor(n));
3265
- };
3266
3273
  var isUnicodeCapable = () => {
3267
3274
  const env = process.env;
3268
3275
  if (env["CI"]) return true;
@@ -3379,9 +3386,9 @@ var spin = (text = "Loading", opts = {}) => {
3379
3386
  signal,
3380
3387
  reducedMotion = false
3381
3388
  } = opts;
3382
- const safeText = ensureString3(text);
3383
- const safePrefix = ensureString3(prefix);
3384
- const safeSuffix = ensureString3(suffix);
3389
+ const safeText = ensureString2(text);
3390
+ const safePrefix = ensureString2(prefix);
3391
+ const safeSuffix = ensureString2(suffix);
3385
3392
  const safeInterval = clampPositiveInt(interval, 80);
3386
3393
  registerCrashHandlers2();
3387
3394
  const frames2 = resolveSpinnerFrames(type);
@@ -3393,7 +3400,7 @@ var spin = (text = "Loading", opts = {}) => {
3393
3400
  return (finalText, success) => {
3394
3401
  if (finalText !== void 0) {
3395
3402
  const icon = success === false ? "\u2717" : success === true ? "\u2713" : "";
3396
- write(`${safePrefix}${icon ? icon + " " : ""}${ensureString3(finalText)}${safeSuffix}`);
3403
+ write(`${safePrefix}${icon ? icon + " " : ""}${ensureString2(finalText)}${safeSuffix}`);
3397
3404
  if (persist) writeln();
3398
3405
  }
3399
3406
  };
@@ -3434,7 +3441,7 @@ var spin = (text = "Loading", opts = {}) => {
3434
3441
  if (finalText !== void 0) {
3435
3442
  const icon = success === false ? sgr(FG.red) + "\u2717" + reset() : success === true ? sgr(FG.green) + "\u2713" + reset() : "";
3436
3443
  const line = padToTerminalWidth(
3437
- `${safePrefix}${icon ? icon + " " : ""}${ensureString3(finalText)}${safeSuffix}`
3444
+ `${safePrefix}${icon ? icon + " " : ""}${ensureString2(finalText)}${safeSuffix}`
3438
3445
  );
3439
3446
  write(line);
3440
3447
  if (persist) writeln();
@@ -3463,7 +3470,7 @@ var progress = (percent, label = "", opts = {}) => {
3463
3470
  const safeWidth = clampPositiveInt(width, 30);
3464
3471
  const safeChar = typeof char === "string" && char.length > 0 ? char : "\u2588";
3465
3472
  const safeEmpty = typeof emptyChar === "string" && emptyChar.length > 0 ? emptyChar : "\u2591";
3466
- const safeLabel = ensureString3(label);
3473
+ const safeLabel = ensureString2(label);
3467
3474
  const clamped = clampPercent(percent);
3468
3475
  const filled = Math.floor(clamped / 100 * safeWidth);
3469
3476
  const empty = Math.max(0, safeWidth - filled);
@@ -3653,7 +3660,7 @@ var custom = (frames2, text = "", opts = {}) => {
3653
3660
  var countdown = async (seconds, opts = {}) => {
3654
3661
  const { label = "Starting in", color: hex, signal } = opts;
3655
3662
  const safeSeconds = isFiniteNumber2(seconds) ? Math.max(0, Math.floor(seconds)) : 0;
3656
- const safeLabel = ensureString3(label);
3663
+ const safeLabel = ensureString2(label);
3657
3664
  const colorToUse = safeColor(hex) ? hex : "#ffd700";
3658
3665
  if (!canAnimate2() || signal?.aborted) {
3659
3666
  const final = applyColor(String(safeSeconds), colorToUse);
@@ -3860,7 +3867,6 @@ var loader = {
3860
3867
  };
3861
3868
 
3862
3869
  // src/frames/index.ts
3863
- var ensureString4 = (v) => typeof v === "string" ? v : String(v ?? "");
3864
3870
  var MAX_FPS = 60;
3865
3871
  var clampFps = (fps, fallback) => {
3866
3872
  if (!isFiniteNumber2(fps)) return fallback;
@@ -4001,7 +4007,7 @@ var play = (frames2, opts = {}) => {
4001
4007
  } catch {
4002
4008
  rendered = frame2;
4003
4009
  }
4004
- const safe = ensureString4(rendered);
4010
+ const safe = ensureString2(rendered);
4005
4011
  try {
4006
4012
  write(safe);
4007
4013
  } catch {
@@ -4111,7 +4117,7 @@ var generate = (count, fn) => {
4111
4117
  if (typeof fn !== "function") return Array(safeCount).fill("");
4112
4118
  return Array.from({ length: safeCount }, (_, i) => {
4113
4119
  try {
4114
- return ensureString4(fn(i, safeCount));
4120
+ return ensureString2(fn(i, safeCount));
4115
4121
  } catch {
4116
4122
  return "";
4117
4123
  }
@@ -4169,15 +4175,15 @@ var live = (opts = {}) => {
4169
4175
  if (wasRunning) showCursorSafe2();
4170
4176
  };
4171
4177
  const update = (newFrame) => {
4172
- currentFrame = ensureString4(newFrame);
4178
+ currentFrame = ensureString2(newFrame);
4173
4179
  if (running) render2();
4174
4180
  };
4175
4181
  if (autoStart) start();
4176
4182
  return { start, stop, update, isRunning: () => running };
4177
4183
  };
4178
4184
  var morph = (frameA, frameB, steps = 8, charset = "\u2591\u2592\u2593\u2588\u2593\u2592\u2591") => {
4179
- const a0 = ensureString4(frameA);
4180
- const b0 = ensureString4(frameB);
4185
+ const a0 = ensureString2(frameA);
4186
+ const b0 = ensureString2(frameB);
4181
4187
  if (!a0 && !b0) return [""];
4182
4188
  const n = Math.max(2, isFiniteNumber2(steps) ? Math.floor(steps) : 8);
4183
4189
  const len = Math.max(a0.length, b0.length);
@@ -4204,7 +4210,7 @@ var presets2 = {
4204
4210
  const safeWidth = Math.max(0, isFiniteNumber2(width) ? Math.floor(width) : 20);
4205
4211
  const safeChar = typeof char === "string" && char.length > 0 ? char : "\u2588";
4206
4212
  const safeEmpty = typeof empty === "string" && empty.length > 0 ? empty : "\u2591";
4207
- const safeLabel = ensureString4(label);
4213
+ const safeLabel = ensureString2(label);
4208
4214
  return generate(safeWidth + 1, (i) => {
4209
4215
  const filled = safeChar.repeat(i);
4210
4216
  const rest = safeEmpty.repeat(safeWidth - i);
@@ -4224,7 +4230,7 @@ var presets2 = {
4224
4230
  /* istanbul ignore next — default opts {} */
4225
4231
  breathe: (text, opts = {}) => {
4226
4232
  const { steps = 8 } = opts;
4227
- const safeText = ensureString4(text);
4233
+ const safeText = ensureString2(text);
4228
4234
  const safeSteps2 = Math.max(1, isFiniteNumber2(steps) ? Math.floor(steps) : 8);
4229
4235
  const shades = ["\u2591", "\u2592", "\u2593", "\u2588"];
4230
4236
  return generate(safeSteps2 * 2, (i) => {
@@ -4236,7 +4242,7 @@ var presets2 = {
4236
4242
  /* istanbul ignore next — default opts {} */
4237
4243
  typeDelete: (text, opts = {}) => {
4238
4244
  const { cursor: cur = "\u258C" } = opts;
4239
- const safeText = ensureString4(text);
4245
+ const safeText = ensureString2(text);
4240
4246
  const safeCur = typeof cur === "string" ? cur : "\u258C";
4241
4247
  const typed = generate(safeText.length + 1, (i) => safeText.slice(0, i) + safeCur);
4242
4248
  const deleted = generate(safeText.length + 1, (i) => safeText.slice(0, safeText.length - i) + safeCur);
@@ -4246,15 +4252,6 @@ var presets2 = {
4246
4252
  var frames = { play, generate, live, morph, presets: presets2 };
4247
4253
 
4248
4254
  // src/components/index.ts
4249
- var ensureString5 = (v) => typeof v === "string" ? v : String(v ?? "");
4250
- var clampNonNeg = (n, fallback) => {
4251
- if (!isFiniteNumber2(n)) return fallback;
4252
- return Math.max(0, Math.floor(n));
4253
- };
4254
- var clampPositive2 = (n, fallback) => {
4255
- if (!isFiniteNumber2(n)) return fallback;
4256
- return Math.max(1, Math.floor(n));
4257
- };
4258
4255
  var safeSgrCode = (code, fallback) => {
4259
4256
  if (!isFiniteNumber2(code)) return fallback;
4260
4257
  return Math.max(0, Math.min(255, Math.floor(code)));
@@ -4301,7 +4298,7 @@ var table = (rows, opts = {}) => {
4301
4298
  if (cols === 0) return "";
4302
4299
  const processedRows = validRows.map(
4303
4300
  (row) => Array.from({ length: cols }, (_, ci) => {
4304
- const raw = ensureString5(row[ci]);
4301
+ const raw = ensureString2(row[ci]);
4305
4302
  const lines2 = raw.split("\n");
4306
4303
  return safeMaxCol !== null ? lines2.map((l) => truncateVisible(l, safeMaxCol)) : lines2;
4307
4304
  })
@@ -4352,8 +4349,8 @@ var badge = (label, value, opts = {}) => {
4352
4349
  padding = 1,
4353
4350
  border = false
4354
4351
  } = opts;
4355
- const safeLabel = ensureString5(label);
4356
- const safeValue = ensureString5(value);
4352
+ const safeLabel = ensureString2(label);
4353
+ const safeValue = ensureString2(value);
4357
4354
  const safePadding = clampNonNeg(padding, 1);
4358
4355
  const pad = " ".repeat(safePadding);
4359
4356
  const lhs = sgr(safeSgrCode(labelBg, BG.blue), safeSgrCode(labelFg, FG.white)) + pad + safeLabel + pad + reset();
@@ -4377,10 +4374,10 @@ var progressBar = (percent, opts = {}) => {
4377
4374
  color: color2 = null,
4378
4375
  gradient: gradientStops2 = null
4379
4376
  } = opts;
4380
- const safeWidth = clampPositive2(width, 30);
4377
+ const safeWidth = clampPositiveInt(width, 30);
4381
4378
  const safeChar = typeof char === "string" && char.length > 0 ? char : "\u2588";
4382
4379
  const safeEmpty = typeof emptyChar === "string" && emptyChar.length > 0 ? emptyChar : "\u2591";
4383
- const safeLabel = ensureString5(label);
4380
+ const safeLabel = ensureString2(label);
4384
4381
  const clamped = clampPercent(percent);
4385
4382
  const filled = Math.floor(clamped / 100 * safeWidth);
4386
4383
  const empty = Math.max(0, safeWidth - filled);
@@ -4407,7 +4404,7 @@ var status = (type, message, opts = {}) => {
4407
4404
  const def = STATUS_MAP[type] ?? STATUS_MAP.info;
4408
4405
  const colorCode = opts.color !== void 0 ? safeSgrCode(opts.color, def.color) : def.color;
4409
4406
  const useIcon = opts.icon === void 0 ? def.icon : opts.icon ?? "";
4410
- const safeMsg = ensureString5(message);
4407
+ const safeMsg = ensureString2(message);
4411
4408
  const iconPart = useIcon ? sgr(colorCode) + useIcon + reset() + " " : "";
4412
4409
  if (safeMsg.includes("\n")) {
4413
4410
  const indent = " ".repeat(useIcon ? visibleLen(useIcon) + 1 : 0);
@@ -4419,7 +4416,7 @@ var status = (type, message, opts = {}) => {
4419
4416
  var section = (title, opts = {}) => {
4420
4417
  const { char = "\u2500", width = null, color: colorCode = FG.cyan } = opts;
4421
4418
  const { cols } = termSize();
4422
- const safeTitle = ensureString5(title);
4419
+ const safeTitle = ensureString2(title);
4423
4420
  const safeChar = typeof char === "string" && char.length > 0 ? char : "\u2500";
4424
4421
  const safeColor2 = safeSgrCode(colorCode, FG.cyan);
4425
4422
  const titleLen = visibleLen(safeTitle);
@@ -4434,7 +4431,7 @@ var section = (title, opts = {}) => {
4434
4431
  var columns = (items, opts = {}) => {
4435
4432
  if (!Array.isArray(items) || items.length === 0) return "";
4436
4433
  const { cols: numCols = 2, gap = 2, width = null, overflow = "truncate" } = opts;
4437
- const safeCols = clampPositive2(numCols, 2);
4434
+ const safeCols = clampPositiveInt(numCols, 2);
4438
4435
  const safeGap = clampNonNeg(gap, 2);
4439
4436
  const { cols: termCols } = termSize();
4440
4437
  const totalW = width !== null && isFiniteNumber2(width) ? Math.max(safeCols, Math.floor(width)) : termCols;
@@ -4444,7 +4441,7 @@ var columns = (items, opts = {}) => {
4444
4441
  for (let i = 0; i < items.length; i += safeCols) {
4445
4442
  const chunk = items.slice(i, i + safeCols);
4446
4443
  if (overflow === "wrap") {
4447
- const cellLines = chunk.map((it) => wrapVisible(ensureString5(it), colW));
4444
+ const cellLines = chunk.map((it) => wrapVisible(ensureString2(it), colW));
4448
4445
  const rowHeight = Math.max(...cellLines.map((c) => c.length), 1);
4449
4446
  for (let line = 0; line < rowHeight; line++) {
4450
4447
  rows.push(
@@ -4454,7 +4451,7 @@ var columns = (items, opts = {}) => {
4454
4451
  } else {
4455
4452
  rows.push(
4456
4453
  chunk.map((item) => {
4457
- const t = truncateVisible(ensureString5(item), colW);
4454
+ const t = truncateVisible(ensureString2(item), colW);
4458
4455
  return padEnd(t, colW);
4459
4456
  }).join(gapStr)
4460
4457
  );
@@ -4477,15 +4474,15 @@ var timeline = (events, opts = {}) => {
4477
4474
  const safeColor2 = safeSgrCode(colorCode, FG.cyan);
4478
4475
  const safeDoneColor = safeSgrCode(doneColor, FG.green);
4479
4476
  const safePendingColor = safeSgrCode(pendingColor, FG.brightBlack);
4480
- const computedTimeWidth = timeColumnWidth !== null && isFiniteNumber2(timeColumnWidth) ? Math.max(0, Math.floor(timeColumnWidth)) : Math.max(0, ...events.map((e) => e.time ? visibleLen(ensureString5(e.time)) : 0));
4477
+ const computedTimeWidth = timeColumnWidth !== null && isFiniteNumber2(timeColumnWidth) ? Math.max(0, Math.floor(timeColumnWidth)) : Math.max(0, ...events.map((e) => e.time ? visibleLen(ensureString2(e.time)) : 0));
4481
4478
  const lines = [];
4482
4479
  events.forEach((ev, i) => {
4483
4480
  const isLast = i === events.length - 1;
4484
- const evLabel = ensureString5(ev.label);
4481
+ const evLabel = ensureString2(ev.label);
4485
4482
  const clr = ev.done ? safeDoneColor : i === 0 ? safeColor2 : safePendingColor;
4486
4483
  const nodeStr = sgr(clr) + safeNode + reset();
4487
4484
  const textStr = ev.done ? sgr(STYLE.bold) + evLabel + reset() : sgr(safePendingColor) + evLabel + reset();
4488
- const timePart = ev.time && computedTimeWidth > 0 ? " " + sgr(FG.brightBlack) + padEnd(ensureString5(ev.time), computedTimeWidth) + reset() : "";
4485
+ const timePart = ev.time && computedTimeWidth > 0 ? " " + sgr(FG.brightBlack) + padEnd(ensureString2(ev.time), computedTimeWidth) + reset() : "";
4489
4486
  lines.push(`${nodeStr} ${textStr}${timePart}`);
4490
4487
  if (!isLast) lines.push(sgr(safePendingColor) + safeConnector + reset());
4491
4488
  });
@@ -4507,8 +4504,8 @@ var menu = (items, opts = {}) => {
4507
4504
  if (!inp.isTTY) return Promise.resolve(multiSelect ? [] : 0);
4508
4505
  const safeColor2 = safeSgrCode(colorCode, FG.cyan);
4509
4506
  const safePointer = typeof pointer === "string" && pointer.length > 0 ? pointer : "\u25B6";
4510
- const safeTitle = title === null ? null : ensureString5(title);
4511
- const safeItems = items.map(ensureString5);
4507
+ const safeTitle = title === null ? null : ensureString2(title);
4508
+ const safeItems = items.map(ensureString2);
4512
4509
  let cursorPos = 0;
4513
4510
  let lastRenderedLines = 0;
4514
4511
  let cursorHidden = false;
@@ -4669,19 +4666,14 @@ var STYLES = {
4669
4666
  heavy: { branch: "\u2523\u2501\u2501 ", last: "\u2517\u2501\u2501 ", vert: "\u2503 ", space: " " },
4670
4667
  ascii: { branch: "+-- ", last: "`-- ", vert: "| ", space: " " }
4671
4668
  };
4672
- var ensureString6 = (v) => typeof v === "string" ? v : String(v ?? "");
4673
- var clampNonNeg2 = (n, fallback) => {
4674
- if (!isFiniteNumber2(n)) return fallback;
4675
- return Math.max(0, Math.floor(n));
4676
- };
4677
4669
  var normalizeNewlines = (s) => s.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
4678
4670
  var toTreeData = (child) => {
4679
4671
  if (typeof child === "string") return { label: child, children: [] };
4680
4672
  if (typeof child !== "object" || child === null || Array.isArray(child)) {
4681
- return { label: ensureString6(child), children: [] };
4673
+ return { label: ensureString2(child), children: [] };
4682
4674
  }
4683
4675
  return {
4684
- label: ensureString6(child.label ?? ""),
4676
+ label: ensureString2(child.label ?? ""),
4685
4677
  children: [],
4686
4678
  ...child
4687
4679
  };
@@ -4717,8 +4709,8 @@ var paletteAt = (palette, depth) => {
4717
4709
  };
4718
4710
  var formatNode = (node, depth, palette) => {
4719
4711
  const colorFn = node.color ?? paletteAt(palette, depth);
4720
- const safeLabel = normalizeNewlines(ensureString6(node.label));
4721
- const iconPrefix = node.icon ? ensureString6(node.icon) + " " : "";
4712
+ const safeLabel = normalizeNewlines(ensureString2(node.label));
4713
+ const iconPrefix = node.icon ? ensureString2(node.icon) + " " : "";
4722
4714
  const labelLines = safeLabel.split("\n");
4723
4715
  return labelLines.map((line, i) => {
4724
4716
  const text = i === 0 ? iconPrefix + line : line;
@@ -4812,7 +4804,7 @@ var renderTree = (root, opts = {}) => {
4812
4804
  indent = 0
4813
4805
  } = opts;
4814
4806
  const safeStyle = style && STYLES[style] ? style : "normal";
4815
- const safeIndent = clampNonNeg2(indent, 0);
4807
+ const safeIndent = clampNonNeg(indent, 0);
4816
4808
  const safeMaxDepth = isFiniteNumber2(maxDepth) ? Math.max(0, Math.floor(maxDepth)) : Infinity;
4817
4809
  const indentStr = " ".repeat(safeIndent);
4818
4810
  const lines = [];
@@ -6158,37 +6150,105 @@ var grid = (blocks, opts) => {
6158
6150
  const alignX = opts.alignX ?? "start";
6159
6151
  const alignY = opts.alignY ?? "start";
6160
6152
  const cellW = opts.cellWidth != null ? Math.max(0, Math.floor(opts.cellWidth)) : null;
6161
- const rows = [];
6162
- for (let i = 0; i < blocks.length; i += columns2) {
6163
- rows.push(blocks.slice(i, i + columns2));
6153
+ const cellH = opts.cellHeight != null ? Math.max(1, Math.floor(opts.cellHeight)) : null;
6154
+ const flow = opts.flow === "column" ? "column" : "row";
6155
+ const spans = blocks.map((_, i) => {
6156
+ const raw = opts.colSpan?.[i];
6157
+ if (typeof raw !== "number" || !Number.isFinite(raw) || raw < 1) return 1;
6158
+ return Math.min(columns2, Math.floor(raw));
6159
+ });
6160
+ const hasSpans = spans.some((s) => s > 1);
6161
+ const cellRows = [];
6162
+ if (flow === "column" && !hasSpans) {
6163
+ const rowCount = Math.ceil(blocks.length / columns2);
6164
+ for (let r = 0; r < rowCount; r++) cellRows.push([]);
6165
+ for (let i = 0; i < blocks.length; i++) {
6166
+ const c = Math.floor(i / rowCount);
6167
+ const r = i % rowCount;
6168
+ cellRows[r].push({ block: blocks[i], span: 1, col: c });
6169
+ }
6170
+ } else {
6171
+ let row = [];
6172
+ let colInRow = 0;
6173
+ for (let i = 0; i < blocks.length; i++) {
6174
+ const span = spans[i];
6175
+ if (colInRow + span > columns2 && row.length > 0) {
6176
+ cellRows.push(row);
6177
+ row = [];
6178
+ colInRow = 0;
6179
+ }
6180
+ row.push({ block: blocks[i], span, col: colInRow });
6181
+ colInRow += span;
6182
+ }
6183
+ if (row.length > 0) cellRows.push(row);
6164
6184
  }
6165
- let widths = null;
6185
+ let widths;
6166
6186
  if (cellW != null) {
6167
6187
  widths = Array(columns2).fill(cellW);
6168
6188
  } else {
6169
6189
  widths = Array(columns2).fill(0);
6170
- for (const row of rows) {
6171
- for (let c = 0; c < row.length; c++) {
6172
- const { maxWidth } = _splitBlock(row[c]);
6173
- if (maxWidth > widths[c]) {
6174
- widths[c] = maxWidth;
6190
+ for (const r of cellRows) {
6191
+ for (const cell of r) {
6192
+ if (cell.span === 1) {
6193
+ const { maxWidth } = _splitBlock(cell.block);
6194
+ if (maxWidth > widths[cell.col]) {
6195
+ widths[cell.col] = maxWidth;
6196
+ }
6175
6197
  }
6176
6198
  }
6177
6199
  }
6178
- }
6179
- const renderedRows = rows.map((row) => {
6180
- const padded = [];
6181
6200
  for (let c = 0; c < columns2; c++) {
6182
- padded.push(row[c] ?? "");
6201
+ if (widths[c] === 0) {
6202
+ for (const r of cellRows) {
6203
+ for (const cell of r) {
6204
+ if (cell.col <= c && cell.col + cell.span > c) {
6205
+ const { maxWidth } = _splitBlock(cell.block);
6206
+ const each = Math.ceil(maxWidth / cell.span);
6207
+ if (each > widths[c]) widths[c] = each;
6208
+ }
6209
+ }
6210
+ }
6211
+ }
6183
6212
  }
6184
- return vsplit(padded, {
6213
+ }
6214
+ const renderedRows = cellRows.map((row) => {
6215
+ const mergedBlocks = [];
6216
+ const mergedWidths = [];
6217
+ let nextCol = 0;
6218
+ for (const cell of row) {
6219
+ let w = 0;
6220
+ for (let k = 0; k < cell.span; k++) {
6221
+ w += widths[cell.col + k];
6222
+ }
6223
+ w += Math.max(0, cell.span - 1) * gapX;
6224
+ let blockToRender = cell.block;
6225
+ if (cellH != null) {
6226
+ blockToRender = _fitHeight(cell.block, cellH);
6227
+ }
6228
+ mergedBlocks.push(blockToRender);
6229
+ mergedWidths.push(w);
6230
+ nextCol += cell.span;
6231
+ }
6232
+ while (nextCol < columns2) {
6233
+ mergedBlocks.push("");
6234
+ mergedWidths.push(widths[nextCol]);
6235
+ nextCol++;
6236
+ }
6237
+ return vsplit(mergedBlocks, {
6185
6238
  gap: gapX,
6186
6239
  align: alignY,
6187
- widths
6240
+ widths: mergedWidths
6188
6241
  });
6189
6242
  });
6190
6243
  return hsplit(renderedRows, { gap: gapY, align: alignX });
6191
6244
  };
6245
+ var _fitHeight = (block, targetH) => {
6246
+ const lines = block.split("\n");
6247
+ if (lines.length === targetH) return block;
6248
+ if (lines.length > targetH) return lines.slice(0, targetH).join("\n");
6249
+ const pad = Array(targetH - lines.length).fill("");
6250
+ return [...lines, ...pad].join("\n");
6251
+ };
6192
6252
  var panels = {
6193
6253
  vsplit,
6194
6254
  hsplit,
@@ -6346,8 +6406,8 @@ var _renderValue = (value, depth, config) => {
6346
6406
  inlineItems.push(_c(`... (${remaining} more)`, COLORS.comment, useColor));
6347
6407
  }
6348
6408
  const candidate = _c("[", COLORS.bracket, useColor) + inlineItems.join(", ") + _c("]", COLORS.bracket, useColor);
6349
- const visibleLen3 = candidate.replace(/\x1b\[[0-9;]*m/g, "").length;
6350
- if (visibleLen3 <= inlineArrayMaxLength) {
6409
+ const visibleLen2 = candidate.replace(/\x1b\[[0-9;]*m/g, "").length;
6410
+ if (visibleLen2 <= inlineArrayMaxLength) {
6351
6411
  return candidate;
6352
6412
  }
6353
6413
  }
@@ -6426,38 +6486,7 @@ var json = {
6426
6486
  pretty
6427
6487
  };
6428
6488
 
6429
- // src/markdown/index.ts
6430
- var THEMES = {
6431
- dark: {
6432
- h1: ["#ff79c6", "#bd93f9", "#8be9fd"],
6433
- h2: "#bd93f9",
6434
- h3: "#8be9fd",
6435
- h4: "#50fa7b",
6436
- h5: "#f1fa8c",
6437
- h6: "#ffb86c",
6438
- code: "#ff79c6",
6439
- codeBlockBorder: "#6272a4",
6440
- link: "#8be9fd",
6441
- blockquote: "#6272a4",
6442
- hr: "#6272a4",
6443
- tableHeader: "#bd93f9"
6444
- },
6445
- light: {
6446
- h1: ["#d63384", "#6f42c1", "#0d6efd"],
6447
- h2: "#6f42c1",
6448
- h3: "#0d6efd",
6449
- h4: "#198754",
6450
- h5: "#664d03",
6451
- h6: "#fd7e14",
6452
- code: "#d63384",
6453
- codeBlockBorder: "#adb5bd",
6454
- link: "#0d6efd",
6455
- blockquote: "#6c757d",
6456
- hr: "#adb5bd",
6457
- tableHeader: "#6f42c1"
6458
- }
6459
- };
6460
- var _normalize = (text) => typeof text === "string" ? text.replace(/\r\n/g, "\n").replace(/\r/g, "\n") : "";
6489
+ // src/markdown/block-parser.ts
6461
6490
  var HEADING_RE = /^(#{1,6})\s+(.+?)\s*#*\s*$/;
6462
6491
  var ORDERED_LIST_RE = /^(\s*)(\d+)[.)]\s+(.+)$/;
6463
6492
  var UNORDERED_LIST_RE = /^(\s*)[-*+]\s+(.+)$/;
@@ -6467,6 +6496,11 @@ var CODEBLOCK_CLOSE_RE = /^```\s*$/;
6467
6496
  var BLOCKQUOTE_RE = /^>\s?(.*)$/;
6468
6497
  var TABLE_SEPARATOR_RE = /^\|?[ \t]*:?-{2,}:?[ \t]*(\|[ \t]*:?-{2,}:?[ \t]*)+\|?[ \t]*$/;
6469
6498
  var TABLE_ROW_RE = /^\|.*\|[ \t]*$/;
6499
+ var _normalize = (text) => typeof text === "string" ? text.replace(/\r\n/g, "\n").replace(/\r/g, "\n") : "";
6500
+ var _splitTableRow = (row) => {
6501
+ const stripped = row.trim().replace(/^\|/, "").replace(/\|[ \t]*$/, "");
6502
+ return stripped.split("|").map((c) => c.trim());
6503
+ };
6470
6504
  var parseBlocks = (source) => {
6471
6505
  if (typeof source !== "string" || source.length === 0) return [];
6472
6506
  const lines = _normalize(source).split("\n");
@@ -6562,14 +6596,41 @@ var parseBlocks = (source) => {
6562
6596
  }
6563
6597
  return out;
6564
6598
  };
6565
- var _splitTableRow = (row) => {
6566
- const stripped = row.trim().replace(/^\|/, "").replace(/\|[ \t]*$/, "");
6567
- return stripped.split("|").map((c) => c.trim());
6599
+
6600
+ // src/markdown/theme.ts
6601
+ var THEMES = {
6602
+ dark: {
6603
+ h1: ["#ff79c6", "#bd93f9", "#8be9fd"],
6604
+ h2: "#bd93f9",
6605
+ h3: "#8be9fd",
6606
+ h4: "#50fa7b",
6607
+ h5: "#f1fa8c",
6608
+ h6: "#ffb86c",
6609
+ code: "#ff79c6",
6610
+ codeBlockBorder: "#6272a4",
6611
+ link: "#8be9fd",
6612
+ blockquote: "#6272a4",
6613
+ hr: "#6272a4",
6614
+ tableHeader: "#bd93f9"
6615
+ },
6616
+ light: {
6617
+ h1: ["#d63384", "#6f42c1", "#0d6efd"],
6618
+ h2: "#6f42c1",
6619
+ h3: "#0d6efd",
6620
+ h4: "#198754",
6621
+ h5: "#664d03",
6622
+ h6: "#fd7e14",
6623
+ code: "#d63384",
6624
+ codeBlockBorder: "#adb5bd",
6625
+ link: "#0d6efd",
6626
+ blockquote: "#6c757d",
6627
+ hr: "#adb5bd",
6628
+ tableHeader: "#6f42c1"
6629
+ }
6568
6630
  };
6569
- var parseInline = (text, opts = {
6570
- theme: "dark",
6571
- inlineCodeBackground: true
6572
- }) => {
6631
+
6632
+ // src/markdown/inline-parser.ts
6633
+ var parseInline = (text, opts = { theme: "dark", inlineCodeBackground: true }) => {
6573
6634
  if (typeof text !== "string" || text.length === 0) return "";
6574
6635
  const t = THEMES[opts.theme];
6575
6636
  const codeSlots = [];
@@ -6589,6 +6650,8 @@ var parseInline = (text, opts = {
6589
6650
  s = s.replace(/\x00CODE(\d+)\x00/g, (_m, idx) => codeSlots[Number(idx)] ?? "");
6590
6651
  return s;
6591
6652
  };
6653
+
6654
+ // src/markdown/renderer.ts
6592
6655
  var _detectWidth = () => {
6593
6656
  const w = process.stdout?.columns;
6594
6657
  return isFiniteNumber2(w) && w > 10 ? w : 80;
@@ -6683,6 +6746,8 @@ var render = (source, opts = {}) => {
6683
6746
  while (out.length > 0 && out[out.length - 1] === "") out.pop();
6684
6747
  return out.join("\n");
6685
6748
  };
6749
+
6750
+ // src/markdown/index.ts
6686
6751
  var markdown = {
6687
6752
  render,
6688
6753
  parseBlocks,
@@ -7048,7 +7113,9 @@ var index_default = ansimax;
7048
7113
  clamp,
7049
7114
  clampByte,
7050
7115
  clampInt,
7116
+ clampNonNeg,
7051
7117
  clampPercent,
7118
+ clampPositiveInt,
7052
7119
  clearAnsiCache,
7053
7120
  clearColorCache,
7054
7121
  clearLine,
@@ -7069,6 +7136,7 @@ var index_default = ansimax;
7069
7136
  debounce,
7070
7137
  diffLines,
7071
7138
  easings,
7139
+ ensureString,
7072
7140
  escapeForRegex,
7073
7141
  escapeRegex,
7074
7142
  fg256,