@simon_he/vue-tui 1.1.1 → 1.1.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/README.md +68 -28
- package/dist/{TMermaidText-CXm_L969.js → TMermaidText-frVr8Ysb.js} +1 -1
- package/dist/{TSelect-CiyMvwl-.js → TSelect-tJ87rKPM.js} +6 -168
- package/dist/{TTree-DKGiuIcM.js → TTree-CGdE-CYu.js} +12 -13
- package/dist/agent.cjs +9 -5
- package/dist/agent.js +15 -1197
- package/dist/{block-source-5CQp4tF8.js → block-source-CrlmaBM5.js} +7 -601
- package/dist/cli/input.d.ts +8 -0
- package/dist/cli/video/ffmpeg-frame-source.d.ts +10 -0
- package/dist/cli/video/png-frame-parser.d.ts +4 -0
- package/dist/cli/video/raw-frame-parser.d.ts +1 -0
- package/dist/cli/video/yt-dlp-frame-source.d.ts +11 -0
- package/dist/cli.cjs +142 -33
- package/dist/cli.d.cts +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +167 -37
- package/dist/core.js +5 -6
- package/dist/create-terminal-app.d.ts +24 -1
- package/dist/{debug-logger-ChY_PXVk.js → debug-logger-CmsGI4of.js} +1 -1
- package/dist/{dom-renderer-DNzmg2As.js → dom-renderer-DXx8fWzD.js} +2 -3
- package/dist/experimental/3d/bun/contributor-avatar-atlas.d.ts +12 -0
- package/dist/experimental/3d/bun/png.d.ts +1 -0
- package/dist/experimental/3d/bun/terminal-badge-scene.d.ts +11 -0
- package/dist/experimental/3d/bun/terminal-badge.wgsl.d.ts +1 -0
- package/dist/experimental/3d/bun/webgpu-renderer.d.ts +26 -0
- package/dist/experimental/3d/bun.cjs +7271 -0
- package/dist/experimental/3d/bun.d.cts +4 -0
- package/dist/experimental/3d/bun.d.ts +4 -0
- package/dist/experimental/3d/bun.js +7390 -0
- package/dist/experimental/video/node.cjs +497 -0
- package/dist/experimental/video/node.d.cts +4 -0
- package/dist/experimental/video/node.d.ts +4 -0
- package/dist/experimental/video/node.js +610 -0
- package/dist/experimental.cjs +3064 -567
- package/dist/experimental.d.cts +5 -0
- package/dist/experimental.d.ts +5 -0
- package/dist/experimental.js +1524 -9
- package/dist/{create-terminal-DXuZ2fci.js → hyperlink-_1FAj7Wq.js} +403 -2
- package/dist/index.js +15 -16
- package/dist/{linkify-CuuquMQT.js → linkify-D68T7rdW.js} +164 -3
- package/dist/markdown.js +8 -8
- package/dist/{mermaid-CWto52Wk.js → mermaid-BNhM1jAZ.js} +1 -1
- package/dist/mermaid.js +3 -3
- package/dist/observability.js +2 -2
- package/dist/{path-suggest-fPzRsgPv.js → path-suggest-Dndu4dTi.js} +1 -1
- package/dist/renderer/terminal-graphics.d.ts +1 -0
- package/dist/renderer-dom.js +3 -4
- package/dist/runtime.js +2 -2
- package/dist/terminal-graphics-Bbe83wSr.js +597 -0
- package/dist/{tlog-theme-CopRt9SC.js → tlog-theme-Bul2Na3u.js} +1206 -12
- package/dist/{trace-CYHDKM1m.js → trace-Bh8WnoMo.js} +1 -1
- package/dist/vue/components/T3DViewport.d.ts +473 -0
- package/dist/vue/components/TAgentTerminalGraphic.d.ts +13 -0
- package/dist/vue/components/TVideo.d.ts +291 -0
- package/dist/vue/video/types.d.ts +39 -0
- package/dist/vue.js +17 -18
- package/package.json +38 -1
- package/dist/hyperlink-B35-O-cW.js +0 -403
- /package/dist/{ansi-palette-CNXqFciC.js → ansi-palette-CH6jc2Z7.js} +0 -0
- /package/dist/{env-DNCzvX8b.js → env-Cl8qmNFN.js} +0 -0
- /package/dist/{frame-perf-BBhE-iuS.js → frame-perf-CHpWhbC4.js} +0 -0
- /package/dist/{path-BI9W15Zt.js → path-mnSgEpCm.js} +0 -0
- /package/dist/{rect-Ng-3eKzF.js → rect-DUpeDfBg.js} +0 -0
- /package/dist/{runtime-D77C03RM.js → runtime-Byf8XXOT.js} +0 -0
- /package/dist/{terminal-selection-CQYr--26.js → terminal-selection-4W1SJj4c.js} +0 -0
- /package/dist/{wheel-scroll-CQ22Hcyj.js → wheel-scroll-DASkEZr-.js} +0 -0
package/dist/experimental.cjs
CHANGED
|
@@ -17,6 +17,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: !0
|
|
|
17
17
|
// src/experimental.ts
|
|
18
18
|
var experimental_exports = {};
|
|
19
19
|
__export(experimental_exports, {
|
|
20
|
+
T3DViewport: () => T3DViewport,
|
|
20
21
|
TCandlestickChart: () => TCandlestickChart,
|
|
21
22
|
TContributionGraph: () => TContributionGraph,
|
|
22
23
|
TLineChart: () => TLineChart,
|
|
@@ -31,6 +32,7 @@ __export(experimental_exports, {
|
|
|
31
32
|
TLogVirtualSearchResults: () => TLogVirtualSearchResults,
|
|
32
33
|
TPieChart: () => TPieChart,
|
|
33
34
|
TTranscriptView: () => TTranscriptView,
|
|
35
|
+
TVideo: () => TVideo,
|
|
34
36
|
TVirtualList: () => TVirtualList,
|
|
35
37
|
captureTLogViewSessionState: () => captureTLogViewSessionState,
|
|
36
38
|
createAppendOnlyLogStore: () => createAppendOnlyLogStore,
|
|
@@ -780,6 +782,14 @@ function hasInlineAsciiControl(text) {
|
|
|
780
782
|
}
|
|
781
783
|
return !1;
|
|
782
784
|
}
|
|
785
|
+
function hasTextBlockAsciiControl(text) {
|
|
786
|
+
for (let i = 0; i < text.length; i++) {
|
|
787
|
+
let code = text.charCodeAt(i);
|
|
788
|
+
if (code === 9 || code <= 31 && code !== 10 || code === 127)
|
|
789
|
+
return !0;
|
|
790
|
+
}
|
|
791
|
+
return !1;
|
|
792
|
+
}
|
|
783
793
|
function forEachGrapheme(text, cb) {
|
|
784
794
|
if (!text)
|
|
785
795
|
return;
|
|
@@ -842,6 +852,25 @@ function sanitizeInlineText(text) {
|
|
|
842
852
|
}
|
|
843
853
|
return out.join("");
|
|
844
854
|
}
|
|
855
|
+
function sanitizeTextBlock(text) {
|
|
856
|
+
if (!text)
|
|
857
|
+
return "";
|
|
858
|
+
if (!UNSAFE_FORMAT_CONTROL_RE.test(text) && !hasTextBlockAsciiControl(text))
|
|
859
|
+
return text;
|
|
860
|
+
let out = [];
|
|
861
|
+
out.length = 0;
|
|
862
|
+
for (let ch of text) {
|
|
863
|
+
let cp = ch.codePointAt(0);
|
|
864
|
+
if (cp !== 13) {
|
|
865
|
+
if (cp === 9) {
|
|
866
|
+
out.push(" ");
|
|
867
|
+
continue;
|
|
868
|
+
}
|
|
869
|
+
cp <= 31 && cp !== 10 || cp === 127 || isUnsafeFormatControl(cp) || out.push(ch);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
return out.join("");
|
|
873
|
+
}
|
|
845
874
|
function textCellWidth(text, provider = currentTextWidthProvider()) {
|
|
846
875
|
if (!text)
|
|
847
876
|
return 0;
|
|
@@ -1393,8 +1422,8 @@ function applyWheelScroll(state, deltaY, scrollTop, maxTop, now = Date.now(), de
|
|
|
1393
1422
|
}
|
|
1394
1423
|
|
|
1395
1424
|
// src/vue/utils/row-scroll.ts
|
|
1396
|
-
function exposedRowsForDelta(y0,
|
|
1397
|
-
let startY = Math.floor(y0), height = Math.max(0, Math.floor(
|
|
1425
|
+
function exposedRowsForDelta(y0, h19, delta) {
|
|
1426
|
+
let startY = Math.floor(y0), height = Math.max(0, Math.floor(h19)), lines = Math.trunc(delta), rows = [];
|
|
1398
1427
|
if (height <= 0 || lines === 0 || Math.abs(lines) >= height)
|
|
1399
1428
|
return rows;
|
|
1400
1429
|
if (lines > 0)
|
|
@@ -1406,17 +1435,17 @@ function exposedRowsForDelta(y0, h15, delta) {
|
|
|
1406
1435
|
return rows;
|
|
1407
1436
|
}
|
|
1408
1437
|
function prepareUnsafeFullRowScroll(options) {
|
|
1409
|
-
let r = options.rect, x = Math.floor(r.x), y = Math.floor(r.y), w = Math.floor(r.w),
|
|
1410
|
-
if (delta === 0 ||
|
|
1438
|
+
let r = options.rect, x = Math.floor(r.x), y = Math.floor(r.y), w = Math.floor(r.w), h19 = Math.floor(r.h), rows = Math.floor(options.terminalSize.rows), cols = Math.floor(options.terminalSize.cols), delta = Math.trunc(options.delta);
|
|
1439
|
+
if (delta === 0 || h19 <= 0 || cols <= 0 || rows <= 0)
|
|
1411
1440
|
return null;
|
|
1412
|
-
let ownsFullRows = x === 0 && w >= cols, withinTerminalRows = y >= 0 && y +
|
|
1413
|
-
if (!((options.strategy ?? "auto") === "auto" && options.rowScrollMode === "unsafe-full-row" && options.rendererCapabilities.scrollOperations && ownsFullRows && withinTerminalRows && !options.isClipped && Math.abs(delta) <
|
|
1441
|
+
let ownsFullRows = x === 0 && w >= cols, withinTerminalRows = y >= 0 && y + h19 <= rows;
|
|
1442
|
+
if (!((options.strategy ?? "auto") === "auto" && options.rowScrollMode === "unsafe-full-row" && options.rendererCapabilities.scrollOperations && ownsFullRows && withinTerminalRows && !options.isClipped && Math.abs(delta) < h19 && !options.hasPendingDirtyRows))
|
|
1414
1443
|
return null;
|
|
1415
|
-
let exposedRows = exposedRowsForDelta(y,
|
|
1444
|
+
let exposedRows = exposedRowsForDelta(y, h19, delta);
|
|
1416
1445
|
return exposedRows.length ? {
|
|
1417
1446
|
exposedRows,
|
|
1418
1447
|
apply: () => {
|
|
1419
|
-
options.render.unsafeScrollPlaneRows(options.plane, y, y +
|
|
1448
|
+
options.render.unsafeScrollPlaneRows(options.plane, y, y + h19, delta);
|
|
1420
1449
|
}
|
|
1421
1450
|
} : null;
|
|
1422
1451
|
}
|
|
@@ -1824,115 +1853,2872 @@ var virtualListInstanceSeq = 0, TVirtualList = (0, import_vue9.defineComponent)(
|
|
|
1824
1853
|
},
|
|
1825
1854
|
keydown: onKeydown
|
|
1826
1855
|
}
|
|
1827
|
-
}));
|
|
1828
|
-
(0, import_vue9.watchEffect)(() => {
|
|
1829
|
-
if (!props.autoFocus || !visible.value)
|
|
1856
|
+
}));
|
|
1857
|
+
(0, import_vue9.watchEffect)(() => {
|
|
1858
|
+
if (!props.autoFocus || !visible.value)
|
|
1859
|
+
return;
|
|
1860
|
+
let manager = events.value, nodeId = eventNode.id.value;
|
|
1861
|
+
!manager || !nodeId || manager.getFocused() !== nodeId && manager.focus(nodeId);
|
|
1862
|
+
}), (0, import_vue9.watch)(
|
|
1863
|
+
() => visible.value,
|
|
1864
|
+
(nextVisible) => {
|
|
1865
|
+
nextVisible || cancelWheelScrollFrame();
|
|
1866
|
+
}
|
|
1867
|
+
), (0, import_vue9.onBeforeUnmount)(() => {
|
|
1868
|
+
alive = !1, pendingWheelTop = null, resetWheelScrollState(wheelState), wheelMailbox.dispose(), terminalGraphicsActivity.dispose();
|
|
1869
|
+
});
|
|
1870
|
+
function viewportRows() {
|
|
1871
|
+
let r = normalizedRect(), rows = [];
|
|
1872
|
+
for (let y = r.y; y < r.y + r.h; y++)
|
|
1873
|
+
rows.push(y);
|
|
1874
|
+
return rows;
|
|
1875
|
+
}
|
|
1876
|
+
function unionDirtyRows(nextRows) {
|
|
1877
|
+
if (!dirtyRowsHint?.length)
|
|
1878
|
+
return nextRows.slice().sort((a, b) => a - b);
|
|
1879
|
+
let rows = new Set(dirtyRowsHint);
|
|
1880
|
+
for (let y of nextRows)
|
|
1881
|
+
rows.add(y);
|
|
1882
|
+
return Array.from(rows).sort((a, b) => a - b);
|
|
1883
|
+
}
|
|
1884
|
+
function markRowsDirty(nextRows) {
|
|
1885
|
+
return hasPaintableViewport() ? (dirtyRowsHint = unionDirtyRows(nextRows), renderNodeId && render.markDirtyRows(renderNodeId, dirtyRowsHint) ? !0 : (dirtyRowsHint = void 0, !1)) : !1;
|
|
1886
|
+
}
|
|
1887
|
+
function markViewportDirty() {
|
|
1888
|
+
return markRowsDirty(viewportRows());
|
|
1889
|
+
}
|
|
1890
|
+
function applyScrollTop(nextTop, options) {
|
|
1891
|
+
let controlled = isScrollControlled(), r = normalizedRect(), full = normalizedFullRect();
|
|
1892
|
+
if (r.h <= 0 || full.h <= 0)
|
|
1893
|
+
return { changed: !1, dirty: !1, top: scrollTop.value, controlled };
|
|
1894
|
+
let clampedTop = clampScrollTop(nextTop), delta = clampedTop - scrollTop.value;
|
|
1895
|
+
if (!delta)
|
|
1896
|
+
return { changed: !1, dirty: !1, top: scrollTop.value, controlled };
|
|
1897
|
+
if (controlled)
|
|
1898
|
+
return terminalGraphicsActivity.markScroll(), (options?.emitUpdate ?? !0) && emit("update:scrollTop", clampedTop), options?.emitScroll && emit("scroll", clampedTop), { changed: !0, dirty: !1, top: clampedTop, controlled };
|
|
1899
|
+
terminalGraphicsActivity.markScroll(), scrollTop.value = clampedTop, options?.emitUpdate && emit("update:scrollTop", clampedTop);
|
|
1900
|
+
let canUseTerminalRowScroll = rendererCapabilities.value.scrollOperations && rendererCapabilities.value.domRows !== !0, scrollPlan = prepareUnsafeFullRowScroll({
|
|
1901
|
+
render,
|
|
1902
|
+
plane: plane.value,
|
|
1903
|
+
rect: r,
|
|
1904
|
+
terminalSize: terminal.size(),
|
|
1905
|
+
delta,
|
|
1906
|
+
rowScrollMode: props.rowScrollMode,
|
|
1907
|
+
rendererCapabilities: {
|
|
1908
|
+
scrollOperations: canUseTerminalRowScroll
|
|
1909
|
+
},
|
|
1910
|
+
isClipped: isClipped(),
|
|
1911
|
+
hasPendingDirtyRows: !!dirtyRowsHint?.length,
|
|
1912
|
+
strategy: options?.strategy ?? "viewport-repaint"
|
|
1913
|
+
}), dirty = !1;
|
|
1914
|
+
return scrollPlan && markRowsDirty(scrollPlan.exposedRows) ? (scrollPlan.apply(), dirty = !0) : dirty = markViewportDirty(), options?.emitScroll && emit("scroll", clampedTop), options?.priority && dirty && invalidateSelf(options.priority, options.reason ?? "scroll"), { changed: !0, dirty, top: clampedTop, controlled };
|
|
1915
|
+
}
|
|
1916
|
+
let renderNode = useRenderNode(() => ({
|
|
1917
|
+
zIndex: props.zIndex,
|
|
1918
|
+
rect: visible.value ? normalizedRect() : { x: 0, y: 0, w: 0, h: 0 },
|
|
1919
|
+
deps: [
|
|
1920
|
+
visible.value,
|
|
1921
|
+
absRect.value,
|
|
1922
|
+
fullRect.value,
|
|
1923
|
+
itemCount.value,
|
|
1924
|
+
props.itemVersion,
|
|
1925
|
+
props.getItem,
|
|
1926
|
+
props.renderItem,
|
|
1927
|
+
active.value,
|
|
1928
|
+
focused.value,
|
|
1929
|
+
props.style,
|
|
1930
|
+
props.activeStyle,
|
|
1931
|
+
defaultStyle.value
|
|
1932
|
+
],
|
|
1933
|
+
paint: (dirtyRows) => {
|
|
1934
|
+
if (dirtyRowsHint = void 0, !visible.value)
|
|
1935
|
+
return;
|
|
1936
|
+
let r = normalizedRect(), full = normalizedFullRect();
|
|
1937
|
+
if (r.w <= 0 || r.h <= 0)
|
|
1938
|
+
return;
|
|
1939
|
+
let base = props.style ?? defaultStyle.value, activeStyle = props.activeStyle ?? defaultActiveStyle(base), top = visibleWindow.value.top, { x: clipX, y: clipY } = clipOffsets(), paintRow = (y) => {
|
|
1940
|
+
if (y < r.y || y >= r.y + r.h)
|
|
1941
|
+
return;
|
|
1942
|
+
let idx = top + clipY + (y - r.y), fullLine = formatInlineCellLine(
|
|
1943
|
+
idx >= 0 && idx < itemCount.value ? itemText(idx) : "",
|
|
1944
|
+
full.w
|
|
1945
|
+
), line = padEndByCells(sliceByCellsRange(fullLine, clipX, clipX + r.w), r.w), style = idx >= 0 && idx < itemCount.value && idx === active.value ? activeStyle : base;
|
|
1946
|
+
terminal.write(line, { x: r.x, y, style });
|
|
1947
|
+
}, rows = dirtyRows;
|
|
1948
|
+
if (rows?.length) {
|
|
1949
|
+
for (let y of rows)
|
|
1950
|
+
paintRow(y);
|
|
1951
|
+
return;
|
|
1952
|
+
}
|
|
1953
|
+
for (let y = r.y; y < r.y + r.h; y++)
|
|
1954
|
+
paintRow(y);
|
|
1955
|
+
}
|
|
1956
|
+
}));
|
|
1957
|
+
return (0, import_vue9.watchEffect)(() => {
|
|
1958
|
+
renderNodeId = renderNode.id.value;
|
|
1959
|
+
}), () => (0, import_vue9.h)("span", rootProps);
|
|
1960
|
+
}
|
|
1961
|
+
});
|
|
1962
|
+
|
|
1963
|
+
// src/vue/components/T3DViewport.ts
|
|
1964
|
+
var import_vue14 = require("vue");
|
|
1965
|
+
|
|
1966
|
+
// src/vue/components/TVideo.ts
|
|
1967
|
+
var import_vue13 = require("vue");
|
|
1968
|
+
|
|
1969
|
+
// src/core/ansi/sgr.ts
|
|
1970
|
+
var ESC = "\x1B";
|
|
1971
|
+
function ansi16ToColorName(code) {
|
|
1972
|
+
switch (code) {
|
|
1973
|
+
case 30:
|
|
1974
|
+
return "black";
|
|
1975
|
+
case 31:
|
|
1976
|
+
return "red";
|
|
1977
|
+
case 32:
|
|
1978
|
+
return "green";
|
|
1979
|
+
case 33:
|
|
1980
|
+
return "yellow";
|
|
1981
|
+
case 34:
|
|
1982
|
+
return "blue";
|
|
1983
|
+
case 35:
|
|
1984
|
+
return "magenta";
|
|
1985
|
+
case 36:
|
|
1986
|
+
return "cyan";
|
|
1987
|
+
case 37:
|
|
1988
|
+
return "white";
|
|
1989
|
+
case 90:
|
|
1990
|
+
return "blackBright";
|
|
1991
|
+
case 91:
|
|
1992
|
+
return "redBright";
|
|
1993
|
+
case 92:
|
|
1994
|
+
return "greenBright";
|
|
1995
|
+
case 93:
|
|
1996
|
+
return "yellowBright";
|
|
1997
|
+
case 94:
|
|
1998
|
+
return "blueBright";
|
|
1999
|
+
case 95:
|
|
2000
|
+
return "magentaBright";
|
|
2001
|
+
case 96:
|
|
2002
|
+
return "cyanBright";
|
|
2003
|
+
case 97:
|
|
2004
|
+
return "whiteBright";
|
|
2005
|
+
default:
|
|
2006
|
+
return;
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
function ansi16BgToColorName(code) {
|
|
2010
|
+
let fgCode = code >= 40 && code <= 47 || code >= 100 && code <= 107 ? code - 10 : null;
|
|
2011
|
+
if (fgCode != null)
|
|
2012
|
+
return ansi16ToColorName(fgCode);
|
|
2013
|
+
}
|
|
2014
|
+
var ANSI16_RGB = {
|
|
2015
|
+
black: { r: 0, g: 0, b: 0 },
|
|
2016
|
+
red: { r: 201, g: 27, b: 0 },
|
|
2017
|
+
green: { r: 0, g: 194, b: 0 },
|
|
2018
|
+
yellow: { r: 199, g: 196, b: 0 },
|
|
2019
|
+
blue: { r: 2, g: 37, b: 199 },
|
|
2020
|
+
magenta: { r: 201, g: 48, b: 199 },
|
|
2021
|
+
cyan: { r: 0, g: 197, b: 199 },
|
|
2022
|
+
white: { r: 199, g: 199, b: 199 },
|
|
2023
|
+
blackBright: { r: 104, g: 104, b: 104 },
|
|
2024
|
+
redBright: { r: 255, g: 110, b: 103 },
|
|
2025
|
+
greenBright: { r: 95, g: 250, b: 104 },
|
|
2026
|
+
yellowBright: { r: 255, g: 252, b: 103 },
|
|
2027
|
+
blueBright: { r: 104, g: 113, b: 255 },
|
|
2028
|
+
magentaBright: { r: 255, g: 118, b: 255 },
|
|
2029
|
+
cyanBright: { r: 95, g: 253, b: 255 },
|
|
2030
|
+
whiteBright: { r: 255, g: 255, b: 255 }
|
|
2031
|
+
};
|
|
2032
|
+
function nearestAnsi16(r, g, b) {
|
|
2033
|
+
let best = "white", bestDist = Number.POSITIVE_INFINITY;
|
|
2034
|
+
for (let [name, rgb] of Object.entries(ANSI16_RGB)) {
|
|
2035
|
+
let dr = r - rgb.r, dg = g - rgb.g, db = b - rgb.b, d = dr * dr + dg * dg + db * db;
|
|
2036
|
+
d < bestDist && (bestDist = d, best = name);
|
|
2037
|
+
}
|
|
2038
|
+
return best;
|
|
2039
|
+
}
|
|
2040
|
+
function ansi256ToRgb(index) {
|
|
2041
|
+
let n = Math.max(0, Math.min(255, Math.trunc(index)));
|
|
2042
|
+
if (n < 16) {
|
|
2043
|
+
let name = [
|
|
2044
|
+
"black",
|
|
2045
|
+
"red",
|
|
2046
|
+
"green",
|
|
2047
|
+
"yellow",
|
|
2048
|
+
"blue",
|
|
2049
|
+
"magenta",
|
|
2050
|
+
"cyan",
|
|
2051
|
+
"white",
|
|
2052
|
+
"blackBright",
|
|
2053
|
+
"redBright",
|
|
2054
|
+
"greenBright",
|
|
2055
|
+
"yellowBright",
|
|
2056
|
+
"blueBright",
|
|
2057
|
+
"magentaBright",
|
|
2058
|
+
"cyanBright",
|
|
2059
|
+
"whiteBright"
|
|
2060
|
+
][n] ?? "white";
|
|
2061
|
+
return ANSI16_RGB[name];
|
|
2062
|
+
}
|
|
2063
|
+
if (n >= 232) {
|
|
2064
|
+
let c = 8 + (n - 232) * 10;
|
|
2065
|
+
return { r: c, g: c, b: c };
|
|
2066
|
+
}
|
|
2067
|
+
let i = n - 16, rr = Math.floor(i / 36), gg = Math.floor(i % 36 / 6), bb = i % 6, toComponent = (v) => v === 0 ? 0 : 55 + v * 40;
|
|
2068
|
+
return { r: toComponent(rr), g: toComponent(gg), b: toComponent(bb) };
|
|
2069
|
+
}
|
|
2070
|
+
function applyAnsiSgrStyle(current, codes) {
|
|
2071
|
+
let next = { ...current };
|
|
2072
|
+
for (let i = 0; i < codes.length; i++) {
|
|
2073
|
+
let code = codes[i];
|
|
2074
|
+
if (code === 0) {
|
|
2075
|
+
next = {};
|
|
2076
|
+
continue;
|
|
2077
|
+
}
|
|
2078
|
+
if (code === 1)
|
|
2079
|
+
next = { ...next, bold: !0 };
|
|
2080
|
+
else if (code === 2)
|
|
2081
|
+
next = { ...next, dim: !0 };
|
|
2082
|
+
else if (code === 3)
|
|
2083
|
+
next = { ...next, italic: !0 };
|
|
2084
|
+
else if (code === 4)
|
|
2085
|
+
next = { ...next, underline: !0 };
|
|
2086
|
+
else if (code === 7)
|
|
2087
|
+
next = { ...next, inverse: !0 };
|
|
2088
|
+
else if (code === 22)
|
|
2089
|
+
next = { ...next, bold: !1, dim: !1 };
|
|
2090
|
+
else if (code === 23)
|
|
2091
|
+
next = { ...next, italic: !1 };
|
|
2092
|
+
else if (code === 24)
|
|
2093
|
+
next = { ...next, underline: !1 };
|
|
2094
|
+
else if (code === 27)
|
|
2095
|
+
next = { ...next, inverse: !1 };
|
|
2096
|
+
else if (code === 39)
|
|
2097
|
+
next = { ...next, fg: void 0 };
|
|
2098
|
+
else if (code === 49)
|
|
2099
|
+
next = { ...next, bg: void 0 };
|
|
2100
|
+
else if (code >= 30 && code <= 37 || code >= 90 && code <= 97) {
|
|
2101
|
+
let fg = ansi16ToColorName(code);
|
|
2102
|
+
next = { ...next, fg: fg ?? next.fg };
|
|
2103
|
+
} else if (code >= 40 && code <= 47 || code >= 100 && code <= 107) {
|
|
2104
|
+
let bg = ansi16BgToColorName(code);
|
|
2105
|
+
next = { ...next, bg: bg ?? next.bg };
|
|
2106
|
+
} else if (code === 38 || code === 48) {
|
|
2107
|
+
let mode = codes[i + 1];
|
|
2108
|
+
if (mode === 5) {
|
|
2109
|
+
let idx = codes[i + 2];
|
|
2110
|
+
if (idx != null) {
|
|
2111
|
+
let { r, g, b } = ansi256ToRgb(idx), name = nearestAnsi16(r, g, b);
|
|
2112
|
+
next = code === 38 ? { ...next, fg: name } : { ...next, bg: name };
|
|
2113
|
+
}
|
|
2114
|
+
i += 2;
|
|
2115
|
+
} else if (mode === 2) {
|
|
2116
|
+
let r = codes[i + 2], g = codes[i + 3], b = codes[i + 4];
|
|
2117
|
+
if (r != null && g != null && b != null) {
|
|
2118
|
+
let name = nearestAnsi16(r, g, b);
|
|
2119
|
+
next = code === 38 ? { ...next, fg: name } : { ...next, bg: name };
|
|
2120
|
+
}
|
|
2121
|
+
i += 4;
|
|
2122
|
+
}
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
return next;
|
|
2126
|
+
}
|
|
2127
|
+
function parseAnsiSgr(input, baseStyle = {}) {
|
|
2128
|
+
let segments = [], style = { ...baseStyle }, lastIndex = 0;
|
|
2129
|
+
for (let i = 0; i < input.length; i++) {
|
|
2130
|
+
if (input[i] !== ESC || input[i + 1] !== "[")
|
|
2131
|
+
continue;
|
|
2132
|
+
let j = i + 2;
|
|
2133
|
+
for (; j < input.length; ) {
|
|
2134
|
+
let c = input.charCodeAt(j);
|
|
2135
|
+
if (c >= 48 && c <= 57 || c === 59) {
|
|
2136
|
+
j++;
|
|
2137
|
+
continue;
|
|
2138
|
+
}
|
|
2139
|
+
break;
|
|
2140
|
+
}
|
|
2141
|
+
if (j >= input.length || input[j] !== "m")
|
|
2142
|
+
continue;
|
|
2143
|
+
i > lastIndex && segments.push({ text: input.slice(lastIndex, i), style });
|
|
2144
|
+
let codes = input.slice(i + 2, j).split(";").filter(Boolean).map((n) => Number.parseInt(n, 10)).filter((n) => Number.isFinite(n));
|
|
2145
|
+
style = applyAnsiSgrStyle(style, codes.length ? codes : [0]), lastIndex = j + 1, i = j;
|
|
2146
|
+
}
|
|
2147
|
+
return lastIndex < input.length && segments.push({ text: input.slice(lastIndex), style }), segments;
|
|
2148
|
+
}
|
|
2149
|
+
|
|
2150
|
+
// src/core/terminal/create-terminal.ts
|
|
2151
|
+
var TERMINAL_PLANE_INTERNALS = Symbol.for("@simon_he/vue-tui:v1:terminal-plane-internals"), TERMINAL_ROOT = Symbol.for("@simon_he/vue-tui:v1:terminal-root");
|
|
2152
|
+
function getRootTerminal(terminal) {
|
|
2153
|
+
return terminal[TERMINAL_ROOT] ?? terminal;
|
|
2154
|
+
}
|
|
2155
|
+
|
|
2156
|
+
// src/renderer/terminal-graphics.ts
|
|
2157
|
+
var ESC2 = "\x1B", BEL = "\x07", ST = `${ESC2}\\`, ESC_RE = "\\u001B", BEL_RE = "\\u0007", CSI_RE = new RegExp(`${ESC_RE}\\[[0-?]*[ -/]*[@-~]`, "g"), OSC_RE = new RegExp(`${ESC_RE}\\][\\s\\S]*?(?:${BEL_RE}|${ESC_RE}\\\\)`, "g"), DCS_RE = new RegExp(`${ESC_RE}P[\\s\\S]*?${ESC_RE}\\\\`, "g"), APC_RE = new RegExp(`${ESC_RE}_[\\s\\S]*?${ESC_RE}\\\\`, "g"), C1_CSI_RE = new RegExp("\\u009B[0-?]*[ -/]*[@-~]", "g"), C1_OSC_RE = new RegExp(`\\u009D[\\s\\S]*?(?:${BEL_RE}|\\u009C)`, "g"), C1_DCS_RE = new RegExp("\\u0090[\\s\\S]*?\\u009C", "g"), C1_APC_RE = new RegExp("\\u009F[\\s\\S]*?\\u009C", "g"), MAX_TERMINAL_GRAPHICS_SEQUENCE_CHARS = 16 * 1024 * 1024, MAX_TERMINAL_GRAPHICS_FALLBACK_CHARS = 16384, MAX_TERMINAL_GRAPHIC_CELLS = 1e4, TERMINAL_GRAPHICS_REGISTRY = Symbol.for("@simon_he/vue-tui:v1:terminal-graphics"), terminalGraphicsGlobal = globalThis, terminalGraphicsRegistry = terminalGraphicsGlobal[TERMINAL_GRAPHICS_REGISTRY] ?? {
|
|
2158
|
+
outputs: /* @__PURE__ */ new WeakMap(),
|
|
2159
|
+
outputVersions: /* @__PURE__ */ new WeakMap(),
|
|
2160
|
+
outputListeners: /* @__PURE__ */ new WeakMap()
|
|
2161
|
+
};
|
|
2162
|
+
terminalGraphicsGlobal[TERMINAL_GRAPHICS_REGISTRY] = terminalGraphicsRegistry;
|
|
2163
|
+
var terminalGraphicsOutputs = terminalGraphicsRegistry.outputs, terminalGraphicsOutputVersions = terminalGraphicsRegistry.outputVersions, terminalGraphicsOutputListeners = terminalGraphicsRegistry.outputListeners;
|
|
2164
|
+
function getTerminalGraphicsOutput(terminal) {
|
|
2165
|
+
return terminalGraphicsOutputs.get(getRootTerminal(terminal)) ?? null;
|
|
2166
|
+
}
|
|
2167
|
+
function getTerminalGraphicsOutputVersion(terminal) {
|
|
2168
|
+
return terminalGraphicsOutputVersions.get(getRootTerminal(terminal)) ?? 0;
|
|
2169
|
+
}
|
|
2170
|
+
function subscribeTerminalGraphicsOutput(terminal, listener) {
|
|
2171
|
+
let rootTerminal = getRootTerminal(terminal), listeners = terminalGraphicsOutputListeners.get(rootTerminal);
|
|
2172
|
+
return listeners || (listeners = /* @__PURE__ */ new Set(), terminalGraphicsOutputListeners.set(rootTerminal, listeners)), listeners.add(listener), () => {
|
|
2173
|
+
listeners.delete(listener), listeners.size === 0 && terminalGraphicsOutputListeners.delete(rootTerminal);
|
|
2174
|
+
};
|
|
2175
|
+
}
|
|
2176
|
+
function isTerminalGraphicsProtocol(value) {
|
|
2177
|
+
return value === "kitty" || value === "iterm2" || value === "sixel";
|
|
2178
|
+
}
|
|
2179
|
+
function stableTerminalGraphicNumericId(input, options = {}) {
|
|
2180
|
+
let min = Math.floor(options.min ?? 1), max = Math.floor(options.max ?? 2147483647), span = Math.max(1, max - min + 1), hash = 2166136261;
|
|
2181
|
+
for (let index = 0; index < input.length; index += 1)
|
|
2182
|
+
hash ^= input.charCodeAt(index), hash = Math.imul(hash, 16777619);
|
|
2183
|
+
return min + (hash >>> 0) % span;
|
|
2184
|
+
}
|
|
2185
|
+
function positiveGraphicInt(value, max) {
|
|
2186
|
+
let n = Math.trunc(Number(value));
|
|
2187
|
+
return !Number.isFinite(n) || n <= 0 ? null : Math.min(max, n);
|
|
2188
|
+
}
|
|
2189
|
+
function normalizeTerminalGraphicSize(width, height) {
|
|
2190
|
+
let w = positiveGraphicInt(width, MAX_TERMINAL_GRAPHIC_CELLS), h19 = positiveGraphicInt(height, MAX_TERMINAL_GRAPHIC_CELLS);
|
|
2191
|
+
return w == null || h19 == null || w * h19 > MAX_TERMINAL_GRAPHIC_CELLS ? null : { width: w, height: h19 };
|
|
2192
|
+
}
|
|
2193
|
+
function canDrawTerminalGraphicRect(rect, size) {
|
|
2194
|
+
let x = Math.floor(rect.x), y = Math.floor(rect.y), graphicSize = normalizeTerminalGraphicSize(rect.w, rect.h), cols = Math.max(0, Math.floor(size.cols)), rows = Math.max(0, Math.floor(size.rows));
|
|
2195
|
+
return graphicSize != null && cols > 0 && rows > 0 && Number.isFinite(x) && Number.isFinite(y) && x >= 0 && y >= 0 && x < cols && y < rows;
|
|
2196
|
+
}
|
|
2197
|
+
function withoutNestedEscapes(body) {
|
|
2198
|
+
return !body.includes(ESC2) && !body.includes(BEL);
|
|
2199
|
+
}
|
|
2200
|
+
function isBase64ish(value) {
|
|
2201
|
+
return /^[A-Za-z0-9+/=]*$/.test(value);
|
|
2202
|
+
}
|
|
2203
|
+
function parseKittyControls(raw) {
|
|
2204
|
+
let out = /* @__PURE__ */ new Map();
|
|
2205
|
+
if (!/^[A-Za-z0-9_,=+.\-:]*$/.test(raw))
|
|
2206
|
+
return null;
|
|
2207
|
+
for (let part of raw.split(",")) {
|
|
2208
|
+
if (!part)
|
|
2209
|
+
continue;
|
|
2210
|
+
let eq = part.indexOf("=");
|
|
2211
|
+
if (eq <= 0)
|
|
2212
|
+
return null;
|
|
2213
|
+
let key = part.slice(0, eq), value = part.slice(eq + 1);
|
|
2214
|
+
if (!/^[A-Za-z]$/.test(key) || !/^[A-Za-z0-9+.\-:]*$/.test(value))
|
|
2215
|
+
return null;
|
|
2216
|
+
out.set(key, value);
|
|
2217
|
+
}
|
|
2218
|
+
return out;
|
|
2219
|
+
}
|
|
2220
|
+
function parseKittyPackets(sequence) {
|
|
2221
|
+
let packets = [], index = 0;
|
|
2222
|
+
for (; index < sequence.length; ) {
|
|
2223
|
+
if (!sequence.startsWith(`${ESC2}_G`, index))
|
|
2224
|
+
return null;
|
|
2225
|
+
let end = sequence.indexOf(ST, index + 3);
|
|
2226
|
+
if (end < 0)
|
|
2227
|
+
return null;
|
|
2228
|
+
let body = sequence.slice(index + 3, end);
|
|
2229
|
+
if (!withoutNestedEscapes(body))
|
|
2230
|
+
return null;
|
|
2231
|
+
let semicolon = body.indexOf(";"), rawControls = semicolon >= 0 ? body.slice(0, semicolon) : body, payload = semicolon >= 0 ? body.slice(semicolon + 1) : "", controls = parseKittyControls(rawControls);
|
|
2232
|
+
if (!controls || payload && !isBase64ish(payload))
|
|
2233
|
+
return null;
|
|
2234
|
+
packets.push({ controls, payload }), index = end + ST.length;
|
|
2235
|
+
}
|
|
2236
|
+
return packets.length ? packets : null;
|
|
2237
|
+
}
|
|
2238
|
+
var KITTY_DRAW_FIRST_CONTROL_KEYS = /* @__PURE__ */ new Set([
|
|
2239
|
+
"a",
|
|
2240
|
+
"f",
|
|
2241
|
+
"q",
|
|
2242
|
+
"C",
|
|
2243
|
+
"i",
|
|
2244
|
+
"I",
|
|
2245
|
+
"p",
|
|
2246
|
+
"c",
|
|
2247
|
+
"r",
|
|
2248
|
+
"x",
|
|
2249
|
+
"y",
|
|
2250
|
+
"w",
|
|
2251
|
+
"h",
|
|
2252
|
+
"z",
|
|
2253
|
+
"m",
|
|
2254
|
+
"t"
|
|
2255
|
+
]), KITTY_DRAW_CONTINUATION_CONTROL_KEYS = /* @__PURE__ */ new Set(["a", "q", "m"]), KITTY_CLEAR_CONTROL_KEYS = /* @__PURE__ */ new Set(["a", "d", "i", "I", "p", "q"]);
|
|
2256
|
+
function kittyControlsUseOnly(controls, allowed) {
|
|
2257
|
+
for (let key of controls.keys())
|
|
2258
|
+
if (!allowed.has(key))
|
|
2259
|
+
return !1;
|
|
2260
|
+
return !0;
|
|
2261
|
+
}
|
|
2262
|
+
var KITTY_UINT32_MAX = 4294967295, KITTY_INT32_MIN = -2147483648, KITTY_INT32_MAX = 2147483647;
|
|
2263
|
+
function kittyControlIsUint32(controls, key, min = 0) {
|
|
2264
|
+
let value = controls.get(key);
|
|
2265
|
+
if (value == null)
|
|
2266
|
+
return !0;
|
|
2267
|
+
if (!/^\d+$/.test(value))
|
|
2268
|
+
return !1;
|
|
2269
|
+
let n = Number(value);
|
|
2270
|
+
return Number.isSafeInteger(n) && n >= min && n <= KITTY_UINT32_MAX;
|
|
2271
|
+
}
|
|
2272
|
+
function kittyControlIsInt32(controls, key) {
|
|
2273
|
+
let value = controls.get(key);
|
|
2274
|
+
if (value == null)
|
|
2275
|
+
return !0;
|
|
2276
|
+
if (!/^-?\d+$/.test(value))
|
|
2277
|
+
return !1;
|
|
2278
|
+
let n = Number(value);
|
|
2279
|
+
return Number.isSafeInteger(n) && n >= KITTY_INT32_MIN && n <= KITTY_INT32_MAX;
|
|
2280
|
+
}
|
|
2281
|
+
function kittyControlPositiveInt(controls, key, fallback) {
|
|
2282
|
+
let value = controls.get(key);
|
|
2283
|
+
if (value == null)
|
|
2284
|
+
return fallback;
|
|
2285
|
+
if (!/^\d+$/.test(value))
|
|
2286
|
+
return null;
|
|
2287
|
+
let n = Number(value);
|
|
2288
|
+
return Number.isSafeInteger(n) && n >= 1 ? n : null;
|
|
2289
|
+
}
|
|
2290
|
+
function kittyControlIsTerminalGraphicCellsBounded(controls) {
|
|
2291
|
+
let columns = kittyControlPositiveInt(controls, "c", 1), rows = kittyControlPositiveInt(controls, "r", 1);
|
|
2292
|
+
return columns != null && rows != null && columns * rows <= MAX_TERMINAL_GRAPHIC_CELLS;
|
|
2293
|
+
}
|
|
2294
|
+
function validateKittySharedSafeControls(controls) {
|
|
2295
|
+
let q = controls.get("q");
|
|
2296
|
+
if (q != null && !/^[0-2]$/.test(q))
|
|
2297
|
+
return !1;
|
|
2298
|
+
let cursorMove = controls.get("C");
|
|
2299
|
+
if (cursorMove != null && !/^[01]$/.test(cursorMove))
|
|
2300
|
+
return !1;
|
|
2301
|
+
for (let key of ["i", "I", "p"])
|
|
2302
|
+
if (!kittyControlIsUint32(controls, key))
|
|
2303
|
+
return !1;
|
|
2304
|
+
for (let key of ["c", "r"])
|
|
2305
|
+
if (!kittyControlIsUint32(controls, key, 1))
|
|
2306
|
+
return !1;
|
|
2307
|
+
if (!kittyControlIsTerminalGraphicCellsBounded(controls))
|
|
2308
|
+
return !1;
|
|
2309
|
+
for (let key of ["x", "y"])
|
|
2310
|
+
if (!kittyControlIsUint32(controls, key))
|
|
2311
|
+
return !1;
|
|
2312
|
+
for (let key of ["w", "h"])
|
|
2313
|
+
if (!kittyControlIsUint32(controls, key, 1))
|
|
2314
|
+
return !1;
|
|
2315
|
+
if (!kittyControlIsInt32(controls, "z"))
|
|
2316
|
+
return !1;
|
|
2317
|
+
let transmissionMedium = controls.get("t");
|
|
2318
|
+
return !(transmissionMedium != null && transmissionMedium !== "d");
|
|
2319
|
+
}
|
|
2320
|
+
function validateKittySequence(sequence, op = "draw") {
|
|
2321
|
+
let packets = parseKittyPackets(sequence);
|
|
2322
|
+
if (!packets)
|
|
2323
|
+
return !1;
|
|
2324
|
+
if (op === "clear") {
|
|
2325
|
+
if (packets.length !== 1)
|
|
2326
|
+
return !1;
|
|
2327
|
+
let packet = packets[0];
|
|
2328
|
+
if (!kittyControlsUseOnly(packet.controls, KITTY_CLEAR_CONTROL_KEYS) || !validateKittySharedSafeControls(packet.controls) || packet.payload || packet.controls.get("a") !== "d")
|
|
2329
|
+
return !1;
|
|
2330
|
+
let d = packet.controls.get("d");
|
|
2331
|
+
return d == null || /^[aAcCiI]$/.test(d);
|
|
2332
|
+
}
|
|
2333
|
+
let first = packets[0];
|
|
2334
|
+
if (!kittyControlsUseOnly(first.controls, KITTY_DRAW_FIRST_CONTROL_KEYS) || !validateKittySharedSafeControls(first.controls))
|
|
2335
|
+
return !1;
|
|
2336
|
+
if (first.controls.get("a") === "p")
|
|
2337
|
+
return !(packets.length !== 1 || first.payload || !first.controls.has("i") && !first.controls.has("I"));
|
|
2338
|
+
if (first.controls.get("a") !== "T" || !first.payload)
|
|
2339
|
+
return !1;
|
|
2340
|
+
let f = first.controls.get("f");
|
|
2341
|
+
if (f != null && f !== "24" && f !== "32" && f !== "100")
|
|
2342
|
+
return !1;
|
|
2343
|
+
let firstMore = first.controls.get("m");
|
|
2344
|
+
if (firstMore != null && firstMore !== "0" && firstMore !== "1" || packets.length > 1 && firstMore !== "1")
|
|
2345
|
+
return !1;
|
|
2346
|
+
for (let i = 1; i < packets.length; i++) {
|
|
2347
|
+
let packet = packets[i];
|
|
2348
|
+
if (!kittyControlsUseOnly(packet.controls, KITTY_DRAW_CONTINUATION_CONTROL_KEYS) || !validateKittySharedSafeControls(packet.controls))
|
|
2349
|
+
return !1;
|
|
2350
|
+
let action = packet.controls.get("a");
|
|
2351
|
+
if (action != null && action !== "T")
|
|
2352
|
+
return !1;
|
|
2353
|
+
let m = packet.controls.get("m");
|
|
2354
|
+
if (m !== "0" && m !== "1" || !packet.payload && !(i === packets.length - 1 && m === "0"))
|
|
2355
|
+
return !1;
|
|
2356
|
+
}
|
|
2357
|
+
return !(packets.length > 1 && packets[packets.length - 1].controls.get("m") === "1");
|
|
2358
|
+
}
|
|
2359
|
+
function validateIterm2Dimension(value) {
|
|
2360
|
+
return /^auto$/i.test(value) || /^(?:[1-9]\d{0,4})(?:px|%)?$/.test(value);
|
|
2361
|
+
}
|
|
2362
|
+
function validateIterm2Params(params) {
|
|
2363
|
+
let seen = /* @__PURE__ */ new Set(), inline = !1;
|
|
2364
|
+
for (let part of params.split(";").filter(Boolean)) {
|
|
2365
|
+
let eq = part.indexOf("=");
|
|
2366
|
+
if (eq <= 0)
|
|
2367
|
+
return !1;
|
|
2368
|
+
let key = part.slice(0, eq), value = part.slice(eq + 1);
|
|
2369
|
+
if (seen.has(key))
|
|
2370
|
+
return !1;
|
|
2371
|
+
switch (seen.add(key), key) {
|
|
2372
|
+
case "inline":
|
|
2373
|
+
if (value !== "1")
|
|
2374
|
+
return !1;
|
|
2375
|
+
inline = !0;
|
|
2376
|
+
break;
|
|
2377
|
+
case "width":
|
|
2378
|
+
case "height":
|
|
2379
|
+
if (!validateIterm2Dimension(value))
|
|
2380
|
+
return !1;
|
|
2381
|
+
break;
|
|
2382
|
+
case "preserveAspectRatio":
|
|
2383
|
+
case "doNotMoveCursor":
|
|
2384
|
+
if (!/^[01]$/.test(value))
|
|
2385
|
+
return !1;
|
|
2386
|
+
break;
|
|
2387
|
+
default:
|
|
2388
|
+
return !1;
|
|
2389
|
+
}
|
|
2390
|
+
}
|
|
2391
|
+
return inline;
|
|
2392
|
+
}
|
|
2393
|
+
function validateIterm2Sequence(sequence, op = "draw") {
|
|
2394
|
+
if (op === "clear")
|
|
2395
|
+
return !1;
|
|
2396
|
+
let index = 0;
|
|
2397
|
+
for (; index < sequence.length; ) {
|
|
2398
|
+
let prefix = `${ESC2}]1337;File=`;
|
|
2399
|
+
if (!sequence.startsWith(prefix, index))
|
|
2400
|
+
return !1;
|
|
2401
|
+
let belEnd = sequence.indexOf(BEL, index + prefix.length), stEnd = sequence.indexOf(ST, index + prefix.length), end = belEnd >= 0 && stEnd >= 0 ? Math.min(belEnd, stEnd) : belEnd >= 0 ? belEnd : stEnd;
|
|
2402
|
+
if (end < 0)
|
|
2403
|
+
return !1;
|
|
2404
|
+
let body = sequence.slice(index + `${ESC2}]1337;`.length, end);
|
|
2405
|
+
if (!body.startsWith("File=") || !withoutNestedEscapes(body))
|
|
2406
|
+
return !1;
|
|
2407
|
+
let colon = body.indexOf(":");
|
|
2408
|
+
if (colon < 0)
|
|
2409
|
+
return !1;
|
|
2410
|
+
let params = body.slice(5, colon), payload = body.slice(colon + 1);
|
|
2411
|
+
if (!/^[A-Za-z0-9_=;,.%+\-:]*$/.test(params) || !payload || !isBase64ish(payload) || !validateIterm2Params(params))
|
|
2412
|
+
return !1;
|
|
2413
|
+
index = end + (end === stEnd ? ST.length : BEL.length);
|
|
2414
|
+
}
|
|
2415
|
+
return sequence.length > 0;
|
|
2416
|
+
}
|
|
2417
|
+
function validateSixelSequence(sequence, op = "draw") {
|
|
2418
|
+
if (op === "clear")
|
|
2419
|
+
return !1;
|
|
2420
|
+
let index = 0;
|
|
2421
|
+
for (; index < sequence.length; ) {
|
|
2422
|
+
if (!sequence.startsWith(`${ESC2}P`, index))
|
|
2423
|
+
return !1;
|
|
2424
|
+
let end = sequence.indexOf(ST, index + 2);
|
|
2425
|
+
if (end < 0)
|
|
2426
|
+
return !1;
|
|
2427
|
+
let body = sequence.slice(index + 2, end);
|
|
2428
|
+
if (!withoutNestedEscapes(body))
|
|
2429
|
+
return !1;
|
|
2430
|
+
for (let i = 0; i < body.length; i++) {
|
|
2431
|
+
let code = body.charCodeAt(i);
|
|
2432
|
+
if (code < 32 || code > 126)
|
|
2433
|
+
return !1;
|
|
2434
|
+
}
|
|
2435
|
+
let q = body.indexOf("q");
|
|
2436
|
+
if (q < 0 || q > 32)
|
|
2437
|
+
return !1;
|
|
2438
|
+
let introducer = body.slice(0, q);
|
|
2439
|
+
if (!/^[0-9;?]*$/.test(introducer) || !body.slice(q + 1).length)
|
|
2440
|
+
return !1;
|
|
2441
|
+
index = end + ST.length;
|
|
2442
|
+
}
|
|
2443
|
+
return sequence.length > 0;
|
|
2444
|
+
}
|
|
2445
|
+
function stripTerminalControlChars(value) {
|
|
2446
|
+
let out = "";
|
|
2447
|
+
for (let index = 0; index < value.length; index++) {
|
|
2448
|
+
let code = value.charCodeAt(index);
|
|
2449
|
+
code <= 8 || code === 11 || code === 12 || code >= 14 && code <= 31 || code === 127 || code >= 128 && code <= 159 || (out += value[index]);
|
|
2450
|
+
}
|
|
2451
|
+
return out;
|
|
2452
|
+
}
|
|
2453
|
+
function sanitizeTerminalFallbackText(text) {
|
|
2454
|
+
return stripTerminalControlChars(
|
|
2455
|
+
String(text ?? "").replace(OSC_RE, "").replace(CSI_RE, "").replace(DCS_RE, "").replace(APC_RE, "").replace(C1_OSC_RE, "").replace(C1_CSI_RE, "").replace(C1_DCS_RE, "").replace(C1_APC_RE, "")
|
|
2456
|
+
).slice(0, MAX_TERMINAL_GRAPHICS_FALLBACK_CHARS);
|
|
2457
|
+
}
|
|
2458
|
+
function isSafeTerminalGraphicsSequence(sequence, protocol, op = "draw") {
|
|
2459
|
+
return !isTerminalGraphicsProtocol(protocol) || !sequence || sequence.length > MAX_TERMINAL_GRAPHICS_SEQUENCE_CHARS ? !1 : protocol === "kitty" ? validateKittySequence(sequence, op) : protocol === "iterm2" ? validateIterm2Sequence(sequence, op) : validateSixelSequence(sequence, op);
|
|
2460
|
+
}
|
|
2461
|
+
function uint32Control(key, value, min = 0) {
|
|
2462
|
+
if (value == null)
|
|
2463
|
+
return "";
|
|
2464
|
+
let n = Math.floor(value);
|
|
2465
|
+
return Number.isSafeInteger(n) && n >= min && n <= KITTY_UINT32_MAX ? `${key}=${n}` : "";
|
|
2466
|
+
}
|
|
2467
|
+
function int32Control(key, value) {
|
|
2468
|
+
if (value == null)
|
|
2469
|
+
return "";
|
|
2470
|
+
let n = Math.floor(value);
|
|
2471
|
+
return Number.isSafeInteger(n) && n >= KITTY_INT32_MIN && n <= KITTY_INT32_MAX ? `${key}=${n}` : "";
|
|
2472
|
+
}
|
|
2473
|
+
function sanitizeBase64(value) {
|
|
2474
|
+
let data = String(value ?? "").replace(/\s+/g, "");
|
|
2475
|
+
return isBase64ish(data) ? data : "";
|
|
2476
|
+
}
|
|
2477
|
+
function kittyGraphicCellControls(columns, rows) {
|
|
2478
|
+
if (columns == null && rows == null)
|
|
2479
|
+
return [];
|
|
2480
|
+
let size = normalizeTerminalGraphicSize(columns ?? 1, rows ?? 1);
|
|
2481
|
+
return size ? [columns == null ? "" : `c=${size.width}`, rows == null ? "" : `r=${size.height}`] : [];
|
|
2482
|
+
}
|
|
2483
|
+
function kittyGraphicSourceControls(sourceX, sourceY, sourceWidth, sourceHeight) {
|
|
2484
|
+
return [
|
|
2485
|
+
uint32Control("x", sourceX),
|
|
2486
|
+
uint32Control("y", sourceY),
|
|
2487
|
+
uint32Control("w", sourceWidth, 1),
|
|
2488
|
+
uint32Control("h", sourceHeight, 1)
|
|
2489
|
+
];
|
|
2490
|
+
}
|
|
2491
|
+
function chunkBase64(value, chunkSize) {
|
|
2492
|
+
let normalizedSize = Math.max(4, Math.floor(chunkSize / 4) * 4), chunks = [];
|
|
2493
|
+
for (let index = 0; index < value.length; index += normalizedSize)
|
|
2494
|
+
chunks.push(value.slice(index, index + normalizedSize));
|
|
2495
|
+
return chunks.length ? chunks : [""];
|
|
2496
|
+
}
|
|
2497
|
+
function createKittyPlacementSequence(options) {
|
|
2498
|
+
let imageId = uint32Control("i", options.imageId), imageNumber = uint32Control("I", options.imageNumber);
|
|
2499
|
+
if (!imageId && !imageNumber)
|
|
2500
|
+
return "";
|
|
2501
|
+
let controls = [
|
|
2502
|
+
"a=p",
|
|
2503
|
+
options.quiet === !1 ? "" : "q=2",
|
|
2504
|
+
options.noCursorMove === !1 ? "" : "C=1",
|
|
2505
|
+
imageId,
|
|
2506
|
+
imageNumber,
|
|
2507
|
+
uint32Control("p", options.placementId),
|
|
2508
|
+
...kittyGraphicCellControls(options.columns, options.rows),
|
|
2509
|
+
...kittyGraphicSourceControls(
|
|
2510
|
+
options.sourceX,
|
|
2511
|
+
options.sourceY,
|
|
2512
|
+
options.sourceWidth,
|
|
2513
|
+
options.sourceHeight
|
|
2514
|
+
),
|
|
2515
|
+
int32Control("z", options.zIndex)
|
|
2516
|
+
].filter(Boolean);
|
|
2517
|
+
return `${ESC2}_G${controls.join(",")}${ST}`;
|
|
2518
|
+
}
|
|
2519
|
+
function createKittyGraphicsSequence(base64Png, options = {}) {
|
|
2520
|
+
let data = sanitizeBase64(base64Png);
|
|
2521
|
+
if (!data)
|
|
2522
|
+
return "";
|
|
2523
|
+
let chunks = chunkBase64(data, options.chunkSize ?? 4096), baseControls = [
|
|
2524
|
+
"a=T",
|
|
2525
|
+
"f=100",
|
|
2526
|
+
options.quiet === !1 ? "" : "q=2",
|
|
2527
|
+
options.noCursorMove === !1 ? "" : "C=1",
|
|
2528
|
+
uint32Control("i", options.imageId),
|
|
2529
|
+
uint32Control("I", options.imageNumber),
|
|
2530
|
+
uint32Control("p", options.placementId),
|
|
2531
|
+
...kittyGraphicCellControls(options.columns, options.rows),
|
|
2532
|
+
...kittyGraphicSourceControls(
|
|
2533
|
+
options.sourceX,
|
|
2534
|
+
options.sourceY,
|
|
2535
|
+
options.sourceWidth,
|
|
2536
|
+
options.sourceHeight
|
|
2537
|
+
),
|
|
2538
|
+
int32Control("z", options.zIndex)
|
|
2539
|
+
].filter(Boolean);
|
|
2540
|
+
return chunks.map((chunk, index) => {
|
|
2541
|
+
let last = index === chunks.length - 1, controls = index === 0 ? [...baseControls, chunks.length > 1 ? `m=${last ? 0 : 1}` : ""] : [options.quiet === !1 ? "" : "q=2", `m=${last ? 0 : 1}`].filter(Boolean);
|
|
2542
|
+
return `${ESC2}_G${controls.filter(Boolean).join(",")};${chunk}${ST}`;
|
|
2543
|
+
}).join("");
|
|
2544
|
+
}
|
|
2545
|
+
function createKittyDeleteGraphicsSequence(options = {}) {
|
|
2546
|
+
let controls = ["a=d"];
|
|
2547
|
+
if (options.allVisible)
|
|
2548
|
+
controls.push(`d=${options.freeImageData ? "A" : "a"}`);
|
|
2549
|
+
else if (options.imageId != null) {
|
|
2550
|
+
let imageId = uint32Control("i", options.imageId), placementId = uint32Control("p", options.placementId);
|
|
2551
|
+
if (!imageId || options.placementId != null && !placementId)
|
|
2552
|
+
return "";
|
|
2553
|
+
controls.push(`d=${options.freeImageData ? "I" : "i"}`), controls.push(imageId), controls.push(placementId);
|
|
2554
|
+
} else if (options.currentCell)
|
|
2555
|
+
controls.push(`d=${options.freeImageData ? "C" : "c"}`);
|
|
2556
|
+
else
|
|
2557
|
+
return "";
|
|
2558
|
+
return options.quiet !== !1 && controls.push("q=2"), `${ESC2}_G${controls.filter(Boolean).join(",")}${ST}`;
|
|
2559
|
+
}
|
|
2560
|
+
function createIterm2InlineImageSequence(base64Data, options = {}) {
|
|
2561
|
+
let data = sanitizeBase64(base64Data);
|
|
2562
|
+
if (!data)
|
|
2563
|
+
return "";
|
|
2564
|
+
let params = [
|
|
2565
|
+
"inline=1",
|
|
2566
|
+
options.width != null ? `width=${formatItermDimension(options.width)}` : "",
|
|
2567
|
+
options.height != null ? `height=${formatItermDimension(options.height)}` : "",
|
|
2568
|
+
`preserveAspectRatio=${options.preserveAspectRatio === !1 ? 0 : 1}`,
|
|
2569
|
+
options.doNotMoveCursor === !1 ? "" : "doNotMoveCursor=1"
|
|
2570
|
+
].filter(Boolean);
|
|
2571
|
+
return `${ESC2}]1337;File=${params.join(";")}:${data}${BEL}`;
|
|
2572
|
+
}
|
|
2573
|
+
function formatItermDimension(value) {
|
|
2574
|
+
if (typeof value == "number") {
|
|
2575
|
+
let n = Math.floor(value);
|
|
2576
|
+
return Number.isFinite(n) ? String(Math.min(99999, Math.max(1, n))) : "auto";
|
|
2577
|
+
}
|
|
2578
|
+
let raw = String(value ?? "").trim();
|
|
2579
|
+
return validateIterm2Dimension(raw) ? raw : "auto";
|
|
2580
|
+
}
|
|
2581
|
+
|
|
2582
|
+
// src/vue/components/TAgentTerminalGraphic.ts
|
|
2583
|
+
var import_vue10 = require("vue");
|
|
2584
|
+
var NO_GRAPHICS_CAPABILITIES = Object.freeze({
|
|
2585
|
+
supported: !1,
|
|
2586
|
+
kitty: !1,
|
|
2587
|
+
iterm2: !1,
|
|
2588
|
+
sixel: !1,
|
|
2589
|
+
preferredProtocol: null,
|
|
2590
|
+
protocol: "unicode",
|
|
2591
|
+
candidates: [],
|
|
2592
|
+
stdoutIsTTY: !1,
|
|
2593
|
+
insideTmux: !1,
|
|
2594
|
+
insideScreen: !1,
|
|
2595
|
+
insideZellij: !1,
|
|
2596
|
+
multiplexer: null,
|
|
2597
|
+
passthrough: !1,
|
|
2598
|
+
forced: !1,
|
|
2599
|
+
reason: "no-terminal-graphics-output"
|
|
2600
|
+
});
|
|
2601
|
+
function splitTextOutput(value) {
|
|
2602
|
+
let lines = sanitizeTextBlock(sanitizeTerminalFallbackText(value).replace(/\r\n?/g, `
|
|
2603
|
+
`)).split(`
|
|
2604
|
+
`);
|
|
2605
|
+
return lines.length ? lines : [""];
|
|
2606
|
+
}
|
|
2607
|
+
function hasVisibleOutput(value) {
|
|
2608
|
+
return value.some((line) => line.trim().length > 0);
|
|
2609
|
+
}
|
|
2610
|
+
function errorMessage(error) {
|
|
2611
|
+
return error instanceof Error ? error.message : String(error);
|
|
2612
|
+
}
|
|
2613
|
+
function positiveInt(value) {
|
|
2614
|
+
let n = Math.floor(Number(value));
|
|
2615
|
+
return Number.isFinite(n) && n > 0 ? n : void 0;
|
|
2616
|
+
}
|
|
2617
|
+
function finiteInt(value) {
|
|
2618
|
+
let n = Math.floor(Number(value));
|
|
2619
|
+
return Number.isFinite(n) ? n : void 0;
|
|
2620
|
+
}
|
|
2621
|
+
function clampNumber(value, min, max) {
|
|
2622
|
+
return Math.max(min, Math.min(max, value));
|
|
2623
|
+
}
|
|
2624
|
+
function rectArea(rect) {
|
|
2625
|
+
return Math.max(0, rect.w) * Math.max(0, rect.h);
|
|
2626
|
+
}
|
|
2627
|
+
function sameRect(a, b) {
|
|
2628
|
+
return a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;
|
|
2629
|
+
}
|
|
2630
|
+
function subtractRect(rect, cover) {
|
|
2631
|
+
let hit = intersectRect(rect, cover);
|
|
2632
|
+
if (!hit)
|
|
2633
|
+
return [rect];
|
|
2634
|
+
let out = [], rectRight = rect.x + rect.w, rectBottom = rect.y + rect.h, hitRight = hit.x + hit.w, hitBottom = hit.y + hit.h;
|
|
2635
|
+
return hit.y > rect.y && out.push({ x: rect.x, y: rect.y, w: rect.w, h: hit.y - rect.y }), hitBottom < rectBottom && out.push({ x: rect.x, y: hitBottom, w: rect.w, h: rectBottom - hitBottom }), hit.x > rect.x && out.push({ x: rect.x, y: hit.y, w: hit.x - rect.x, h: hit.h }), hitRight < rectRight && out.push({ x: hitRight, y: hit.y, w: rectRight - hitRight, h: hit.h }), out.filter((part) => part.w > 0 && part.h > 0);
|
|
2636
|
+
}
|
|
2637
|
+
function largestUncoveredRect(rect, covers) {
|
|
2638
|
+
let parts = [rect];
|
|
2639
|
+
for (let cover of covers)
|
|
2640
|
+
if (parts = parts.flatMap((part) => subtractRect(part, cover)), !parts.length)
|
|
2641
|
+
return null;
|
|
2642
|
+
return parts.sort((a, b) => rectArea(b) - rectArea(a) || a.y - b.y || a.x - b.x), parts[0] ?? null;
|
|
2643
|
+
}
|
|
2644
|
+
function parseKittyClearControls(sequence) {
|
|
2645
|
+
let prefix = "\x1B_G", terminator = "\x1B\\";
|
|
2646
|
+
if (!sequence.startsWith(prefix) || !sequence.endsWith(terminator))
|
|
2647
|
+
return null;
|
|
2648
|
+
let body = sequence.slice(prefix.length, -terminator.length);
|
|
2649
|
+
if (body.includes(terminator) || body.includes("\x1B") || body.includes("\x07"))
|
|
2650
|
+
return null;
|
|
2651
|
+
let semicolon = body.indexOf(";"), rawControls = semicolon >= 0 ? body.slice(0, semicolon) : body, controls = /* @__PURE__ */ new Map();
|
|
2652
|
+
for (let part of rawControls.split(",")) {
|
|
2653
|
+
let eq = part.indexOf("=");
|
|
2654
|
+
if (eq <= 0)
|
|
2655
|
+
return null;
|
|
2656
|
+
controls.set(part.slice(0, eq), part.slice(eq + 1));
|
|
2657
|
+
}
|
|
2658
|
+
return controls;
|
|
2659
|
+
}
|
|
2660
|
+
function kittyClearTargetsComponent(sequence, imageId, placementId) {
|
|
2661
|
+
let controls = parseKittyClearControls(sequence);
|
|
2662
|
+
if (!controls)
|
|
2663
|
+
return !1;
|
|
2664
|
+
let mode = controls.get("d");
|
|
2665
|
+
return mode !== "i" && mode !== "I" ? !1 : controls.get("i") === String(imageId) && controls.get("p") === String(placementId);
|
|
2666
|
+
}
|
|
2667
|
+
function isSafeComponentClearSequence(sequence, protocol, imageId, placementId) {
|
|
2668
|
+
return isSafeTerminalGraphicsSequence(sequence, protocol, "clear") ? protocol !== "kitty" || kittyClearTargetsComponent(sequence, imageId, placementId) : !1;
|
|
2669
|
+
}
|
|
2670
|
+
var textEncoder = null;
|
|
2671
|
+
function stringByteLength(value) {
|
|
2672
|
+
if (typeof TextEncoder < "u")
|
|
2673
|
+
return textEncoder ?? (textEncoder = new TextEncoder()), textEncoder.encode(value).length;
|
|
2674
|
+
let bytes = 0;
|
|
2675
|
+
for (let index = 0; index < value.length; index++) {
|
|
2676
|
+
let code = value.charCodeAt(index);
|
|
2677
|
+
code <= 127 ? bytes += 1 : code <= 2047 ? bytes += 2 : code >= 55296 && code <= 56319 && index + 1 < value.length ? (bytes += 4, index++) : bytes += 3;
|
|
2678
|
+
}
|
|
2679
|
+
return bytes;
|
|
2680
|
+
}
|
|
2681
|
+
function smallHash(input) {
|
|
2682
|
+
let hash = 2166136261;
|
|
2683
|
+
for (let i = 0; i < input.length; i++)
|
|
2684
|
+
hash ^= input.charCodeAt(i), hash = Math.imul(hash, 16777619);
|
|
2685
|
+
return (hash >>> 0).toString(36);
|
|
2686
|
+
}
|
|
2687
|
+
var tAgentTerminalGraphicProps = {
|
|
2688
|
+
x: { type: Number, required: !0 },
|
|
2689
|
+
y: { type: Number, required: !0 },
|
|
2690
|
+
w: { type: Number, required: !0 },
|
|
2691
|
+
h: { type: Number, default: void 0 },
|
|
2692
|
+
zIndex: { type: Number, default: 0 },
|
|
2693
|
+
content: { type: String, required: !0 },
|
|
2694
|
+
kind: {
|
|
2695
|
+
type: String,
|
|
2696
|
+
default: "image"
|
|
2697
|
+
},
|
|
2698
|
+
fallback: { type: String, default: void 0 },
|
|
2699
|
+
style: { type: Object, default: void 0 },
|
|
2700
|
+
loadingStyle: { type: Object, default: void 0 },
|
|
2701
|
+
errorStyle: { type: Object, default: void 0 },
|
|
2702
|
+
clear: { type: Boolean, default: !0 },
|
|
2703
|
+
final: { type: Boolean, default: !0 },
|
|
2704
|
+
streaming: { type: Boolean, default: !1 },
|
|
2705
|
+
renderer: {
|
|
2706
|
+
type: Function,
|
|
2707
|
+
default: void 0
|
|
2708
|
+
},
|
|
2709
|
+
loadingText: {
|
|
2710
|
+
type: String,
|
|
2711
|
+
default: "Rendering terminal graphic..."
|
|
2712
|
+
},
|
|
2713
|
+
deferRenderUntilVisible: { type: Boolean, default: !0 },
|
|
2714
|
+
suspendRawWhileScrolling: { type: Boolean, default: !0 },
|
|
2715
|
+
suspendRenderWhileScrolling: { type: Boolean, default: !0 },
|
|
2716
|
+
scrolling: { type: Boolean, default: !1 },
|
|
2717
|
+
scrollVersion: { type: Number, default: 0 },
|
|
2718
|
+
placementMoveWithoutClear: { type: Boolean, default: !1 },
|
|
2719
|
+
preserveRawWhileRendering: { type: Boolean, default: !1 },
|
|
2720
|
+
suspended: { type: Boolean, default: !1 },
|
|
2721
|
+
retainRawWhileCovered: { type: Boolean, default: !1 },
|
|
2722
|
+
ignoreRawCoverage: { type: Boolean, default: !1 },
|
|
2723
|
+
ignoreSamePlaneRawCoverage: { type: Boolean, default: !1 },
|
|
2724
|
+
cacheKey: { type: String, default: void 0 },
|
|
2725
|
+
placementKey: { type: String, default: void 0 },
|
|
2726
|
+
trace: {
|
|
2727
|
+
type: Function,
|
|
2728
|
+
default: void 0
|
|
2729
|
+
}
|
|
2730
|
+
};
|
|
2731
|
+
function terminalDrawKey(current, rect, clearSequence, resizeSequence) {
|
|
2732
|
+
return [
|
|
2733
|
+
current.protocol,
|
|
2734
|
+
rect.x,
|
|
2735
|
+
rect.y,
|
|
2736
|
+
rect.w,
|
|
2737
|
+
rect.h,
|
|
2738
|
+
current.sequenceHash,
|
|
2739
|
+
clearSequence === current.clearSequence ? current.clearSequenceHash ?? "" : smallHash(clearSequence ?? ""),
|
|
2740
|
+
resizeSequence === current.resizeSequence ? current.resizeSequenceHash ?? "" : smallHash(resizeSequence ?? "")
|
|
2741
|
+
].join(":");
|
|
2742
|
+
}
|
|
2743
|
+
var TAgentTerminalGraphic = (0, import_vue10.defineComponent)({
|
|
2744
|
+
name: "TAgentTerminalGraphic",
|
|
2745
|
+
props: tAgentTerminalGraphicProps,
|
|
2746
|
+
setup(props) {
|
|
2747
|
+
let instance = (0, import_vue10.getCurrentInstance)(), { terminal, defaultStyle, scheduler, widthProvider, render } = useTerminal(), layout = useLayout(), { visible, rootProps } = useVisibility(), graphicsActivity = (0, import_vue10.inject)(TerminalGraphicsActivityKey, null), status = (0, import_vue10.shallowRef)("idle"), error = (0, import_vue10.shallowRef)(""), graphic = (0, import_vue10.shallowRef)(null), documentVersion = (0, import_vue10.shallowRef)(0), builtOnce = !1, renderVersion = 0, renderAbort = null, alive = !0, lastRenderedContent = "", lastRenderRawVisible = !1, lastRenderProtocol = null, lastRenderGraphicsOutputVersion = 0, rawIdSeed = props.placementKey ? `placement:${props.placementKey}` : props.cacheKey ? `cache:${props.cacheKey}` : `instance:${instance?.uid ?? "unknown"}`, rawId = `TAgentTerminalGraphic:${smallHash(rawIdSeed)}`, frameTaskId = `${rawId}:render`, lastDrawnGraphic = (0, import_vue10.shallowRef)(null), rawClearPendingRepaint = (0, import_vue10.shallowRef)(null), rawDrawRejectedKey = (0, import_vue10.shallowRef)(null), reservedTerminalGraphicSize = (0, import_vue10.shallowRef)(null), terminalSizeVersion = (0, import_vue10.shallowRef)(0), renderNodeId = (0, import_vue10.shallowRef)(null), lastRawSkipScrollKey = "", lastDeferTraceKey = "", isParentScrolling = (0, import_vue10.computed)(
|
|
2748
|
+
() => props.scrolling || !!graphicsActivity?.scrolling.value
|
|
2749
|
+
), graphicsActivityVersion = (0, import_vue10.computed)(
|
|
2750
|
+
() => (graphicsActivity?.version.value ?? 0) + Math.floor(Number(props.scrollVersion ?? 0))
|
|
2751
|
+
), graphicsOutput = () => getTerminalGraphicsOutput(terminal), graphicsOutputVersion = (0, import_vue10.shallowRef)(getTerminalGraphicsOutputVersion(terminal)), unsubscribeGraphicsOutput = subscribeTerminalGraphicsOutput(terminal, () => {
|
|
2752
|
+
graphicsOutputVersion.value = getTerminalGraphicsOutputVersion(terminal);
|
|
2753
|
+
}), unsubscribeTerminalResize = terminal.on("resize", () => {
|
|
2754
|
+
terminalSizeVersion.value++;
|
|
2755
|
+
}), fallbackText = () => props.fallback ?? (props.kind === "math" ? props.content : ""), contentIdentity = (0, import_vue10.computed)(() => `${props.content.length}:${smallHash(props.content)}`), stableGraphicKey = (0, import_vue10.computed)(
|
|
2756
|
+
() => [
|
|
2757
|
+
rawIdSeed,
|
|
2758
|
+
props.cacheKey ?? "",
|
|
2759
|
+
props.kind,
|
|
2760
|
+
contentIdentity.value,
|
|
2761
|
+
props.w,
|
|
2762
|
+
props.h ?? "",
|
|
2763
|
+
props.final ? "final" : "draft"
|
|
2764
|
+
].join("")
|
|
2765
|
+
), imageId = (0, import_vue10.computed)(
|
|
2766
|
+
() => stableTerminalGraphicNumericId(`image:${stableGraphicKey.value}`)
|
|
2767
|
+
), placementId = (0, import_vue10.computed)(
|
|
2768
|
+
() => stableTerminalGraphicNumericId(`placement:${stableGraphicKey.value}`)
|
|
2769
|
+
);
|
|
2770
|
+
function rememberTerminalGraphicSize(current) {
|
|
2771
|
+
if (current.type !== "terminal")
|
|
2772
|
+
return;
|
|
2773
|
+
let rows = positiveInt(current.rows);
|
|
2774
|
+
rows && (reservedTerminalGraphicSize.value = {
|
|
2775
|
+
key: stableGraphicKey.value,
|
|
2776
|
+
rows
|
|
2777
|
+
});
|
|
2778
|
+
}
|
|
2779
|
+
function bump() {
|
|
2780
|
+
documentVersion.value++;
|
|
2781
|
+
}
|
|
2782
|
+
function currentCapabilities() {
|
|
2783
|
+
return graphicsOutput()?.capabilities ?? NO_GRAPHICS_CAPABILITIES;
|
|
2784
|
+
}
|
|
2785
|
+
function trace(type, extra = {}) {
|
|
2786
|
+
let capabilities = currentCapabilities();
|
|
2787
|
+
try {
|
|
2788
|
+
props.trace?.({
|
|
2789
|
+
type,
|
|
2790
|
+
id: rawId,
|
|
2791
|
+
kind: props.kind,
|
|
2792
|
+
protocol: capabilities.protocol,
|
|
2793
|
+
contentHash: smallHash(props.content),
|
|
2794
|
+
...extra
|
|
2795
|
+
});
|
|
2796
|
+
} catch {
|
|
2797
|
+
}
|
|
2798
|
+
let protocol = isTerminalGraphicsProtocol(capabilities.protocol) ? capabilities.protocol : void 0, key = props.cacheKey ?? smallHash(props.content);
|
|
2799
|
+
type === "render-start" ? recordTerminalGraphicTrace({ type: "renderer-start", id: rawId, key, protocol }) : type === "render-end" ? recordTerminalGraphicTrace({
|
|
2800
|
+
type: extra.reason ? "renderer-error" : "renderer-end",
|
|
2801
|
+
id: rawId,
|
|
2802
|
+
key,
|
|
2803
|
+
protocol,
|
|
2804
|
+
durationMs: extra.durationMs,
|
|
2805
|
+
bytes: extra.sequenceBytes,
|
|
2806
|
+
error: extra.reason
|
|
2807
|
+
}) : type === "defer" ? recordTerminalGraphicTrace({
|
|
2808
|
+
type: extra.reason === "scrolling" ? "skip-scrolling" : "skip-hidden",
|
|
2809
|
+
id: rawId,
|
|
2810
|
+
key,
|
|
2811
|
+
protocol,
|
|
2812
|
+
reason: extra.reason
|
|
2813
|
+
}) : type === "raw-draw" || (type === "render-abort" ? recordTerminalGraphicTrace({
|
|
2814
|
+
type: "renderer-abort",
|
|
2815
|
+
id: rawId,
|
|
2816
|
+
key,
|
|
2817
|
+
protocol,
|
|
2818
|
+
reason: extra.reason
|
|
2819
|
+
}) : type === "raw-clear" ? recordTerminalGraphicTrace({ type: "clear", id: rawId, key, protocol }) : type === "raw-skip-scroll" && recordTerminalGraphicTrace({
|
|
2820
|
+
type: "skip-scrolling",
|
|
2821
|
+
id: rawId,
|
|
2822
|
+
key,
|
|
2823
|
+
protocol,
|
|
2824
|
+
reason: extra.reason
|
|
2825
|
+
}));
|
|
2826
|
+
}
|
|
2827
|
+
function traceDeferOnce(reason) {
|
|
2828
|
+
let key = [reason, graphicsActivityVersion.value, stableGraphicKey.value].join(":");
|
|
2829
|
+
lastDeferTraceKey !== key && (lastDeferTraceKey = key, trace("defer", { reason }));
|
|
2830
|
+
}
|
|
2831
|
+
function abortCurrentRender(reason) {
|
|
2832
|
+
renderAbort && (renderAbort.abort(), renderAbort = null, trace("render-abort", { reason }));
|
|
2833
|
+
}
|
|
2834
|
+
function normalizeResult(result) {
|
|
2835
|
+
if (result == null)
|
|
2836
|
+
return {
|
|
2837
|
+
type: "text",
|
|
2838
|
+
text: fallbackText()
|
|
2839
|
+
};
|
|
2840
|
+
if (typeof result == "string")
|
|
2841
|
+
return {
|
|
2842
|
+
type: "text",
|
|
2843
|
+
text: result
|
|
2844
|
+
};
|
|
2845
|
+
if (typeof result != "object")
|
|
2846
|
+
return {
|
|
2847
|
+
type: "text",
|
|
2848
|
+
text: fallbackText()
|
|
2849
|
+
};
|
|
2850
|
+
if ("type" in result && result.type === "text")
|
|
2851
|
+
return {
|
|
2852
|
+
type: "text",
|
|
2853
|
+
text: result.text
|
|
2854
|
+
};
|
|
2855
|
+
let maybeRaw = result;
|
|
2856
|
+
if (!(maybeRaw.type === "sequence" || "sequence" in result || "protocol" in result) && "text" in result)
|
|
2857
|
+
return {
|
|
2858
|
+
type: "text",
|
|
2859
|
+
text: result.text
|
|
2860
|
+
};
|
|
2861
|
+
let sequence = typeof maybeRaw.sequence == "string" ? maybeRaw.sequence : "", protocol = isTerminalGraphicsProtocol(maybeRaw.protocol) ? maybeRaw.protocol : null, fallback = typeof maybeRaw.fallback == "string" ? sanitizeTerminalFallbackText(maybeRaw.fallback) : fallbackText(), fallbackFromProps = typeof maybeRaw.fallback != "string";
|
|
2862
|
+
if (!sequence || !protocol || !isSafeTerminalGraphicsSequence(sequence, protocol, "draw"))
|
|
2863
|
+
return {
|
|
2864
|
+
type: "text",
|
|
2865
|
+
text: fallback
|
|
2866
|
+
};
|
|
2867
|
+
let rawClear = typeof maybeRaw.clearSequence == "string" ? maybeRaw.clearSequence : void 0, clearSequence = rawClear && isSafeComponentClearSequence(rawClear, protocol, imageId.value, placementId.value) ? rawClear : void 0, rawResize = typeof maybeRaw.resizeSequence == "string" ? maybeRaw.resizeSequence : void 0, resizeSequence = rawResize && isSafeTerminalGraphicsSequence(rawResize, protocol, "draw") ? rawResize : void 0, declaredRows = positiveInt(maybeRaw.rows), declaredCols = positiveInt(maybeRaw.cols), sourceWidth = positiveInt(maybeRaw.sourceWidth), sourceHeight = positiveInt(maybeRaw.sourceHeight), zIndex = finiteInt(maybeRaw.zIndex), declaredSize = declaredRows == null ? null : normalizeTerminalGraphicSize(declaredCols ?? props.w, declaredRows);
|
|
2868
|
+
return {
|
|
2869
|
+
type: "terminal",
|
|
2870
|
+
protocol,
|
|
2871
|
+
sequence,
|
|
2872
|
+
sequenceHash: smallHash(sequence),
|
|
2873
|
+
sequenceBytes: stringByteLength(sequence),
|
|
2874
|
+
fallback,
|
|
2875
|
+
fallbackFromProps,
|
|
2876
|
+
clearSequence,
|
|
2877
|
+
clearSequenceHash: clearSequence ? smallHash(clearSequence) : void 0,
|
|
2878
|
+
resizeSequence,
|
|
2879
|
+
resizeSequenceHash: resizeSequence ? smallHash(resizeSequence) : void 0,
|
|
2880
|
+
cols: declaredRows == null ? declaredCols : declaredSize?.width,
|
|
2881
|
+
rows: declaredSize?.height,
|
|
2882
|
+
sourceWidth,
|
|
2883
|
+
sourceHeight,
|
|
2884
|
+
zIndex
|
|
2885
|
+
};
|
|
2886
|
+
}
|
|
2887
|
+
function defaultClearSequence(protocol) {
|
|
2888
|
+
return protocol === "kitty" ? createKittyDeleteGraphicsSequence({
|
|
2889
|
+
imageId: imageId.value,
|
|
2890
|
+
placementId: placementId.value
|
|
2891
|
+
}) : "";
|
|
2892
|
+
}
|
|
2893
|
+
function resolveClearSequence(current) {
|
|
2894
|
+
if (current.clearSequence)
|
|
2895
|
+
return current.clearSequence;
|
|
2896
|
+
let candidate = defaultClearSequence(current.protocol);
|
|
2897
|
+
if (candidate)
|
|
2898
|
+
return isSafeComponentClearSequence(
|
|
2899
|
+
candidate,
|
|
2900
|
+
current.protocol,
|
|
2901
|
+
imageId.value,
|
|
2902
|
+
placementId.value
|
|
2903
|
+
) ? candidate : void 0;
|
|
2904
|
+
}
|
|
2905
|
+
function resolveResizeSequence(current, rect, full) {
|
|
2906
|
+
if (current.protocol !== "kitty")
|
|
2907
|
+
return current.resizeSequence;
|
|
2908
|
+
let sourceWidth = positiveInt(current.sourceWidth), sourceHeight = positiveInt(current.sourceHeight);
|
|
2909
|
+
if (!sourceWidth || !sourceHeight || full.w <= 0 || full.h <= 0)
|
|
2910
|
+
return current.resizeSequence;
|
|
2911
|
+
let offsetX = Math.max(0, rect.x - full.x), offsetY = Math.max(0, rect.y - full.y), visibleW = Math.max(0, Math.min(rect.w, full.w - offsetX)), visibleH = Math.max(0, Math.min(rect.h, full.h - offsetY)), x0 = clampNumber(Math.floor(offsetX * sourceWidth / full.w), 0, sourceWidth - 1), y0 = clampNumber(Math.floor(offsetY * sourceHeight / full.h), 0, sourceHeight - 1), x1 = Math.max(
|
|
2912
|
+
x0 + 1,
|
|
2913
|
+
clampNumber(Math.ceil((offsetX + visibleW) * sourceWidth / full.w), 1, sourceWidth)
|
|
2914
|
+
), y1 = Math.max(
|
|
2915
|
+
y0 + 1,
|
|
2916
|
+
clampNumber(Math.ceil((offsetY + visibleH) * sourceHeight / full.h), 1, sourceHeight)
|
|
2917
|
+
);
|
|
2918
|
+
return createKittyPlacementSequence({
|
|
2919
|
+
imageId: imageId.value,
|
|
2920
|
+
placementId: placementId.value,
|
|
2921
|
+
columns: rect.w,
|
|
2922
|
+
rows: rect.h,
|
|
2923
|
+
sourceX: x0,
|
|
2924
|
+
sourceY: y0,
|
|
2925
|
+
sourceWidth: x1 - x0,
|
|
2926
|
+
sourceHeight: y1 - y0,
|
|
2927
|
+
zIndex: current.zIndex
|
|
2928
|
+
});
|
|
2929
|
+
}
|
|
2930
|
+
function queueClearLastGraphic(options = {}) {
|
|
2931
|
+
let previous = lastDrawnGraphic.value;
|
|
2932
|
+
if (!previous)
|
|
2933
|
+
return !1;
|
|
2934
|
+
let output = graphicsOutput(), accepted = !1;
|
|
2935
|
+
if (output?.clear && !previous.retainOnClear)
|
|
2936
|
+
try {
|
|
2937
|
+
accepted = !!output.clear(previous.id);
|
|
2938
|
+
} catch {
|
|
2939
|
+
accepted = !1;
|
|
2940
|
+
}
|
|
2941
|
+
if (!accepted && output && previous.clearSequence)
|
|
2942
|
+
try {
|
|
2943
|
+
accepted = output.queue({
|
|
2944
|
+
id: previous.id,
|
|
2945
|
+
x: previous.x,
|
|
2946
|
+
y: previous.y,
|
|
2947
|
+
w: previous.w,
|
|
2948
|
+
h: previous.h,
|
|
2949
|
+
protocol: previous.protocol,
|
|
2950
|
+
sequence: previous.clearSequence,
|
|
2951
|
+
deferFlush: !0,
|
|
2952
|
+
retainOnClear: previous.retainOnClear,
|
|
2953
|
+
op: "clear"
|
|
2954
|
+
});
|
|
2955
|
+
} catch {
|
|
2956
|
+
accepted = !1;
|
|
2957
|
+
}
|
|
2958
|
+
return accepted && ((options.markPendingRepaint ?? !0) && (rawClearPendingRepaint.value = previous), lastDrawnGraphic.value = null, trace("raw-clear", {
|
|
2959
|
+
x: previous.x,
|
|
2960
|
+
y: previous.y,
|
|
2961
|
+
w: previous.w,
|
|
2962
|
+
h: previous.h
|
|
2963
|
+
})), accepted;
|
|
2964
|
+
}
|
|
2965
|
+
function queueDrawGraphic(output, current, rect, full = rect, options = {}) {
|
|
2966
|
+
let clearSequence = resolveClearSequence(current), resizeSequence = resolveResizeSequence(current, rect, full), drawKey = terminalDrawKey(current, rect, clearSequence, resizeSequence), activePrevious = lastDrawnGraphic.value, retainedPrevious = rawClearPendingRepaint.value, previous = activePrevious ?? retainedPrevious, previousIsRetained = activePrevious == null && retainedPrevious != null, previousStillActive = previous ? typeof output.isActive == "function" ? output.isActive(previous.id) : !0 : !1, preservePreviousForAtomicReplace = props.preserveRawWhileRendering && activePrevious != null && !previousIsRetained && previousStillActive;
|
|
2967
|
+
if (!previousIsRetained && !options.force && previous?.drawKey === drawKey && previousStillActive)
|
|
2968
|
+
return !1;
|
|
2969
|
+
let canReusePlacementSequence = previousStillActive && previous?.protocol === current.protocol && previous.sequenceHash === current.sequenceHash && current.protocol === "kitty" && !!resizeSequence, scrollVersion = Math.floor(Number(props.scrollVersion ?? 0)), canMoveWithoutClear = canReusePlacementSequence && !!options.placementMoveWithoutClear;
|
|
2970
|
+
if (!previousIsRetained && previousStillActive && !resizeSequence && previous?.protocol === current.protocol && previous.sequenceHash === current.sequenceHash && previous.x === rect.x && previous.y === rect.y && rect.w <= previous.w && rect.h <= previous.h && (options.force || !sameRect(rect, full)))
|
|
2971
|
+
return lastDrawnGraphic.value = {
|
|
2972
|
+
...previous,
|
|
2973
|
+
w: rect.w,
|
|
2974
|
+
h: rect.h,
|
|
2975
|
+
clearSequence,
|
|
2976
|
+
resizeSequence,
|
|
2977
|
+
drawKey,
|
|
2978
|
+
activityVersion: graphicsActivityVersion.value,
|
|
2979
|
+
scrollVersion
|
|
2980
|
+
}, lastRawSkipScrollKey = "", !1;
|
|
2981
|
+
if (previousStillActive && !previousIsRetained && !canReusePlacementSequence && !preservePreviousForAtomicReplace) {
|
|
2982
|
+
if (!queueClearLastGraphic({ markPendingRepaint: !1 }))
|
|
2983
|
+
return !1;
|
|
2984
|
+
} else
|
|
2985
|
+
previous && (previousStillActive || (lastDrawnGraphic.value = null, rawClearPendingRepaint.value = null));
|
|
2986
|
+
let accepted = !1;
|
|
2987
|
+
try {
|
|
2988
|
+
accepted = output.queue({
|
|
2989
|
+
id: rawId,
|
|
2990
|
+
x: rect.x,
|
|
2991
|
+
y: rect.y,
|
|
2992
|
+
w: rect.w,
|
|
2993
|
+
h: rect.h,
|
|
2994
|
+
protocol: current.protocol,
|
|
2995
|
+
sequence: canReusePlacementSequence && resizeSequence ? resizeSequence : current.sequence,
|
|
2996
|
+
resizeSequence,
|
|
2997
|
+
clearSequence,
|
|
2998
|
+
retainOnClear: !!(props.cacheKey && resizeSequence),
|
|
2999
|
+
resizeRedraw: canReusePlacementSequence,
|
|
3000
|
+
placementMoveWithoutClear: canMoveWithoutClear,
|
|
3001
|
+
allowTextOverlay: options.allowTextOverlay,
|
|
3002
|
+
forceDraw: options.force,
|
|
3003
|
+
deferFlush: options.deferFlush ?? !0,
|
|
3004
|
+
fallbackText: current.fallback
|
|
3005
|
+
});
|
|
3006
|
+
} catch {
|
|
3007
|
+
accepted = !1;
|
|
3008
|
+
}
|
|
3009
|
+
return accepted ? (rawDrawRejectedKey.value = null, rawClearPendingRepaint.value = null, lastDrawnGraphic.value = {
|
|
3010
|
+
id: rawId,
|
|
3011
|
+
x: rect.x,
|
|
3012
|
+
y: rect.y,
|
|
3013
|
+
w: rect.w,
|
|
3014
|
+
h: rect.h,
|
|
3015
|
+
protocol: current.protocol,
|
|
3016
|
+
sequenceHash: current.sequenceHash,
|
|
3017
|
+
clearSequence,
|
|
3018
|
+
resizeSequence,
|
|
3019
|
+
retainOnClear: !!(props.cacheKey && resizeSequence),
|
|
3020
|
+
allowTextOverlay: !!options.allowTextOverlay,
|
|
3021
|
+
drawKey,
|
|
3022
|
+
activityVersion: graphicsActivityVersion.value,
|
|
3023
|
+
scrollVersion
|
|
3024
|
+
}, lastRawSkipScrollKey = "", !0) : (preservePreviousForAtomicReplace ? (lastDrawnGraphic.value = activePrevious, queueClearLastGraphic({ markPendingRepaint: !1 })) : lastDrawnGraphic.value = null, rawDrawRejectedKey.value !== drawKey && (rawDrawRejectedKey.value = drawKey, scheduler.invalidate({ priority: "low", reason: "data" })), !1);
|
|
3025
|
+
}
|
|
3026
|
+
function hasRetainedActiveRawGraphic() {
|
|
3027
|
+
let output = graphicsOutput();
|
|
3028
|
+
return !!(status.value === "loading" && !graphic.value && output && typeof output.isActive == "function" && output.isActive(rawId));
|
|
3029
|
+
}
|
|
3030
|
+
let showingInitialLoadingText = (0, import_vue10.computed)(
|
|
3031
|
+
() => status.value === "loading" && !graphic.value && !hasRetainedActiveRawGraphic()
|
|
3032
|
+
), fullRect = (0, import_vue10.computed)(() => {
|
|
3033
|
+
let current = graphic.value, reserved = reservedTerminalGraphicSize.value, reservedRows = current?.type === "terminal" ? void 0 : status.value === "idle" && reserved?.key === stableGraphicKey.value ? reserved.rows : void 0, textLines = current?.type === "text" ? splitTextOutput(current.text) : splitTextOutput(fallbackText()), height = props.h ?? (current?.type === "terminal" ? current.rows : void 0) ?? reservedRows ?? Math.max(1, textLines.length);
|
|
3034
|
+
return translateRect(
|
|
3035
|
+
{ x: props.x, y: props.y, w: props.w, h: height },
|
|
3036
|
+
layout.originX,
|
|
3037
|
+
layout.originY
|
|
3038
|
+
);
|
|
3039
|
+
}), absRect = (0, import_vue10.computed)(() => {
|
|
3040
|
+
terminalSizeVersion.value;
|
|
3041
|
+
let translated = fullRect.value, size = terminal.size(), terminalClip = {
|
|
3042
|
+
x: 0,
|
|
3043
|
+
y: 0,
|
|
3044
|
+
w: Math.max(0, Math.floor(size.cols)),
|
|
3045
|
+
h: Math.max(0, Math.floor(size.rows))
|
|
3046
|
+
}, clip = layout.clipRect ? intersectRect(layout.clipRect, terminalClip) : terminalClip;
|
|
3047
|
+
return clip ? intersectRect(translated, clip) ?? { x: 0, y: 0, w: 0, h: 0 } : { x: 0, y: 0, w: 0, h: 0 };
|
|
3048
|
+
}), renderRect = (0, import_vue10.computed)(() => absRect.value);
|
|
3049
|
+
function rawRectFitsTerminalViewport(rect) {
|
|
3050
|
+
return canDrawTerminalGraphicRect(rect, terminal.size());
|
|
3051
|
+
}
|
|
3052
|
+
function rawCoveredByHigherRenderNode(rect = fullRect.value) {
|
|
3053
|
+
if (props.retainRawWhileCovered)
|
|
3054
|
+
return !1;
|
|
3055
|
+
let id = renderNodeId.value;
|
|
3056
|
+
return !props.ignoreRawCoverage && id != null && render.isRectCoveredByHigherNode(id, rect, {
|
|
3057
|
+
ignoreSamePlane: props.ignoreSamePlaneRawCoverage
|
|
3058
|
+
});
|
|
3059
|
+
}
|
|
3060
|
+
function retainedRawCoveredByHigherRenderNode(rect) {
|
|
3061
|
+
if (!props.retainRawWhileCovered)
|
|
3062
|
+
return !1;
|
|
3063
|
+
let id = renderNodeId.value;
|
|
3064
|
+
return !!(id != null && render.isRectCoveredByHigherNode(id, rect, {
|
|
3065
|
+
ignoreSamePlane: props.ignoreSamePlaneRawCoverage
|
|
3066
|
+
}));
|
|
3067
|
+
}
|
|
3068
|
+
function rawUncoveredRenderRect(rect) {
|
|
3069
|
+
if (props.retainRawWhileCovered)
|
|
3070
|
+
return rect;
|
|
3071
|
+
let id = renderNodeId.value;
|
|
3072
|
+
if (id == null)
|
|
3073
|
+
return rect;
|
|
3074
|
+
let covers = render.higherNodeCoverageRects(id, rect, {
|
|
3075
|
+
ignoreSamePlane: props.ignoreSamePlaneRawCoverage
|
|
3076
|
+
});
|
|
3077
|
+
return covers.length ? props.ignoreRawCoverage ? largestUncoveredRect(rect, covers) : null : rect;
|
|
3078
|
+
}
|
|
3079
|
+
let rawCanRender = (0, import_vue10.computed)(() => {
|
|
3080
|
+
graphicsOutputVersion.value, terminalSizeVersion.value;
|
|
3081
|
+
let current = graphic.value, output = graphicsOutput(), rect = absRect.value;
|
|
3082
|
+
return current?.type === "terminal" && rawRectFitsTerminalViewport(rect) && !!output?.capabilities.supported && output?.capabilities.preferredProtocol === current.protocol;
|
|
3083
|
+
}), rawOutputCanRenderValue = (0, import_vue10.computed)(() => (graphicsOutputVersion.value, terminalSizeVersion.value, rawOutputCanRender())), rawSuppressedByScroll = (0, import_vue10.computed)(
|
|
3084
|
+
() => props.suspended || props.suspendRawWhileScrolling && isParentScrolling.value
|
|
3085
|
+
), rawCanQueue = (0, import_vue10.computed)(() => rawCanRender.value && !rawSuppressedByScroll.value);
|
|
3086
|
+
function traceRawSkipScrollOnce(reason) {
|
|
3087
|
+
let r = absRect.value, key = [
|
|
3088
|
+
reason,
|
|
3089
|
+
graphicsActivityVersion.value,
|
|
3090
|
+
stableGraphicKey.value,
|
|
3091
|
+
r.x,
|
|
3092
|
+
r.y,
|
|
3093
|
+
r.w,
|
|
3094
|
+
r.h
|
|
3095
|
+
].join(":");
|
|
3096
|
+
lastRawSkipScrollKey !== key && (lastRawSkipScrollKey = key, trace("raw-skip-scroll", { reason }));
|
|
3097
|
+
}
|
|
3098
|
+
function hasPaintableRect() {
|
|
3099
|
+
let r = absRect.value;
|
|
3100
|
+
return visible.value && r.w > 0 && r.h > 0;
|
|
3101
|
+
}
|
|
3102
|
+
function rawOutputCanRender() {
|
|
3103
|
+
let output = graphicsOutput(), rect = absRect.value;
|
|
3104
|
+
return rawRectFitsTerminalViewport(rect) && !!output?.capabilities.supported;
|
|
3105
|
+
}
|
|
3106
|
+
function renderDeferReason() {
|
|
3107
|
+
return props.suspended ? "suspended" : props.deferRenderUntilVisible && !hasPaintableRect() ? "not-visible" : props.suspendRenderWhileScrolling && isParentScrolling.value ? "scrolling" : null;
|
|
3108
|
+
}
|
|
3109
|
+
function shouldDeferRender() {
|
|
3110
|
+
return renderDeferReason() != null;
|
|
3111
|
+
}
|
|
3112
|
+
function shouldRerenderForGraphicsOutputChange() {
|
|
3113
|
+
if (!props.renderer || !props.content.trim() || shouldDeferRender() || rawSuppressedByScroll.value)
|
|
3114
|
+
return !1;
|
|
3115
|
+
let protocol = currentCapabilities().protocol;
|
|
3116
|
+
return lastRenderProtocol != null && (lastRenderProtocol !== protocol || lastRenderGraphicsOutputVersion !== graphicsOutputVersion.value);
|
|
3117
|
+
}
|
|
3118
|
+
function shouldRetryTemporaryRawFallback(rawCovered = rawCoveredByHigherRenderNode()) {
|
|
3119
|
+
return !!props.renderer && props.content.trim().length > 0 && graphic.value?.type === "text" && status.value !== "loading" && !lastRenderRawVisible && rawOutputCanRenderValue.value && !rawSuppressedByScroll.value && !rawCovered;
|
|
3120
|
+
}
|
|
3121
|
+
function setDeferredFallback(content) {
|
|
3122
|
+
graphic.value = { type: "text", text: content.trim() ? fallbackText() : "" }, lastRenderedContent = content, status.value = "idle", error.value = "", bump();
|
|
3123
|
+
}
|
|
3124
|
+
function resolveRendererContext(signal) {
|
|
3125
|
+
let capabilities = currentCapabilities(), visibleNow = hasPaintableRect(), rawVisible = rawOutputCanRenderValue.value && !rawSuppressedByScroll.value && !rawCoveredByHigherRenderNode();
|
|
3126
|
+
return {
|
|
3127
|
+
kind: props.kind,
|
|
3128
|
+
width: props.w,
|
|
3129
|
+
height: props.h,
|
|
3130
|
+
final: props.final,
|
|
3131
|
+
streaming: props.streaming,
|
|
3132
|
+
protocol: capabilities.protocol,
|
|
3133
|
+
capabilities,
|
|
3134
|
+
signal,
|
|
3135
|
+
imageId: imageId.value,
|
|
3136
|
+
placementId: placementId.value,
|
|
3137
|
+
visible: visibleNow,
|
|
3138
|
+
rawVisible,
|
|
3139
|
+
scrolling: isParentScrolling.value,
|
|
3140
|
+
cacheKey: props.cacheKey,
|
|
3141
|
+
viewport: {
|
|
3142
|
+
visible: visibleNow,
|
|
3143
|
+
rawVisible,
|
|
3144
|
+
scrolling: isParentScrolling.value,
|
|
3145
|
+
rect: absRect.value,
|
|
3146
|
+
fullRect: fullRect.value
|
|
3147
|
+
}
|
|
3148
|
+
};
|
|
3149
|
+
}
|
|
3150
|
+
async function renderNow(version) {
|
|
3151
|
+
let protocol = currentCapabilities().protocol;
|
|
3152
|
+
recordTerminalGraphicTrace({
|
|
3153
|
+
type: "request",
|
|
3154
|
+
id: rawId,
|
|
3155
|
+
key: props.cacheKey ?? smallHash(props.content),
|
|
3156
|
+
protocol: isTerminalGraphicsProtocol(protocol) ? protocol : void 0
|
|
3157
|
+
});
|
|
3158
|
+
let content = props.content;
|
|
3159
|
+
if (!content.trim()) {
|
|
3160
|
+
if (abortCurrentRender("superseded"), !alive || version !== renderVersion)
|
|
3161
|
+
return;
|
|
3162
|
+
graphic.value = { type: "text", text: "" }, lastRenderedContent = content, status.value = "ready", error.value = "", bump();
|
|
3163
|
+
return;
|
|
3164
|
+
}
|
|
3165
|
+
let renderer = props.renderer;
|
|
3166
|
+
if (!renderer) {
|
|
3167
|
+
if (abortCurrentRender("superseded"), !alive || version !== renderVersion)
|
|
3168
|
+
return;
|
|
3169
|
+
graphic.value = { type: "text", text: fallbackText() }, lastRenderedContent = content, status.value = "ready", error.value = "", bump();
|
|
3170
|
+
return;
|
|
3171
|
+
}
|
|
3172
|
+
let deferred = renderDeferReason();
|
|
3173
|
+
if (deferred) {
|
|
3174
|
+
if (abortCurrentRender(deferred), !alive || version !== renderVersion)
|
|
3175
|
+
return;
|
|
3176
|
+
setDeferredFallback(content), traceDeferOnce(deferred);
|
|
3177
|
+
return;
|
|
3178
|
+
}
|
|
3179
|
+
abortCurrentRender("superseded"), lastDeferTraceKey = "";
|
|
3180
|
+
let abort = new AbortController();
|
|
3181
|
+
renderAbort = abort;
|
|
3182
|
+
let startedAt = nowTerminalGraphicTraceTime();
|
|
3183
|
+
status.value = "loading", error.value = "", trace("render-start"), bump();
|
|
3184
|
+
try {
|
|
3185
|
+
let contextGraphicsOutputVersion = graphicsOutputVersion.value, context = resolveRendererContext(abort.signal);
|
|
3186
|
+
lastRenderRawVisible = context.rawVisible, lastRenderProtocol = context.protocol, lastRenderGraphicsOutputVersion = contextGraphicsOutputVersion;
|
|
3187
|
+
let result = await renderer(content, context);
|
|
3188
|
+
if (abort.signal.aborted || !alive || version !== renderVersion)
|
|
3189
|
+
return;
|
|
3190
|
+
let normalized = normalizeResult(result);
|
|
3191
|
+
rememberTerminalGraphicSize(normalized), graphic.value = normalized, lastRenderedContent = content, status.value = "ready", error.value = "", trace("render-end", {
|
|
3192
|
+
durationMs: nowTerminalGraphicTraceTime() - startedAt,
|
|
3193
|
+
sequenceChars: normalized.type === "terminal" ? normalized.sequence.length : 0,
|
|
3194
|
+
sequenceBytes: normalized.type === "terminal" ? normalized.sequenceBytes : 0
|
|
3195
|
+
}), bump(), normalized.type === "terminal" && scheduler.invalidate({ priority: "low", reason: "data" });
|
|
3196
|
+
} catch (err) {
|
|
3197
|
+
if (abort.signal.aborted || !alive || version !== renderVersion)
|
|
3198
|
+
return;
|
|
3199
|
+
graphic.value = { type: "text", text: fallbackText() }, lastRenderedContent = content, status.value = "ready", error.value = errorMessage(err), trace("render-end", {
|
|
3200
|
+
durationMs: nowTerminalGraphicTraceTime() - startedAt,
|
|
3201
|
+
reason: error.value
|
|
3202
|
+
}), bump();
|
|
3203
|
+
} finally {
|
|
3204
|
+
renderAbort === abort && (renderAbort = null);
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
function scheduleRender(options = {}) {
|
|
3208
|
+
let version = ++renderVersion;
|
|
3209
|
+
if ((options.clearLastGraphic ?? !props.preserveRawWhileRendering) && queueClearLastGraphic(), !builtOnce || !props.streaming) {
|
|
3210
|
+
builtOnce = !0, renderNow(version);
|
|
3211
|
+
return;
|
|
3212
|
+
}
|
|
3213
|
+
scheduler.queueFrameTask({
|
|
3214
|
+
id: frameTaskId,
|
|
3215
|
+
reason: "stream",
|
|
3216
|
+
priority: "low",
|
|
3217
|
+
sync: !1,
|
|
3218
|
+
run: () => {
|
|
3219
|
+
alive && version === renderVersion && renderNow(version);
|
|
3220
|
+
}
|
|
3221
|
+
}) === !1 && renderNow(version);
|
|
3222
|
+
}
|
|
3223
|
+
(0, import_vue10.watch)(
|
|
3224
|
+
[
|
|
3225
|
+
() => props.content,
|
|
3226
|
+
() => props.kind,
|
|
3227
|
+
() => props.renderer,
|
|
3228
|
+
() => props.w,
|
|
3229
|
+
() => props.h,
|
|
3230
|
+
() => props.streaming,
|
|
3231
|
+
() => props.final,
|
|
3232
|
+
() => props.deferRenderUntilVisible,
|
|
3233
|
+
() => props.suspendRawWhileScrolling,
|
|
3234
|
+
() => props.suspendRenderWhileScrolling,
|
|
3235
|
+
() => props.scrolling,
|
|
3236
|
+
() => props.preserveRawWhileRendering,
|
|
3237
|
+
() => props.suspended,
|
|
3238
|
+
() => props.retainRawWhileCovered,
|
|
3239
|
+
() => props.ignoreRawCoverage,
|
|
3240
|
+
() => props.ignoreSamePlaneRawCoverage,
|
|
3241
|
+
() => props.cacheKey,
|
|
3242
|
+
() => props.placementKey
|
|
3243
|
+
],
|
|
3244
|
+
() => {
|
|
3245
|
+
scheduleRender();
|
|
3246
|
+
},
|
|
3247
|
+
{ immediate: !0 }
|
|
3248
|
+
), (0, import_vue10.watch)(
|
|
3249
|
+
() => props.fallback,
|
|
3250
|
+
() => {
|
|
3251
|
+
let current = graphic.value;
|
|
3252
|
+
if (current?.type === "terminal") {
|
|
3253
|
+
if (current.fallbackFromProps) {
|
|
3254
|
+
graphic.value = { ...current, fallback: fallbackText() }, bump(), scheduler.invalidate({ priority: "low", reason: "data" });
|
|
3255
|
+
return;
|
|
3256
|
+
}
|
|
3257
|
+
scheduleRender({ clearLastGraphic: !1 });
|
|
3258
|
+
return;
|
|
3259
|
+
}
|
|
3260
|
+
scheduleRender();
|
|
3261
|
+
}
|
|
3262
|
+
), (0, import_vue10.watch)(
|
|
3263
|
+
() => [graphicsOutputVersion.value, rawOutputCanRenderValue.value],
|
|
3264
|
+
() => {
|
|
3265
|
+
!props.renderer || !props.content.trim() || graphic.value?.type !== "terminal" && (!rawOutputCanRenderValue.value || shouldDeferRender() || scheduleRender({ clearLastGraphic: !1 }));
|
|
3266
|
+
}
|
|
3267
|
+
), (0, import_vue10.watch)(
|
|
3268
|
+
() => [props.x, props.y, props.w, props.h, props.scrollVersion],
|
|
3269
|
+
() => {
|
|
3270
|
+
if (graphic.value?.type === "terminal") {
|
|
3271
|
+
scheduler.invalidate({ priority: "low", reason: "data" });
|
|
3272
|
+
return;
|
|
3273
|
+
}
|
|
3274
|
+
props.kind !== "image" || status.value !== "loading" || !props.renderer || scheduleRender({ clearLastGraphic: !1 });
|
|
3275
|
+
},
|
|
3276
|
+
{ flush: "sync" }
|
|
3277
|
+
), (0, import_vue10.onBeforeUnmount)(() => {
|
|
3278
|
+
alive = !1, renderVersion++, unsubscribeTerminalResize(), unsubscribeGraphicsOutput(), abortCurrentRender("unmount"), scheduler.cancelFrameTask?.(frameTaskId), queueClearLastGraphic();
|
|
3279
|
+
});
|
|
3280
|
+
function resolveDisplayLines(rawPlaceholderAllowed) {
|
|
3281
|
+
if (showingInitialLoadingText.value)
|
|
3282
|
+
return splitTextOutput(props.loadingText);
|
|
3283
|
+
let current = graphic.value;
|
|
3284
|
+
if (!current)
|
|
3285
|
+
return splitTextOutput(fallbackText());
|
|
3286
|
+
if (current.type === "terminal" && rawPlaceholderAllowed) {
|
|
3287
|
+
let clearSequence = resolveClearSequence(current), drawKey = terminalDrawKey(
|
|
3288
|
+
current,
|
|
3289
|
+
absRect.value,
|
|
3290
|
+
clearSequence,
|
|
3291
|
+
resolveResizeSequence(current, absRect.value, fullRect.value)
|
|
3292
|
+
);
|
|
3293
|
+
if (rawDrawRejectedKey.value !== drawKey)
|
|
3294
|
+
return (0, import_vue10.markRaw)([""]);
|
|
3295
|
+
}
|
|
3296
|
+
let text = current.type === "terminal" ? current.fallback : current.text, lines = splitTextOutput(text);
|
|
3297
|
+
return text.trim().length > 0 && !hasVisibleOutput(lines) ? splitTextOutput(fallbackText()) : lines;
|
|
3298
|
+
}
|
|
3299
|
+
let displayLines = (0, import_vue10.computed)(() => resolveDisplayLines(rawCanQueue.value)), currentStyle = (0, import_vue10.computed)(() => error.value ? props.errorStyle ?? props.style ?? defaultStyle.value : showingInitialLoadingText.value ? props.loadingStyle ?? props.style ?? defaultStyle.value : props.style ?? defaultStyle.value), renderNode = useRenderNode(() => ({
|
|
3300
|
+
zIndex: props.zIndex,
|
|
3301
|
+
rect: visible.value ? renderRect.value : { x: 0, y: 0, w: 0, h: 0 },
|
|
3302
|
+
deps: [
|
|
3303
|
+
visible.value,
|
|
3304
|
+
renderRect.value,
|
|
3305
|
+
fullRect.value,
|
|
3306
|
+
displayLines.value,
|
|
3307
|
+
currentStyle.value,
|
|
3308
|
+
props.clear,
|
|
3309
|
+
status.value,
|
|
3310
|
+
error.value,
|
|
3311
|
+
documentVersion.value,
|
|
3312
|
+
rawOutputCanRenderValue.value,
|
|
3313
|
+
rawCanRender.value,
|
|
3314
|
+
rawCanQueue.value,
|
|
3315
|
+
rawClearPendingRepaint.value,
|
|
3316
|
+
rawDrawRejectedKey.value,
|
|
3317
|
+
rawSuppressedByScroll.value,
|
|
3318
|
+
props.placementMoveWithoutClear,
|
|
3319
|
+
props.retainRawWhileCovered,
|
|
3320
|
+
isParentScrolling.value,
|
|
3321
|
+
graphicsActivityVersion.value,
|
|
3322
|
+
graphicsOutputVersion.value
|
|
3323
|
+
],
|
|
3324
|
+
paint: (dirtyRows) => {
|
|
3325
|
+
withTextWidthProvider(widthProvider, () => {
|
|
3326
|
+
if (!visible.value) {
|
|
3327
|
+
queueClearLastGraphic();
|
|
3328
|
+
return;
|
|
3329
|
+
}
|
|
3330
|
+
let r = absRect.value, full = fullRect.value;
|
|
3331
|
+
if (r.w <= 0 || r.h <= 0) {
|
|
3332
|
+
queueClearLastGraphic();
|
|
3333
|
+
return;
|
|
3334
|
+
}
|
|
3335
|
+
let style = currentStyle.value, dx = Math.max(0, Math.floor(r.x - full.x)), fullY = Math.floor(full.y), current = graphic.value, output = graphicsOutput(), retainedActiveRawGraphic = hasRetainedActiveRawGraphic(), rawRectForPaint = rawUncoveredRenderRect(r), rawCoverageClipped = rawRectForPaint != null && props.ignoreRawCoverage && !sameRect(rawRectForPaint, r), rawCoveredForPaint = rawRectForPaint == null && rawCoveredByHigherRenderNode(r), rawCanQueueForPaint = current?.type === "terminal" && rawCanQueue.value && rawRectForPaint != null, preserveActiveRawGraphic = !1, forceActiveRawRedraw = !1, allowTextOverlay = !1;
|
|
3336
|
+
if (rawCanQueueForPaint && output) {
|
|
3337
|
+
let previous = lastDrawnGraphic.value;
|
|
3338
|
+
if ((previous ? typeof output.isActive == "function" ? output.isActive(previous.id) : !0 : !1) && previous) {
|
|
3339
|
+
let clearSequence = resolveClearSequence(current), resizeSequence = resolveResizeSequence(current, rawRectForPaint, full);
|
|
3340
|
+
preserveActiveRawGraphic = rawClearPendingRepaint.value == null && previous.drawKey === terminalDrawKey(current, rawRectForPaint, clearSequence, resizeSequence), allowTextOverlay = retainedRawCoveredByHigherRenderNode(r), forceActiveRawRedraw = preserveActiveRawGraphic && (previous.activityVersion !== graphicsActivityVersion.value || previous.allowTextOverlay !== allowTextOverlay);
|
|
3341
|
+
}
|
|
3342
|
+
}
|
|
3343
|
+
let preserveActiveRawGraphicForPaint = preserveActiveRawGraphic, out = rawCanQueueForPaint ? displayLines.value : resolveDisplayLines(!1), clearingRawGraphic = rawClearPendingRepaint.value != null || lastDrawnGraphic.value != null && !preserveActiveRawGraphicForPaint, clearOwnedRegion = preserveActiveRawGraphicForPaint || retainedActiveRawGraphic ? !1 : props.clear || clearingRawGraphic || !!rawCanQueueForPaint, blank = clearOwnedRegion ? spaces(r.w) : "", paintRow = (y) => {
|
|
3344
|
+
if (y < r.y || y >= r.y + r.h)
|
|
3345
|
+
return;
|
|
3346
|
+
let rowIndex = y - fullY;
|
|
3347
|
+
if (rowIndex < 0 || rowIndex >= out.length) {
|
|
3348
|
+
clearOwnedRegion && terminal.write(blank, { x: r.x, y, style });
|
|
3349
|
+
return;
|
|
3350
|
+
}
|
|
3351
|
+
let src = out[rowIndex] ?? "", clipped = dx > 0 ? sliceByCellsRange(src, dx, dx + r.w) : sliceByCells(src, r.w), value = clearOwnedRegion ? padEndByCells(clipped, r.w) : clipped;
|
|
3352
|
+
(value || clearOwnedRegion) && terminal.write(value, { x: r.x, y, style });
|
|
3353
|
+
}, paintRows = () => {
|
|
3354
|
+
if (dirtyRows?.length)
|
|
3355
|
+
for (let y of dirtyRows)
|
|
3356
|
+
paintRow(y);
|
|
3357
|
+
else
|
|
3358
|
+
for (let y = r.y; y < r.y + r.h; y++)
|
|
3359
|
+
paintRow(y);
|
|
3360
|
+
};
|
|
3361
|
+
if (paintRows(), current?.type === "terminal" && output?.capabilities.supported && output.capabilities.preferredProtocol === current.protocol && rawCanQueueForPaint) {
|
|
3362
|
+
let drawKey = terminalDrawKey(
|
|
3363
|
+
current,
|
|
3364
|
+
rawRectForPaint,
|
|
3365
|
+
resolveClearSequence(current),
|
|
3366
|
+
resolveResizeSequence(current, rawRectForPaint, full)
|
|
3367
|
+
);
|
|
3368
|
+
queueDrawGraphic(output, current, rawRectForPaint, full, {
|
|
3369
|
+
force: forceActiveRawRedraw,
|
|
3370
|
+
deferFlush: preserveActiveRawGraphicForPaint,
|
|
3371
|
+
placementMoveWithoutClear: props.placementMoveWithoutClear || rawCoverageClipped,
|
|
3372
|
+
allowTextOverlay
|
|
3373
|
+
}) ? trace("raw-draw", {
|
|
3374
|
+
sequenceChars: current.sequence.length,
|
|
3375
|
+
sequenceBytes: current.sequenceBytes,
|
|
3376
|
+
x: rawRectForPaint.x,
|
|
3377
|
+
y: rawRectForPaint.y,
|
|
3378
|
+
w: rawRectForPaint.w,
|
|
3379
|
+
h: rawRectForPaint.h
|
|
3380
|
+
}) : rawDrawRejectedKey.value === drawKey && (out = resolveDisplayLines(!1), paintRows());
|
|
3381
|
+
} else
|
|
3382
|
+
current?.type === "terminal" && rawSuppressedByScroll.value && traceRawSkipScrollOnce(isParentScrolling.value ? "scrolling" : "suspended"), queueClearLastGraphic({ markPendingRepaint: !1 }), !shouldDeferRender() && shouldRetryTemporaryRawFallback(rawCoveredForPaint) && scheduleRender({ clearLastGraphic: !1 });
|
|
3383
|
+
clearingRawGraphic && (rawClearPendingRepaint.value = null);
|
|
3384
|
+
});
|
|
3385
|
+
}
|
|
3386
|
+
}));
|
|
3387
|
+
return (0, import_vue10.watch)(
|
|
3388
|
+
renderNode.id,
|
|
3389
|
+
(id) => {
|
|
3390
|
+
renderNodeId.value = id;
|
|
3391
|
+
},
|
|
3392
|
+
{ immediate: !0 }
|
|
3393
|
+
), (0, import_vue10.watch)(
|
|
3394
|
+
[
|
|
3395
|
+
visible,
|
|
3396
|
+
rawOutputCanRenderValue,
|
|
3397
|
+
rawCanRender,
|
|
3398
|
+
rawCanQueue,
|
|
3399
|
+
rawSuppressedByScroll,
|
|
3400
|
+
isParentScrolling,
|
|
3401
|
+
graphicsActivityVersion,
|
|
3402
|
+
graphicsOutputVersion,
|
|
3403
|
+
() => renderRect.value.x,
|
|
3404
|
+
() => renderRect.value.y,
|
|
3405
|
+
() => renderRect.value.w,
|
|
3406
|
+
() => renderRect.value.h,
|
|
3407
|
+
() => fullRect.value.x,
|
|
3408
|
+
() => fullRect.value.y,
|
|
3409
|
+
() => fullRect.value.w,
|
|
3410
|
+
() => fullRect.value.h
|
|
3411
|
+
],
|
|
3412
|
+
() => {
|
|
3413
|
+
if (!alive)
|
|
3414
|
+
return;
|
|
3415
|
+
let deferred = renderDeferReason();
|
|
3416
|
+
deferred && (abortCurrentRender(deferred), (status.value === "loading" || !graphic.value || lastRenderedContent !== props.content) && setDeferredFallback(props.content), traceDeferOnce(deferred)), (!visible.value || !rawCanQueue.value) && queueClearLastGraphic();
|
|
3417
|
+
let shouldRetryTemporaryFallback = shouldRetryTemporaryRawFallback(), shouldRerenderForOutputChange = shouldRerenderForGraphicsOutputChange();
|
|
3418
|
+
if (!shouldDeferRender() && (!graphic.value || status.value === "idle" || shouldRetryTemporaryFallback || shouldRerenderForOutputChange)) {
|
|
3419
|
+
scheduleRender();
|
|
3420
|
+
return;
|
|
3421
|
+
}
|
|
3422
|
+
scheduler.invalidate({ priority: "low", reason: "data" });
|
|
3423
|
+
},
|
|
3424
|
+
{ flush: "post" }
|
|
3425
|
+
), () => (0, import_vue10.h)("span", rootProps);
|
|
3426
|
+
}
|
|
3427
|
+
});
|
|
3428
|
+
|
|
3429
|
+
// src/vue/components/TText.ts
|
|
3430
|
+
var import_vue11 = require("vue");
|
|
3431
|
+
function fitText(text, max) {
|
|
3432
|
+
return max <= 0 ? "" : (text = sanitizeInlineText(text), sliceByCells(text, max));
|
|
3433
|
+
}
|
|
3434
|
+
function splitLines(text) {
|
|
3435
|
+
return sanitizeTextBlock(text).split(`
|
|
3436
|
+
`);
|
|
3437
|
+
}
|
|
3438
|
+
function computeDefaultWidth(text) {
|
|
3439
|
+
let lines = splitLines(text), max = 0;
|
|
3440
|
+
for (let line of lines)
|
|
3441
|
+
max = Math.max(max, textCellWidth(line));
|
|
3442
|
+
return max;
|
|
3443
|
+
}
|
|
3444
|
+
var TText = (0, import_vue11.defineComponent)({
|
|
3445
|
+
name: "TText",
|
|
3446
|
+
props: {
|
|
3447
|
+
x: { type: Number, required: !0 },
|
|
3448
|
+
y: { type: Number, required: !0 },
|
|
3449
|
+
zIndex: { type: Number, default: 0 },
|
|
3450
|
+
value: { type: String, required: !0 },
|
|
3451
|
+
w: { type: Number, default: void 0 },
|
|
3452
|
+
h: { type: Number, default: void 0 },
|
|
3453
|
+
style: { type: Object, default: void 0 },
|
|
3454
|
+
clear: { type: Boolean, default: !0 },
|
|
3455
|
+
wrap: { type: Boolean, default: !1 },
|
|
3456
|
+
/**
|
|
3457
|
+
* Optional key that participates in render-node dependency tracking.
|
|
3458
|
+
* Useful for forcing a repaint when the rendered output might change
|
|
3459
|
+
* even if `value`, `style`, and geometry are unchanged (e.g. external
|
|
3460
|
+
* terminal writes or higher-level virtualized row reuse).
|
|
3461
|
+
*/
|
|
3462
|
+
depsKey: { type: null, default: void 0 }
|
|
3463
|
+
},
|
|
3464
|
+
setup(props) {
|
|
3465
|
+
let { terminal, defaultStyle } = useTerminal(), layout = useLayout(), { visible, rootProps } = useVisibility(), defaultWidth = (0, import_vue11.computed)(() => computeDefaultWidth(props.value)), lines = (0, import_vue11.computed)(() => {
|
|
3466
|
+
let w = props.w ?? defaultWidth.value;
|
|
3467
|
+
if (w <= 0)
|
|
3468
|
+
return [""];
|
|
3469
|
+
if (!props.wrap)
|
|
3470
|
+
return splitLines(props.value).map((l) => fitText(l, w));
|
|
3471
|
+
let safe = sanitizeTextBlock(props.value);
|
|
3472
|
+
return wrapByCells(safe, w).map((l) => fitText(l, w));
|
|
3473
|
+
}), absRect = (0, import_vue11.computed)(() => {
|
|
3474
|
+
let width = props.w ?? defaultWidth.value, height = props.h ?? (props.wrap, lines.value.length || 1), raw = { x: props.x, y: props.y, w: width, h: height }, translated = translateRect(raw, layout.originX, layout.originY);
|
|
3475
|
+
return layout.clipRect ? intersectRect(translated, layout.clipRect) ?? { x: 0, y: 0, w: 0, h: 0 } : translated;
|
|
3476
|
+
}), fullRect = (0, import_vue11.computed)(() => {
|
|
3477
|
+
let width = props.w ?? defaultWidth.value, height = props.h ?? (props.wrap, lines.value.length || 1);
|
|
3478
|
+
return translateRect(
|
|
3479
|
+
{ x: props.x, y: props.y, w: width, h: height },
|
|
3480
|
+
layout.originX,
|
|
3481
|
+
layout.originY
|
|
3482
|
+
);
|
|
3483
|
+
});
|
|
3484
|
+
return useRenderNode(() => ({
|
|
3485
|
+
zIndex: props.zIndex,
|
|
3486
|
+
rect: visible.value ? absRect.value : { x: 0, y: 0, w: 0, h: 0 },
|
|
3487
|
+
deps: [
|
|
3488
|
+
visible.value,
|
|
3489
|
+
absRect.value,
|
|
3490
|
+
fullRect.value,
|
|
3491
|
+
props.value,
|
|
3492
|
+
props.w,
|
|
3493
|
+
props.h,
|
|
3494
|
+
props.wrap,
|
|
3495
|
+
props.style,
|
|
3496
|
+
defaultStyle.value,
|
|
3497
|
+
props.depsKey
|
|
3498
|
+
],
|
|
3499
|
+
paint: (dirtyRows) => {
|
|
3500
|
+
if (!visible.value)
|
|
3501
|
+
return;
|
|
3502
|
+
let r = absRect.value;
|
|
3503
|
+
if (r.w <= 0 || r.h <= 0)
|
|
3504
|
+
return;
|
|
3505
|
+
let full = fullRect.value, style = props.style ?? defaultStyle.value, blank = props.clear ? spaces(r.w) : "", out = lines.value, dx = Math.max(0, Math.floor(r.x - full.x)), fullY = Math.floor(full.y), paintRow = (y) => {
|
|
3506
|
+
let relY = y - r.y;
|
|
3507
|
+
if (relY < 0 || relY >= r.h)
|
|
3508
|
+
return;
|
|
3509
|
+
let i = y - fullY;
|
|
3510
|
+
if (i < 0 || i >= out.length) {
|
|
3511
|
+
props.clear && terminal.write(blank, { x: r.x, y, style });
|
|
3512
|
+
return;
|
|
3513
|
+
}
|
|
3514
|
+
let src = out[i] ?? "", clipped = dx > 0 ? sliceByCellsRange(src, dx, dx + r.w) : sliceByCells(src, r.w);
|
|
3515
|
+
terminal.write(padEndByCells(clipped, r.w), { x: r.x, y, style });
|
|
3516
|
+
};
|
|
3517
|
+
if (!dirtyRows) {
|
|
3518
|
+
for (let i = 0; i < r.h; i++)
|
|
3519
|
+
paintRow(r.y + i);
|
|
3520
|
+
return;
|
|
3521
|
+
}
|
|
3522
|
+
for (let y of dirtyRows)
|
|
3523
|
+
paintRow(y);
|
|
3524
|
+
}
|
|
3525
|
+
})), () => (0, import_vue11.h)("span", rootProps);
|
|
3526
|
+
}
|
|
3527
|
+
});
|
|
3528
|
+
|
|
3529
|
+
// src/vue/components/TView.ts
|
|
3530
|
+
var import_vue12 = require("vue");
|
|
3531
|
+
var EMPTY_RECT = Object.freeze({ x: 0, y: 0, w: 0, h: 0 }), TView = (0, import_vue12.defineComponent)({
|
|
3532
|
+
name: "TView",
|
|
3533
|
+
props: {
|
|
3534
|
+
x: { type: Number, required: !0 },
|
|
3535
|
+
y: { type: Number, required: !0 },
|
|
3536
|
+
w: { type: Number, required: !0 },
|
|
3537
|
+
h: { type: Number, required: !0 },
|
|
3538
|
+
zIndex: { type: Number, default: 0 },
|
|
3539
|
+
scrollX: { type: Number, default: 0 },
|
|
3540
|
+
scrollY: { type: Number, default: 0 },
|
|
3541
|
+
focusable: { type: Boolean, default: !1 },
|
|
3542
|
+
selectable: { type: Boolean, default: void 0 },
|
|
3543
|
+
selectionScrollBy: {
|
|
3544
|
+
type: Function,
|
|
3545
|
+
default: void 0
|
|
3546
|
+
},
|
|
3547
|
+
autoFocus: { type: Boolean, default: !1 }
|
|
3548
|
+
},
|
|
3549
|
+
emits: [
|
|
3550
|
+
"clickCapture",
|
|
3551
|
+
"click",
|
|
3552
|
+
"dblclickCapture",
|
|
3553
|
+
"dblclick",
|
|
3554
|
+
"pointerdownCapture",
|
|
3555
|
+
"pointerdown",
|
|
3556
|
+
"pointerupCapture",
|
|
3557
|
+
"pointerup",
|
|
3558
|
+
"pointermoveCapture",
|
|
3559
|
+
"pointermove",
|
|
3560
|
+
"pointerenterCapture",
|
|
3561
|
+
"pointerenter",
|
|
3562
|
+
"pointerleaveCapture",
|
|
3563
|
+
"pointerleave",
|
|
3564
|
+
"wheelCapture",
|
|
3565
|
+
"wheel",
|
|
3566
|
+
"keydownCapture",
|
|
3567
|
+
"keydown",
|
|
3568
|
+
"keyupCapture",
|
|
3569
|
+
"keyup",
|
|
3570
|
+
"focusCapture",
|
|
3571
|
+
"focus",
|
|
3572
|
+
"blurCapture",
|
|
3573
|
+
"blur"
|
|
3574
|
+
],
|
|
3575
|
+
setup(props, { emit, slots }) {
|
|
3576
|
+
let parent = useLayout(), { render, events } = useTerminal(), parentStack = useRenderStack(), { visible, rootProps } = useVisibility({ provide: !0 }), parentEventZ = (0, import_vue12.inject)(EventZIndexContextKey, (0, import_vue12.computed)(() => 0)), eventZ = (0, import_vue12.computed)(() => (parentEventZ.value ?? 0) + (props.zIndex ?? 0)), rawRect = (0, import_vue12.computed)(
|
|
3577
|
+
() => translateRect(
|
|
3578
|
+
{ x: props.x, y: props.y, w: props.w, h: props.h },
|
|
3579
|
+
parent.originX,
|
|
3580
|
+
parent.originY
|
|
3581
|
+
)
|
|
3582
|
+
), rect = (0, import_vue12.computed)(() => {
|
|
3583
|
+
let translated = rawRect.value;
|
|
3584
|
+
return parent.clipRect ? intersectRect(translated, parent.clipRect) ?? EMPTY_RECT : translated;
|
|
3585
|
+
}), { id } = useTerminalNode(() => ({
|
|
3586
|
+
rect: rect.value,
|
|
3587
|
+
zIndex: eventZ.value,
|
|
3588
|
+
visible: visible.value,
|
|
3589
|
+
focusable: props.focusable,
|
|
3590
|
+
selectable: props.selectable,
|
|
3591
|
+
selectionScrollBy: props.selectionScrollBy,
|
|
3592
|
+
handlers: {
|
|
3593
|
+
clickCapture: (e) => emit("clickCapture", e),
|
|
3594
|
+
click: (e) => emit("click", e),
|
|
3595
|
+
dblclickCapture: (e) => emit("dblclickCapture", e),
|
|
3596
|
+
dblclick: (e) => emit("dblclick", e),
|
|
3597
|
+
pointerdownCapture: (e) => emit("pointerdownCapture", e),
|
|
3598
|
+
pointerdown: (e) => emit("pointerdown", e),
|
|
3599
|
+
pointerupCapture: (e) => emit("pointerupCapture", e),
|
|
3600
|
+
pointerup: (e) => emit("pointerup", e),
|
|
3601
|
+
pointermoveCapture: (e) => emit("pointermoveCapture", e),
|
|
3602
|
+
pointermove: (e) => emit("pointermove", e),
|
|
3603
|
+
pointerenterCapture: (e) => emit("pointerenterCapture", e),
|
|
3604
|
+
pointerenter: (e) => emit("pointerenter", e),
|
|
3605
|
+
pointerleaveCapture: (e) => emit("pointerleaveCapture", e),
|
|
3606
|
+
pointerleave: (e) => emit("pointerleave", e),
|
|
3607
|
+
wheelCapture: (e) => emit("wheelCapture", e),
|
|
3608
|
+
wheel: (e) => emit("wheel", e),
|
|
3609
|
+
keydownCapture: (e) => emit("keydownCapture", e),
|
|
3610
|
+
keydown: (e) => emit("keydown", e),
|
|
3611
|
+
keyupCapture: (e) => emit("keyupCapture", e),
|
|
3612
|
+
keyup: (e) => emit("keyup", e),
|
|
3613
|
+
focusCapture: (e) => emit("focusCapture", e),
|
|
3614
|
+
focus: (e) => emit("focus", e),
|
|
3615
|
+
blurCapture: (e) => emit("blurCapture", e),
|
|
3616
|
+
blur: (e) => emit("blur", e)
|
|
3617
|
+
}
|
|
3618
|
+
}));
|
|
3619
|
+
(0, import_vue12.watchEffect)(() => {
|
|
3620
|
+
if (!props.autoFocus || !visible.value)
|
|
3621
|
+
return;
|
|
3622
|
+
let manager = events.value, nodeId = id.value;
|
|
3623
|
+
!manager || !nodeId || manager.getFocused() !== nodeId && manager.focus(nodeId);
|
|
3624
|
+
});
|
|
3625
|
+
let childLayout = (0, import_vue12.shallowReactive)({
|
|
3626
|
+
originX: 0,
|
|
3627
|
+
originY: 0,
|
|
3628
|
+
clipRect: null
|
|
3629
|
+
}), childStack = (0, import_vue12.computed)(() => render.createStack(parentStack.value, props.zIndex));
|
|
3630
|
+
return (0, import_vue12.watchEffect)(() => {
|
|
3631
|
+
let translated = rawRect.value;
|
|
3632
|
+
childLayout.originX = translated.x - Math.floor(props.scrollX), childLayout.originY = translated.y - Math.floor(props.scrollY), childLayout.clipRect = rect.value;
|
|
3633
|
+
}), (0, import_vue12.provide)(LayoutContextKey, childLayout), (0, import_vue12.provide)(RenderStackKey, childStack), (0, import_vue12.provide)(EventZIndexContextKey, eventZ), () => (0, import_vue12.h)("div", rootProps, slots.default?.());
|
|
3634
|
+
}
|
|
3635
|
+
});
|
|
3636
|
+
|
|
3637
|
+
// src/vue/components/TVideo.ts
|
|
3638
|
+
var DEFAULT_MAX_FPS = 12, DEFAULT_MAX_PIXEL_WIDTH = 640, DEFAULT_MAX_PIXEL_HEIGHT = 360, MAX_PIXEL_DIMENSION = 4096, MAX_FRAME_BYTES = 8 * 1024 * 1024, MAX_GRAY8_FPS = 10, MAX_GRAY8_WIDTH = 512, MAX_GRAY8_HEIGHT = 256, ASCII_RAMP = " .:-=+*#%@", CONTROL_REFRESH_MS = 250, PLAYBACK_RATES = [1, 2, 3];
|
|
3639
|
+
function positiveInt2(value, fallback, max) {
|
|
3640
|
+
let parsed = Math.floor(Number(value));
|
|
3641
|
+
return !Number.isFinite(parsed) || parsed <= 0 ? Math.min(max, fallback) : Math.min(max, parsed);
|
|
3642
|
+
}
|
|
3643
|
+
function positiveNumber(value, fallback, max) {
|
|
3644
|
+
let parsed = Number(value);
|
|
3645
|
+
return !Number.isFinite(parsed) || parsed <= 0 ? fallback : Math.min(max, parsed);
|
|
3646
|
+
}
|
|
3647
|
+
function playbackRate(value) {
|
|
3648
|
+
return value === 2 || value === 3 ? value : 1;
|
|
3649
|
+
}
|
|
3650
|
+
function optionalDuration(value) {
|
|
3651
|
+
let parsed = Number(value);
|
|
3652
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
3653
|
+
}
|
|
3654
|
+
function formatPlaybackTime(valueMs, hourDigits = 0) {
|
|
3655
|
+
if (valueMs == null)
|
|
3656
|
+
return "--:--";
|
|
3657
|
+
let seconds = Math.max(0, Math.floor(valueMs / 1e3)), hours = Math.floor(seconds / 3600), minutes = Math.floor(seconds % 3600 / 60), remainder = seconds % 60;
|
|
3658
|
+
return hours > 0 || hourDigits > 0 ? `${String(hours).padStart(Math.max(1, hourDigits), "0")}:${String(minutes).padStart(2, "0")}:${String(remainder).padStart(2, "0")}` : `${String(minutes).padStart(2, "0")}:${String(remainder).padStart(2, "0")}`;
|
|
3659
|
+
}
|
|
3660
|
+
function readUint32(bytes, offset) {
|
|
3661
|
+
return bytes[offset] * 16777216 + (bytes[offset + 1] << 16) + (bytes[offset + 2] << 8) + bytes[offset + 3] >>> 0;
|
|
3662
|
+
}
|
|
3663
|
+
function normalizeFrame(frame) {
|
|
3664
|
+
if (frame.format === "gray8") {
|
|
3665
|
+
let pixelWidth2 = Math.floor(Number(frame.pixelWidth)), pixelHeight2 = Math.floor(Number(frame.pixelHeight)), pixels = frame.pixels;
|
|
3666
|
+
if (!Number.isFinite(pixelWidth2) || !Number.isFinite(pixelHeight2) || pixelWidth2 <= 0 || pixelHeight2 <= 0 || pixelWidth2 > MAX_GRAY8_WIDTH || pixelHeight2 > MAX_GRAY8_HEIGHT || !(pixels instanceof Uint8Array) || pixels.length !== pixelWidth2 * pixelHeight2 || pixels.length > MAX_FRAME_BYTES)
|
|
3667
|
+
throw new Error("TVideo gray8 frame must match its bounded pixel dimensions");
|
|
3668
|
+
return {
|
|
3669
|
+
format: "gray8",
|
|
3670
|
+
pixels,
|
|
3671
|
+
timestampMs: Math.max(0, Number(frame.timestampMs) || 0),
|
|
3672
|
+
pixelWidth: pixelWidth2,
|
|
3673
|
+
pixelHeight: pixelHeight2,
|
|
3674
|
+
fingerprint: frame.fingerprint,
|
|
3675
|
+
durationMs: optionalDuration(frame.durationMs)
|
|
3676
|
+
};
|
|
3677
|
+
}
|
|
3678
|
+
let png = frame.png;
|
|
3679
|
+
if (!(png instanceof Uint8Array) || png.length < 24 || png.length > MAX_FRAME_BYTES)
|
|
3680
|
+
throw new Error("TVideo frame must contain a bounded PNG Uint8Array");
|
|
3681
|
+
if (png[0] !== 137 || png[1] !== 80 || png[2] !== 78 || png[3] !== 71 || png[4] !== 13 || png[5] !== 10 || png[6] !== 26 || png[7] !== 10)
|
|
3682
|
+
throw new Error("TVideo frame source emitted invalid PNG data");
|
|
3683
|
+
let pixelWidth = readUint32(png, 16), pixelHeight = readUint32(png, 20);
|
|
3684
|
+
if (pixelWidth <= 0 || pixelHeight <= 0 || pixelWidth > MAX_PIXEL_DIMENSION || pixelHeight > MAX_PIXEL_DIMENSION)
|
|
3685
|
+
throw new Error(`TVideo frame has an unsupported size: ${pixelWidth}x${pixelHeight}`);
|
|
3686
|
+
return {
|
|
3687
|
+
format: "png",
|
|
3688
|
+
png,
|
|
3689
|
+
timestampMs: Math.max(0, Number(frame.timestampMs) || 0),
|
|
3690
|
+
pixelWidth,
|
|
3691
|
+
pixelHeight,
|
|
3692
|
+
fingerprint: frame.fingerprint,
|
|
3693
|
+
durationMs: optionalDuration(frame.durationMs)
|
|
3694
|
+
};
|
|
3695
|
+
}
|
|
3696
|
+
function frameBytes(frame) {
|
|
3697
|
+
return frame.format === "gray8" ? frame.pixels : frame.png;
|
|
3698
|
+
}
|
|
3699
|
+
function gray8ToAscii(frame, cellWidth) {
|
|
3700
|
+
let lines = [], width = Math.max(1, Math.floor(cellWidth));
|
|
3701
|
+
for (let y = 0; y < frame.pixelHeight; y++) {
|
|
3702
|
+
let line = "", rowStart = y * frame.pixelWidth;
|
|
3703
|
+
for (let x = 0; x < frame.pixelWidth; x++) {
|
|
3704
|
+
let value = frame.pixels[rowStart + x], glyph = ASCII_RAMP[Math.min(ASCII_RAMP.length - 1, value * ASCII_RAMP.length >> 8)];
|
|
3705
|
+
line += `${glyph}${glyph}`;
|
|
3706
|
+
}
|
|
3707
|
+
lines.push(line.slice(0, width));
|
|
3708
|
+
}
|
|
3709
|
+
return lines.join(`
|
|
3710
|
+
`);
|
|
3711
|
+
}
|
|
3712
|
+
function sameBytes(left, right) {
|
|
3713
|
+
if (left.length !== right.length)
|
|
3714
|
+
return !1;
|
|
3715
|
+
for (let index = 0; index < left.length; index++)
|
|
3716
|
+
if (left[index] !== right[index])
|
|
3717
|
+
return !1;
|
|
3718
|
+
return !0;
|
|
3719
|
+
}
|
|
3720
|
+
function bytesToBase64(bytes) {
|
|
3721
|
+
let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", chunks = [], chunk = "";
|
|
3722
|
+
for (let index = 0; index < bytes.length; index += 3) {
|
|
3723
|
+
let a = bytes[index], hasB = index + 1 < bytes.length, hasC = index + 2 < bytes.length, b = hasB ? bytes[index + 1] : 0, c = hasC ? bytes[index + 2] : 0;
|
|
3724
|
+
chunk += alphabet[a >> 2] + alphabet[(a & 3) << 4 | b >> 4] + (hasB ? alphabet[(b & 15) << 2 | c >> 6] : "=") + (hasC ? alphabet[c & 63] : "="), chunk.length >= 16384 && (chunks.push(chunk), chunk = "");
|
|
3725
|
+
}
|
|
3726
|
+
return chunk && chunks.push(chunk), chunks.join("");
|
|
3727
|
+
}
|
|
3728
|
+
function resolveKittyPlacement(frame, context) {
|
|
3729
|
+
let rect = context.viewport.rect, full = context.viewport.fullRect, columns = Math.max(1, Math.floor(rect.w)), rows = Math.max(1, Math.floor(rect.h));
|
|
3730
|
+
if (full.w <= 0 || full.h <= 0)
|
|
3731
|
+
return { columns, rows };
|
|
3732
|
+
let offsetX = Math.max(0, rect.x - full.x), offsetY = Math.max(0, rect.y - full.y), visibleW = Math.max(0, Math.min(rect.w, full.w - offsetX)), visibleH = Math.max(0, Math.min(rect.h, full.h - offsetY));
|
|
3733
|
+
if (offsetX <= 0 && offsetY <= 0 && visibleW >= full.w && visibleH >= full.h)
|
|
3734
|
+
return { columns, rows };
|
|
3735
|
+
let sourceX = Math.max(
|
|
3736
|
+
0,
|
|
3737
|
+
Math.min(frame.pixelWidth - 1, Math.floor(offsetX * frame.pixelWidth / full.w))
|
|
3738
|
+
), sourceY = Math.max(
|
|
3739
|
+
0,
|
|
3740
|
+
Math.min(frame.pixelHeight - 1, Math.floor(offsetY * frame.pixelHeight / full.h))
|
|
3741
|
+
), sourceRight = Math.max(
|
|
3742
|
+
sourceX + 1,
|
|
3743
|
+
Math.min(frame.pixelWidth, Math.ceil((offsetX + visibleW) * frame.pixelWidth / full.w))
|
|
3744
|
+
), sourceBottom = Math.max(
|
|
3745
|
+
sourceY + 1,
|
|
3746
|
+
Math.min(frame.pixelHeight, Math.ceil((offsetY + visibleH) * frame.pixelHeight / full.h))
|
|
3747
|
+
);
|
|
3748
|
+
return {
|
|
3749
|
+
columns,
|
|
3750
|
+
rows,
|
|
3751
|
+
sourceX,
|
|
3752
|
+
sourceY,
|
|
3753
|
+
sourceWidth: sourceRight - sourceX,
|
|
3754
|
+
sourceHeight: sourceBottom - sourceY
|
|
3755
|
+
};
|
|
3756
|
+
}
|
|
3757
|
+
function createFrameRenderer(frame, cellWidth) {
|
|
3758
|
+
if (frame.format === "gray8") {
|
|
3759
|
+
let text = gray8ToAscii(frame, cellWidth);
|
|
3760
|
+
return () => ({ type: "text", text });
|
|
3761
|
+
}
|
|
3762
|
+
let base64;
|
|
3763
|
+
return (_content, context) => {
|
|
3764
|
+
if (!context.visible || !context.rawVisible)
|
|
3765
|
+
return null;
|
|
3766
|
+
if (base64 ?? (base64 = bytesToBase64(frame.png)), context.protocol === "kitty") {
|
|
3767
|
+
let placement = resolveKittyPlacement(frame, context);
|
|
3768
|
+
return {
|
|
3769
|
+
type: "sequence",
|
|
3770
|
+
protocol: "kitty",
|
|
3771
|
+
sequence: createKittyGraphicsSequence(base64, {
|
|
3772
|
+
imageId: context.imageId,
|
|
3773
|
+
placementId: context.placementId,
|
|
3774
|
+
...placement
|
|
3775
|
+
}),
|
|
3776
|
+
resizeSequence: createKittyPlacementSequence({
|
|
3777
|
+
imageId: context.imageId,
|
|
3778
|
+
placementId: context.placementId,
|
|
3779
|
+
...placement
|
|
3780
|
+
}),
|
|
3781
|
+
clearSequence: createKittyDeleteGraphicsSequence({
|
|
3782
|
+
imageId: context.imageId,
|
|
3783
|
+
placementId: context.placementId,
|
|
3784
|
+
freeImageData: !0
|
|
3785
|
+
}),
|
|
3786
|
+
cols: context.width,
|
|
3787
|
+
rows: context.height,
|
|
3788
|
+
sourceWidth: frame.pixelWidth,
|
|
3789
|
+
sourceHeight: frame.pixelHeight
|
|
3790
|
+
};
|
|
3791
|
+
}
|
|
3792
|
+
return context.protocol === "iterm2" ? {
|
|
3793
|
+
type: "sequence",
|
|
3794
|
+
protocol: "iterm2",
|
|
3795
|
+
sequence: createIterm2InlineImageSequence(base64, {
|
|
3796
|
+
width: context.width,
|
|
3797
|
+
height: context.height,
|
|
3798
|
+
preserveAspectRatio: !0,
|
|
3799
|
+
doNotMoveCursor: !0
|
|
3800
|
+
}),
|
|
3801
|
+
cols: context.width,
|
|
3802
|
+
rows: context.height,
|
|
3803
|
+
sourceWidth: frame.pixelWidth,
|
|
3804
|
+
sourceHeight: frame.pixelHeight
|
|
3805
|
+
} : null;
|
|
3806
|
+
};
|
|
3807
|
+
}
|
|
3808
|
+
function errorMessage2(error) {
|
|
3809
|
+
return error instanceof Error ? error.message : String(error);
|
|
3810
|
+
}
|
|
3811
|
+
var tVideoProps = {
|
|
3812
|
+
x: { type: Number, required: !0 },
|
|
3813
|
+
y: { type: Number, required: !0 },
|
|
3814
|
+
w: { type: Number, required: !0 },
|
|
3815
|
+
h: { type: Number, required: !0 },
|
|
3816
|
+
zIndex: { type: Number, default: 0 },
|
|
3817
|
+
src: { type: String, required: !0 },
|
|
3818
|
+
frameSource: {
|
|
3819
|
+
type: Function,
|
|
3820
|
+
required: !0
|
|
3821
|
+
},
|
|
3822
|
+
paused: { type: Boolean, default: void 0 },
|
|
3823
|
+
playbackRate: { type: Number, default: void 0 },
|
|
3824
|
+
controls: { type: Boolean, default: !1 },
|
|
3825
|
+
controlsLayout: {
|
|
3826
|
+
type: String,
|
|
3827
|
+
default: "compact"
|
|
3828
|
+
},
|
|
3829
|
+
durationMs: { type: Number, default: void 0 },
|
|
3830
|
+
loop: { type: Boolean, default: !1 },
|
|
3831
|
+
maxFps: { type: Number, default: DEFAULT_MAX_FPS },
|
|
3832
|
+
pixelWidth: { type: Number, default: void 0 },
|
|
3833
|
+
pixelHeight: { type: Number, default: void 0 },
|
|
3834
|
+
fallback: { type: String, default: "[video]" },
|
|
3835
|
+
style: { type: Object, default: void 0 },
|
|
3836
|
+
clear: { type: Boolean, default: !0 }
|
|
3837
|
+
}, TVideo = (0, import_vue13.defineComponent)({
|
|
3838
|
+
name: "TVideo",
|
|
3839
|
+
props: tVideoProps,
|
|
3840
|
+
emits: {
|
|
3841
|
+
frame: (_event) => !0,
|
|
3842
|
+
ended: () => !0,
|
|
3843
|
+
error: (_error) => !0,
|
|
3844
|
+
seek: (_event) => !0,
|
|
3845
|
+
"update:paused": (_paused) => !0,
|
|
3846
|
+
"update:playbackRate": (_rate) => !0
|
|
3847
|
+
},
|
|
3848
|
+
setup(props, { emit }) {
|
|
3849
|
+
let instance = (0, import_vue13.getCurrentInstance)(), { terminal, scheduler } = useTerminal(), layout = useLayout(), { visible, rootProps } = useVisibility({ provide: !0 }), graphicsActivity = (0, import_vue13.inject)(TerminalGraphicsActivityKey, null), frameRenderer = (0, import_vue13.shallowRef)(), playbackError = (0, import_vue13.shallowRef)(""), internalPaused = (0, import_vue13.shallowRef)(props.paused ?? !1), internalPlaybackRate = (0, import_vue13.shallowRef)(playbackRate(props.playbackRate)), discoveredDurationMs = (0, import_vue13.shallowRef)(), displayedTimestampMs = (0, import_vue13.shallowRef)(0), seekPreviewMs = (0, import_vue13.shallowRef)(), seeking = (0, import_vue13.shallowRef)(!1), terminalSizeVersion = (0, import_vue13.shallowRef)(0), graphicsOutputVersion = (0, import_vue13.shallowRef)(getTerminalGraphicsOutputVersion(terminal)), placementKey = `TVideo:${instance?.uid ?? "unknown"}`, mailboxId = `${placementKey}:frame`, alive = !0, generation = 0, activeAbort = null, lastSourceBytes = null, lastQueuedBytes = null, lastQueuedFormat = null, lastQueuedFingerprint, lastTimestampMs = 0, droppedFrames = 0, pendingEndedGeneration = null, suppressNextVideoClick = !1, controlPointerCapture = null, unsubscribeTerminalResize = terminal.on("resize", () => {
|
|
3850
|
+
terminalSizeVersion.value++;
|
|
3851
|
+
}), unsubscribeGraphicsOutput = subscribeTerminalGraphicsOutput(terminal, () => {
|
|
3852
|
+
graphicsOutputVersion.value = getTerminalGraphicsOutputVersion(terminal);
|
|
3853
|
+
}), showControls = (0, import_vue13.computed)(
|
|
3854
|
+
() => props.controls && Math.floor(props.w) >= 14 && Math.floor(props.h) >= 2
|
|
3855
|
+
), resolvedControlsLayout = (0, import_vue13.computed)(
|
|
3856
|
+
() => props.controlsLayout === "cinema" && Math.floor(props.h) >= 3 ? "cinema" : "compact"
|
|
3857
|
+
), controlRows = (0, import_vue13.computed)(
|
|
3858
|
+
() => showControls.value ? resolvedControlsLayout.value === "cinema" ? 2 : 1 : 0
|
|
3859
|
+
), videoHeight = (0, import_vue13.computed)(() => Math.max(1, Math.floor(props.h) - controlRows.value)), resolvedMaxFps = (0, import_vue13.computed)(() => positiveNumber(props.maxFps, DEFAULT_MAX_FPS, 60)), resolvedPixelSize = (0, import_vue13.computed)(() => {
|
|
3860
|
+
let desiredWidth = Math.max(2, Math.floor(props.w) * 8), desiredHeight = Math.max(2, videoHeight.value * 16);
|
|
3861
|
+
if (props.pixelWidth == null && props.pixelHeight == null) {
|
|
3862
|
+
let scale = Math.min(
|
|
3863
|
+
1,
|
|
3864
|
+
DEFAULT_MAX_PIXEL_WIDTH / desiredWidth,
|
|
3865
|
+
DEFAULT_MAX_PIXEL_HEIGHT / desiredHeight
|
|
3866
|
+
);
|
|
3867
|
+
return {
|
|
3868
|
+
width: Math.max(2, Math.floor(desiredWidth * scale)),
|
|
3869
|
+
height: Math.max(2, Math.floor(desiredHeight * scale))
|
|
3870
|
+
};
|
|
3871
|
+
}
|
|
3872
|
+
if (props.pixelWidth != null && props.pixelHeight == null) {
|
|
3873
|
+
let width = positiveInt2(props.pixelWidth, desiredWidth, MAX_PIXEL_DIMENSION), inferredHeight = width * desiredHeight / desiredWidth, scale = Math.min(1, MAX_PIXEL_DIMENSION / inferredHeight);
|
|
3874
|
+
return {
|
|
3875
|
+
width: Math.max(2, Math.floor(width * scale)),
|
|
3876
|
+
height: Math.max(2, Math.floor(inferredHeight * scale))
|
|
3877
|
+
};
|
|
3878
|
+
}
|
|
3879
|
+
if (props.pixelWidth == null && props.pixelHeight != null) {
|
|
3880
|
+
let height = positiveInt2(props.pixelHeight, desiredHeight, MAX_PIXEL_DIMENSION), inferredWidth = height * desiredWidth / desiredHeight, scale = Math.min(1, MAX_PIXEL_DIMENSION / inferredWidth);
|
|
3881
|
+
return {
|
|
3882
|
+
width: Math.max(2, Math.floor(inferredWidth * scale)),
|
|
3883
|
+
height: Math.max(2, Math.floor(height * scale))
|
|
3884
|
+
};
|
|
3885
|
+
}
|
|
3886
|
+
return {
|
|
3887
|
+
width: positiveInt2(props.pixelWidth, desiredWidth, MAX_PIXEL_DIMENSION),
|
|
3888
|
+
height: positiveInt2(props.pixelHeight, desiredHeight, MAX_PIXEL_DIMENSION)
|
|
3889
|
+
};
|
|
3890
|
+
}), resolvedPixelWidth = (0, import_vue13.computed)(() => resolvedPixelSize.value.width), resolvedPixelHeight = (0, import_vue13.computed)(() => resolvedPixelSize.value.height), paintable = (0, import_vue13.computed)(() => {
|
|
3891
|
+
if (terminalSizeVersion.value, !visible.value)
|
|
3892
|
+
return !1;
|
|
3893
|
+
let size = terminal.size(), terminalRect = {
|
|
3894
|
+
x: 0,
|
|
3895
|
+
y: 0,
|
|
3896
|
+
w: Math.max(0, Math.floor(size.cols)),
|
|
3897
|
+
h: Math.max(0, Math.floor(size.rows))
|
|
3898
|
+
}, clip = layout.clipRect ? intersectRect(layout.clipRect, terminalRect) : terminalRect;
|
|
3899
|
+
if (!clip)
|
|
3900
|
+
return !1;
|
|
3901
|
+
let rect = translateRect(
|
|
3902
|
+
{ x: props.x, y: props.y, w: props.w, h: videoHeight.value },
|
|
3903
|
+
layout.originX,
|
|
3904
|
+
layout.originY
|
|
3905
|
+
), visibleRect = intersectRect(rect, clip);
|
|
3906
|
+
return !!(visibleRect && visibleRect.w > 0 && visibleRect.h > 0);
|
|
3907
|
+
}), graphicsProtocol = (0, import_vue13.computed)(() => (graphicsOutputVersion.value, getTerminalGraphicsOutput(terminal)?.capabilities.preferredProtocol ?? null)), preferredFormat = (0, import_vue13.computed)(
|
|
3908
|
+
() => graphicsProtocol.value === "kitty" || graphicsProtocol.value === "iterm2" ? "png" : "gray8"
|
|
3909
|
+
), resolvedDecodeFps = (0, import_vue13.computed)(
|
|
3910
|
+
() => preferredFormat.value === "gray8" ? Math.min(MAX_GRAY8_FPS, resolvedMaxFps.value) : resolvedMaxFps.value
|
|
3911
|
+
), resolvedDecodeWidth = (0, import_vue13.computed)(
|
|
3912
|
+
() => preferredFormat.value === "gray8" ? positiveInt2(Math.ceil(props.w / 2), 1, MAX_GRAY8_WIDTH) : resolvedPixelWidth.value
|
|
3913
|
+
), resolvedDecodeHeight = (0, import_vue13.computed)(
|
|
3914
|
+
() => preferredFormat.value === "gray8" ? positiveInt2(videoHeight.value, 1, MAX_GRAY8_HEIGHT) : resolvedPixelHeight.value
|
|
3915
|
+
), resolvedDurationMs = (0, import_vue13.computed)(
|
|
3916
|
+
() => optionalDuration(props.durationMs) ?? discoveredDurationMs.value
|
|
3917
|
+
), effectivePaused = (0, import_vue13.computed)(() => props.paused ?? internalPaused.value), effectivePlaybackRate = (0, import_vue13.computed)(
|
|
3918
|
+
() => props.playbackRate == null ? internalPlaybackRate.value : playbackRate(props.playbackRate)
|
|
3919
|
+
), controlTimestampMs = (0, import_vue13.computed)(() => seekPreviewMs.value ?? displayedTimestampMs.value), timeHourDigits = (0, import_vue13.computed)(() => {
|
|
3920
|
+
let duration = resolvedDurationMs.value;
|
|
3921
|
+
return !duration || duration < 36e5 ? 0 : String(Math.floor(duration / 36e5)).length;
|
|
3922
|
+
}), currentTimeText = (0, import_vue13.computed)(
|
|
3923
|
+
() => formatPlaybackTime(controlTimestampMs.value, timeHourDigits.value)
|
|
3924
|
+
), durationTimeText = (0, import_vue13.computed)(
|
|
3925
|
+
() => formatPlaybackTime(resolvedDurationMs.value, timeHourDigits.value)
|
|
3926
|
+
), controlLayout = (0, import_vue13.computed)(() => {
|
|
3927
|
+
let width = Math.max(1, Math.floor(props.w)), progressY = videoHeight.value, current = currentTimeText.value, duration = durationTimeText.value, timeWidth = Math.max(textCellWidth(current), textCellWidth(duration)), ratesWidth = 8;
|
|
3928
|
+
if (resolvedControlsLayout.value === "cinema") {
|
|
3929
|
+
let ratesX2 = Math.max(3, width - ratesWidth), timeText = `${current} / ${duration}`;
|
|
3930
|
+
return {
|
|
3931
|
+
width,
|
|
3932
|
+
kind: "cinema",
|
|
3933
|
+
progressX: 0,
|
|
3934
|
+
progressY,
|
|
3935
|
+
progressWidth: width,
|
|
3936
|
+
actionY: progressY + 1,
|
|
3937
|
+
ratesX: ratesX2,
|
|
3938
|
+
showAllRates: !0,
|
|
3939
|
+
showTimes: 3 + textCellWidth(timeText) < ratesX2,
|
|
3940
|
+
current,
|
|
3941
|
+
duration,
|
|
3942
|
+
timeText,
|
|
3943
|
+
timeWidth,
|
|
3944
|
+
currentX: 3,
|
|
3945
|
+
totalX: 0
|
|
3946
|
+
};
|
|
3947
|
+
}
|
|
3948
|
+
let ratesX = width - ratesWidth, progressX = timeWidth + 4, totalX = ratesX - timeWidth - 1, progressWidth = totalX - progressX - 1;
|
|
3949
|
+
if (progressWidth >= 4)
|
|
3950
|
+
return {
|
|
3951
|
+
width,
|
|
3952
|
+
kind: "compact",
|
|
3953
|
+
progressX,
|
|
3954
|
+
progressY,
|
|
3955
|
+
progressWidth,
|
|
3956
|
+
actionY: progressY,
|
|
3957
|
+
ratesX,
|
|
3958
|
+
showAllRates: !0,
|
|
3959
|
+
showTimes: !0,
|
|
3960
|
+
current,
|
|
3961
|
+
duration,
|
|
3962
|
+
timeText: "",
|
|
3963
|
+
timeWidth,
|
|
3964
|
+
currentX: 3,
|
|
3965
|
+
totalX
|
|
3966
|
+
};
|
|
3967
|
+
let compactRatesX = Math.max(4, width - 2);
|
|
3968
|
+
return {
|
|
3969
|
+
width,
|
|
3970
|
+
kind: "compact",
|
|
3971
|
+
progressX: 3,
|
|
3972
|
+
progressY,
|
|
3973
|
+
progressWidth: Math.max(1, compactRatesX - 4),
|
|
3974
|
+
actionY: progressY,
|
|
3975
|
+
ratesX: compactRatesX,
|
|
3976
|
+
showAllRates: !1,
|
|
3977
|
+
showTimes: !1,
|
|
3978
|
+
current,
|
|
3979
|
+
duration,
|
|
3980
|
+
timeText: "",
|
|
3981
|
+
timeWidth,
|
|
3982
|
+
currentX: 0,
|
|
3983
|
+
totalX: 0
|
|
3984
|
+
};
|
|
3985
|
+
}), rateStyles = (0, import_vue13.computed)(
|
|
3986
|
+
() => PLAYBACK_RATES.map(
|
|
3987
|
+
(rate) => rate === effectivePlaybackRate.value ? { ...props.style, inverse: !0 } : props.style
|
|
3988
|
+
)
|
|
3989
|
+
), remainingProgressStyle = (0, import_vue13.computed)(() => ({ ...props.style, dim: !0 })), progressThumbStyle = (0, import_vue13.computed)(() => ({ ...props.style, inverse: !0 })), progressSegments = (0, import_vue13.computed)(() => {
|
|
3990
|
+
let { progressWidth } = controlLayout.value, duration = resolvedDurationMs.value;
|
|
3991
|
+
if (!duration)
|
|
3992
|
+
return { playedWidth: 0, thumbWidth: 0, remainingWidth: progressWidth };
|
|
3993
|
+
let ratio = Math.max(0, Math.min(1, controlTimestampMs.value / duration)), marker = Math.round(ratio * Math.max(0, progressWidth - 1));
|
|
3994
|
+
return {
|
|
3995
|
+
playedWidth: marker,
|
|
3996
|
+
thumbWidth: 1,
|
|
3997
|
+
remainingWidth: progressWidth - marker - 1
|
|
3998
|
+
};
|
|
3999
|
+
}), controlFill = (0, import_vue13.computed)(() => " ".repeat(controlLayout.value.width)), progressGlyphs = (0, import_vue13.computed)(() => ({
|
|
4000
|
+
played: "\u2501".repeat(progressSegments.value.playedWidth),
|
|
4001
|
+
remaining: "\u2500".repeat(progressSegments.value.remainingWidth)
|
|
4002
|
+
})), playbackEnabled = (0, import_vue13.computed)(
|
|
4003
|
+
() => alive && !effectivePaused.value && !graphicsActivity?.scrolling.value && props.src.trim().length > 0 && paintable.value
|
|
4004
|
+
), shouldPlay = (0, import_vue13.computed)(() => playbackEnabled.value && !seeking.value), visibleFallback = (0, import_vue13.computed)(
|
|
4005
|
+
() => playbackError.value ? `${props.fallback}: ${playbackError.value}` : props.fallback
|
|
4006
|
+
);
|
|
4007
|
+
function timelineTimestamp(timestampMs) {
|
|
4008
|
+
let duration = resolvedDurationMs.value;
|
|
4009
|
+
return duration ? props.loop ? Math.max(0, timestampMs) % duration : Math.max(0, Math.min(duration, timestampMs)) : Math.max(0, timestampMs);
|
|
4010
|
+
}
|
|
4011
|
+
function seekTimestamp(timestampMs) {
|
|
4012
|
+
let duration = resolvedDurationMs.value;
|
|
4013
|
+
if (!duration)
|
|
4014
|
+
return Math.max(0, timestampMs);
|
|
4015
|
+
let end = props.loop ? Math.max(0, duration - 1) : duration;
|
|
4016
|
+
return Math.max(0, Math.min(end, timestampMs));
|
|
4017
|
+
}
|
|
4018
|
+
function updateTimestamp(timestampMs, force = !1) {
|
|
4019
|
+
let next = timelineTimestamp(timestampMs);
|
|
4020
|
+
if (lastTimestampMs = next, !showControls.value)
|
|
4021
|
+
return;
|
|
4022
|
+
let threshold = CONTROL_REFRESH_MS * effectivePlaybackRate.value;
|
|
4023
|
+
(force || next < displayedTimestampMs.value || Math.abs(next - displayedTimestampMs.value) >= threshold) && (displayedTimestampMs.value = next);
|
|
4024
|
+
}
|
|
4025
|
+
function commitFrame(frame, dropped) {
|
|
4026
|
+
if (!alive)
|
|
4027
|
+
return;
|
|
4028
|
+
droppedFrames += dropped, frameRenderer.value = (0, import_vue13.markRaw)(createFrameRenderer(frame, props.w)), updateTimestamp(frame.timestampMs);
|
|
4029
|
+
let durationMs = resolvedDurationMs.value;
|
|
4030
|
+
emit("frame", {
|
|
4031
|
+
timestampMs: frame.timestampMs,
|
|
4032
|
+
pixelWidth: frame.pixelWidth,
|
|
4033
|
+
pixelHeight: frame.pixelHeight,
|
|
4034
|
+
droppedFrames,
|
|
4035
|
+
...durationMs ? { durationMs } : {},
|
|
4036
|
+
playbackRate: effectivePlaybackRate.value
|
|
4037
|
+
});
|
|
4038
|
+
}
|
|
4039
|
+
let mailbox = createFrameMailbox({
|
|
4040
|
+
scheduler,
|
|
4041
|
+
id: mailboxId,
|
|
4042
|
+
reason: "stream",
|
|
4043
|
+
priority: "low",
|
|
4044
|
+
apply(frame, _context, meta) {
|
|
4045
|
+
commitFrame(frame, meta.dropped), pendingEndedGeneration === generation && (pendingEndedGeneration = null, emit("ended"));
|
|
4046
|
+
}
|
|
4047
|
+
});
|
|
4048
|
+
function stopPlayback() {
|
|
4049
|
+
generation++, pendingEndedGeneration = null;
|
|
4050
|
+
let discardedPendingFrame = mailbox.hasPending();
|
|
4051
|
+
mailbox.cancel(), discardedPendingFrame && (lastQueuedBytes = null, lastQueuedFormat = null, lastQueuedFingerprint = void 0), activeAbort?.abort(), activeAbort = null;
|
|
4052
|
+
}
|
|
4053
|
+
function resetQueuedFrameIdentity() {
|
|
4054
|
+
lastSourceBytes = null, lastQueuedBytes = null, lastQueuedFormat = null, lastQueuedFingerprint = void 0;
|
|
4055
|
+
}
|
|
4056
|
+
function setPaused(paused) {
|
|
4057
|
+
effectivePaused.value !== paused && (props.paused == null && (internalPaused.value = paused), emit("update:paused", paused));
|
|
4058
|
+
}
|
|
4059
|
+
function setPlaybackRate(rate) {
|
|
4060
|
+
let next = playbackRate(rate);
|
|
4061
|
+
effectivePlaybackRate.value !== next && (props.playbackRate == null && (internalPlaybackRate.value = next), emit("update:playbackRate", next));
|
|
4062
|
+
}
|
|
4063
|
+
function applySeek(timestampMs, restart) {
|
|
4064
|
+
let parsed = Number(timestampMs);
|
|
4065
|
+
if (!Number.isFinite(parsed))
|
|
4066
|
+
return;
|
|
4067
|
+
stopPlayback(), resetQueuedFrameIdentity();
|
|
4068
|
+
let next = seekTimestamp(parsed);
|
|
4069
|
+
updateTimestamp(next, !0), seekPreviewMs.value = void 0;
|
|
4070
|
+
let durationMs = resolvedDurationMs.value;
|
|
4071
|
+
emit("seek", {
|
|
4072
|
+
timestampMs: next,
|
|
4073
|
+
...durationMs ? { durationMs } : {}
|
|
4074
|
+
}), restart && startPlayback(effectivePaused.value);
|
|
4075
|
+
}
|
|
4076
|
+
function controlCell(event) {
|
|
4077
|
+
return {
|
|
4078
|
+
x: Math.floor(event.cellX - layout.originX - props.x),
|
|
4079
|
+
y: Math.floor(event.cellY - layout.originY - props.y)
|
|
4080
|
+
};
|
|
4081
|
+
}
|
|
4082
|
+
function previewSeekAt(cellX) {
|
|
4083
|
+
let duration = resolvedDurationMs.value;
|
|
4084
|
+
if (!duration)
|
|
4085
|
+
return;
|
|
4086
|
+
let { progressX, progressWidth } = controlLayout.value, offset = Math.max(0, Math.min(progressWidth - 1, cellX - progressX));
|
|
4087
|
+
seekPreviewMs.value = progressWidth <= 1 ? 0 : offset / Math.max(1, progressWidth - 1) * duration;
|
|
4088
|
+
}
|
|
4089
|
+
function captureControlPointer(event) {
|
|
4090
|
+
let native = event.nativeEvent, pointerId = native?.pointerId, target = native?.target;
|
|
4091
|
+
pointerId == null || !target?.setPointerCapture || (target.setPointerCapture(pointerId), controlPointerCapture = { pointerId, target });
|
|
4092
|
+
}
|
|
4093
|
+
function releaseControlPointer() {
|
|
4094
|
+
controlPointerCapture && (controlPointerCapture.target.releasePointerCapture?.(controlPointerCapture.pointerId), controlPointerCapture = null);
|
|
4095
|
+
}
|
|
4096
|
+
function rateAt(cellX) {
|
|
4097
|
+
let { ratesX, showAllRates } = controlLayout.value, offset = cellX - ratesX;
|
|
4098
|
+
if (!showAllRates) {
|
|
4099
|
+
if (offset < 0 || offset >= 2)
|
|
4100
|
+
return;
|
|
4101
|
+
let index = PLAYBACK_RATES.indexOf(effectivePlaybackRate.value);
|
|
4102
|
+
return PLAYBACK_RATES[(index + 1) % PLAYBACK_RATES.length];
|
|
4103
|
+
}
|
|
4104
|
+
if (!(offset < 0 || offset % 3 >= 2))
|
|
4105
|
+
return PLAYBACK_RATES[Math.floor(offset / 3)];
|
|
4106
|
+
}
|
|
4107
|
+
function onInteractivePointerDown(event) {
|
|
4108
|
+
if (event.button != null && event.button !== 0)
|
|
4109
|
+
return;
|
|
4110
|
+
let { x: cellX, y: cellY } = controlCell(event);
|
|
4111
|
+
if (cellY < videoHeight.value) {
|
|
4112
|
+
suppressNextVideoClick = !1;
|
|
4113
|
+
return;
|
|
4114
|
+
}
|
|
4115
|
+
if (!showControls.value)
|
|
4116
|
+
return;
|
|
4117
|
+
let { actionY, progressY, progressX, progressWidth } = controlLayout.value, rate = rateAt(cellX);
|
|
4118
|
+
if (cellY === actionY && cellX <= 1) {
|
|
4119
|
+
event.preventDefault(), event.stopPropagation(), suppressNextVideoClick = !0, setPaused(!effectivePaused.value);
|
|
4120
|
+
return;
|
|
4121
|
+
}
|
|
4122
|
+
if (cellY === actionY && rate) {
|
|
4123
|
+
event.preventDefault(), event.stopPropagation(), suppressNextVideoClick = !0, setPlaybackRate(rate);
|
|
4124
|
+
return;
|
|
4125
|
+
}
|
|
4126
|
+
cellY !== progressY || !resolvedDurationMs.value || cellX < progressX || cellX >= progressX + progressWidth || (event.preventDefault(), event.stopPropagation(), suppressNextVideoClick = !0, seeking.value = !0, stopPlayback(), previewSeekAt(cellX), captureControlPointer(event));
|
|
4127
|
+
}
|
|
4128
|
+
function onInteractivePointerMove(event) {
|
|
4129
|
+
if (seeking.value) {
|
|
4130
|
+
if (event.buttons === 0) {
|
|
4131
|
+
onInteractivePointerUp(event);
|
|
4132
|
+
return;
|
|
4133
|
+
}
|
|
4134
|
+
event.preventDefault(), event.stopPropagation(), previewSeekAt(controlCell(event).x);
|
|
4135
|
+
}
|
|
4136
|
+
}
|
|
4137
|
+
function onInteractivePointerUp(event) {
|
|
4138
|
+
if (!seeking.value)
|
|
4139
|
+
return;
|
|
4140
|
+
event.preventDefault(), event.stopPropagation(), previewSeekAt(controlCell(event).x);
|
|
4141
|
+
let timestampMs = seekPreviewMs.value ?? lastTimestampMs;
|
|
4142
|
+
applySeek(timestampMs, !1), seeking.value = !1, releaseControlPointer(), startPlayback(effectivePaused.value);
|
|
4143
|
+
}
|
|
4144
|
+
function onVideoClick(event) {
|
|
4145
|
+
if (!(event.button != null && event.button !== 0)) {
|
|
4146
|
+
if (suppressNextVideoClick) {
|
|
4147
|
+
suppressNextVideoClick = !1, event.preventDefault(), event.stopPropagation();
|
|
4148
|
+
return;
|
|
4149
|
+
}
|
|
4150
|
+
controlCell(event).y >= videoHeight.value || (event.preventDefault(), event.stopPropagation(), setPaused(!effectivePaused.value));
|
|
4151
|
+
}
|
|
4152
|
+
}
|
|
4153
|
+
function finishControlSeek() {
|
|
4154
|
+
if (!seeking.value)
|
|
4155
|
+
return;
|
|
4156
|
+
let timestampMs = seekPreviewMs.value ?? lastTimestampMs;
|
|
4157
|
+
applySeek(timestampMs, !1), seeking.value = !1, releaseControlPointer(), startPlayback(effectivePaused.value);
|
|
4158
|
+
}
|
|
4159
|
+
function onControlKeydown(event) {
|
|
4160
|
+
if (event.key === "Enter" || event.key === " " || event.key === "Spacebar") {
|
|
4161
|
+
event.preventDefault(), event.stopPropagation(), setPaused(!effectivePaused.value);
|
|
4162
|
+
return;
|
|
4163
|
+
}
|
|
4164
|
+
if (event.key === "ArrowUp" || event.key === "ArrowDown") {
|
|
4165
|
+
event.preventDefault(), event.stopPropagation();
|
|
4166
|
+
let index = PLAYBACK_RATES.indexOf(effectivePlaybackRate.value), offset = event.key === "ArrowUp" ? 1 : -1;
|
|
4167
|
+
setPlaybackRate(PLAYBACK_RATES[Math.max(0, Math.min(2, index + offset))]);
|
|
4168
|
+
return;
|
|
4169
|
+
}
|
|
4170
|
+
if (!event.repeat && (event.key === "Home" || event.key === "End") && resolvedDurationMs.value) {
|
|
4171
|
+
event.preventDefault(), event.stopPropagation(), applySeek(event.key === "Home" ? 0 : resolvedDurationMs.value, !0);
|
|
4172
|
+
return;
|
|
4173
|
+
}
|
|
4174
|
+
(event.key === "1" || event.key === "2" || event.key === "3") && (event.preventDefault(), event.stopPropagation(), setPlaybackRate(Number(event.key)));
|
|
4175
|
+
}
|
|
4176
|
+
function queueFrame(frame, expectedFormat) {
|
|
4177
|
+
let normalized = normalizeFrame(frame);
|
|
4178
|
+
if (normalized.format !== expectedFormat)
|
|
4179
|
+
throw new Error(`TVideo frame source did not provide requested ${expectedFormat} frames`);
|
|
4180
|
+
normalized.durationMs != null && normalized.durationMs !== discoveredDurationMs.value && (discoveredDurationMs.value = normalized.durationMs), normalized = { ...normalized, timestampMs: timelineTimestamp(normalized.timestampMs) };
|
|
4181
|
+
let sourceBytes = frameBytes(normalized), reusesSourceBuffer = sourceBytes === lastSourceBytes;
|
|
4182
|
+
lastSourceBytes = sourceBytes;
|
|
4183
|
+
let stableFrame = reusesSourceBuffer ? normalized.format === "gray8" ? { ...normalized, pixels: new Uint8Array(normalized.pixels) } : { ...normalized, png: new Uint8Array(normalized.png) } : normalized, bytes = frameBytes(stableFrame), sameFingerprint = normalized.format === lastQueuedFormat && normalized.fingerprint != null && lastQueuedFingerprint != null && normalized.fingerprint === lastQueuedFingerprint, canCompareBytes = normalized.fingerprint == null && lastQueuedFingerprint == null && !reusesSourceBuffer;
|
|
4184
|
+
if (sameFingerprint || canCompareBytes && normalized.format === lastQueuedFormat && lastQueuedBytes && sameBytes(lastQueuedBytes, sourceBytes)) {
|
|
4185
|
+
lastQueuedBytes = bytes, lastQueuedFormat = normalized.format, lastQueuedFingerprint = normalized.fingerprint, updateTimestamp(normalized.timestampMs), mailbox.hasPending() && mailbox.replacePending(stableFrame);
|
|
4186
|
+
return;
|
|
4187
|
+
}
|
|
4188
|
+
lastQueuedBytes = bytes, lastQueuedFormat = normalized.format, lastQueuedFingerprint = normalized.fingerprint, mailbox.queue(stableFrame) || (commitFrame(stableFrame, 0), scheduler.invalidate({ priority: "low", reason: "stream" }));
|
|
4189
|
+
}
|
|
4190
|
+
function startPlayback(oneFrame = !1) {
|
|
4191
|
+
if (stopPlayback(), !shouldPlay.value && !(oneFrame && alive && props.src.trim().length > 0 && paintable.value && !graphicsActivity?.scrolling.value))
|
|
4192
|
+
return;
|
|
4193
|
+
let currentGeneration = generation, abort = new AbortController();
|
|
4194
|
+
activeAbort = abort, playbackError.value = "";
|
|
4195
|
+
let source = props.frameSource, format = preferredFormat.value, context = {
|
|
4196
|
+
src: props.src,
|
|
4197
|
+
signal: abort.signal,
|
|
4198
|
+
maxFps: resolvedDecodeFps.value,
|
|
4199
|
+
pixelWidth: resolvedDecodeWidth.value,
|
|
4200
|
+
pixelHeight: resolvedDecodeHeight.value,
|
|
4201
|
+
startAtMs: lastTimestampMs,
|
|
4202
|
+
preferredFormat: format,
|
|
4203
|
+
playbackRate: effectivePlaybackRate.value,
|
|
4204
|
+
loop: props.loop
|
|
4205
|
+
};
|
|
4206
|
+
(async () => {
|
|
4207
|
+
try {
|
|
4208
|
+
let frames = await source(context);
|
|
4209
|
+
for await (let frame of frames)
|
|
4210
|
+
if (!alive || abort.signal.aborted || currentGeneration !== generation || (queueFrame(frame, format), oneFrame))
|
|
4211
|
+
return;
|
|
4212
|
+
if (!alive || abort.signal.aborted || currentGeneration !== generation)
|
|
4213
|
+
return;
|
|
4214
|
+
mailbox.hasPending() ? pendingEndedGeneration = currentGeneration : emit("ended");
|
|
4215
|
+
} catch (error) {
|
|
4216
|
+
if (!alive || abort.signal.aborted || currentGeneration !== generation)
|
|
4217
|
+
return;
|
|
4218
|
+
playbackError.value = errorMessage2(error), emit("error", error), scheduler.invalidate({ priority: "low", reason: "data" });
|
|
4219
|
+
} finally {
|
|
4220
|
+
activeAbort === abort && (activeAbort = null);
|
|
4221
|
+
}
|
|
4222
|
+
})();
|
|
4223
|
+
}
|
|
4224
|
+
return (0, import_vue13.watch)(
|
|
4225
|
+
() => props.paused,
|
|
4226
|
+
(paused) => {
|
|
4227
|
+
paused != null && (internalPaused.value = paused);
|
|
4228
|
+
}
|
|
4229
|
+
), (0, import_vue13.watch)(
|
|
4230
|
+
() => props.playbackRate,
|
|
4231
|
+
(rate) => {
|
|
4232
|
+
rate != null && (internalPlaybackRate.value = playbackRate(rate));
|
|
4233
|
+
}
|
|
4234
|
+
), (0, import_vue13.watch)(
|
|
4235
|
+
[
|
|
4236
|
+
() => props.src,
|
|
4237
|
+
() => props.frameSource,
|
|
4238
|
+
playbackEnabled,
|
|
4239
|
+
resolvedDecodeFps,
|
|
4240
|
+
resolvedDecodeWidth,
|
|
4241
|
+
resolvedDecodeHeight,
|
|
4242
|
+
preferredFormat,
|
|
4243
|
+
effectivePlaybackRate,
|
|
4244
|
+
() => props.loop
|
|
4245
|
+
],
|
|
4246
|
+
(next, previous) => {
|
|
4247
|
+
let sourceChanged = !previous || next[0] !== previous[0] || next[1] !== previous[1], formatChanged = !previous || next[6] !== previous[6];
|
|
4248
|
+
(sourceChanged || formatChanged) && (resetQueuedFrameIdentity(), sourceChanged && (lastTimestampMs = 0, displayedTimestampMs.value = 0, discoveredDurationMs.value = void 0, seekPreviewMs.value = void 0, seeking.value = !1, suppressNextVideoClick = !1, releaseControlPointer(), droppedFrames = 0), playbackError.value = "", frameRenderer.value = void 0), startPlayback();
|
|
4249
|
+
},
|
|
4250
|
+
{ immediate: !0, flush: "post" }
|
|
4251
|
+
), (0, import_vue13.onBeforeUnmount)(() => {
|
|
4252
|
+
alive = !1, stopPlayback(), releaseControlPointer(), mailbox.dispose(), unsubscribeTerminalResize(), unsubscribeGraphicsOutput();
|
|
4253
|
+
}), () => {
|
|
4254
|
+
let children = [
|
|
4255
|
+
(0, import_vue13.h)(TAgentTerminalGraphic, {
|
|
4256
|
+
x: props.x,
|
|
4257
|
+
y: props.y,
|
|
4258
|
+
w: props.w,
|
|
4259
|
+
h: videoHeight.value,
|
|
4260
|
+
zIndex: props.zIndex,
|
|
4261
|
+
content: props.src.trim() ? props.src : "video",
|
|
4262
|
+
fallback: visibleFallback.value,
|
|
4263
|
+
style: props.style,
|
|
4264
|
+
clear: props.clear,
|
|
4265
|
+
final: !1,
|
|
4266
|
+
streaming: !0,
|
|
4267
|
+
renderer: frameRenderer.value,
|
|
4268
|
+
placementKey,
|
|
4269
|
+
preserveRawWhileRendering: !0,
|
|
4270
|
+
ignoreSamePlaneRawCoverage: !0,
|
|
4271
|
+
suspended: !paintable.value
|
|
4272
|
+
})
|
|
4273
|
+
];
|
|
4274
|
+
return props.controls && children.push(
|
|
4275
|
+
(0, import_vue13.h)(
|
|
4276
|
+
TView,
|
|
4277
|
+
{
|
|
4278
|
+
x: props.x,
|
|
4279
|
+
y: props.y,
|
|
4280
|
+
w: Math.max(0, Math.floor(props.w)),
|
|
4281
|
+
h: Math.max(0, Math.floor(props.h)),
|
|
4282
|
+
zIndex: props.zIndex,
|
|
4283
|
+
focusable: !0,
|
|
4284
|
+
selectable: !1,
|
|
4285
|
+
onClick: onVideoClick,
|
|
4286
|
+
onPointerdown: onInteractivePointerDown,
|
|
4287
|
+
onPointermove: onInteractivePointerMove,
|
|
4288
|
+
onPointerup: onInteractivePointerUp,
|
|
4289
|
+
onKeydown: onControlKeydown,
|
|
4290
|
+
onBlur: finishControlSeek
|
|
4291
|
+
},
|
|
4292
|
+
() => {
|
|
4293
|
+
if (!showControls.value)
|
|
4294
|
+
return [];
|
|
4295
|
+
let layout2 = controlLayout.value, segments = progressSegments.value, controls = Array.from(
|
|
4296
|
+
{ length: controlRows.value },
|
|
4297
|
+
(_, index) => (0, import_vue13.h)(TText, {
|
|
4298
|
+
x: 0,
|
|
4299
|
+
y: videoHeight.value + index,
|
|
4300
|
+
w: layout2.width,
|
|
4301
|
+
value: controlFill.value,
|
|
4302
|
+
style: props.style
|
|
4303
|
+
})
|
|
4304
|
+
);
|
|
4305
|
+
return controls.push(
|
|
4306
|
+
(0, import_vue13.h)(TText, {
|
|
4307
|
+
x: 0,
|
|
4308
|
+
y: layout2.actionY,
|
|
4309
|
+
w: 2,
|
|
4310
|
+
value: effectivePaused.value ? "> " : "||",
|
|
4311
|
+
style: props.style
|
|
4312
|
+
})
|
|
4313
|
+
), layout2.showTimes && (layout2.kind === "cinema" ? controls.push(
|
|
4314
|
+
(0, import_vue13.h)(TText, {
|
|
4315
|
+
x: layout2.currentX,
|
|
4316
|
+
y: layout2.actionY,
|
|
4317
|
+
w: textCellWidth(layout2.timeText),
|
|
4318
|
+
value: layout2.timeText,
|
|
4319
|
+
style: props.style
|
|
4320
|
+
})
|
|
4321
|
+
) : controls.push(
|
|
4322
|
+
(0, import_vue13.h)(TText, {
|
|
4323
|
+
x: layout2.currentX,
|
|
4324
|
+
y: layout2.actionY,
|
|
4325
|
+
w: layout2.timeWidth,
|
|
4326
|
+
value: layout2.current,
|
|
4327
|
+
style: props.style
|
|
4328
|
+
}),
|
|
4329
|
+
(0, import_vue13.h)(TText, {
|
|
4330
|
+
x: layout2.totalX,
|
|
4331
|
+
y: layout2.actionY,
|
|
4332
|
+
w: layout2.timeWidth,
|
|
4333
|
+
value: layout2.duration,
|
|
4334
|
+
style: props.style
|
|
4335
|
+
})
|
|
4336
|
+
)), segments.playedWidth > 0 && controls.push(
|
|
4337
|
+
(0, import_vue13.h)(TText, {
|
|
4338
|
+
x: layout2.progressX,
|
|
4339
|
+
y: layout2.progressY,
|
|
4340
|
+
w: segments.playedWidth,
|
|
4341
|
+
value: progressGlyphs.value.played,
|
|
4342
|
+
style: props.style
|
|
4343
|
+
})
|
|
4344
|
+
), segments.thumbWidth > 0 && controls.push(
|
|
4345
|
+
(0, import_vue13.h)(TText, {
|
|
4346
|
+
x: layout2.progressX + segments.playedWidth,
|
|
4347
|
+
y: layout2.progressY,
|
|
4348
|
+
w: 1,
|
|
4349
|
+
value: "\u254B",
|
|
4350
|
+
style: progressThumbStyle.value
|
|
4351
|
+
})
|
|
4352
|
+
), segments.remainingWidth > 0 && controls.push(
|
|
4353
|
+
(0, import_vue13.h)(TText, {
|
|
4354
|
+
x: layout2.progressX + segments.playedWidth + segments.thumbWidth,
|
|
4355
|
+
y: layout2.progressY,
|
|
4356
|
+
w: segments.remainingWidth,
|
|
4357
|
+
value: progressGlyphs.value.remaining,
|
|
4358
|
+
style: remainingProgressStyle.value
|
|
4359
|
+
})
|
|
4360
|
+
), layout2.showAllRates ? controls.push(
|
|
4361
|
+
...PLAYBACK_RATES.map(
|
|
4362
|
+
(rate, index) => (0, import_vue13.h)(TText, {
|
|
4363
|
+
x: layout2.ratesX + index * 3,
|
|
4364
|
+
y: layout2.actionY,
|
|
4365
|
+
w: 2,
|
|
4366
|
+
value: `${rate}x`,
|
|
4367
|
+
style: rateStyles.value[index]
|
|
4368
|
+
})
|
|
4369
|
+
)
|
|
4370
|
+
) : controls.push(
|
|
4371
|
+
(0, import_vue13.h)(TText, {
|
|
4372
|
+
x: layout2.ratesX,
|
|
4373
|
+
y: layout2.actionY,
|
|
4374
|
+
w: 2,
|
|
4375
|
+
value: `${effectivePlaybackRate.value}x`,
|
|
4376
|
+
style: rateStyles.value[PLAYBACK_RATES.indexOf(effectivePlaybackRate.value)]
|
|
4377
|
+
})
|
|
4378
|
+
), controls;
|
|
4379
|
+
}
|
|
4380
|
+
)
|
|
4381
|
+
), (0, import_vue13.h)("span", rootProps, children);
|
|
4382
|
+
};
|
|
4383
|
+
}
|
|
4384
|
+
});
|
|
4385
|
+
|
|
4386
|
+
// src/vue/components/T3DViewport.ts
|
|
4387
|
+
var DEFAULT_MAX_FPS2 = 24, DEFAULT_AUTO_ROTATE_SPEED = 0.35, DEFAULT_POINTER_SENSITIVITY = 0.055, VELOCITY_DAMPING_PER_SECOND = 5.5, ZOOM_DAMPING_PER_SECOND = 7, MAX_ZOOM_VELOCITY = 3, DEFAULT_MIN_ZOOM = 0.65, DEFAULT_MAX_ZOOM = 1.65, DEFAULT_ZOOM_SENSITIVITY = 0.1, MAX_PITCH = Math.PI * 0.42, t3DViewportProps = {
|
|
4388
|
+
/** Horizontal position in terminal cells. */
|
|
4389
|
+
x: { type: Number, required: !0 },
|
|
4390
|
+
/** Vertical position in terminal cells. */
|
|
4391
|
+
y: { type: Number, required: !0 },
|
|
4392
|
+
/** Width in terminal cells. */
|
|
4393
|
+
w: { type: Number, required: !0 },
|
|
4394
|
+
/** Height in terminal cells. */
|
|
4395
|
+
h: { type: Number, required: !0 },
|
|
4396
|
+
/** Paint and pointer hit-test stacking order. */
|
|
4397
|
+
zIndex: { type: Number, default: 0 },
|
|
4398
|
+
/** Pull renderer captured at mount; remount the component to replace it. */
|
|
4399
|
+
renderer: { type: Object, required: !0 },
|
|
4400
|
+
/** Stops frame pulling while true. */
|
|
4401
|
+
paused: { type: Boolean, default: !1 },
|
|
4402
|
+
/** Maximum requested frames per second. */
|
|
4403
|
+
maxFps: { type: Number, default: DEFAULT_MAX_FPS2 },
|
|
4404
|
+
/** Requested source width in pixels; TVideo may adapt it for ASCII output. */
|
|
4405
|
+
pixelWidth: { type: Number, default: void 0 },
|
|
4406
|
+
/** Requested source height in pixels; TVideo may adapt it for ASCII output. */
|
|
4407
|
+
pixelHeight: { type: Number, default: void 0 },
|
|
4408
|
+
/** Text displayed before a frame is available or after rendering fails. */
|
|
4409
|
+
fallback: { type: String, default: "[3D viewport]" },
|
|
4410
|
+
/** Terminal style applied to fallback and ASCII output. */
|
|
4411
|
+
style: { type: Object, default: void 0 },
|
|
4412
|
+
/** Clears cells underneath each video frame. */
|
|
4413
|
+
clear: { type: Boolean, default: !0 },
|
|
4414
|
+
/** Enables pointer orbit, wheel zoom, and hover motion tracking. */
|
|
4415
|
+
interactive: { type: Boolean, default: !0 },
|
|
4416
|
+
/** Initial yaw angle in radians, also restored by resetMotion(). */
|
|
4417
|
+
initialYaw: { type: Number, default: 0 },
|
|
4418
|
+
/** Initial pitch angle in radians, also restored by resetMotion(). */
|
|
4419
|
+
initialPitch: { type: Number, default: 0 },
|
|
4420
|
+
/** Enables continuous yaw rotation when not dragging. */
|
|
4421
|
+
autoRotate: { type: Boolean, default: !0 },
|
|
4422
|
+
/** Automatic yaw rotation speed in radians per second. */
|
|
4423
|
+
autoRotateSpeed: { type: Number, default: DEFAULT_AUTO_ROTATE_SPEED },
|
|
4424
|
+
/** Drag sensitivity in radians per terminal cell. */
|
|
4425
|
+
pointerSensitivity: { type: Number, default: DEFAULT_POINTER_SENSITIVITY },
|
|
4426
|
+
/** Initial camera zoom, also restored by resetMotion(). */
|
|
4427
|
+
initialZoom: { type: Number, default: 1 },
|
|
4428
|
+
/** Minimum camera zoom accepted from wheel and trackpad gestures. */
|
|
4429
|
+
minZoom: { type: Number, default: DEFAULT_MIN_ZOOM },
|
|
4430
|
+
/** Maximum camera zoom accepted from wheel and trackpad gestures. */
|
|
4431
|
+
maxZoom: { type: Number, default: DEFAULT_MAX_ZOOM },
|
|
4432
|
+
/** Zoom impulse per normalized wheel or trackpad unit. */
|
|
4433
|
+
zoomSensitivity: { type: Number, default: DEFAULT_ZOOM_SENSITIVITY }
|
|
4434
|
+
};
|
|
4435
|
+
function finite(value, fallback) {
|
|
4436
|
+
return Number.isFinite(value) ? value : fallback;
|
|
4437
|
+
}
|
|
4438
|
+
function clampPitch(value) {
|
|
4439
|
+
return Math.max(-MAX_PITCH, Math.min(MAX_PITCH, value));
|
|
4440
|
+
}
|
|
4441
|
+
function zoomBounds(minZoom, maxZoom) {
|
|
4442
|
+
let first = Math.max(0.01, finite(minZoom, DEFAULT_MIN_ZOOM)), second = Math.max(0.01, finite(maxZoom, DEFAULT_MAX_ZOOM));
|
|
4443
|
+
return first <= second ? { min: first, max: second } : { min: second, max: first };
|
|
4444
|
+
}
|
|
4445
|
+
function clampZoom(value, minZoom, maxZoom) {
|
|
4446
|
+
let { min, max } = zoomBounds(minZoom, maxZoom);
|
|
4447
|
+
return Math.max(min, Math.min(max, finite(value, 1)));
|
|
4448
|
+
}
|
|
4449
|
+
function normalizedWheelDelta(event) {
|
|
4450
|
+
let deltaY = Number(event.deltaY ?? 0);
|
|
4451
|
+
return !Number.isFinite(deltaY) || deltaY === 0 ? 0 : event.deltaMode === 1 ? deltaY : event.deltaMode === 2 ? Math.max(-3, Math.min(3, deltaY * 3)) : event.deltaMode === 0 ? deltaY / 100 : Number.isInteger(deltaY) && Math.abs(deltaY) <= 3 ? deltaY : deltaY / 100;
|
|
4452
|
+
}
|
|
4453
|
+
function nowMs() {
|
|
4454
|
+
return typeof performance < "u" ? performance.now() : Date.now();
|
|
4455
|
+
}
|
|
4456
|
+
function abortError() {
|
|
4457
|
+
let error = new Error("T3D viewport render aborted");
|
|
4458
|
+
return error.name = "AbortError", error;
|
|
4459
|
+
}
|
|
4460
|
+
function warnDev(message) {
|
|
4461
|
+
globalThis.process?.env?.NODE_ENV !== "production" && console.warn(message);
|
|
4462
|
+
}
|
|
4463
|
+
function waitFor(ms, signal) {
|
|
4464
|
+
return signal.aborted || ms <= 0 ? Promise.resolve() : new Promise((resolve) => {
|
|
4465
|
+
let timer = setTimeout(done, ms);
|
|
4466
|
+
function done() {
|
|
4467
|
+
clearTimeout(timer), signal.removeEventListener("abort", done), resolve();
|
|
4468
|
+
}
|
|
4469
|
+
signal.addEventListener("abort", done, { once: !0 });
|
|
4470
|
+
});
|
|
4471
|
+
}
|
|
4472
|
+
var T3DViewport = (0, import_vue14.defineComponent)({
|
|
4473
|
+
name: "T3DViewport",
|
|
4474
|
+
props: t3DViewportProps,
|
|
4475
|
+
emits: {
|
|
4476
|
+
/** A frame was committed by TVideo. */
|
|
4477
|
+
frame: (_event) => !0,
|
|
4478
|
+
/** Rendering or frame processing failed. */
|
|
4479
|
+
error: (_error) => !0,
|
|
4480
|
+
/** Hovered renderer object changed, or cleared to null. */
|
|
4481
|
+
objecthover: (_hit) => !0,
|
|
4482
|
+
/** Click-locked renderer object changed, or cleared to null. */
|
|
4483
|
+
objectselect: (_hit) => !0
|
|
4484
|
+
},
|
|
4485
|
+
setup(props, { emit, expose }) {
|
|
4486
|
+
let layout = useLayout(), renderer = props.renderer, alive = !0, yaw = finite(props.initialYaw, 0), pitch = clampPitch(finite(props.initialPitch, 0)), yawVelocity = 0, pitchVelocity = 0, pointerX = 0, pointerY = 0, pointerSpeed = 0, hovering = !1, zoom = clampZoom(props.initialZoom, props.minZoom, props.maxZoom), zoomVelocity = 0, hoveredObject = null, selectedObject = null, actualPixelWidth = Math.max(1, Math.floor(props.pixelWidth ?? props.w)), actualPixelHeight = Math.max(1, Math.floor(props.pixelHeight ?? props.h)), pointer = null, drag = null, renderTail = Promise.resolve();
|
|
4487
|
+
function motionSnapshot() {
|
|
4488
|
+
return {
|
|
4489
|
+
yaw,
|
|
4490
|
+
pitch,
|
|
4491
|
+
yawVelocity,
|
|
4492
|
+
pitchVelocity,
|
|
4493
|
+
pointerX,
|
|
4494
|
+
pointerY,
|
|
4495
|
+
pointerSpeed,
|
|
4496
|
+
hovering,
|
|
4497
|
+
zoom,
|
|
4498
|
+
zoomVelocity,
|
|
4499
|
+
hoveredObjectId: hoveredObject?.objectId ?? null,
|
|
4500
|
+
selectedObjectId: selectedObject?.objectId ?? null
|
|
4501
|
+
};
|
|
4502
|
+
}
|
|
4503
|
+
async function renderFrame(context) {
|
|
4504
|
+
let previous = renderTail, release = () => {
|
|
4505
|
+
};
|
|
4506
|
+
renderTail = new Promise((resolve) => {
|
|
4507
|
+
release = resolve;
|
|
4508
|
+
}), await previous;
|
|
4509
|
+
try {
|
|
4510
|
+
if (!alive || context.signal.aborted)
|
|
4511
|
+
throw abortError();
|
|
4512
|
+
return await renderer.render(context);
|
|
4513
|
+
} finally {
|
|
4514
|
+
release();
|
|
4515
|
+
}
|
|
4516
|
+
}
|
|
4517
|
+
function sameHit(left, right) {
|
|
4518
|
+
return left?.objectId === right?.objectId;
|
|
4519
|
+
}
|
|
4520
|
+
function setHoveredObject(hit) {
|
|
4521
|
+
sameHit(hoveredObject, hit) || (hoveredObject = hit, emit("objecthover", hit));
|
|
4522
|
+
}
|
|
4523
|
+
function setSelectedObject(hit) {
|
|
4524
|
+
sameHit(selectedObject, hit) || (selectedObject = hit, emit("objectselect", hit));
|
|
4525
|
+
}
|
|
4526
|
+
function resetMotion() {
|
|
4527
|
+
yaw = finite(props.initialYaw, 0), pitch = clampPitch(finite(props.initialPitch, 0)), yawVelocity = 0, pitchVelocity = 0, pointerX = 0, pointerY = 0, pointerSpeed = 0, zoom = clampZoom(props.initialZoom, props.minZoom, props.maxZoom), zoomVelocity = 0, setHoveredObject(null), setSelectedObject(null), pointer = null, drag = null;
|
|
4528
|
+
}
|
|
4529
|
+
expose({ resetMotion });
|
|
4530
|
+
function localCell(event) {
|
|
4531
|
+
return {
|
|
4532
|
+
x: Math.floor(event.cellX - layout.originX - props.x),
|
|
4533
|
+
y: Math.floor(event.cellY - layout.originY - props.y)
|
|
4534
|
+
};
|
|
4535
|
+
}
|
|
4536
|
+
function eventTime(event) {
|
|
4537
|
+
return Number.isFinite(event.timeStamp) ? event.timeStamp : nowMs();
|
|
4538
|
+
}
|
|
4539
|
+
function updatePointerPosition(point) {
|
|
4540
|
+
let width = Math.max(1, Math.floor(props.w)), height = Math.max(1, Math.floor(props.h));
|
|
4541
|
+
pointerX = Math.max(-1, Math.min(1, (point.x + 0.5) / width * 2 - 1)), pointerY = Math.max(-1, Math.min(1, (point.y + 0.5) / height * 2 - 1));
|
|
4542
|
+
}
|
|
4543
|
+
function hitTest() {
|
|
4544
|
+
if (!renderer.hitTest)
|
|
4545
|
+
return null;
|
|
4546
|
+
try {
|
|
4547
|
+
return renderer.hitTest({
|
|
4548
|
+
pointerX,
|
|
4549
|
+
pointerY,
|
|
4550
|
+
pixelWidth: actualPixelWidth,
|
|
4551
|
+
pixelHeight: actualPixelHeight,
|
|
4552
|
+
cellWidth: Math.max(1, Math.floor(props.w)),
|
|
4553
|
+
cellHeight: Math.max(1, Math.floor(props.h)),
|
|
4554
|
+
motion: motionSnapshot()
|
|
4555
|
+
});
|
|
4556
|
+
} catch (error) {
|
|
4557
|
+
return emit("error", error), null;
|
|
4558
|
+
}
|
|
4559
|
+
}
|
|
4560
|
+
function updateHoveredObject() {
|
|
4561
|
+
renderer.hitTest && setHoveredObject(hitTest());
|
|
4562
|
+
}
|
|
4563
|
+
function onPointerEnter(event) {
|
|
4564
|
+
if (!props.interactive)
|
|
4565
|
+
return;
|
|
4566
|
+
let point = localCell(event);
|
|
4567
|
+
hovering = !0, updatePointerPosition(point), pointer = { ...point, timeMs: eventTime(event) }, updateHoveredObject();
|
|
4568
|
+
}
|
|
4569
|
+
function onPointerDown(event) {
|
|
4570
|
+
if (!props.interactive || event.button != null && event.button !== 0)
|
|
4571
|
+
return;
|
|
4572
|
+
event.preventDefault(), event.stopPropagation();
|
|
4573
|
+
let point = localCell(event), timeMs = eventTime(event);
|
|
4574
|
+
hovering = !0, updatePointerPosition(point), yawVelocity = 0, pitchVelocity = 0, pointerSpeed = 0, pointer = { ...point, timeMs }, drag = { ...point, timeMs, moved: !1 }, updateHoveredObject();
|
|
4575
|
+
}
|
|
4576
|
+
function onPointerMove(event) {
|
|
4577
|
+
if (!props.interactive)
|
|
4578
|
+
return;
|
|
4579
|
+
hovering = !0;
|
|
4580
|
+
let point = localCell(event);
|
|
4581
|
+
updatePointerPosition(point);
|
|
4582
|
+
let timeMs = eventTime(event), previous = drag ?? pointer;
|
|
4583
|
+
if (pointer = { ...point, timeMs }, !previous)
|
|
4584
|
+
return;
|
|
4585
|
+
let dtMs = Math.max(1, timeMs - previous.timeMs), dx = point.x - previous.x, dy = point.y - previous.y, sensitivity = finite(props.pointerSensitivity, DEFAULT_POINTER_SENSITIVITY), deltaYaw = dx * sensitivity, deltaPitch = dy * sensitivity;
|
|
4586
|
+
if (pointerSpeed = Math.hypot(dx, dy) * 1e3 / dtMs, !drag) {
|
|
4587
|
+
if (renderer.hitTest) {
|
|
4588
|
+
yawVelocity = 0, pitchVelocity = 0, updateHoveredObject();
|
|
4589
|
+
return;
|
|
4590
|
+
}
|
|
4591
|
+
yawVelocity = deltaYaw * 650 / dtMs, pitchVelocity = deltaPitch * 450 / dtMs;
|
|
1830
4592
|
return;
|
|
1831
|
-
let manager = events.value, nodeId = eventNode.id.value;
|
|
1832
|
-
!manager || !nodeId || manager.getFocused() !== nodeId && manager.focus(nodeId);
|
|
1833
|
-
}), (0, import_vue9.watch)(
|
|
1834
|
-
() => visible.value,
|
|
1835
|
-
(nextVisible) => {
|
|
1836
|
-
nextVisible || cancelWheelScrollFrame();
|
|
1837
4593
|
}
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
for (let y = r.y; y < r.y + r.h; y++)
|
|
1844
|
-
rows.push(y);
|
|
1845
|
-
return rows;
|
|
4594
|
+
if (event.buttons === 0) {
|
|
4595
|
+
drag = null;
|
|
4596
|
+
return;
|
|
4597
|
+
}
|
|
4598
|
+
event.preventDefault(), event.stopPropagation(), yaw += deltaYaw, pitch = clampPitch(pitch + deltaPitch), yawVelocity = deltaYaw * 1e3 / dtMs, pitchVelocity = deltaPitch * 1e3 / dtMs, setHoveredObject(null), drag = { ...point, timeMs, moved: drag.moved || dx !== 0 || dy !== 0 };
|
|
1846
4599
|
}
|
|
1847
|
-
function
|
|
1848
|
-
if (!
|
|
1849
|
-
return
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
4600
|
+
function onPointerUp(event) {
|
|
4601
|
+
if (!drag)
|
|
4602
|
+
return;
|
|
4603
|
+
event.preventDefault(), event.stopPropagation();
|
|
4604
|
+
let moved = drag.moved;
|
|
4605
|
+
if (drag = null, !moved && renderer.hitTest) {
|
|
4606
|
+
let hit = hitTest();
|
|
4607
|
+
setHoveredObject(hit), setSelectedObject(hit);
|
|
4608
|
+
} else
|
|
4609
|
+
updateHoveredObject();
|
|
1854
4610
|
}
|
|
1855
|
-
function
|
|
1856
|
-
|
|
4611
|
+
function onPointerLeave(event) {
|
|
4612
|
+
drag && (event.preventDefault(), event.stopPropagation(), drag = null), hovering = !1, pointer = null, setHoveredObject(null);
|
|
1857
4613
|
}
|
|
1858
|
-
function
|
|
1859
|
-
|
|
4614
|
+
function onWheel(event) {
|
|
4615
|
+
if (!props.interactive)
|
|
4616
|
+
return;
|
|
4617
|
+
let delta = normalizedWheelDelta(event), sensitivity = Math.max(0, finite(props.zoomSensitivity, DEFAULT_ZOOM_SENSITIVITY));
|
|
4618
|
+
delta === 0 || sensitivity === 0 || (event.preventDefault(), event.stopPropagation(), zoomVelocity = Math.max(
|
|
4619
|
+
-MAX_ZOOM_VELOCITY,
|
|
4620
|
+
Math.min(MAX_ZOOM_VELOCITY, zoomVelocity - delta * sensitivity * 6)
|
|
4621
|
+
));
|
|
1860
4622
|
}
|
|
1861
|
-
function
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
return
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
terminalGraphicsActivity.markScroll(), scrollTop.value = clampedTop, options?.emitUpdate && emit("update:scrollTop", clampedTop);
|
|
1871
|
-
let canUseTerminalRowScroll = rendererCapabilities.value.scrollOperations && rendererCapabilities.value.domRows !== !0, scrollPlan = prepareUnsafeFullRowScroll({
|
|
1872
|
-
render,
|
|
1873
|
-
plane: plane.value,
|
|
1874
|
-
rect: r,
|
|
1875
|
-
terminalSize: terminal.size(),
|
|
1876
|
-
delta,
|
|
1877
|
-
rowScrollMode: props.rowScrollMode,
|
|
1878
|
-
rendererCapabilities: {
|
|
1879
|
-
scrollOperations: canUseTerminalRowScroll
|
|
1880
|
-
},
|
|
1881
|
-
isClipped: isClipped(),
|
|
1882
|
-
hasPendingDirtyRows: !!dirtyRowsHint?.length,
|
|
1883
|
-
strategy: options?.strategy ?? "viewport-repaint"
|
|
1884
|
-
}), dirty = !1;
|
|
1885
|
-
return scrollPlan && markRowsDirty(scrollPlan.exposedRows) ? (scrollPlan.apply(), dirty = !0) : dirty = markViewportDirty(), options?.emitScroll && emit("scroll", clampedTop), options?.priority && dirty && invalidateSelf(options.priority, options.reason ?? "scroll"), { changed: !0, dirty, top: clampedTop, controlled };
|
|
4623
|
+
function advanceZoom(deltaMs) {
|
|
4624
|
+
if (deltaMs <= 0 || zoomVelocity === 0)
|
|
4625
|
+
return;
|
|
4626
|
+
let dt = Math.min(deltaMs, 100) / 1e3, next = zoom + zoomVelocity * dt;
|
|
4627
|
+
if (zoom = clampZoom(next, props.minZoom, props.maxZoom), zoom !== next) {
|
|
4628
|
+
zoomVelocity = 0;
|
|
4629
|
+
return;
|
|
4630
|
+
}
|
|
4631
|
+
zoomVelocity *= Math.exp(-ZOOM_DAMPING_PER_SECOND * dt), Math.abs(zoomVelocity) < 1e-3 && (zoomVelocity = 0);
|
|
1886
4632
|
}
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
let
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
paintRow(y);
|
|
4633
|
+
function advanceMotion(deltaMs) {
|
|
4634
|
+
if (deltaMs <= 0 || (advanceZoom(deltaMs), drag))
|
|
4635
|
+
return;
|
|
4636
|
+
let dt = Math.min(deltaMs, 100) / 1e3;
|
|
4637
|
+
if (hovering && !renderer.hitTest) {
|
|
4638
|
+
let targetPitch = clampPitch(-pointerY * 0.36);
|
|
4639
|
+
pitchVelocity += (targetPitch - pitch) * 4.5 * dt;
|
|
4640
|
+
} else
|
|
4641
|
+
hovering || (pointerX *= Math.exp(-7 * dt), pointerY *= Math.exp(-7 * dt));
|
|
4642
|
+
yaw += yawVelocity * dt, pitch = clampPitch(pitch + pitchVelocity * dt);
|
|
4643
|
+
let inspectingObject = !!(renderer.hitTest && (hoveredObject || selectedObject));
|
|
4644
|
+
if (props.autoRotate && !inspectingObject) {
|
|
4645
|
+
let baseSpeed = finite(props.autoRotateSpeed, DEFAULT_AUTO_ROTATE_SPEED), steering = hovering ? 0.85 + pointerX * 1.75 : 1;
|
|
4646
|
+
yaw += baseSpeed * steering * dt;
|
|
4647
|
+
}
|
|
4648
|
+
let decay = Math.exp(-VELOCITY_DAMPING_PER_SECOND * dt);
|
|
4649
|
+
yawVelocity *= decay, pitchVelocity *= decay, pointerSpeed *= decay;
|
|
4650
|
+
}
|
|
4651
|
+
let frameSource = async function* (videoContext) {
|
|
4652
|
+
let startedAt = nowMs(), previousAt = startedAt, frame = 0, frameIntervalMs = 1e3 / Math.max(1, finite(videoContext.maxFps, DEFAULT_MAX_FPS2));
|
|
4653
|
+
for (; alive && !videoContext.signal.aborted; ) {
|
|
4654
|
+
let pulledAt = nowMs(), deltaMs = frame === 0 ? 0 : Math.max(0, pulledAt - previousAt);
|
|
4655
|
+
advanceMotion(deltaMs), actualPixelWidth = videoContext.pixelWidth, actualPixelHeight = videoContext.pixelHeight;
|
|
4656
|
+
let result = await renderFrame({
|
|
4657
|
+
timeMs: Math.max(0, pulledAt - startedAt),
|
|
4658
|
+
deltaMs,
|
|
4659
|
+
frame,
|
|
4660
|
+
pixelWidth: videoContext.pixelWidth,
|
|
4661
|
+
pixelHeight: videoContext.pixelHeight,
|
|
4662
|
+
format: videoContext.preferredFormat,
|
|
4663
|
+
signal: videoContext.signal,
|
|
4664
|
+
motion: motionSnapshot()
|
|
4665
|
+
});
|
|
4666
|
+
if (!alive || videoContext.signal.aborted)
|
|
1922
4667
|
return;
|
|
1923
|
-
|
|
1924
|
-
for (let y = r.y; y < r.y + r.h; y++)
|
|
1925
|
-
paintRow(y);
|
|
4668
|
+
yield result, frame++, previousAt = pulledAt, await waitFor(frameIntervalMs - (nowMs() - pulledAt), videoContext.signal);
|
|
1926
4669
|
}
|
|
1927
|
-
}
|
|
1928
|
-
return (0,
|
|
1929
|
-
|
|
1930
|
-
|
|
4670
|
+
};
|
|
4671
|
+
return (0, import_vue14.watch)(
|
|
4672
|
+
() => props.renderer,
|
|
4673
|
+
(next) => {
|
|
4674
|
+
next !== renderer && warnDev("[vue-tui] T3DViewport renderer is init-only. Remount T3DViewport to replace it.");
|
|
4675
|
+
}
|
|
4676
|
+
), (0, import_vue14.watch)(
|
|
4677
|
+
() => props.interactive,
|
|
4678
|
+
(interactive) => {
|
|
4679
|
+
interactive || (hovering = !1, pointer = null, drag = null, setHoveredObject(null), setSelectedObject(null));
|
|
4680
|
+
}
|
|
4681
|
+
), (0, import_vue14.onBeforeUnmount)(() => {
|
|
4682
|
+
alive = !1, pointer = null, drag = null;
|
|
4683
|
+
}), (0, import_vue14.onUnmounted)(() => renderer.dispose?.()), () => (0, import_vue14.h)("span", [
|
|
4684
|
+
(0, import_vue14.h)(TVideo, {
|
|
4685
|
+
x: props.x,
|
|
4686
|
+
y: props.y,
|
|
4687
|
+
w: props.w,
|
|
4688
|
+
h: props.h,
|
|
4689
|
+
zIndex: props.zIndex,
|
|
4690
|
+
src: "t3d://viewport",
|
|
4691
|
+
frameSource,
|
|
4692
|
+
paused: props.paused,
|
|
4693
|
+
maxFps: props.maxFps,
|
|
4694
|
+
pixelWidth: props.pixelWidth,
|
|
4695
|
+
pixelHeight: props.pixelHeight,
|
|
4696
|
+
fallback: props.fallback,
|
|
4697
|
+
style: props.style,
|
|
4698
|
+
clear: props.clear,
|
|
4699
|
+
onFrame: (event) => emit("frame", event),
|
|
4700
|
+
onError: (error) => emit("error", error)
|
|
4701
|
+
}),
|
|
4702
|
+
props.interactive ? (0, import_vue14.h)(TView, {
|
|
4703
|
+
x: props.x,
|
|
4704
|
+
y: props.y,
|
|
4705
|
+
w: Math.max(0, Math.floor(props.w)),
|
|
4706
|
+
h: Math.max(0, Math.floor(props.h)),
|
|
4707
|
+
zIndex: props.zIndex + 1,
|
|
4708
|
+
selectable: !1,
|
|
4709
|
+
onPointerenter: onPointerEnter,
|
|
4710
|
+
onPointermove: onPointerMove,
|
|
4711
|
+
onPointerleave: onPointerLeave,
|
|
4712
|
+
onPointerdown: onPointerDown,
|
|
4713
|
+
onPointerup: onPointerUp,
|
|
4714
|
+
onWheel
|
|
4715
|
+
}) : null
|
|
4716
|
+
]);
|
|
1931
4717
|
}
|
|
1932
4718
|
});
|
|
1933
4719
|
|
|
1934
4720
|
// src/vue/components/TCharts.ts
|
|
1935
|
-
var
|
|
4721
|
+
var import_vue15 = require("vue");
|
|
1936
4722
|
|
|
1937
4723
|
// src/vue/components/simple-utils.ts
|
|
1938
4724
|
function mergeStyle(...styles) {
|
|
@@ -2271,7 +5057,7 @@ function chooseTooltipPlacement(cells, width, height, anchorX, anchorY, textWidt
|
|
|
2271
5057
|
}
|
|
2272
5058
|
function useChartVisibleRect(props, size) {
|
|
2273
5059
|
let layout = useLayout();
|
|
2274
|
-
return (0,
|
|
5060
|
+
return (0, import_vue15.computed)(() => {
|
|
2275
5061
|
let full = translateRect(
|
|
2276
5062
|
{
|
|
2277
5063
|
x: Math.floor(props.x),
|
|
@@ -2353,7 +5139,7 @@ function createSurface(width, height, clearStyle, cells) {
|
|
|
2353
5139
|
return { width, height, clearStyle, rows };
|
|
2354
5140
|
}
|
|
2355
5141
|
function useChartRender(props, surface, options) {
|
|
2356
|
-
let { terminal } = useTerminal(), layout = useLayout(), { visible, rootProps } = useVisibility(), parentEventZ = (0,
|
|
5142
|
+
let { terminal } = useTerminal(), layout = useLayout(), { visible, rootProps } = useVisibility(), parentEventZ = (0, import_vue15.inject)(EventZIndexContextKey, (0, import_vue15.computed)(() => 0)), eventZ = (0, import_vue15.computed)(() => (parentEventZ.value ?? 0) + (props.zIndex ?? 0)), fullRect = (0, import_vue15.computed)(
|
|
2357
5143
|
() => translateRect(
|
|
2358
5144
|
{
|
|
2359
5145
|
x: Math.floor(props.x),
|
|
@@ -2364,10 +5150,10 @@ function useChartRender(props, surface, options) {
|
|
|
2364
5150
|
layout.originX,
|
|
2365
5151
|
layout.originY
|
|
2366
5152
|
)
|
|
2367
|
-
), absRect = (0,
|
|
5153
|
+
), absRect = (0, import_vue15.computed)(() => {
|
|
2368
5154
|
let translated = fullRect.value;
|
|
2369
5155
|
return layout.clipRect ? intersectRect(translated, layout.clipRect) ?? { x: 0, y: 0, w: 0, h: 0 } : translated;
|
|
2370
|
-
}), dirtyRowsHint = (0,
|
|
5156
|
+
}), dirtyRowsHint = (0, import_vue15.computed)(() => {
|
|
2371
5157
|
if (!visible.value)
|
|
2372
5158
|
return [];
|
|
2373
5159
|
let r = absRect.value;
|
|
@@ -2414,7 +5200,7 @@ function useChartRender(props, surface, options) {
|
|
|
2414
5200
|
for (let y of dirtyRows)
|
|
2415
5201
|
paintRow(y);
|
|
2416
5202
|
}
|
|
2417
|
-
})), () => (0,
|
|
5203
|
+
})), () => (0, import_vue15.h)("span", rootProps);
|
|
2418
5204
|
}
|
|
2419
5205
|
function positiveHeatmapStyle(value, max, styles) {
|
|
2420
5206
|
if (!styles.length)
|
|
@@ -2424,7 +5210,7 @@ function positiveHeatmapStyle(value, max, styles) {
|
|
|
2424
5210
|
let ratio = Math.max(0, Math.min(1, value / max)), index = Math.max(0, Math.min(styles.length - 1, Math.ceil(ratio * styles.length) - 1));
|
|
2425
5211
|
return styles[index] ?? {};
|
|
2426
5212
|
}
|
|
2427
|
-
var TContributionGraph = (0,
|
|
5213
|
+
var TContributionGraph = (0, import_vue15.defineComponent)({
|
|
2428
5214
|
name: "TContributionGraph",
|
|
2429
5215
|
props: {
|
|
2430
5216
|
/** Left position in terminal cells. */
|
|
@@ -2471,7 +5257,7 @@ var TContributionGraph = (0, import_vue10.defineComponent)({
|
|
|
2471
5257
|
style: { type: Object, default: void 0 }
|
|
2472
5258
|
},
|
|
2473
5259
|
setup(props) {
|
|
2474
|
-
let { defaultStyle } = useTerminal(), baseStyle = (0,
|
|
5260
|
+
let { defaultStyle } = useTerminal(), baseStyle = (0, import_vue15.computed)(() => mergeStyle(defaultStyle.value, props.style)), hoverPointer = (0, import_vue15.ref)(null), graphLayout = (0, import_vue15.computed)(() => {
|
|
2475
5261
|
let rowCount = cellCount(props.rows, 7);
|
|
2476
5262
|
if (rowCount <= 0)
|
|
2477
5263
|
return {
|
|
@@ -2506,7 +5292,7 @@ var TContributionGraph = (0, import_vue10.defineComponent)({
|
|
|
2506
5292
|
let label = props.labels?.[index] ?? `#${index + 1}`;
|
|
2507
5293
|
return { x: cellX, y: localY, index, value, label };
|
|
2508
5294
|
}
|
|
2509
|
-
let surface = (0,
|
|
5295
|
+
let surface = (0, import_vue15.computed)(() => {
|
|
2510
5296
|
let current = graphLayout.value;
|
|
2511
5297
|
if (current.rowCount <= 0)
|
|
2512
5298
|
return createSurface(0, 0, baseStyle.value, []);
|
|
@@ -2556,7 +5342,7 @@ var TContributionGraph = (0, import_vue10.defineComponent)({
|
|
|
2556
5342
|
})
|
|
2557
5343
|
});
|
|
2558
5344
|
}
|
|
2559
|
-
}), TLineChart = (0,
|
|
5345
|
+
}), TLineChart = (0, import_vue15.defineComponent)({
|
|
2560
5346
|
name: "TLineChart",
|
|
2561
5347
|
props: {
|
|
2562
5348
|
/** Left position in terminal cells. */
|
|
@@ -2606,7 +5392,7 @@ var TContributionGraph = (0, import_vue10.defineComponent)({
|
|
|
2606
5392
|
tooltipStyle: { type: Object, default: () => ({ fg: "whiteBright" }) }
|
|
2607
5393
|
},
|
|
2608
5394
|
setup(props) {
|
|
2609
|
-
let { defaultStyle } = useTerminal(), clearStyle = (0,
|
|
5395
|
+
let { defaultStyle } = useTerminal(), clearStyle = (0, import_vue15.computed)(() => mergeStyle(defaultStyle.value, props.style)), lineStyle = (0, import_vue15.computed)(() => mergeStyle(clearStyle.value, props.lineStyle)), axisStyle = (0, import_vue15.computed)(() => mergeStyle(clearStyle.value, props.axisStyle)), labelStyle = (0, import_vue15.computed)(() => mergeStyle(clearStyle.value, props.labelStyle)), hoverPointer = (0, import_vue15.ref)(null), lineLayout = (0, import_vue15.computed)(() => {
|
|
2610
5396
|
let width = cellCount(props.w, 0), height = cellCount(props.h, 0), runs = finiteLineRuns(props.values), sourceLength = props.values.length, { min, max } = domainFromValues(props.values, props.min, props.max), layout = resolveAxisLayout(width, height, min, max, props.showAxes);
|
|
2611
5397
|
return { width, height, layout, runs, sourceLength, min, max };
|
|
2612
5398
|
}), visibleRect = useChartVisibleRect(props, lineLayout);
|
|
@@ -2628,7 +5414,7 @@ var TContributionGraph = (0, import_vue10.defineComponent)({
|
|
|
2628
5414
|
), y = layout.plotY + valueToY(value, min, max, layout.plotH), label = props.labels?.[point.originalIndex] ?? `#${point.originalIndex + 1}`;
|
|
2629
5415
|
return { x, y, index: point.originalIndex, label, value };
|
|
2630
5416
|
}
|
|
2631
|
-
let baseCells = (0,
|
|
5417
|
+
let baseCells = (0, import_vue15.computed)(() => {
|
|
2632
5418
|
let { width, height, layout, runs, sourceLength, min, max } = lineLayout.value, cells = [];
|
|
2633
5419
|
if (layout.plotW > 0 && layout.plotH > 0 && runs.length > 0) {
|
|
2634
5420
|
let occupiedLineCells = /* @__PURE__ */ new Set();
|
|
@@ -2677,7 +5463,7 @@ var TContributionGraph = (0, import_vue10.defineComponent)({
|
|
|
2677
5463
|
props.startLabel || (sourceLength > 0 ? "1" : ""),
|
|
2678
5464
|
props.endLabel || (sourceLength > 0 ? String(sourceLength) : "")
|
|
2679
5465
|
), cells;
|
|
2680
|
-
}), surface = (0,
|
|
5466
|
+
}), surface = (0, import_vue15.computed)(() => {
|
|
2681
5467
|
let { width, height, layout } = lineLayout.value, cells = baseCells.value.slice(), pointer = hoverPointer.value, hovered = pointer ? hitLine(pointer.x, pointer.y) : null;
|
|
2682
5468
|
hovered && cells.push({
|
|
2683
5469
|
x: hovered.x,
|
|
@@ -2723,7 +5509,7 @@ var TContributionGraph = (0, import_vue10.defineComponent)({
|
|
|
2723
5509
|
})
|
|
2724
5510
|
});
|
|
2725
5511
|
}
|
|
2726
|
-
}), TCandlestickChart = (0,
|
|
5512
|
+
}), TCandlestickChart = (0, import_vue15.defineComponent)({
|
|
2727
5513
|
name: "TCandlestickChart",
|
|
2728
5514
|
props: {
|
|
2729
5515
|
/** Left position in terminal cells. */
|
|
@@ -2772,7 +5558,7 @@ var TContributionGraph = (0, import_vue10.defineComponent)({
|
|
|
2772
5558
|
tooltipStyle: { type: Object, default: () => ({ fg: "whiteBright" }) }
|
|
2773
5559
|
},
|
|
2774
5560
|
setup(props) {
|
|
2775
|
-
let { defaultStyle } = useTerminal(), baseStyle = (0,
|
|
5561
|
+
let { defaultStyle } = useTerminal(), baseStyle = (0, import_vue15.computed)(() => mergeStyle(defaultStyle.value, props.style)), axisStyle = (0, import_vue15.computed)(() => mergeStyle(baseStyle.value, props.axisStyle)), labelStyle = (0, import_vue15.computed)(() => mergeStyle(baseStyle.value, props.labelStyle)), hoverPointer = (0, import_vue15.ref)(null), candleLayout = (0, import_vue15.computed)(() => {
|
|
2776
5562
|
let width = cellCount(props.w, 0), height = cellCount(props.h, 0), min = 0, max = 0, layout = resolveAxisLayout(width, height, min, max, props.showAxes), startIndex = props.candles.length, visibleCandles = [];
|
|
2777
5563
|
for (let capacity = Math.min(props.candles.length, width); capacity >= 0 && (startIndex = Math.max(0, props.candles.length - capacity), visibleCandles = props.candles.slice(startIndex), { min, max } = domainFromValues(
|
|
2778
5564
|
candlestickDomainValues(visibleCandles),
|
|
@@ -2806,7 +5592,7 @@ var TContributionGraph = (0, import_vue10.defineComponent)({
|
|
|
2806
5592
|
close
|
|
2807
5593
|
};
|
|
2808
5594
|
}
|
|
2809
|
-
let surface = (0,
|
|
5595
|
+
let surface = (0, import_vue15.computed)(() => {
|
|
2810
5596
|
let current = candleLayout.value, { width, height, layout, visibleCandles, candleOffsetX, min, max } = current, cells = [], upStyle = mergeStyle(baseStyle.value, props.upStyle), downStyle = mergeStyle(baseStyle.value, props.downStyle), upWickStyle = mergeStyle(baseStyle.value, props.upStyle, props.wickStyle), downWickStyle = mergeStyle(baseStyle.value, props.downStyle, props.wickStyle), pointer = hoverPointer.value, hovered = pointer ? hitCandle(pointer.x, pointer.y) : null;
|
|
2811
5597
|
for (let x = 0; x < visibleCandles.length; x++) {
|
|
2812
5598
|
let candle = visibleCandles[x], values = normalizeCandlestick(candle);
|
|
@@ -2872,7 +5658,7 @@ var TContributionGraph = (0, import_vue10.defineComponent)({
|
|
|
2872
5658
|
})
|
|
2873
5659
|
});
|
|
2874
5660
|
}
|
|
2875
|
-
}), TPieChart = (0,
|
|
5661
|
+
}), TPieChart = (0, import_vue15.defineComponent)({
|
|
2876
5662
|
name: "TPieChart",
|
|
2877
5663
|
props: {
|
|
2878
5664
|
/** Left position in terminal cells. */
|
|
@@ -2902,7 +5688,7 @@ var TContributionGraph = (0, import_vue10.defineComponent)({
|
|
|
2902
5688
|
legendStyle: { type: Object, default: () => ({ fg: "whiteBright" }) }
|
|
2903
5689
|
},
|
|
2904
5690
|
setup(props) {
|
|
2905
|
-
let { defaultStyle } = useTerminal(), baseStyle = (0,
|
|
5691
|
+
let { defaultStyle } = useTerminal(), baseStyle = (0, import_vue15.computed)(() => mergeStyle(defaultStyle.value, props.style)), legendStyle = (0, import_vue15.computed)(() => mergeStyle(baseStyle.value, props.legendStyle)), surface = (0, import_vue15.computed)(() => {
|
|
2906
5692
|
let width = cellCount(props.w, 0), height = cellCount(props.h, 0), values = props.values.map((value) => {
|
|
2907
5693
|
let n = Number(value);
|
|
2908
5694
|
return Number.isFinite(n) ? Math.max(0, n) : 0;
|
|
@@ -2971,7 +5757,7 @@ var TContributionGraph = (0, import_vue10.defineComponent)({
|
|
|
2971
5757
|
});
|
|
2972
5758
|
|
|
2973
5759
|
// src/vue/components/TTranscriptView.ts
|
|
2974
|
-
var
|
|
5760
|
+
var import_vue17 = require("vue");
|
|
2975
5761
|
|
|
2976
5762
|
// src/observability/frame-perf.ts
|
|
2977
5763
|
var EMPTY_METRIC_STATS = Object.freeze({ avg: 0, max: 0, min: 0 });
|
|
@@ -3118,147 +5904,39 @@ function layoutTranscriptRow(options) {
|
|
|
3118
5904
|
rowIndex: options.rowIndex,
|
|
3119
5905
|
payload: { row: options.row, rowKey: options.rowKey },
|
|
3120
5906
|
hoverStyle: options.hoverStyle,
|
|
3121
|
-
focusStyle: options.focusStyle
|
|
3122
|
-
};
|
|
3123
|
-
for (let i = 0; i < segments.length; i++)
|
|
3124
|
-
appendTextSegment(segments[i], i, i === 0 ? foldRegion : toolRegion);
|
|
3125
|
-
} else
|
|
3126
|
-
for (let i = 0; i < segments.length; i++)
|
|
3127
|
-
appendTextSegment(segments[i], i);
|
|
3128
|
-
if ("actions" in options.row)
|
|
3129
|
-
for (let action of options.row.actions ?? [])
|
|
3130
|
-
appendAction(action);
|
|
3131
|
-
return pushCurrentIfNeeded(), visualRows.length ? visualRows : [createVisualRow(0, 0)];
|
|
3132
|
-
}
|
|
3133
|
-
|
|
3134
|
-
// src/vue/transcript/plain-text.ts
|
|
3135
|
-
function plainTextForTranscriptRow(row) {
|
|
3136
|
-
if (row.selectableText != null)
|
|
3137
|
-
return row.selectableText;
|
|
3138
|
-
if (row.kind === "message")
|
|
3139
|
-
return row.segments.map((segment) => segment.text).join("");
|
|
3140
|
-
if (row.kind === "action")
|
|
3141
|
-
return row.label;
|
|
3142
|
-
if (row.kind === "approval") {
|
|
3143
|
-
let description = row.description?.map((segment) => segment.text).join("") ?? "";
|
|
3144
|
-
return description ? `${row.title}
|
|
3145
|
-
${description}` : row.title;
|
|
3146
|
-
}
|
|
3147
|
-
let summary = row.summary?.map((segment) => segment.text).join("") ?? "", body = row.collapsed ? "" : row.body?.map((segment) => segment.text).join("") ?? "";
|
|
3148
|
-
return [row.title, summary, body].filter(Boolean).join(`
|
|
3149
|
-
`);
|
|
3150
|
-
}
|
|
3151
|
-
|
|
3152
|
-
// src/vue/components/TView.ts
|
|
3153
|
-
var import_vue11 = require("vue");
|
|
3154
|
-
var EMPTY_RECT = Object.freeze({ x: 0, y: 0, w: 0, h: 0 }), TView = (0, import_vue11.defineComponent)({
|
|
3155
|
-
name: "TView",
|
|
3156
|
-
props: {
|
|
3157
|
-
x: { type: Number, required: !0 },
|
|
3158
|
-
y: { type: Number, required: !0 },
|
|
3159
|
-
w: { type: Number, required: !0 },
|
|
3160
|
-
h: { type: Number, required: !0 },
|
|
3161
|
-
zIndex: { type: Number, default: 0 },
|
|
3162
|
-
scrollX: { type: Number, default: 0 },
|
|
3163
|
-
scrollY: { type: Number, default: 0 },
|
|
3164
|
-
focusable: { type: Boolean, default: !1 },
|
|
3165
|
-
selectable: { type: Boolean, default: void 0 },
|
|
3166
|
-
selectionScrollBy: {
|
|
3167
|
-
type: Function,
|
|
3168
|
-
default: void 0
|
|
3169
|
-
},
|
|
3170
|
-
autoFocus: { type: Boolean, default: !1 }
|
|
3171
|
-
},
|
|
3172
|
-
emits: [
|
|
3173
|
-
"clickCapture",
|
|
3174
|
-
"click",
|
|
3175
|
-
"dblclickCapture",
|
|
3176
|
-
"dblclick",
|
|
3177
|
-
"pointerdownCapture",
|
|
3178
|
-
"pointerdown",
|
|
3179
|
-
"pointerupCapture",
|
|
3180
|
-
"pointerup",
|
|
3181
|
-
"pointermoveCapture",
|
|
3182
|
-
"pointermove",
|
|
3183
|
-
"pointerenterCapture",
|
|
3184
|
-
"pointerenter",
|
|
3185
|
-
"pointerleaveCapture",
|
|
3186
|
-
"pointerleave",
|
|
3187
|
-
"wheelCapture",
|
|
3188
|
-
"wheel",
|
|
3189
|
-
"keydownCapture",
|
|
3190
|
-
"keydown",
|
|
3191
|
-
"keyupCapture",
|
|
3192
|
-
"keyup",
|
|
3193
|
-
"focusCapture",
|
|
3194
|
-
"focus",
|
|
3195
|
-
"blurCapture",
|
|
3196
|
-
"blur"
|
|
3197
|
-
],
|
|
3198
|
-
setup(props, { emit, slots }) {
|
|
3199
|
-
let parent = useLayout(), { render, events } = useTerminal(), parentStack = useRenderStack(), { visible, rootProps } = useVisibility({ provide: !0 }), parentEventZ = (0, import_vue11.inject)(EventZIndexContextKey, (0, import_vue11.computed)(() => 0)), eventZ = (0, import_vue11.computed)(() => (parentEventZ.value ?? 0) + (props.zIndex ?? 0)), rawRect = (0, import_vue11.computed)(
|
|
3200
|
-
() => translateRect(
|
|
3201
|
-
{ x: props.x, y: props.y, w: props.w, h: props.h },
|
|
3202
|
-
parent.originX,
|
|
3203
|
-
parent.originY
|
|
3204
|
-
)
|
|
3205
|
-
), rect = (0, import_vue11.computed)(() => {
|
|
3206
|
-
let translated = rawRect.value;
|
|
3207
|
-
return parent.clipRect ? intersectRect(translated, parent.clipRect) ?? EMPTY_RECT : translated;
|
|
3208
|
-
}), { id } = useTerminalNode(() => ({
|
|
3209
|
-
rect: rect.value,
|
|
3210
|
-
zIndex: eventZ.value,
|
|
3211
|
-
visible: visible.value,
|
|
3212
|
-
focusable: props.focusable,
|
|
3213
|
-
selectable: props.selectable,
|
|
3214
|
-
selectionScrollBy: props.selectionScrollBy,
|
|
3215
|
-
handlers: {
|
|
3216
|
-
clickCapture: (e) => emit("clickCapture", e),
|
|
3217
|
-
click: (e) => emit("click", e),
|
|
3218
|
-
dblclickCapture: (e) => emit("dblclickCapture", e),
|
|
3219
|
-
dblclick: (e) => emit("dblclick", e),
|
|
3220
|
-
pointerdownCapture: (e) => emit("pointerdownCapture", e),
|
|
3221
|
-
pointerdown: (e) => emit("pointerdown", e),
|
|
3222
|
-
pointerupCapture: (e) => emit("pointerupCapture", e),
|
|
3223
|
-
pointerup: (e) => emit("pointerup", e),
|
|
3224
|
-
pointermoveCapture: (e) => emit("pointermoveCapture", e),
|
|
3225
|
-
pointermove: (e) => emit("pointermove", e),
|
|
3226
|
-
pointerenterCapture: (e) => emit("pointerenterCapture", e),
|
|
3227
|
-
pointerenter: (e) => emit("pointerenter", e),
|
|
3228
|
-
pointerleaveCapture: (e) => emit("pointerleaveCapture", e),
|
|
3229
|
-
pointerleave: (e) => emit("pointerleave", e),
|
|
3230
|
-
wheelCapture: (e) => emit("wheelCapture", e),
|
|
3231
|
-
wheel: (e) => emit("wheel", e),
|
|
3232
|
-
keydownCapture: (e) => emit("keydownCapture", e),
|
|
3233
|
-
keydown: (e) => emit("keydown", e),
|
|
3234
|
-
keyupCapture: (e) => emit("keyupCapture", e),
|
|
3235
|
-
keyup: (e) => emit("keyup", e),
|
|
3236
|
-
focusCapture: (e) => emit("focusCapture", e),
|
|
3237
|
-
focus: (e) => emit("focus", e),
|
|
3238
|
-
blurCapture: (e) => emit("blurCapture", e),
|
|
3239
|
-
blur: (e) => emit("blur", e)
|
|
3240
|
-
}
|
|
3241
|
-
}));
|
|
3242
|
-
(0, import_vue11.watchEffect)(() => {
|
|
3243
|
-
if (!props.autoFocus || !visible.value)
|
|
3244
|
-
return;
|
|
3245
|
-
let manager = events.value, nodeId = id.value;
|
|
3246
|
-
!manager || !nodeId || manager.getFocused() !== nodeId && manager.focus(nodeId);
|
|
3247
|
-
});
|
|
3248
|
-
let childLayout = (0, import_vue11.shallowReactive)({
|
|
3249
|
-
originX: 0,
|
|
3250
|
-
originY: 0,
|
|
3251
|
-
clipRect: null
|
|
3252
|
-
}), childStack = (0, import_vue11.computed)(() => render.createStack(parentStack.value, props.zIndex));
|
|
3253
|
-
return (0, import_vue11.watchEffect)(() => {
|
|
3254
|
-
let translated = rawRect.value;
|
|
3255
|
-
childLayout.originX = translated.x - Math.floor(props.scrollX), childLayout.originY = translated.y - Math.floor(props.scrollY), childLayout.clipRect = rect.value;
|
|
3256
|
-
}), (0, import_vue11.provide)(LayoutContextKey, childLayout), (0, import_vue11.provide)(RenderStackKey, childStack), (0, import_vue11.provide)(EventZIndexContextKey, eventZ), () => (0, import_vue11.h)("div", rootProps, slots.default?.());
|
|
5907
|
+
focusStyle: options.focusStyle
|
|
5908
|
+
};
|
|
5909
|
+
for (let i = 0; i < segments.length; i++)
|
|
5910
|
+
appendTextSegment(segments[i], i, i === 0 ? foldRegion : toolRegion);
|
|
5911
|
+
} else
|
|
5912
|
+
for (let i = 0; i < segments.length; i++)
|
|
5913
|
+
appendTextSegment(segments[i], i);
|
|
5914
|
+
if ("actions" in options.row)
|
|
5915
|
+
for (let action of options.row.actions ?? [])
|
|
5916
|
+
appendAction(action);
|
|
5917
|
+
return pushCurrentIfNeeded(), visualRows.length ? visualRows : [createVisualRow(0, 0)];
|
|
5918
|
+
}
|
|
5919
|
+
|
|
5920
|
+
// src/vue/transcript/plain-text.ts
|
|
5921
|
+
function plainTextForTranscriptRow(row) {
|
|
5922
|
+
if (row.selectableText != null)
|
|
5923
|
+
return row.selectableText;
|
|
5924
|
+
if (row.kind === "message")
|
|
5925
|
+
return row.segments.map((segment) => segment.text).join("");
|
|
5926
|
+
if (row.kind === "action")
|
|
5927
|
+
return row.label;
|
|
5928
|
+
if (row.kind === "approval") {
|
|
5929
|
+
let description = row.description?.map((segment) => segment.text).join("") ?? "";
|
|
5930
|
+
return description ? `${row.title}
|
|
5931
|
+
${description}` : row.title;
|
|
3257
5932
|
}
|
|
3258
|
-
|
|
5933
|
+
let summary = row.summary?.map((segment) => segment.text).join("") ?? "", body = row.collapsed ? "" : row.body?.map((segment) => segment.text).join("") ?? "";
|
|
5934
|
+
return [row.title, summary, body].filter(Boolean).join(`
|
|
5935
|
+
`);
|
|
5936
|
+
}
|
|
3259
5937
|
|
|
3260
5938
|
// src/vue/components/TVirtualRows.ts
|
|
3261
|
-
var
|
|
5939
|
+
var import_vue16 = require("vue");
|
|
3262
5940
|
function clamp3(n, min, max) {
|
|
3263
5941
|
return Math.max(min, Math.min(max, n));
|
|
3264
5942
|
}
|
|
@@ -3276,7 +5954,7 @@ function getWheelScrollInput2(e) {
|
|
|
3276
5954
|
let deltaY = Number(e.deltaY ?? 0), deltaMode = typeof e.deltaMode == "number" ? e.deltaMode : void 0;
|
|
3277
5955
|
return Number.isInteger(deltaY) && deltaY !== 0 && Math.abs(deltaY) >= 100 && Math.abs(deltaY) % 100 === 0 && deltaMode == null ? { deltaY: deltaY / 100, mode: "line" } : deltaMode === 1 ? { deltaY, mode: "line" } : deltaMode === 0 ? { deltaY, mode: "pixel" } : { deltaY, mode: "auto" };
|
|
3278
5956
|
}
|
|
3279
|
-
var virtualRowsInstanceSeq = 0, EMPTY_RECT2 = Object.freeze({ x: 0, y: 0, w: 0, h: 0 }), TVirtualRows = (0,
|
|
5957
|
+
var virtualRowsInstanceSeq = 0, EMPTY_RECT2 = Object.freeze({ x: 0, y: 0, w: 0, h: 0 }), TVirtualRows = (0, import_vue16.defineComponent)({
|
|
3280
5958
|
name: "TVirtualRows",
|
|
3281
5959
|
props: {
|
|
3282
5960
|
x: { type: Number, required: !0 },
|
|
@@ -3340,27 +6018,27 @@ var virtualRowsInstanceSeq = 0, EMPTY_RECT2 = Object.freeze({ x: 0, y: 0, w: 0,
|
|
|
3340
6018
|
"itemClick"
|
|
3341
6019
|
],
|
|
3342
6020
|
setup(props, { emit, expose }) {
|
|
3343
|
-
let { terminal, scheduler, render, rendererCapabilities, defaultStyle, events, selection } = useTerminal(), instance = (0,
|
|
6021
|
+
let { terminal, scheduler, render, rendererCapabilities, defaultStyle, events, selection } = useTerminal(), instance = (0, import_vue16.getCurrentInstance)(), layout = useLayout(), { visible, rootProps } = useVisibility(), plane = (0, import_vue16.inject)(RenderPlaneContextKey, (0, import_vue16.ref)("default")), parentEventZ = (0, import_vue16.inject)(EventZIndexContextKey, (0, import_vue16.computed)(() => 0)), eventZ = (0, import_vue16.computed)(() => (parentEventZ.value ?? 0) + (props.zIndex ?? 0)), parentStack = useRenderStack(), childLayout = (0, import_vue16.shallowReactive)({
|
|
3344
6022
|
originX: 0,
|
|
3345
6023
|
originY: 0,
|
|
3346
6024
|
clipRect: null
|
|
3347
|
-
}), childStack = (0,
|
|
3348
|
-
(0,
|
|
3349
|
-
let virtualRowsInstanceId = ++virtualRowsInstanceSeq, parentTerminalGraphicsActivity = (0,
|
|
6025
|
+
}), childStack = (0, import_vue16.computed)(() => render.createStack(parentStack.value, props.zIndex));
|
|
6026
|
+
(0, import_vue16.provide)(LayoutContextKey, childLayout), (0, import_vue16.provide)(RenderStackKey, childStack), (0, import_vue16.provide)(EventZIndexContextKey, eventZ);
|
|
6027
|
+
let virtualRowsInstanceId = ++virtualRowsInstanceSeq, parentTerminalGraphicsActivity = (0, import_vue16.inject)(TerminalGraphicsActivityKey, null), terminalGraphicsActivity = createTerminalGraphicsActivity({
|
|
3350
6028
|
scrollIdleMs: props.terminalGraphicScrollIdleMs,
|
|
3351
6029
|
traceId: `TVirtualRows:${virtualRowsInstanceId}:terminal-graphics`
|
|
3352
6030
|
});
|
|
3353
|
-
(0,
|
|
6031
|
+
(0, import_vue16.provide)(
|
|
3354
6032
|
TerminalGraphicsActivityKey,
|
|
3355
6033
|
createCombinedTerminalGraphicsActivity(
|
|
3356
6034
|
parentTerminalGraphicsActivity,
|
|
3357
6035
|
terminalGraphicsActivity
|
|
3358
6036
|
)
|
|
3359
|
-
), (0,
|
|
6037
|
+
), (0, import_vue16.watch)(
|
|
3360
6038
|
() => props.terminalGraphicScrollIdleMs,
|
|
3361
6039
|
(value) => terminalGraphicsActivity.setScrollIdleMs(value)
|
|
3362
6040
|
);
|
|
3363
|
-
let frameTaskId = `TVirtualRows:${virtualRowsInstanceId}`, innerScrollTop = (0,
|
|
6041
|
+
let frameTaskId = `TVirtualRows:${virtualRowsInstanceId}`, innerScrollTop = (0, import_vue16.ref)(0), controlledScrollTop = (0, import_vue16.ref)(0), focused = (0, import_vue16.ref)(!1), wheelState = createWheelScrollState(), initializedScrollTop = !1, dirtyRowsHint, renderNodeId = null, pendingWheelTop = null, pendingSelectionScrollFocusRemap = !1, alive = !0, itemCount = (0, import_vue16.computed)(() => Math.max(0, normalizeInt(props.itemCount))), fullRect = (0, import_vue16.computed)(
|
|
3364
6042
|
() => translateRect(
|
|
3365
6043
|
{
|
|
3366
6044
|
x: normalizeInt(props.x),
|
|
@@ -3371,7 +6049,7 @@ var virtualRowsInstanceSeq = 0, EMPTY_RECT2 = Object.freeze({ x: 0, y: 0, w: 0,
|
|
|
3371
6049
|
layout.originX,
|
|
3372
6050
|
layout.originY
|
|
3373
6051
|
)
|
|
3374
|
-
), absRect = (0,
|
|
6052
|
+
), absRect = (0, import_vue16.computed)(() => {
|
|
3375
6053
|
let translated = fullRect.value;
|
|
3376
6054
|
return layout.clipRect ? intersectRect(translated, layout.clipRect) ?? EMPTY_RECT2 : translated;
|
|
3377
6055
|
});
|
|
@@ -3437,10 +6115,10 @@ var virtualRowsInstanceSeq = 0, EMPTY_RECT2 = Object.freeze({ x: 0, y: 0, w: 0,
|
|
|
3437
6115
|
rows.push(y);
|
|
3438
6116
|
return rows;
|
|
3439
6117
|
}
|
|
3440
|
-
function exposedRowsForDelta2(y0,
|
|
6118
|
+
function exposedRowsForDelta2(y0, h19, delta) {
|
|
3441
6119
|
let rows = [];
|
|
3442
6120
|
if (delta > 0)
|
|
3443
|
-
for (let i =
|
|
6121
|
+
for (let i = h19 - delta; i < h19; i++)
|
|
3444
6122
|
rows.push(y0 + i);
|
|
3445
6123
|
else
|
|
3446
6124
|
for (let i = 0; i < -delta; i++)
|
|
@@ -3465,11 +6143,11 @@ var virtualRowsInstanceSeq = 0, EMPTY_RECT2 = Object.freeze({ x: 0, y: 0, w: 0,
|
|
|
3465
6143
|
scheduler.invalidate({ priority, plane: plane.value, reason: "scroll" });
|
|
3466
6144
|
}
|
|
3467
6145
|
function markScrollDamage(prevTop, nextTop, strategy = "auto") {
|
|
3468
|
-
let r = normalizedRect(),
|
|
3469
|
-
if (
|
|
6146
|
+
let r = normalizedRect(), h19 = r.h, delta = nextTop - prevTop;
|
|
6147
|
+
if (h19 <= 0 || !delta)
|
|
3470
6148
|
return;
|
|
3471
|
-
let size = terminal.size(), ownsFullRows = Math.floor(r.x) === 0 && Math.floor(r.w) >= size.cols, withinTerminalRows = r.y >= 0 && r.y +
|
|
3472
|
-
strategy === "auto" && props.rowScrollMode === "unsafe-full-row" && rendererCapabilities.value.scrollOperations && ownsFullRows && withinTerminalRows && !isClipped() && Math.abs(delta) <
|
|
6149
|
+
let size = terminal.size(), ownsFullRows = Math.floor(r.x) === 0 && Math.floor(r.w) >= size.cols, withinTerminalRows = r.y >= 0 && r.y + h19 <= size.rows;
|
|
6150
|
+
strategy === "auto" && props.rowScrollMode === "unsafe-full-row" && rendererCapabilities.value.scrollOperations && ownsFullRows && withinTerminalRows && !isClipped() && Math.abs(delta) < h19 && !dirtyRowsHint?.length ? (render.unsafeScrollPlaneRows(plane.value, r.y, r.y + h19, delta), markRowsDirty(exposedRowsForDelta2(r.y, h19, delta))) : markViewportDirty();
|
|
3473
6151
|
}
|
|
3474
6152
|
function applyScrollTop(nextTop, options) {
|
|
3475
6153
|
if (normalizedRect().h <= 0)
|
|
@@ -3614,7 +6292,7 @@ var virtualRowsInstanceSeq = 0, EMPTY_RECT2 = Object.freeze({ x: 0, y: 0, w: 0,
|
|
|
3614
6292
|
getText: textForSelectionRange,
|
|
3615
6293
|
getVisibleSpans: visibleSpansForSelectionRange
|
|
3616
6294
|
}, unregisterSelectionTextProvider = selection.registerTextProvider(selectionTextProvider);
|
|
3617
|
-
(0,
|
|
6295
|
+
(0, import_vue16.onBeforeUnmount)(unregisterSelectionTextProvider);
|
|
3618
6296
|
let eventNode = useTerminalNode(() => ({
|
|
3619
6297
|
rect: normalizedRect(),
|
|
3620
6298
|
zIndex: eventZ.value,
|
|
@@ -3666,15 +6344,15 @@ var virtualRowsInstanceSeq = 0, EMPTY_RECT2 = Object.freeze({ x: 0, y: 0, w: 0,
|
|
|
3666
6344
|
}
|
|
3667
6345
|
}
|
|
3668
6346
|
}));
|
|
3669
|
-
(0,
|
|
6347
|
+
(0, import_vue16.watchEffect)(() => {
|
|
3670
6348
|
if (!props.autoFocus || !visible.value)
|
|
3671
6349
|
return;
|
|
3672
6350
|
let manager = events.value, nodeId = eventNode.id.value;
|
|
3673
6351
|
!manager || !nodeId || manager.getFocused() !== nodeId && manager.focus(nodeId);
|
|
3674
|
-
}), (0,
|
|
6352
|
+
}), (0, import_vue16.watchEffect)(() => {
|
|
3675
6353
|
let full = normalizedFullRect();
|
|
3676
6354
|
childLayout.originX = full.x, childLayout.originY = full.y, childLayout.clipRect = normalizedRect();
|
|
3677
|
-
}), (0,
|
|
6355
|
+
}), (0, import_vue16.watch)(
|
|
3678
6356
|
() => props.scrollTop,
|
|
3679
6357
|
() => {
|
|
3680
6358
|
if (!isScrollControlled())
|
|
@@ -3693,7 +6371,7 @@ var virtualRowsInstanceSeq = 0, EMPTY_RECT2 = Object.freeze({ x: 0, y: 0, w: 0,
|
|
|
3693
6371
|
controlledScrollTop.value = nextTop, terminalGraphicsActivity.markScroll(), markScrollDamage(prevTop, nextTop), selection.refresh(pendingSelectionScrollFocusRemap ? { remapFocus: !0 } : void 0), pendingSelectionScrollFocusRemap = !1, invalidateSelf("high"), desiredTop !== nextTop && (emit("update:scrollTop", nextTop), emitScroll(nextTop));
|
|
3694
6372
|
},
|
|
3695
6373
|
{ immediate: !0 }
|
|
3696
|
-
), (0,
|
|
6374
|
+
), (0, import_vue16.watch)(
|
|
3697
6375
|
[
|
|
3698
6376
|
() => itemCount.value,
|
|
3699
6377
|
() => props.itemVersion,
|
|
@@ -3719,12 +6397,12 @@ var virtualRowsInstanceSeq = 0, EMPTY_RECT2 = Object.freeze({ x: 0, y: 0, w: 0,
|
|
|
3719
6397
|
markViewportDirty(), invalidateSelf("normal");
|
|
3720
6398
|
},
|
|
3721
6399
|
{ immediate: !0 }
|
|
3722
|
-
), (0,
|
|
6400
|
+
), (0, import_vue16.watch)(
|
|
3723
6401
|
() => visible.value,
|
|
3724
6402
|
(nextVisible) => {
|
|
3725
6403
|
nextVisible || cancelWheelScrollFrame();
|
|
3726
6404
|
}
|
|
3727
|
-
), (0,
|
|
6405
|
+
), (0, import_vue16.onBeforeUnmount)(() => {
|
|
3728
6406
|
alive = !1, pendingWheelTop = null, resetWheelScrollState(wheelState), wheelMailbox.dispose(), terminalGraphicsActivity.dispose();
|
|
3729
6407
|
});
|
|
3730
6408
|
let renderNode = useRenderNode(() => ({
|
|
@@ -3777,7 +6455,7 @@ var virtualRowsInstanceSeq = 0, EMPTY_RECT2 = Object.freeze({ x: 0, y: 0, w: 0,
|
|
|
3777
6455
|
paintRow(y);
|
|
3778
6456
|
}
|
|
3779
6457
|
}));
|
|
3780
|
-
return (0,
|
|
6458
|
+
return (0, import_vue16.watchEffect)(() => {
|
|
3781
6459
|
renderNodeId = renderNode.id.value;
|
|
3782
6460
|
}), () => {
|
|
3783
6461
|
let children = [];
|
|
@@ -3798,7 +6476,7 @@ var virtualRowsInstanceSeq = 0, EMPTY_RECT2 = Object.freeze({ x: 0, y: 0, w: 0,
|
|
|
3798
6476
|
);
|
|
3799
6477
|
}
|
|
3800
6478
|
}
|
|
3801
|
-
return (0,
|
|
6479
|
+
return (0, import_vue16.h)("div", rootProps, children);
|
|
3802
6480
|
};
|
|
3803
6481
|
}
|
|
3804
6482
|
});
|
|
@@ -3874,7 +6552,7 @@ function reindexVisualRows(rows, rowIndex) {
|
|
|
3874
6552
|
function sameCachedLayout(entry, next, matchRowIndex = !0) {
|
|
3875
6553
|
return !!entry && (next.usesSourceRowVersion || entry.version === next.version) && entry.rowVersion === next.rowVersion && entry.usesSourceRowVersion === next.usesSourceRowVersion && (next.usesSourceRowVersion || entry.row === next.row) && (!matchRowIndex || entry.rowIndex === next.rowIndex) && entry.rowKey === next.rowKey && entry.width === next.width && entry.wrap === next.wrap && entry.baseStyle === next.baseStyle && entry.hoverStyle === next.hoverStyle && entry.focusStyle === next.focusStyle && entry.hoverRegionId === next.hoverRegionId && entry.focusedRegionId === next.focusedRegionId;
|
|
3876
6554
|
}
|
|
3877
|
-
var TTranscriptView = (0,
|
|
6555
|
+
var TTranscriptView = (0, import_vue17.defineComponent)({
|
|
3878
6556
|
name: "TTranscriptView",
|
|
3879
6557
|
props: {
|
|
3880
6558
|
x: { type: Number, required: !0 },
|
|
@@ -3915,7 +6593,7 @@ var TTranscriptView = (0, import_vue13.defineComponent)({
|
|
|
3915
6593
|
"hoverRegion"
|
|
3916
6594
|
],
|
|
3917
6595
|
setup(props, { emit, expose }) {
|
|
3918
|
-
let { defaultStyle, observability } = useTerminal(), instance = (0,
|
|
6596
|
+
let { defaultStyle, observability } = useTerminal(), instance = (0, import_vue17.getCurrentInstance)(), rowsRef = (0, import_vue17.ref)(null), innerScrollTop = (0, import_vue17.ref)(normalizeInt2(props.defaultScrollTop)), hoveredRegion = (0, import_vue17.ref)(null), focusedRegion = (0, import_vue17.ref)(null), rowLayoutCache = /* @__PURE__ */ new Map(), keyedRowLayoutCache = /* @__PURE__ */ new Map(), previousWrappedLayout = null, previousWrappedDeps = null, canUseWrappedChangedRangeRepaint = !1, warnedLargeFlattenedRows = !1;
|
|
3919
6597
|
function isScrollControlled() {
|
|
3920
6598
|
return Object.prototype.hasOwnProperty.call(instance?.vnode.props ?? {}, "scrollTop");
|
|
3921
6599
|
}
|
|
@@ -4023,7 +6701,7 @@ var TTranscriptView = (0, import_vue13.defineComponent)({
|
|
|
4023
6701
|
};
|
|
4024
6702
|
return previousWrappedLayout = state, { state, cacheHit, cacheMiss };
|
|
4025
6703
|
}
|
|
4026
|
-
let layoutState = (0,
|
|
6704
|
+
let layoutState = (0, import_vue17.computed)(() => {
|
|
4027
6705
|
props.version, canUseWrappedChangedRangeRepaint = !1;
|
|
4028
6706
|
let perfEnabled = observability.framePerf.enabled.value, perfStartedAt = perfEnabled ? framePerfNow() : 0, width = Math.max(1, Math.floor(props.w)), count = Math.max(0, normalizeInt2(props.source.rowCount()));
|
|
4029
6707
|
if (!count)
|
|
@@ -4113,7 +6791,7 @@ var TTranscriptView = (0, import_vue13.defineComponent)({
|
|
|
4113
6791
|
});
|
|
4114
6792
|
let state = { visualRows, rowStarts, rowEnds, regions, fixedRows, rowCount: count };
|
|
4115
6793
|
return fixedRows ? (previousWrappedLayout = null, previousWrappedDeps = null) : (previousWrappedLayout = state, previousWrappedDeps = wrappedDeps), state;
|
|
4116
|
-
}), maxScrollTop = (0,
|
|
6794
|
+
}), maxScrollTop = (0, import_vue17.computed)(
|
|
4117
6795
|
() => Math.max(0, layoutState.value.visualRows.length - Math.max(0, normalizeInt2(props.h)))
|
|
4118
6796
|
);
|
|
4119
6797
|
function setScrollTop(top) {
|
|
@@ -4255,12 +6933,12 @@ var TTranscriptView = (0, import_vue13.defineComponent)({
|
|
|
4255
6933
|
focusPreviousRegion,
|
|
4256
6934
|
activateFocusedRegion,
|
|
4257
6935
|
getHoveredRegion: () => hoveredRegion.value
|
|
4258
|
-
}), (0,
|
|
6936
|
+
}), (0, import_vue17.watch)(
|
|
4259
6937
|
() => props.defaultScrollTop,
|
|
4260
6938
|
(top) => {
|
|
4261
6939
|
isScrollControlled() || (innerScrollTop.value = clamp4(normalizeInt2(top), 0, maxScrollTop.value));
|
|
4262
6940
|
}
|
|
4263
|
-
), (0,
|
|
6941
|
+
), (0, import_vue17.watch)(
|
|
4264
6942
|
() => layoutState.value.visualRows.length,
|
|
4265
6943
|
(next, prev) => {
|
|
4266
6944
|
if (!props.autoStickToBottom)
|
|
@@ -4271,7 +6949,7 @@ var TTranscriptView = (0, import_vue13.defineComponent)({
|
|
|
4271
6949
|
let nextTop = Math.max(0, next - viewportRows);
|
|
4272
6950
|
rowsRef.value?.scrollTo(nextTop), setScrollTop(nextTop);
|
|
4273
6951
|
}
|
|
4274
|
-
), (0,
|
|
6952
|
+
), (0, import_vue17.watch)(
|
|
4275
6953
|
() => [layoutState.value.regions, currentScrollTop(), props.h],
|
|
4276
6954
|
() => reconcileActiveRegions()
|
|
4277
6955
|
);
|
|
@@ -4299,7 +6977,7 @@ var TTranscriptView = (0, import_vue13.defineComponent)({
|
|
|
4299
6977
|
let nodes = [];
|
|
4300
6978
|
for (let region of visualRow.hitRegions)
|
|
4301
6979
|
nodes.push(
|
|
4302
|
-
(0,
|
|
6980
|
+
(0, import_vue17.h)(TView, {
|
|
4303
6981
|
key: `${region.id}:${ctx.index}:${region.x0}`,
|
|
4304
6982
|
x: region.x0,
|
|
4305
6983
|
y: ctx.row,
|
|
@@ -4354,7 +7032,7 @@ var TTranscriptView = (0, import_vue13.defineComponent)({
|
|
|
4354
7032
|
let visualRow = ctx.item;
|
|
4355
7033
|
return visualRow ? visualRow.selectionSegments.length ? textForSelectionSegments(visualRow.selectionSegments, ctx.x0, ctx.x1) : sliceByCellsRange(selectionTextForVisualRow(visualRow), ctx.x0, ctx.x1) : "";
|
|
4356
7034
|
}
|
|
4357
|
-
return () => (0,
|
|
7035
|
+
return () => (0, import_vue17.h)(TVirtualRows, {
|
|
4358
7036
|
ref: rowsRef,
|
|
4359
7037
|
x: props.x,
|
|
4360
7038
|
y: props.y,
|
|
@@ -4395,187 +7073,6 @@ var TTranscriptView = (0, import_vue13.defineComponent)({
|
|
|
4395
7073
|
}
|
|
4396
7074
|
});
|
|
4397
7075
|
|
|
4398
|
-
// src/core/ansi/sgr.ts
|
|
4399
|
-
var ESC = "\x1B";
|
|
4400
|
-
function ansi16ToColorName(code) {
|
|
4401
|
-
switch (code) {
|
|
4402
|
-
case 30:
|
|
4403
|
-
return "black";
|
|
4404
|
-
case 31:
|
|
4405
|
-
return "red";
|
|
4406
|
-
case 32:
|
|
4407
|
-
return "green";
|
|
4408
|
-
case 33:
|
|
4409
|
-
return "yellow";
|
|
4410
|
-
case 34:
|
|
4411
|
-
return "blue";
|
|
4412
|
-
case 35:
|
|
4413
|
-
return "magenta";
|
|
4414
|
-
case 36:
|
|
4415
|
-
return "cyan";
|
|
4416
|
-
case 37:
|
|
4417
|
-
return "white";
|
|
4418
|
-
case 90:
|
|
4419
|
-
return "blackBright";
|
|
4420
|
-
case 91:
|
|
4421
|
-
return "redBright";
|
|
4422
|
-
case 92:
|
|
4423
|
-
return "greenBright";
|
|
4424
|
-
case 93:
|
|
4425
|
-
return "yellowBright";
|
|
4426
|
-
case 94:
|
|
4427
|
-
return "blueBright";
|
|
4428
|
-
case 95:
|
|
4429
|
-
return "magentaBright";
|
|
4430
|
-
case 96:
|
|
4431
|
-
return "cyanBright";
|
|
4432
|
-
case 97:
|
|
4433
|
-
return "whiteBright";
|
|
4434
|
-
default:
|
|
4435
|
-
return;
|
|
4436
|
-
}
|
|
4437
|
-
}
|
|
4438
|
-
function ansi16BgToColorName(code) {
|
|
4439
|
-
let fgCode = code >= 40 && code <= 47 || code >= 100 && code <= 107 ? code - 10 : null;
|
|
4440
|
-
if (fgCode != null)
|
|
4441
|
-
return ansi16ToColorName(fgCode);
|
|
4442
|
-
}
|
|
4443
|
-
var ANSI16_RGB = {
|
|
4444
|
-
black: { r: 0, g: 0, b: 0 },
|
|
4445
|
-
red: { r: 201, g: 27, b: 0 },
|
|
4446
|
-
green: { r: 0, g: 194, b: 0 },
|
|
4447
|
-
yellow: { r: 199, g: 196, b: 0 },
|
|
4448
|
-
blue: { r: 2, g: 37, b: 199 },
|
|
4449
|
-
magenta: { r: 201, g: 48, b: 199 },
|
|
4450
|
-
cyan: { r: 0, g: 197, b: 199 },
|
|
4451
|
-
white: { r: 199, g: 199, b: 199 },
|
|
4452
|
-
blackBright: { r: 104, g: 104, b: 104 },
|
|
4453
|
-
redBright: { r: 255, g: 110, b: 103 },
|
|
4454
|
-
greenBright: { r: 95, g: 250, b: 104 },
|
|
4455
|
-
yellowBright: { r: 255, g: 252, b: 103 },
|
|
4456
|
-
blueBright: { r: 104, g: 113, b: 255 },
|
|
4457
|
-
magentaBright: { r: 255, g: 118, b: 255 },
|
|
4458
|
-
cyanBright: { r: 95, g: 253, b: 255 },
|
|
4459
|
-
whiteBright: { r: 255, g: 255, b: 255 }
|
|
4460
|
-
};
|
|
4461
|
-
function nearestAnsi16(r, g, b) {
|
|
4462
|
-
let best = "white", bestDist = Number.POSITIVE_INFINITY;
|
|
4463
|
-
for (let [name, rgb] of Object.entries(ANSI16_RGB)) {
|
|
4464
|
-
let dr = r - rgb.r, dg = g - rgb.g, db = b - rgb.b, d = dr * dr + dg * dg + db * db;
|
|
4465
|
-
d < bestDist && (bestDist = d, best = name);
|
|
4466
|
-
}
|
|
4467
|
-
return best;
|
|
4468
|
-
}
|
|
4469
|
-
function ansi256ToRgb(index) {
|
|
4470
|
-
let n = Math.max(0, Math.min(255, Math.trunc(index)));
|
|
4471
|
-
if (n < 16) {
|
|
4472
|
-
let name = [
|
|
4473
|
-
"black",
|
|
4474
|
-
"red",
|
|
4475
|
-
"green",
|
|
4476
|
-
"yellow",
|
|
4477
|
-
"blue",
|
|
4478
|
-
"magenta",
|
|
4479
|
-
"cyan",
|
|
4480
|
-
"white",
|
|
4481
|
-
"blackBright",
|
|
4482
|
-
"redBright",
|
|
4483
|
-
"greenBright",
|
|
4484
|
-
"yellowBright",
|
|
4485
|
-
"blueBright",
|
|
4486
|
-
"magentaBright",
|
|
4487
|
-
"cyanBright",
|
|
4488
|
-
"whiteBright"
|
|
4489
|
-
][n] ?? "white";
|
|
4490
|
-
return ANSI16_RGB[name];
|
|
4491
|
-
}
|
|
4492
|
-
if (n >= 232) {
|
|
4493
|
-
let c = 8 + (n - 232) * 10;
|
|
4494
|
-
return { r: c, g: c, b: c };
|
|
4495
|
-
}
|
|
4496
|
-
let i = n - 16, rr = Math.floor(i / 36), gg = Math.floor(i % 36 / 6), bb = i % 6, toComponent = (v) => v === 0 ? 0 : 55 + v * 40;
|
|
4497
|
-
return { r: toComponent(rr), g: toComponent(gg), b: toComponent(bb) };
|
|
4498
|
-
}
|
|
4499
|
-
function applyAnsiSgrStyle(current, codes) {
|
|
4500
|
-
let next = { ...current };
|
|
4501
|
-
for (let i = 0; i < codes.length; i++) {
|
|
4502
|
-
let code = codes[i];
|
|
4503
|
-
if (code === 0) {
|
|
4504
|
-
next = {};
|
|
4505
|
-
continue;
|
|
4506
|
-
}
|
|
4507
|
-
if (code === 1)
|
|
4508
|
-
next = { ...next, bold: !0 };
|
|
4509
|
-
else if (code === 2)
|
|
4510
|
-
next = { ...next, dim: !0 };
|
|
4511
|
-
else if (code === 3)
|
|
4512
|
-
next = { ...next, italic: !0 };
|
|
4513
|
-
else if (code === 4)
|
|
4514
|
-
next = { ...next, underline: !0 };
|
|
4515
|
-
else if (code === 7)
|
|
4516
|
-
next = { ...next, inverse: !0 };
|
|
4517
|
-
else if (code === 22)
|
|
4518
|
-
next = { ...next, bold: !1, dim: !1 };
|
|
4519
|
-
else if (code === 23)
|
|
4520
|
-
next = { ...next, italic: !1 };
|
|
4521
|
-
else if (code === 24)
|
|
4522
|
-
next = { ...next, underline: !1 };
|
|
4523
|
-
else if (code === 27)
|
|
4524
|
-
next = { ...next, inverse: !1 };
|
|
4525
|
-
else if (code === 39)
|
|
4526
|
-
next = { ...next, fg: void 0 };
|
|
4527
|
-
else if (code === 49)
|
|
4528
|
-
next = { ...next, bg: void 0 };
|
|
4529
|
-
else if (code >= 30 && code <= 37 || code >= 90 && code <= 97) {
|
|
4530
|
-
let fg = ansi16ToColorName(code);
|
|
4531
|
-
next = { ...next, fg: fg ?? next.fg };
|
|
4532
|
-
} else if (code >= 40 && code <= 47 || code >= 100 && code <= 107) {
|
|
4533
|
-
let bg = ansi16BgToColorName(code);
|
|
4534
|
-
next = { ...next, bg: bg ?? next.bg };
|
|
4535
|
-
} else if (code === 38 || code === 48) {
|
|
4536
|
-
let mode = codes[i + 1];
|
|
4537
|
-
if (mode === 5) {
|
|
4538
|
-
let idx = codes[i + 2];
|
|
4539
|
-
if (idx != null) {
|
|
4540
|
-
let { r, g, b } = ansi256ToRgb(idx), name = nearestAnsi16(r, g, b);
|
|
4541
|
-
next = code === 38 ? { ...next, fg: name } : { ...next, bg: name };
|
|
4542
|
-
}
|
|
4543
|
-
i += 2;
|
|
4544
|
-
} else if (mode === 2) {
|
|
4545
|
-
let r = codes[i + 2], g = codes[i + 3], b = codes[i + 4];
|
|
4546
|
-
if (r != null && g != null && b != null) {
|
|
4547
|
-
let name = nearestAnsi16(r, g, b);
|
|
4548
|
-
next = code === 38 ? { ...next, fg: name } : { ...next, bg: name };
|
|
4549
|
-
}
|
|
4550
|
-
i += 4;
|
|
4551
|
-
}
|
|
4552
|
-
}
|
|
4553
|
-
}
|
|
4554
|
-
return next;
|
|
4555
|
-
}
|
|
4556
|
-
function parseAnsiSgr(input, baseStyle = {}) {
|
|
4557
|
-
let segments = [], style = { ...baseStyle }, lastIndex = 0;
|
|
4558
|
-
for (let i = 0; i < input.length; i++) {
|
|
4559
|
-
if (input[i] !== ESC || input[i + 1] !== "[")
|
|
4560
|
-
continue;
|
|
4561
|
-
let j = i + 2;
|
|
4562
|
-
for (; j < input.length; ) {
|
|
4563
|
-
let c = input.charCodeAt(j);
|
|
4564
|
-
if (c >= 48 && c <= 57 || c === 59) {
|
|
4565
|
-
j++;
|
|
4566
|
-
continue;
|
|
4567
|
-
}
|
|
4568
|
-
break;
|
|
4569
|
-
}
|
|
4570
|
-
if (j >= input.length || input[j] !== "m")
|
|
4571
|
-
continue;
|
|
4572
|
-
i > lastIndex && segments.push({ text: input.slice(lastIndex, i), style });
|
|
4573
|
-
let codes = input.slice(i + 2, j).split(";").filter(Boolean).map((n) => Number.parseInt(n, 10)).filter((n) => Number.isFinite(n));
|
|
4574
|
-
style = applyAnsiSgrStyle(style, codes.length ? codes : [0]), lastIndex = j + 1, i = j;
|
|
4575
|
-
}
|
|
4576
|
-
return lastIndex < input.length && segments.push({ text: input.slice(lastIndex), style }), segments;
|
|
4577
|
-
}
|
|
4578
|
-
|
|
4579
7076
|
// src/utils/url-safety.ts
|
|
4580
7077
|
var ENCODED_ASCII_CONTROL_RE = /%(?:0[0-9a-f]|1[0-9a-f]|7f)/i;
|
|
4581
7078
|
function hasControlCodePoint(value) {
|
|
@@ -4660,7 +7157,7 @@ function sanitizeDomHref(value, options = {}) {
|
|
|
4660
7157
|
}
|
|
4661
7158
|
|
|
4662
7159
|
// src/vue/components/TLogView.ts
|
|
4663
|
-
var
|
|
7160
|
+
var import_vue18 = require("vue");
|
|
4664
7161
|
|
|
4665
7162
|
// src/vue/theme.ts
|
|
4666
7163
|
var tuiDefaultTheme = Object.freeze({
|
|
@@ -5142,7 +7639,7 @@ function countAsciiAnsiTextCells(text) {
|
|
|
5142
7639
|
}
|
|
5143
7640
|
return cells;
|
|
5144
7641
|
}
|
|
5145
|
-
var TLogView = (0,
|
|
7642
|
+
var TLogView = (0, import_vue18.defineComponent)({
|
|
5146
7643
|
name: "TLogView",
|
|
5147
7644
|
props: {
|
|
5148
7645
|
x: { type: Number, required: !0 },
|
|
@@ -5251,19 +7748,19 @@ var TLogView = (0, import_vue14.defineComponent)({
|
|
|
5251
7748
|
"keydown"
|
|
5252
7749
|
],
|
|
5253
7750
|
setup(props, { emit, expose }) {
|
|
5254
|
-
let { terminal, scheduler, render, rendererCapabilities, defaultStyle, events, selection } = useTerminal(), layout = useLayout(), { visible, rootProps } = useVisibility(), plane = (0,
|
|
7751
|
+
let { terminal, scheduler, render, rendererCapabilities, defaultStyle, events, selection } = useTerminal(), layout = useLayout(), { visible, rootProps } = useVisibility(), plane = (0, import_vue18.inject)(RenderPlaneContextKey, (0, import_vue18.ref)("default")), parentEventZ = (0, import_vue18.inject)(EventZIndexContextKey, (0, import_vue18.computed)(() => 0)), eventZ = (0, import_vue18.computed)(() => (parentEventZ.value ?? 0) + (props.zIndex ?? 0)), theme = (0, import_vue18.inject)(TuiThemeContextKey, (0, import_vue18.ref)(tuiDefaultTheme)), effectiveAnsiLinkStyle = (0, import_vue18.computed)(() => props.linkStyle ?? DEFAULT_LINK_STYLE), effectiveLinkStyle = (0, import_vue18.computed)(() => ({
|
|
5255
7752
|
...theme.value.components.TLink?.style ?? {},
|
|
5256
7753
|
...props.linkStyle ?? {}
|
|
5257
|
-
})), focused = (0,
|
|
7754
|
+
})), focused = (0, import_vue18.ref)(!1), innerScrollTop = (0, import_vue18.ref)(0), stickToBottom = (0, import_vue18.ref)(!0), frameTaskId = `TLogView:${nextTLogViewTaskId++}`, dirtyRowsHint, renderNodeId = null, alive = !0, pendingWheelTop = null, pendingSelectionScrollFocusRemap = !1, initializedScrollTop = !1, lastLineCount = 0, lastFirstLineIndex = 0, lastPaintedBottom = null, cacheClock = 0, renderLineCache = /* @__PURE__ */ new Map(), wrapLineCache = /* @__PURE__ */ new Map(), ansiLineCache = /* @__PURE__ */ new Map(), ansiTextCache = /* @__PURE__ */ new Map(), ansiWrapCache = /* @__PURE__ */ new Map(), ansiRowCache = /* @__PURE__ */ new Map(), linkifyLineCache = /* @__PURE__ */ new Map(), linkifyWrapCache = /* @__PURE__ */ new Map(), searchLineCache = /* @__PURE__ */ new Map(), visibleLinksByRow = /* @__PURE__ */ new Map(), focusedVisibleLinkIndex = (0, import_vue18.ref)(-1), focusedLinkTarget = null, searchGeneration = 0, searchCursor = 0, searchStatus = "idle", searchError = null, compiledSearch = {
|
|
5258
7755
|
key: '["text","",""]',
|
|
5259
7756
|
query: "",
|
|
5260
7757
|
mode: "text",
|
|
5261
7758
|
error: null,
|
|
5262
7759
|
findLineMatches: () => []
|
|
5263
|
-
}, currentMatchIndex = -1, searchMatches = [], searchMarkersGeneration = 0, searchMarkersCacheGeneration = -1, searchMarkersCache = [], lastSearchMarkersPayloadKey = "", matchesByLine = /* @__PURE__ */ new Map(), wheelState = createWheelScrollState(), visualIndexWidth = 0, visualIndexLineCount = 0, visualIndexCapacity = 0, visualCounts = [], visualKeys = [], visualTree = [0], visualIndexStatus = "exact", visualMeasureGeneration = 0, visualMeasureCursor = 0, measuredLineCount = 0, measuredVisualRows = 0, lastVisualIndexPayloadKey = "", fullRect = (0,
|
|
7760
|
+
}, currentMatchIndex = -1, searchMatches = [], searchMarkersGeneration = 0, searchMarkersCacheGeneration = -1, searchMarkersCache = [], lastSearchMarkersPayloadKey = "", matchesByLine = /* @__PURE__ */ new Map(), wheelState = createWheelScrollState(), visualIndexWidth = 0, visualIndexLineCount = 0, visualIndexCapacity = 0, visualCounts = [], visualKeys = [], visualTree = [0], visualIndexStatus = "exact", visualMeasureGeneration = 0, visualMeasureCursor = 0, measuredLineCount = 0, measuredVisualRows = 0, lastVisualIndexPayloadKey = "", fullRect = (0, import_vue18.computed)(() => {
|
|
5264
7761
|
let raw = { x: props.x, y: props.y, w: props.w, h: props.h };
|
|
5265
7762
|
return translateRect(raw, layout.originX, layout.originY);
|
|
5266
|
-
}), absRect = (0,
|
|
7763
|
+
}), absRect = (0, import_vue18.computed)(() => {
|
|
5267
7764
|
let translated = fullRect.value;
|
|
5268
7765
|
return layout.clipRect ? intersectRect(translated, layout.clipRect) ?? { x: 0, y: 0, w: 0, h: 0 } : translated;
|
|
5269
7766
|
});
|
|
@@ -5327,7 +7824,7 @@ var TLogView = (0, import_vue14.defineComponent)({
|
|
|
5327
7824
|
options.protocols ?? []
|
|
5328
7825
|
]);
|
|
5329
7826
|
}
|
|
5330
|
-
let linkifyOptionsKey = (0,
|
|
7827
|
+
let linkifyOptionsKey = (0, import_vue18.computed)(() => linkifyOptionsCacheKey());
|
|
5331
7828
|
function linkStyleCacheKey() {
|
|
5332
7829
|
return linksEnabled() ? styleCacheKey(effectiveAnsiLinkStyle.value) : "";
|
|
5333
7830
|
}
|
|
@@ -6500,10 +8997,10 @@ var TLogView = (0, import_vue14.defineComponent)({
|
|
|
6500
8997
|
function shiftVisibleLinksForScrollRegion(y0, y1, delta) {
|
|
6501
8998
|
if (!visibleLinksByRow.size || delta === 0)
|
|
6502
8999
|
return;
|
|
6503
|
-
let
|
|
6504
|
-
if (
|
|
9000
|
+
let h19 = y1 - y0;
|
|
9001
|
+
if (h19 <= 0)
|
|
6505
9002
|
return;
|
|
6506
|
-
if (Math.abs(delta) >=
|
|
9003
|
+
if (Math.abs(delta) >= h19) {
|
|
6507
9004
|
for (let y = y0; y < y1; y++)
|
|
6508
9005
|
visibleLinksByRow.delete(y);
|
|
6509
9006
|
return;
|
|
@@ -6597,8 +9094,8 @@ var TLogView = (0, import_vue14.defineComponent)({
|
|
|
6597
9094
|
return props.wrap || delta <= 0 || delta >= r.h || prevCount <= 0 || nextCount <= prevCount || lastPaintedBottom?.index !== prevCount - 1 || lineKey(prevCount - 1) === lastPaintedBottom.lineKey ? null : r.y + r.h - delta - 1;
|
|
6598
9095
|
}
|
|
6599
9096
|
function applyScrollTop(nextTop, strategy = "auto", options) {
|
|
6600
|
-
let r = normalizedRect(), full = normalizedFullRect(),
|
|
6601
|
-
if (
|
|
9097
|
+
let r = normalizedRect(), full = normalizedFullRect(), h19 = r.h;
|
|
9098
|
+
if (h19 <= 0 || full.h <= 0)
|
|
6602
9099
|
return !1;
|
|
6603
9100
|
options?.stickToBottom === !0 && props.wrap && ensureBottomMeasured();
|
|
6604
9101
|
let prevTop = rawScrollTop(), clampedTop = normalizeScrollTop(nextTop), delta = clampedTop - prevTop;
|
|
@@ -6622,7 +9119,7 @@ var TLogView = (0, import_vue14.defineComponent)({
|
|
|
6622
9119
|
if (scrollPlan) {
|
|
6623
9120
|
let rows = options?.extraDirtyRows?.length ? [...scrollPlan.exposedRows, ...options.extraDirtyRows] : scrollPlan.exposedRows;
|
|
6624
9121
|
if (markRowsDirty(rows))
|
|
6625
|
-
return scrollPlan.apply(), shiftVisibleLinksForScrollRegion(r.y, r.y +
|
|
9122
|
+
return scrollPlan.apply(), shiftVisibleLinksForScrollRegion(r.y, r.y + h19, delta), options?.emitScroll && emitScroll(clampedTop), !0;
|
|
6626
9123
|
}
|
|
6627
9124
|
return markViewportDirty(), options?.emitScroll && emitScroll(clampedTop), !0;
|
|
6628
9125
|
}
|
|
@@ -6851,8 +9348,8 @@ var TLogView = (0, import_vue14.defineComponent)({
|
|
|
6851
9348
|
return;
|
|
6852
9349
|
let lineIndex = clamp5(normalizeScrollNumber(index), 0, count - 1), target = lineIndex, visualCount = 1;
|
|
6853
9350
|
props.wrap && (ensureVisualIndex(), measureVisualLine(lineIndex), target = visualStartForLine(lineIndex), visualCount = visualCounts[lineIndex] ?? 1);
|
|
6854
|
-
let
|
|
6855
|
-
options?.align === "center" ? target -= Math.floor((
|
|
9351
|
+
let h19 = viewportHeight();
|
|
9352
|
+
options?.align === "center" ? target -= Math.floor((h19 - visualCount) / 2) : options?.align === "end" && (target += visualCount - h19), scrollToVisualRow(target);
|
|
6856
9353
|
}
|
|
6857
9354
|
function repaintInvalidatedViewport() {
|
|
6858
9355
|
let nextTop = stickToBottom.value ? bottomScrollTop() : currentScrollTop(), changed = applyScrollTop(nextTop, "viewport-repaint", {
|
|
@@ -7066,7 +9563,7 @@ var TLogView = (0, import_vue14.defineComponent)({
|
|
|
7066
9563
|
getText: textForSelectionRange,
|
|
7067
9564
|
getVisibleSpans: visibleSpansForSelectionRange
|
|
7068
9565
|
}, unregisterSelectionTextProvider = selection.registerTextProvider(selectionTextProvider);
|
|
7069
|
-
(0,
|
|
9566
|
+
(0, import_vue18.onBeforeUnmount)(unregisterSelectionTextProvider);
|
|
7070
9567
|
let eventNode = useTerminalNode(() => ({
|
|
7071
9568
|
rect: normalizedRect(),
|
|
7072
9569
|
zIndex: eventZ.value,
|
|
@@ -7102,12 +9599,12 @@ var TLogView = (0, import_vue14.defineComponent)({
|
|
|
7102
9599
|
keydown: onKeydown
|
|
7103
9600
|
}
|
|
7104
9601
|
}));
|
|
7105
|
-
(0,
|
|
9602
|
+
(0, import_vue18.watchEffect)(() => {
|
|
7106
9603
|
if (!props.autoFocus || !visible.value)
|
|
7107
9604
|
return;
|
|
7108
9605
|
let manager = events.value, nodeId = eventNode.id.value;
|
|
7109
9606
|
!manager || !nodeId || manager.getFocused() !== nodeId && manager.focus(nodeId);
|
|
7110
|
-
}), (0,
|
|
9607
|
+
}), (0, import_vue18.watch)(
|
|
7111
9608
|
[
|
|
7112
9609
|
() => visible.value,
|
|
7113
9610
|
() => absRect.value.x,
|
|
@@ -7127,24 +9624,24 @@ var TLogView = (0, import_vue14.defineComponent)({
|
|
|
7127
9624
|
let nextPendingTop = normalizeScrollTop(pendingWheelTop);
|
|
7128
9625
|
nextPendingTop === currentScrollTop() ? cancelWheelScrollFrame() : nextPendingTop !== pendingWheelTop && replacePendingWheelTop(nextPendingTop);
|
|
7129
9626
|
}
|
|
7130
|
-
), (0,
|
|
9627
|
+
), (0, import_vue18.watch)(
|
|
7131
9628
|
() => props.version,
|
|
7132
9629
|
() => {
|
|
7133
9630
|
resetWheelScrollState(wheelState), requestDataFrame(), requestSearchScan();
|
|
7134
9631
|
}
|
|
7135
|
-
), (0,
|
|
9632
|
+
), (0, import_vue18.watch)(
|
|
7136
9633
|
() => [props.ansi, props.links, props.linkify],
|
|
7137
9634
|
() => {
|
|
7138
9635
|
visualLinksEnabled() || clearLinkFocus();
|
|
7139
9636
|
}
|
|
7140
|
-
), (0,
|
|
9637
|
+
), (0, import_vue18.watch)(
|
|
7141
9638
|
() => props.scrollTop,
|
|
7142
9639
|
() => {
|
|
7143
9640
|
cancelWheelScrollFrame(), syncStickFromCurrentScrollTop();
|
|
7144
9641
|
let remap = pendingSelectionScrollFocusRemap;
|
|
7145
9642
|
pendingSelectionScrollFocusRemap = !1, selection.refresh(remap ? { remapFocus: !0 } : void 0), markViewportDirty(), invalidateSelf("high", "scroll");
|
|
7146
9643
|
}
|
|
7147
|
-
), (0,
|
|
9644
|
+
), (0, import_vue18.watch)(
|
|
7148
9645
|
[
|
|
7149
9646
|
() => props.source,
|
|
7150
9647
|
() => props.wrap,
|
|
@@ -7167,7 +9664,7 @@ var TLogView = (0, import_vue14.defineComponent)({
|
|
|
7167
9664
|
emitVisualIndex(!0);
|
|
7168
9665
|
},
|
|
7169
9666
|
{ immediate: !0 }
|
|
7170
|
-
), (0,
|
|
9667
|
+
), (0, import_vue18.watch)(
|
|
7171
9668
|
[
|
|
7172
9669
|
() => props.searchQuery,
|
|
7173
9670
|
() => props.searchOptions?.mode,
|
|
@@ -7184,12 +9681,12 @@ var TLogView = (0, import_vue14.defineComponent)({
|
|
|
7184
9681
|
requestSearchScan();
|
|
7185
9682
|
},
|
|
7186
9683
|
{ immediate: !0 }
|
|
7187
|
-
), (0,
|
|
9684
|
+
), (0, import_vue18.watch)(
|
|
7188
9685
|
[() => props.highlightMatches, () => props.matchStyle, () => props.currentMatchStyle],
|
|
7189
9686
|
() => {
|
|
7190
9687
|
markViewportDirty(), invalidateSelf("normal", "data");
|
|
7191
9688
|
}
|
|
7192
|
-
), (0,
|
|
9689
|
+
), (0, import_vue18.watch)(
|
|
7193
9690
|
[
|
|
7194
9691
|
() => props.source,
|
|
7195
9692
|
() => props.wrap,
|
|
@@ -7215,7 +9712,7 @@ var TLogView = (0, import_vue14.defineComponent)({
|
|
|
7215
9712
|
changed && selection.refresh(), changed || markViewportDirty(), invalidateSelf("normal", "data");
|
|
7216
9713
|
},
|
|
7217
9714
|
{ immediate: !0 }
|
|
7218
|
-
), (0,
|
|
9715
|
+
), (0, import_vue18.onBeforeUnmount)(() => {
|
|
7219
9716
|
alive = !1, searchGeneration++, visualMeasureGeneration++, cancelWheelScrollFrame(), wheelMailbox.dispose(), dataHighMailbox.dispose(), dataNormalMailbox.dispose();
|
|
7220
9717
|
});
|
|
7221
9718
|
let renderNode = useRenderNode(() => ({
|
|
@@ -7400,14 +9897,14 @@ var TLogView = (0, import_vue14.defineComponent)({
|
|
|
7400
9897
|
syncFocusedVisibleLinkFromViewport(), trimRenderCache(), trimWrapCache(), trimAnsiLineCache(), trimAnsiWrapCache(), trimAnsiRowCache(), trimLinkifyLineCache(), trimLinkifyWrapCache();
|
|
7401
9898
|
}
|
|
7402
9899
|
}));
|
|
7403
|
-
return (0,
|
|
9900
|
+
return (0, import_vue18.watchEffect)(() => {
|
|
7404
9901
|
renderNodeId = renderNode.id.value;
|
|
7405
|
-
}), lastLineCount = lineCount(), lastFirstLineIndex = firstLineIndex(), () => (0,
|
|
9902
|
+
}), lastLineCount = lineCount(), lastFirstLineIndex = firstLineIndex(), () => (0, import_vue18.h)("span", rootProps);
|
|
7406
9903
|
}
|
|
7407
9904
|
});
|
|
7408
9905
|
|
|
7409
9906
|
// src/vue/components/TLogScrollbar.ts
|
|
7410
|
-
var
|
|
9907
|
+
var import_vue19 = require("vue");
|
|
7411
9908
|
var EMPTY_RECT3 = Object.freeze({ x: 0, y: 0, w: 0, h: 0 }), SCROLLBAR_WIDTH = 1, TRACK_CHAR = "\u2502", EXACT_THUMB_CHAR = "\u2588", MEASURING_THUMB_CHAR = "\u2592", ESTIMATED_THUMB_CHAR = "\u2591", MARKER_CHAR = "\u2022", ESTIMATED_MARKER_CHAR = "\xB7", CURRENT_MARKER_CHAR = "\u25C6", UP_ARROW_CHAR = "\u25B2", DOWN_ARROW_CHAR = "\u25BC";
|
|
7412
9909
|
function clamp6(n, min, max) {
|
|
7413
9910
|
return Math.max(min, Math.min(max, n));
|
|
@@ -7469,7 +9966,7 @@ function collectMarkersByRow(markers, metrics2, height, showArrows) {
|
|
|
7469
9966
|
function mergeStyle3(base, overlay) {
|
|
7470
9967
|
return overlay ? { ...base, ...overlay } : base;
|
|
7471
9968
|
}
|
|
7472
|
-
var TLogScrollbar = (0,
|
|
9969
|
+
var TLogScrollbar = (0, import_vue19.defineComponent)({
|
|
7473
9970
|
name: "TLogScrollbar",
|
|
7474
9971
|
props: {
|
|
7475
9972
|
x: { type: Number, required: !0 },
|
|
@@ -7501,7 +9998,7 @@ var TLogScrollbar = (0, import_vue15.defineComponent)({
|
|
|
7501
9998
|
},
|
|
7502
9999
|
emits: ["scrollTo", "scrollBy", "markerClick"],
|
|
7503
10000
|
setup(props, { emit }) {
|
|
7504
|
-
let { terminal, defaultStyle } = useTerminal(), parent = useLayout(), { visible, rootProps } = useVisibility(), parentEventZ = (0,
|
|
10001
|
+
let { terminal, defaultStyle } = useTerminal(), parent = useLayout(), { visible, rootProps } = useVisibility(), parentEventZ = (0, import_vue19.inject)(EventZIndexContextKey, (0, import_vue19.computed)(() => 0)), eventZ = (0, import_vue19.computed)(() => (parentEventZ.value ?? 0) + (props.zIndex ?? 0)), fullRect = (0, import_vue19.computed)(
|
|
7505
10002
|
() => translateRect(
|
|
7506
10003
|
{
|
|
7507
10004
|
x: normalizeInt3(props.x),
|
|
@@ -7512,7 +10009,7 @@ var TLogScrollbar = (0, import_vue15.defineComponent)({
|
|
|
7512
10009
|
parent.originX,
|
|
7513
10010
|
parent.originY
|
|
7514
10011
|
)
|
|
7515
|
-
), rect = (0,
|
|
10012
|
+
), rect = (0, import_vue19.computed)(() => {
|
|
7516
10013
|
let translated = fullRect.value;
|
|
7517
10014
|
return parent.clipRect ? intersectRect(translated, parent.clipRect) ?? EMPTY_RECT3 : translated;
|
|
7518
10015
|
});
|
|
@@ -7615,12 +10112,12 @@ var TLogScrollbar = (0, import_vue15.defineComponent)({
|
|
|
7615
10112
|
for (let y of dirtyRows)
|
|
7616
10113
|
paintRow(y);
|
|
7617
10114
|
}
|
|
7618
|
-
})), () => (0,
|
|
10115
|
+
})), () => (0, import_vue19.h)("span", rootProps);
|
|
7619
10116
|
}
|
|
7620
10117
|
});
|
|
7621
10118
|
|
|
7622
10119
|
// src/vue/components/TLogMinimap.ts
|
|
7623
|
-
var
|
|
10120
|
+
var import_vue20 = require("vue");
|
|
7624
10121
|
var EMPTY_RECT4 = Object.freeze({ x: 0, y: 0, w: 0, h: 0 }), CURRENT_MARKER_CHAR2 = "\u25C6", MARKER_CHAR2 = "\u2022", ESTIMATED_MARKER_CHAR2 = "\xB7", VIEWPORT_CHAR = "\u2588", DENSITY_HIGH_CHAR = "\u2593", DENSITY_MEDIUM_CHAR = "\u2592", DENSITY_LOW_CHAR = "\u2591";
|
|
7625
10122
|
function clamp7(n, min, max) {
|
|
7626
10123
|
return Math.max(min, Math.min(max, n));
|
|
@@ -7709,7 +10206,7 @@ function collectDensityByRow(density, metrics2, height) {
|
|
|
7709
10206
|
function densityChar(value) {
|
|
7710
10207
|
return value >= 0.66 ? DENSITY_HIGH_CHAR : value >= 0.33 ? DENSITY_MEDIUM_CHAR : value > 0 ? DENSITY_LOW_CHAR : " ";
|
|
7711
10208
|
}
|
|
7712
|
-
var TLogMinimap = (0,
|
|
10209
|
+
var TLogMinimap = (0, import_vue20.defineComponent)({
|
|
7713
10210
|
name: "TLogMinimap",
|
|
7714
10211
|
props: {
|
|
7715
10212
|
x: { type: Number, required: !0 },
|
|
@@ -7741,7 +10238,7 @@ var TLogMinimap = (0, import_vue16.defineComponent)({
|
|
|
7741
10238
|
},
|
|
7742
10239
|
emits: ["scrollTo", "markerClick"],
|
|
7743
10240
|
setup(props, { emit }) {
|
|
7744
|
-
let { terminal, defaultStyle } = useTerminal(), parent = useLayout(), { visible, rootProps } = useVisibility(), parentEventZ = (0,
|
|
10241
|
+
let { terminal, defaultStyle } = useTerminal(), parent = useLayout(), { visible, rootProps } = useVisibility(), parentEventZ = (0, import_vue20.inject)(EventZIndexContextKey, (0, import_vue20.computed)(() => 0)), eventZ = (0, import_vue20.computed)(() => (parentEventZ.value ?? 0) + (props.zIndex ?? 0)), fullRect = (0, import_vue20.computed)(
|
|
7745
10242
|
() => translateRect(
|
|
7746
10243
|
{
|
|
7747
10244
|
x: normalizeInt4(props.x),
|
|
@@ -7752,7 +10249,7 @@ var TLogMinimap = (0, import_vue16.defineComponent)({
|
|
|
7752
10249
|
parent.originX,
|
|
7753
10250
|
parent.originY
|
|
7754
10251
|
)
|
|
7755
|
-
), rect = (0,
|
|
10252
|
+
), rect = (0, import_vue20.computed)(() => {
|
|
7756
10253
|
let translated = fullRect.value;
|
|
7757
10254
|
return parent.clipRect ? intersectRect(translated, parent.clipRect) ?? EMPTY_RECT4 : translated;
|
|
7758
10255
|
});
|
|
@@ -7847,12 +10344,12 @@ var TLogMinimap = (0, import_vue16.defineComponent)({
|
|
|
7847
10344
|
for (let y of dirtyRows)
|
|
7848
10345
|
paintRow(y);
|
|
7849
10346
|
}
|
|
7850
|
-
})), () => (0,
|
|
10347
|
+
})), () => (0, import_vue20.h)("span", rootProps);
|
|
7851
10348
|
}
|
|
7852
10349
|
});
|
|
7853
10350
|
|
|
7854
10351
|
// src/vue/components/TLogSearchBar.ts
|
|
7855
|
-
var
|
|
10352
|
+
var import_vue21 = require("vue");
|
|
7856
10353
|
var EMPTY_RECT5 = Object.freeze({ x: 0, y: 0, w: 0, h: 0 }), PREVIOUS_CHAR = "\u25C0", NEXT_CHAR = "\u25B6";
|
|
7857
10354
|
function clamp8(n, min, max) {
|
|
7858
10355
|
return Math.max(min, Math.min(max, n));
|
|
@@ -7882,7 +10379,7 @@ function cellToStringIndex(text, cell) {
|
|
|
7882
10379
|
function errorLabel(error) {
|
|
7883
10380
|
return error?.kind === "invalid-regex" ? "Invalid regex" : "Search error";
|
|
7884
10381
|
}
|
|
7885
|
-
var TLogSearchBar = (0,
|
|
10382
|
+
var TLogSearchBar = (0, import_vue21.defineComponent)({
|
|
7886
10383
|
name: "TLogSearchBar",
|
|
7887
10384
|
props: {
|
|
7888
10385
|
x: { type: Number, required: !0 },
|
|
@@ -7933,7 +10430,7 @@ var TLogSearchBar = (0, import_vue17.defineComponent)({
|
|
|
7933
10430
|
"keydown"
|
|
7934
10431
|
],
|
|
7935
10432
|
setup(props, { emit }) {
|
|
7936
|
-
let { terminal, scheduler, defaultStyle, events } = useTerminal(), parent = useLayout(), { visible, rootProps } = useVisibility(), parentEventZ = (0,
|
|
10433
|
+
let { terminal, scheduler, defaultStyle, events } = useTerminal(), parent = useLayout(), { visible, rootProps } = useVisibility(), parentEventZ = (0, import_vue21.inject)(EventZIndexContextKey, (0, import_vue21.computed)(() => 0)), eventZ = (0, import_vue21.computed)(() => (parentEventZ.value ?? 0) + (props.zIndex ?? 0)), focused = (0, import_vue21.ref)(!1), cursor = (0, import_vue21.ref)(0), scrollCellOffset = (0, import_vue21.ref)(0), pendingUpdate = (0, import_vue21.ref)(null), fullRect = (0, import_vue21.computed)(
|
|
7937
10434
|
() => translateRect(
|
|
7938
10435
|
{
|
|
7939
10436
|
x: normalizeInt5(props.x),
|
|
@@ -7944,7 +10441,7 @@ var TLogSearchBar = (0, import_vue17.defineComponent)({
|
|
|
7944
10441
|
parent.originX,
|
|
7945
10442
|
parent.originY
|
|
7946
10443
|
)
|
|
7947
|
-
), rect = (0,
|
|
10444
|
+
), rect = (0, import_vue21.computed)(() => {
|
|
7948
10445
|
let translated = fullRect.value;
|
|
7949
10446
|
return parent.clipRect ? intersectRect(translated, parent.clipRect) ?? EMPTY_RECT5 : translated;
|
|
7950
10447
|
});
|
|
@@ -7964,7 +10461,7 @@ var TLogSearchBar = (0, import_vue17.defineComponent)({
|
|
|
7964
10461
|
let totalCells = textCellWidth(query), maxScroll = Math.max(0, totalCells - inputWidth), cursorCell = stringIndexToCell2(query, cursor.value), nextScroll = clamp8(scrollCellOffset.value, 0, maxScroll);
|
|
7965
10462
|
cursorCell < nextScroll && (nextScroll = cursorCell), cursorCell >= nextScroll + inputWidth && (nextScroll = cursorCell - inputWidth + 1), scrollCellOffset.value = clamp8(nextScroll, 0, maxScroll);
|
|
7966
10463
|
}
|
|
7967
|
-
let statusText = (0,
|
|
10464
|
+
let statusText = (0, import_vue21.computed)(() => props.state.status === "error" ? errorLabel(props.state.error) : props.state.status === "scanning" ? !props.showCount || props.state.matchCount <= 0 ? "Scanning\u2026" : `Scanning\u2026 ${props.state.matchCount}` : !props.showCount || !props.state.query ? "" : `${props.state.matchCount > 0 && props.state.currentMatchIndex >= 0 ? props.state.currentMatchIndex + 1 : 0}/${props.state.matchCount}`), rowLayout = (0, import_vue21.computed)(() => {
|
|
7968
10465
|
let width = Math.max(0, normalizeInt5(props.w)), base = props.style ?? defaultStyle.value, toggleBase = mergeStyle5(base, props.toggleStyle), active = mergeStyle5(toggleBase, props.activeStyle), disabled = mergeStyle5(toggleBase, props.disabledStyle), error = mergeStyle5(base, props.errorStyle), navigationEnabled = props.state.matchCount > 0 && props.state.status !== "error" && props.state.query.length > 0, prefixPieces = [], suffixSpecs = [], hits = [], prefixWidth = 0, pushPrefix = (text, style, action) => {
|
|
7969
10466
|
if (!text)
|
|
7970
10467
|
return;
|
|
@@ -8130,7 +10627,7 @@ var TLogSearchBar = (0, import_vue17.defineComponent)({
|
|
|
8130
10627
|
);
|
|
8131
10628
|
}
|
|
8132
10629
|
}
|
|
8133
|
-
(0,
|
|
10630
|
+
(0, import_vue21.watch)(
|
|
8134
10631
|
() => [
|
|
8135
10632
|
props.state.query,
|
|
8136
10633
|
props.state.mode,
|
|
@@ -8228,7 +10725,7 @@ var TLogSearchBar = (0, import_vue17.defineComponent)({
|
|
|
8228
10725
|
clipped && terminal.write(clipped, { x: Math.max(drawX, r.x), y: r.y, style: piece.style });
|
|
8229
10726
|
}
|
|
8230
10727
|
}
|
|
8231
|
-
})), () => (0,
|
|
10728
|
+
})), () => (0, import_vue21.h)(
|
|
8232
10729
|
"div",
|
|
8233
10730
|
{
|
|
8234
10731
|
...rootProps,
|
|
@@ -8240,7 +10737,7 @@ var TLogSearchBar = (0, import_vue17.defineComponent)({
|
|
|
8240
10737
|
});
|
|
8241
10738
|
|
|
8242
10739
|
// src/vue/components/TLogSearchResults.ts
|
|
8243
|
-
var
|
|
10740
|
+
var import_vue22 = require("vue");
|
|
8244
10741
|
var EMPTY_RECT6 = Object.freeze({ x: 0, y: 0, w: 0, h: 0 });
|
|
8245
10742
|
function clamp9(n, min, max) {
|
|
8246
10743
|
return Math.max(min, Math.min(max, n));
|
|
@@ -8258,7 +10755,7 @@ function normalizeActiveIndex(value, count) {
|
|
|
8258
10755
|
let n = Math.floor(Number(value));
|
|
8259
10756
|
return !Number.isFinite(n) || n < 0 ? -1 : clamp9(n, 0, count - 1);
|
|
8260
10757
|
}
|
|
8261
|
-
var TLogSearchResults = (0,
|
|
10758
|
+
var TLogSearchResults = (0, import_vue22.defineComponent)({
|
|
8262
10759
|
name: "TLogSearchResults",
|
|
8263
10760
|
props: {
|
|
8264
10761
|
x: { type: Number, required: !0 },
|
|
@@ -8289,7 +10786,7 @@ var TLogSearchResults = (0, import_vue18.defineComponent)({
|
|
|
8289
10786
|
},
|
|
8290
10787
|
emits: ["select", "activeChange", "keydown", "focus", "blur"],
|
|
8291
10788
|
setup(props, { emit }) {
|
|
8292
|
-
let { terminal, scheduler, defaultStyle, events } = useTerminal(), parent = useLayout(), { visible, rootProps } = useVisibility(), parentEventZ = (0,
|
|
10789
|
+
let { terminal, scheduler, defaultStyle, events } = useTerminal(), parent = useLayout(), { visible, rootProps } = useVisibility(), parentEventZ = (0, import_vue22.inject)(EventZIndexContextKey, (0, import_vue22.computed)(() => 0)), eventZ = (0, import_vue22.computed)(() => (parentEventZ.value ?? 0) + (props.zIndex ?? 0)), focused = (0, import_vue22.ref)(!1), internalActiveIndex = (0, import_vue22.ref)(-1), fullRect = (0, import_vue22.computed)(
|
|
8293
10790
|
() => translateRect(
|
|
8294
10791
|
{
|
|
8295
10792
|
x: normalizeInt6(props.x),
|
|
@@ -8300,16 +10797,16 @@ var TLogSearchResults = (0, import_vue18.defineComponent)({
|
|
|
8300
10797
|
parent.originX,
|
|
8301
10798
|
parent.originY
|
|
8302
10799
|
)
|
|
8303
|
-
), rect = (0,
|
|
10800
|
+
), rect = (0, import_vue22.computed)(() => {
|
|
8304
10801
|
let translated = fullRect.value;
|
|
8305
10802
|
return parent.clipRect ? intersectRect(translated, parent.clipRect) ?? EMPTY_RECT6 : translated;
|
|
8306
|
-
}), lineNumberDigits = (0,
|
|
10803
|
+
}), lineNumberDigits = (0, import_vue22.computed)(
|
|
8307
10804
|
() => props.showLineNumbers ? props.results.reduce(
|
|
8308
10805
|
(max, result) => Math.max(max, String(result.absoluteLineIndex).length),
|
|
8309
10806
|
1
|
|
8310
10807
|
) : 0
|
|
8311
10808
|
);
|
|
8312
|
-
(0,
|
|
10809
|
+
(0, import_vue22.watch)(
|
|
8313
10810
|
[() => props.activeIndex, () => props.results.length],
|
|
8314
10811
|
() => {
|
|
8315
10812
|
internalActiveIndex.value = normalizeActiveIndex(props.activeIndex, props.results.length);
|
|
@@ -8440,12 +10937,12 @@ var TLogSearchResults = (0, import_vue18.defineComponent)({
|
|
|
8440
10937
|
}), result.text || segments.push({ text: "", style: rowStyle }), writeSegments(y, rowStyle, segments);
|
|
8441
10938
|
}
|
|
8442
10939
|
}
|
|
8443
|
-
})), () => (0,
|
|
10940
|
+
})), () => (0, import_vue22.h)("span", rootProps);
|
|
8444
10941
|
}
|
|
8445
10942
|
});
|
|
8446
10943
|
|
|
8447
10944
|
// src/vue/components/TLogSearchPager.ts
|
|
8448
|
-
var
|
|
10945
|
+
var import_vue23 = require("vue");
|
|
8449
10946
|
var EMPTY_RECT7 = Object.freeze({ x: 0, y: 0, w: 0, h: 0 }), PREVIOUS_CHAR2 = "\u25C0", NEXT_CHAR2 = "\u25B6";
|
|
8450
10947
|
function clamp10(n, min, max) {
|
|
8451
10948
|
return Math.max(min, Math.min(max, n));
|
|
@@ -8463,7 +10960,7 @@ function formatCount(matchCount) {
|
|
|
8463
10960
|
function errorLabel2(error) {
|
|
8464
10961
|
return error?.kind === "invalid-regex" ? "Invalid regex" : "Search error";
|
|
8465
10962
|
}
|
|
8466
|
-
var TLogSearchPager = (0,
|
|
10963
|
+
var TLogSearchPager = (0, import_vue23.defineComponent)({
|
|
8467
10964
|
name: "TLogSearchPager",
|
|
8468
10965
|
props: {
|
|
8469
10966
|
x: { type: Number, required: !0 },
|
|
@@ -8488,7 +10985,7 @@ var TLogSearchPager = (0, import_vue19.defineComponent)({
|
|
|
8488
10985
|
},
|
|
8489
10986
|
emits: ["previousPage", "nextPage", "pageChange"],
|
|
8490
10987
|
setup(props, { emit }) {
|
|
8491
|
-
let { terminal, scheduler, defaultStyle, events } = useTerminal(), parent = useLayout(), { visible, rootProps } = useVisibility(), parentEventZ = (0,
|
|
10988
|
+
let { terminal, scheduler, defaultStyle, events } = useTerminal(), parent = useLayout(), { visible, rootProps } = useVisibility(), parentEventZ = (0, import_vue23.inject)(EventZIndexContextKey, (0, import_vue23.computed)(() => 0)), eventZ = (0, import_vue23.computed)(() => (parentEventZ.value ?? 0) + (props.zIndex ?? 0)), focused = (0, import_vue23.ref)(!1), fullRect = (0, import_vue23.computed)(
|
|
8492
10989
|
() => translateRect(
|
|
8493
10990
|
{
|
|
8494
10991
|
x: normalizeInt7(props.x),
|
|
@@ -8499,10 +10996,10 @@ var TLogSearchPager = (0, import_vue19.defineComponent)({
|
|
|
8499
10996
|
parent.originX,
|
|
8500
10997
|
parent.originY
|
|
8501
10998
|
)
|
|
8502
|
-
), rect = (0,
|
|
10999
|
+
), rect = (0, import_vue23.computed)(() => {
|
|
8503
11000
|
let translated = fullRect.value;
|
|
8504
11001
|
return parent.clipRect ? intersectRect(translated, parent.clipRect) ?? EMPTY_RECT7 : translated;
|
|
8505
|
-
}), viewState = (0,
|
|
11002
|
+
}), viewState = (0, import_vue23.computed)(() => props.state), segments = (0, import_vue23.computed)(() => {
|
|
8506
11003
|
let base = props.style ?? defaultStyle.value, active = mergeStyle7(base, props.activeStyle), disabled = mergeStyle7(base, props.disabledStyle), error = mergeStyle7(base, props.errorStyle), state = viewState.value;
|
|
8507
11004
|
if (!state || state.status === "idle")
|
|
8508
11005
|
return [{ text: "No search", style: base }];
|
|
@@ -8623,7 +11120,7 @@ var TLogSearchPager = (0, import_vue19.defineComponent)({
|
|
|
8623
11120
|
break;
|
|
8624
11121
|
}
|
|
8625
11122
|
}
|
|
8626
|
-
})), () => (0,
|
|
11123
|
+
})), () => (0, import_vue23.h)(
|
|
8627
11124
|
"div",
|
|
8628
11125
|
{
|
|
8629
11126
|
...rootProps,
|
|
@@ -8635,7 +11132,7 @@ var TLogSearchPager = (0, import_vue19.defineComponent)({
|
|
|
8635
11132
|
});
|
|
8636
11133
|
|
|
8637
11134
|
// src/vue/components/TLogLinksPanel.ts
|
|
8638
|
-
var
|
|
11135
|
+
var import_vue24 = require("vue");
|
|
8639
11136
|
var EMPTY_RECT8 = Object.freeze({ x: 0, y: 0, w: 0, h: 0 }), EMPTY_LABEL = "No visible links";
|
|
8640
11137
|
function clamp11(n, min, max) {
|
|
8641
11138
|
return Math.max(min, Math.min(max, n));
|
|
@@ -8653,7 +11150,7 @@ function normalizeActiveIndex2(value, count) {
|
|
|
8653
11150
|
let n = Math.floor(Number(value));
|
|
8654
11151
|
return !Number.isFinite(n) || n < 0 ? -1 : clamp11(n, 0, count - 1);
|
|
8655
11152
|
}
|
|
8656
|
-
var TLogLinksPanel = (0,
|
|
11153
|
+
var TLogLinksPanel = (0, import_vue24.defineComponent)({
|
|
8657
11154
|
name: "TLogLinksPanel",
|
|
8658
11155
|
props: {
|
|
8659
11156
|
x: { type: Number, required: !0 },
|
|
@@ -8689,7 +11186,7 @@ var TLogLinksPanel = (0, import_vue20.defineComponent)({
|
|
|
8689
11186
|
},
|
|
8690
11187
|
emits: ["select", "activate", "activeChange", "focus", "blur", "keydown"],
|
|
8691
11188
|
setup(props, { emit }) {
|
|
8692
|
-
let { terminal, scheduler, defaultStyle, events } = useTerminal(), parent = useLayout(), { visible, rootProps } = useVisibility(), parentEventZ = (0,
|
|
11189
|
+
let { terminal, scheduler, defaultStyle, events } = useTerminal(), parent = useLayout(), { visible, rootProps } = useVisibility(), parentEventZ = (0, import_vue24.inject)(EventZIndexContextKey, (0, import_vue24.computed)(() => 0)), eventZ = (0, import_vue24.computed)(() => (parentEventZ.value ?? 0) + (props.zIndex ?? 0)), focused = (0, import_vue24.ref)(!1), internalActiveIndex = (0, import_vue24.ref)(-1), fullRect = (0, import_vue24.computed)(
|
|
8693
11190
|
() => translateRect(
|
|
8694
11191
|
{
|
|
8695
11192
|
x: normalizeInt8(props.x),
|
|
@@ -8700,13 +11197,13 @@ var TLogLinksPanel = (0, import_vue20.defineComponent)({
|
|
|
8700
11197
|
parent.originX,
|
|
8701
11198
|
parent.originY
|
|
8702
11199
|
)
|
|
8703
|
-
), rect = (0,
|
|
11200
|
+
), rect = (0, import_vue24.computed)(() => {
|
|
8704
11201
|
let translated = fullRect.value;
|
|
8705
11202
|
return parent.clipRect ? intersectRect(translated, parent.clipRect) ?? EMPTY_RECT8 : translated;
|
|
8706
|
-
}), lineNumberDigits = (0,
|
|
11203
|
+
}), lineNumberDigits = (0, import_vue24.computed)(
|
|
8707
11204
|
() => props.showLineNumbers ? props.links.reduce((max, link) => Math.max(max, String(link.absoluteLineIndex).length), 1) : 0
|
|
8708
11205
|
);
|
|
8709
|
-
(0,
|
|
11206
|
+
(0, import_vue24.watch)(
|
|
8710
11207
|
[() => props.activeIndex, () => props.links.length],
|
|
8711
11208
|
() => {
|
|
8712
11209
|
internalActiveIndex.value = normalizeActiveIndex2(props.activeIndex, props.links.length);
|
|
@@ -8846,12 +11343,12 @@ var TLogLinksPanel = (0, import_vue20.defineComponent)({
|
|
|
8846
11343
|
}), item.text && segments.push({ text: item.text, style: rowStyle }), props.showHref && item.href && (item.text && segments.push({ text: " ", style: rowStyle }), segments.push({ text: item.href, style: hrefRowStyle })), segments.length || segments.push({ text: "", style: rowStyle }), writeSegments(y, rowStyle, segments);
|
|
8847
11344
|
}
|
|
8848
11345
|
}
|
|
8849
|
-
})), () => (0,
|
|
11346
|
+
})), () => (0, import_vue24.h)("span", rootProps);
|
|
8850
11347
|
}
|
|
8851
11348
|
});
|
|
8852
11349
|
|
|
8853
11350
|
// src/vue/components/TLogVirtualSearchResults.ts
|
|
8854
|
-
var
|
|
11351
|
+
var import_vue25 = require("vue");
|
|
8855
11352
|
function sliceByCells2(text, start, end) {
|
|
8856
11353
|
let cells = 0, out = "";
|
|
8857
11354
|
for (let ch of text) {
|
|
@@ -8867,7 +11364,7 @@ function formatItem(item, width, showLineNumbers) {
|
|
|
8867
11364
|
let currentPrefix = item.current ? "*" : " ", linePrefix = showLineNumbers ? `${String(item.absoluteLineIndex).padStart(5, " ")} ` : "", before = sliceByCells2(item.text, 0, item.matchStartCell), match = sliceByCells2(item.text, item.matchStartCell, item.matchEndCell), after = sliceByCells2(item.text, item.matchEndCell, Number.MAX_SAFE_INTEGER);
|
|
8868
11365
|
return `${currentPrefix}${linePrefix}${before}[${match}]${after}`.slice(0, Math.max(0, width));
|
|
8869
11366
|
}
|
|
8870
|
-
var TLogVirtualSearchResults = (0,
|
|
11367
|
+
var TLogVirtualSearchResults = (0, import_vue25.defineComponent)({
|
|
8871
11368
|
name: "TLogVirtualSearchResults",
|
|
8872
11369
|
props: {
|
|
8873
11370
|
x: { type: Number, required: !0 },
|
|
@@ -8892,7 +11389,7 @@ var TLogVirtualSearchResults = (0, import_vue21.defineComponent)({
|
|
|
8892
11389
|
},
|
|
8893
11390
|
emits: ["update:modelValue", "activeChange", "select", "focus", "blur", "keydown", "scroll"],
|
|
8894
11391
|
setup(props, { emit }) {
|
|
8895
|
-
let model = (0,
|
|
11392
|
+
let model = (0, import_vue25.computed)({
|
|
8896
11393
|
get: () => props.modelValue,
|
|
8897
11394
|
set: (value) => {
|
|
8898
11395
|
emit("update:modelValue", value), emit("activeChange", {
|
|
@@ -8901,7 +11398,7 @@ var TLogVirtualSearchResults = (0, import_vue21.defineComponent)({
|
|
|
8901
11398
|
});
|
|
8902
11399
|
}
|
|
8903
11400
|
});
|
|
8904
|
-
return () => (0,
|
|
11401
|
+
return () => (0, import_vue25.h)(TVirtualList, {
|
|
8905
11402
|
x: props.x,
|
|
8906
11403
|
y: props.y,
|
|
8907
11404
|
w: props.w,
|
|
@@ -8939,14 +11436,14 @@ var TLogVirtualSearchResults = (0, import_vue21.defineComponent)({
|
|
|
8939
11436
|
});
|
|
8940
11437
|
|
|
8941
11438
|
// src/vue/components/TLogVirtualLinksPanel.ts
|
|
8942
|
-
var
|
|
11439
|
+
var import_vue26 = require("vue");
|
|
8943
11440
|
function formatItem2(item, width, showLineNumbers) {
|
|
8944
11441
|
if (!item)
|
|
8945
11442
|
return "";
|
|
8946
11443
|
let currentPrefix = item.current ? "*" : " ", linePrefix = showLineNumbers ? `${String(item.absoluteLineIndex).padStart(5, " ")} ` : "";
|
|
8947
11444
|
return `${currentPrefix}${linePrefix}${item.text} -> ${item.href}`.slice(0, Math.max(0, width));
|
|
8948
11445
|
}
|
|
8949
|
-
var TLogVirtualLinksPanel = (0,
|
|
11446
|
+
var TLogVirtualLinksPanel = (0, import_vue26.defineComponent)({
|
|
8950
11447
|
name: "TLogVirtualLinksPanel",
|
|
8951
11448
|
props: {
|
|
8952
11449
|
x: { type: Number, required: !0 },
|
|
@@ -8978,7 +11475,7 @@ var TLogVirtualLinksPanel = (0, import_vue22.defineComponent)({
|
|
|
8978
11475
|
"scroll"
|
|
8979
11476
|
],
|
|
8980
11477
|
setup(props, { emit }) {
|
|
8981
|
-
let model = (0,
|
|
11478
|
+
let model = (0, import_vue26.computed)({
|
|
8982
11479
|
get: () => props.modelValue,
|
|
8983
11480
|
set: (value) => {
|
|
8984
11481
|
emit("update:modelValue", value), emit("activeChange", {
|
|
@@ -8987,7 +11484,7 @@ var TLogVirtualLinksPanel = (0, import_vue22.defineComponent)({
|
|
|
8987
11484
|
});
|
|
8988
11485
|
}
|
|
8989
11486
|
});
|
|
8990
|
-
return () => (0,
|
|
11487
|
+
return () => (0, import_vue26.h)(TVirtualList, {
|
|
8991
11488
|
x: props.x,
|
|
8992
11489
|
y: props.y,
|
|
8993
11490
|
w: props.w,
|
|
@@ -9025,7 +11522,7 @@ var TLogVirtualLinksPanel = (0, import_vue22.defineComponent)({
|
|
|
9025
11522
|
});
|
|
9026
11523
|
|
|
9027
11524
|
// src/vue/log/append-only-log-store.ts
|
|
9028
|
-
var
|
|
11525
|
+
var import_vue27 = require("vue");
|
|
9029
11526
|
function normalizeMaxLines(value) {
|
|
9030
11527
|
if (value == null)
|
|
9031
11528
|
return null;
|
|
@@ -9033,7 +11530,7 @@ function normalizeMaxLines(value) {
|
|
|
9033
11530
|
return Number.isFinite(n) ? Math.max(1, n) : null;
|
|
9034
11531
|
}
|
|
9035
11532
|
function createAppendOnlyLogStore(options) {
|
|
9036
|
-
let lines = [], version = (0,
|
|
11533
|
+
let lines = [], version = (0, import_vue27.ref)(0), maxLines = normalizeMaxLines(options?.maxLines), head = 0, firstLineIndex = 0, tail = "", tailVersion = 0, nextLineId = 0;
|
|
9037
11534
|
function bump() {
|
|
9038
11535
|
version.value++;
|
|
9039
11536
|
}
|
|
@@ -9107,7 +11604,7 @@ function createAppendOnlyLogStore(options) {
|
|
|
9107
11604
|
}
|
|
9108
11605
|
|
|
9109
11606
|
// src/vue/log/use-tlog-link-controller.ts
|
|
9110
|
-
var
|
|
11607
|
+
var import_vue28 = require("vue");
|
|
9111
11608
|
|
|
9112
11609
|
// src/vue/log/tlog-plugins.ts
|
|
9113
11610
|
function escapeRegExp(value) {
|
|
@@ -9414,7 +11911,7 @@ function actionKey(value) {
|
|
|
9414
11911
|
]);
|
|
9415
11912
|
}
|
|
9416
11913
|
function useTLogLinkController(logView, options = {}) {
|
|
9417
|
-
let visibleLinks = (0,
|
|
11914
|
+
let visibleLinks = (0, import_vue28.ref)([]), activeIndex = (0, import_vue28.ref)(-1), suppressedActivateKey = null;
|
|
9418
11915
|
function emitAction(action) {
|
|
9419
11916
|
options.onAction?.(action), dispatchTLogPluginLinkAction(options.plugins, action);
|
|
9420
11917
|
}
|
|
@@ -9479,7 +11976,7 @@ function useTLogLinkController(logView, options = {}) {
|
|
|
9479
11976
|
}
|
|
9480
11977
|
emitAction(action), refresh();
|
|
9481
11978
|
}
|
|
9482
|
-
return (0,
|
|
11979
|
+
return (0, import_vue28.watch)(
|
|
9483
11980
|
() => logView.value,
|
|
9484
11981
|
() => {
|
|
9485
11982
|
refresh();
|
|
@@ -9501,10 +11998,10 @@ function useTLogLinkController(logView, options = {}) {
|
|
|
9501
11998
|
}
|
|
9502
11999
|
|
|
9503
12000
|
// src/vue/log/use-tlog-search-controller.ts
|
|
9504
|
-
var
|
|
12001
|
+
var import_vue30 = require("vue");
|
|
9505
12002
|
|
|
9506
12003
|
// src/vue/log/use-tlog-search-results-page.ts
|
|
9507
|
-
var
|
|
12004
|
+
var import_vue29 = require("vue"), DEFAULT_PAGE_SIZE = 20;
|
|
9508
12005
|
function clamp12(n, min, max) {
|
|
9509
12006
|
return Math.max(min, Math.min(max, n));
|
|
9510
12007
|
}
|
|
@@ -9536,7 +12033,7 @@ function createEmptyState(pageSize, status = "idle", error = null) {
|
|
|
9536
12033
|
};
|
|
9537
12034
|
}
|
|
9538
12035
|
function useTLogSearchResultsPage(logView, options = {}) {
|
|
9539
|
-
let pageSize = normalizePageSize(options.pageSize), includePreview = options.includePreview === !0, currentPage = (0,
|
|
12036
|
+
let pageSize = normalizePageSize(options.pageSize), includePreview = options.includePreview === !0, currentPage = (0, import_vue29.ref)(0), state = (0, import_vue29.ref)(createEmptyState(pageSize));
|
|
9540
12037
|
function clear(status = "idle", error = null) {
|
|
9541
12038
|
currentPage.value = 0, state.value = createEmptyState(pageSize, status, error);
|
|
9542
12039
|
}
|
|
@@ -9596,7 +12093,7 @@ function useTLogSearchResultsPage(logView, options = {}) {
|
|
|
9596
12093
|
let normalizedMatchIndex = normalizeInt9(matchIndex, -1);
|
|
9597
12094
|
return handle.selectSearchMatch(normalizedMatchIndex) ? (currentPage.value = Math.floor(normalizedMatchIndex / pageSize), refresh(), !0) : (refresh(), !1);
|
|
9598
12095
|
}
|
|
9599
|
-
return (0,
|
|
12096
|
+
return (0, import_vue29.watch)(
|
|
9600
12097
|
() => logView.value,
|
|
9601
12098
|
() => {
|
|
9602
12099
|
currentPage.value = 0, refresh();
|
|
@@ -9633,7 +12130,7 @@ function sameSavedSearch(a, b) {
|
|
|
9633
12130
|
return a.query === b.query && a.mode === b.mode && !!a.caseSensitive == !!b.caseSensitive && !!a.wholeWord == !!b.wholeWord && (a.regexFlags ?? "") === (b.regexFlags ?? "");
|
|
9634
12131
|
}
|
|
9635
12132
|
function useTLogSearchController(logView, options = {}) {
|
|
9636
|
-
let query = (0,
|
|
12133
|
+
let query = (0, import_vue30.ref)(options.initialQuery ?? ""), mode = (0, import_vue30.ref)(options.initialMode === "regex" ? "regex" : "text"), caseSensitive = (0, import_vue30.ref)(options.initialCaseSensitive === !0), wholeWord = (0, import_vue30.ref)(options.initialWholeWord === !0), regexFlags = (0, import_vue30.ref)(options.initialRegexFlags ?? ""), searchState = (0, import_vue30.ref)(normalizeSearchState(query.value)), markers = (0, import_vue30.ref)([]), metrics2 = (0, import_vue30.ref)(null), searchHistory = (0, import_vue30.ref)([]), savedSearches = (0, import_vue30.ref)(options.initialSavedSearches ?? []), historyLimit = normalizeHistoryLimit(options.maxHistory), resultsPage = useTLogSearchResultsPage(logView, options), nextSavedSearchId = 0;
|
|
9637
12134
|
function nextSavedSearchIdValue() {
|
|
9638
12135
|
let id = "";
|
|
9639
12136
|
do
|
|
@@ -9641,7 +12138,7 @@ function useTLogSearchController(logView, options = {}) {
|
|
|
9641
12138
|
while (savedSearches.value.some((entry) => entry.id === id));
|
|
9642
12139
|
return id;
|
|
9643
12140
|
}
|
|
9644
|
-
let searchBarState = (0,
|
|
12141
|
+
let searchBarState = (0, import_vue30.computed)(() => ({
|
|
9645
12142
|
query: query.value,
|
|
9646
12143
|
mode: mode.value,
|
|
9647
12144
|
caseSensitive: caseSensitive.value,
|
|
@@ -9746,7 +12243,7 @@ function useTLogSearchController(logView, options = {}) {
|
|
|
9746
12243
|
regexFlags: entry.regexFlags || void 0
|
|
9747
12244
|
}));
|
|
9748
12245
|
}
|
|
9749
|
-
return (0,
|
|
12246
|
+
return (0, import_vue30.watch)(
|
|
9750
12247
|
() => logView.value,
|
|
9751
12248
|
() => {
|
|
9752
12249
|
refresh();
|
|
@@ -9783,13 +12280,13 @@ function useTLogSearchController(logView, options = {}) {
|
|
|
9783
12280
|
}
|
|
9784
12281
|
|
|
9785
12282
|
// src/vue/log/use-tlog-virtual-search-results.ts
|
|
9786
|
-
var
|
|
12283
|
+
var import_vue31 = require("vue");
|
|
9787
12284
|
function normalizeInt10(value, fallback = 0) {
|
|
9788
12285
|
let n = Math.floor(Number(value));
|
|
9789
12286
|
return Number.isFinite(n) ? n : fallback;
|
|
9790
12287
|
}
|
|
9791
12288
|
function useTLogVirtualSearchResults(logView, options = {}) {
|
|
9792
|
-
let state = (0,
|
|
12289
|
+
let state = (0, import_vue31.ref)({
|
|
9793
12290
|
itemCount: 0,
|
|
9794
12291
|
itemVersion: 0,
|
|
9795
12292
|
activeIndex: -1,
|
|
@@ -9848,7 +12345,7 @@ function useTLogVirtualSearchResults(logView, options = {}) {
|
|
|
9848
12345
|
let selected = handle.selectSearchMatch(normalizeInt10(matchIndex, -1));
|
|
9849
12346
|
return refresh(), selected;
|
|
9850
12347
|
}
|
|
9851
|
-
return (0,
|
|
12348
|
+
return (0, import_vue31.watch)(() => logView.value, refresh, { immediate: !0 }), {
|
|
9852
12349
|
state,
|
|
9853
12350
|
refresh,
|
|
9854
12351
|
getItem,
|
|
@@ -9857,7 +12354,7 @@ function useTLogVirtualSearchResults(logView, options = {}) {
|
|
|
9857
12354
|
}
|
|
9858
12355
|
|
|
9859
12356
|
// src/vue/log/use-tlog-retained-index.ts
|
|
9860
|
-
var
|
|
12357
|
+
var import_vue32 = require("vue");
|
|
9861
12358
|
var DEFAULT_BUDGET_MS = 4, DEFAULT_MAX_ITEMS = 1e4;
|
|
9862
12359
|
function clamp13(n, min, max) {
|
|
9863
12360
|
return Math.max(min, Math.min(max, n));
|
|
@@ -9874,7 +12371,7 @@ function sanitizeIndexedExternalHref(value, options = {}) {
|
|
|
9874
12371
|
return sanitizeTerminalHref(value, options);
|
|
9875
12372
|
}
|
|
9876
12373
|
function useTLogRetainedIndex(logView, source, version, options = {}) {
|
|
9877
|
-
let status = (0,
|
|
12374
|
+
let status = (0, import_vue32.ref)("idle"), links = (0, import_vue32.ref)([]), diagnostics = (0, import_vue32.ref)([]), density = (0, import_vue32.ref)([]), plugins = (0, import_vue32.computed)(() => {
|
|
9878
12375
|
let builtins = [];
|
|
9879
12376
|
return options.links && builtins.push(createTLogOsc8LinkPlugin()), options.urls && builtins.push(createTLogUrlPlugin({ allowFileUrls: options.allowFileUrls })), options.levels && builtins.push(createTLogLevelPlugin({ bucketCount: options.bucketCount })), [...builtins, ...options.plugins ?? []];
|
|
9880
12377
|
}), generation = 0, cursor = 0, rafHandle = null, indexedLines = [];
|
|
@@ -10004,7 +12501,7 @@ function useTLogRetainedIndex(logView, source, version, options = {}) {
|
|
|
10004
12501
|
function refresh() {
|
|
10005
12502
|
cancel(), indexedLines = [], links.value = [], diagnostics.value = [], density.value = [], cursor = 0, status.value = "indexing", schedule();
|
|
10006
12503
|
}
|
|
10007
|
-
return (0,
|
|
12504
|
+
return (0, import_vue32.watch)([() => source.value, () => version.value, () => logView.value], refresh, {
|
|
10008
12505
|
immediate: !0
|
|
10009
12506
|
}), {
|
|
10010
12507
|
status,
|
|
@@ -10017,7 +12514,7 @@ function useTLogRetainedIndex(logView, source, version, options = {}) {
|
|
|
10017
12514
|
}
|
|
10018
12515
|
|
|
10019
12516
|
// src/vue/log/tlog-session.ts
|
|
10020
|
-
var
|
|
12517
|
+
var import_vue33 = require("vue");
|
|
10021
12518
|
function clamp14(n, min, max) {
|
|
10022
12519
|
return Math.max(min, Math.min(max, n));
|
|
10023
12520
|
}
|
|
@@ -10035,7 +12532,7 @@ function deserializeTLogViewSessionState(value) {
|
|
|
10035
12532
|
}
|
|
10036
12533
|
}
|
|
10037
12534
|
function createTLogViewSessionStore(options = {}) {
|
|
10038
|
-
let storageKey = options.storageKey ?? "@simon_he/vue-tui:tlog-session", storage = options.storage ?? globalThis.localStorage ?? null, state = (0,
|
|
12535
|
+
let storageKey = options.storageKey ?? "@simon_he/vue-tui:tlog-session", storage = options.storage ?? globalThis.localStorage ?? null, state = (0, import_vue33.ref)(null);
|
|
10039
12536
|
function load() {
|
|
10040
12537
|
let next = deserializeTLogViewSessionState(storage?.getItem(storageKey));
|
|
10041
12538
|
return state.value = next, next;
|