ink-hud 0.1.2 → 0.1.4
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/README.md +242 -147
- package/dist/index.cjs +891 -366
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +350 -125
- package/dist/index.d.ts +350 -125
- package/dist/index.js +874 -366
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -4,6 +4,7 @@ var React6 = require('react');
|
|
|
4
4
|
var chalk = require('chalk');
|
|
5
5
|
var tinygradient = require('tinygradient');
|
|
6
6
|
var ink = require('ink');
|
|
7
|
+
var zlib = require('zlib');
|
|
7
8
|
|
|
8
9
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
10
|
|
|
@@ -440,186 +441,6 @@ var BlockRenderer = class _BlockRenderer extends Renderer {
|
|
|
440
441
|
}
|
|
441
442
|
};
|
|
442
443
|
|
|
443
|
-
// src/core/ascii.ts
|
|
444
|
-
var AsciiRenderer = class extends Renderer {
|
|
445
|
-
getMetadata() {
|
|
446
|
-
return {
|
|
447
|
-
name: "ascii",
|
|
448
|
-
displayName: "ASCII",
|
|
449
|
-
description: "ASCII character (. _ - ' / \\ |) 1x3 resolution, maximum compatibility",
|
|
450
|
-
resolution: {
|
|
451
|
-
horizontal: 1,
|
|
452
|
-
vertical: 3
|
|
453
|
-
},
|
|
454
|
-
requiresUtf8: false,
|
|
455
|
-
requiresUnicode: false,
|
|
456
|
-
minScore: 0
|
|
457
|
-
// No requirements, usable in any terminal
|
|
458
|
-
};
|
|
459
|
-
}
|
|
460
|
-
// ============================================================
|
|
461
|
-
// ASCII-specific private methods
|
|
462
|
-
// ============================================================
|
|
463
|
-
/**
|
|
464
|
-
* Check if the pixel at the specified position is set
|
|
465
|
-
*/
|
|
466
|
-
isPixelSet(pixels, x, y) {
|
|
467
|
-
const row = pixels[y];
|
|
468
|
-
if (!row) return false;
|
|
469
|
-
return row[x]?.active ?? false;
|
|
470
|
-
}
|
|
471
|
-
getCellPositions(pixels, x, baseY) {
|
|
472
|
-
const positions = [];
|
|
473
|
-
for (let offset = 0; offset < 3; offset++) {
|
|
474
|
-
if (this.isPixelSet(pixels, x, baseY + offset)) {
|
|
475
|
-
positions.push(offset);
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
return positions;
|
|
479
|
-
}
|
|
480
|
-
getNeighborPosition(pixels, x, baseY) {
|
|
481
|
-
const positions = this.getCellPositions(pixels, x, baseY);
|
|
482
|
-
if (positions.length === 0) {
|
|
483
|
-
return null;
|
|
484
|
-
}
|
|
485
|
-
const sum = positions.reduce((total, value) => total + value, 0);
|
|
486
|
-
return sum / positions.length;
|
|
487
|
-
}
|
|
488
|
-
selectMultiPixelChar(hasAnyLeft, hasAnyRight) {
|
|
489
|
-
return hasAnyLeft || hasAnyRight ? "+" : "|";
|
|
490
|
-
}
|
|
491
|
-
selectHorizontalChar(pos) {
|
|
492
|
-
if (pos === 0) {
|
|
493
|
-
return "'";
|
|
494
|
-
}
|
|
495
|
-
if (pos === 1) {
|
|
496
|
-
return "-";
|
|
497
|
-
}
|
|
498
|
-
return "_";
|
|
499
|
-
}
|
|
500
|
-
selectDiagonalChar(params) {
|
|
501
|
-
const { pos, hasAnyLeft, hasAnyRight, leftPos, rightPos } = params;
|
|
502
|
-
if (hasAnyLeft && leftPos !== null && leftPos !== pos) {
|
|
503
|
-
return pos < leftPos ? "/" : "\\";
|
|
504
|
-
}
|
|
505
|
-
if (hasAnyRight && rightPos !== null && rightPos !== pos) {
|
|
506
|
-
return pos > rightPos ? "/" : "\\";
|
|
507
|
-
}
|
|
508
|
-
return null;
|
|
509
|
-
}
|
|
510
|
-
selectIsolatedChar(pos) {
|
|
511
|
-
if (pos === 0) {
|
|
512
|
-
return '"';
|
|
513
|
-
}
|
|
514
|
-
if (pos === 1) {
|
|
515
|
-
return "+";
|
|
516
|
-
}
|
|
517
|
-
return ".";
|
|
518
|
-
}
|
|
519
|
-
selectSinglePixelChar(params) {
|
|
520
|
-
const { pos, hasSameHorizontal, hasAnyLeft, hasAnyRight, leftPos, rightPos } = params;
|
|
521
|
-
if (hasSameHorizontal) {
|
|
522
|
-
return this.selectHorizontalChar(pos);
|
|
523
|
-
}
|
|
524
|
-
const diagonal = this.selectDiagonalChar({
|
|
525
|
-
pos,
|
|
526
|
-
hasAnyLeft,
|
|
527
|
-
hasAnyRight,
|
|
528
|
-
leftPos,
|
|
529
|
-
rightPos
|
|
530
|
-
});
|
|
531
|
-
if (diagonal) {
|
|
532
|
-
return diagonal;
|
|
533
|
-
}
|
|
534
|
-
return this.selectIsolatedChar(pos);
|
|
535
|
-
}
|
|
536
|
-
/**
|
|
537
|
-
* Intelligently select ASCII character
|
|
538
|
-
* Select appropriate character based on 1x3 vertical pixels and adjacent column connections
|
|
539
|
-
*/
|
|
540
|
-
selectAsciiChar(pixels, x, baseY) {
|
|
541
|
-
const positions = this.getCellPositions(pixels, x, baseY);
|
|
542
|
-
if (positions.length === 0) {
|
|
543
|
-
return " ";
|
|
544
|
-
}
|
|
545
|
-
const leftPos = this.getNeighborPosition(pixels, x - 1, baseY);
|
|
546
|
-
const rightPos = this.getNeighborPosition(pixels, x + 1, baseY);
|
|
547
|
-
const hasAnyLeft = leftPos !== null;
|
|
548
|
-
const hasAnyRight = rightPos !== null;
|
|
549
|
-
if (positions.length >= 2) {
|
|
550
|
-
return this.selectMultiPixelChar(hasAnyLeft, hasAnyRight);
|
|
551
|
-
}
|
|
552
|
-
const pos = positions[0] ?? 1;
|
|
553
|
-
const hasLeftSame = this.isPixelSet(pixels, x - 1, baseY + pos);
|
|
554
|
-
const hasRightSame = this.isPixelSet(pixels, x + 1, baseY + pos);
|
|
555
|
-
const hasSameHorizontal = hasLeftSame || hasRightSame;
|
|
556
|
-
return this.selectSinglePixelChar({
|
|
557
|
-
pos,
|
|
558
|
-
hasSameHorizontal,
|
|
559
|
-
hasAnyLeft,
|
|
560
|
-
hasAnyRight,
|
|
561
|
-
leftPos,
|
|
562
|
-
rightPos
|
|
563
|
-
});
|
|
564
|
-
}
|
|
565
|
-
/**
|
|
566
|
-
* Determine the primary color for this character cell
|
|
567
|
-
*/
|
|
568
|
-
resolveColor(pixels, x, baseY) {
|
|
569
|
-
const counts = /* @__PURE__ */ new Map();
|
|
570
|
-
for (let offset = 0; offset < 3; offset++) {
|
|
571
|
-
const y = baseY + offset;
|
|
572
|
-
if (y >= pixels.length) continue;
|
|
573
|
-
const pixel = pixels[y]?.[x];
|
|
574
|
-
if (pixel?.active && pixel.color) {
|
|
575
|
-
counts.set(pixel.color, (counts.get(pixel.color) ?? 0) + 1);
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
if (counts.size === 0) return void 0;
|
|
579
|
-
let maxCount = 0;
|
|
580
|
-
let dominantColor;
|
|
581
|
-
for (const [color, count] of counts) {
|
|
582
|
-
if (count > maxCount) {
|
|
583
|
-
maxCount = count;
|
|
584
|
-
dominantColor = color;
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
return dominantColor;
|
|
588
|
-
}
|
|
589
|
-
// ============================================================
|
|
590
|
-
// Methods that subclasses must implement
|
|
591
|
-
// ============================================================
|
|
592
|
-
renderCanvas(pixels, width, height) {
|
|
593
|
-
const lines = [];
|
|
594
|
-
const charHeight = Math.ceil(height / 3);
|
|
595
|
-
for (let cy = 0; cy < charHeight; cy++) {
|
|
596
|
-
const lineSegments = [];
|
|
597
|
-
const baseY = cy * 3;
|
|
598
|
-
let buffer = "";
|
|
599
|
-
let bufferColor;
|
|
600
|
-
for (let x = 0; x < width; x++) {
|
|
601
|
-
const char = this.selectAsciiChar(pixels, x, baseY);
|
|
602
|
-
const color = char === " " ? void 0 : this.resolveColor(pixels, x, baseY);
|
|
603
|
-
if (buffer && bufferColor !== color) {
|
|
604
|
-
lineSegments.push(
|
|
605
|
-
bufferColor ? { text: buffer, color: bufferColor } : { text: buffer }
|
|
606
|
-
);
|
|
607
|
-
buffer = "";
|
|
608
|
-
}
|
|
609
|
-
bufferColor = color;
|
|
610
|
-
buffer += char;
|
|
611
|
-
}
|
|
612
|
-
if (buffer) {
|
|
613
|
-
lineSegments.push(
|
|
614
|
-
bufferColor ? { text: buffer, color: bufferColor } : { text: buffer }
|
|
615
|
-
);
|
|
616
|
-
}
|
|
617
|
-
lines.push(lineSegments);
|
|
618
|
-
}
|
|
619
|
-
return lines;
|
|
620
|
-
}
|
|
621
|
-
};
|
|
622
|
-
|
|
623
444
|
// src/detect/terminal.ts
|
|
624
445
|
var TerminalDetector = class _TerminalDetector {
|
|
625
446
|
/** Terminal whitelist supporting Braille characters (lowercase) */
|
|
@@ -796,8 +617,6 @@ var RendererSelector = class {
|
|
|
796
617
|
return new BrailleRenderer();
|
|
797
618
|
case "block":
|
|
798
619
|
return new BlockRenderer();
|
|
799
|
-
case "ascii":
|
|
800
|
-
return new AsciiRenderer();
|
|
801
620
|
}
|
|
802
621
|
}
|
|
803
622
|
/**
|
|
@@ -808,6 +627,17 @@ var RendererSelector = class {
|
|
|
808
627
|
getRenderer(type) {
|
|
809
628
|
return this.createRenderer(type);
|
|
810
629
|
}
|
|
630
|
+
/**
|
|
631
|
+
* Check if a renderer type is supported by the current terminal
|
|
632
|
+
* Used internally by InkHudProvider to determine the per-chart renderer
|
|
633
|
+
* @param type - Renderer type
|
|
634
|
+
* @returns Whether the renderer type is supported
|
|
635
|
+
*/
|
|
636
|
+
isRendererTypeSupported(type) {
|
|
637
|
+
const capabilities = this.detector.detect();
|
|
638
|
+
const renderer = this.createRenderer(type);
|
|
639
|
+
return this.isRendererSupported(renderer, capabilities);
|
|
640
|
+
}
|
|
811
641
|
/**
|
|
812
642
|
* Check if the renderer meets terminal capability requirements
|
|
813
643
|
* @param renderer - Renderer instance
|
|
@@ -835,15 +665,16 @@ var RendererSelector = class {
|
|
|
835
665
|
return true;
|
|
836
666
|
}
|
|
837
667
|
/**
|
|
838
|
-
* Automatically select the best renderer
|
|
668
|
+
* Automatically select the best renderer from a priority chain.
|
|
839
669
|
*
|
|
840
|
-
*
|
|
841
|
-
*
|
|
670
|
+
* @deprecated Prefer `<InkHudProvider renderers={{ line: 'block' }}>` combined
|
|
671
|
+
* with `useChartRenderer(kind)`. This method remains as a low-level escape
|
|
672
|
+
* hatch for custom renderer selection outside the React component tree.
|
|
842
673
|
*
|
|
843
|
-
* @param preferredChain - Priority chain (default: ['braille', 'block'
|
|
674
|
+
* @param preferredChain - Priority chain (default: ['braille', 'block'])
|
|
844
675
|
* @returns Selected renderer instance
|
|
845
676
|
*/
|
|
846
|
-
selectBest(preferredChain = ["braille", "block"
|
|
677
|
+
selectBest(preferredChain = ["braille", "block"]) {
|
|
847
678
|
const capabilities = this.detector.detect();
|
|
848
679
|
for (const rendererType of preferredChain) {
|
|
849
680
|
const renderer = this.getRenderer(rendererType);
|
|
@@ -851,7 +682,7 @@ var RendererSelector = class {
|
|
|
851
682
|
return renderer;
|
|
852
683
|
}
|
|
853
684
|
}
|
|
854
|
-
return this.getRenderer("
|
|
685
|
+
return this.getRenderer("block");
|
|
855
686
|
}
|
|
856
687
|
/**
|
|
857
688
|
* Get terminal capability information
|
|
@@ -862,33 +693,70 @@ var RendererSelector = class {
|
|
|
862
693
|
}
|
|
863
694
|
};
|
|
864
695
|
var rendererSelector = new RendererSelector();
|
|
696
|
+
|
|
697
|
+
// src/components/InkHudProvider.tsx
|
|
698
|
+
var DEFAULT_CHART_RENDERERS = {
|
|
699
|
+
line: "braille",
|
|
700
|
+
area: "braille",
|
|
701
|
+
bar: "block",
|
|
702
|
+
pie: "block"
|
|
703
|
+
};
|
|
704
|
+
var selectorFallbackWarnings = /* @__PURE__ */ new WeakMap();
|
|
705
|
+
function warnFallback(selector, kind, target) {
|
|
706
|
+
if (process.env.NODE_ENV === "production") return;
|
|
707
|
+
let warned = selectorFallbackWarnings.get(selector);
|
|
708
|
+
if (!warned) {
|
|
709
|
+
warned = /* @__PURE__ */ new Set();
|
|
710
|
+
selectorFallbackWarnings.set(selector, warned);
|
|
711
|
+
}
|
|
712
|
+
const key = `${kind}:${target}`;
|
|
713
|
+
if (warned.has(key)) return;
|
|
714
|
+
warned.add(key);
|
|
715
|
+
console.warn(
|
|
716
|
+
`[ink-hud] Renderer '${target}' is not supported by the current terminal; falling back to 'block' for chart kind '${kind}'. Override via <InkHudProvider renderers={{ ${kind}: 'block' }}>.`
|
|
717
|
+
);
|
|
718
|
+
}
|
|
865
719
|
var defaultSelector = new RendererSelector();
|
|
866
720
|
var defaultContext = {
|
|
867
721
|
selector: defaultSelector,
|
|
868
722
|
getCapabilities: () => defaultSelector.getTerminalCapabilities(),
|
|
869
723
|
getRenderer: (type) => defaultSelector.getRenderer(type),
|
|
870
|
-
|
|
724
|
+
getRendererFor: (kind) => {
|
|
725
|
+
const target = DEFAULT_CHART_RENDERERS[kind];
|
|
726
|
+
if (defaultSelector.isRendererTypeSupported(target)) {
|
|
727
|
+
return defaultSelector.getRenderer(target);
|
|
728
|
+
}
|
|
729
|
+
warnFallback(defaultSelector, kind, target);
|
|
730
|
+
return defaultSelector.getRenderer("block");
|
|
731
|
+
}
|
|
871
732
|
};
|
|
872
733
|
var InkHudContext = React6.createContext(defaultContext);
|
|
873
734
|
var InkHudProvider = ({
|
|
874
735
|
detector,
|
|
875
|
-
|
|
736
|
+
renderers,
|
|
876
737
|
children
|
|
877
738
|
}) => {
|
|
878
739
|
const value = React6.useMemo(() => {
|
|
879
740
|
const selector = detector ? new RendererSelector(detector) : defaultSelector;
|
|
741
|
+
const mergedRenderers = {
|
|
742
|
+
...DEFAULT_CHART_RENDERERS,
|
|
743
|
+
...renderers
|
|
744
|
+
};
|
|
745
|
+
const getRendererFor = (kind) => {
|
|
746
|
+
const target = mergedRenderers[kind];
|
|
747
|
+
if (selector.isRendererTypeSupported(target)) {
|
|
748
|
+
return selector.getRenderer(target);
|
|
749
|
+
}
|
|
750
|
+
warnFallback(selector, kind, target);
|
|
751
|
+
return selector.getRenderer("block");
|
|
752
|
+
};
|
|
880
753
|
return {
|
|
881
754
|
selector,
|
|
882
755
|
getCapabilities: () => selector.getTerminalCapabilities(),
|
|
883
756
|
getRenderer: (type) => selector.getRenderer(type),
|
|
884
|
-
|
|
885
|
-
if (forceRenderer) {
|
|
886
|
-
return selector.getRenderer(forceRenderer);
|
|
887
|
-
}
|
|
888
|
-
return selector.selectBest(chain);
|
|
889
|
-
}
|
|
757
|
+
getRendererFor
|
|
890
758
|
};
|
|
891
|
-
}, [detector,
|
|
759
|
+
}, [detector, renderers]);
|
|
892
760
|
return /* @__PURE__ */ React6__default.default.createElement(InkHudContext.Provider, { value }, children);
|
|
893
761
|
};
|
|
894
762
|
function useInkHud() {
|
|
@@ -1364,6 +1232,420 @@ function useThrottle(value, fps = 30) {
|
|
|
1364
1232
|
}, [value, fps]);
|
|
1365
1233
|
return throttledValue;
|
|
1366
1234
|
}
|
|
1235
|
+
|
|
1236
|
+
// src/render/capabilities.ts
|
|
1237
|
+
function detectImageProtocol(env = process.env) {
|
|
1238
|
+
const override = env.INKHU_IMAGE_PROTOCOL;
|
|
1239
|
+
if (override === "kitty") return "kitty";
|
|
1240
|
+
if (override === "iterm2") return "iterm2";
|
|
1241
|
+
if (override === "none") return null;
|
|
1242
|
+
if (env.KITTY_WINDOW_ID) return "kitty";
|
|
1243
|
+
const tp = (env.TERM_PROGRAM ?? "").toLowerCase();
|
|
1244
|
+
if (tp === "wezterm" || tp === "ghostty") return "kitty";
|
|
1245
|
+
if (tp === "iterm.app") return "iterm2";
|
|
1246
|
+
return null;
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
// src/render/image/iterm2.ts
|
|
1250
|
+
function encodeIterm2(pngBuffer, cols) {
|
|
1251
|
+
const b64 = pngBuffer.toString("base64");
|
|
1252
|
+
const args = ["inline=1", "preserveAspectRatio=1"];
|
|
1253
|
+
if (cols !== void 0) args.push(`width=${cols}`);
|
|
1254
|
+
return `\x1B]1337;File=${args.join(";")}:${b64}\x07`;
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
// src/render/image/kitty.ts
|
|
1258
|
+
var CHUNK_SIZE = 4096;
|
|
1259
|
+
var DIACRITICS = [
|
|
1260
|
+
// 0–99 (original set)
|
|
1261
|
+
773,
|
|
1262
|
+
781,
|
|
1263
|
+
782,
|
|
1264
|
+
784,
|
|
1265
|
+
786,
|
|
1266
|
+
829,
|
|
1267
|
+
830,
|
|
1268
|
+
831,
|
|
1269
|
+
838,
|
|
1270
|
+
842,
|
|
1271
|
+
843,
|
|
1272
|
+
844,
|
|
1273
|
+
848,
|
|
1274
|
+
849,
|
|
1275
|
+
850,
|
|
1276
|
+
855,
|
|
1277
|
+
859,
|
|
1278
|
+
867,
|
|
1279
|
+
868,
|
|
1280
|
+
869,
|
|
1281
|
+
870,
|
|
1282
|
+
871,
|
|
1283
|
+
872,
|
|
1284
|
+
873,
|
|
1285
|
+
874,
|
|
1286
|
+
875,
|
|
1287
|
+
876,
|
|
1288
|
+
877,
|
|
1289
|
+
878,
|
|
1290
|
+
879,
|
|
1291
|
+
1155,
|
|
1292
|
+
1156,
|
|
1293
|
+
1157,
|
|
1294
|
+
1158,
|
|
1295
|
+
1159,
|
|
1296
|
+
1426,
|
|
1297
|
+
1427,
|
|
1298
|
+
1428,
|
|
1299
|
+
1429,
|
|
1300
|
+
1431,
|
|
1301
|
+
1432,
|
|
1302
|
+
1433,
|
|
1303
|
+
1436,
|
|
1304
|
+
1437,
|
|
1305
|
+
1438,
|
|
1306
|
+
1439,
|
|
1307
|
+
1440,
|
|
1308
|
+
1441,
|
|
1309
|
+
1448,
|
|
1310
|
+
1449,
|
|
1311
|
+
1451,
|
|
1312
|
+
1452,
|
|
1313
|
+
1455,
|
|
1314
|
+
1476,
|
|
1315
|
+
1552,
|
|
1316
|
+
1553,
|
|
1317
|
+
1554,
|
|
1318
|
+
1555,
|
|
1319
|
+
1556,
|
|
1320
|
+
1557,
|
|
1321
|
+
1558,
|
|
1322
|
+
1559,
|
|
1323
|
+
1623,
|
|
1324
|
+
1624,
|
|
1325
|
+
1625,
|
|
1326
|
+
1626,
|
|
1327
|
+
1627,
|
|
1328
|
+
1629,
|
|
1329
|
+
1630,
|
|
1330
|
+
1750,
|
|
1331
|
+
1751,
|
|
1332
|
+
1752,
|
|
1333
|
+
1753,
|
|
1334
|
+
1754,
|
|
1335
|
+
1755,
|
|
1336
|
+
1756,
|
|
1337
|
+
1759,
|
|
1338
|
+
1760,
|
|
1339
|
+
1761,
|
|
1340
|
+
1762,
|
|
1341
|
+
1764,
|
|
1342
|
+
1767,
|
|
1343
|
+
1768,
|
|
1344
|
+
1771,
|
|
1345
|
+
1772,
|
|
1346
|
+
1840,
|
|
1347
|
+
1842,
|
|
1348
|
+
1843,
|
|
1349
|
+
1845,
|
|
1350
|
+
1846,
|
|
1351
|
+
1850,
|
|
1352
|
+
1853,
|
|
1353
|
+
1855,
|
|
1354
|
+
1856,
|
|
1355
|
+
1857,
|
|
1356
|
+
1859,
|
|
1357
|
+
1861,
|
|
1358
|
+
1863,
|
|
1359
|
+
1865,
|
|
1360
|
+
1866,
|
|
1361
|
+
// 100–107
|
|
1362
|
+
2027,
|
|
1363
|
+
2028,
|
|
1364
|
+
2029,
|
|
1365
|
+
2030,
|
|
1366
|
+
2031,
|
|
1367
|
+
2032,
|
|
1368
|
+
2033,
|
|
1369
|
+
2035,
|
|
1370
|
+
// 108–128
|
|
1371
|
+
2070,
|
|
1372
|
+
2071,
|
|
1373
|
+
2072,
|
|
1374
|
+
2073,
|
|
1375
|
+
2075,
|
|
1376
|
+
2076,
|
|
1377
|
+
2077,
|
|
1378
|
+
2078,
|
|
1379
|
+
2079,
|
|
1380
|
+
2080,
|
|
1381
|
+
2081,
|
|
1382
|
+
2082,
|
|
1383
|
+
2083,
|
|
1384
|
+
2085,
|
|
1385
|
+
2086,
|
|
1386
|
+
2087,
|
|
1387
|
+
2089,
|
|
1388
|
+
2090,
|
|
1389
|
+
2091,
|
|
1390
|
+
2092,
|
|
1391
|
+
2093,
|
|
1392
|
+
// 129–131
|
|
1393
|
+
2385,
|
|
1394
|
+
2387,
|
|
1395
|
+
2388,
|
|
1396
|
+
// 132–135
|
|
1397
|
+
3970,
|
|
1398
|
+
3971,
|
|
1399
|
+
3974,
|
|
1400
|
+
3975,
|
|
1401
|
+
// 136–138
|
|
1402
|
+
4957,
|
|
1403
|
+
4958,
|
|
1404
|
+
4959,
|
|
1405
|
+
// 139
|
|
1406
|
+
6109,
|
|
1407
|
+
// 140
|
|
1408
|
+
6458,
|
|
1409
|
+
// 141–149
|
|
1410
|
+
6679,
|
|
1411
|
+
6773,
|
|
1412
|
+
6774,
|
|
1413
|
+
6775,
|
|
1414
|
+
6776,
|
|
1415
|
+
6777,
|
|
1416
|
+
6778,
|
|
1417
|
+
6779,
|
|
1418
|
+
6780,
|
|
1419
|
+
// 150–158
|
|
1420
|
+
7019,
|
|
1421
|
+
7020,
|
|
1422
|
+
7021,
|
|
1423
|
+
7022,
|
|
1424
|
+
7023,
|
|
1425
|
+
7024,
|
|
1426
|
+
7025,
|
|
1427
|
+
7026,
|
|
1428
|
+
7027,
|
|
1429
|
+
// 159–173
|
|
1430
|
+
7376,
|
|
1431
|
+
7377,
|
|
1432
|
+
7378,
|
|
1433
|
+
7386,
|
|
1434
|
+
7387,
|
|
1435
|
+
7392,
|
|
1436
|
+
7393,
|
|
1437
|
+
7394,
|
|
1438
|
+
7395,
|
|
1439
|
+
7396,
|
|
1440
|
+
7397,
|
|
1441
|
+
7398,
|
|
1442
|
+
7399,
|
|
1443
|
+
7400,
|
|
1444
|
+
7405,
|
|
1445
|
+
// 174–176
|
|
1446
|
+
7412,
|
|
1447
|
+
7416,
|
|
1448
|
+
7417,
|
|
1449
|
+
// 177–187
|
|
1450
|
+
7616,
|
|
1451
|
+
7617,
|
|
1452
|
+
7619,
|
|
1453
|
+
7620,
|
|
1454
|
+
7621,
|
|
1455
|
+
7622,
|
|
1456
|
+
7623,
|
|
1457
|
+
7624,
|
|
1458
|
+
7625,
|
|
1459
|
+
7627,
|
|
1460
|
+
7628,
|
|
1461
|
+
// 188–210
|
|
1462
|
+
7633,
|
|
1463
|
+
7634,
|
|
1464
|
+
7635,
|
|
1465
|
+
7636,
|
|
1466
|
+
7637,
|
|
1467
|
+
7638,
|
|
1468
|
+
7639,
|
|
1469
|
+
7640,
|
|
1470
|
+
7641,
|
|
1471
|
+
7642,
|
|
1472
|
+
7643,
|
|
1473
|
+
7644,
|
|
1474
|
+
7645,
|
|
1475
|
+
7646,
|
|
1476
|
+
7647,
|
|
1477
|
+
7648,
|
|
1478
|
+
7649,
|
|
1479
|
+
7650,
|
|
1480
|
+
7651,
|
|
1481
|
+
7652,
|
|
1482
|
+
7653,
|
|
1483
|
+
7654,
|
|
1484
|
+
7678,
|
|
1485
|
+
// 211–222
|
|
1486
|
+
8400,
|
|
1487
|
+
8401,
|
|
1488
|
+
8404,
|
|
1489
|
+
8405,
|
|
1490
|
+
8406,
|
|
1491
|
+
8407,
|
|
1492
|
+
8411,
|
|
1493
|
+
8412,
|
|
1494
|
+
8417,
|
|
1495
|
+
8423,
|
|
1496
|
+
8425,
|
|
1497
|
+
8432,
|
|
1498
|
+
// 223–225
|
|
1499
|
+
11503,
|
|
1500
|
+
11504,
|
|
1501
|
+
11505,
|
|
1502
|
+
// 226–255
|
|
1503
|
+
11744,
|
|
1504
|
+
11745,
|
|
1505
|
+
11746,
|
|
1506
|
+
11747,
|
|
1507
|
+
11748,
|
|
1508
|
+
11749,
|
|
1509
|
+
11750,
|
|
1510
|
+
11751,
|
|
1511
|
+
11752,
|
|
1512
|
+
11753,
|
|
1513
|
+
11754,
|
|
1514
|
+
11755,
|
|
1515
|
+
11756,
|
|
1516
|
+
11757,
|
|
1517
|
+
11758,
|
|
1518
|
+
11759,
|
|
1519
|
+
11760,
|
|
1520
|
+
11761,
|
|
1521
|
+
11762,
|
|
1522
|
+
11763,
|
|
1523
|
+
11764,
|
|
1524
|
+
11765,
|
|
1525
|
+
11766,
|
|
1526
|
+
11767,
|
|
1527
|
+
11768,
|
|
1528
|
+
11769,
|
|
1529
|
+
11770,
|
|
1530
|
+
11771,
|
|
1531
|
+
11772,
|
|
1532
|
+
11773
|
|
1533
|
+
];
|
|
1534
|
+
function encodeKittyUpload(pngBuffer, cols, rows, imageId) {
|
|
1535
|
+
const b64 = pngBuffer.toString("base64");
|
|
1536
|
+
const parts = [];
|
|
1537
|
+
for (let i = 0; i < b64.length; i += CHUNK_SIZE) {
|
|
1538
|
+
const data = b64.slice(i, i + CHUNK_SIZE);
|
|
1539
|
+
const isFirst = i === 0;
|
|
1540
|
+
const isLast = i + CHUNK_SIZE >= b64.length;
|
|
1541
|
+
let params;
|
|
1542
|
+
if (isFirst) {
|
|
1543
|
+
const more = isLast ? 0 : 1;
|
|
1544
|
+
params = `a=T,U=1,i=${imageId},f=100,q=2,m=${more},c=${cols},r=${rows}`;
|
|
1545
|
+
} else {
|
|
1546
|
+
params = `m=${isLast ? 0 : 1},q=2`;
|
|
1547
|
+
}
|
|
1548
|
+
parts.push(`\x1B_G${params};${data}\x1B\\`);
|
|
1549
|
+
}
|
|
1550
|
+
return parts.join("");
|
|
1551
|
+
}
|
|
1552
|
+
function encodeKittyPlaceholders(cols, rows, imageId, options = {}) {
|
|
1553
|
+
const { trailingSpace = true } = options;
|
|
1554
|
+
const r = imageId >> 16 & 255;
|
|
1555
|
+
const g = imageId >> 8 & 255;
|
|
1556
|
+
const b = imageId & 255;
|
|
1557
|
+
const colorSeq = `\x1B[38;2;${r};${g};${b}m`;
|
|
1558
|
+
const resetSeq = "\x1B[39m";
|
|
1559
|
+
const placeholder = "\u{10EEEE}";
|
|
1560
|
+
const maxDim = DIACRITICS.length;
|
|
1561
|
+
if (rows > maxDim || cols > maxDim) {
|
|
1562
|
+
throw new RangeError(
|
|
1563
|
+
`encodeKittyPlaceholders: rows (${rows}) and cols (${cols}) must each be \u2264 ${maxDim}`
|
|
1564
|
+
);
|
|
1565
|
+
}
|
|
1566
|
+
const lines = [];
|
|
1567
|
+
for (let row = 0; row < rows; row++) {
|
|
1568
|
+
const rowMark = String.fromCodePoint(DIACRITICS[row] ?? 0);
|
|
1569
|
+
let line = colorSeq;
|
|
1570
|
+
for (let col = 0; col < cols; col++) {
|
|
1571
|
+
const colMark = String.fromCodePoint(DIACRITICS[col] ?? 0);
|
|
1572
|
+
line += placeholder + rowMark + colMark + (trailingSpace ? " " : "");
|
|
1573
|
+
}
|
|
1574
|
+
line += resetSeq;
|
|
1575
|
+
lines.push(line);
|
|
1576
|
+
}
|
|
1577
|
+
return lines.join("\n");
|
|
1578
|
+
}
|
|
1579
|
+
function encodeKittyDelete(imageId) {
|
|
1580
|
+
return `\x1B_Ga=d,d=I,i=${imageId}\x1B\\`;
|
|
1581
|
+
}
|
|
1582
|
+
function encodeKitty(pngBuffer, cols, rows) {
|
|
1583
|
+
const b64 = pngBuffer.toString("base64");
|
|
1584
|
+
const parts = [];
|
|
1585
|
+
for (let i = 0; i < b64.length; i += CHUNK_SIZE) {
|
|
1586
|
+
const data = b64.slice(i, i + CHUNK_SIZE);
|
|
1587
|
+
const isFirst = i === 0;
|
|
1588
|
+
const isLast = i + CHUNK_SIZE >= b64.length;
|
|
1589
|
+
let params;
|
|
1590
|
+
if (isFirst) {
|
|
1591
|
+
const more = isLast ? 0 : 1;
|
|
1592
|
+
params = `a=T,f=100,q=2,m=${more},c=${cols},r=${rows}`;
|
|
1593
|
+
} else {
|
|
1594
|
+
params = `m=${isLast ? 0 : 1},q=2`;
|
|
1595
|
+
}
|
|
1596
|
+
parts.push(`\x1B_G${params};${data}\x1B\\`);
|
|
1597
|
+
}
|
|
1598
|
+
return parts.join("");
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
// src/hooks/useImageProtocol.ts
|
|
1602
|
+
var nextImageId = 1;
|
|
1603
|
+
function useImageProtocol({
|
|
1604
|
+
mode,
|
|
1605
|
+
charCols,
|
|
1606
|
+
charRows,
|
|
1607
|
+
pngBuf,
|
|
1608
|
+
trailingSpace = true
|
|
1609
|
+
}) {
|
|
1610
|
+
const { stdout } = ink.useStdout();
|
|
1611
|
+
const imageIdRef = React6.useRef(null);
|
|
1612
|
+
if (imageIdRef.current === null) {
|
|
1613
|
+
imageIdRef.current = nextImageId++;
|
|
1614
|
+
}
|
|
1615
|
+
const imageId = imageIdRef.current;
|
|
1616
|
+
const protocol = React6.useMemo(() => {
|
|
1617
|
+
if (mode === "character") return null;
|
|
1618
|
+
return detectImageProtocol();
|
|
1619
|
+
}, [mode]);
|
|
1620
|
+
const useImage = protocol !== null && mode !== "character" && pngBuf !== null && charCols > 0 && charRows > 0;
|
|
1621
|
+
React6.useEffect(() => {
|
|
1622
|
+
if (protocol !== "kitty" || !pngBuf || charCols <= 0 || charRows <= 0 || mode === "character")
|
|
1623
|
+
return;
|
|
1624
|
+
stdout.write(encodeKittyUpload(pngBuf, charCols, charRows, imageId));
|
|
1625
|
+
return () => {
|
|
1626
|
+
stdout.write(encodeKittyDelete(imageId));
|
|
1627
|
+
};
|
|
1628
|
+
}, [mode, protocol, pngBuf, charCols, charRows, imageId, stdout]);
|
|
1629
|
+
React6.useEffect(() => {
|
|
1630
|
+
if (protocol !== "iterm2" || !pngBuf || charCols <= 0 || charRows <= 0 || mode === "character")
|
|
1631
|
+
return;
|
|
1632
|
+
const terminalCols = charCols * (trailingSpace ? 2 : 1);
|
|
1633
|
+
const seq = encodeIterm2(pngBuf, terminalCols);
|
|
1634
|
+
stdout.write(`\x1B[${charRows}A\x1B[0G${seq}\x1B[${charRows}B`);
|
|
1635
|
+
}, [mode, protocol, pngBuf, charCols, charRows, trailingSpace, stdout]);
|
|
1636
|
+
if (!useImage) {
|
|
1637
|
+
return { useImage: false, kittyLines: null, iterm2Cols: null };
|
|
1638
|
+
}
|
|
1639
|
+
if (protocol === "kitty") {
|
|
1640
|
+
const text = encodeKittyPlaceholders(charCols, charRows, imageId, { trailingSpace });
|
|
1641
|
+
return { useImage: true, kittyLines: text.split("\n"), iterm2Cols: null };
|
|
1642
|
+
}
|
|
1643
|
+
return {
|
|
1644
|
+
useImage: true,
|
|
1645
|
+
kittyLines: null,
|
|
1646
|
+
iterm2Cols: charCols * (trailingSpace ? 2 : 1)
|
|
1647
|
+
};
|
|
1648
|
+
}
|
|
1367
1649
|
var GridContext = React6.createContext({
|
|
1368
1650
|
columns: 12,
|
|
1369
1651
|
gap: 0,
|
|
@@ -1492,6 +1774,24 @@ var GridItem = ({
|
|
|
1492
1774
|
};
|
|
1493
1775
|
|
|
1494
1776
|
// src/components/common/chartUtils.ts
|
|
1777
|
+
function estimateHorizontalLegendRows(names, availableWidth) {
|
|
1778
|
+
if (!names || names.length === 0) return 1;
|
|
1779
|
+
const SYMBOL_WIDTH = 2;
|
|
1780
|
+
const ITEM_GAP = 2;
|
|
1781
|
+
let rows = 1;
|
|
1782
|
+
let used = 0;
|
|
1783
|
+
for (const n of names) {
|
|
1784
|
+
const itemWidth = SYMBOL_WIDTH + n.length;
|
|
1785
|
+
const needed = used === 0 ? itemWidth : itemWidth + ITEM_GAP;
|
|
1786
|
+
if (used + needed > availableWidth && used > 0) {
|
|
1787
|
+
rows++;
|
|
1788
|
+
used = itemWidth;
|
|
1789
|
+
} else {
|
|
1790
|
+
used += needed;
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1793
|
+
return rows;
|
|
1794
|
+
}
|
|
1495
1795
|
function resolveSeriesColors(series, colors, palette) {
|
|
1496
1796
|
if (series.length === 0) {
|
|
1497
1797
|
return [];
|
|
@@ -1519,7 +1819,8 @@ function useChartLayout(props, config) {
|
|
|
1519
1819
|
defaultWidth = 60,
|
|
1520
1820
|
defaultHeight = 15,
|
|
1521
1821
|
min,
|
|
1522
|
-
max
|
|
1822
|
+
max,
|
|
1823
|
+
legendNames
|
|
1523
1824
|
} = config;
|
|
1524
1825
|
const gridContext = React6.useContext(GridItemContext);
|
|
1525
1826
|
const totalHeight = props.height ?? (typeof gridContext?.height === "number" ? gridContext.height : defaultHeight);
|
|
@@ -1542,9 +1843,11 @@ function useChartLayout(props, config) {
|
|
|
1542
1843
|
let legendHeight = 0;
|
|
1543
1844
|
if (showLegend) {
|
|
1544
1845
|
if (legendPosition === "right") {
|
|
1545
|
-
legendWidth = 20;
|
|
1846
|
+
legendWidth = legendNames && legendNames.length > 0 ? Math.max(...legendNames.map((n) => n.length)) + 2 : 20;
|
|
1546
1847
|
} else {
|
|
1547
|
-
|
|
1848
|
+
const legendAvailWidth = Math.max(1, totalWidth - yAxisWidth - (showYAxis ? 1 : 0));
|
|
1849
|
+
const contentRows = estimateHorizontalLegendRows(legendNames, legendAvailWidth);
|
|
1850
|
+
legendHeight = contentRows + 1;
|
|
1548
1851
|
}
|
|
1549
1852
|
}
|
|
1550
1853
|
const yAxisSpacing = showYAxis ? 1 : 0;
|
|
@@ -1568,7 +1871,7 @@ function useChartLayout(props, config) {
|
|
|
1568
1871
|
xAxisHeight: effectiveXAxisHeight
|
|
1569
1872
|
};
|
|
1570
1873
|
}
|
|
1571
|
-
function useChartLayoutSimple(props, min, max) {
|
|
1874
|
+
function useChartLayoutSimple(props, min, max, legendNames) {
|
|
1572
1875
|
const {
|
|
1573
1876
|
width: propsWidth,
|
|
1574
1877
|
height: propsHeight,
|
|
@@ -1603,7 +1906,8 @@ function useChartLayoutSimple(props, min, max) {
|
|
|
1603
1906
|
yTickCount,
|
|
1604
1907
|
...yTickFormat && { yTickFormat },
|
|
1605
1908
|
min,
|
|
1606
|
-
max
|
|
1909
|
+
max,
|
|
1910
|
+
...legendNames && { legendNames }
|
|
1607
1911
|
}
|
|
1608
1912
|
);
|
|
1609
1913
|
}
|
|
@@ -1803,8 +2107,38 @@ var ChartContainer = ({
|
|
|
1803
2107
|
children
|
|
1804
2108
|
}) => {
|
|
1805
2109
|
const { totalWidth, totalHeight, plotWidth, plotHeight, yAxisWidth } = layout;
|
|
1806
|
-
return /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "column", width: totalWidth, height: totalHeight }, showLegend && legendPosition === "top" && /* @__PURE__ */ React6__default.default.createElement(ink.Box, { marginBottom: 1, marginLeft: showYAxis ? yAxisWidth + 1 : 0 }, /* @__PURE__ */ React6__default.default.createElement(Legend, { items: legendItems, position: "horizontal" })), /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "row" }, showYAxis && yAxisConfig && /* @__PURE__ */ React6__default.default.createElement(ink.Box, { marginRight: 1, width: yAxisWidth }, /* @__PURE__ */ React6__default.default.createElement(Axis, { type: "y", length: plotHeight, ...yAxisConfig })), /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "column" }, children), showLegend && legendPosition === "right" && /* @__PURE__ */ React6__default.default.createElement(ink.Box, { marginLeft: 2 }, /* @__PURE__ */ React6__default.default.createElement(Legend, { items: legendItems, position: "vertical" }))), showXAxis && xAxisConfig && /* @__PURE__ */ React6__default.default.createElement(ink.Box, { marginLeft: showYAxis ? yAxisWidth + 1 : 0 }, /* @__PURE__ */ React6__default.default.createElement(Axis, { type: "x", length: plotWidth, ...xAxisConfig })), showLegend && legendPosition === "bottom" && /* @__PURE__ */ React6__default.default.createElement(
|
|
2110
|
+
return /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "column", width: totalWidth, height: totalHeight }, showLegend && legendPosition === "top" && /* @__PURE__ */ React6__default.default.createElement(ink.Box, { marginBottom: 1, marginLeft: showYAxis ? yAxisWidth + 1 : 0 }, /* @__PURE__ */ React6__default.default.createElement(Legend, { items: legendItems, position: "horizontal" })), /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "row" }, showYAxis && yAxisConfig && /* @__PURE__ */ React6__default.default.createElement(ink.Box, { marginRight: 1, width: yAxisWidth }, /* @__PURE__ */ React6__default.default.createElement(Axis, { type: "y", length: plotHeight, ...yAxisConfig })), /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "column" }, children), showLegend && legendPosition === "right" && /* @__PURE__ */ React6__default.default.createElement(ink.Box, { marginLeft: 2 }, /* @__PURE__ */ React6__default.default.createElement(Legend, { items: legendItems, position: "vertical" }))), showXAxis && xAxisConfig && /* @__PURE__ */ React6__default.default.createElement(ink.Box, { marginLeft: showYAxis ? yAxisWidth + 1 : 0 }, /* @__PURE__ */ React6__default.default.createElement(Axis, { type: "x", length: plotWidth, ...xAxisConfig })), showLegend && legendPosition === "bottom" && /* @__PURE__ */ React6__default.default.createElement(
|
|
2111
|
+
ink.Box,
|
|
2112
|
+
{
|
|
2113
|
+
marginTop: 1,
|
|
2114
|
+
marginLeft: showYAxis ? yAxisWidth + 1 : 0,
|
|
2115
|
+
width: plotWidth,
|
|
2116
|
+
justifyContent: "center"
|
|
2117
|
+
},
|
|
2118
|
+
/* @__PURE__ */ React6__default.default.createElement(Legend, { items: legendItems, position: "horizontal" })
|
|
2119
|
+
));
|
|
1807
2120
|
};
|
|
2121
|
+
|
|
2122
|
+
// src/symbols.ts
|
|
2123
|
+
var TREND = { up: "\u25B2", down: "\u25BC", neutral: "\u2500" };
|
|
2124
|
+
var LEGEND = { dot: "\u25CF" };
|
|
2125
|
+
var BAR = { fill: "\u2588", empty: "\u2591" };
|
|
2126
|
+
var HEATMAP = { default: "\u25A0" };
|
|
2127
|
+
var BORDER_ROUNDED = {
|
|
2128
|
+
topLeft: "\u256D",
|
|
2129
|
+
topRight: "\u256E",
|
|
2130
|
+
bottomLeft: "\u2570",
|
|
2131
|
+
bottomRight: "\u256F",
|
|
2132
|
+
horizontal: "\u2500",
|
|
2133
|
+
vertical: "\u2502",
|
|
2134
|
+
bar: "\u258C"
|
|
2135
|
+
};
|
|
2136
|
+
var SPARK_LEVELS = {
|
|
2137
|
+
block: [" ", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588"],
|
|
2138
|
+
braille: ["\u2800", "\u2840", "\u28C0", "\u28C4", "\u28E4", "\u28E6", "\u28F6", "\u28F7", "\u28FF"]
|
|
2139
|
+
};
|
|
2140
|
+
|
|
2141
|
+
// src/components/common/useChartCore.ts
|
|
1808
2142
|
function useChartCore(props) {
|
|
1809
2143
|
const { series: seriesProp, data, seriesName, colors: colorsProp, colorPalette } = props;
|
|
1810
2144
|
const series = React6.useMemo(
|
|
@@ -1820,7 +2154,7 @@ function useChartCore(props) {
|
|
|
1820
2154
|
() => series.map((item, i) => ({
|
|
1821
2155
|
name: item.name,
|
|
1822
2156
|
color: item.color ?? colors[i] ?? "cyan",
|
|
1823
|
-
symbol:
|
|
2157
|
+
symbol: LEGEND.dot
|
|
1824
2158
|
})),
|
|
1825
2159
|
[series, colors]
|
|
1826
2160
|
);
|
|
@@ -1833,17 +2167,9 @@ function useChartCore(props) {
|
|
|
1833
2167
|
legendItems
|
|
1834
2168
|
};
|
|
1835
2169
|
}
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
const { getRenderer, selectBest } = useInkHud();
|
|
1840
|
-
const { renderer: preferredRenderer, rendererChain = defaultChain } = props;
|
|
1841
|
-
return React6.useMemo(() => {
|
|
1842
|
-
if (preferredRenderer) {
|
|
1843
|
-
return getRenderer(preferredRenderer);
|
|
1844
|
-
}
|
|
1845
|
-
return selectBest(rendererChain);
|
|
1846
|
-
}, [preferredRenderer, rendererChain, getRenderer, selectBest]);
|
|
2170
|
+
function useChartRenderer(kind) {
|
|
2171
|
+
const { getRendererFor } = useInkHud();
|
|
2172
|
+
return React6.useMemo(() => getRendererFor(kind), [kind, getRendererFor]);
|
|
1847
2173
|
}
|
|
1848
2174
|
|
|
1849
2175
|
// src/components/LineChart.tsx
|
|
@@ -1860,15 +2186,19 @@ var LineChart = (props) => {
|
|
|
1860
2186
|
yTickCount = 5,
|
|
1861
2187
|
xTickFormat,
|
|
1862
2188
|
yTickFormat,
|
|
1863
|
-
rendererChain = DEFAULT_RENDERER_CHAIN,
|
|
1864
2189
|
xIntegerScale = true,
|
|
1865
2190
|
yIntegerScale = false
|
|
1866
2191
|
} = props;
|
|
1867
2192
|
const renderXAxis = showXAxis ?? showAxis;
|
|
1868
2193
|
const renderYAxis = showYAxis ?? showAxis;
|
|
1869
2194
|
const { series, min, max, maxLength, colors, legendItems } = useChartCore(props);
|
|
1870
|
-
const renderer = useChartRenderer(
|
|
1871
|
-
const layout = useChartLayoutSimple(
|
|
2195
|
+
const renderer = useChartRenderer("line");
|
|
2196
|
+
const layout = useChartLayoutSimple(
|
|
2197
|
+
props,
|
|
2198
|
+
min,
|
|
2199
|
+
max,
|
|
2200
|
+
legendItems.map((it) => it.name)
|
|
2201
|
+
);
|
|
1872
2202
|
const { plotWidth: canvasWidth, plotHeight: canvasHeight } = layout;
|
|
1873
2203
|
const coloredLines = React6.useMemo(
|
|
1874
2204
|
() => renderLineChartCanvas({
|
|
@@ -2040,15 +2370,19 @@ var AreaChart = (props) => {
|
|
|
2040
2370
|
yTickCount = 5,
|
|
2041
2371
|
xTickFormat,
|
|
2042
2372
|
yTickFormat,
|
|
2043
|
-
rendererChain = DEFAULT_RENDERER_CHAIN,
|
|
2044
2373
|
xIntegerScale = true,
|
|
2045
2374
|
yIntegerScale = false
|
|
2046
2375
|
} = props;
|
|
2047
2376
|
const renderXAxis = showXAxis ?? showAxis;
|
|
2048
2377
|
const renderYAxis = showYAxis ?? showAxis;
|
|
2049
2378
|
const { series, min, max, maxLength, colors, legendItems } = useChartCore(props);
|
|
2050
|
-
const renderer = useChartRenderer(
|
|
2051
|
-
const layout = useChartLayoutSimple(
|
|
2379
|
+
const renderer = useChartRenderer("area");
|
|
2380
|
+
const layout = useChartLayoutSimple(
|
|
2381
|
+
props,
|
|
2382
|
+
min,
|
|
2383
|
+
max,
|
|
2384
|
+
legendItems.map((it) => it.name)
|
|
2385
|
+
);
|
|
2052
2386
|
const { plotWidth: canvasWidth, plotHeight: canvasHeight } = layout;
|
|
2053
2387
|
const coloredLines = React6.useMemo(
|
|
2054
2388
|
() => renderAreaChartCanvas({
|
|
@@ -2264,15 +2598,19 @@ var BarChart = (props) => {
|
|
|
2264
2598
|
yTickCount = 5,
|
|
2265
2599
|
xTickFormat,
|
|
2266
2600
|
yTickFormat,
|
|
2267
|
-
rendererChain = BAR_CHART_RENDERER_CHAIN,
|
|
2268
2601
|
xIntegerScale,
|
|
2269
2602
|
yIntegerScale
|
|
2270
2603
|
} = props;
|
|
2271
2604
|
const renderXAxis = showXAxis ?? showAxis;
|
|
2272
2605
|
const renderYAxis = showYAxis ?? showAxis;
|
|
2273
2606
|
const { series, min, max, maxLength, colors, legendItems } = useChartCore(props);
|
|
2274
|
-
const renderer = useChartRenderer(
|
|
2275
|
-
const layout = useChartLayoutSimple(
|
|
2607
|
+
const renderer = useChartRenderer("bar");
|
|
2608
|
+
const layout = useChartLayoutSimple(
|
|
2609
|
+
props,
|
|
2610
|
+
min,
|
|
2611
|
+
max,
|
|
2612
|
+
legendItems.map((it) => it.name)
|
|
2613
|
+
);
|
|
2276
2614
|
const { plotWidth: canvasWidth, plotHeight: canvasHeight } = layout;
|
|
2277
2615
|
const coloredLines = React6.useMemo(() => {
|
|
2278
2616
|
if (series.length === 0 || maxLength === 0) return [];
|
|
@@ -2353,15 +2691,17 @@ function resolveDataItems(data, labels) {
|
|
|
2353
2691
|
}
|
|
2354
2692
|
var TWO_PI = Math.PI * 2;
|
|
2355
2693
|
var START_ANGLE = -Math.PI / 2;
|
|
2356
|
-
function resolveRadius(
|
|
2357
|
-
const
|
|
2358
|
-
const
|
|
2359
|
-
const
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
);
|
|
2363
|
-
const
|
|
2364
|
-
|
|
2694
|
+
function resolveRadius(canvasWChars, canvasHChars, renderer, customRadius, aspectRatioCorrection) {
|
|
2695
|
+
const { pixelWidth, pixelHeight } = getPixelDimensions(renderer, canvasWChars, canvasHChars);
|
|
2696
|
+
const { vertical } = renderer.getResolution();
|
|
2697
|
+
const centerX = (pixelWidth - 1) / 2;
|
|
2698
|
+
const centerY = (pixelHeight - 1) / 2;
|
|
2699
|
+
const maxRadiusByWidth = Math.min(centerX, pixelWidth - 1 - centerX);
|
|
2700
|
+
const verticalInsetPixels = Math.ceil(vertical / 2);
|
|
2701
|
+
const maxRadiusByHeight = Math.max(0, Math.min(centerY, pixelHeight - 1 - centerY) - verticalInsetPixels) * aspectRatioCorrection;
|
|
2702
|
+
const maxRadius = Math.max(0, Math.min(maxRadiusByWidth, maxRadiusByHeight));
|
|
2703
|
+
const radius = customRadius !== void 0 ? Math.min(Math.max(0, customRadius), maxRadius) : maxRadius;
|
|
2704
|
+
return { pixelWidth, pixelHeight, centerX, centerY, radius };
|
|
2365
2705
|
}
|
|
2366
2706
|
function buildAngleStops(data, total) {
|
|
2367
2707
|
if (total <= 0) {
|
|
@@ -2401,34 +2741,35 @@ var PieChart = ({
|
|
|
2401
2741
|
showLegend = true,
|
|
2402
2742
|
legendPosition = "right",
|
|
2403
2743
|
colors,
|
|
2404
|
-
colorPalette
|
|
2405
|
-
renderer: preferredRenderer,
|
|
2406
|
-
rendererChain = ["braille", "block", "ascii"],
|
|
2407
|
-
heightOffset = 0,
|
|
2408
|
-
widthOffset = 0
|
|
2744
|
+
colorPalette
|
|
2409
2745
|
}) => {
|
|
2410
2746
|
const data = React6.useMemo(() => resolveDataItems(dataProp, labels), [dataProp, labels]);
|
|
2747
|
+
const percentagesEarly = React6.useMemo(() => {
|
|
2748
|
+
const sum = data.reduce((acc, item) => acc + item.value, 0);
|
|
2749
|
+
return data.map((item) => sum > 0 ? item.value / sum * 100 : 0);
|
|
2750
|
+
}, [data]);
|
|
2751
|
+
const legendNamesForLayout = React6.useMemo(() => {
|
|
2752
|
+
if (!showLegend) return void 0;
|
|
2753
|
+
return data.map(
|
|
2754
|
+
(item, i) => showLabels ? `${item.name} (${percentagesEarly[i]?.toFixed(1)}%)` : item.name
|
|
2755
|
+
);
|
|
2756
|
+
}, [data, showLegend, showLabels, percentagesEarly]);
|
|
2411
2757
|
const layout = useChartLayoutSimple(
|
|
2412
2758
|
{
|
|
2413
2759
|
...width !== void 0 && { width },
|
|
2414
2760
|
...height !== void 0 && { height },
|
|
2415
2761
|
showAxis: false,
|
|
2416
2762
|
showLegend,
|
|
2417
|
-
legendPosition
|
|
2418
|
-
widthOffset,
|
|
2419
|
-
heightOffset
|
|
2763
|
+
legendPosition
|
|
2420
2764
|
},
|
|
2421
2765
|
0,
|
|
2422
|
-
0
|
|
2766
|
+
0,
|
|
2767
|
+
legendNamesForLayout
|
|
2423
2768
|
);
|
|
2424
|
-
const { totalWidth, plotWidth:
|
|
2425
|
-
const
|
|
2426
|
-
const
|
|
2427
|
-
|
|
2428
|
-
return getRenderer(preferredRenderer);
|
|
2429
|
-
}
|
|
2430
|
-
return selectBest(rendererChain);
|
|
2431
|
-
}, [preferredRenderer, rendererChain, getRenderer, selectBest]);
|
|
2769
|
+
const { totalWidth, plotWidth: plotW, plotHeight: plotH } = layout;
|
|
2770
|
+
const canvasHeight = Math.max(1, Math.min(plotH, Math.floor(plotW / 2)));
|
|
2771
|
+
const canvasWidth = canvasHeight * 2;
|
|
2772
|
+
const renderer = useChartRenderer("pie");
|
|
2432
2773
|
const ratio = React6.useMemo(() => {
|
|
2433
2774
|
if (aspectRatio !== void 0) return aspectRatio;
|
|
2434
2775
|
const resolution = renderer.getResolution();
|
|
@@ -2443,22 +2784,20 @@ var PieChart = ({
|
|
|
2443
2784
|
}
|
|
2444
2785
|
return assignColors(data.length, colorPalette);
|
|
2445
2786
|
}, [data.length, colors, colorPalette]);
|
|
2446
|
-
const
|
|
2447
|
-
|
|
2448
|
-
const pcts = data.map((item) => sum > 0 ? item.value / sum * 100 : 0);
|
|
2449
|
-
return { total: sum, percentages: pcts };
|
|
2450
|
-
}, [data]);
|
|
2787
|
+
const total = React6.useMemo(() => data.reduce((acc, item) => acc + item.value, 0), [data]);
|
|
2788
|
+
const percentages = percentagesEarly;
|
|
2451
2789
|
const coloredLines = React6.useMemo(() => {
|
|
2452
2790
|
if (data.length === 0 || total <= 0) {
|
|
2453
2791
|
return [];
|
|
2454
2792
|
}
|
|
2455
|
-
const { pixelWidth, pixelHeight } = getPixelDimensions(renderer, canvasWidth, canvasHeight);
|
|
2456
|
-
const canvas = renderer.createCanvas(pixelWidth, pixelHeight);
|
|
2457
2793
|
const {
|
|
2794
|
+
pixelWidth,
|
|
2795
|
+
pixelHeight,
|
|
2458
2796
|
centerX,
|
|
2459
2797
|
centerY,
|
|
2460
2798
|
radius: outerRadius
|
|
2461
|
-
} = resolveRadius(
|
|
2799
|
+
} = resolveRadius(canvasWidth, canvasHeight, renderer, customRadius, ratio);
|
|
2800
|
+
const canvas = renderer.createCanvas(pixelWidth, pixelHeight);
|
|
2462
2801
|
const innerRadius = outerRadius * donutRatio;
|
|
2463
2802
|
const angleStops = buildAngleStops(data, total);
|
|
2464
2803
|
for (let y = 0; y < pixelHeight; y++) {
|
|
@@ -2495,7 +2834,7 @@ var PieChart = ({
|
|
|
2495
2834
|
return data.map((item, i) => ({
|
|
2496
2835
|
name: showLabels ? `${item.name} (${percentages[i]?.toFixed(1)}%)` : item.name,
|
|
2497
2836
|
color: item.color ?? itemColors[i] ?? "cyan",
|
|
2498
|
-
symbol:
|
|
2837
|
+
symbol: LEGEND.dot
|
|
2499
2838
|
}));
|
|
2500
2839
|
}, [data, itemColors, showLabels, percentages]);
|
|
2501
2840
|
if (coloredLines.length === 0) {
|
|
@@ -2509,40 +2848,203 @@ var PieChart = ({
|
|
|
2509
2848
|
...segment.backgroundColor ? { backgroundColor: segment.backgroundColor } : {}
|
|
2510
2849
|
},
|
|
2511
2850
|
segment.text
|
|
2512
|
-
))))), showLegend && legendPosition === "right" && /* @__PURE__ */ React6__default.default.createElement(ink.Box, { marginLeft: 2 }, /* @__PURE__ */ React6__default.default.createElement(Legend, { items: legendItems, position: "vertical" }))), showLegend && legendPosition === "bottom" && /* @__PURE__ */ React6__default.default.createElement(ink.Box, { marginTop: 1 }, /* @__PURE__ */ React6__default.default.createElement(Legend, { items: legendItems, position: "horizontal" })));
|
|
2851
|
+
))))), showLegend && legendPosition === "right" && /* @__PURE__ */ React6__default.default.createElement(ink.Box, { marginLeft: 2 }, /* @__PURE__ */ React6__default.default.createElement(Legend, { items: legendItems, position: "vertical" }))), showLegend && legendPosition === "bottom" && /* @__PURE__ */ React6__default.default.createElement(ink.Box, { marginTop: 1, width: totalWidth, justifyContent: "center" }, /* @__PURE__ */ React6__default.default.createElement(Legend, { items: legendItems, position: "horizontal" })));
|
|
2513
2852
|
};
|
|
2514
|
-
var
|
|
2515
|
-
|
|
2516
|
-
|
|
2853
|
+
var CRC_TABLE = (() => {
|
|
2854
|
+
const table = new Uint32Array(256);
|
|
2855
|
+
for (let i = 0; i < 256; i++) {
|
|
2856
|
+
let c = i;
|
|
2857
|
+
for (let k = 0; k < 8; k++) {
|
|
2858
|
+
c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
|
|
2859
|
+
}
|
|
2860
|
+
table[i] = c;
|
|
2861
|
+
}
|
|
2862
|
+
return table;
|
|
2863
|
+
})();
|
|
2864
|
+
function crc32(buf) {
|
|
2865
|
+
let crc = 4294967295;
|
|
2866
|
+
for (let i = 0; i < buf.length; i++) {
|
|
2867
|
+
crc = (CRC_TABLE[(crc ^ buf[i]) & 255] ?? 0) ^ crc >>> 8;
|
|
2868
|
+
}
|
|
2869
|
+
return (crc ^ 4294967295) >>> 0;
|
|
2870
|
+
}
|
|
2871
|
+
function chunk(type, data) {
|
|
2872
|
+
const len = Buffer.alloc(4);
|
|
2873
|
+
len.writeUInt32BE(data.length, 0);
|
|
2874
|
+
const typeBytes = Buffer.from(type, "ascii");
|
|
2875
|
+
const crcBytes = Buffer.alloc(4);
|
|
2876
|
+
crcBytes.writeUInt32BE(crc32(Buffer.concat([typeBytes, data])), 0);
|
|
2877
|
+
return Buffer.concat([len, typeBytes, data, crcBytes]);
|
|
2878
|
+
}
|
|
2879
|
+
function createRgbPng(pixels) {
|
|
2880
|
+
const height = pixels.length;
|
|
2881
|
+
const width = pixels[0]?.length ?? 0;
|
|
2882
|
+
const ihdrData = Buffer.alloc(13);
|
|
2883
|
+
ihdrData.writeUInt32BE(width, 0);
|
|
2884
|
+
ihdrData.writeUInt32BE(height, 4);
|
|
2885
|
+
ihdrData[8] = 8;
|
|
2886
|
+
ihdrData[9] = 2;
|
|
2887
|
+
const rawRows = [];
|
|
2888
|
+
for (const row of pixels) {
|
|
2889
|
+
const rowBuf = Buffer.alloc(1 + width * 3);
|
|
2890
|
+
rowBuf[0] = 0;
|
|
2891
|
+
let offset = 1;
|
|
2892
|
+
for (const [r, g, b] of row) {
|
|
2893
|
+
rowBuf[offset++] = r;
|
|
2894
|
+
rowBuf[offset++] = g;
|
|
2895
|
+
rowBuf[offset++] = b;
|
|
2896
|
+
}
|
|
2897
|
+
rawRows.push(rowBuf);
|
|
2898
|
+
}
|
|
2899
|
+
const compressed = zlib.deflateSync(Buffer.concat(rawRows), { level: 1 });
|
|
2900
|
+
const PNG_SIGNATURE = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
|
|
2901
|
+
return Buffer.concat([
|
|
2902
|
+
PNG_SIGNATURE,
|
|
2903
|
+
chunk("IHDR", ihdrData),
|
|
2904
|
+
chunk("IDAT", compressed),
|
|
2905
|
+
chunk("IEND", Buffer.alloc(0))
|
|
2906
|
+
]);
|
|
2907
|
+
}
|
|
2908
|
+
function hexToRgb(hex) {
|
|
2909
|
+
const h = hex.startsWith("#") ? hex.slice(1) : hex;
|
|
2910
|
+
const n = Number.parseInt(h, 16);
|
|
2911
|
+
return [n >> 16 & 255, n >> 8 & 255, n & 255];
|
|
2912
|
+
}
|
|
2913
|
+
|
|
2914
|
+
// src/render/image/drawing.ts
|
|
2915
|
+
function clamp2(v, lo, hi) {
|
|
2916
|
+
return v < lo ? lo : v > hi ? hi : v;
|
|
2917
|
+
}
|
|
2918
|
+
function darken(rgb, factor) {
|
|
2919
|
+
return [Math.round(rgb[0] * factor), Math.round(rgb[1] * factor), Math.round(rgb[2] * factor)];
|
|
2920
|
+
}
|
|
2921
|
+
function gradientColorFn(colors) {
|
|
2922
|
+
if (colors.length === 0) return () => [128, 128, 128];
|
|
2923
|
+
if (colors.length === 1) {
|
|
2924
|
+
const rgb = hexToRgb(colors[0] ?? "");
|
|
2925
|
+
return () => rgb;
|
|
2926
|
+
}
|
|
2927
|
+
const g = tinygradient__default.default(colors);
|
|
2928
|
+
const palette = g.rgb(256).map((c) => hexToRgb(`#${c.toHex()}`));
|
|
2929
|
+
return (normalized) => {
|
|
2930
|
+
const idx = clamp2(Math.floor(normalized * 256), 0, 255);
|
|
2931
|
+
return palette[idx] ?? [128, 128, 128];
|
|
2932
|
+
};
|
|
2933
|
+
}
|
|
2934
|
+
function buildSparklinePixelGrid(data, widthPx, heightPx, min, max, colorFn, bgColor = [10, 10, 14]) {
|
|
2935
|
+
const grid = Array.from(
|
|
2936
|
+
{ length: heightPx },
|
|
2937
|
+
() => Array.from({ length: widthPx }, () => [...bgColor])
|
|
2938
|
+
);
|
|
2939
|
+
if (data.length === 0 || widthPx === 0 || heightPx === 0) return grid;
|
|
2940
|
+
const range = max === min ? 1 : max - min;
|
|
2941
|
+
for (let x = 0; x < widthPx; x++) {
|
|
2942
|
+
const t = data.length === 1 ? 0 : x / Math.max(widthPx - 1, 1) * (data.length - 1);
|
|
2943
|
+
const baseIdx = clamp2(Math.floor(t), 0, data.length - 2);
|
|
2944
|
+
const frac = data.length === 1 ? 0 : t - baseIdx;
|
|
2945
|
+
const raw = data.length === 1 ? data[0] ?? 0 : (data[baseIdx] ?? 0) * (1 - frac) + (data[baseIdx + 1] ?? 0) * frac;
|
|
2946
|
+
const normalized = clamp2((raw - min) / range, 0, 1);
|
|
2947
|
+
const yLine = Math.round((1 - normalized) * (heightPx - 1));
|
|
2948
|
+
const lineRgb = colorFn(normalized);
|
|
2949
|
+
const fillRgb = darken(lineRgb, 0.28);
|
|
2950
|
+
for (let y = yLine + 2; y < heightPx; y++) {
|
|
2951
|
+
const row = grid[y];
|
|
2952
|
+
if (row !== void 0) row[x] = fillRgb;
|
|
2953
|
+
}
|
|
2954
|
+
if (yLine + 1 < heightPx) {
|
|
2955
|
+
const row = grid[yLine + 1];
|
|
2956
|
+
if (row !== void 0) row[x] = darken(lineRgb, 0.55);
|
|
2957
|
+
}
|
|
2958
|
+
const lineRow = grid[yLine];
|
|
2959
|
+
if (lineRow !== void 0) lineRow[x] = lineRgb;
|
|
2960
|
+
if (yLine - 1 >= 0) {
|
|
2961
|
+
const capRow = grid[yLine - 1];
|
|
2962
|
+
if (capRow !== void 0) capRow[x] = darken(lineRgb, 0.75);
|
|
2963
|
+
}
|
|
2964
|
+
}
|
|
2965
|
+
return grid;
|
|
2966
|
+
}
|
|
2967
|
+
|
|
2968
|
+
// src/components/Sparkline.tsx
|
|
2517
2969
|
var Sparkline = ({
|
|
2518
2970
|
data,
|
|
2519
2971
|
width: propsWidth,
|
|
2520
2972
|
min: userMin,
|
|
2521
2973
|
max: userMax,
|
|
2522
2974
|
color,
|
|
2523
|
-
variant = "block"
|
|
2975
|
+
variant = "block",
|
|
2976
|
+
mode = "auto",
|
|
2977
|
+
height = 1,
|
|
2978
|
+
colors,
|
|
2979
|
+
cellPx = 8
|
|
2524
2980
|
}) => {
|
|
2525
2981
|
const gridContext = React6.useContext(GridItemContext);
|
|
2982
|
+
const theme = useTheme();
|
|
2526
2983
|
const effectiveWidth = propsWidth ?? gridContext?.width;
|
|
2527
|
-
const
|
|
2528
|
-
if (!data || data.length === 0) return
|
|
2529
|
-
let
|
|
2984
|
+
const { processedData, min, max } = React6.useMemo(() => {
|
|
2985
|
+
if (!data || data.length === 0) return { processedData: [], min: 0, max: 1 };
|
|
2986
|
+
let processed = data;
|
|
2530
2987
|
if (effectiveWidth && data.length > effectiveWidth) {
|
|
2531
|
-
|
|
2532
|
-
}
|
|
2533
|
-
const
|
|
2534
|
-
let
|
|
2535
|
-
if (
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2988
|
+
processed = lttb(data, effectiveWidth);
|
|
2989
|
+
}
|
|
2990
|
+
const lo = userMin ?? Math.min(...processed);
|
|
2991
|
+
let hi = userMax ?? Math.max(...processed);
|
|
2992
|
+
if (hi === lo) hi = lo + 1;
|
|
2993
|
+
return { processedData: processed, min: lo, max: hi };
|
|
2994
|
+
}, [data, effectiveWidth, userMin, userMax]);
|
|
2995
|
+
const charCols = effectiveWidth ?? processedData.length;
|
|
2996
|
+
const charRows = height;
|
|
2997
|
+
const pngBuf = React6.useMemo(() => {
|
|
2998
|
+
if (mode === "character" || charCols === 0 || processedData.length === 0) return null;
|
|
2999
|
+
const effectiveColors = colors ?? (color ? [color] : theme.heatmapGradient);
|
|
3000
|
+
const colorFn = gradientColorFn(effectiveColors);
|
|
3001
|
+
const pixelGrid = buildSparklinePixelGrid(
|
|
3002
|
+
processedData,
|
|
3003
|
+
charCols * cellPx,
|
|
3004
|
+
charRows * cellPx,
|
|
3005
|
+
min,
|
|
3006
|
+
max,
|
|
3007
|
+
colorFn
|
|
3008
|
+
);
|
|
3009
|
+
return createRgbPng(pixelGrid);
|
|
3010
|
+
}, [
|
|
3011
|
+
mode,
|
|
3012
|
+
charCols,
|
|
3013
|
+
charRows,
|
|
3014
|
+
cellPx,
|
|
3015
|
+
colors,
|
|
3016
|
+
color,
|
|
3017
|
+
theme.heatmapGradient,
|
|
3018
|
+
processedData,
|
|
3019
|
+
min,
|
|
3020
|
+
max
|
|
3021
|
+
]);
|
|
3022
|
+
const { kittyLines, iterm2Cols } = useImageProtocol({
|
|
3023
|
+
mode,
|
|
3024
|
+
charCols,
|
|
3025
|
+
charRows,
|
|
3026
|
+
pngBuf,
|
|
3027
|
+
trailingSpace: false
|
|
3028
|
+
});
|
|
3029
|
+
if (kittyLines !== null) {
|
|
3030
|
+
return /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "column" }, kittyLines.map((line, i) => /* @__PURE__ */ React6__default.default.createElement(ink.Text, { key: i }, line)));
|
|
3031
|
+
}
|
|
3032
|
+
if (iterm2Cols !== null) {
|
|
3033
|
+
return /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "column" }, Array.from({ length: charRows }, (_, i) => /* @__PURE__ */ React6__default.default.createElement(ink.Text, { key: i }, " ".repeat(iterm2Cols))));
|
|
3034
|
+
}
|
|
3035
|
+
if (processedData.length === 0) {
|
|
3036
|
+
return /* @__PURE__ */ React6__default.default.createElement(ink.Text, null, "");
|
|
3037
|
+
}
|
|
3038
|
+
const levels = SPARK_LEVELS[variant];
|
|
3039
|
+
const outputCols = charCols > 0 ? charCols : processedData.length;
|
|
3040
|
+
const text = Array.from({ length: outputCols }, (_, i) => {
|
|
3041
|
+
const dataIndex = Math.floor(i * processedData.length / outputCols);
|
|
3042
|
+
const v = processedData[dataIndex] ?? 0;
|
|
3043
|
+
const value = Math.max(min, Math.min(max, v));
|
|
3044
|
+
const normalized = (value - min) / (max - min);
|
|
3045
|
+
const index = Math.round(normalized * (levels.length - 1));
|
|
3046
|
+
return levels[index];
|
|
3047
|
+
}).join("");
|
|
2546
3048
|
return /* @__PURE__ */ React6__default.default.createElement(ink.Text, { ...color ? { color } : {} }, text);
|
|
2547
3049
|
};
|
|
2548
3050
|
var Panel = ({
|
|
@@ -2591,10 +3093,6 @@ var Panel = ({
|
|
|
2591
3093
|
/* @__PURE__ */ React6__default.default.createElement(ink.Text, { bold: true, color: borderColor || "white" }, " ", title, " ")
|
|
2592
3094
|
), /* @__PURE__ */ React6__default.default.createElement(ink.Box, { padding, flexDirection: "column", flexGrow: 1 }, children)));
|
|
2593
3095
|
};
|
|
2594
|
-
var CHAR_SETS = {
|
|
2595
|
-
unicode: { fill: "\u2588", empty: "\u2591" },
|
|
2596
|
-
ascii: { fill: "#", empty: "-" }
|
|
2597
|
-
};
|
|
2598
3096
|
var Gauge = ({
|
|
2599
3097
|
value,
|
|
2600
3098
|
min = 0,
|
|
@@ -2603,7 +3101,6 @@ var Gauge = ({
|
|
|
2603
3101
|
color,
|
|
2604
3102
|
emptyColor,
|
|
2605
3103
|
showPercent = true,
|
|
2606
|
-
variant = "unicode",
|
|
2607
3104
|
fillChar,
|
|
2608
3105
|
emptyChar,
|
|
2609
3106
|
label
|
|
@@ -2611,9 +3108,8 @@ var Gauge = ({
|
|
|
2611
3108
|
const theme = useTheme();
|
|
2612
3109
|
const effectiveColor = color ?? theme.semantic.success;
|
|
2613
3110
|
const effectiveEmptyColor = emptyColor ?? theme.semantic.muted;
|
|
2614
|
-
const
|
|
2615
|
-
const
|
|
2616
|
-
const effectiveEmptyChar = emptyChar ?? charSet.empty;
|
|
3111
|
+
const effectiveFillChar = fillChar ?? BAR.fill;
|
|
3112
|
+
const effectiveEmptyChar = emptyChar ?? BAR.empty;
|
|
2617
3113
|
const clampedValue = Math.min(Math.max(value, min), max);
|
|
2618
3114
|
const range = max - min;
|
|
2619
3115
|
const ratio = range === 0 ? 0 : (clampedValue - min) / range;
|
|
@@ -2660,35 +3156,31 @@ var BRAILLE_FONT = {
|
|
|
2660
3156
|
"+": ["\u2800\u2800", "\u2810\u2812", "\u2800\u2800"],
|
|
2661
3157
|
"-": ["\u2800\u2800", "\u2810\u2812", "\u2800\u2800"]
|
|
2662
3158
|
};
|
|
2663
|
-
var ASCII_FONT = {
|
|
2664
|
-
"0": ["+~+", "| |", "+~+"],
|
|
2665
|
-
"1": [" | ", " | ", " | "],
|
|
2666
|
-
"2": ["~~+", "+-+", "+~~"],
|
|
2667
|
-
"3": ["~~+", " ~+", "~~+"],
|
|
2668
|
-
"4": ["+ +", "+-+", " +"],
|
|
2669
|
-
"5": ["+~~", "+~+", "~~+"],
|
|
2670
|
-
"6": ["+~~", "+~+", "+~+"],
|
|
2671
|
-
"7": ["~~+", " +", " +"],
|
|
2672
|
-
"8": ["+~+", "+~+", "+~+"],
|
|
2673
|
-
"9": ["+~+", "+~+", " +"],
|
|
2674
|
-
".": [" ", " ", " . "],
|
|
2675
|
-
",": [" ", " ", " , "],
|
|
2676
|
-
"%": ["* ", " * ", " *"],
|
|
2677
|
-
"+": [" ", " + ", " "],
|
|
2678
|
-
"-": [" ", " - ", " "]
|
|
2679
|
-
};
|
|
2680
3159
|
var FONTS = {
|
|
2681
3160
|
block: BLOCK_FONT,
|
|
2682
|
-
braille: BRAILLE_FONT
|
|
2683
|
-
ascii: ASCII_FONT
|
|
3161
|
+
braille: BRAILLE_FONT
|
|
2684
3162
|
};
|
|
2685
3163
|
var UNKNOWN = {
|
|
2686
3164
|
block: [" ", " ? ", " "],
|
|
2687
|
-
braille: ["\u2800\u2800", "\u2800\u2826", "\u2800\u2800"]
|
|
2688
|
-
ascii: [" ", " ? ", " "]
|
|
3165
|
+
braille: ["\u2800\u2800", "\u2800\u2826", "\u2800\u2800"]
|
|
2689
3166
|
};
|
|
3167
|
+
var warnedChars = /* @__PURE__ */ new Set();
|
|
3168
|
+
function warnUnsupportedChar(char, style) {
|
|
3169
|
+
if (process.env.NODE_ENV === "production") return;
|
|
3170
|
+
const key = `${style}:${char}`;
|
|
3171
|
+
if (warnedChars.has(key)) return;
|
|
3172
|
+
warnedChars.add(key);
|
|
3173
|
+
console.warn(
|
|
3174
|
+
`[ink-hud] BigNumber: unsupported char "${char}" (style="${style}") rendered as "?". Use the prefix/suffix props for units or symbols (e.g. <BigNumber value="49" suffix="ms" />).`
|
|
3175
|
+
);
|
|
3176
|
+
}
|
|
2690
3177
|
function getBigChar(char, style = "block") {
|
|
2691
|
-
|
|
3178
|
+
const glyphs = FONTS[style][char];
|
|
3179
|
+
if (!glyphs) {
|
|
3180
|
+
warnUnsupportedChar(char, style);
|
|
3181
|
+
return UNKNOWN[style];
|
|
3182
|
+
}
|
|
3183
|
+
return glyphs;
|
|
2692
3184
|
}
|
|
2693
3185
|
function renderBigString(text, style = "block") {
|
|
2694
3186
|
const rows = ["", "", ""];
|
|
@@ -2702,42 +3194,34 @@ function renderBigString(text, style = "block") {
|
|
|
2702
3194
|
}
|
|
2703
3195
|
|
|
2704
3196
|
// src/components/BigNumber.tsx
|
|
2705
|
-
var TREND_ARROWS = {
|
|
2706
|
-
unicode: { up: "\u25B2", down: "\u25BC", neutral: "\u2500" },
|
|
2707
|
-
ascii: { up: "^", down: "v", neutral: "-" }
|
|
2708
|
-
};
|
|
2709
3197
|
var BigNumber = ({
|
|
2710
3198
|
value,
|
|
3199
|
+
prefix,
|
|
3200
|
+
suffix,
|
|
2711
3201
|
label,
|
|
2712
3202
|
color = "white",
|
|
2713
3203
|
trendDirection,
|
|
2714
3204
|
trendLabel,
|
|
2715
|
-
variant = "unicode",
|
|
2716
3205
|
fontStyle = "block",
|
|
2717
3206
|
align = "center"
|
|
2718
3207
|
}) => {
|
|
2719
3208
|
const bigLines = React6.useMemo(() => renderBigString(String(value), fontStyle), [value, fontStyle]);
|
|
2720
3209
|
const theme = useTheme();
|
|
2721
|
-
const arrows = TREND_ARROWS[variant];
|
|
2722
3210
|
let trendColor = theme.semantic.muted;
|
|
2723
3211
|
let trendArrow = "";
|
|
2724
3212
|
if (trendDirection === "up") {
|
|
2725
3213
|
trendColor = theme.semantic.success;
|
|
2726
|
-
trendArrow =
|
|
3214
|
+
trendArrow = TREND.up;
|
|
2727
3215
|
} else if (trendDirection === "down") {
|
|
2728
3216
|
trendColor = theme.semantic.error;
|
|
2729
|
-
trendArrow =
|
|
3217
|
+
trendArrow = TREND.down;
|
|
2730
3218
|
} else if (trendDirection === "neutral") {
|
|
2731
|
-
trendArrow =
|
|
3219
|
+
trendArrow = TREND.neutral;
|
|
2732
3220
|
}
|
|
2733
3221
|
const alignItems = align === "center" ? "center" : align === "right" ? "flex-end" : "flex-start";
|
|
2734
|
-
return /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "column", alignItems }, /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "
|
|
2735
|
-
};
|
|
2736
|
-
var CHAR_SETS2 = {
|
|
2737
|
-
unicode: "\u25A0",
|
|
2738
|
-
ascii: "#"
|
|
3222
|
+
return /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "column", alignItems }, /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "row", alignItems: "flex-end", marginBottom: 1 }, prefix && /* @__PURE__ */ React6__default.default.createElement(ink.Box, { marginRight: 1 }, /* @__PURE__ */ React6__default.default.createElement(ink.Text, { color }, prefix)), /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "column" }, bigLines.map((line, i) => /* @__PURE__ */ React6__default.default.createElement(ink.Text, { key: i, color }, line))), suffix && /* @__PURE__ */ React6__default.default.createElement(ink.Box, { marginLeft: 1 }, /* @__PURE__ */ React6__default.default.createElement(ink.Text, { color }, suffix))), /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "row", gap: 1 }, label && /* @__PURE__ */ React6__default.default.createElement(ink.Text, { color: theme.semantic.textSecondary }, label), (trendLabel || trendArrow) && /* @__PURE__ */ React6__default.default.createElement(ink.Text, { color: trendColor }, trendArrow, " ", trendLabel)));
|
|
2739
3223
|
};
|
|
2740
|
-
|
|
3224
|
+
function findMinMax(data) {
|
|
2741
3225
|
let minVal = Number.POSITIVE_INFINITY;
|
|
2742
3226
|
let maxVal = Number.NEGATIVE_INFINITY;
|
|
2743
3227
|
for (const row of data) {
|
|
@@ -2747,21 +3231,71 @@ var findMinMax = (data) => {
|
|
|
2747
3231
|
}
|
|
2748
3232
|
}
|
|
2749
3233
|
return { min: minVal, max: maxVal };
|
|
2750
|
-
}
|
|
2751
|
-
|
|
3234
|
+
}
|
|
3235
|
+
function gradientRgbPalette(colors, steps) {
|
|
3236
|
+
if (steps === 0) return [];
|
|
3237
|
+
if (colors.length === 0) return Array(steps).fill([128, 128, 128]);
|
|
3238
|
+
if (colors.length === 1) {
|
|
3239
|
+
const rgb = hexToRgb(colors[0] ?? "#808080");
|
|
3240
|
+
return Array(steps).fill(rgb);
|
|
3241
|
+
}
|
|
3242
|
+
const g = tinygradient__default.default(colors);
|
|
3243
|
+
return g.rgb(steps).map((c) => hexToRgb(`#${c.toHex()}`));
|
|
3244
|
+
}
|
|
3245
|
+
var Heatmap = ({
|
|
3246
|
+
data,
|
|
3247
|
+
colors,
|
|
3248
|
+
char,
|
|
3249
|
+
mode = "auto",
|
|
3250
|
+
cellPx = 8
|
|
3251
|
+
}) => {
|
|
2752
3252
|
const theme = useTheme();
|
|
2753
3253
|
const effectiveColors = colors ?? theme.heatmapGradient;
|
|
2754
|
-
const effectiveChar = char ??
|
|
3254
|
+
const effectiveChar = char ?? HEATMAP.default;
|
|
3255
|
+
const dataRows = data.length;
|
|
3256
|
+
const dataCols = data[0]?.length ?? 0;
|
|
2755
3257
|
const { min, max } = React6.useMemo(() => {
|
|
2756
3258
|
const { min: minVal, max: maxVal } = findMinMax(data);
|
|
2757
3259
|
if (minVal === Number.POSITIVE_INFINITY) return { min: 0, max: 0 };
|
|
2758
3260
|
return { min: minVal, max: maxVal > minVal ? maxVal : minVal + 1 };
|
|
2759
3261
|
}, [data]);
|
|
2760
3262
|
const steps = effectiveColors.length;
|
|
2761
|
-
const
|
|
2762
|
-
(
|
|
2763
|
-
|
|
2764
|
-
|
|
3263
|
+
const pngBuf = React6.useMemo(() => {
|
|
3264
|
+
if (mode === "character" || !dataRows || !dataCols) return null;
|
|
3265
|
+
const palette = gradientRgbPalette(effectiveColors, steps);
|
|
3266
|
+
const pixelGrid = [];
|
|
3267
|
+
const GAP = [16, 16, 16];
|
|
3268
|
+
for (let row = 0; row < dataRows; row++) {
|
|
3269
|
+
for (let py = 0; py < cellPx; py++) {
|
|
3270
|
+
const pixelRow = [];
|
|
3271
|
+
for (let col = 0; col < dataCols; col++) {
|
|
3272
|
+
const val = data[row]?.[col] ?? 0;
|
|
3273
|
+
const normalized = max === min ? 0 : (val - min) / (max - min);
|
|
3274
|
+
let si = Math.floor(normalized * steps);
|
|
3275
|
+
if (si >= steps) si = steps - 1;
|
|
3276
|
+
const rgb = palette[si] ?? GAP;
|
|
3277
|
+
for (let px = 0; px < cellPx; px++) pixelRow.push(rgb);
|
|
3278
|
+
for (let px = 0; px < cellPx; px++) pixelRow.push(GAP);
|
|
3279
|
+
}
|
|
3280
|
+
pixelGrid.push(pixelRow);
|
|
3281
|
+
}
|
|
3282
|
+
}
|
|
3283
|
+
return createRgbPng(pixelGrid);
|
|
3284
|
+
}, [data, min, max, steps, effectiveColors, cellPx, mode, dataRows, dataCols]);
|
|
3285
|
+
const { kittyLines, iterm2Cols } = useImageProtocol({
|
|
3286
|
+
mode,
|
|
3287
|
+
charCols: dataCols,
|
|
3288
|
+
charRows: dataRows,
|
|
3289
|
+
pngBuf,
|
|
3290
|
+
trailingSpace: true
|
|
3291
|
+
});
|
|
3292
|
+
if (kittyLines !== null) {
|
|
3293
|
+
return /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "column" }, kittyLines.map((line, i) => /* @__PURE__ */ React6__default.default.createElement(ink.Text, { key: i }, line)));
|
|
3294
|
+
}
|
|
3295
|
+
if (iterm2Cols !== null) {
|
|
3296
|
+
return /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "column" }, data.map((_, i) => /* @__PURE__ */ React6__default.default.createElement(ink.Text, { key: i }, " ".repeat(iterm2Cols))));
|
|
3297
|
+
}
|
|
3298
|
+
const gradient = createGradient(effectiveColors, steps);
|
|
2765
3299
|
return /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "column" }, data.map((row, rowIndex) => /* @__PURE__ */ React6__default.default.createElement(ink.Box, { key: rowIndex, flexDirection: "row" }, row.map((val, colIndex) => {
|
|
2766
3300
|
const normalized = max === min ? 0 : (val - min) / (max - min);
|
|
2767
3301
|
let stepIndex = Math.floor(normalized * steps);
|
|
@@ -2875,7 +3409,7 @@ var SortableHeaderCell = ({
|
|
|
2875
3409
|
});
|
|
2876
3410
|
let indicator = "";
|
|
2877
3411
|
if (isSorted) {
|
|
2878
|
-
indicator = sortDirection === "asc" ?
|
|
3412
|
+
indicator = sortDirection === "asc" ? ` ${TREND.up}` : ` ${TREND.down}`;
|
|
2879
3413
|
}
|
|
2880
3414
|
return /* @__PURE__ */ React6__default.default.createElement(
|
|
2881
3415
|
ink.Box,
|
|
@@ -3015,34 +3549,8 @@ var Table = ({
|
|
|
3015
3549
|
})
|
|
3016
3550
|
);
|
|
3017
3551
|
};
|
|
3018
|
-
var
|
|
3019
|
-
unicode: {
|
|
3020
|
-
bar: "\u258C",
|
|
3021
|
-
left: "\u256D",
|
|
3022
|
-
right: "\u256E",
|
|
3023
|
-
leftBottom: "\u2570",
|
|
3024
|
-
rightBottom: "\u256F",
|
|
3025
|
-
horizontal: "\u2500",
|
|
3026
|
-
vertical: "\u2502"
|
|
3027
|
-
},
|
|
3028
|
-
ascii: {
|
|
3029
|
-
bar: "|",
|
|
3030
|
-
left: "/",
|
|
3031
|
-
right: "\\",
|
|
3032
|
-
leftBottom: "\\",
|
|
3033
|
-
rightBottom: "/",
|
|
3034
|
-
horizontal: "-",
|
|
3035
|
-
vertical: "|"
|
|
3036
|
-
}
|
|
3037
|
-
};
|
|
3038
|
-
var PulseBar = ({
|
|
3039
|
-
records,
|
|
3040
|
-
maxBars = 30,
|
|
3041
|
-
variant = "unicode",
|
|
3042
|
-
colors
|
|
3043
|
-
}) => {
|
|
3552
|
+
var PulseBar = ({ records = [], maxBars = 30, colors }) => {
|
|
3044
3553
|
const theme = useTheme();
|
|
3045
|
-
const chars = CHAR_SETS3[variant];
|
|
3046
3554
|
const getColor = (status) => {
|
|
3047
3555
|
switch (status) {
|
|
3048
3556
|
case "good":
|
|
@@ -3056,23 +3564,27 @@ var PulseBar = ({
|
|
|
3056
3564
|
const displayRecords = records.slice(-maxBars);
|
|
3057
3565
|
const paddingCount = maxBars - displayRecords.length;
|
|
3058
3566
|
const borderColor = theme.semantic.muted;
|
|
3059
|
-
const topBorder =
|
|
3060
|
-
const bottomBorder =
|
|
3061
|
-
return /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "column" }, /* @__PURE__ */ React6__default.default.createElement(ink.Text, { color: borderColor }, topBorder), /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "row" }, /* @__PURE__ */ React6__default.default.createElement(ink.Text, { color: borderColor },
|
|
3567
|
+
const topBorder = BORDER_ROUNDED.topLeft + BORDER_ROUNDED.horizontal.repeat(maxBars) + BORDER_ROUNDED.topRight;
|
|
3568
|
+
const bottomBorder = BORDER_ROUNDED.bottomLeft + BORDER_ROUNDED.horizontal.repeat(maxBars) + BORDER_ROUNDED.bottomRight;
|
|
3569
|
+
return /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "column" }, /* @__PURE__ */ React6__default.default.createElement(ink.Text, { color: borderColor }, topBorder), /* @__PURE__ */ React6__default.default.createElement(ink.Box, { flexDirection: "row" }, /* @__PURE__ */ React6__default.default.createElement(ink.Text, { color: borderColor }, BORDER_ROUNDED.vertical), paddingCount > 0 && /* @__PURE__ */ React6__default.default.createElement(ink.Text, { color: borderColor }, BORDER_ROUNDED.bar.repeat(paddingCount)), displayRecords.map((record, index) => /* @__PURE__ */ React6__default.default.createElement(ink.Text, { key: index, color: getColor(record.status) }, BORDER_ROUNDED.bar)), /* @__PURE__ */ React6__default.default.createElement(ink.Text, { color: borderColor }, BORDER_ROUNDED.vertical)), /* @__PURE__ */ React6__default.default.createElement(ink.Text, { color: borderColor }, bottomBorder));
|
|
3062
3570
|
};
|
|
3063
3571
|
|
|
3064
3572
|
exports.AreaChart = AreaChart;
|
|
3065
|
-
exports.AsciiRenderer = AsciiRenderer;
|
|
3066
3573
|
exports.Axis = Axis;
|
|
3574
|
+
exports.BAR = BAR;
|
|
3575
|
+
exports.BORDER_ROUNDED = BORDER_ROUNDED;
|
|
3067
3576
|
exports.BarChart = BarChart;
|
|
3068
3577
|
exports.BigNumber = BigNumber;
|
|
3069
3578
|
exports.BlockRenderer = BlockRenderer;
|
|
3070
3579
|
exports.BrailleRenderer = BrailleRenderer;
|
|
3580
|
+
exports.DEFAULT_CHART_RENDERERS = DEFAULT_CHART_RENDERERS;
|
|
3071
3581
|
exports.Gauge = Gauge;
|
|
3072
3582
|
exports.Grid = Grid;
|
|
3073
3583
|
exports.GridItem = GridItem;
|
|
3584
|
+
exports.HEATMAP = HEATMAP;
|
|
3074
3585
|
exports.Heatmap = Heatmap;
|
|
3075
3586
|
exports.InkHudProvider = InkHudProvider;
|
|
3587
|
+
exports.LEGEND = LEGEND;
|
|
3076
3588
|
exports.Legend = Legend;
|
|
3077
3589
|
exports.LineChart = LineChart;
|
|
3078
3590
|
exports.LogStream = LogStream;
|
|
@@ -3082,23 +3594,35 @@ exports.PieChart = PieChart;
|
|
|
3082
3594
|
exports.PulseBar = PulseBar;
|
|
3083
3595
|
exports.Renderer = Renderer;
|
|
3084
3596
|
exports.RendererSelector = RendererSelector;
|
|
3597
|
+
exports.SPARK_LEVELS = SPARK_LEVELS;
|
|
3085
3598
|
exports.Sparkline = Sparkline;
|
|
3599
|
+
exports.TREND = TREND;
|
|
3086
3600
|
exports.Table = Table;
|
|
3087
3601
|
exports.TerminalDetector = TerminalDetector;
|
|
3088
3602
|
exports.ThemeProvider = ThemeProvider;
|
|
3089
3603
|
exports.arcPoints = arcPoints;
|
|
3090
3604
|
exports.assignColors = assignColors;
|
|
3091
3605
|
exports.averageDownsampling = averageDownsampling;
|
|
3606
|
+
exports.buildSparklinePixelGrid = buildSparklinePixelGrid;
|
|
3092
3607
|
exports.clamp = clamp;
|
|
3093
3608
|
exports.colorToChalk = colorToChalk;
|
|
3094
3609
|
exports.createGradient = createGradient;
|
|
3610
|
+
exports.createRgbPng = createRgbPng;
|
|
3095
3611
|
exports.degreesToRadians = degreesToRadians;
|
|
3612
|
+
exports.detectImageProtocol = detectImageProtocol;
|
|
3096
3613
|
exports.distanceBetweenPoints = distanceBetweenPoints;
|
|
3097
3614
|
exports.easeInCubic = easeInCubic;
|
|
3098
3615
|
exports.easeInOutQuad = easeInOutQuad;
|
|
3099
3616
|
exports.easeLinear = easeLinear;
|
|
3100
3617
|
exports.easeOutCubic = easeOutCubic;
|
|
3618
|
+
exports.encodeIterm2 = encodeIterm2;
|
|
3619
|
+
exports.encodeKitty = encodeKitty;
|
|
3620
|
+
exports.encodeKittyDelete = encodeKittyDelete;
|
|
3621
|
+
exports.encodeKittyPlaceholders = encodeKittyPlaceholders;
|
|
3622
|
+
exports.encodeKittyUpload = encodeKittyUpload;
|
|
3101
3623
|
exports.fixedIntervalDownsampling = fixedIntervalDownsampling;
|
|
3624
|
+
exports.gradientColorFn = gradientColorFn;
|
|
3625
|
+
exports.hexToRgb = hexToRgb;
|
|
3102
3626
|
exports.linearScale = linearScale;
|
|
3103
3627
|
exports.lttb = lttb;
|
|
3104
3628
|
exports.midpointCircle = midpointCircle;
|
|
@@ -3109,6 +3633,7 @@ exports.radiansToDegrees = radiansToDegrees;
|
|
|
3109
3633
|
exports.rendererSelector = rendererSelector;
|
|
3110
3634
|
exports.scaleToRange = scaleToRange;
|
|
3111
3635
|
exports.terminalDetector = terminalDetector;
|
|
3636
|
+
exports.useImageProtocol = useImageProtocol;
|
|
3112
3637
|
exports.useInkHud = useInkHud;
|
|
3113
3638
|
exports.useRendererSelector = useRendererSelector;
|
|
3114
3639
|
exports.useSemanticColors = useSemanticColors;
|