@h-rig/cli 0.0.6-alpha.85 → 0.0.6-alpha.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/rig.js +79 -1027
- package/dist/src/app-opentui/bootstrap.js +79 -1027
- package/dist/src/app-opentui/command-palette.js +1 -0
- package/dist/src/app-opentui/drone.js +1 -0
- package/dist/src/app-opentui/index.js +61 -1024
- package/dist/src/app-opentui/list-search.d.ts +5 -1
- package/dist/src/app-opentui/list-search.js +2 -2
- package/dist/src/app-opentui/react/App.js +62 -970
- package/dist/src/app-opentui/react/Backdrop.js +3 -9
- package/dist/src/app-opentui/react/ChromeHost.js +6 -1038
- package/dist/src/app-opentui/react/SceneFrameView.js +55 -5
- package/dist/src/app-opentui/react/launch.js +62 -970
- package/dist/src/app-opentui/react/syntax.js +1 -0
- package/dist/src/app-opentui/registry.js +3 -5
- package/dist/src/app-opentui/render/constants.d.ts +0 -1
- package/dist/src/app-opentui/render/constants.js +0 -2
- package/dist/src/app-opentui/render/graphics.js +3 -9
- package/dist/src/app-opentui/render/hover.d.ts +11 -0
- package/dist/src/app-opentui/render/hover.js +34 -0
- package/dist/src/app-opentui/render/native-host.js +1 -0
- package/dist/src/app-opentui/render/panels.js +50 -3
- package/dist/src/app-opentui/render/preloader.js +1 -0
- package/dist/src/app-opentui/render/scene.js +1 -0
- package/dist/src/app-opentui/render/text.d.ts +13 -0
- package/dist/src/app-opentui/render/text.js +54 -5
- package/dist/src/app-opentui/render/type-bar.js +1 -0
- package/dist/src/app-opentui/runtime.js +62 -1025
- package/dist/src/app-opentui/scenes/command.js +1 -0
- package/dist/src/app-opentui/scenes/doctor.js +1 -0
- package/dist/src/app-opentui/scenes/error.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/agent.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/browser.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/dist.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/git.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/github.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/harness.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/index.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/kit.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/profile.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/queue.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/remote.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/review.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/setup.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/stats.js +1 -0
- package/dist/src/app-opentui/scenes/family.js +1 -0
- package/dist/src/app-opentui/scenes/fleet.js +3 -5
- package/dist/src/app-opentui/scenes/handoff.js +1 -0
- package/dist/src/app-opentui/scenes/help.js +1 -0
- package/dist/src/app-opentui/scenes/inbox.js +1 -0
- package/dist/src/app-opentui/scenes/init.js +1 -0
- package/dist/src/app-opentui/scenes/inspect.js +1 -0
- package/dist/src/app-opentui/scenes/main.js +1 -0
- package/dist/src/app-opentui/scenes/pi.js +1 -0
- package/dist/src/app-opentui/scenes/plugin.js +1 -0
- package/dist/src/app-opentui/scenes/repo.js +1 -0
- package/dist/src/app-opentui/scenes/run-detail.js +1 -0
- package/dist/src/app-opentui/scenes/server.js +1 -0
- package/dist/src/app-opentui/scenes/tasks.js +3 -5
- package/dist/src/app-opentui/scenes/workspace.js +1 -0
- package/dist/src/app-opentui/selectable.js +1 -0
- package/dist/src/app-opentui/theme.d.ts +1 -0
- package/dist/src/app-opentui/theme.js +1 -0
- package/package.json +8 -8
- package/dist/src/app-opentui/render/image-visual-layer-worker.d.ts +0 -1
- package/dist/src/app-opentui/render/image-visual-layer-worker.js +0 -1084
- package/dist/src/app-opentui/render/image-visual-layer.d.ts +0 -109
- package/dist/src/app-opentui/render/image-visual-layer.js +0 -1068
- package/dist/src/app-opentui/terminal-capabilities.d.ts +0 -7
- package/dist/src/app-opentui/terminal-capabilities.js +0 -15
package/dist/bin/rig.js
CHANGED
|
@@ -17453,6 +17453,7 @@ var init_theme2 = __esm(() => {
|
|
|
17453
17453
|
bg2: "#0b0c0e",
|
|
17454
17454
|
panel: "#101115",
|
|
17455
17455
|
panel2: "#14161b",
|
|
17456
|
+
hover: "#181b24",
|
|
17456
17457
|
glass: "#1e2230",
|
|
17457
17458
|
border: "#2a2e3a",
|
|
17458
17459
|
ink: "#f4f5f8",
|
|
@@ -19802,11 +19803,8 @@ var init_family2 = __esm(() => {
|
|
|
19802
19803
|
});
|
|
19803
19804
|
|
|
19804
19805
|
// packages/cli/src/app-opentui/list-search.ts
|
|
19805
|
-
function
|
|
19806
|
-
return
|
|
19807
|
-
}
|
|
19808
|
-
function listSearchQuery(state) {
|
|
19809
|
-
return isListSearchScene(state.scene) ? state.typeBar.value.trim() : "";
|
|
19806
|
+
function listSearchQuery(_state) {
|
|
19807
|
+
return "";
|
|
19810
19808
|
}
|
|
19811
19809
|
function valueText(value) {
|
|
19812
19810
|
if (value === undefined || value === null)
|
|
@@ -24321,22 +24319,9 @@ function panelContentRect(layout, panel) {
|
|
|
24321
24319
|
const contentWidth = Math.max(1, width - paddingX * 2 - 1);
|
|
24322
24320
|
return { left, top, width, height, paddingX, paddingY, contentWidth };
|
|
24323
24321
|
}
|
|
24324
|
-
function panelPixelPlacement(layout, panel, size, minPixels = 8) {
|
|
24325
|
-
const cellW = size.width / layout.width;
|
|
24326
|
-
const cellH = size.height / layout.height;
|
|
24327
|
-
const leftCells = layout.centerLeft + (panel.left ?? 0);
|
|
24328
|
-
const topCells = layout.centerTop + panel.top;
|
|
24329
|
-
const widthCells = panel.width ?? layout.centerWidth;
|
|
24330
|
-
const heightCells = panel.height;
|
|
24331
|
-
const left = Math.round(leftCells * cellW);
|
|
24332
|
-
const top = Math.round(topCells * cellH);
|
|
24333
|
-
const width = Math.round(widthCells * cellW);
|
|
24334
|
-
const height = Math.round(heightCells * cellH);
|
|
24335
|
-
return width > minPixels && height > minPixels ? { left, top, width, height, leftCells, topCells, widthCells, heightCells } : null;
|
|
24336
|
-
}
|
|
24337
24322
|
|
|
24338
24323
|
// packages/cli/src/app-opentui/render/constants.ts
|
|
24339
|
-
var LCG_MULTIPLIER = 1664525, LCG_INCREMENT = 1013904223, LCG_DIVISOR = 4294967295, PACKET_CYAN_PROBABILITY = 0.22, LANE_INTERP_STEPS = 32, LANE_LEN_BASE = 0.32, LANE_LEN_SPREAD = 0.42, LANE_CURVE_RANGE = 0.7, PACKET_SPEED_BASE = 0.003, PACKET_SPEED_SPREAD = 0.009, DISPATCH_LANES_COMPACT = 7, DISPATCH_LANES_WIDE = 12, DISPATCH_PACKETS_COMPACT = 70, DISPATCH_PACKETS_WIDE = 150, CARRIER_NODES_COMPACT = 5, CARRIER_NODES_WIDE = 7, LOOP_GATES_COMPACT = 4, LOOP_GATES_WIDE = 5, DISPATCH_DRONES_COMPACT = 4, DISPATCH_DRONES_WIDE = 8, CORE_DISPATCH_X = 0.3, CORE_DISPATCH_Y = 0.45, CORE_CARRIER_X = 0.5, CORE_CARRIER_Y = 0.54, CORE_LOOP_X = 0.09, CORE_LOOP_Y = 0.56, RAIL_YS_LOOP, RAIL_YS_CARRIER, RAIL_YS_DISPATCH, GLOW_FALLOFF_EXP_ASCII = 2.2
|
|
24324
|
+
var LCG_MULTIPLIER = 1664525, LCG_INCREMENT = 1013904223, LCG_DIVISOR = 4294967295, PACKET_CYAN_PROBABILITY = 0.22, LANE_INTERP_STEPS = 32, LANE_LEN_BASE = 0.32, LANE_LEN_SPREAD = 0.42, LANE_CURVE_RANGE = 0.7, PACKET_SPEED_BASE = 0.003, PACKET_SPEED_SPREAD = 0.009, DISPATCH_LANES_COMPACT = 7, DISPATCH_LANES_WIDE = 12, DISPATCH_PACKETS_COMPACT = 70, DISPATCH_PACKETS_WIDE = 150, CARRIER_NODES_COMPACT = 5, CARRIER_NODES_WIDE = 7, LOOP_GATES_COMPACT = 4, LOOP_GATES_WIDE = 5, DISPATCH_DRONES_COMPACT = 4, DISPATCH_DRONES_WIDE = 8, CORE_DISPATCH_X = 0.3, CORE_DISPATCH_Y = 0.45, CORE_CARRIER_X = 0.5, CORE_CARRIER_Y = 0.54, CORE_LOOP_X = 0.09, CORE_LOOP_Y = 0.56, RAIL_YS_LOOP, RAIL_YS_CARRIER, RAIL_YS_DISPATCH, GLOW_FALLOFF_EXP_ASCII = 2.2;
|
|
24340
24325
|
var init_constants = __esm(() => {
|
|
24341
24326
|
RAIL_YS_LOOP = [0.18, 0.5, 0.82];
|
|
24342
24327
|
RAIL_YS_CARRIER = [0.24, 0.54, 0.82];
|
|
@@ -24755,27 +24740,20 @@ function writeCell(layer, x, y, char, fg2, bg) {
|
|
|
24755
24740
|
function drawFullCell(layer, x, y, bg) {
|
|
24756
24741
|
writeCell(layer, x, y, " ", TRANSPARENT, bg);
|
|
24757
24742
|
}
|
|
24758
|
-
function
|
|
24759
|
-
writeCell(layer, x, y, char, fg2, BACKDROP);
|
|
24760
|
-
}
|
|
24761
|
-
function drawRoundedFill(layer, left, top, right, bottom, dividerY) {
|
|
24743
|
+
function drawPanelFill(layer, left, top, right, bottom, dividerY) {
|
|
24762
24744
|
const bgForY = (y) => y < dividerY ? PANEL_HEADER_BG : PANEL_BG;
|
|
24763
24745
|
for (let y = top;y <= bottom; y += 1) {
|
|
24764
24746
|
const bg = bgForY(y);
|
|
24765
24747
|
for (let x = left;x <= right; x += 1)
|
|
24766
24748
|
drawFullCell(layer, x, y, bg);
|
|
24767
24749
|
}
|
|
24768
|
-
drawCornerCut(layer, left, top, "\u2597", PANEL_HEADER_BG);
|
|
24769
|
-
drawCornerCut(layer, right, top, "\u2596", PANEL_HEADER_BG);
|
|
24770
|
-
drawCornerCut(layer, left, bottom, "\u259D", PANEL_BG);
|
|
24771
|
-
drawCornerCut(layer, right, bottom, "\u2598", PANEL_BG);
|
|
24772
24750
|
}
|
|
24773
24751
|
function drawAdTerminalPanel(layer, layout, panel) {
|
|
24774
24752
|
const rect = panelCellRect(layout, panel);
|
|
24775
24753
|
if (!rect)
|
|
24776
24754
|
return;
|
|
24777
24755
|
const { left, top, width, right, bottom, headerHeight, dividerY } = rect;
|
|
24778
|
-
|
|
24756
|
+
drawPanelFill(layer, left, top, right, bottom, dividerY);
|
|
24779
24757
|
if (dividerY > top && dividerY < bottom) {
|
|
24780
24758
|
for (let x = left + 2;x < right - 1; x += 1) {
|
|
24781
24759
|
writeCell(layer, x, dividerY, "\u2500", PANEL_LINE_DIM, PANEL_BG);
|
|
@@ -24883,973 +24861,69 @@ var init_graphics = __esm(() => {
|
|
|
24883
24861
|
];
|
|
24884
24862
|
});
|
|
24885
24863
|
|
|
24886
|
-
// packages/cli/src/app-opentui/
|
|
24887
|
-
|
|
24888
|
-
|
|
24889
|
-
const imageProtocol = getCapabilities().images;
|
|
24890
|
-
const supportsKittyImages = imageProtocol === "kitty";
|
|
24891
|
-
return {
|
|
24892
|
-
imageProtocol,
|
|
24893
|
-
supportsKittyImages,
|
|
24894
|
-
visualMode: supportsKittyImages ? "kitty-images" : "framebuffer-fallback"
|
|
24895
|
-
};
|
|
24896
|
-
}
|
|
24897
|
-
var init_terminal_capabilities = () => {};
|
|
24898
|
-
|
|
24899
|
-
// packages/cli/src/app-opentui/render/image-visual-layer.ts
|
|
24900
|
-
import { Worker } from "worker_threads";
|
|
24901
|
-
import { deflateSync } from "zlib";
|
|
24902
|
-
import { allocateImageId, deleteKittyImage } from "@earendil-works/pi-tui";
|
|
24903
|
-
function loadBucket(load) {
|
|
24904
|
-
if (!Number.isFinite(load ?? NaN))
|
|
24905
|
-
return 0;
|
|
24906
|
-
return Math.max(0, Math.min(LOAD_BUCKETS, Math.round((load ?? 0) * LOAD_BUCKETS)));
|
|
24907
|
-
}
|
|
24908
|
-
function imageTransport() {
|
|
24909
|
-
const forced = process.env.RIG_OPENTUI_IMAGE_TRANSPORT;
|
|
24910
|
-
if (forced === "rgba-zlib")
|
|
24911
|
-
return "rgba-zlib";
|
|
24912
|
-
return "png";
|
|
24913
|
-
}
|
|
24914
|
-
function imageResolutionScale() {
|
|
24915
|
-
const raw = Number.parseFloat(process.env.RIG_OPENTUI_IMAGE_SCALE ?? "");
|
|
24916
|
-
if (Number.isFinite(raw) && raw > 0)
|
|
24917
|
-
return Math.max(0.25, Math.min(1, raw));
|
|
24918
|
-
return DEFAULT_IMAGE_RESOLUTION_SCALE;
|
|
24919
|
-
}
|
|
24920
|
-
function rgbaWord(color) {
|
|
24921
|
-
return (color[3] << 24 | color[2] << 16 | color[1] << 8 | color[0]) >>> 0;
|
|
24922
|
-
}
|
|
24923
|
-
function fillRgba(data, color, word = rgbaWord(color)) {
|
|
24924
|
-
if (data.byteOffset % 4 === 0 && data.byteLength % 4 === 0) {
|
|
24925
|
-
new Uint32Array(data.buffer, data.byteOffset, data.byteLength / 4).fill(word);
|
|
24926
|
-
return;
|
|
24927
|
-
}
|
|
24928
|
-
for (let i = 0;i < data.length; i += 4) {
|
|
24929
|
-
data[i] = color[0];
|
|
24930
|
-
data[i + 1] = color[1];
|
|
24931
|
-
data[i + 2] = color[2];
|
|
24932
|
-
data[i + 3] = color[3];
|
|
24933
|
-
}
|
|
24934
|
-
}
|
|
24935
|
-
function sceneStaticTick(scene) {
|
|
24936
|
-
let hash = 0;
|
|
24937
|
-
for (let index = 0;index < scene.length; index += 1)
|
|
24938
|
-
hash = hash * 33 + scene.charCodeAt(index) >>> 0;
|
|
24939
|
-
return 11 + hash % 97;
|
|
24940
|
-
}
|
|
24941
|
-
function charColor(char, row, totalRows) {
|
|
24942
|
-
if (char === "@" || char === "$" || char === "o")
|
|
24943
|
-
return LIME;
|
|
24944
|
-
if (char === "%" || char === "!" || char === "/" || char === "\\" || char === "|")
|
|
24945
|
-
return CYAN;
|
|
24946
|
-
if (char === "." || char === "'" || char === "_" || row < 3 || row > totalRows - 4)
|
|
24947
|
-
return INK_DIM;
|
|
24948
|
-
if (char === "-" || char === "=" || char === "(" || char === ")")
|
|
24949
|
-
return LIME_DIM;
|
|
24950
|
-
return MAGENTA;
|
|
24951
|
-
}
|
|
24952
|
-
function fillRectAlpha(data, width, height, left, top, rectWidth, rectHeight, color, alpha) {
|
|
24953
|
-
const x0 = Math.max(0, Math.floor(left));
|
|
24954
|
-
const y0 = Math.max(0, Math.floor(top));
|
|
24955
|
-
const x1 = Math.min(width, Math.ceil(left + rectWidth));
|
|
24956
|
-
const y1 = Math.min(height, Math.ceil(top + rectHeight));
|
|
24957
|
-
for (let y = y0;y < y1; y += 1) {
|
|
24958
|
-
for (let x = x0;x < x1; x += 1)
|
|
24959
|
-
blendOver(data, (y * width + x) * 4, color, alpha);
|
|
24960
|
-
}
|
|
24961
|
-
}
|
|
24962
|
-
function drawAsciiGlyph(data, width, height, x, y, cellWidth, cellHeight, char, color, alpha) {
|
|
24963
|
-
const pattern = ASCII_GLYPHS[char] ?? ASCII_GLYPHS["*"];
|
|
24964
|
-
const glyphWidth = Math.max(1, cellWidth * 0.56);
|
|
24965
|
-
const glyphHeight = Math.max(1, cellHeight * 0.7);
|
|
24966
|
-
const originX = x + (cellWidth - glyphWidth) * 0.5;
|
|
24967
|
-
const originY = y + (cellHeight - glyphHeight) * 0.5;
|
|
24968
|
-
const pixelWidth = Math.max(1, glyphWidth / pattern[0].length);
|
|
24969
|
-
const pixelHeight = Math.max(1, glyphHeight / pattern.length);
|
|
24970
|
-
for (let row = 0;row < pattern.length; row += 1) {
|
|
24971
|
-
const bits = pattern[row];
|
|
24972
|
-
for (let col = 0;col < bits.length; col += 1) {
|
|
24973
|
-
if (bits[col] !== "1")
|
|
24974
|
-
continue;
|
|
24975
|
-
fillRectAlpha(data, width, height, originX + col * pixelWidth, originY + row * pixelHeight, pixelWidth * 0.72, pixelHeight * 0.72, color, alpha);
|
|
24976
|
-
}
|
|
24977
|
-
}
|
|
24978
|
-
}
|
|
24979
|
-
function drawStaticAsciiFleetBackground(data, width, height, scene, layout, load, activeRuns) {
|
|
24980
|
-
const rows = fleetRows(sceneStaticTick(scene), { animate: true });
|
|
24981
|
-
const cellWidth = width / Math.max(1, layout.width);
|
|
24982
|
-
const cellHeight = height / Math.max(1, layout.height);
|
|
24983
|
-
const sideBySide = layout.width >= FLEET_GRID_WIDTH * 1.9;
|
|
24984
|
-
const leftCells = sideBySide ? Math.max(1, Math.floor(layout.width * 0.3 - FLEET_GRID_WIDTH / 2)) : Math.floor((layout.width - FLEET_GRID_WIDTH) / 2);
|
|
24985
|
-
const topCells = Math.floor((layout.height - FLEET_GRID_HEIGHT) / 2);
|
|
24986
|
-
const fleetLeft = leftCells * cellWidth;
|
|
24987
|
-
const fleetTop = topCells * cellHeight;
|
|
24988
|
-
drawGlow2(data, width, height, width * 0.5, height * 0.5, Math.min(width, height) * 0.4, LIME, 0.022 + load * 0.03);
|
|
24989
|
-
drawGlow2(data, width, height, width * 0.18, height * 0.22, Math.min(width, height) * 0.28, CYAN, 0.018 + load * 0.012);
|
|
24990
|
-
drawGlow2(data, width, height, width * 0.82, height * 0.78, Math.min(width, height) * 0.22, MAGENTA, 0.012 + load * 0.008);
|
|
24991
|
-
let droneTotal = 0;
|
|
24992
|
-
for (const line2 of rows)
|
|
24993
|
-
for (const char of line2)
|
|
24994
|
-
if (char === "@" || char === "$" || char === "%")
|
|
24995
|
-
droneTotal += 1;
|
|
24996
|
-
const litTarget = Math.max(0, Math.min(droneTotal, activeRuns));
|
|
24997
|
-
let droneIndex = 0;
|
|
24998
|
-
for (let row = 0;row < rows.length; row += 1) {
|
|
24999
|
-
const line2 = rows[row];
|
|
25000
|
-
for (let col = 0;col < line2.length; col += 1) {
|
|
25001
|
-
const char = line2[col];
|
|
25002
|
-
if (char === " ")
|
|
25003
|
-
continue;
|
|
25004
|
-
const x = fleetLeft + col * cellWidth;
|
|
25005
|
-
const y = fleetTop + row * cellHeight;
|
|
25006
|
-
const color = charColor(char, row, rows.length);
|
|
25007
|
-
const isDrone = char === "@" || char === "$" || char === "%";
|
|
25008
|
-
const lit = isDrone && droneIndex < litTarget;
|
|
25009
|
-
drawAsciiGlyph(data, width, height, x + cellWidth * 0.07, y + cellHeight * 0.05, cellWidth, cellHeight, char, color, lit ? 0.72 : 0.46);
|
|
25010
|
-
if (isDrone) {
|
|
25011
|
-
droneIndex += 1;
|
|
25012
|
-
drawGlow2(data, width, height, x + cellWidth * 0.5, y + cellHeight * 0.5, Math.max(cellWidth, cellHeight) * 0.95, color, lit ? 0.044 : 0.014);
|
|
25013
|
-
}
|
|
25014
|
-
}
|
|
25015
|
-
}
|
|
25016
|
-
}
|
|
25017
|
-
function applyStaticAtmosphere(data, width, height, load) {
|
|
25018
|
-
const cx = width * 0.5;
|
|
25019
|
-
const cy = height * 0.42;
|
|
25020
|
-
const radius = Math.max(width, height) * 0.78;
|
|
25021
|
-
const minVignette = 0.1 - load * 0.02;
|
|
25022
|
-
for (let y = 0;y < height; y += 1) {
|
|
25023
|
-
for (let x = 0;x < width; x += 1) {
|
|
25024
|
-
const distance = Math.hypot(x - cx, y - cy) / radius;
|
|
25025
|
-
const alpha = Math.max(minVignette, Math.min(0.82, 0.12 + Math.pow(distance, 1.65) * 0.62));
|
|
25026
|
-
blendOver(data, (y * width + x) * 4, BG, alpha);
|
|
25027
|
-
}
|
|
25028
|
-
}
|
|
25029
|
-
drawGlow2(data, width, height, width * 0.82, height * 0.04, Math.min(width, height) * 0.2, LIME, 0.024 + load * 0.012);
|
|
25030
|
-
drawGlow2(data, width, height, width * 0.12, height * 0.18, Math.min(width, height) * 0.16, CYAN, 0.018 + load * 0.008);
|
|
25031
|
-
}
|
|
25032
|
-
function makeCrcTable() {
|
|
25033
|
-
const table = new Uint32Array(256);
|
|
25034
|
-
for (let n = 0;n < 256; n += 1) {
|
|
25035
|
-
let c = n;
|
|
25036
|
-
for (let k = 0;k < 8; k += 1)
|
|
25037
|
-
c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
|
|
25038
|
-
table[n] = c >>> 0;
|
|
25039
|
-
}
|
|
25040
|
-
return table;
|
|
25041
|
-
}
|
|
25042
|
-
function crc32(bytes) {
|
|
25043
|
-
let c = 4294967295;
|
|
25044
|
-
for (let i = 0;i < bytes.length; i += 1)
|
|
25045
|
-
c = CRC_TABLE[(c ^ bytes[i]) & 255] ^ c >>> 8;
|
|
25046
|
-
return (c ^ 4294967295) >>> 0;
|
|
25047
|
-
}
|
|
25048
|
-
function chunk2(type, data) {
|
|
25049
|
-
const out = new Uint8Array(12 + data.length);
|
|
25050
|
-
const view = new DataView(out.buffer);
|
|
25051
|
-
view.setUint32(0, data.length);
|
|
25052
|
-
out[4] = type.charCodeAt(0);
|
|
25053
|
-
out[5] = type.charCodeAt(1);
|
|
25054
|
-
out[6] = type.charCodeAt(2);
|
|
25055
|
-
out[7] = type.charCodeAt(3);
|
|
25056
|
-
out.set(data, 8);
|
|
25057
|
-
view.setUint32(8 + data.length, crc32(out.subarray(4, 8 + data.length)));
|
|
25058
|
-
return out;
|
|
24864
|
+
// packages/cli/src/app-opentui/render/hover.ts
|
|
24865
|
+
function getHoveredSelectableId() {
|
|
24866
|
+
return hoveredId;
|
|
25059
24867
|
}
|
|
25060
|
-
function
|
|
25061
|
-
|
|
25062
|
-
const ihdrView = new DataView(ihdr.buffer);
|
|
25063
|
-
ihdrView.setUint32(0, width);
|
|
25064
|
-
ihdrView.setUint32(4, height);
|
|
25065
|
-
ihdr[8] = 8;
|
|
25066
|
-
ihdr[9] = 6;
|
|
25067
|
-
ihdr[10] = 0;
|
|
25068
|
-
ihdr[11] = 0;
|
|
25069
|
-
ihdr[12] = 0;
|
|
25070
|
-
const stride = width * 4;
|
|
25071
|
-
const raw = new Uint8Array((stride + 1) * height);
|
|
25072
|
-
for (let y = 0;y < height; y += 1) {
|
|
25073
|
-
const rawOffset = y * (stride + 1);
|
|
25074
|
-
raw[rawOffset] = 0;
|
|
25075
|
-
raw.set(rgba.subarray(y * stride, y * stride + stride), rawOffset + 1);
|
|
25076
|
-
}
|
|
25077
|
-
const compressed = deflateSync(raw, { level: ZLIB_LEVEL });
|
|
25078
|
-
return Buffer.concat([
|
|
25079
|
-
Buffer.from(PNG_SIGNATURE),
|
|
25080
|
-
Buffer.from(chunk2("IHDR", ihdr)),
|
|
25081
|
-
Buffer.from(chunk2("IDAT", compressed)),
|
|
25082
|
-
Buffer.from(chunk2("IEND", new Uint8Array(0)))
|
|
25083
|
-
]);
|
|
24868
|
+
function isHovered(id) {
|
|
24869
|
+
return id !== undefined && id === hoveredId;
|
|
25084
24870
|
}
|
|
25085
|
-
function
|
|
25086
|
-
|
|
25087
|
-
if (options.format === 32) {
|
|
25088
|
-
params.push(`s=${options.pixelWidth ?? 1}`, `v=${options.pixelHeight ?? 1}`);
|
|
25089
|
-
if (options.compressed)
|
|
25090
|
-
params.push("o=z");
|
|
25091
|
-
}
|
|
25092
|
-
if (base64.length <= KITTY_CHUNK_SIZE)
|
|
25093
|
-
return `\x1B_G${params.join(",")};${base64}\x1B\\`;
|
|
25094
|
-
const chunks = [];
|
|
25095
|
-
for (let offset = 0;offset < base64.length; offset += KITTY_CHUNK_SIZE) {
|
|
25096
|
-
const part = base64.slice(offset, offset + KITTY_CHUNK_SIZE);
|
|
25097
|
-
const last = offset + KITTY_CHUNK_SIZE >= base64.length;
|
|
25098
|
-
chunks.push(`\x1B_G${offset === 0 ? `${params.join(",")},` : ""}m=${last ? 0 : 1};${part}\x1B\\`);
|
|
25099
|
-
}
|
|
25100
|
-
return chunks.join("");
|
|
25101
|
-
}
|
|
25102
|
-
function clampByte(value) {
|
|
25103
|
-
return Math.max(0, Math.min(255, Math.round(value)));
|
|
25104
|
-
}
|
|
25105
|
-
function blendOver(data, index, color, alphaScale = 1) {
|
|
25106
|
-
const alpha = color[3] / 255 * alphaScale;
|
|
25107
|
-
const inv = 1 - alpha;
|
|
25108
|
-
data[index] = clampByte(color[0] * alpha + data[index] * inv);
|
|
25109
|
-
data[index + 1] = clampByte(color[1] * alpha + data[index + 1] * inv);
|
|
25110
|
-
data[index + 2] = clampByte(color[2] * alpha + data[index + 2] * inv);
|
|
25111
|
-
data[index + 3] = 255;
|
|
25112
|
-
}
|
|
25113
|
-
function drawDisc(data, width, height, cx, cy, radius, color, alpha = 1) {
|
|
25114
|
-
const minX = Math.max(0, Math.floor(cx - radius));
|
|
25115
|
-
const maxX = Math.min(width - 1, Math.ceil(cx + radius));
|
|
25116
|
-
const minY = Math.max(0, Math.floor(cy - radius));
|
|
25117
|
-
const maxY = Math.min(height - 1, Math.ceil(cy + radius));
|
|
25118
|
-
for (let y = minY;y <= maxY; y += 1) {
|
|
25119
|
-
for (let x = minX;x <= maxX; x += 1) {
|
|
25120
|
-
const dx = x + 0.5 - cx;
|
|
25121
|
-
const dy = y + 0.5 - cy;
|
|
25122
|
-
const d = Math.sqrt(dx * dx + dy * dy);
|
|
25123
|
-
if (d > radius)
|
|
25124
|
-
continue;
|
|
25125
|
-
const edge = Math.max(0, Math.min(1, radius - d));
|
|
25126
|
-
blendOver(data, (y * width + x) * 4, color, alpha * Math.min(1, 0.35 + edge));
|
|
25127
|
-
}
|
|
25128
|
-
}
|
|
25129
|
-
}
|
|
25130
|
-
function drawGlow2(data, width, height, cx, cy, radius, color, alpha = 0.18) {
|
|
25131
|
-
const minX = Math.max(0, Math.floor(cx - radius));
|
|
25132
|
-
const maxX = Math.min(width - 1, Math.ceil(cx + radius));
|
|
25133
|
-
const minY = Math.max(0, Math.floor(cy - radius));
|
|
25134
|
-
const maxY = Math.min(height - 1, Math.ceil(cy + radius));
|
|
25135
|
-
for (let y = minY;y <= maxY; y += 1) {
|
|
25136
|
-
for (let x = minX;x <= maxX; x += 1) {
|
|
25137
|
-
const dx = x + 0.5 - cx;
|
|
25138
|
-
const dy = y + 0.5 - cy;
|
|
25139
|
-
const d = Math.sqrt(dx * dx + dy * dy);
|
|
25140
|
-
if (d > radius)
|
|
25141
|
-
continue;
|
|
25142
|
-
const falloff = Math.pow(1 - d / Math.max(1, radius), GLOW_FALLOFF_EXP_IMAGE);
|
|
25143
|
-
blendOver(data, (y * width + x) * 4, color, alpha * falloff);
|
|
25144
|
-
}
|
|
25145
|
-
}
|
|
25146
|
-
}
|
|
25147
|
-
function drawLine2(data, width, height, x0, y0, x1, y1, color, alpha = 0.5, thickness = 1.4) {
|
|
25148
|
-
const dx = x1 - x0;
|
|
25149
|
-
const dy = y1 - y0;
|
|
25150
|
-
const steps = Math.max(1, Math.ceil(Math.hypot(dx, dy) * 1.2));
|
|
25151
|
-
for (let i = 0;i <= steps; i += 1) {
|
|
25152
|
-
const t2 = i / steps;
|
|
25153
|
-
drawDisc(data, width, height, x0 + dx * t2, y0 + dy * t2, thickness, color, alpha);
|
|
25154
|
-
}
|
|
25155
|
-
}
|
|
25156
|
-
function roundRectAlpha(px, py, x, y, w, h, r) {
|
|
25157
|
-
const rx = Math.max(x + r, Math.min(px, x + w - r));
|
|
25158
|
-
const ry = Math.max(y + r, Math.min(py, y + h - r));
|
|
25159
|
-
const dx = px - rx;
|
|
25160
|
-
const dy = py - ry;
|
|
25161
|
-
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
25162
|
-
return Math.max(0, Math.min(1, r + 0.75 - dist));
|
|
25163
|
-
}
|
|
25164
|
-
function panelRect(layout, panel, size) {
|
|
25165
|
-
return panelPixelPlacement(layout, panel, size);
|
|
25166
|
-
}
|
|
25167
|
-
function downsampleRegion(data, canvasW, canvasH, rect, scale) {
|
|
25168
|
-
const w = Math.max(1, Math.ceil(rect.width / scale));
|
|
25169
|
-
const h = Math.max(1, Math.ceil(rect.height / scale));
|
|
25170
|
-
const out = new Uint8ClampedArray(w * h * 3);
|
|
25171
|
-
for (let y = 0;y < h; y += 1) {
|
|
25172
|
-
for (let x = 0;x < w; x += 1) {
|
|
25173
|
-
let r = 0, g = 0, b = 0, count = 0;
|
|
25174
|
-
const sx0 = rect.left + x * scale;
|
|
25175
|
-
const sy0 = rect.top + y * scale;
|
|
25176
|
-
for (let yy = 0;yy < scale; yy += 1) {
|
|
25177
|
-
const sy = sy0 + yy;
|
|
25178
|
-
if (sy < 0 || sy >= canvasH)
|
|
25179
|
-
continue;
|
|
25180
|
-
for (let xx = 0;xx < scale; xx += 1) {
|
|
25181
|
-
const sx = sx0 + xx;
|
|
25182
|
-
if (sx < 0 || sx >= canvasW)
|
|
25183
|
-
continue;
|
|
25184
|
-
const i = (sy * canvasW + sx) * 4;
|
|
25185
|
-
r += data[i];
|
|
25186
|
-
g += data[i + 1];
|
|
25187
|
-
b += data[i + 2];
|
|
25188
|
-
count += 1;
|
|
25189
|
-
}
|
|
25190
|
-
}
|
|
25191
|
-
const oi = (y * w + x) * 3;
|
|
25192
|
-
out[oi] = count ? r / count : BG[0];
|
|
25193
|
-
out[oi + 1] = count ? g / count : BG[1];
|
|
25194
|
-
out[oi + 2] = count ? b / count : BG[2];
|
|
25195
|
-
}
|
|
25196
|
-
}
|
|
25197
|
-
return { pixels: out, width: w, height: h };
|
|
25198
|
-
}
|
|
25199
|
-
function blurRgb(buffer, width, height, radius) {
|
|
25200
|
-
const tmp = new Uint8ClampedArray(buffer.length);
|
|
25201
|
-
const out = new Uint8ClampedArray(buffer.length);
|
|
25202
|
-
const window = radius * 2 + 1;
|
|
25203
|
-
for (let y = 0;y < height; y += 1) {
|
|
25204
|
-
let r = 0, g = 0, b = 0;
|
|
25205
|
-
for (let x = -radius;x <= radius; x += 1) {
|
|
25206
|
-
const sx = Math.max(0, Math.min(width - 1, x));
|
|
25207
|
-
const i = (y * width + sx) * 3;
|
|
25208
|
-
r += buffer[i];
|
|
25209
|
-
g += buffer[i + 1];
|
|
25210
|
-
b += buffer[i + 2];
|
|
25211
|
-
}
|
|
25212
|
-
for (let x = 0;x < width; x += 1) {
|
|
25213
|
-
const oi = (y * width + x) * 3;
|
|
25214
|
-
tmp[oi] = r / window;
|
|
25215
|
-
tmp[oi + 1] = g / window;
|
|
25216
|
-
tmp[oi + 2] = b / window;
|
|
25217
|
-
const removeX = Math.max(0, x - radius);
|
|
25218
|
-
const addX = Math.min(width - 1, x + radius + 1);
|
|
25219
|
-
const ri = (y * width + removeX) * 3;
|
|
25220
|
-
const ai = (y * width + addX) * 3;
|
|
25221
|
-
r += tmp.length ? buffer[ai] - buffer[ri] : 0;
|
|
25222
|
-
g += tmp.length ? buffer[ai + 1] - buffer[ri + 1] : 0;
|
|
25223
|
-
b += tmp.length ? buffer[ai + 2] - buffer[ri + 2] : 0;
|
|
25224
|
-
}
|
|
25225
|
-
}
|
|
25226
|
-
for (let x = 0;x < width; x += 1) {
|
|
25227
|
-
let r = 0, g = 0, b = 0;
|
|
25228
|
-
for (let y = -radius;y <= radius; y += 1) {
|
|
25229
|
-
const sy = Math.max(0, Math.min(height - 1, y));
|
|
25230
|
-
const i = (sy * width + x) * 3;
|
|
25231
|
-
r += tmp[i];
|
|
25232
|
-
g += tmp[i + 1];
|
|
25233
|
-
b += tmp[i + 2];
|
|
25234
|
-
}
|
|
25235
|
-
for (let y = 0;y < height; y += 1) {
|
|
25236
|
-
const oi = (y * width + x) * 3;
|
|
25237
|
-
out[oi] = r / window;
|
|
25238
|
-
out[oi + 1] = g / window;
|
|
25239
|
-
out[oi + 2] = b / window;
|
|
25240
|
-
const removeY = Math.max(0, y - radius);
|
|
25241
|
-
const addY = Math.min(height - 1, y + radius + 1);
|
|
25242
|
-
const ri = (removeY * width + x) * 3;
|
|
25243
|
-
const ai = (addY * width + x) * 3;
|
|
25244
|
-
r += tmp[ai] - tmp[ri];
|
|
25245
|
-
g += tmp[ai + 1] - tmp[ri + 1];
|
|
25246
|
-
b += tmp[ai + 2] - tmp[ri + 2];
|
|
25247
|
-
}
|
|
25248
|
-
}
|
|
25249
|
-
return out;
|
|
25250
|
-
}
|
|
25251
|
-
function panelMaskKey(width, height, rect, headerPx, blurScale) {
|
|
25252
|
-
return `${width}x${height}:${rect.left},${rect.top},${rect.width},${rect.height}:${Math.round(headerPx * 100) / 100}:${blurScale}`;
|
|
25253
|
-
}
|
|
25254
|
-
function getPanelMask(width, height, rect, headerPx, blurScale) {
|
|
25255
|
-
const key = panelMaskKey(width, height, rect, headerPx, blurScale);
|
|
25256
|
-
const cached = panelMaskCache.get(key);
|
|
25257
|
-
if (cached)
|
|
25258
|
-
return cached;
|
|
25259
|
-
const radius = Math.max(PANEL_MASK_RADIUS_MIN, Math.min(PANEL_MASK_RADIUS_MAX, Math.round(Math.min(rect.width, rect.height) * PANEL_MASK_RADIUS_FACTOR)));
|
|
25260
|
-
const sampledWidth = Math.max(1, Math.ceil(rect.width / blurScale));
|
|
25261
|
-
const sampledHeight = Math.max(1, Math.ceil(rect.height / blurScale));
|
|
25262
|
-
const x0 = Math.max(0, rect.left);
|
|
25263
|
-
const y0 = Math.max(0, rect.top);
|
|
25264
|
-
const x1 = Math.min(width - 1, rect.left + rect.width - 1);
|
|
25265
|
-
const y1 = Math.min(height - 1, rect.top + rect.height - 1);
|
|
25266
|
-
const indices = [];
|
|
25267
|
-
const sampleIndices = [];
|
|
25268
|
-
const panelAlpha = [];
|
|
25269
|
-
const edgeAlpha = [];
|
|
25270
|
-
const headerFlags = [];
|
|
25271
|
-
const dividerIndices = [];
|
|
25272
|
-
for (let y = y0;y <= y1; y += 1) {
|
|
25273
|
-
for (let x = x0;x <= x1; x += 1) {
|
|
25274
|
-
const a = roundRectAlpha(x + 0.5, y + 0.5, rect.left, rect.top, rect.width, rect.height, radius);
|
|
25275
|
-
if (a <= 0)
|
|
25276
|
-
continue;
|
|
25277
|
-
const edge = roundRectAlpha(x + 0.5, y + 0.5, rect.left + 1.2, rect.top + 1.2, rect.width - 2.4, rect.height - 2.4, Math.max(1, radius - 1.2));
|
|
25278
|
-
const sx = Math.max(0, Math.min(sampledWidth - 1, Math.floor((x - rect.left) / blurScale)));
|
|
25279
|
-
const sy = Math.max(0, Math.min(sampledHeight - 1, Math.floor((y - rect.top) / blurScale)));
|
|
25280
|
-
indices.push((y * width + x) * 4);
|
|
25281
|
-
sampleIndices.push((sy * sampledWidth + sx) * 3);
|
|
25282
|
-
panelAlpha.push(a);
|
|
25283
|
-
edgeAlpha.push(edge < 0.96 ? Math.min(1, (1 - edge) * 0.7) : 0);
|
|
25284
|
-
headerFlags.push(y < rect.top + headerPx ? 1 : 0);
|
|
25285
|
-
}
|
|
25286
|
-
}
|
|
25287
|
-
const dividerY = Math.round(rect.top + headerPx);
|
|
25288
|
-
if (dividerY > y0 && dividerY < y1) {
|
|
25289
|
-
for (let x = x0 + radius;x <= x1 - radius; x += 1) {
|
|
25290
|
-
dividerIndices.push((dividerY * width + x) * 4);
|
|
25291
|
-
}
|
|
25292
|
-
}
|
|
25293
|
-
const mask = {
|
|
25294
|
-
key,
|
|
25295
|
-
indices: Uint32Array.from(indices),
|
|
25296
|
-
sampleIndices: Uint32Array.from(sampleIndices),
|
|
25297
|
-
panelAlpha: Float32Array.from(panelAlpha),
|
|
25298
|
-
edgeAlpha: Float32Array.from(edgeAlpha),
|
|
25299
|
-
headerFlags: Uint8Array.from(headerFlags),
|
|
25300
|
-
dividerIndices: Uint32Array.from(dividerIndices)
|
|
25301
|
-
};
|
|
25302
|
-
panelMaskCache.set(key, mask);
|
|
25303
|
-
while (panelMaskCache.size > PANEL_MASK_CACHE_LIMIT) {
|
|
25304
|
-
const oldest = panelMaskCache.keys().next().value;
|
|
25305
|
-
if (!oldest)
|
|
25306
|
-
break;
|
|
25307
|
-
panelMaskCache.delete(oldest);
|
|
25308
|
-
}
|
|
25309
|
-
return mask;
|
|
25310
|
-
}
|
|
25311
|
-
function compositePanel(data, width, height, rect, headerPx) {
|
|
25312
|
-
const blurScale = PANEL_BLUR_SCALE;
|
|
25313
|
-
const sampled = downsampleRegion(data, width, height, rect, blurScale);
|
|
25314
|
-
const blurRadius = Math.max(PANEL_BLUR_RADIUS_MIN, Math.min(PANEL_BLUR_RADIUS_MAX, Math.round(Math.min(rect.width, rect.height) * PANEL_BLUR_RADIUS_FACTOR)));
|
|
25315
|
-
const blurred = blurRgb(sampled.pixels, sampled.width, sampled.height, blurRadius);
|
|
25316
|
-
const mask = getPanelMask(width, height, rect, headerPx, blurScale);
|
|
25317
|
-
for (let i = 0;i < mask.indices.length; i += 1) {
|
|
25318
|
-
const idx = mask.indices[i];
|
|
25319
|
-
const sampleIdx = mask.sampleIndices[i];
|
|
25320
|
-
data[idx] = blurred[sampleIdx];
|
|
25321
|
-
data[idx + 1] = blurred[sampleIdx + 1];
|
|
25322
|
-
data[idx + 2] = blurred[sampleIdx + 2];
|
|
25323
|
-
data[idx + 3] = 255;
|
|
25324
|
-
blendOver(data, idx, mask.headerFlags[i] ? PANEL_HEADER : PANEL, mask.panelAlpha[i]);
|
|
25325
|
-
const edge = mask.edgeAlpha[i];
|
|
25326
|
-
if (edge > 0)
|
|
25327
|
-
blendOver(data, idx, PANEL_LINE2, edge);
|
|
25328
|
-
}
|
|
25329
|
-
for (let i = 0;i < mask.dividerIndices.length; i += 1) {
|
|
25330
|
-
blendOver(data, mask.dividerIndices[i], PANEL_LINE2, 0.28);
|
|
25331
|
-
}
|
|
25332
|
-
}
|
|
25333
|
-
function drawBigRigWordmark(data, width, height, layout, load) {
|
|
25334
|
-
const sideBySide = layout.width >= FLEET_GRID_WIDTH * 1.9;
|
|
25335
|
-
if (!sideBySide)
|
|
24871
|
+
function setHoveredSelectableId(id) {
|
|
24872
|
+
if (hoveredId === id)
|
|
25336
24873
|
return;
|
|
25337
|
-
|
|
25338
|
-
const
|
|
25339
|
-
|
|
25340
|
-
const glyphW = width * 0.13;
|
|
25341
|
-
const gap = glyphW * 0.3;
|
|
25342
|
-
const totalW = letters.length * glyphW + (letters.length - 1) * gap;
|
|
25343
|
-
const centerX = width * 0.71;
|
|
25344
|
-
const startX = centerX - totalW / 2;
|
|
25345
|
-
const top = (height - glyphH) / 2;
|
|
25346
|
-
const stroke = Math.max(2, min * 0.013);
|
|
25347
|
-
drawGlow2(data, width, height, centerX, top + glyphH / 2, Math.max(glyphW, glyphH) * 0.9, LIME, 0.022 + load * 0.02);
|
|
25348
|
-
const strokeAlpha = 0.1 + load * 0.06;
|
|
25349
|
-
letters.split("").forEach((letter, index) => {
|
|
25350
|
-
const segments = RIG_GLYPH_STROKES[letter];
|
|
25351
|
-
if (!segments)
|
|
25352
|
-
return;
|
|
25353
|
-
const ox = startX + index * (glyphW + gap);
|
|
25354
|
-
for (const [x0, y0, x1, y1] of segments) {
|
|
25355
|
-
drawLine2(data, width, height, ox + x0 * glyphW, top + y0 * glyphH, ox + x1 * glyphW, top + y1 * glyphH, LIME_DIM, strokeAlpha, stroke);
|
|
25356
|
-
}
|
|
25357
|
-
});
|
|
25358
|
-
}
|
|
25359
|
-
function drawBackground(data, width, height, _tick, scene, layout, load, activeRuns) {
|
|
25360
|
-
fillRgba(data, BG, BG_WORD);
|
|
25361
|
-
drawStaticAsciiFleetBackground(data, width, height, scene, layout, load, activeRuns);
|
|
25362
|
-
drawBigRigWordmark(data, width, height, layout, load);
|
|
25363
|
-
applyStaticAtmosphere(data, width, height, load);
|
|
25364
|
-
}
|
|
25365
|
-
function imageVisualFrameKey(input) {
|
|
25366
|
-
const width = Math.max(1, Math.floor(input.pixelSize.width));
|
|
25367
|
-
const height = Math.max(1, Math.floor(input.pixelSize.height));
|
|
25368
|
-
const layer = "layer" in input ? input.layer ?? "full" : "full";
|
|
25369
|
-
const load = loadBucket(input.load);
|
|
25370
|
-
return `${layer}:${width}x${height}:${input.layout.width}x${input.layout.height}:${input.scene}:${input.tick}:l${load}:${input.panels.map((panel) => `${panel.id}:${panel.top}:${panel.height}:${panel.width ?? ""}:${panel.left ?? ""}:${panel.headerHeight ?? ""}`).join("|")}`;
|
|
25371
|
-
}
|
|
25372
|
-
function encodeKittyFrame(width, height, data, input) {
|
|
25373
|
-
if (input.transport === "png") {
|
|
25374
|
-
const png = encodePng(width, height, data);
|
|
25375
|
-
return kittyImageSequence(png.toString("base64"), { columns: input.layout.width, rows: input.layout.height, imageId: input.imageId, zIndex: input.zIndex, format: 100 });
|
|
25376
|
-
}
|
|
25377
|
-
const compressed = deflateSync(data, { level: ZLIB_LEVEL });
|
|
25378
|
-
return kittyImageSequence(compressed.toString("base64"), {
|
|
25379
|
-
columns: input.layout.width,
|
|
25380
|
-
rows: input.layout.height,
|
|
25381
|
-
imageId: input.imageId,
|
|
25382
|
-
zIndex: input.zIndex,
|
|
25383
|
-
format: 32,
|
|
25384
|
-
pixelWidth: width,
|
|
25385
|
-
pixelHeight: height,
|
|
25386
|
-
compressed: true
|
|
25387
|
-
});
|
|
25388
|
-
}
|
|
25389
|
-
function cropRgba(data, sourceWidth, rect) {
|
|
25390
|
-
const out = new Uint8ClampedArray(rect.width * rect.height * 4);
|
|
25391
|
-
for (let y = 0;y < rect.height; y += 1) {
|
|
25392
|
-
const sourceStart = ((rect.top + y) * sourceWidth + rect.left) * 4;
|
|
25393
|
-
out.set(data.subarray(sourceStart, sourceStart + rect.width * 4), y * rect.width * 4);
|
|
25394
|
-
}
|
|
25395
|
-
return out;
|
|
25396
|
-
}
|
|
25397
|
-
function encodePanelPatch(data, sourceWidth, placement, imageId, zIndex) {
|
|
25398
|
-
const patch = cropRgba(data, sourceWidth, placement);
|
|
25399
|
-
const png = encodePng(placement.width, placement.height, patch);
|
|
25400
|
-
const sequence = kittyImageSequence(png.toString("base64"), {
|
|
25401
|
-
columns: Math.max(1, Math.round(placement.widthCells)),
|
|
25402
|
-
rows: Math.max(1, Math.round(placement.heightCells)),
|
|
25403
|
-
imageId,
|
|
25404
|
-
zIndex,
|
|
25405
|
-
format: 100
|
|
25406
|
-
});
|
|
25407
|
-
return `\x1B[${Math.max(1, Math.round(placement.topCells) + 1)};${Math.max(1, Math.round(placement.leftCells) + 1)}H${sequence}`;
|
|
25408
|
-
}
|
|
25409
|
-
function renderImageVisualFrame(input) {
|
|
25410
|
-
const width = Math.max(1, Math.floor(input.pixelSize.width));
|
|
25411
|
-
const height = Math.max(1, Math.floor(input.pixelSize.height));
|
|
25412
|
-
const byteCount = width * height * 4;
|
|
25413
|
-
if (byteCount > MAX_IMAGE_BYTES)
|
|
25414
|
-
return null;
|
|
25415
|
-
const layer = input.layer ?? "full";
|
|
25416
|
-
const data = new Uint8ClampedArray(byteCount);
|
|
25417
|
-
const load = loadBucket(input.load) / LOAD_BUCKETS;
|
|
25418
|
-
const activeRuns = Math.max(0, Math.floor(input.activeRuns ?? 0));
|
|
25419
|
-
drawBackground(data, width, height, 0, input.scene, input.layout, load, activeRuns);
|
|
25420
|
-
if (layer === "split") {
|
|
25421
|
-
const sequences = [encodeKittyFrame(width, height, data, input)];
|
|
25422
|
-
let panelIndex = 0;
|
|
25423
|
-
for (const panel of input.panels) {
|
|
25424
|
-
if (panel.chrome !== "ad-terminal")
|
|
25425
|
-
continue;
|
|
25426
|
-
const placement = panelPixelPlacement(input.layout, panel, { width, height });
|
|
25427
|
-
if (!placement)
|
|
25428
|
-
continue;
|
|
25429
|
-
const cellH = height / input.layout.height;
|
|
25430
|
-
const headerPx = Math.max(cellH * 3, (panel.headerHeight ?? 3) * cellH);
|
|
25431
|
-
compositePanel(data, width, height, placement, headerPx);
|
|
25432
|
-
const imageId = input.imageIds?.[panelIndex] ?? (input.imageId + 1000 + panelIndex >>> 0 || panelIndex + 1);
|
|
25433
|
-
sequences.push(encodePanelPatch(data, width, placement, imageId, -12));
|
|
25434
|
-
panelIndex += 1;
|
|
25435
|
-
}
|
|
25436
|
-
return { key: imageVisualFrameKey(input), sequence: sequences.join("") };
|
|
25437
|
-
}
|
|
25438
|
-
if (layer === "panel-chrome")
|
|
25439
|
-
return { key: imageVisualFrameKey(input), sequence: "" };
|
|
25440
|
-
if (layer === "background") {
|
|
25441
|
-
return { key: imageVisualFrameKey(input), sequence: encodeKittyFrame(width, height, data, input) };
|
|
25442
|
-
}
|
|
25443
|
-
if (layer === "panel-patches") {
|
|
25444
|
-
const sequences = [];
|
|
25445
|
-
let panelIndex = 0;
|
|
25446
|
-
for (const panel of input.panels) {
|
|
25447
|
-
if (panel.chrome !== "ad-terminal")
|
|
25448
|
-
continue;
|
|
25449
|
-
const placement = panelPixelPlacement(input.layout, panel, { width, height });
|
|
25450
|
-
if (!placement)
|
|
25451
|
-
continue;
|
|
25452
|
-
const cellH = height / input.layout.height;
|
|
25453
|
-
const headerPx = Math.max(cellH * 3, (panel.headerHeight ?? 3) * cellH);
|
|
25454
|
-
compositePanel(data, width, height, placement, headerPx);
|
|
25455
|
-
const imageId = input.imageIds?.[panelIndex] ?? (input.imageId + 1000 + panelIndex >>> 0 || panelIndex + 1);
|
|
25456
|
-
sequences.push(encodePanelPatch(data, width, placement, imageId, input.zIndex));
|
|
25457
|
-
panelIndex += 1;
|
|
25458
|
-
}
|
|
25459
|
-
return { key: imageVisualFrameKey(input), sequence: sequences.join("") };
|
|
25460
|
-
}
|
|
25461
|
-
for (const panel of input.panels) {
|
|
25462
|
-
if (panel.chrome !== "ad-terminal")
|
|
25463
|
-
continue;
|
|
25464
|
-
const rect = panelRect(input.layout, panel, { width, height });
|
|
25465
|
-
if (!rect)
|
|
25466
|
-
continue;
|
|
25467
|
-
const cellH = height / input.layout.height;
|
|
25468
|
-
const headerPx = Math.max(cellH * 3, (panel.headerHeight ?? 3) * cellH);
|
|
25469
|
-
compositePanel(data, width, height, rect, headerPx);
|
|
25470
|
-
}
|
|
25471
|
-
return { key: imageVisualFrameKey(input), sequence: encodeKittyFrame(width, height, data, input) };
|
|
25472
|
-
}
|
|
25473
|
-
function shouldRenderImagesInline() {
|
|
25474
|
-
return process.env.RIG_OPENTUI_IMAGE_WORKER === "0" || import.meta.url.includes("$bunfs");
|
|
25475
|
-
}
|
|
25476
|
-
function createImageWorker() {
|
|
25477
|
-
if (shouldRenderImagesInline())
|
|
25478
|
-
return null;
|
|
25479
|
-
const isTypeScriptRuntime = import.meta.url.endsWith(".ts");
|
|
25480
|
-
const workerUrl = new URL(isTypeScriptRuntime ? "./image-visual-layer-worker.ts" : "./image-visual-layer-worker.js", import.meta.url);
|
|
25481
|
-
try {
|
|
25482
|
-
return new Worker(workerUrl);
|
|
25483
|
-
} catch {
|
|
25484
|
-
if (typeof process.versions.bun === "string") {
|
|
25485
|
-
try {
|
|
25486
|
-
return new Worker("./src/app-opentui/render/image-visual-layer-worker.ts");
|
|
25487
|
-
} catch {}
|
|
25488
|
-
}
|
|
25489
|
-
return null;
|
|
25490
|
-
}
|
|
25491
|
-
}
|
|
25492
|
-
function imageOutputBacklogBytes() {
|
|
25493
|
-
const raw = Number.parseInt(process.env.RIG_OPENTUI_IMAGE_BACKLOG_BYTES ?? "", 10);
|
|
25494
|
-
if (Number.isFinite(raw) && raw > 0)
|
|
25495
|
-
return Math.max(64 * 1024, Math.min(2 * 1024 * 1024, raw));
|
|
25496
|
-
return DEFAULT_IMAGE_OUTPUT_BACKLOG_BYTES;
|
|
24874
|
+
hoveredId = id;
|
|
24875
|
+
for (const listener of listeners)
|
|
24876
|
+
listener();
|
|
25497
24877
|
}
|
|
25498
|
-
function
|
|
25499
|
-
|
|
25500
|
-
|
|
25501
|
-
return Math.max(128 * 1024, Math.min(2 * 1024 * 1024, raw));
|
|
25502
|
-
return DEFAULT_IMAGE_OUTPUT_BYTES_PER_SECOND;
|
|
24878
|
+
function clearHoveredSelectableId(id) {
|
|
24879
|
+
if (id !== undefined && hoveredId === id)
|
|
24880
|
+
setHoveredSelectableId(undefined);
|
|
25503
24881
|
}
|
|
25504
|
-
function
|
|
25505
|
-
|
|
25506
|
-
|
|
25507
|
-
|
|
25508
|
-
class ImageVisualLayer {
|
|
25509
|
-
imageId = allocateImageId();
|
|
25510
|
-
panelImageIds = Array.from({ length: 8 }, () => allocateImageId());
|
|
25511
|
-
panelChromeImageIds = Array.from({ length: 8 }, () => allocateImageId());
|
|
25512
|
-
stdout;
|
|
25513
|
-
onFrameReady;
|
|
25514
|
-
protocol;
|
|
25515
|
-
transport = imageTransport();
|
|
25516
|
-
maxOutputBacklogBytes = imageOutputBacklogBytes();
|
|
25517
|
-
outputBytesPerSecond = imageOutputBytesPerSecond();
|
|
25518
|
-
outputBudgetBytes = imageOutputBytesPerSecond();
|
|
25519
|
-
lastBudgetAtMs = Date.now();
|
|
25520
|
-
motionSlot = this.createSlot();
|
|
25521
|
-
workersStarted = false;
|
|
25522
|
-
pendingFrames = new Map;
|
|
25523
|
-
recentWrittenKeys = [];
|
|
25524
|
-
imagesVisible = false;
|
|
25525
|
-
flushPaused = false;
|
|
25526
|
-
requestId = 0;
|
|
25527
|
-
lastBackgroundKey = "";
|
|
25528
|
-
fatalWorkerError = null;
|
|
25529
|
-
destroyed = false;
|
|
25530
|
-
constructor(stdout = process.stdout, onFrameReady) {
|
|
25531
|
-
this.stdout = stdout;
|
|
25532
|
-
this.onFrameReady = onFrameReady;
|
|
25533
|
-
this.protocol = getRigTerminalCapabilities().imageProtocol;
|
|
25534
|
-
}
|
|
25535
|
-
get enabled() {
|
|
25536
|
-
return this.protocol === "kitty";
|
|
25537
|
-
}
|
|
25538
|
-
clear() {
|
|
25539
|
-
if (this.enabled) {
|
|
25540
|
-
if (this.imagesVisible)
|
|
25541
|
-
this.stdout.write([this.imageId, ...this.panelImageIds, ...this.panelChromeImageIds].map((id) => deleteKittyImage(id)).join("") + "\x1B[?25h");
|
|
25542
|
-
this.imagesVisible = false;
|
|
25543
|
-
this.pendingFrames.clear();
|
|
25544
|
-
this.recentWrittenKeys.length = 0;
|
|
25545
|
-
this.resetSlot(this.motionSlot);
|
|
25546
|
-
this.lastBackgroundKey = "";
|
|
25547
|
-
this.outputBudgetBytes = this.outputBytesPerSecond;
|
|
25548
|
-
this.lastBudgetAtMs = Date.now();
|
|
25549
|
-
this.motionSlot.clearedThroughRequestId = this.requestId;
|
|
25550
|
-
}
|
|
25551
|
-
}
|
|
25552
|
-
destroy() {
|
|
25553
|
-
if (this.destroyed)
|
|
25554
|
-
return;
|
|
25555
|
-
this.clear();
|
|
25556
|
-
this.destroyed = true;
|
|
25557
|
-
const workers = [this.motionSlot.worker];
|
|
25558
|
-
this.motionSlot.worker = null;
|
|
25559
|
-
for (const worker of workers)
|
|
25560
|
-
if (worker)
|
|
25561
|
-
worker.terminate().catch(() => {
|
|
25562
|
-
return;
|
|
25563
|
-
});
|
|
25564
|
-
}
|
|
25565
|
-
setFlushPaused(paused) {
|
|
25566
|
-
this.flushPaused = paused;
|
|
25567
|
-
}
|
|
25568
|
-
isReady(input) {
|
|
25569
|
-
if (!this.enabled || this.destroyed)
|
|
25570
|
-
return true;
|
|
25571
|
-
this.throwIfFatal();
|
|
25572
|
-
const splitKey = imageVisualFrameKey({ ...input, tick: 0, layer: "split" });
|
|
25573
|
-
return this.recentWrittenKeys.includes(splitKey) || Array.from(this.pendingFrames.values()).some((frame) => frame.key === splitKey);
|
|
25574
|
-
}
|
|
25575
|
-
render(input) {
|
|
25576
|
-
if (!this.enabled || this.destroyed)
|
|
25577
|
-
return;
|
|
25578
|
-
this.throwIfFatal();
|
|
25579
|
-
if (this.transport !== "png")
|
|
25580
|
-
this.failWorker("renderer", new Error("OpenTUI image visuals require PNG transport for static-background rendering."));
|
|
25581
|
-
this.ensureWorkersStarted();
|
|
25582
|
-
const width = Math.max(1, Math.floor(input.pixelSize.width));
|
|
25583
|
-
const height = Math.max(1, Math.floor(input.pixelSize.height));
|
|
25584
|
-
if (width * height * 4 > MAX_IMAGE_BYTES)
|
|
25585
|
-
return;
|
|
25586
|
-
if (this.isOutputBackedUp())
|
|
25587
|
-
return;
|
|
25588
|
-
this.refillOutputBudget();
|
|
25589
|
-
const splitInput = { ...input, tick: 0, layer: "split" };
|
|
25590
|
-
const splitKey = imageVisualFrameKey(splitInput);
|
|
25591
|
-
if (input.force || splitKey !== this.lastBackgroundKey) {
|
|
25592
|
-
this.scheduleRender(this.motionSlot, splitInput, this.imageId, -30, input.force, this.panelImageIds);
|
|
25593
|
-
this.lastBackgroundKey = splitKey;
|
|
25594
|
-
}
|
|
25595
|
-
}
|
|
25596
|
-
flush() {
|
|
25597
|
-
this.throwIfFatal();
|
|
25598
|
-
if (this.flushPaused)
|
|
25599
|
-
return false;
|
|
25600
|
-
if (this.pendingFrames.size === 0)
|
|
25601
|
-
return false;
|
|
25602
|
-
this.refillOutputBudget();
|
|
25603
|
-
if (this.isOutputBackedUp()) {
|
|
25604
|
-
const retainedSplit = this.pendingFrames.get("split");
|
|
25605
|
-
this.pendingFrames.clear();
|
|
25606
|
-
if (retainedSplit)
|
|
25607
|
-
this.pendingFrames.set("split", retainedSplit);
|
|
25608
|
-
return false;
|
|
25609
|
-
}
|
|
25610
|
-
const framePriority = (frame) => {
|
|
25611
|
-
const layer = pendingLayerKey(frame.key);
|
|
25612
|
-
if (layer === "split")
|
|
25613
|
-
return 1;
|
|
25614
|
-
return 4;
|
|
25615
|
-
};
|
|
25616
|
-
const frames = Array.from(this.pendingFrames.values()).sort((a, b) => framePriority(a) - framePriority(b));
|
|
25617
|
-
const prefix = "\x1B[?25l\x1B7\x1B[s\x1B[H";
|
|
25618
|
-
const suffix = "\x1B[u\x1B8";
|
|
25619
|
-
const selected = [];
|
|
25620
|
-
const retained = new Map;
|
|
25621
|
-
let sequence = "";
|
|
25622
|
-
let byteLength = Buffer.byteLength(prefix + suffix);
|
|
25623
|
-
for (const frame of frames) {
|
|
25624
|
-
const candidate = sequence + frame.sequence;
|
|
25625
|
-
const candidateBytes = Buffer.byteLength(prefix + candidate + suffix);
|
|
25626
|
-
const layer = pendingLayerKey(frame.key);
|
|
25627
|
-
const allowOneStaticFrame = selected.length === 0 && layer === "split";
|
|
25628
|
-
if (candidateBytes <= this.outputBudgetBytes || allowOneStaticFrame) {
|
|
25629
|
-
selected.push(frame);
|
|
25630
|
-
sequence = candidate;
|
|
25631
|
-
byteLength = candidateBytes;
|
|
25632
|
-
} else if (layer === "split") {
|
|
25633
|
-
retained.set(layer, frame);
|
|
25634
|
-
}
|
|
25635
|
-
}
|
|
25636
|
-
this.pendingFrames.clear();
|
|
25637
|
-
for (const [layer, frame] of retained)
|
|
25638
|
-
this.pendingFrames.set(layer, frame);
|
|
25639
|
-
if (!sequence || selected.length === 0)
|
|
25640
|
-
return false;
|
|
25641
|
-
const payload = `${prefix}${sequence}${suffix}`;
|
|
25642
|
-
for (const frame of selected)
|
|
25643
|
-
this.markWritten(frame.key);
|
|
25644
|
-
this.outputBudgetBytes -= byteLength;
|
|
25645
|
-
this.stdout.cork?.();
|
|
25646
|
-
const accepted = this.stdout.write(payload);
|
|
25647
|
-
this.stdout.uncork?.();
|
|
25648
|
-
this.imagesVisible = true;
|
|
25649
|
-
return accepted;
|
|
25650
|
-
}
|
|
25651
|
-
createSlot() {
|
|
25652
|
-
return { worker: null, busy: false, queuedRequest: null, inFlightKey: "", queuedKey: "", clearedThroughRequestId: 0, latestRequestId: 0 };
|
|
25653
|
-
}
|
|
25654
|
-
resetSlot(slot) {
|
|
25655
|
-
slot.busy = false;
|
|
25656
|
-
slot.queuedRequest = null;
|
|
25657
|
-
slot.inFlightKey = "";
|
|
25658
|
-
slot.queuedKey = "";
|
|
25659
|
-
}
|
|
25660
|
-
markWritten(key) {
|
|
25661
|
-
this.recentWrittenKeys.push(key);
|
|
25662
|
-
while (this.recentWrittenKeys.length > RECENT_WRITTEN_LIMIT)
|
|
25663
|
-
this.recentWrittenKeys.shift();
|
|
25664
|
-
}
|
|
25665
|
-
refillOutputBudget() {
|
|
25666
|
-
const now = Date.now();
|
|
25667
|
-
const elapsedMs = Math.max(0, now - this.lastBudgetAtMs);
|
|
25668
|
-
this.lastBudgetAtMs = now;
|
|
25669
|
-
this.outputBudgetBytes = Math.min(this.outputBytesPerSecond, this.outputBudgetBytes + elapsedMs / 1000 * this.outputBytesPerSecond);
|
|
25670
|
-
}
|
|
25671
|
-
isOutputBackedUp() {
|
|
25672
|
-
return Boolean(this.stdout.writableNeedDrain) || this.stdout.writableLength > this.maxOutputBacklogBytes;
|
|
25673
|
-
}
|
|
25674
|
-
stageFrame(frame) {
|
|
25675
|
-
this.pendingFrames.set(pendingLayerKey(frame.key), frame);
|
|
25676
|
-
}
|
|
25677
|
-
isKnownKey(slot, key) {
|
|
25678
|
-
return this.recentWrittenKeys.includes(key) || Array.from(this.pendingFrames.values()).some((frame) => frame.key === key) || key === slot.inFlightKey || key === slot.queuedKey;
|
|
25679
|
-
}
|
|
25680
|
-
ensureWorkersStarted() {
|
|
25681
|
-
if (this.workersStarted)
|
|
25682
|
-
return;
|
|
25683
|
-
this.workersStarted = true;
|
|
25684
|
-
this.startWorker(this.motionSlot, "static-visuals");
|
|
25685
|
-
}
|
|
25686
|
-
failWorker(name, error) {
|
|
25687
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
25688
|
-
this.fatalWorkerError ??= new Error(`OpenTUI image worker ${name} failed: ${detail}`);
|
|
25689
|
-
throw this.fatalWorkerError;
|
|
25690
|
-
}
|
|
25691
|
-
throwIfFatal() {
|
|
25692
|
-
if (this.fatalWorkerError)
|
|
25693
|
-
throw this.fatalWorkerError;
|
|
25694
|
-
}
|
|
25695
|
-
scheduleRender(slot, input, imageId, zIndex, force, imageIds) {
|
|
25696
|
-
this.throwIfFatal();
|
|
25697
|
-
const key = imageVisualFrameKey(input);
|
|
25698
|
-
if (!force && this.isKnownKey(slot, key))
|
|
25699
|
-
return;
|
|
25700
|
-
const request = {
|
|
25701
|
-
...input,
|
|
25702
|
-
imageId,
|
|
25703
|
-
...imageIds ? { imageIds } : {},
|
|
25704
|
-
zIndex,
|
|
25705
|
-
transport: this.transport,
|
|
25706
|
-
requestId: ++this.requestId,
|
|
25707
|
-
key
|
|
25708
|
-
};
|
|
25709
|
-
slot.latestRequestId = request.requestId;
|
|
25710
|
-
if (!slot.worker) {
|
|
25711
|
-
this.renderInline(slot, request);
|
|
25712
|
-
return;
|
|
25713
|
-
}
|
|
25714
|
-
this.enqueueWorkerRender(slot, request);
|
|
25715
|
-
}
|
|
25716
|
-
startWorker(slot, name) {
|
|
25717
|
-
const worker = createImageWorker();
|
|
25718
|
-
if (!worker)
|
|
25719
|
-
return;
|
|
25720
|
-
slot.worker = worker;
|
|
25721
|
-
worker.on("message", (message2) => this.handleWorkerMessage(slot, message2));
|
|
25722
|
-
worker.once("error", (error) => {
|
|
25723
|
-
if (!this.destroyed)
|
|
25724
|
-
this.fatalWorkerError ??= new Error(`OpenTUI image worker ${name} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
25725
|
-
});
|
|
25726
|
-
worker.once("exit", (code) => {
|
|
25727
|
-
if (!this.destroyed)
|
|
25728
|
-
this.fatalWorkerError ??= new Error(`OpenTUI image worker ${name} exited unexpectedly with code ${code}.`);
|
|
25729
|
-
});
|
|
25730
|
-
}
|
|
25731
|
-
renderInline(slot, request) {
|
|
25732
|
-
try {
|
|
25733
|
-
const result = renderImageVisualFrame(request);
|
|
25734
|
-
if (result?.sequence && !this.isKnownKey(slot, result.key) && (!this.isOutputBackedUp() || pendingLayerKey(result.key) === "split")) {
|
|
25735
|
-
this.stageFrame({ key: result.key, sequence: result.sequence });
|
|
25736
|
-
this.onFrameReady?.();
|
|
25737
|
-
}
|
|
25738
|
-
} catch (error) {
|
|
25739
|
-
this.failWorker(String(request.layer ?? "visual"), error);
|
|
25740
|
-
}
|
|
25741
|
-
}
|
|
25742
|
-
enqueueWorkerRender(slot, request) {
|
|
25743
|
-
this.throwIfFatal();
|
|
25744
|
-
if (slot.busy) {
|
|
25745
|
-
slot.queuedRequest = request;
|
|
25746
|
-
slot.queuedKey = request.key;
|
|
25747
|
-
return;
|
|
25748
|
-
}
|
|
25749
|
-
this.dispatchWorkerRender(slot, request);
|
|
25750
|
-
}
|
|
25751
|
-
dispatchWorkerRender(slot, request) {
|
|
25752
|
-
this.throwIfFatal();
|
|
25753
|
-
if (!slot.worker)
|
|
25754
|
-
this.failWorker(String(request.layer ?? "visual"), new Error("worker is unavailable"));
|
|
25755
|
-
slot.busy = true;
|
|
25756
|
-
slot.inFlightKey = request.key;
|
|
25757
|
-
try {
|
|
25758
|
-
slot.worker.postMessage(request);
|
|
25759
|
-
} catch (error) {
|
|
25760
|
-
this.failWorker(String(request.layer ?? "visual"), error);
|
|
25761
|
-
}
|
|
25762
|
-
}
|
|
25763
|
-
handleWorkerMessage(slot, message2) {
|
|
25764
|
-
if (this.destroyed || !message2 || typeof message2 !== "object")
|
|
25765
|
-
return;
|
|
25766
|
-
const response = message2;
|
|
25767
|
-
slot.busy = false;
|
|
25768
|
-
slot.inFlightKey = "";
|
|
25769
|
-
const isStale = response.requestId <= slot.clearedThroughRequestId || response.requestId < slot.latestRequestId;
|
|
25770
|
-
if (!isStale) {
|
|
25771
|
-
if (response.error)
|
|
25772
|
-
this.failWorker(pendingLayerKey(response.key), new Error(response.error));
|
|
25773
|
-
if (response.sequence && !this.isKnownKey(slot, response.key) && (!this.isOutputBackedUp() || pendingLayerKey(response.key) === "split")) {
|
|
25774
|
-
this.stageFrame({ key: response.key, sequence: response.sequence });
|
|
25775
|
-
this.onFrameReady?.();
|
|
25776
|
-
}
|
|
25777
|
-
}
|
|
25778
|
-
const next = slot.queuedRequest;
|
|
25779
|
-
slot.queuedRequest = null;
|
|
25780
|
-
slot.queuedKey = "";
|
|
25781
|
-
if (next && !this.isKnownKey(slot, next.key))
|
|
25782
|
-
this.dispatchWorkerRender(slot, next);
|
|
25783
|
-
}
|
|
25784
|
-
}
|
|
25785
|
-
function pixelSizeForRenderer(renderer) {
|
|
25786
|
-
const resolution = renderer.resolution;
|
|
25787
|
-
const base = resolution?.width && resolution?.height ? resolution : { width: renderer.width * 12, height: renderer.height * 24 };
|
|
25788
|
-
const scale = imageResolutionScale();
|
|
25789
|
-
return {
|
|
25790
|
-
width: Math.max(renderer.width, Math.floor(base.width * scale)),
|
|
25791
|
-
height: Math.max(renderer.height, Math.floor(base.height * scale))
|
|
24882
|
+
function subscribeHover(listener) {
|
|
24883
|
+
listeners.add(listener);
|
|
24884
|
+
return () => {
|
|
24885
|
+
listeners.delete(listener);
|
|
25792
24886
|
};
|
|
25793
24887
|
}
|
|
25794
|
-
|
|
25795
|
-
|
|
25796
|
-
|
|
25797
|
-
var PANEL_MASK_RADIUS_MIN = 14, PANEL_MASK_RADIUS_MAX = 34, PANEL_MASK_RADIUS_FACTOR = 0.035, PANEL_BLUR_RADIUS_MIN = 8, PANEL_BLUR_RADIUS_MAX = 28, PANEL_BLUR_RADIUS_FACTOR = 0.018, BG, PANEL, PANEL_HEADER, PANEL_LINE2, LIME, LIME_DIM, CYAN, MAGENTA, INK_DIM, PNG_SIGNATURE, CRC_TABLE, MAX_IMAGE_BYTES, KITTY_CHUNK_SIZE = 4096, PANEL_BLUR_SCALE = 1, PANEL_MASK_CACHE_LIMIT = 16, ZLIB_LEVEL = 1, DEFAULT_IMAGE_RESOLUTION_SCALE = 1, LOAD_BUCKETS = 5, panelMaskCache, BG_WORD, ASCII_GLYPHS, RIG_GLYPH_STROKES, RECENT_WRITTEN_LIMIT = 24, DEFAULT_IMAGE_OUTPUT_BACKLOG_BYTES, DEFAULT_IMAGE_OUTPUT_BYTES_PER_SECOND;
|
|
25798
|
-
var init_image_visual_layer = __esm(() => {
|
|
25799
|
-
init_terminal_capabilities();
|
|
25800
|
-
init_ascii_fleet();
|
|
25801
|
-
init_constants();
|
|
25802
|
-
BG = [7, 8, 9, 255];
|
|
25803
|
-
PANEL = [16, 17, 21, 184];
|
|
25804
|
-
PANEL_HEADER = [16, 17, 21, 190];
|
|
25805
|
-
PANEL_LINE2 = [255, 255, 255, 24];
|
|
25806
|
-
LIME = [204, 255, 77, 255];
|
|
25807
|
-
LIME_DIM = [169, 214, 63, 255];
|
|
25808
|
-
CYAN = [86, 216, 255, 255];
|
|
25809
|
-
MAGENTA = [255, 121, 176, 255];
|
|
25810
|
-
INK_DIM = [108, 110, 121, 255];
|
|
25811
|
-
PNG_SIGNATURE = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);
|
|
25812
|
-
CRC_TABLE = makeCrcTable();
|
|
25813
|
-
MAX_IMAGE_BYTES = 48 * 1024 * 1024;
|
|
25814
|
-
panelMaskCache = new Map;
|
|
25815
|
-
BG_WORD = rgbaWord(BG);
|
|
25816
|
-
ASCII_GLYPHS = {
|
|
25817
|
-
".": ["00000", "00000", "00000", "00000", "00000", "00100", "00100"],
|
|
25818
|
-
"'": ["00100", "00100", "00000", "00000", "00000", "00000", "00000"],
|
|
25819
|
-
"-": ["00000", "00000", "00000", "11111", "00000", "00000", "00000"],
|
|
25820
|
-
_: ["00000", "00000", "00000", "00000", "00000", "00000", "11111"],
|
|
25821
|
-
"=": ["00000", "11111", "00000", "00000", "11111", "00000", "00000"],
|
|
25822
|
-
"|": ["00100", "00100", "00100", "00100", "00100", "00100", "00100"],
|
|
25823
|
-
"/": ["00001", "00010", "00010", "00100", "01000", "01000", "10000"],
|
|
25824
|
-
"\\": ["10000", "01000", "01000", "00100", "00010", "00010", "00001"],
|
|
25825
|
-
"(": ["00010", "00100", "01000", "01000", "01000", "00100", "00010"],
|
|
25826
|
-
")": ["01000", "00100", "00010", "00010", "00010", "00100", "01000"],
|
|
25827
|
-
"!": ["00100", "00100", "00100", "00100", "00100", "00000", "00100"],
|
|
25828
|
-
"%": ["11001", "11010", "00100", "01000", "10110", "00110", "00000"],
|
|
25829
|
-
$: ["00100", "11110", "10100", "11110", "00101", "11110", "00100"],
|
|
25830
|
-
"@": ["01110", "10001", "10111", "10101", "10111", "10000", "01111"],
|
|
25831
|
-
o: ["00000", "01110", "10001", "10001", "10001", "01110", "00000"],
|
|
25832
|
-
"*": ["00100", "10101", "01110", "11111", "01110", "10101", "00100"]
|
|
25833
|
-
};
|
|
25834
|
-
RIG_GLYPH_STROKES = {
|
|
25835
|
-
R: [[0, 0, 0, 1], [0, 0, 0.82, 0], [0.82, 0, 0.82, 0.5], [0, 0.5, 0.82, 0.5], [0.36, 0.5, 0.92, 1]],
|
|
25836
|
-
I: [[0.5, 0, 0.5, 1], [0.18, 0, 0.82, 0], [0.18, 1, 0.82, 1]],
|
|
25837
|
-
G: [[0.92, 0.08, 0.12, 0], [0.12, 0, 0.12, 1], [0.12, 1, 0.92, 1], [0.92, 0.5, 0.92, 1], [0.5, 0.5, 0.92, 0.5]]
|
|
25838
|
-
};
|
|
25839
|
-
DEFAULT_IMAGE_OUTPUT_BACKLOG_BYTES = 256 * 1024;
|
|
25840
|
-
DEFAULT_IMAGE_OUTPUT_BYTES_PER_SECOND = 850 * 1024;
|
|
24888
|
+
var hoveredId, listeners;
|
|
24889
|
+
var init_hover = __esm(() => {
|
|
24890
|
+
listeners = new Set;
|
|
25841
24891
|
});
|
|
25842
24892
|
|
|
25843
24893
|
// packages/cli/src/app-opentui/render/text.ts
|
|
25844
24894
|
import { RGBA as RGBA4, TextAttributes as TextAttributes4, TextRenderable } from "@opentui/core";
|
|
24895
|
+
function lineIsClickable(line2) {
|
|
24896
|
+
return line2?.selectable !== undefined || line2?.selectableIndex !== undefined;
|
|
24897
|
+
}
|
|
24898
|
+
function lineSelectableId(line2) {
|
|
24899
|
+
return line2?.selectable?.id ?? line2?.selectableId;
|
|
24900
|
+
}
|
|
24901
|
+
function lineBackground(line2) {
|
|
24902
|
+
if (line2?.bg)
|
|
24903
|
+
return RGBA4.fromHex(line2.bg);
|
|
24904
|
+
const id = lineSelectableId(line2);
|
|
24905
|
+
if (id !== undefined && isHovered(id))
|
|
24906
|
+
return HOVER_BG;
|
|
24907
|
+
return TRANSPARENT2;
|
|
24908
|
+
}
|
|
25845
24909
|
function selectableMouseHandler(currentLineRef, onLineMouseDown) {
|
|
25846
24910
|
return (event) => {
|
|
25847
24911
|
const currentLine = currentLineRef();
|
|
25848
|
-
if (currentLine
|
|
24912
|
+
if (!lineIsClickable(currentLine))
|
|
25849
24913
|
return;
|
|
25850
24914
|
onLineMouseDown?.(currentLine, event);
|
|
25851
24915
|
};
|
|
25852
24916
|
}
|
|
24917
|
+
function hoverHandlers(currentLineRef) {
|
|
24918
|
+
return {
|
|
24919
|
+
onMouseOver: () => {
|
|
24920
|
+
const id = lineSelectableId(currentLineRef());
|
|
24921
|
+
if (id !== undefined)
|
|
24922
|
+
setHoveredSelectableId(id);
|
|
24923
|
+
},
|
|
24924
|
+
onMouseOut: () => clearHoveredSelectableId(lineSelectableId(currentLineRef()))
|
|
24925
|
+
};
|
|
24926
|
+
}
|
|
25853
24927
|
function createTextLine(renderer, id, top, onLineMouseDown) {
|
|
25854
24928
|
let currentLine;
|
|
25855
24929
|
const renderable = new TextRenderable(renderer, {
|
|
@@ -25861,7 +24935,8 @@ function createTextLine(renderer, id, top, onLineMouseDown) {
|
|
|
25861
24935
|
width: 1,
|
|
25862
24936
|
fg: RIG_UI.ink2,
|
|
25863
24937
|
selectable: true,
|
|
25864
|
-
onMouseDown: selectableMouseHandler(() => currentLine, onLineMouseDown)
|
|
24938
|
+
onMouseDown: selectableMouseHandler(() => currentLine, onLineMouseDown),
|
|
24939
|
+
...hoverHandlers(() => currentLine)
|
|
25865
24940
|
});
|
|
25866
24941
|
renderable.setRigSceneLine = (line2) => {
|
|
25867
24942
|
currentLine = line2;
|
|
@@ -25878,7 +24953,8 @@ function createFlowTextLine(renderer, id, onLineMouseDown) {
|
|
|
25878
24953
|
flexShrink: 0,
|
|
25879
24954
|
fg: RIG_UI.ink2,
|
|
25880
24955
|
selectable: true,
|
|
25881
|
-
onMouseDown: selectableMouseHandler(() => currentLine, onLineMouseDown)
|
|
24956
|
+
onMouseDown: selectableMouseHandler(() => currentLine, onLineMouseDown),
|
|
24957
|
+
...hoverHandlers(() => currentLine)
|
|
25882
24958
|
});
|
|
25883
24959
|
renderable.setRigSceneLine = (line2) => {
|
|
25884
24960
|
currentLine = line2;
|
|
@@ -25892,7 +24968,7 @@ function applyTextLine(renderable, line2, top, left, width) {
|
|
|
25892
24968
|
renderable.width = width;
|
|
25893
24969
|
renderable.content = line2?.styledText ?? line2?.text ?? "";
|
|
25894
24970
|
renderable.fg = line2?.fg ?? RIG_UI.ink2;
|
|
25895
|
-
renderable.bg = line2
|
|
24971
|
+
renderable.bg = lineBackground(line2);
|
|
25896
24972
|
renderable.attributes = line2?.bold ? TextAttributes4.BOLD : line2?.dim ? TextAttributes4.DIM : 0;
|
|
25897
24973
|
}
|
|
25898
24974
|
function applyFlowTextLine(renderable, line2, width) {
|
|
@@ -25902,7 +24978,7 @@ function applyFlowTextLine(renderable, line2, width) {
|
|
|
25902
24978
|
renderable.width = Math.max(1, width);
|
|
25903
24979
|
renderable.content = line2?.styledText ?? line2?.text ?? "";
|
|
25904
24980
|
renderable.fg = line2?.fg ?? RIG_UI.ink2;
|
|
25905
|
-
renderable.bg = line2
|
|
24981
|
+
renderable.bg = lineBackground(line2);
|
|
25906
24982
|
renderable.attributes = line2?.bold ? TextAttributes4.BOLD : line2?.dim ? TextAttributes4.DIM : 0;
|
|
25907
24983
|
}
|
|
25908
24984
|
function clearTextLines(renderables, from = 0) {
|
|
@@ -25916,10 +24992,12 @@ function clearTextLines(renderables, from = 0) {
|
|
|
25916
24992
|
renderable.bg = TRANSPARENT2;
|
|
25917
24993
|
}
|
|
25918
24994
|
}
|
|
25919
|
-
var TRANSPARENT2;
|
|
24995
|
+
var TRANSPARENT2, HOVER_BG;
|
|
25920
24996
|
var init_text = __esm(() => {
|
|
25921
24997
|
init_theme2();
|
|
24998
|
+
init_hover();
|
|
25922
24999
|
TRANSPARENT2 = RGBA4.fromInts(0, 0, 0, 0);
|
|
25000
|
+
HOVER_BG = RGBA4.fromHex(RIG_UI.hover);
|
|
25923
25001
|
});
|
|
25924
25002
|
|
|
25925
25003
|
// packages/cli/src/app-opentui/render/panels.ts
|
|
@@ -27044,7 +26122,7 @@ function __renderSceneForTest(renderer, state, sceneRenderers) {
|
|
|
27044
26122
|
renderer.root.add(navText);
|
|
27045
26123
|
const registry = buildSceneRendererRegistry(sceneRenderers);
|
|
27046
26124
|
const transition = { scene: state.scene, startedAtMs: 0, minUntilMs: 0 };
|
|
27047
|
-
const selectables = renderNow(renderer, null, null,
|
|
26125
|
+
const selectables = renderNow(renderer, null, null, scrollPanels, null, null, navText, textLines, nativeHost, state, registry, transition);
|
|
27048
26126
|
return { selectables, nativeHost };
|
|
27049
26127
|
}
|
|
27050
26128
|
async function launchRigOpenTuiApp(options) {
|
|
@@ -27056,7 +26134,6 @@ async function launchRigOpenTuiApp(options) {
|
|
|
27056
26134
|
const events = createAppEventBus();
|
|
27057
26135
|
let renderer = null;
|
|
27058
26136
|
let graphics = null;
|
|
27059
|
-
let imageVisuals = null;
|
|
27060
26137
|
let preloaderBackdrop = null;
|
|
27061
26138
|
const scrollPanels = [];
|
|
27062
26139
|
let typeBar = null;
|
|
@@ -27084,7 +26161,7 @@ async function launchRigOpenTuiApp(options) {
|
|
|
27084
26161
|
if (!renderer || destroyed)
|
|
27085
26162
|
return;
|
|
27086
26163
|
const currentState = store.getState();
|
|
27087
|
-
renderedSelectableItems = renderNow(renderer, graphics,
|
|
26164
|
+
renderedSelectableItems = renderNow(renderer, graphics, preloaderBackdrop, scrollPanels, typeBar, brandText, navText, textLines, nativeHost, currentState, sceneRendererRegistry, preloaderTransition, scheduleAppRender);
|
|
27088
26165
|
focusManager.restoreTypeBarFocus(typeBar, { hidden: currentState.scene === "handoff" });
|
|
27089
26166
|
maybeRedirectFromUnresolvedScene(currentState);
|
|
27090
26167
|
};
|
|
@@ -27244,18 +26321,8 @@ async function launchRigOpenTuiApp(options) {
|
|
|
27244
26321
|
});
|
|
27245
26322
|
renderer.setTerminalTitle?.("Operator cockpit");
|
|
27246
26323
|
const layout = computeStageLayout(renderer.width, renderer.height);
|
|
27247
|
-
|
|
27248
|
-
|
|
27249
|
-
const flushImageVisuals = async () => {
|
|
27250
|
-
imageVisuals?.flush();
|
|
27251
|
-
};
|
|
27252
|
-
renderer.setFrameCallback(flushImageVisuals);
|
|
27253
|
-
resources.add(() => renderer?.removeFrameCallback(flushImageVisuals));
|
|
27254
|
-
}
|
|
27255
|
-
if (!imageVisuals?.enabled) {
|
|
27256
|
-
graphics = createGraphicsLayer(renderer, layout);
|
|
27257
|
-
renderer.root.add(graphics);
|
|
27258
|
-
}
|
|
26324
|
+
graphics = createGraphicsLayer(renderer, layout);
|
|
26325
|
+
renderer.root.add(graphics);
|
|
27259
26326
|
preloaderBackdrop = new BoxRenderable3(renderer, {
|
|
27260
26327
|
id: "rig-preloader-backdrop",
|
|
27261
26328
|
position: "absolute",
|
|
@@ -27278,8 +26345,7 @@ async function launchRigOpenTuiApp(options) {
|
|
|
27278
26345
|
} else if (!selectById(store, id, renderedSelectableItems)) {
|
|
27279
26346
|
return;
|
|
27280
26347
|
}
|
|
27281
|
-
|
|
27282
|
-
runAppAction("Activate selection", () => activateSelection(runtime, renderedSelectableItems));
|
|
26348
|
+
runAppAction("Activate selection", () => activateSelection(runtime, renderedSelectableItems));
|
|
27283
26349
|
};
|
|
27284
26350
|
for (let index = 0;index < MAX_SCENE_PANELS; index += 1) {
|
|
27285
26351
|
const panel = createScrollPanelLayer(renderer, `rig-scroll-panel-${index}`, onLineClick);
|
|
@@ -27346,6 +26412,7 @@ async function launchRigOpenTuiApp(options) {
|
|
|
27346
26412
|
};
|
|
27347
26413
|
renderer.keyInput.on("keypress", onKeyPress);
|
|
27348
26414
|
resources.add(() => renderer?.keyInput.off("keypress", onKeyPress));
|
|
26415
|
+
resources.add(subscribeHover(() => scheduleAppRender(0)));
|
|
27349
26416
|
const onPaste = (event) => {
|
|
27350
26417
|
const state = store.getState();
|
|
27351
26418
|
if (state.scene === "handoff") {
|
|
@@ -27381,7 +26448,6 @@ async function launchRigOpenTuiApp(options) {
|
|
|
27381
26448
|
stopActivePiHost("renderer destroyed");
|
|
27382
26449
|
stopActiveCommandHost("renderer destroyed");
|
|
27383
26450
|
destroyNativeHost(nativeHost);
|
|
27384
|
-
imageVisuals?.destroy();
|
|
27385
26451
|
if (renderTimer)
|
|
27386
26452
|
clearTimeout(renderTimer);
|
|
27387
26453
|
renderTimer = null;
|
|
@@ -27430,14 +26496,13 @@ async function launchRigOpenTuiApp(options) {
|
|
|
27430
26496
|
clearTimeout(renderTimer);
|
|
27431
26497
|
renderTimer = null;
|
|
27432
26498
|
resources.disposeAll();
|
|
27433
|
-
imageVisuals?.destroy();
|
|
27434
26499
|
stopActivePiHost("app shutdown");
|
|
27435
26500
|
stopActiveCommandHost("app shutdown");
|
|
27436
26501
|
if (renderer && !renderer.isDestroyed)
|
|
27437
26502
|
renderer.destroy();
|
|
27438
26503
|
}
|
|
27439
26504
|
}
|
|
27440
|
-
function renderNow(renderer, graphics,
|
|
26505
|
+
function renderNow(renderer, graphics, preloaderBackdrop, scrollPanels, typeBar, brandText, navText, textLines, nativeHost, state, sceneRendererRegistry, preloaderTransition, scheduleRenderAfter) {
|
|
27441
26506
|
const layout = computeStageLayout(renderer.width, renderer.height);
|
|
27442
26507
|
const hideNav = () => {
|
|
27443
26508
|
if (navText)
|
|
@@ -27446,7 +26511,6 @@ function renderNow(renderer, graphics, imageVisuals, preloaderBackdrop, scrollPa
|
|
|
27446
26511
|
if (layout.tooSmall) {
|
|
27447
26512
|
if (graphics)
|
|
27448
26513
|
clearGraphicsLayer(graphics);
|
|
27449
|
-
imageVisuals?.clear();
|
|
27450
26514
|
if (preloaderBackdrop)
|
|
27451
26515
|
preloaderBackdrop.visible = false;
|
|
27452
26516
|
if (brandText)
|
|
@@ -27480,8 +26544,7 @@ function renderNow(renderer, graphics, imageVisuals, preloaderBackdrop, scrollPa
|
|
|
27480
26544
|
preloaderTransition.minUntilMs = now;
|
|
27481
26545
|
const targetFrame = renderState.typeBar.mode === "command" ? commandPaletteFrame(renderState, layout) : rendererForScene(renderState.scene, sceneRendererRegistry)(renderState, layout);
|
|
27482
26546
|
const targetContentLayout = targetFrame.fullScreen ? { ...layout, centerWidth: layout.width, centerLeft: 0, centerTop: 0, centerHeight: Math.min(layout.height, MAX_SCENE_LINES) } : layout;
|
|
27483
|
-
const
|
|
27484
|
-
let targetVisualReady = true;
|
|
26547
|
+
const targetVisualReady = true;
|
|
27485
26548
|
const fleetStats = fleetStatsFromState(state);
|
|
27486
26549
|
const fleetLoad = fleetStats.load;
|
|
27487
26550
|
const fleetActive = fleetStats.active;
|
|
@@ -27491,23 +26554,7 @@ function renderNow(renderer, graphics, imageVisuals, preloaderBackdrop, scrollPa
|
|
|
27491
26554
|
if (renderState.scene === "command") {
|
|
27492
26555
|
getActiveCommandHost()?.resize(Math.max(40, targetContentLayout.centerWidth - 12), Math.max(10, targetContentLayout.centerHeight - 6));
|
|
27493
26556
|
}
|
|
27494
|
-
if (imageVisuals && targetFrame.terminalActive) {
|
|
27495
|
-
imageVisuals.clear();
|
|
27496
|
-
} else if (imageVisuals && !targetFrame.fullScreen && !sceneJustChanged) {
|
|
27497
|
-
const visualInput = {
|
|
27498
|
-
layout: targetContentLayout,
|
|
27499
|
-
pixelSize: pixelSizeForRenderer(renderer),
|
|
27500
|
-
panels: targetPanelsForImages,
|
|
27501
|
-
scene: state.scene,
|
|
27502
|
-
tick: state.tick,
|
|
27503
|
-
load: fleetLoad,
|
|
27504
|
-
activeRuns: fleetActive
|
|
27505
|
-
};
|
|
27506
|
-
imageVisuals.render(visualInput);
|
|
27507
|
-
targetVisualReady = imageVisuals.isReady(visualInput);
|
|
27508
|
-
}
|
|
27509
26557
|
const preloaderActive = sceneJustChanged && !cachedFastPath || isPreloaderActive(preloaderTransition, targetVisualReady, now);
|
|
27510
|
-
imageVisuals?.setFlushPaused(preloaderActive);
|
|
27511
26558
|
const frame = preloaderActive ? renderAsciiPreloaderFrame(renderState.scene, layout, state.tick) : targetFrame;
|
|
27512
26559
|
if (graphics) {
|
|
27513
26560
|
resizeGraphicsLayer(graphics, layout);
|
|
@@ -27606,8 +26653,8 @@ var init_runtime = __esm(() => {
|
|
|
27606
26653
|
init_theme2();
|
|
27607
26654
|
init_graphics();
|
|
27608
26655
|
init_fleet_stats();
|
|
27609
|
-
init_image_visual_layer();
|
|
27610
26656
|
init_text();
|
|
26657
|
+
init_hover();
|
|
27611
26658
|
init_panels();
|
|
27612
26659
|
init_type_bar();
|
|
27613
26660
|
init_scene();
|
|
@@ -27745,13 +26792,16 @@ function lineContent(line2) {
|
|
|
27745
26792
|
}
|
|
27746
26793
|
function LineView(props) {
|
|
27747
26794
|
const { line: line2, onLineClick } = props;
|
|
26795
|
+
const id = lineSelectableId(line2);
|
|
27748
26796
|
return /* @__PURE__ */ jsxDEV("text", {
|
|
27749
26797
|
style: { position: "absolute", left: props.left, top: props.top, width: props.width, zIndex: 5 },
|
|
27750
26798
|
fg: line2.fg ?? RIG_UI.ink2,
|
|
27751
|
-
bg: line2
|
|
26799
|
+
bg: lineBackground(line2),
|
|
27752
26800
|
attributes: lineAttributes(line2),
|
|
27753
26801
|
content: lineContent(line2),
|
|
27754
|
-
onMouseDown: onLineClick ? () => onLineClick(line2) : undefined
|
|
26802
|
+
onMouseDown: onLineClick ? () => onLineClick(line2) : undefined,
|
|
26803
|
+
onMouseOver: id !== undefined ? () => setHoveredSelectableId(id) : undefined,
|
|
26804
|
+
onMouseOut: id !== undefined ? () => clearHoveredSelectableId(id) : undefined
|
|
27755
26805
|
}, undefined, false, undefined, this);
|
|
27756
26806
|
}
|
|
27757
26807
|
function PanelHost(props) {
|
|
@@ -27838,6 +26888,7 @@ var init_SceneFrameView = __esm(() => {
|
|
|
27838
26888
|
init_theme2();
|
|
27839
26889
|
init_scene();
|
|
27840
26890
|
init_text();
|
|
26891
|
+
init_hover();
|
|
27841
26892
|
init_panels();
|
|
27842
26893
|
init_native_host();
|
|
27843
26894
|
init_scroll();
|
|
@@ -27991,7 +27042,7 @@ var init_nav = __esm(() => {
|
|
|
27991
27042
|
});
|
|
27992
27043
|
|
|
27993
27044
|
// packages/cli/src/app-opentui/react/App.tsx
|
|
27994
|
-
import { useMemo, useRef as useRef4 } from "react";
|
|
27045
|
+
import { useMemo, useRef as useRef4, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
27995
27046
|
import { useKeyboard, useRenderer as useRenderer4, useTerminalDimensions as useTerminalDimensions2 } from "@opentui/react";
|
|
27996
27047
|
import { jsxDEV as jsxDEV3 } from "@opentui/react/jsx-dev-runtime";
|
|
27997
27048
|
function defaultFrame(state) {
|
|
@@ -28009,6 +27060,7 @@ function App(props) {
|
|
|
28009
27060
|
const runAppAction = useRunAppAction();
|
|
28010
27061
|
const store = useStore();
|
|
28011
27062
|
const renderer = useRenderer4();
|
|
27063
|
+
useSyncExternalStore2(subscribeHover, getHoveredSelectableId, getHoveredSelectableId);
|
|
28012
27064
|
const dims = useTerminalDimensions2();
|
|
28013
27065
|
const layout = computeStageLayout(dims.width, dims.height);
|
|
28014
27066
|
const registry = useMemo(() => ({ ...BUILTIN, ...props.sceneRenderers ?? {} }), [props.sceneRenderers]);
|
|
@@ -28043,8 +27095,7 @@ function App(props) {
|
|
|
28043
27095
|
} else {
|
|
28044
27096
|
return;
|
|
28045
27097
|
}
|
|
28046
|
-
|
|
28047
|
-
runAppAction("Activate selection", () => activateSelection(runtime, items));
|
|
27098
|
+
runAppAction("Activate selection", () => activateSelection(runtime, items));
|
|
28048
27099
|
};
|
|
28049
27100
|
return /* @__PURE__ */ jsxDEV3("box", {
|
|
28050
27101
|
style: { position: "absolute", left: 0, top: 0, width: "100%", height: "100%" },
|
|
@@ -28094,6 +27145,7 @@ var init_App = __esm(() => {
|
|
|
28094
27145
|
init_SceneFrameView();
|
|
28095
27146
|
init_ChromeHost();
|
|
28096
27147
|
init_scroll();
|
|
27148
|
+
init_hover();
|
|
28097
27149
|
init_context();
|
|
28098
27150
|
init_nav();
|
|
28099
27151
|
BUILTIN = {
|