@hex1b/web-terminal 0.1.0 → 0.167.0-alpha.1512.1.d6b2173
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 +14 -0
- package/dist/hyperlinks.d.ts +10 -0
- package/dist/hyperlinks.d.ts.map +1 -0
- package/dist/hyperlinks.js +28 -0
- package/dist/hyperlinks.js.map +1 -0
- package/dist/mouse-input.d.ts +3 -0
- package/dist/mouse-input.d.ts.map +1 -1
- package/dist/mouse-input.js +69 -2
- package/dist/mouse-input.js.map +1 -1
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +14 -0
- package/dist/protocol.js.map +1 -1
- package/dist/terminal-worker.js +1 -1
- package/dist/terminal-worker.js.map +1 -1
- package/dist/web-terminal.d.ts.map +1 -1
- package/dist/web-terminal.js +16 -2
- package/dist/web-terminal.js.map +1 -1
- package/dist/wire-types.d.ts +8 -0
- package/dist/wire-types.d.ts.map +1 -1
- package/dist/wire-types.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -172,6 +172,20 @@ actions reject if selection/input/focus changes before their asynchronous work
|
|
|
172
172
|
can be applied safely. Errors are surfaced rather than silently reported as
|
|
173
173
|
successful copies or pastes.
|
|
174
174
|
|
|
175
|
+
### Hyperlinks
|
|
176
|
+
|
|
177
|
+
Hold Ctrl or Cmd and click an OSC 8 hyperlink to open its destination in a new
|
|
178
|
+
tab. Hovering shows the destination and activation hint; holding the modifier
|
|
179
|
+
also shows a pointer cursor. Links work in live output, scrollback, and read-only
|
|
180
|
+
views. Plain clicks and drags retain their existing selection/application
|
|
181
|
+
behavior, and explicit input-policy routes or actions take precedence.
|
|
182
|
+
Shift and Alt/Option continue to reserve selection gestures.
|
|
183
|
+
|
|
184
|
+
Only absolute `http:`, `https:`, and `mailto:` destinations are activated
|
|
185
|
+
(`mailto:` handling depends on the browser). New tabs use `noopener,noreferrer`.
|
|
186
|
+
Script, data, file, relative, and custom-scheme URLs are not activated.
|
|
187
|
+
Plain URL text is not automatically detected; the workload must emit OSC 8.
|
|
188
|
+
|
|
175
189
|
## Selection UI hooks
|
|
176
190
|
|
|
177
191
|
`onSelectionUI` receives a typed `SelectionUIEvent`, also dispatched as the
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TerminalPoint } from "./types.js";
|
|
2
|
+
import type { HyperlinkRange } from "./wire-types.js";
|
|
3
|
+
/** OSC 8 destinations are untrusted output, not page-relative navigation. */
|
|
4
|
+
export declare function hyperlinkUri(uri: string): string | null;
|
|
5
|
+
export declare class Hyperlinks {
|
|
6
|
+
#private;
|
|
7
|
+
update(ranges: readonly HyperlinkRange[]): void;
|
|
8
|
+
at(point: TerminalPoint): string | null;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=hyperlinks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyperlinks.d.ts","sourceRoot":"","sources":["../src/hyperlinks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIvD;AAED,qBAAa,UAAU;;IAGrB,MAAM,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI;IAa/C,EAAE,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI;CAIxC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** OSC 8 destinations are untrusted output, not page-relative navigation. */
|
|
2
|
+
export function hyperlinkUri(uri) {
|
|
3
|
+
if (/[\u0000-\u0020\u007f]/u.test(uri) || !URL.canParse(uri))
|
|
4
|
+
return null;
|
|
5
|
+
const url = new URL(uri);
|
|
6
|
+
return ["https:", "http:", "mailto:"].includes(url.protocol) ? url.href : null;
|
|
7
|
+
}
|
|
8
|
+
export class Hyperlinks {
|
|
9
|
+
#rows = new Map();
|
|
10
|
+
update(ranges) {
|
|
11
|
+
this.#rows.clear();
|
|
12
|
+
const destinations = new Map();
|
|
13
|
+
for (const range of ranges) {
|
|
14
|
+
if (!destinations.has(range.uri))
|
|
15
|
+
destinations.set(range.uri, hyperlinkUri(range.uri));
|
|
16
|
+
const uri = destinations.get(range.uri);
|
|
17
|
+
if (!uri)
|
|
18
|
+
continue;
|
|
19
|
+
const row = this.#rows.get(range.row) ?? [];
|
|
20
|
+
row.push({ ...range, uri });
|
|
21
|
+
this.#rows.set(range.row, row);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
at(point) {
|
|
25
|
+
return this.#rows.get(point.y)?.find(range => point.x >= range.startColumn && point.x < range.endColumn)?.uri ?? null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=hyperlinks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyperlinks.js","sourceRoot":"","sources":["../src/hyperlinks.ts"],"names":[],"mappings":"AAGA,6EAA6E;AAC7E,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,IAAI,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1E,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACjF,CAAC;AAED,MAAM,OAAO,UAAU;IACrB,KAAK,GAAG,IAAI,GAAG,EAA4B,CAAC;IAE5C,MAAM,CAAC,MAAiC;QACtC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,YAAY,GAAG,IAAI,GAAG,EAAyB,CAAC;QACtD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;gBAAE,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;YACvF,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACxC,IAAI,CAAC,GAAG;gBAAE,SAAS;YACnB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YAC5C,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,EAAE,CAAC,KAAoB;QACrB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAC3C,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC;IAC5E,CAAC;CACF","sourcesContent":["import type { TerminalPoint } from \"./types.js\";\nimport type { HyperlinkRange } from \"./wire-types.js\";\n\n/** OSC 8 destinations are untrusted output, not page-relative navigation. */\nexport function hyperlinkUri(uri: string): string | null {\n if (/[\\u0000-\\u0020\\u007f]/u.test(uri) || !URL.canParse(uri)) return null;\n const url = new URL(uri);\n return [\"https:\", \"http:\", \"mailto:\"].includes(url.protocol) ? url.href : null;\n}\n\nexport class Hyperlinks {\n #rows = new Map<number, HyperlinkRange[]>();\n\n update(ranges: readonly HyperlinkRange[]): void {\n this.#rows.clear();\n const destinations = new Map<string, string | null>();\n for (const range of ranges) {\n if (!destinations.has(range.uri)) destinations.set(range.uri, hyperlinkUri(range.uri));\n const uri = destinations.get(range.uri);\n if (!uri) continue;\n const row = this.#rows.get(range.row) ?? [];\n row.push({ ...range, uri });\n this.#rows.set(range.row, row);\n }\n }\n\n at(point: TerminalPoint): string | null {\n return this.#rows.get(point.y)?.find(range =>\n point.x >= range.startColumn && point.x < range.endColumn)?.uri ?? null;\n }\n}\n"]}
|
package/dist/mouse-input.d.ts
CHANGED
|
@@ -14,9 +14,12 @@ interface MouseInspection {
|
|
|
14
14
|
execute?: (decision: Extract<InputDecision, {
|
|
15
15
|
action: unknown;
|
|
16
16
|
}>, input: TerminalInput) => void;
|
|
17
|
+
hyperlink?: (point: TerminalPoint) => string | null;
|
|
18
|
+
openHyperlink?: (uri: string) => void;
|
|
17
19
|
}
|
|
18
20
|
export interface MouseCapture {
|
|
19
21
|
update(columns: number, rows: number, tracking: MouseTrackingMode): void;
|
|
22
|
+
refresh(): void;
|
|
20
23
|
cancel(): void;
|
|
21
24
|
dispose(): void;
|
|
22
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mouse-input.d.ts","sourceRoot":"","sources":["../src/mouse-input.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAmB,iBAAiB,EAAiB,aAAa,EAC3F,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAA6B,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"mouse-input.d.ts","sourceRoot":"","sources":["../src/mouse-input.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAmB,iBAAiB,EAAiB,aAAa,EAC3F,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAA6B,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAM/E,UAAU,eAAe;IACvB,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAC7C,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE;QAAE,IAAI,EAAE,aAAa,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC5F,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACxC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;IAC3D,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,aAAa,CAAC;IAClD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,aAAa,EAAE;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC,EAAE,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAChG,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,MAAM,GAAG,IAAI,CAAC;IACpD,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AACD,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACzE,OAAO,IAAI,IAAI,CAAC;IAChB,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,EAC3F,KAAK,EAAE,MAAM,IAAI,EAAE,UAAU,GAAE,eAAoB,GAAG,YAAY,CA2WnE"}
|
package/dist/mouse-input.js
CHANGED
|
@@ -24,10 +24,27 @@ export function captureMouse(canvas, send, focus, inspection = {}) {
|
|
|
24
24
|
let completedClick;
|
|
25
25
|
let routedGesture;
|
|
26
26
|
let contextMenuRoute;
|
|
27
|
+
let hyperlinkClick;
|
|
28
|
+
let hoverEvent;
|
|
29
|
+
let hoverModifiers;
|
|
30
|
+
const originalTitle = canvas.title;
|
|
31
|
+
const originalCursor = canvas.style.cursor;
|
|
27
32
|
const state = () => ({ tracking, ...inspection.state?.() });
|
|
28
33
|
function point(event, clamp = false) {
|
|
29
34
|
return cellPoint(event, canvas.getBoundingClientRect(), columns, rows, clamp);
|
|
30
35
|
}
|
|
36
|
+
function refreshHover(modifiers = hoverModifiers) {
|
|
37
|
+
if (!inspection.hyperlink)
|
|
38
|
+
return;
|
|
39
|
+
hoverModifiers = modifiers;
|
|
40
|
+
const position = hoverEvent && point(hoverEvent);
|
|
41
|
+
const uri = position ? inspection.hyperlink(position) : null;
|
|
42
|
+
canvas.title = uri ? `${uri}\nCtrl/Cmd+click to open link` : originalTitle;
|
|
43
|
+
canvas.style.cursor = uri && modifiers && (modifiers.ctrlKey || modifiers.metaKey) &&
|
|
44
|
+
!modifiers.altKey && !modifiers.shiftKey ? "pointer" : originalCursor;
|
|
45
|
+
if (hyperlinkClick && hyperlinkClick.uri !== uri)
|
|
46
|
+
hyperlinkClick.dragged = true;
|
|
47
|
+
}
|
|
31
48
|
function updateAutoScroll() {
|
|
32
49
|
clearTimeout(autoScroll);
|
|
33
50
|
autoScroll = undefined;
|
|
@@ -83,6 +100,7 @@ export function captureMouse(canvas, send, focus, inspection = {}) {
|
|
|
83
100
|
pointerEvent = undefined;
|
|
84
101
|
selectionClick = undefined;
|
|
85
102
|
completedClick = undefined;
|
|
103
|
+
hyperlinkClick = undefined;
|
|
86
104
|
gesture.end();
|
|
87
105
|
routedGesture = undefined;
|
|
88
106
|
if (report)
|
|
@@ -115,6 +133,8 @@ export function captureMouse(canvas, send, focus, inspection = {}) {
|
|
|
115
133
|
if (!position)
|
|
116
134
|
return;
|
|
117
135
|
if (pointerId !== null) {
|
|
136
|
+
if (hyperlinkClick)
|
|
137
|
+
hyperlinkClick.dragged = true;
|
|
118
138
|
if (routedGesture !== InputRoute.Browser)
|
|
119
139
|
event.preventDefault();
|
|
120
140
|
if ((gesture.owner === "app" || routedGesture === InputRoute.Application) && pointerId === event.pointerId)
|
|
@@ -125,8 +145,20 @@ export function captureMouse(canvas, send, focus, inspection = {}) {
|
|
|
125
145
|
const input = { type: "pointer", button: pointerButtons[event.button],
|
|
126
146
|
point: Object.freeze({ ...position }), ...inputModifiers(event) };
|
|
127
147
|
const decision = inspection.resolve?.(input) ?? { route: InputRoute.Continue };
|
|
128
|
-
|
|
148
|
+
let route = decision.action !== undefined ? InputRoute.Consume : decision.route;
|
|
149
|
+
if (route === InputRoute.Continue && event.button === 0 && (event.ctrlKey || event.metaKey) &&
|
|
150
|
+
!event.altKey && !event.shiftKey) {
|
|
151
|
+
const uri = inspection.hyperlink?.(position);
|
|
152
|
+
if (uri) {
|
|
153
|
+
hyperlinkClick = { uri, x: event.clientX, y: event.clientY, dragged: false };
|
|
154
|
+
route = InputRoute.Consume;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
129
157
|
contextMenuRoute = event.button === 2 ? route : undefined;
|
|
158
|
+
if (hyperlinkClick)
|
|
159
|
+
contextMenuRoute = InputRoute.Consume;
|
|
160
|
+
hoverEvent = event;
|
|
161
|
+
refreshHover(event);
|
|
130
162
|
if (route !== InputRoute.Continue) {
|
|
131
163
|
completedClick = selectionClick = undefined;
|
|
132
164
|
click.count = 0;
|
|
@@ -186,6 +218,10 @@ export function captureMouse(canvas, send, focus, inspection = {}) {
|
|
|
186
218
|
return;
|
|
187
219
|
if (pointerId !== null && pointerId !== event.pointerId)
|
|
188
220
|
return;
|
|
221
|
+
hoverEvent = event;
|
|
222
|
+
refreshHover(event);
|
|
223
|
+
if (hyperlinkClick && Math.hypot(event.clientX - hyperlinkClick.x, event.clientY - hyperlinkClick.y) >= 4)
|
|
224
|
+
hyperlinkClick.dragged = true;
|
|
189
225
|
const position = point(event, pointerId !== null);
|
|
190
226
|
if (!position)
|
|
191
227
|
return;
|
|
@@ -224,6 +260,21 @@ export function captureMouse(canvas, send, focus, inspection = {}) {
|
|
|
224
260
|
canvas.addEventListener("pointerup", event => {
|
|
225
261
|
if (pointerId !== event.pointerId)
|
|
226
262
|
return;
|
|
263
|
+
if (hyperlinkClick) {
|
|
264
|
+
event.preventDefault();
|
|
265
|
+
const link = hyperlinkClick;
|
|
266
|
+
const position = point(event);
|
|
267
|
+
const activate = event.button === 0 && event.buttons === 0 && !link.dragged &&
|
|
268
|
+
Math.hypot(event.clientX - link.x, event.clientY - link.y) < 4 &&
|
|
269
|
+
position && inspection.hyperlink?.(position) === link.uri;
|
|
270
|
+
if (event.buttons === 0)
|
|
271
|
+
cancel(false, false);
|
|
272
|
+
else
|
|
273
|
+
link.dragged = true;
|
|
274
|
+
if (activate)
|
|
275
|
+
inspection.openHyperlink?.(link.uri);
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
227
278
|
const position = point(event, true) ?? lastPoint;
|
|
228
279
|
if (routedGesture) {
|
|
229
280
|
if (routedGesture === InputRoute.Application && position)
|
|
@@ -262,11 +313,21 @@ export function captureMouse(canvas, send, focus, inspection = {}) {
|
|
|
262
313
|
inspection.begin?.(completed.point, { mode, extend: false });
|
|
263
314
|
}, options);
|
|
264
315
|
canvas.addEventListener("pointercancel", () => cancel(), options);
|
|
316
|
+
canvas.addEventListener("pointerleave", () => {
|
|
317
|
+
hoverEvent = undefined;
|
|
318
|
+
refreshHover();
|
|
319
|
+
}, options);
|
|
265
320
|
canvas.addEventListener("lostpointercapture", () => {
|
|
266
321
|
if (pointerId !== null)
|
|
267
322
|
cancel();
|
|
268
323
|
}, options);
|
|
269
|
-
window.addEventListener("blur", () =>
|
|
324
|
+
window.addEventListener("blur", () => {
|
|
325
|
+
cancel();
|
|
326
|
+
hoverEvent = undefined;
|
|
327
|
+
refreshHover();
|
|
328
|
+
}, options);
|
|
329
|
+
window.addEventListener("keydown", event => refreshHover(event), { ...options, capture: true });
|
|
330
|
+
window.addEventListener("keyup", event => refreshHover(event), { ...options, capture: true });
|
|
270
331
|
canvas.addEventListener("contextmenu", event => {
|
|
271
332
|
if (contextMenuRoute !== undefined && contextMenuRoute !== InputRoute.Continue) {
|
|
272
333
|
const route = contextMenuRoute;
|
|
@@ -279,6 +340,8 @@ export function captureMouse(canvas, send, focus, inspection = {}) {
|
|
|
279
340
|
event.preventDefault();
|
|
280
341
|
}, options);
|
|
281
342
|
canvas.addEventListener("wheel", event => {
|
|
343
|
+
if (hyperlinkClick)
|
|
344
|
+
hyperlinkClick.dragged = true;
|
|
282
345
|
const input = { type: "wheel", deltaX: event.deltaX, deltaY: event.deltaY,
|
|
283
346
|
deltaMode: event.deltaMode, point: point(event), ...inputModifiers(event) };
|
|
284
347
|
const decision = pointerId === null
|
|
@@ -345,11 +408,15 @@ export function captureMouse(canvas, send, focus, inspection = {}) {
|
|
|
345
408
|
rows = nextRows;
|
|
346
409
|
tracking = nextTracking;
|
|
347
410
|
}
|
|
411
|
+
refreshHover();
|
|
348
412
|
},
|
|
413
|
+
refresh() { refreshHover(); },
|
|
349
414
|
cancel() { cancel(); },
|
|
350
415
|
dispose() {
|
|
351
416
|
cancel(false);
|
|
352
417
|
listeners.abort();
|
|
418
|
+
canvas.title = originalTitle;
|
|
419
|
+
canvas.style.cursor = originalCursor;
|
|
353
420
|
}
|
|
354
421
|
};
|
|
355
422
|
}
|
package/dist/mouse-input.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mouse-input.js","sourceRoot":"","sources":["../src/mouse-input.ts"],"names":[],"mappings":"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","sourcesContent":["import { cellPoint, WheelAccumulator, SelectionGesture } from \"./selection-input.js\";\nimport { InputRoute, inputModifiers } from \"./input-policy.js\";\nimport type { GestureState } from \"./selection-input.js\";\nimport type { InputDecision, InputRouteValue, MouseTrackingMode, PointerButton, SelectionMode,\n TerminalInput, TerminalPoint } from \"./types.js\";\nimport type { CellPosition, MouseButton, MouseCommand } from \"./wire-types.js\";\n\nconst buttons: readonly (readonly [PointerButton, number])[] = [[\"left\", 1], [\"middle\", 4], [\"right\", 2]];\nconst pointerButtons: readonly PointerButton[] = [\"left\", \"middle\", \"right\"];\ninterface SelectionClick { point: TerminalPoint; mode: SelectionMode; extend: boolean; dragged: boolean }\ninterface MouseInspection {\n state?: () => Omit<GestureState, \"tracking\">;\n begin?: (point: TerminalPoint, selection: { mode: SelectionMode; extend: boolean }) => void;\n extend?: (point: TerminalPoint) => void;\n scroll?: (delta: number, endpoint?: TerminalPoint) => void;\n end?: (cancelled: boolean) => void;\n resolve?: (input: TerminalInput) => InputDecision;\n execute?: (decision: Extract<InputDecision, { action: unknown }>, input: TerminalInput) => void;\n}\nexport interface MouseCapture {\n update(columns: number, rows: number, tracking: MouseTrackingMode): void;\n cancel(): void;\n dispose(): void;\n}\n\n/** Capture input intent only; the server chooses and encodes the mouse protocol. */\nexport function captureMouse(canvas: HTMLCanvasElement, send: (command: MouseCommand) => void,\n focus: () => void, inspection: MouseInspection = {}): MouseCapture {\n const listeners = new AbortController();\n const options = { signal: listeners.signal };\n let columns = 1, rows = 1;\n let tracking: MouseTrackingMode = 0;\n let pointerId: number | null = null;\n const pressed = new Set<PointerButton>();\n let lastPoint: CellPosition | undefined;\n let pendingMove: MouseCommand | undefined;\n let lastMove: string | undefined;\n let scheduled: number | undefined;\n const wheel = new WheelAccumulator();\n const gesture = new SelectionGesture();\n let wheelOwner: \"local\" | \"app\" | undefined;\n let pointerEvent: PointerEvent | undefined;\n let autoScroll: ReturnType<typeof setTimeout> | undefined;\n let click = { count: 0, time: 0, x: -1, y: -1 };\n let selectionClick: SelectionClick | undefined;\n let completedClick: SelectionClick | undefined;\n let routedGesture: InputRouteValue | undefined;\n let contextMenuRoute: InputRouteValue | undefined;\n const state = () => ({ tracking, ...inspection.state?.() });\n\n function point(event: MouseEvent, clamp = false): CellPosition | null {\n return cellPoint(event, canvas.getBoundingClientRect(), columns, rows, clamp);\n }\n\n function updateAutoScroll() {\n clearTimeout(autoScroll);\n autoScroll = undefined;\n if (gesture.owner !== \"local\" || !pointerEvent) return;\n const bounds = canvas.getBoundingClientRect();\n const distance = pointerEvent.clientY < bounds.top ? pointerEvent.clientY - bounds.top\n : pointerEvent.clientY >= bounds.bottom ? pointerEvent.clientY - bounds.bottom + 1 : 0;\n if (!distance) return;\n autoScroll = setTimeout(() => {\n autoScroll = undefined;\n if (!pointerEvent) return;\n const position = point(pointerEvent, true);\n if (gesture.owner === \"local\" && position) {\n if (selectionClick) selectionClick.dragged = true;\n click.count = 0;\n const lines = Math.sign(distance) * Math.min(8, Math.max(1, Math.ceil(Math.abs(distance) / (bounds.height / rows))));\n inspection.scroll?.(lines, gesture.scrollPoint(position));\n updateAutoScroll();\n }\n }, 60);\n }\n\n function flushMove() {\n if (scheduled !== undefined) cancelAnimationFrame(scheduled);\n scheduled = undefined;\n if (pendingMove) send(pendingMove);\n pendingMove = undefined;\n }\n\n function changeButtons(event: PointerEvent, position: CellPosition): void {\n for (const [button, mask] of buttons) {\n const down = (event.buttons & mask) !== 0;\n if (down === pressed.has(button)) continue;\n flushMove();\n if (down) pressed.add(button);\n else pressed.delete(button);\n if (down || tracking !== 9)\n send({ type: \"mouse\", action: down ? \"down\" : \"up\", button, ...position });\n lastMove = undefined;\n }\n }\n\n function cancel(report = true, cancelled = true) {\n inspection.end?.(cancelled);\n clearTimeout(autoScroll);\n autoScroll = undefined;\n pointerEvent = undefined;\n selectionClick = undefined;\n completedClick = undefined;\n gesture.end();\n routedGesture = undefined;\n if (report) flushMove();\n else {\n if (scheduled !== undefined) cancelAnimationFrame(scheduled);\n scheduled = undefined;\n pendingMove = undefined;\n }\n if (report && tracking !== 9 && lastPoint) {\n for (const button of pressed)\n send({ type: \"mouse\", action: \"up\", button, ...lastPoint });\n }\n pressed.clear();\n const captured = pointerId;\n pointerId = null;\n if (captured !== null && canvas.hasPointerCapture(captured))\n canvas.releasePointerCapture(captured);\n lastMove = undefined;\n wheel.reset();\n wheelOwner = undefined;\n }\n\n canvas.addEventListener(\"pointerdown\", event => {\n if (event.defaultPrevented && pointerId === null) return;\n if (event.pointerType !== \"mouse\" || ![0, 1, 2].includes(event.button)) return;\n const position = point(event);\n if (!position) return;\n if (pointerId !== null) {\n if (routedGesture !== InputRoute.Browser) event.preventDefault();\n if ((gesture.owner === \"app\" || routedGesture === InputRoute.Application) && pointerId === event.pointerId)\n changeButtons(event, position);\n return;\n }\n focus();\n const input: TerminalInput = { type: \"pointer\", button: pointerButtons[event.button],\n point: Object.freeze({ ...position }), ...inputModifiers(event) };\n const decision = inspection.resolve?.(input) ?? { route: InputRoute.Continue };\n const route = decision.action !== undefined ? InputRoute.Consume : decision.route;\n contextMenuRoute = event.button === 2 ? route : undefined;\n if (route !== InputRoute.Continue) {\n completedClick = selectionClick = undefined;\n click.count = 0;\n routedGesture = route;\n pointerId = event.pointerId;\n lastPoint = position;\n canvas.setPointerCapture(pointerId);\n if (route !== InputRoute.Browser) event.preventDefault();\n if (route === InputRoute.Application) flushMove();\n else {\n if (scheduled !== undefined) cancelAnimationFrame(scheduled);\n scheduled = undefined;\n pendingMove = undefined;\n }\n if (route === InputRoute.Application) changeButtons(event, position);\n if (decision.action !== undefined) inspection.execute?.(decision, input);\n return;\n }\n // Keep focus on the hidden keyboard input instead of the canvas.\n event.preventDefault();\n if (event.metaKey) return;\n const now = performance.now();\n click.count = now - click.time < 500 && position.x === click.x && position.y === click.y\n ? click.count % 3 + 1 : 1;\n click = { count: click.count, time: now, x: position.x, y: position.y };\n const start = gesture.begin({ button: event.button, shiftKey: event.shiftKey, altKey: event.altKey,\n detail: event.detail || click.count }, position, state());\n if (!start) return;\n pointerId = event.pointerId;\n pointerEvent = event;\n lastPoint = position;\n completedClick = undefined;\n canvas.setPointerCapture(pointerId);\n if (start.owner === \"local\") {\n if (scheduled !== undefined) cancelAnimationFrame(scheduled);\n scheduled = undefined;\n pendingMove = undefined;\n lastMove = undefined;\n selectionClick = { point: position, mode: start.mode, extend: start.extend, dragged: false };\n inspection.begin?.(position, start);\n }\n else changeButtons(event, position);\n }, options);\n\n canvas.addEventListener(\"pointermove\", event => {\n if (event.pointerType !== \"mouse\") return;\n if (pointerId === null && event.buttons) return;\n if (pointerId !== null && pointerId !== event.pointerId) return;\n const position = point(event, pointerId !== null);\n if (!position) return;\n lastPoint = position;\n if (routedGesture && routedGesture !== InputRoute.Application) return;\n if (gesture.owner === \"local\") {\n pointerEvent = event;\n const previous = gesture.endpoint;\n const endpoint = gesture.move(position);\n if (endpoint && previous && (endpoint.x !== previous.x || endpoint.y !== previous.y)) {\n click.count = 0;\n if (selectionClick) selectionClick.dragged = true;\n inspection.extend?.(endpoint);\n }\n updateAutoScroll();\n return;\n }\n if (!tracking || (!routedGesture && gesture.owner === null && (state().historical || state().readOnly || event.shiftKey))) return;\n if (pointerId === event.pointerId) changeButtons(event, position);\n if (event.metaKey || (tracking !== 1003 && !(tracking === 1002 && pressed.size))) return;\n const button = buttons.find(([name]) => pressed.has(name))?.[0] ?? \"none\";\n const move: MouseCommand = { type: \"mouse\", action: \"move\", button, ...position };\n const key = JSON.stringify(move);\n if (key === lastMove) return;\n lastMove = key;\n pendingMove = move;\n if (scheduled === undefined) scheduled = requestAnimationFrame(flushMove);\n }, options);\n\n canvas.addEventListener(\"pointerup\", event => {\n if (pointerId !== event.pointerId) return;\n const position = point(event, true) ?? lastPoint;\n if (routedGesture) {\n if (routedGesture === InputRoute.Application && position) changeButtons(event, position);\n if (event.buttons === 0) cancel(routedGesture === InputRoute.Application);\n return;\n }\n if (gesture.owner === \"local\") {\n if (position && gesture.endpoint && (position.x !== gesture.endpoint.x || position.y !== gesture.endpoint.y)) {\n if (selectionClick) selectionClick.dragged = true;\n const endpoint = gesture.move(position);\n if (endpoint) inspection.extend?.(endpoint);\n }\n const completed = selectionClick;\n cancel(false, false);\n completedClick = completed;\n return;\n }\n if (position) changeButtons(event, position);\n if (!pressed.size) cancel();\n }, options);\n canvas.addEventListener(\"click\", event => {\n const completed = completedClick;\n completedClick = undefined;\n if (!completed || completed.dragged || !Number.isInteger(event.detail) || event.detail < 1) return;\n click.count = event.detail;\n // Some browsers expose native multiclick counts only on click, not pointerdown.\n const mode = event.detail >= 3 ? \"line\" : event.detail === 2 ? \"word\" : \"character\";\n if (!completed.extend && completed.mode !== \"rectangle\" && mode !== completed.mode)\n inspection.begin?.(completed.point, { mode, extend: false });\n }, options);\n canvas.addEventListener(\"pointercancel\", () => cancel(), options);\n canvas.addEventListener(\"lostpointercapture\", () => {\n if (pointerId !== null) cancel();\n }, options);\n window.addEventListener(\"blur\", () => cancel(), options);\n canvas.addEventListener(\"contextmenu\", event => {\n if (contextMenuRoute !== undefined && contextMenuRoute !== InputRoute.Continue) {\n const route = contextMenuRoute;\n contextMenuRoute = undefined;\n if (route !== InputRoute.Browser) event.preventDefault();\n return;\n }\n if (tracking || gesture.owner === \"local\") event.preventDefault();\n }, options);\n canvas.addEventListener(\"wheel\", event => {\n const input: TerminalInput = { type: \"wheel\", deltaX: event.deltaX, deltaY: event.deltaY,\n deltaMode: event.deltaMode, point: point(event), ...inputModifiers(event) };\n const decision: InputDecision = pointerId === null\n ? inspection.resolve?.(input) ?? { route: InputRoute.Continue }\n : { route: routedGesture ?? InputRoute.Continue };\n if (decision.route === InputRoute.Browser) return;\n if (decision.action !== undefined || decision.route === InputRoute.Consume) {\n event.preventDefault();\n if (decision.action !== undefined) inspection.execute?.(decision, input);\n return;\n }\n // Ctrl+wheel (including trackpad pinch) remains browser zoom.\n if (decision.route !== InputRoute.Application && (event.ctrlKey || event.metaKey)) return;\n const owner = decision.route === InputRoute.Application ? \"app\" : gesture.wheelOwner(event, state());\n if (owner === \"app\" && tracking === 9) return;\n const position = point(gesture.owner === \"local\" && pointerEvent ? pointerEvent : event, gesture.owner === \"local\");\n if (!position) return;\n event.preventDefault();\n flushMove();\n const bounds = canvas.getBoundingClientRect();\n if (wheelOwner !== owner) wheel.reset();\n wheelOwner = owner;\n const { x: horizontal, y: vertical } = wheel.take(event, bounds, rows);\n if (owner === \"local\") {\n if (vertical) {\n if (selectionClick) selectionClick.dragged = true;\n click.count = 0;\n inspection.scroll?.(vertical, gesture.scrollPoint(position));\n }\n return;\n }\n const wheelDirections: [number, MouseButton, MouseButton][] = [\n [vertical, \"wheelUp\", \"wheelDown\"],\n [horizontal, \"wheelLeft\", \"wheelRight\"]\n ];\n for (const [steps, negative, positive] of wheelDirections) {\n if (steps) send({\n type: \"mouse\", action: \"wheel\", button: steps < 0 ? negative : positive,\n count: Math.min(32, Math.abs(steps)), ...position\n });\n }\n }, { ...options, passive: false });\n\n return {\n update(nextColumns, nextRows, nextTracking) {\n if (columns !== nextColumns || rows !== nextRows || tracking !== nextTracking) {\n if (lastPoint) {\n lastPoint = { ...lastPoint,\n x: Math.min(lastPoint.x, nextColumns - 1),\n y: Math.min(lastPoint.y, nextRows - 1)\n };\n }\n // Application mode changes do not transfer ownership mid-gesture.\n if (columns !== nextColumns || rows !== nextRows) cancel(nextTracking !== 0);\n columns = nextColumns;\n rows = nextRows;\n tracking = nextTracking;\n }\n },\n cancel() { cancel(); },\n dispose() {\n cancel(false);\n listeners.abort();\n }\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mouse-input.js","sourceRoot":"","sources":["../src/mouse-input.ts"],"names":[],"mappings":"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","sourcesContent":["import { cellPoint, WheelAccumulator, SelectionGesture } from \"./selection-input.js\";\nimport { InputRoute, inputModifiers } from \"./input-policy.js\";\nimport type { GestureState } from \"./selection-input.js\";\nimport type { InputDecision, InputRouteValue, MouseTrackingMode, PointerButton, SelectionMode,\n TerminalInput, TerminalPoint } from \"./types.js\";\nimport type { CellPosition, MouseButton, MouseCommand } from \"./wire-types.js\";\n\nconst buttons: readonly (readonly [PointerButton, number])[] = [[\"left\", 1], [\"middle\", 4], [\"right\", 2]];\nconst pointerButtons: readonly PointerButton[] = [\"left\", \"middle\", \"right\"];\ninterface SelectionClick { point: TerminalPoint; mode: SelectionMode; extend: boolean; dragged: boolean }\ninterface HyperlinkClick { uri: string; x: number; y: number; dragged: boolean }\ninterface MouseInspection {\n state?: () => Omit<GestureState, \"tracking\">;\n begin?: (point: TerminalPoint, selection: { mode: SelectionMode; extend: boolean }) => void;\n extend?: (point: TerminalPoint) => void;\n scroll?: (delta: number, endpoint?: TerminalPoint) => void;\n end?: (cancelled: boolean) => void;\n resolve?: (input: TerminalInput) => InputDecision;\n execute?: (decision: Extract<InputDecision, { action: unknown }>, input: TerminalInput) => void;\n hyperlink?: (point: TerminalPoint) => string | null;\n openHyperlink?: (uri: string) => void;\n}\nexport interface MouseCapture {\n update(columns: number, rows: number, tracking: MouseTrackingMode): void;\n refresh(): void;\n cancel(): void;\n dispose(): void;\n}\n\n/** Capture input intent only; the server chooses and encodes the mouse protocol. */\nexport function captureMouse(canvas: HTMLCanvasElement, send: (command: MouseCommand) => void,\n focus: () => void, inspection: MouseInspection = {}): MouseCapture {\n const listeners = new AbortController();\n const options = { signal: listeners.signal };\n let columns = 1, rows = 1;\n let tracking: MouseTrackingMode = 0;\n let pointerId: number | null = null;\n const pressed = new Set<PointerButton>();\n let lastPoint: CellPosition | undefined;\n let pendingMove: MouseCommand | undefined;\n let lastMove: string | undefined;\n let scheduled: number | undefined;\n const wheel = new WheelAccumulator();\n const gesture = new SelectionGesture();\n let wheelOwner: \"local\" | \"app\" | undefined;\n let pointerEvent: PointerEvent | undefined;\n let autoScroll: ReturnType<typeof setTimeout> | undefined;\n let click = { count: 0, time: 0, x: -1, y: -1 };\n let selectionClick: SelectionClick | undefined;\n let completedClick: SelectionClick | undefined;\n let routedGesture: InputRouteValue | undefined;\n let contextMenuRoute: InputRouteValue | undefined;\n let hyperlinkClick: HyperlinkClick | undefined;\n let hoverEvent: PointerEvent | undefined;\n let hoverModifiers: Pick<MouseEvent, \"ctrlKey\" | \"metaKey\" | \"altKey\" | \"shiftKey\"> | undefined;\n const originalTitle = canvas.title;\n const originalCursor = canvas.style.cursor;\n const state = () => ({ tracking, ...inspection.state?.() });\n\n function point(event: MouseEvent, clamp = false): CellPosition | null {\n return cellPoint(event, canvas.getBoundingClientRect(), columns, rows, clamp);\n }\n\n function refreshHover(modifiers = hoverModifiers) {\n if (!inspection.hyperlink) return;\n hoverModifiers = modifiers;\n const position = hoverEvent && point(hoverEvent);\n const uri = position ? inspection.hyperlink(position) : null;\n canvas.title = uri ? `${uri}\\nCtrl/Cmd+click to open link` : originalTitle;\n canvas.style.cursor = uri && modifiers && (modifiers.ctrlKey || modifiers.metaKey) &&\n !modifiers.altKey && !modifiers.shiftKey ? \"pointer\" : originalCursor;\n if (hyperlinkClick && hyperlinkClick.uri !== uri) hyperlinkClick.dragged = true;\n }\n\n function updateAutoScroll() {\n clearTimeout(autoScroll);\n autoScroll = undefined;\n if (gesture.owner !== \"local\" || !pointerEvent) return;\n const bounds = canvas.getBoundingClientRect();\n const distance = pointerEvent.clientY < bounds.top ? pointerEvent.clientY - bounds.top\n : pointerEvent.clientY >= bounds.bottom ? pointerEvent.clientY - bounds.bottom + 1 : 0;\n if (!distance) return;\n autoScroll = setTimeout(() => {\n autoScroll = undefined;\n if (!pointerEvent) return;\n const position = point(pointerEvent, true);\n if (gesture.owner === \"local\" && position) {\n if (selectionClick) selectionClick.dragged = true;\n click.count = 0;\n const lines = Math.sign(distance) * Math.min(8, Math.max(1, Math.ceil(Math.abs(distance) / (bounds.height / rows))));\n inspection.scroll?.(lines, gesture.scrollPoint(position));\n updateAutoScroll();\n }\n }, 60);\n }\n\n function flushMove() {\n if (scheduled !== undefined) cancelAnimationFrame(scheduled);\n scheduled = undefined;\n if (pendingMove) send(pendingMove);\n pendingMove = undefined;\n }\n\n function changeButtons(event: PointerEvent, position: CellPosition): void {\n for (const [button, mask] of buttons) {\n const down = (event.buttons & mask) !== 0;\n if (down === pressed.has(button)) continue;\n flushMove();\n if (down) pressed.add(button);\n else pressed.delete(button);\n if (down || tracking !== 9)\n send({ type: \"mouse\", action: down ? \"down\" : \"up\", button, ...position });\n lastMove = undefined;\n }\n }\n\n function cancel(report = true, cancelled = true) {\n inspection.end?.(cancelled);\n clearTimeout(autoScroll);\n autoScroll = undefined;\n pointerEvent = undefined;\n selectionClick = undefined;\n completedClick = undefined;\n hyperlinkClick = undefined;\n gesture.end();\n routedGesture = undefined;\n if (report) flushMove();\n else {\n if (scheduled !== undefined) cancelAnimationFrame(scheduled);\n scheduled = undefined;\n pendingMove = undefined;\n }\n if (report && tracking !== 9 && lastPoint) {\n for (const button of pressed)\n send({ type: \"mouse\", action: \"up\", button, ...lastPoint });\n }\n pressed.clear();\n const captured = pointerId;\n pointerId = null;\n if (captured !== null && canvas.hasPointerCapture(captured))\n canvas.releasePointerCapture(captured);\n lastMove = undefined;\n wheel.reset();\n wheelOwner = undefined;\n }\n\n canvas.addEventListener(\"pointerdown\", event => {\n if (event.defaultPrevented && pointerId === null) return;\n if (event.pointerType !== \"mouse\" || ![0, 1, 2].includes(event.button)) return;\n const position = point(event);\n if (!position) return;\n if (pointerId !== null) {\n if (hyperlinkClick) hyperlinkClick.dragged = true;\n if (routedGesture !== InputRoute.Browser) event.preventDefault();\n if ((gesture.owner === \"app\" || routedGesture === InputRoute.Application) && pointerId === event.pointerId)\n changeButtons(event, position);\n return;\n }\n focus();\n const input: TerminalInput = { type: \"pointer\", button: pointerButtons[event.button],\n point: Object.freeze({ ...position }), ...inputModifiers(event) };\n const decision = inspection.resolve?.(input) ?? { route: InputRoute.Continue };\n let route = decision.action !== undefined ? InputRoute.Consume : decision.route;\n if (route === InputRoute.Continue && event.button === 0 && (event.ctrlKey || event.metaKey) &&\n !event.altKey && !event.shiftKey) {\n const uri = inspection.hyperlink?.(position);\n if (uri) {\n hyperlinkClick = { uri, x: event.clientX, y: event.clientY, dragged: false };\n route = InputRoute.Consume;\n }\n }\n contextMenuRoute = event.button === 2 ? route : undefined;\n if (hyperlinkClick) contextMenuRoute = InputRoute.Consume;\n hoverEvent = event;\n refreshHover(event);\n if (route !== InputRoute.Continue) {\n completedClick = selectionClick = undefined;\n click.count = 0;\n routedGesture = route;\n pointerId = event.pointerId;\n lastPoint = position;\n canvas.setPointerCapture(pointerId);\n if (route !== InputRoute.Browser) event.preventDefault();\n if (route === InputRoute.Application) flushMove();\n else {\n if (scheduled !== undefined) cancelAnimationFrame(scheduled);\n scheduled = undefined;\n pendingMove = undefined;\n }\n if (route === InputRoute.Application) changeButtons(event, position);\n if (decision.action !== undefined) inspection.execute?.(decision, input);\n return;\n }\n // Keep focus on the hidden keyboard input instead of the canvas.\n event.preventDefault();\n if (event.metaKey) return;\n const now = performance.now();\n click.count = now - click.time < 500 && position.x === click.x && position.y === click.y\n ? click.count % 3 + 1 : 1;\n click = { count: click.count, time: now, x: position.x, y: position.y };\n const start = gesture.begin({ button: event.button, shiftKey: event.shiftKey, altKey: event.altKey,\n detail: event.detail || click.count }, position, state());\n if (!start) return;\n pointerId = event.pointerId;\n pointerEvent = event;\n lastPoint = position;\n completedClick = undefined;\n canvas.setPointerCapture(pointerId);\n if (start.owner === \"local\") {\n if (scheduled !== undefined) cancelAnimationFrame(scheduled);\n scheduled = undefined;\n pendingMove = undefined;\n lastMove = undefined;\n selectionClick = { point: position, mode: start.mode, extend: start.extend, dragged: false };\n inspection.begin?.(position, start);\n }\n else changeButtons(event, position);\n }, options);\n\n canvas.addEventListener(\"pointermove\", event => {\n if (event.pointerType !== \"mouse\") return;\n if (pointerId === null && event.buttons) return;\n if (pointerId !== null && pointerId !== event.pointerId) return;\n hoverEvent = event;\n refreshHover(event);\n if (hyperlinkClick && Math.hypot(event.clientX - hyperlinkClick.x, event.clientY - hyperlinkClick.y) >= 4)\n hyperlinkClick.dragged = true;\n const position = point(event, pointerId !== null);\n if (!position) return;\n lastPoint = position;\n if (routedGesture && routedGesture !== InputRoute.Application) return;\n if (gesture.owner === \"local\") {\n pointerEvent = event;\n const previous = gesture.endpoint;\n const endpoint = gesture.move(position);\n if (endpoint && previous && (endpoint.x !== previous.x || endpoint.y !== previous.y)) {\n click.count = 0;\n if (selectionClick) selectionClick.dragged = true;\n inspection.extend?.(endpoint);\n }\n updateAutoScroll();\n return;\n }\n if (!tracking || (!routedGesture && gesture.owner === null && (state().historical || state().readOnly || event.shiftKey))) return;\n if (pointerId === event.pointerId) changeButtons(event, position);\n if (event.metaKey || (tracking !== 1003 && !(tracking === 1002 && pressed.size))) return;\n const button = buttons.find(([name]) => pressed.has(name))?.[0] ?? \"none\";\n const move: MouseCommand = { type: \"mouse\", action: \"move\", button, ...position };\n const key = JSON.stringify(move);\n if (key === lastMove) return;\n lastMove = key;\n pendingMove = move;\n if (scheduled === undefined) scheduled = requestAnimationFrame(flushMove);\n }, options);\n\n canvas.addEventListener(\"pointerup\", event => {\n if (pointerId !== event.pointerId) return;\n if (hyperlinkClick) {\n event.preventDefault();\n const link = hyperlinkClick;\n const position = point(event);\n const activate = event.button === 0 && event.buttons === 0 && !link.dragged &&\n Math.hypot(event.clientX - link.x, event.clientY - link.y) < 4 &&\n position && inspection.hyperlink?.(position) === link.uri;\n if (event.buttons === 0) cancel(false, false);\n else link.dragged = true;\n if (activate) inspection.openHyperlink?.(link.uri);\n return;\n }\n const position = point(event, true) ?? lastPoint;\n if (routedGesture) {\n if (routedGesture === InputRoute.Application && position) changeButtons(event, position);\n if (event.buttons === 0) cancel(routedGesture === InputRoute.Application);\n return;\n }\n if (gesture.owner === \"local\") {\n if (position && gesture.endpoint && (position.x !== gesture.endpoint.x || position.y !== gesture.endpoint.y)) {\n if (selectionClick) selectionClick.dragged = true;\n const endpoint = gesture.move(position);\n if (endpoint) inspection.extend?.(endpoint);\n }\n const completed = selectionClick;\n cancel(false, false);\n completedClick = completed;\n return;\n }\n if (position) changeButtons(event, position);\n if (!pressed.size) cancel();\n }, options);\n canvas.addEventListener(\"click\", event => {\n const completed = completedClick;\n completedClick = undefined;\n if (!completed || completed.dragged || !Number.isInteger(event.detail) || event.detail < 1) return;\n click.count = event.detail;\n // Some browsers expose native multiclick counts only on click, not pointerdown.\n const mode = event.detail >= 3 ? \"line\" : event.detail === 2 ? \"word\" : \"character\";\n if (!completed.extend && completed.mode !== \"rectangle\" && mode !== completed.mode)\n inspection.begin?.(completed.point, { mode, extend: false });\n }, options);\n canvas.addEventListener(\"pointercancel\", () => cancel(), options);\n canvas.addEventListener(\"pointerleave\", () => {\n hoverEvent = undefined;\n refreshHover();\n }, options);\n canvas.addEventListener(\"lostpointercapture\", () => {\n if (pointerId !== null) cancel();\n }, options);\n window.addEventListener(\"blur\", () => {\n cancel();\n hoverEvent = undefined;\n refreshHover();\n }, options);\n window.addEventListener(\"keydown\", event => refreshHover(event), { ...options, capture: true });\n window.addEventListener(\"keyup\", event => refreshHover(event), { ...options, capture: true });\n canvas.addEventListener(\"contextmenu\", event => {\n if (contextMenuRoute !== undefined && contextMenuRoute !== InputRoute.Continue) {\n const route = contextMenuRoute;\n contextMenuRoute = undefined;\n if (route !== InputRoute.Browser) event.preventDefault();\n return;\n }\n if (tracking || gesture.owner === \"local\") event.preventDefault();\n }, options);\n canvas.addEventListener(\"wheel\", event => {\n if (hyperlinkClick) hyperlinkClick.dragged = true;\n const input: TerminalInput = { type: \"wheel\", deltaX: event.deltaX, deltaY: event.deltaY,\n deltaMode: event.deltaMode, point: point(event), ...inputModifiers(event) };\n const decision: InputDecision = pointerId === null\n ? inspection.resolve?.(input) ?? { route: InputRoute.Continue }\n : { route: routedGesture ?? InputRoute.Continue };\n if (decision.route === InputRoute.Browser) return;\n if (decision.action !== undefined || decision.route === InputRoute.Consume) {\n event.preventDefault();\n if (decision.action !== undefined) inspection.execute?.(decision, input);\n return;\n }\n // Ctrl+wheel (including trackpad pinch) remains browser zoom.\n if (decision.route !== InputRoute.Application && (event.ctrlKey || event.metaKey)) return;\n const owner = decision.route === InputRoute.Application ? \"app\" : gesture.wheelOwner(event, state());\n if (owner === \"app\" && tracking === 9) return;\n const position = point(gesture.owner === \"local\" && pointerEvent ? pointerEvent : event, gesture.owner === \"local\");\n if (!position) return;\n event.preventDefault();\n flushMove();\n const bounds = canvas.getBoundingClientRect();\n if (wheelOwner !== owner) wheel.reset();\n wheelOwner = owner;\n const { x: horizontal, y: vertical } = wheel.take(event, bounds, rows);\n if (owner === \"local\") {\n if (vertical) {\n if (selectionClick) selectionClick.dragged = true;\n click.count = 0;\n inspection.scroll?.(vertical, gesture.scrollPoint(position));\n }\n return;\n }\n const wheelDirections: [number, MouseButton, MouseButton][] = [\n [vertical, \"wheelUp\", \"wheelDown\"],\n [horizontal, \"wheelLeft\", \"wheelRight\"]\n ];\n for (const [steps, negative, positive] of wheelDirections) {\n if (steps) send({\n type: \"mouse\", action: \"wheel\", button: steps < 0 ? negative : positive,\n count: Math.min(32, Math.abs(steps)), ...position\n });\n }\n }, { ...options, passive: false });\n\n return {\n update(nextColumns, nextRows, nextTracking) {\n if (columns !== nextColumns || rows !== nextRows || tracking !== nextTracking) {\n if (lastPoint) {\n lastPoint = { ...lastPoint,\n x: Math.min(lastPoint.x, nextColumns - 1),\n y: Math.min(lastPoint.y, nextRows - 1)\n };\n }\n // Application mode changes do not transfer ownership mid-gesture.\n if (columns !== nextColumns || rows !== nextRows) cancel(nextTracking !== 0);\n columns = nextColumns;\n rows = nextRows;\n tracking = nextTracking;\n }\n refreshHover();\n },\n refresh() { refreshHover(); },\n cancel() { cancel(); },\n dispose() {\n cancel(false);\n listeners.abort();\n canvas.title = originalTitle;\n canvas.style.cursor = originalCursor;\n }\n };\n}\n"]}
|
package/dist/protocol.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,eAAe,EAAiB,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIlH,eAAO,MAAM,MAAM;;;;;;;;EAQjB,CAAC;AAKH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAGxD;AAyBD,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,IAAI,eAAe,GAAG,IAAI,CAqC1H;
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,eAAe,EAAiB,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIlH,eAAO,MAAM,MAAM;;;;;;;;EAQjB,CAAC;AAKH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAGxD;AAyBD,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,IAAI,eAAe,GAAG,IAAI,CAqC1H;AA+GD,8FAA8F;AAC9F,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,aAAa,CAiD1D;AAED,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,YAAY,GAAG,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAY9G"}
|
package/dist/protocol.js
CHANGED
|
@@ -116,6 +116,20 @@ function validateMetadata(metadata) {
|
|
|
116
116
|
}
|
|
117
117
|
integer(columns * rows, "cell count", 1, LIMITS.cells);
|
|
118
118
|
validateHistory(metadata.history, columns, rows);
|
|
119
|
+
array(metadata.hyperlinks, "hyperlinks", columns * rows);
|
|
120
|
+
let previousLinkEnd = 0;
|
|
121
|
+
for (const link of metadata.hyperlinks) {
|
|
122
|
+
if (!isRecord(link))
|
|
123
|
+
throw new Error("Invalid hyperlink");
|
|
124
|
+
const row = integer(link.row, "hyperlink row", 0, rows - 1);
|
|
125
|
+
const start = integer(link.startColumn, "hyperlink start column", 0, columns - 1);
|
|
126
|
+
const end = integer(link.endColumn, "hyperlink end column", start + 1, columns);
|
|
127
|
+
if (row * columns + start < previousLinkEnd)
|
|
128
|
+
throw new Error("Unordered or overlapping hyperlinks");
|
|
129
|
+
previousLinkEnd = row * columns + end;
|
|
130
|
+
if (typeof link.uri !== "string" || !link.uri.length || link.uri.length > LIMITS.metadataBytes)
|
|
131
|
+
throw new Error("Invalid hyperlink URI");
|
|
132
|
+
}
|
|
119
133
|
if (metadata.cellWidth !== 10 || metadata.cellHeight !== 20) {
|
|
120
134
|
throw new Error("This spike requires server geometry of 10 × 20 logical pixels");
|
|
121
135
|
}
|
package/dist/protocol.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FrameMetadata, HistoryMetadata, SelectionText, TerminalCell, TerminalFrame } from \"./wire-types.js\";\nimport { isRecord } from \"./validation.js\";\n\n// Binary validation is deliberately independent of the GPU and the transport.\nexport const LIMITS = Object.freeze({\n commandBytes: 64 * 1024,\n frameBytes: 96 * 1024 * 1024,\n metadataBytes: 8 * 1024 * 1024,\n cells: 262144,\n images: 4096,\n placements: 16384,\n textureBytes: 256 * 1024 * 1024,\n});\n\nconst utf8 = new TextDecoder(\"utf-8\", { fatal: true });\nconst utf8Encoder = new TextEncoder();\n\nexport function assertCommandSize(command: unknown): void {\n if (utf8Encoder.encode(JSON.stringify(command)).byteLength > LIMITS.commandBytes)\n throw new RangeError(\"Terminal input exceeds the 64 KiB message limit. Send a smaller amount of text.\");\n}\n\nfunction integer(value: unknown, name: string, min = 0, max = Number.MAX_SAFE_INTEGER): number {\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < min || value > max) {\n throw new Error(`Invalid ${name}: ${String(value)}`);\n }\n return value;\n}\n\nfunction array(value: unknown, name: string, limit: number): asserts value is unknown[] {\n if (!Array.isArray(value) || value.length > limit) throw new Error(`Invalid ${name}`);\n}\n\nfunction key(value: unknown): asserts value is string {\n if (typeof value !== \"string\" || !value.length || value.length > 1024) {\n throw new Error(\"Invalid image key\");\n }\n}\n\nfunction rowId(value: unknown, name: string): asserts value is string {\n if (typeof value !== \"string\" || !/^[1-9][0-9]{0,18}$/u.test(value) || BigInt(value) > 9223372036854775807n) {\n throw new Error(`Invalid ${name}`);\n }\n}\n\nexport function validateHistory(history: unknown, columns: number, rows: number): asserts history is HistoryMetadata | null {\n if (history === null) return;\n if (!isRecord(history)) throw new Error(\"Missing history metadata\");\n rowId(history.generation, \"history generation\");\n if (history.buffer !== \"main\" && history.buffer !== \"alternate\") throw new Error(\"Invalid history buffer\");\n const totalRows = integer(history.totalRows, \"history total rows\", rows, 2147483647);\n const liveTop = integer(history.liveTop, \"history live top\", 0, totalRows - rows);\n if (liveTop !== totalRows - rows) throw new Error(\"Inconsistent history extent\");\n integer(history.top, \"history top\", 0, liveTop);\n if (typeof history.following !== \"boolean\" || (history.following && history.top !== history.liveTop)) {\n throw new Error(\"Invalid history following state\");\n }\n integer(history.requestId, \"viewport request id\");\n array(history.rowIds, \"viewport row ids\", rows);\n if (history.rowIds.length !== rows || new Set(history.rowIds).size !== rows) throw new Error(\"Invalid viewport row ids\");\n for (const id of history.rowIds) rowId(id, \"viewport row id\");\n const selection = history.selection;\n if (!isRecord(selection) || typeof selection.status !== \"string\" ||\n ![\"none\", \"valid\", \"invalidated\"].includes(selection.status)) throw new Error(\"Invalid selection status\");\n integer(selection.requestId, \"selection request id\");\n if (typeof selection.mode !== \"string\" || ![\"character\", \"word\", \"line\", \"rectangle\"].includes(selection.mode)) throw new Error(\"Invalid selection mode\");\n array(selection.ranges, \"selection ranges\", rows);\n let previousRow = -1;\n for (const range of selection.ranges) {\n if (!isRecord(range)) throw new Error(\"Invalid selection range\");\n const row = integer(range.row, \"selection range row\", previousRow + 1, rows - 1);\n const startColumn = integer(range.startColumn, \"selection start column\", 0, columns - 1);\n integer(range.endColumn, \"selection end column\", startColumn + 1, columns);\n previousRow = row;\n }\n validateSelectionText(selection);\n if (selection.status !== \"valid\" && selection.ranges.length) throw new Error(\"Inactive selection has highlight ranges\");\n if (history.copy !== null) {\n if (!isRecord(history.copy)) throw new Error(\"Missing copy metadata\");\n integer(history.copy.requestId, \"copy request id\", 1);\n validateSelectionText(history.copy);\n }\n}\n\nfunction validateSelectionText(selection: Record<string, unknown>): asserts selection is Record<string, unknown> & SelectionText {\n if (typeof selection.status !== \"string\" || ![\"none\", \"valid\", \"invalidated\"].includes(selection.status) ||\n (selection.status === \"valid\"\n ? typeof selection.text !== \"string\" || selection.text.length > LIMITS.metadataBytes\n : selection.text !== null)) {\n throw new Error(\"Invalid selection text\");\n }\n}\n\nfunction validateMetadata(metadata: unknown): asserts metadata is FrameMetadata {\n if (!isRecord(metadata) || metadata.version !== 1 || typeof metadata.full !== \"boolean\") {\n throw new Error(\"Unsupported frame metadata version\");\n }\n integer(metadata.revision, \"revision\", 1);\n integer(metadata.baseRevision, \"base revision\");\n const columns = integer(metadata.columns, \"columns\", 1, 1024);\n const rows = integer(metadata.rows, \"rows\", 1, 512);\n if (typeof metadata.mouseTracking !== \"number\" || ![0, 9, 1000, 1002, 1003].includes(metadata.mouseTracking)) {\n throw new Error(\"Unsupported mouse tracking mode\");\n }\n if (!isRecord(metadata.peer) || typeof metadata.peer.isPrimary !== \"boolean\") throw new Error(\"Invalid peer state\");\n for (const field of [\"id\", \"primaryId\"]) {\n const id = metadata.peer[field];\n if (id !== null && (typeof id !== \"string\" || !id.length || id.length > 256)) {\n throw new Error(`Invalid peer ${field}`);\n }\n }\n if (metadata.peer.id !== null && metadata.peer.isPrimary !== (metadata.peer.id === metadata.peer.primaryId)) {\n throw new Error(\"Inconsistent primary peer state\");\n }\n integer(columns * rows, \"cell count\", 1, LIMITS.cells);\n validateHistory(metadata.history, columns, rows);\n if (metadata.cellWidth !== 10 || metadata.cellHeight !== 20) {\n throw new Error(\"This spike requires server geometry of 10 × 20 logical pixels\");\n }\n for (const field of [\"defaultBackground\", \"defaultForeground\"]) {\n if (metadata[field] !== undefined) integer(metadata[field], field, 0, 0xffffffff);\n }\n if (!isRecord(metadata.cursor) || typeof metadata.cursor.visible !== \"boolean\") throw new Error(\"Invalid cursor\");\n integer(metadata.cursor.x, \"cursor x\", -1, 1024);\n integer(metadata.cursor.y, \"cursor y\", -1, 512);\n const shapes = [\"Default\", \"BlinkingBlock\", \"SteadyBlock\", \"BlinkingUnderline\", \"SteadyUnderline\", \"BlinkingBar\", \"SteadyBar\"];\n if (typeof metadata.cursor.shape === \"string\") metadata.cursor.shape = shapes.indexOf(metadata.cursor.shape);\n integer(metadata.cursor.shape, \"cursor shape\", 0, 6);\n array(metadata.images, \"images\", LIMITS.images);\n array(metadata.retainedImages, \"retained image keys\", LIMITS.images);\n array(metadata.placements, \"placements\", LIMITS.placements);\n array(metadata.warnings, \"warnings\", 256);\n if (metadata.warnings.some(w => typeof w !== \"string\")) throw new Error(\"Invalid warning\");\n if (!isRecord(metadata.stats)) throw new Error(\"Invalid server metrics\");\n for (const field of [\"workloadBytes\", \"outputBatches\", \"captureMs\", \"elapsedMs\"]) {\n const metric = metadata.stats[field];\n if (typeof metric !== \"number\" || !Number.isFinite(metric) || metric < 0) {\n throw new Error(`Invalid server metric ${field}`);\n }\n }\n const retained = new Set<string>();\n for (const imageKey of metadata.retainedImages) {\n key(imageKey);\n if (retained.has(imageKey)) throw new Error(\"Duplicate retained image key\");\n retained.add(imageKey);\n }\n const imageKeys = new Set<string>();\n let decodedImageBytes = 0;\n for (const image of metadata.images) {\n if (!isRecord(image)) throw new Error(\"Invalid image\");\n key(image.key);\n if (imageKeys.has(image.key) || !retained.has(image.key)) throw new Error(\"Inconsistent new image keys\");\n imageKeys.add(image.key);\n const width = integer(image.width, \"image width\", 1, 16384);\n const height = integer(image.height, \"image height\", 1, 16384);\n const byteLength = integer(image.byteLength, \"image byte length\", 1, LIMITS.frameBytes);\n if (image.format !== \"rgba\" && image.format !== \"png\") throw new Error(\"Unsupported image format\");\n if (image.format === \"rgba\" && byteLength !== width * height * 4) {\n throw new Error(\"RGBA image size mismatch\");\n }\n decodedImageBytes += width * height * 4;\n if (decodedImageBytes > LIMITS.textureBytes) throw new Error(\"New images exceed decoded texture budget\");\n }\n for (const placement of metadata.placements) {\n if (!isRecord(placement)) throw new Error(\"Invalid placement\");\n key(placement.key);\n if (!retained.has(placement.key)) throw new Error(\"Placement references an unretained image\");\n if (placement.kind !== \"kgp\" && placement.kind !== \"sixel\") throw new Error(\"Invalid placement kind\");\n for (const field of [\"x\", \"y\", \"width\", \"height\", \"sourceX\", \"sourceY\", \"sourceWidth\", \"sourceHeight\", \"clipX\", \"clipY\", \"clipWidth\", \"clipHeight\", \"z\"]) {\n const coordinate = placement[field];\n if (typeof coordinate !== \"number\" || !Number.isFinite(coordinate) || Math.abs(coordinate) > 2147483648) {\n throw new Error(`Invalid placement ${field}`);\n }\n }\n for (const field of [\"width\", \"height\", \"sourceWidth\", \"sourceHeight\", \"clipWidth\", \"clipHeight\"]) {\n const coordinate = placement[field];\n if (typeof coordinate !== \"number\" || coordinate < 0) throw new Error(`Negative placement ${field}`);\n }\n }\n}\n\n/** Decode one complete, experimental HWT1 message, checking every boundary before reading. */\nexport function decodeFrame(buffer: unknown): TerminalFrame {\n if (!(buffer instanceof ArrayBuffer) || buffer.byteLength > LIMITS.frameBytes) {\n throw new Error(\"Invalid or oversized binary frame\");\n }\n const view = new DataView(buffer);\n let offset = 0;\n const requireBytes = (count: number) => {\n if (count < 0 || count > view.byteLength - offset) throw new Error(\"Truncated HWT1 frame\");\n };\n const u32 = () => { requireBytes(4); const n = view.getUint32(offset, true); offset += 4; return n; };\n if (u32() !== 0x31545748) throw new Error(\"Unsupported frame magic (expected HWT1)\");\n const metadataLength = integer(u32(), \"metadata length\", 2, LIMITS.metadataBytes);\n requireBytes(metadataLength);\n const metadata: unknown = JSON.parse(utf8.decode(new Uint8Array(buffer, offset, metadataLength)));\n offset += metadataLength;\n validateMetadata(metadata);\n const cellCount = metadata.columns * metadata.rows;\n const changedCount = integer(u32(), \"changed cell count\", 0, cellCount);\n if (changedCount > Math.floor((view.byteLength - offset) / 22)) throw new Error(\"Truncated cell records\");\n if (metadata.full && changedCount !== cellCount) throw new Error(\"Incomplete full frame\");\n const cells = [];\n const seen = new Set();\n for (let i = 0; i < changedCount; i++) {\n requireBytes(22);\n const index = u32();\n if (index >= cellCount || seen.has(index)) throw new Error(\"Invalid or duplicate cell index\");\n seen.add(index);\n const foreground = u32();\n const background = u32();\n const underlineColor = u32();\n const attributes = view.getUint16(offset, true);\n const width = view.getUint8(offset + 2);\n const underlineStyle = view.getUint8(offset + 3);\n const textLength = view.getUint16(offset + 4, true);\n offset += 6;\n if (underlineStyle > 5) throw new Error(\"Unsupported underline style\");\n requireBytes(textLength);\n const text = utf8.decode(new Uint8Array(buffer, offset, textLength));\n offset += textLength;\n cells.push({ index, foreground, background, underlineColor, attributes, width, underlineStyle, text });\n }\n const imageBytes = metadata.images.reduce((total, image) => total + image.byteLength, 0);\n if (imageBytes !== view.byteLength - offset) throw new Error(\"Image payload length mismatch\");\n const images = metadata.images.map(image => {\n const bytes = new Uint8Array(buffer, offset, image.byteLength);\n offset += image.byteLength;\n return { ...image, bytes };\n });\n return { metadata, cells, images };\n}\n\n/** Mirror text, not ANSI; continuation cells are already represented by their lead glyph. */\nexport function screenText(cells: readonly (TerminalCell | undefined)[], columns: number, rows: number): string {\n const lines = [];\n for (let y = 0; y < rows; y++) {\n let line = \"\";\n for (let x = 0; x < columns; x++) {\n const cell = cells[y * columns + x];\n if (!cell || cell.width === 0) continue;\n line += cell.attributes & 64 ? \" \".repeat(cell.width) : (cell.text || \" \");\n }\n lines.push(line.replace(/ +$/u, \"\"));\n }\n return lines.join(\"\\n\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,8EAA8E;AAC9E,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAClC,YAAY,EAAE,EAAE,GAAG,IAAI;IACvB,UAAU,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;IAC5B,aAAa,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI;IAC9B,KAAK,EAAE,MAAM;IACb,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,KAAK;IACjB,YAAY,EAAE,GAAG,GAAG,IAAI,GAAG,IAAI;CAChC,CAAC,CAAC;AAEH,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACvD,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;AAEtC,MAAM,UAAU,iBAAiB,CAAC,OAAgB;IAChD,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,GAAG,MAAM,CAAC,YAAY;QAC9E,MAAM,IAAI,UAAU,CAAC,iFAAiF,CAAC,CAAC;AAC5G,CAAC;AAED,SAAS,OAAO,CAAC,KAAc,EAAE,IAAY,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,MAAM,CAAC,gBAAgB;IACnF,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,GAAG,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;QAC5F,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,KAAK,CAAC,KAAc,EAAE,IAAY,EAAE,KAAa;IACxD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;AACxF,CAAC;AAED,SAAS,GAAG,CAAC,KAAc;IACzB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;QACtE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,KAAc,EAAE,IAAY;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,oBAAoB,EAAE,CAAC;QAC5G,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;IACrC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAgB,EAAE,OAAe,EAAE,IAAY;IAC7E,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO;IAC7B,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACpE,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;IAChD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,WAAW;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC3G,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,oBAAoB,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IACrF,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,kBAAkB,EAAE,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC;IAClF,IAAI,OAAO,KAAK,SAAS,GAAG,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjF,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;IAChD,IAAI,OAAO,OAAO,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,KAAK,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACrG,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC;IAClD,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;IAChD,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI,IAAI,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACzH,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,MAAM;QAAE,KAAK,CAAC,EAAE,EAAE,iBAAiB,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IACpC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,OAAO,SAAS,CAAC,MAAM,KAAK,QAAQ;QAC5D,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9G,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAC;IACrD,IAAI,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC1J,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;IAClD,IAAI,WAAW,GAAG,CAAC,CAAC,CAAC;IACrB,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;QACrC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACjE,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,qBAAqB,EAAE,WAAW,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;QACjF,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,wBAAwB,EAAE,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;QACzF,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,sBAAsB,EAAE,WAAW,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;QAC3E,WAAW,GAAG,GAAG,CAAC;IACpB,CAAC;IACD,qBAAqB,CAAC,SAAS,CAAC,CAAC;IACjC,IAAI,SAAS,CAAC,MAAM,KAAK,OAAO,IAAI,SAAS,CAAC,MAAM,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IACxH,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACtE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC;QACtD,qBAAqB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,SAAkC;IAC/D,IAAI,OAAO,SAAS,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC;QACpG,CAAC,SAAS,CAAC,MAAM,KAAK,OAAO;YAC3B,CAAC,CAAC,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,aAAa;YACpF,CAAC,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAiB;IACzC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,OAAO,KAAK,CAAC,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACxF,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9D,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,IAAI,OAAO,QAAQ,CAAC,aAAa,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QAC7G,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACpH,KAAK,MAAM,KAAK,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC;QACxC,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC;YAC7E,MAAM,IAAI,KAAK,CAAC,gBAAgB,KAAK,EAAE,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5G,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,CAAC,OAAO,GAAG,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACvD,eAAe,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACjD,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC,CAAC;IACzD,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;QACvC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,EAAE,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,wBAAwB,EAAE,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;QAClF,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,sBAAsB,EAAE,KAAK,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;QAChF,IAAI,GAAG,GAAG,OAAO,GAAG,KAAK,GAAG,eAAe;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACpG,eAAe,GAAG,GAAG,GAAG,OAAO,GAAG,GAAG,CAAC;QACtC,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,aAAa;YAC5F,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,QAAQ,CAAC,SAAS,KAAK,EAAE,IAAI,QAAQ,CAAC,UAAU,KAAK,EAAE,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,EAAE,CAAC;QAC/D,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,SAAS;YAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;IACpF,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,OAAO,QAAQ,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAClH,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,CAAC,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;IAC/H,IAAI,OAAO,QAAQ,CAAC,MAAM,CAAC,KAAK,KAAK,QAAQ;QAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7G,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACrD,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAChD,KAAK,CAAC,QAAQ,CAAC,cAAc,EAAE,qBAAqB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACrE,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,YAAY,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAC5D,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IAC1C,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC3F,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACzE,KAAK,MAAM,KAAK,IAAI,CAAC,eAAe,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;QACjF,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACzE,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,cAAc,EAAE,CAAC;QAC/C,GAAG,CAAC,QAAQ,CAAC,CAAC;QACd,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC5E,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,IAAI,iBAAiB,GAAG,CAAC,CAAC;IAC1B,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;QACvD,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACf,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACzG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACzB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,aAAa,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAC/D,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,mBAAmB,EAAE,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QACxF,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QACnG,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,UAAU,KAAK,KAAK,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC;YACjE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACD,iBAAiB,IAAI,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC;QACxC,IAAI,iBAAiB,GAAG,MAAM,CAAC,YAAY;YAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC3G,CAAC;IACD,KAAK,MAAM,SAAS,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;QAC5C,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC/D,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC9F,IAAI,SAAS,CAAC,IAAI,KAAK,KAAK,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACtG,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,CAAC,EAAE,CAAC;YACzJ,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,UAAU,EAAE,CAAC;gBACxG,MAAM,IAAI,KAAK,CAAC,qBAAqB,KAAK,EAAE,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE,CAAC;YAClG,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,GAAG,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,KAAK,EAAE,CAAC,CAAC;QACvG,CAAC;IACH,CAAC;AACH,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,WAAW,CAAC,MAAe;IACzC,IAAI,CAAC,CAAC,MAAM,YAAY,WAAW,CAAC,IAAI,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAC9E,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,YAAY,GAAG,CAAC,KAAa,EAAE,EAAE;QACrC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,UAAU,GAAG,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC7F,CAAC,CAAC;IACF,MAAM,GAAG,GAAG,GAAG,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACtG,IAAI,GAAG,EAAE,KAAK,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IACrF,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,EAAE,EAAE,iBAAiB,EAAE,CAAC,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;IAClF,YAAY,CAAC,cAAc,CAAC,CAAC;IAC7B,MAAM,QAAQ,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IAClG,MAAM,IAAI,cAAc,CAAC;IACzB,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC3B,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC;IACnD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,EAAE,oBAAoB,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;IACxE,IAAI,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC1G,IAAI,QAAQ,CAAC,IAAI,IAAI,YAAY,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC1F,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,YAAY,CAAC,EAAE,CAAC,CAAC;QACjB,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC;QACpB,IAAI,KAAK,IAAI,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QAC9F,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChB,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC;QACzB,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC;QAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACxC,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;QACpD,MAAM,IAAI,CAAC,CAAC;QACZ,IAAI,cAAc,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACvE,YAAY,CAAC,UAAU,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;QACrE,MAAM,IAAI,UAAU,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;IACzG,CAAC;IACD,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IACzF,IAAI,UAAU,KAAK,IAAI,CAAC,UAAU,GAAG,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC9F,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QACzC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QAC/D,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC;QAC3B,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACrC,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,UAAU,CAAC,KAA4C,EAAE,OAAe,EAAE,IAAY;IACpG,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC;gBAAE,SAAS;YACxC,IAAI,IAAI,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;QAC7E,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC","sourcesContent":["import type { FrameMetadata, HistoryMetadata, SelectionText, TerminalCell, TerminalFrame } from \"./wire-types.js\";\nimport { isRecord } from \"./validation.js\";\n\n// Binary validation is deliberately independent of the GPU and the transport.\nexport const LIMITS = Object.freeze({\n commandBytes: 64 * 1024,\n frameBytes: 96 * 1024 * 1024,\n metadataBytes: 8 * 1024 * 1024,\n cells: 262144,\n images: 4096,\n placements: 16384,\n textureBytes: 256 * 1024 * 1024,\n});\n\nconst utf8 = new TextDecoder(\"utf-8\", { fatal: true });\nconst utf8Encoder = new TextEncoder();\n\nexport function assertCommandSize(command: unknown): void {\n if (utf8Encoder.encode(JSON.stringify(command)).byteLength > LIMITS.commandBytes)\n throw new RangeError(\"Terminal input exceeds the 64 KiB message limit. Send a smaller amount of text.\");\n}\n\nfunction integer(value: unknown, name: string, min = 0, max = Number.MAX_SAFE_INTEGER): number {\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < min || value > max) {\n throw new Error(`Invalid ${name}: ${String(value)}`);\n }\n return value;\n}\n\nfunction array(value: unknown, name: string, limit: number): asserts value is unknown[] {\n if (!Array.isArray(value) || value.length > limit) throw new Error(`Invalid ${name}`);\n}\n\nfunction key(value: unknown): asserts value is string {\n if (typeof value !== \"string\" || !value.length || value.length > 1024) {\n throw new Error(\"Invalid image key\");\n }\n}\n\nfunction rowId(value: unknown, name: string): asserts value is string {\n if (typeof value !== \"string\" || !/^[1-9][0-9]{0,18}$/u.test(value) || BigInt(value) > 9223372036854775807n) {\n throw new Error(`Invalid ${name}`);\n }\n}\n\nexport function validateHistory(history: unknown, columns: number, rows: number): asserts history is HistoryMetadata | null {\n if (history === null) return;\n if (!isRecord(history)) throw new Error(\"Missing history metadata\");\n rowId(history.generation, \"history generation\");\n if (history.buffer !== \"main\" && history.buffer !== \"alternate\") throw new Error(\"Invalid history buffer\");\n const totalRows = integer(history.totalRows, \"history total rows\", rows, 2147483647);\n const liveTop = integer(history.liveTop, \"history live top\", 0, totalRows - rows);\n if (liveTop !== totalRows - rows) throw new Error(\"Inconsistent history extent\");\n integer(history.top, \"history top\", 0, liveTop);\n if (typeof history.following !== \"boolean\" || (history.following && history.top !== history.liveTop)) {\n throw new Error(\"Invalid history following state\");\n }\n integer(history.requestId, \"viewport request id\");\n array(history.rowIds, \"viewport row ids\", rows);\n if (history.rowIds.length !== rows || new Set(history.rowIds).size !== rows) throw new Error(\"Invalid viewport row ids\");\n for (const id of history.rowIds) rowId(id, \"viewport row id\");\n const selection = history.selection;\n if (!isRecord(selection) || typeof selection.status !== \"string\" ||\n ![\"none\", \"valid\", \"invalidated\"].includes(selection.status)) throw new Error(\"Invalid selection status\");\n integer(selection.requestId, \"selection request id\");\n if (typeof selection.mode !== \"string\" || ![\"character\", \"word\", \"line\", \"rectangle\"].includes(selection.mode)) throw new Error(\"Invalid selection mode\");\n array(selection.ranges, \"selection ranges\", rows);\n let previousRow = -1;\n for (const range of selection.ranges) {\n if (!isRecord(range)) throw new Error(\"Invalid selection range\");\n const row = integer(range.row, \"selection range row\", previousRow + 1, rows - 1);\n const startColumn = integer(range.startColumn, \"selection start column\", 0, columns - 1);\n integer(range.endColumn, \"selection end column\", startColumn + 1, columns);\n previousRow = row;\n }\n validateSelectionText(selection);\n if (selection.status !== \"valid\" && selection.ranges.length) throw new Error(\"Inactive selection has highlight ranges\");\n if (history.copy !== null) {\n if (!isRecord(history.copy)) throw new Error(\"Missing copy metadata\");\n integer(history.copy.requestId, \"copy request id\", 1);\n validateSelectionText(history.copy);\n }\n}\n\nfunction validateSelectionText(selection: Record<string, unknown>): asserts selection is Record<string, unknown> & SelectionText {\n if (typeof selection.status !== \"string\" || ![\"none\", \"valid\", \"invalidated\"].includes(selection.status) ||\n (selection.status === \"valid\"\n ? typeof selection.text !== \"string\" || selection.text.length > LIMITS.metadataBytes\n : selection.text !== null)) {\n throw new Error(\"Invalid selection text\");\n }\n}\n\nfunction validateMetadata(metadata: unknown): asserts metadata is FrameMetadata {\n if (!isRecord(metadata) || metadata.version !== 1 || typeof metadata.full !== \"boolean\") {\n throw new Error(\"Unsupported frame metadata version\");\n }\n integer(metadata.revision, \"revision\", 1);\n integer(metadata.baseRevision, \"base revision\");\n const columns = integer(metadata.columns, \"columns\", 1, 1024);\n const rows = integer(metadata.rows, \"rows\", 1, 512);\n if (typeof metadata.mouseTracking !== \"number\" || ![0, 9, 1000, 1002, 1003].includes(metadata.mouseTracking)) {\n throw new Error(\"Unsupported mouse tracking mode\");\n }\n if (!isRecord(metadata.peer) || typeof metadata.peer.isPrimary !== \"boolean\") throw new Error(\"Invalid peer state\");\n for (const field of [\"id\", \"primaryId\"]) {\n const id = metadata.peer[field];\n if (id !== null && (typeof id !== \"string\" || !id.length || id.length > 256)) {\n throw new Error(`Invalid peer ${field}`);\n }\n }\n if (metadata.peer.id !== null && metadata.peer.isPrimary !== (metadata.peer.id === metadata.peer.primaryId)) {\n throw new Error(\"Inconsistent primary peer state\");\n }\n integer(columns * rows, \"cell count\", 1, LIMITS.cells);\n validateHistory(metadata.history, columns, rows);\n array(metadata.hyperlinks, \"hyperlinks\", columns * rows);\n let previousLinkEnd = 0;\n for (const link of metadata.hyperlinks) {\n if (!isRecord(link)) throw new Error(\"Invalid hyperlink\");\n const row = integer(link.row, \"hyperlink row\", 0, rows - 1);\n const start = integer(link.startColumn, \"hyperlink start column\", 0, columns - 1);\n const end = integer(link.endColumn, \"hyperlink end column\", start + 1, columns);\n if (row * columns + start < previousLinkEnd) throw new Error(\"Unordered or overlapping hyperlinks\");\n previousLinkEnd = row * columns + end;\n if (typeof link.uri !== \"string\" || !link.uri.length || link.uri.length > LIMITS.metadataBytes)\n throw new Error(\"Invalid hyperlink URI\");\n }\n if (metadata.cellWidth !== 10 || metadata.cellHeight !== 20) {\n throw new Error(\"This spike requires server geometry of 10 × 20 logical pixels\");\n }\n for (const field of [\"defaultBackground\", \"defaultForeground\"]) {\n if (metadata[field] !== undefined) integer(metadata[field], field, 0, 0xffffffff);\n }\n if (!isRecord(metadata.cursor) || typeof metadata.cursor.visible !== \"boolean\") throw new Error(\"Invalid cursor\");\n integer(metadata.cursor.x, \"cursor x\", -1, 1024);\n integer(metadata.cursor.y, \"cursor y\", -1, 512);\n const shapes = [\"Default\", \"BlinkingBlock\", \"SteadyBlock\", \"BlinkingUnderline\", \"SteadyUnderline\", \"BlinkingBar\", \"SteadyBar\"];\n if (typeof metadata.cursor.shape === \"string\") metadata.cursor.shape = shapes.indexOf(metadata.cursor.shape);\n integer(metadata.cursor.shape, \"cursor shape\", 0, 6);\n array(metadata.images, \"images\", LIMITS.images);\n array(metadata.retainedImages, \"retained image keys\", LIMITS.images);\n array(metadata.placements, \"placements\", LIMITS.placements);\n array(metadata.warnings, \"warnings\", 256);\n if (metadata.warnings.some(w => typeof w !== \"string\")) throw new Error(\"Invalid warning\");\n if (!isRecord(metadata.stats)) throw new Error(\"Invalid server metrics\");\n for (const field of [\"workloadBytes\", \"outputBatches\", \"captureMs\", \"elapsedMs\"]) {\n const metric = metadata.stats[field];\n if (typeof metric !== \"number\" || !Number.isFinite(metric) || metric < 0) {\n throw new Error(`Invalid server metric ${field}`);\n }\n }\n const retained = new Set<string>();\n for (const imageKey of metadata.retainedImages) {\n key(imageKey);\n if (retained.has(imageKey)) throw new Error(\"Duplicate retained image key\");\n retained.add(imageKey);\n }\n const imageKeys = new Set<string>();\n let decodedImageBytes = 0;\n for (const image of metadata.images) {\n if (!isRecord(image)) throw new Error(\"Invalid image\");\n key(image.key);\n if (imageKeys.has(image.key) || !retained.has(image.key)) throw new Error(\"Inconsistent new image keys\");\n imageKeys.add(image.key);\n const width = integer(image.width, \"image width\", 1, 16384);\n const height = integer(image.height, \"image height\", 1, 16384);\n const byteLength = integer(image.byteLength, \"image byte length\", 1, LIMITS.frameBytes);\n if (image.format !== \"rgba\" && image.format !== \"png\") throw new Error(\"Unsupported image format\");\n if (image.format === \"rgba\" && byteLength !== width * height * 4) {\n throw new Error(\"RGBA image size mismatch\");\n }\n decodedImageBytes += width * height * 4;\n if (decodedImageBytes > LIMITS.textureBytes) throw new Error(\"New images exceed decoded texture budget\");\n }\n for (const placement of metadata.placements) {\n if (!isRecord(placement)) throw new Error(\"Invalid placement\");\n key(placement.key);\n if (!retained.has(placement.key)) throw new Error(\"Placement references an unretained image\");\n if (placement.kind !== \"kgp\" && placement.kind !== \"sixel\") throw new Error(\"Invalid placement kind\");\n for (const field of [\"x\", \"y\", \"width\", \"height\", \"sourceX\", \"sourceY\", \"sourceWidth\", \"sourceHeight\", \"clipX\", \"clipY\", \"clipWidth\", \"clipHeight\", \"z\"]) {\n const coordinate = placement[field];\n if (typeof coordinate !== \"number\" || !Number.isFinite(coordinate) || Math.abs(coordinate) > 2147483648) {\n throw new Error(`Invalid placement ${field}`);\n }\n }\n for (const field of [\"width\", \"height\", \"sourceWidth\", \"sourceHeight\", \"clipWidth\", \"clipHeight\"]) {\n const coordinate = placement[field];\n if (typeof coordinate !== \"number\" || coordinate < 0) throw new Error(`Negative placement ${field}`);\n }\n }\n}\n\n/** Decode one complete, experimental HWT1 message, checking every boundary before reading. */\nexport function decodeFrame(buffer: unknown): TerminalFrame {\n if (!(buffer instanceof ArrayBuffer) || buffer.byteLength > LIMITS.frameBytes) {\n throw new Error(\"Invalid or oversized binary frame\");\n }\n const view = new DataView(buffer);\n let offset = 0;\n const requireBytes = (count: number) => {\n if (count < 0 || count > view.byteLength - offset) throw new Error(\"Truncated HWT1 frame\");\n };\n const u32 = () => { requireBytes(4); const n = view.getUint32(offset, true); offset += 4; return n; };\n if (u32() !== 0x31545748) throw new Error(\"Unsupported frame magic (expected HWT1)\");\n const metadataLength = integer(u32(), \"metadata length\", 2, LIMITS.metadataBytes);\n requireBytes(metadataLength);\n const metadata: unknown = JSON.parse(utf8.decode(new Uint8Array(buffer, offset, metadataLength)));\n offset += metadataLength;\n validateMetadata(metadata);\n const cellCount = metadata.columns * metadata.rows;\n const changedCount = integer(u32(), \"changed cell count\", 0, cellCount);\n if (changedCount > Math.floor((view.byteLength - offset) / 22)) throw new Error(\"Truncated cell records\");\n if (metadata.full && changedCount !== cellCount) throw new Error(\"Incomplete full frame\");\n const cells = [];\n const seen = new Set();\n for (let i = 0; i < changedCount; i++) {\n requireBytes(22);\n const index = u32();\n if (index >= cellCount || seen.has(index)) throw new Error(\"Invalid or duplicate cell index\");\n seen.add(index);\n const foreground = u32();\n const background = u32();\n const underlineColor = u32();\n const attributes = view.getUint16(offset, true);\n const width = view.getUint8(offset + 2);\n const underlineStyle = view.getUint8(offset + 3);\n const textLength = view.getUint16(offset + 4, true);\n offset += 6;\n if (underlineStyle > 5) throw new Error(\"Unsupported underline style\");\n requireBytes(textLength);\n const text = utf8.decode(new Uint8Array(buffer, offset, textLength));\n offset += textLength;\n cells.push({ index, foreground, background, underlineColor, attributes, width, underlineStyle, text });\n }\n const imageBytes = metadata.images.reduce((total, image) => total + image.byteLength, 0);\n if (imageBytes !== view.byteLength - offset) throw new Error(\"Image payload length mismatch\");\n const images = metadata.images.map(image => {\n const bytes = new Uint8Array(buffer, offset, image.byteLength);\n offset += image.byteLength;\n return { ...image, bytes };\n });\n return { metadata, cells, images };\n}\n\n/** Mirror text, not ANSI; continuation cells are already represented by their lead glyph. */\nexport function screenText(cells: readonly (TerminalCell | undefined)[], columns: number, rows: number): string {\n const lines = [];\n for (let y = 0; y < rows; y++) {\n let line = \"\";\n for (let x = 0; x < columns; x++) {\n const cell = cells[y * columns + x];\n if (!cell || cell.width === 0) continue;\n line += cell.attributes & 64 ? \" \".repeat(cell.width) : (cell.text || \" \");\n }\n lines.push(line.replace(/ +$/u, \"\"));\n }\n return lines.join(\"\\n\");\n}\n"]}
|
package/dist/terminal-worker.js
CHANGED
|
@@ -123,7 +123,7 @@ async function drawFrame() {
|
|
|
123
123
|
type: "geometry", columns: metadata.columns, rows: metadata.rows,
|
|
124
124
|
cellWidth: metadata.cellWidth, cellHeight: metadata.cellHeight,
|
|
125
125
|
mouseTracking: metadata.mouseTracking, peer: metadata.peer,
|
|
126
|
-
history: metadata.history, revision: frame.revision, text
|
|
126
|
+
history: metadata.history, revision: frame.revision, text, hyperlinks: metadata.hyperlinks
|
|
127
127
|
});
|
|
128
128
|
send({ type: "ack", revision: frame.revision });
|
|
129
129
|
emitStats(text);
|