@opentui/core 0.1.86 → 0.1.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.
@@ -1793,600 +1793,9 @@ var BorderCharArrays = {
1793
1793
  heavy: borderCharsToArray(BorderChars.heavy)
1794
1794
  };
1795
1795
 
1796
- // src/lib/parse.keypress.ts
1797
- import { Buffer as Buffer2 } from "buffer";
1798
-
1799
- // src/lib/parse.keypress-kitty.ts
1800
- var kittyKeyMap = {
1801
- 27: "escape",
1802
- 9: "tab",
1803
- 13: "return",
1804
- 127: "backspace",
1805
- 57344: "escape",
1806
- 57345: "return",
1807
- 57346: "tab",
1808
- 57347: "backspace",
1809
- 57348: "insert",
1810
- 57349: "delete",
1811
- 57350: "left",
1812
- 57351: "right",
1813
- 57352: "up",
1814
- 57353: "down",
1815
- 57354: "pageup",
1816
- 57355: "pagedown",
1817
- 57356: "home",
1818
- 57357: "end",
1819
- 57364: "f1",
1820
- 57365: "f2",
1821
- 57366: "f3",
1822
- 57367: "f4",
1823
- 57368: "f5",
1824
- 57369: "f6",
1825
- 57370: "f7",
1826
- 57371: "f8",
1827
- 57372: "f9",
1828
- 57373: "f10",
1829
- 57374: "f11",
1830
- 57375: "f12",
1831
- 57376: "f13",
1832
- 57377: "f14",
1833
- 57378: "f15",
1834
- 57379: "f16",
1835
- 57380: "f17",
1836
- 57381: "f18",
1837
- 57382: "f19",
1838
- 57383: "f20",
1839
- 57384: "f21",
1840
- 57385: "f22",
1841
- 57386: "f23",
1842
- 57387: "f24",
1843
- 57388: "f25",
1844
- 57389: "f26",
1845
- 57390: "f27",
1846
- 57391: "f28",
1847
- 57392: "f29",
1848
- 57393: "f30",
1849
- 57394: "f31",
1850
- 57395: "f32",
1851
- 57396: "f33",
1852
- 57397: "f34",
1853
- 57398: "f35",
1854
- 57399: "kp0",
1855
- 57400: "kp1",
1856
- 57401: "kp2",
1857
- 57402: "kp3",
1858
- 57403: "kp4",
1859
- 57404: "kp5",
1860
- 57405: "kp6",
1861
- 57406: "kp7",
1862
- 57407: "kp8",
1863
- 57408: "kp9",
1864
- 57409: "kpdecimal",
1865
- 57410: "kpdivide",
1866
- 57411: "kpmultiply",
1867
- 57412: "kpminus",
1868
- 57413: "kpplus",
1869
- 57414: "kpenter",
1870
- 57415: "kpequal",
1871
- 57428: "mediaplay",
1872
- 57429: "mediapause",
1873
- 57430: "mediaplaypause",
1874
- 57431: "mediareverse",
1875
- 57432: "mediastop",
1876
- 57433: "mediafastforward",
1877
- 57434: "mediarewind",
1878
- 57435: "medianext",
1879
- 57436: "mediaprev",
1880
- 57437: "mediarecord",
1881
- 57438: "volumedown",
1882
- 57439: "volumeup",
1883
- 57440: "mute",
1884
- 57441: "leftshift",
1885
- 57442: "leftctrl",
1886
- 57443: "leftalt",
1887
- 57444: "leftsuper",
1888
- 57445: "lefthyper",
1889
- 57446: "leftmeta",
1890
- 57447: "rightshift",
1891
- 57448: "rightctrl",
1892
- 57449: "rightalt",
1893
- 57450: "rightsuper",
1894
- 57451: "righthyper",
1895
- 57452: "rightmeta",
1896
- 57453: "iso_level3_shift",
1897
- 57454: "iso_level5_shift"
1898
- };
1899
- function fromKittyMods(mod) {
1900
- return {
1901
- shift: !!(mod & 1),
1902
- alt: !!(mod & 2),
1903
- ctrl: !!(mod & 4),
1904
- super: !!(mod & 8),
1905
- hyper: !!(mod & 16),
1906
- meta: !!(mod & 32),
1907
- capsLock: !!(mod & 64),
1908
- numLock: !!(mod & 128)
1909
- };
1910
- }
1911
- var functionalKeyMap = {
1912
- A: "up",
1913
- B: "down",
1914
- C: "right",
1915
- D: "left",
1916
- H: "home",
1917
- F: "end",
1918
- P: "f1",
1919
- Q: "f2",
1920
- R: "f3",
1921
- S: "f4"
1922
- };
1923
- var tildeKeyMap = {
1924
- "1": "home",
1925
- "2": "insert",
1926
- "3": "delete",
1927
- "4": "end",
1928
- "5": "pageup",
1929
- "6": "pagedown",
1930
- "7": "home",
1931
- "8": "end",
1932
- "11": "f1",
1933
- "12": "f2",
1934
- "13": "f3",
1935
- "14": "f4",
1936
- "15": "f5",
1937
- "17": "f6",
1938
- "18": "f7",
1939
- "19": "f8",
1940
- "20": "f9",
1941
- "21": "f10",
1942
- "23": "f11",
1943
- "24": "f12"
1944
- };
1945
- function parseKittySpecialKey(sequence) {
1946
- const specialKeyRe = /^\x1b\[(\d+);(\d+):(\d+)([A-Z~])$/;
1947
- const match = specialKeyRe.exec(sequence);
1948
- if (!match)
1949
- return null;
1950
- const keyNumOrOne = match[1];
1951
- const modifierStr = match[2];
1952
- const eventTypeStr = match[3];
1953
- const terminator = match[4];
1954
- let keyName;
1955
- if (terminator === "~") {
1956
- keyName = tildeKeyMap[keyNumOrOne];
1957
- } else {
1958
- if (keyNumOrOne !== "1")
1959
- return null;
1960
- keyName = functionalKeyMap[terminator];
1961
- }
1962
- if (!keyName)
1963
- return null;
1964
- const key = {
1965
- name: keyName,
1966
- ctrl: false,
1967
- meta: false,
1968
- shift: false,
1969
- option: false,
1970
- number: false,
1971
- sequence,
1972
- raw: sequence,
1973
- eventType: "press",
1974
- source: "kitty",
1975
- super: false,
1976
- hyper: false,
1977
- capsLock: false,
1978
- numLock: false
1979
- };
1980
- if (modifierStr) {
1981
- const modifierMask = parseInt(modifierStr, 10);
1982
- if (!isNaN(modifierMask) && modifierMask > 1) {
1983
- const mods = fromKittyMods(modifierMask - 1);
1984
- key.shift = mods.shift;
1985
- key.ctrl = mods.ctrl;
1986
- key.meta = mods.alt || mods.meta;
1987
- key.option = mods.alt;
1988
- key.super = mods.super;
1989
- key.hyper = mods.hyper;
1990
- key.capsLock = mods.capsLock;
1991
- key.numLock = mods.numLock;
1992
- }
1993
- }
1994
- if (eventTypeStr === "1" || !eventTypeStr) {
1995
- key.eventType = "press";
1996
- } else if (eventTypeStr === "2") {
1997
- key.eventType = "press";
1998
- key.repeated = true;
1999
- } else if (eventTypeStr === "3") {
2000
- key.eventType = "release";
2001
- }
2002
- return key;
2003
- }
2004
- function parseKittyKeyboard(sequence) {
2005
- const specialResult = parseKittySpecialKey(sequence);
2006
- if (specialResult)
2007
- return specialResult;
2008
- const kittyRe = /^\x1b\[([^\x1b]+)u$/;
2009
- const match = kittyRe.exec(sequence);
2010
- if (!match)
2011
- return null;
2012
- const params = match[1];
2013
- const fields = params.split(";");
2014
- if (fields.length < 1)
2015
- return null;
2016
- const key = {
2017
- name: "",
2018
- ctrl: false,
2019
- meta: false,
2020
- shift: false,
2021
- option: false,
2022
- number: false,
2023
- sequence,
2024
- raw: sequence,
2025
- eventType: "press",
2026
- source: "kitty",
2027
- super: false,
2028
- hyper: false,
2029
- capsLock: false,
2030
- numLock: false
2031
- };
2032
- let text = "";
2033
- const field1 = fields[0]?.split(":") || [];
2034
- const codepointStr = field1[0];
2035
- if (!codepointStr)
2036
- return null;
2037
- const codepoint = parseInt(codepointStr, 10);
2038
- if (isNaN(codepoint))
2039
- return null;
2040
- let shiftedCodepoint;
2041
- let baseCodepoint;
2042
- if (field1[1]) {
2043
- const shifted = parseInt(field1[1], 10);
2044
- if (!isNaN(shifted) && shifted > 0 && shifted <= 1114111) {
2045
- shiftedCodepoint = shifted;
2046
- }
2047
- }
2048
- if (field1[2]) {
2049
- const base = parseInt(field1[2], 10);
2050
- if (!isNaN(base) && base > 0 && base <= 1114111) {
2051
- baseCodepoint = base;
2052
- }
2053
- }
2054
- const knownKey = kittyKeyMap[codepoint];
2055
- if (knownKey) {
2056
- key.name = knownKey;
2057
- key.code = `[${codepoint}u`;
2058
- } else {
2059
- if (codepoint > 0 && codepoint <= 1114111) {
2060
- const char = String.fromCodePoint(codepoint);
2061
- key.name = char;
2062
- if (baseCodepoint) {
2063
- key.baseCode = baseCodepoint;
2064
- }
2065
- } else {
2066
- return null;
2067
- }
2068
- }
2069
- if (fields[1]) {
2070
- const field2 = fields[1].split(":");
2071
- const modifierStr = field2[0];
2072
- const eventTypeStr = field2[1];
2073
- if (modifierStr) {
2074
- const modifierMask = parseInt(modifierStr, 10);
2075
- if (!isNaN(modifierMask) && modifierMask > 1) {
2076
- const mods = fromKittyMods(modifierMask - 1);
2077
- key.shift = mods.shift;
2078
- key.ctrl = mods.ctrl;
2079
- key.meta = mods.alt || mods.meta;
2080
- key.option = mods.alt;
2081
- key.super = mods.super;
2082
- key.hyper = mods.hyper;
2083
- key.capsLock = mods.capsLock;
2084
- key.numLock = mods.numLock;
2085
- }
2086
- }
2087
- if (eventTypeStr === "1" || !eventTypeStr) {
2088
- key.eventType = "press";
2089
- } else if (eventTypeStr === "2") {
2090
- key.eventType = "press";
2091
- key.repeated = true;
2092
- } else if (eventTypeStr === "3") {
2093
- key.eventType = "release";
2094
- } else {
2095
- key.eventType = "press";
2096
- }
2097
- }
2098
- if (fields[2]) {
2099
- const codepoints = fields[2].split(":");
2100
- for (const cpStr of codepoints) {
2101
- const cp = parseInt(cpStr, 10);
2102
- if (!isNaN(cp) && cp > 0 && cp <= 1114111) {
2103
- text += String.fromCodePoint(cp);
2104
- }
2105
- }
2106
- }
2107
- if (text === "") {
2108
- const isPrintable = key.name.length > 0 && !kittyKeyMap[codepoint];
2109
- if (isPrintable) {
2110
- if (key.shift && shiftedCodepoint) {
2111
- text = String.fromCodePoint(shiftedCodepoint);
2112
- } else if (key.shift && key.name.length === 1) {
2113
- text = key.name.toLocaleUpperCase();
2114
- } else {
2115
- text = key.name;
2116
- }
2117
- }
2118
- }
2119
- if (key.name === " " && key.shift && !key.ctrl && !key.meta) {
2120
- text = " ";
2121
- }
2122
- if (text) {
2123
- key.sequence = text;
2124
- }
2125
- return key;
2126
- }
2127
-
2128
- // src/lib/parse.keypress.ts
2129
- var metaKeyCodeRe = /^(?:\x1b)([a-zA-Z0-9])$/;
2130
- var fnKeyRe = /^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/;
2131
- var keyName = {
2132
- OP: "f1",
2133
- OQ: "f2",
2134
- OR: "f3",
2135
- OS: "f4",
2136
- "[11~": "f1",
2137
- "[12~": "f2",
2138
- "[13~": "f3",
2139
- "[14~": "f4",
2140
- "[[A": "f1",
2141
- "[[B": "f2",
2142
- "[[C": "f3",
2143
- "[[D": "f4",
2144
- "[[E": "f5",
2145
- "[15~": "f5",
2146
- "[17~": "f6",
2147
- "[18~": "f7",
2148
- "[19~": "f8",
2149
- "[20~": "f9",
2150
- "[21~": "f10",
2151
- "[23~": "f11",
2152
- "[24~": "f12",
2153
- "[A": "up",
2154
- "[B": "down",
2155
- "[C": "right",
2156
- "[D": "left",
2157
- "[E": "clear",
2158
- "[F": "end",
2159
- "[H": "home",
2160
- OA: "up",
2161
- OB: "down",
2162
- OC: "right",
2163
- OD: "left",
2164
- OE: "clear",
2165
- OF: "end",
2166
- OH: "home",
2167
- "[1~": "home",
2168
- "[2~": "insert",
2169
- "[3~": "delete",
2170
- "[4~": "end",
2171
- "[5~": "pageup",
2172
- "[6~": "pagedown",
2173
- "[[5~": "pageup",
2174
- "[[6~": "pagedown",
2175
- "[7~": "home",
2176
- "[8~": "end",
2177
- "[a": "up",
2178
- "[b": "down",
2179
- "[c": "right",
2180
- "[d": "left",
2181
- "[e": "clear",
2182
- f: "right",
2183
- b: "left",
2184
- p: "up",
2185
- n: "down",
2186
- "[2$": "insert",
2187
- "[3$": "delete",
2188
- "[5$": "pageup",
2189
- "[6$": "pagedown",
2190
- "[7$": "home",
2191
- "[8$": "end",
2192
- Oa: "up",
2193
- Ob: "down",
2194
- Oc: "right",
2195
- Od: "left",
2196
- Oe: "clear",
2197
- "[2^": "insert",
2198
- "[3^": "delete",
2199
- "[5^": "pageup",
2200
- "[6^": "pagedown",
2201
- "[7^": "home",
2202
- "[8^": "end",
2203
- "[Z": "tab"
2204
- };
2205
- var nonAlphanumericKeys = [...Object.values(keyName), "backspace"];
2206
- var isShiftKey = (code) => {
2207
- return ["[a", "[b", "[c", "[d", "[e", "[2$", "[3$", "[5$", "[6$", "[7$", "[8$", "[Z"].includes(code);
2208
- };
2209
- var isCtrlKey = (code) => {
2210
- return ["Oa", "Ob", "Oc", "Od", "Oe", "[2^", "[3^", "[5^", "[6^", "[7^", "[8^"].includes(code);
2211
- };
2212
- var modifyOtherKeysRe = /^\x1b\[27;(\d+);(\d+)~$/;
2213
- var parseKeypress = (s = "", options = {}) => {
2214
- let parts;
2215
- if (Buffer2.isBuffer(s)) {
2216
- if (s[0] > 127 && s[1] === undefined) {
2217
- s[0] -= 128;
2218
- s = "\x1B" + String(s);
2219
- } else {
2220
- s = String(s);
2221
- }
2222
- } else if (s !== undefined && typeof s !== "string") {
2223
- s = String(s);
2224
- } else if (!s) {
2225
- s = "";
2226
- }
2227
- if (/^\x1b\[<\d+;\d+;\d+[Mm]$/.test(s)) {
2228
- return null;
2229
- }
2230
- if (s.startsWith("\x1B[M") && s.length >= 6) {
2231
- return null;
2232
- }
2233
- if (/^\x1b\[\d+;\d+;\d+t$/.test(s)) {
2234
- return null;
2235
- }
2236
- if (/^\x1b\[\d+;\d+R$/.test(s)) {
2237
- return null;
2238
- }
2239
- if (/^\x1b\[\?[\d;]+c$/.test(s)) {
2240
- return null;
2241
- }
2242
- if (/^\x1b\[\?[\d;]+\$y$/.test(s)) {
2243
- return null;
2244
- }
2245
- if (s === "\x1B[I" || s === "\x1B[O") {
2246
- return null;
2247
- }
2248
- if (/^\x1b\][\d;].*(\x1b\\|\x07)$/.test(s)) {
2249
- return null;
2250
- }
2251
- if (s === "\x1B[200~" || s === "\x1B[201~") {
2252
- return null;
2253
- }
2254
- const key = {
2255
- name: "",
2256
- ctrl: false,
2257
- meta: false,
2258
- shift: false,
2259
- option: false,
2260
- number: false,
2261
- sequence: s,
2262
- raw: s,
2263
- eventType: "press",
2264
- source: "raw"
2265
- };
2266
- key.sequence = key.sequence || s || key.name;
2267
- if (options.useKittyKeyboard) {
2268
- const kittyResult = parseKittyKeyboard(s);
2269
- if (kittyResult) {
2270
- return kittyResult;
2271
- }
2272
- }
2273
- const modifyOtherKeysMatch = modifyOtherKeysRe.exec(s);
2274
- if (modifyOtherKeysMatch) {
2275
- const modifier = parseInt(modifyOtherKeysMatch[1], 10) - 1;
2276
- const charCode = parseInt(modifyOtherKeysMatch[2], 10);
2277
- key.ctrl = !!(modifier & 4);
2278
- key.meta = !!(modifier & 2);
2279
- key.shift = !!(modifier & 1);
2280
- key.option = !!(modifier & 2);
2281
- key.super = !!(modifier & 8);
2282
- key.hyper = !!(modifier & 16);
2283
- if (charCode === 13) {
2284
- key.name = "return";
2285
- } else if (charCode === 27) {
2286
- key.name = "escape";
2287
- } else if (charCode === 9) {
2288
- key.name = "tab";
2289
- } else if (charCode === 32) {
2290
- key.name = "space";
2291
- } else if (charCode === 127 || charCode === 8) {
2292
- key.name = "backspace";
2293
- } else {
2294
- const char = String.fromCharCode(charCode);
2295
- key.name = char;
2296
- key.sequence = char;
2297
- if (charCode >= 48 && charCode <= 57) {
2298
- key.number = true;
2299
- }
2300
- }
2301
- return key;
2302
- }
2303
- if (s === "\r" || s === "\x1B\r") {
2304
- key.name = "return";
2305
- key.meta = s.length === 2;
2306
- } else if (s === `
2307
- ` || s === `\x1B
2308
- `) {
2309
- key.name = "linefeed";
2310
- key.meta = s.length === 2;
2311
- } else if (s === "\t") {
2312
- key.name = "tab";
2313
- } else if (s === "\b" || s === "\x1B\b" || s === "\x7F" || s === "\x1B\x7F") {
2314
- key.name = "backspace";
2315
- key.meta = s.charAt(0) === "\x1B";
2316
- } else if (s === "\x1B" || s === "\x1B\x1B") {
2317
- key.name = "escape";
2318
- key.meta = s.length === 2;
2319
- } else if (s === " " || s === "\x1B ") {
2320
- key.name = "space";
2321
- key.meta = s.length === 2;
2322
- } else if (s === "\x00") {
2323
- key.name = "space";
2324
- key.ctrl = true;
2325
- } else if (s.length === 1 && s <= "\x1A") {
2326
- key.name = String.fromCharCode(s.charCodeAt(0) + 97 - 1);
2327
- key.ctrl = true;
2328
- } else if (s.length === 1 && s >= "0" && s <= "9") {
2329
- key.name = s;
2330
- key.number = true;
2331
- } else if (s.length === 1 && s >= "a" && s <= "z") {
2332
- key.name = s;
2333
- } else if (s.length === 1 && s >= "A" && s <= "Z") {
2334
- key.name = s.toLowerCase();
2335
- key.shift = true;
2336
- } else if (s.length === 1) {
2337
- key.name = s;
2338
- } else if (parts = metaKeyCodeRe.exec(s)) {
2339
- key.meta = true;
2340
- const char = parts[1];
2341
- const isUpperCase = /^[A-Z]$/.test(char);
2342
- if (char === "F") {
2343
- key.name = "right";
2344
- } else if (char === "B") {
2345
- key.name = "left";
2346
- } else if (isUpperCase) {
2347
- key.shift = true;
2348
- key.name = char;
2349
- } else {
2350
- key.name = char;
2351
- }
2352
- } else if (s.length === 2 && s[0] === "\x1B" && s[1] <= "\x1A") {
2353
- key.meta = true;
2354
- key.ctrl = true;
2355
- key.name = String.fromCharCode(s.charCodeAt(1) + 97 - 1);
2356
- } else if (parts = fnKeyRe.exec(s)) {
2357
- const segs = [...s];
2358
- if (segs[0] === "\x1B" && segs[1] === "\x1B") {
2359
- key.option = true;
2360
- key.meta = true;
2361
- }
2362
- const code = [parts[1], parts[2], parts[4], parts[6]].filter(Boolean).join("");
2363
- const modifier = parseInt(parts[3] || parts[5] || "1", 10) - 1;
2364
- key.ctrl = !!(modifier & 4);
2365
- key.meta = !!(modifier & 2);
2366
- key.shift = !!(modifier & 1);
2367
- key.option = !!(modifier & 2);
2368
- key.super = !!(modifier & 8);
2369
- key.hyper = !!(modifier & 16);
2370
- key.code = code;
2371
- const keyNameResult = keyName[code];
2372
- if (keyNameResult) {
2373
- key.name = keyNameResult;
2374
- key.shift = isShiftKey(code) || key.shift;
2375
- key.ctrl = isCtrlKey(code) || key.ctrl;
2376
- } else {
2377
- key.name = "";
2378
- key.code = undefined;
2379
- }
2380
- } else if (s === "\x1B[3~") {
2381
- key.name = "delete";
2382
- key.meta = false;
2383
- key.code = "[3~";
2384
- }
2385
- return key;
2386
- };
2387
-
2388
1796
  // src/lib/KeyHandler.ts
2389
1797
  import { EventEmitter } from "events";
1798
+
2390
1799
  class KeyEvent {
2391
1800
  name;
2392
1801
  ctrl;
@@ -2462,16 +1871,7 @@ class PasteEvent {
2462
1871
  }
2463
1872
 
2464
1873
  class KeyHandler extends EventEmitter {
2465
- useKittyKeyboard;
2466
- constructor(useKittyKeyboard = false) {
2467
- super();
2468
- this.useKittyKeyboard = useKittyKeyboard;
2469
- }
2470
- processInput(data) {
2471
- const parsedKey = parseKeypress(data, { useKittyKeyboard: this.useKittyKeyboard });
2472
- if (!parsedKey) {
2473
- return false;
2474
- }
1874
+ processParsedKey(parsedKey) {
2475
1875
  try {
2476
1876
  switch (parsedKey.eventType) {
2477
1877
  case "press":
@@ -2485,7 +1885,7 @@ class KeyHandler extends EventEmitter {
2485
1885
  break;
2486
1886
  }
2487
1887
  } catch (error) {
2488
- console.error(`[KeyHandler] Error processing input:`, error);
1888
+ console.error(`[KeyHandler] Error processing parsed key:`, error);
2489
1889
  return true;
2490
1890
  }
2491
1891
  return true;
@@ -2502,9 +1902,6 @@ class KeyHandler extends EventEmitter {
2502
1902
 
2503
1903
  class InternalKeyHandler extends KeyHandler {
2504
1904
  renderableHandlers = new Map;
2505
- constructor(useKittyKeyboard = false) {
2506
- super(useKittyKeyboard);
2507
- }
2508
1905
  emit(event, ...args) {
2509
1906
  return this.emitWithPriority(event, ...args);
2510
1907
  }
@@ -5498,15 +4895,119 @@ function getParsedFont(fontKey) {
5498
4895
  chars: parsedChars
5499
4896
  };
5500
4897
  }
5501
- return parsedFonts[fontKey];
4898
+ return parsedFonts[fontKey];
4899
+ }
4900
+ function measureText({ text, font = "tiny" }) {
4901
+ const fontDef = getParsedFont(font);
4902
+ if (!fontDef) {
4903
+ console.warn(`Font '${font}' not found`);
4904
+ return { width: 0, height: 0 };
4905
+ }
4906
+ let currentX = 0;
4907
+ for (let i = 0;i < text.length; i++) {
4908
+ const char = text[i].toUpperCase();
4909
+ const charDef = fontDef.chars[char];
4910
+ if (!charDef) {
4911
+ const spaceChar = fontDef.chars[" "];
4912
+ if (spaceChar && spaceChar[0]) {
4913
+ let spaceWidth = 0;
4914
+ for (const segment of spaceChar[0]) {
4915
+ spaceWidth += segment.text.length;
4916
+ }
4917
+ currentX += spaceWidth;
4918
+ } else {
4919
+ currentX += 1;
4920
+ }
4921
+ continue;
4922
+ }
4923
+ let charWidth = 0;
4924
+ if (charDef[0]) {
4925
+ for (const segment of charDef[0]) {
4926
+ charWidth += segment.text.length;
4927
+ }
4928
+ }
4929
+ currentX += charWidth;
4930
+ if (i < text.length - 1) {
4931
+ currentX += fontDef.letterspace_size;
4932
+ }
4933
+ }
4934
+ return {
4935
+ width: currentX,
4936
+ height: fontDef.lines
4937
+ };
4938
+ }
4939
+ function getCharacterPositions(text, font = "tiny") {
4940
+ const fontDef = getParsedFont(font);
4941
+ if (!fontDef) {
4942
+ return [0];
4943
+ }
4944
+ const positions = [0];
4945
+ let currentX = 0;
4946
+ for (let i = 0;i < text.length; i++) {
4947
+ const char = text[i].toUpperCase();
4948
+ const charDef = fontDef.chars[char];
4949
+ let charWidth = 0;
4950
+ if (!charDef) {
4951
+ const spaceChar = fontDef.chars[" "];
4952
+ if (spaceChar && spaceChar[0]) {
4953
+ for (const segment of spaceChar[0]) {
4954
+ charWidth += segment.text.length;
4955
+ }
4956
+ } else {
4957
+ charWidth = 1;
4958
+ }
4959
+ } else if (charDef[0]) {
4960
+ for (const segment of charDef[0]) {
4961
+ charWidth += segment.text.length;
4962
+ }
4963
+ }
4964
+ currentX += charWidth;
4965
+ if (i < text.length - 1) {
4966
+ currentX += fontDef.letterspace_size;
4967
+ }
4968
+ positions.push(currentX);
4969
+ }
4970
+ return positions;
4971
+ }
4972
+ function coordinateToCharacterIndex(x, text, font = "tiny") {
4973
+ const positions = getCharacterPositions(text, font);
4974
+ if (x < 0) {
4975
+ return 0;
4976
+ }
4977
+ for (let i = 0;i < positions.length - 1; i++) {
4978
+ const currentPos = positions[i];
4979
+ const nextPos = positions[i + 1];
4980
+ if (x >= currentPos && x < nextPos) {
4981
+ const charMidpoint = currentPos + (nextPos - currentPos) / 2;
4982
+ return x < charMidpoint ? i : i + 1;
4983
+ }
4984
+ }
4985
+ if (positions.length > 0 && x >= positions[positions.length - 1]) {
4986
+ return text.length;
4987
+ }
4988
+ return 0;
5502
4989
  }
5503
- function measureText({ text, font = "tiny" }) {
4990
+ function renderFontToFrameBuffer(buffer, {
4991
+ text,
4992
+ x = 0,
4993
+ y = 0,
4994
+ color = [RGBA.fromInts(255, 255, 255, 255)],
4995
+ backgroundColor = RGBA.fromInts(0, 0, 0, 255),
4996
+ font = "tiny"
4997
+ }) {
4998
+ const width = buffer.width;
4999
+ const height = buffer.height;
5504
5000
  const fontDef = getParsedFont(font);
5505
5001
  if (!fontDef) {
5506
5002
  console.warn(`Font '${font}' not found`);
5507
5003
  return { width: 0, height: 0 };
5508
5004
  }
5509
- let currentX = 0;
5005
+ const colors = Array.isArray(color) ? color : [color];
5006
+ if (y < 0 || y + fontDef.lines > height) {
5007
+ return { width: 0, height: fontDef.lines };
5008
+ }
5009
+ let currentX = x;
5010
+ const startX = x;
5510
5011
  for (let i = 0;i < text.length; i++) {
5511
5012
  const char = text[i].toUpperCase();
5512
5013
  const charDef = fontDef.chars[char];
@@ -5529,704 +5030,945 @@ function measureText({ text, font = "tiny" }) {
5529
5030
  charWidth += segment.text.length;
5530
5031
  }
5531
5032
  }
5033
+ if (currentX >= width)
5034
+ break;
5035
+ if (currentX + charWidth < 0) {
5036
+ currentX += charWidth + fontDef.letterspace_size;
5037
+ continue;
5038
+ }
5039
+ for (let lineIdx = 0;lineIdx < fontDef.lines && lineIdx < charDef.length; lineIdx++) {
5040
+ const segments = charDef[lineIdx];
5041
+ const renderY = y + lineIdx;
5042
+ if (renderY >= 0 && renderY < height) {
5043
+ let segmentX = currentX;
5044
+ for (const segment of segments) {
5045
+ const segmentColor = colors[segment.colorIndex] || colors[0];
5046
+ for (let charIdx = 0;charIdx < segment.text.length; charIdx++) {
5047
+ const renderX = segmentX + charIdx;
5048
+ if (renderX >= 0 && renderX < width) {
5049
+ const fontChar = segment.text[charIdx];
5050
+ if (fontChar !== " ") {
5051
+ buffer.setCellWithAlphaBlending(renderX, renderY, fontChar, parseColor(segmentColor), parseColor(backgroundColor));
5052
+ }
5053
+ }
5054
+ }
5055
+ segmentX += segment.text.length;
5056
+ }
5057
+ }
5058
+ }
5532
5059
  currentX += charWidth;
5533
5060
  if (i < text.length - 1) {
5534
5061
  currentX += fontDef.letterspace_size;
5535
5062
  }
5536
5063
  }
5537
5064
  return {
5538
- width: currentX,
5065
+ width: currentX - startX,
5539
5066
  height: fontDef.lines
5540
5067
  };
5541
5068
  }
5542
- function getCharacterPositions(text, font = "tiny") {
5543
- const fontDef = getParsedFont(font);
5544
- if (!fontDef) {
5545
- return [0];
5069
+
5070
+ // src/types.ts
5071
+ var TextAttributes = {
5072
+ NONE: 0,
5073
+ BOLD: 1 << 0,
5074
+ DIM: 1 << 1,
5075
+ ITALIC: 1 << 2,
5076
+ UNDERLINE: 1 << 3,
5077
+ BLINK: 1 << 4,
5078
+ INVERSE: 1 << 5,
5079
+ HIDDEN: 1 << 6,
5080
+ STRIKETHROUGH: 1 << 7
5081
+ };
5082
+ var ATTRIBUTE_BASE_BITS = 8;
5083
+ var ATTRIBUTE_BASE_MASK = 255;
5084
+ function getBaseAttributes(attr) {
5085
+ return attr & ATTRIBUTE_BASE_MASK;
5086
+ }
5087
+ var DebugOverlayCorner;
5088
+ ((DebugOverlayCorner2) => {
5089
+ DebugOverlayCorner2[DebugOverlayCorner2["topLeft"] = 0] = "topLeft";
5090
+ DebugOverlayCorner2[DebugOverlayCorner2["topRight"] = 1] = "topRight";
5091
+ DebugOverlayCorner2[DebugOverlayCorner2["bottomLeft"] = 2] = "bottomLeft";
5092
+ DebugOverlayCorner2[DebugOverlayCorner2["bottomRight"] = 3] = "bottomRight";
5093
+ })(DebugOverlayCorner ||= {});
5094
+
5095
+ // src/utils.ts
5096
+ function createTextAttributes({
5097
+ bold = false,
5098
+ italic = false,
5099
+ underline = false,
5100
+ dim = false,
5101
+ blink = false,
5102
+ inverse = false,
5103
+ hidden = false,
5104
+ strikethrough = false
5105
+ } = {}) {
5106
+ let attributes = TextAttributes.NONE;
5107
+ if (bold)
5108
+ attributes |= TextAttributes.BOLD;
5109
+ if (italic)
5110
+ attributes |= TextAttributes.ITALIC;
5111
+ if (underline)
5112
+ attributes |= TextAttributes.UNDERLINE;
5113
+ if (dim)
5114
+ attributes |= TextAttributes.DIM;
5115
+ if (blink)
5116
+ attributes |= TextAttributes.BLINK;
5117
+ if (inverse)
5118
+ attributes |= TextAttributes.INVERSE;
5119
+ if (hidden)
5120
+ attributes |= TextAttributes.HIDDEN;
5121
+ if (strikethrough)
5122
+ attributes |= TextAttributes.STRIKETHROUGH;
5123
+ return attributes;
5124
+ }
5125
+ var ATTRIBUTE_BASE_MASK2 = 255;
5126
+ var LINK_ID_SHIFT = 8;
5127
+ var LINK_ID_PAYLOAD_MASK = 16777215;
5128
+ function attributesWithLink(baseAttributes, linkId) {
5129
+ const base = baseAttributes & ATTRIBUTE_BASE_MASK2;
5130
+ const linkBits = (linkId & LINK_ID_PAYLOAD_MASK) << LINK_ID_SHIFT;
5131
+ return base | linkBits;
5132
+ }
5133
+ function getLinkId(attributes) {
5134
+ return attributes >>> LINK_ID_SHIFT & LINK_ID_PAYLOAD_MASK;
5135
+ }
5136
+ function visualizeRenderableTree(renderable, maxDepth = 10) {
5137
+ function buildTreeLines(node, prefix = "", parentPrefix = "", isLastChild = true, depth = 0) {
5138
+ if (depth >= maxDepth) {
5139
+ return [`${prefix}${node.id} ... (max depth reached)`];
5140
+ }
5141
+ const lines = [];
5142
+ const children = node.getChildren();
5143
+ lines.push(`${prefix}${node.id}`);
5144
+ if (children.length > 0) {
5145
+ const lastChildIndex = children.length - 1;
5146
+ children.forEach((child, index) => {
5147
+ const childIsLast = index === lastChildIndex;
5148
+ const connector = childIsLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
5149
+ const childPrefix = parentPrefix + (isLastChild ? " " : "\u2502 ");
5150
+ const childLines = buildTreeLines(child, childPrefix + connector, childPrefix, childIsLast, depth + 1);
5151
+ lines.push(...childLines);
5152
+ });
5153
+ }
5154
+ return lines;
5546
5155
  }
5547
- const positions = [0];
5548
- let currentX = 0;
5549
- for (let i = 0;i < text.length; i++) {
5550
- const char = text[i].toUpperCase();
5551
- const charDef = fontDef.chars[char];
5552
- let charWidth = 0;
5553
- if (!charDef) {
5554
- const spaceChar = fontDef.chars[" "];
5555
- if (spaceChar && spaceChar[0]) {
5556
- for (const segment of spaceChar[0]) {
5557
- charWidth += segment.text.length;
5558
- }
5559
- } else {
5560
- charWidth = 1;
5561
- }
5562
- } else if (charDef[0]) {
5563
- for (const segment of charDef[0]) {
5564
- charWidth += segment.text.length;
5565
- }
5156
+ const treeLines = buildTreeLines(renderable);
5157
+ console.log(`Renderable Tree:
5158
+ ` + treeLines.join(`
5159
+ `));
5160
+ }
5161
+
5162
+ // src/lib/styled-text.ts
5163
+ var BrandedStyledText = Symbol.for("@opentui/core/StyledText");
5164
+ function isStyledText(obj) {
5165
+ return obj && obj[BrandedStyledText];
5166
+ }
5167
+
5168
+ class StyledText {
5169
+ [BrandedStyledText] = true;
5170
+ chunks;
5171
+ constructor(chunks) {
5172
+ this.chunks = chunks;
5173
+ }
5174
+ }
5175
+ function stringToStyledText(content) {
5176
+ const chunk = {
5177
+ __isChunk: true,
5178
+ text: content
5179
+ };
5180
+ return new StyledText([chunk]);
5181
+ }
5182
+ function applyStyle(input, style) {
5183
+ if (typeof input === "object" && "__isChunk" in input) {
5184
+ const existingChunk = input;
5185
+ const fg = style.fg ? parseColor(style.fg) : existingChunk.fg;
5186
+ const bg = style.bg ? parseColor(style.bg) : existingChunk.bg;
5187
+ const newAttrs = createTextAttributes(style);
5188
+ const mergedAttrs = existingChunk.attributes ? existingChunk.attributes | newAttrs : newAttrs;
5189
+ return {
5190
+ __isChunk: true,
5191
+ text: existingChunk.text,
5192
+ fg,
5193
+ bg,
5194
+ attributes: mergedAttrs,
5195
+ link: existingChunk.link
5196
+ };
5197
+ } else {
5198
+ const plainTextStr = String(input);
5199
+ const fg = style.fg ? parseColor(style.fg) : undefined;
5200
+ const bg = style.bg ? parseColor(style.bg) : undefined;
5201
+ const attributes = createTextAttributes(style);
5202
+ return {
5203
+ __isChunk: true,
5204
+ text: plainTextStr,
5205
+ fg,
5206
+ bg,
5207
+ attributes
5208
+ };
5209
+ }
5210
+ }
5211
+ var black = (input) => applyStyle(input, { fg: "black" });
5212
+ var red = (input) => applyStyle(input, { fg: "red" });
5213
+ var green = (input) => applyStyle(input, { fg: "green" });
5214
+ var yellow = (input) => applyStyle(input, { fg: "yellow" });
5215
+ var blue = (input) => applyStyle(input, { fg: "blue" });
5216
+ var magenta = (input) => applyStyle(input, { fg: "magenta" });
5217
+ var cyan = (input) => applyStyle(input, { fg: "cyan" });
5218
+ var white = (input) => applyStyle(input, { fg: "white" });
5219
+ var brightBlack = (input) => applyStyle(input, { fg: "brightBlack" });
5220
+ var brightRed = (input) => applyStyle(input, { fg: "brightRed" });
5221
+ var brightGreen = (input) => applyStyle(input, { fg: "brightGreen" });
5222
+ var brightYellow = (input) => applyStyle(input, { fg: "brightYellow" });
5223
+ var brightBlue = (input) => applyStyle(input, { fg: "brightBlue" });
5224
+ var brightMagenta = (input) => applyStyle(input, { fg: "brightMagenta" });
5225
+ var brightCyan = (input) => applyStyle(input, { fg: "brightCyan" });
5226
+ var brightWhite = (input) => applyStyle(input, { fg: "brightWhite" });
5227
+ var bgBlack = (input) => applyStyle(input, { bg: "black" });
5228
+ var bgRed = (input) => applyStyle(input, { bg: "red" });
5229
+ var bgGreen = (input) => applyStyle(input, { bg: "green" });
5230
+ var bgYellow = (input) => applyStyle(input, { bg: "yellow" });
5231
+ var bgBlue = (input) => applyStyle(input, { bg: "blue" });
5232
+ var bgMagenta = (input) => applyStyle(input, { bg: "magenta" });
5233
+ var bgCyan = (input) => applyStyle(input, { bg: "cyan" });
5234
+ var bgWhite = (input) => applyStyle(input, { bg: "white" });
5235
+ var bold = (input) => applyStyle(input, { bold: true });
5236
+ var italic = (input) => applyStyle(input, { italic: true });
5237
+ var underline = (input) => applyStyle(input, { underline: true });
5238
+ var strikethrough = (input) => applyStyle(input, { strikethrough: true });
5239
+ var dim = (input) => applyStyle(input, { dim: true });
5240
+ var reverse = (input) => applyStyle(input, { reverse: true });
5241
+ var blink = (input) => applyStyle(input, { blink: true });
5242
+ var fg = (color) => (input) => applyStyle(input, { fg: color });
5243
+ var bg = (color) => (input) => applyStyle(input, { bg: color });
5244
+ var link = (url) => (input) => {
5245
+ const chunk = typeof input === "object" && "__isChunk" in input ? input : {
5246
+ __isChunk: true,
5247
+ text: String(input)
5248
+ };
5249
+ return {
5250
+ ...chunk,
5251
+ link: { url }
5252
+ };
5253
+ };
5254
+ function t(strings, ...values) {
5255
+ const chunks = [];
5256
+ for (let i = 0;i < strings.length; i++) {
5257
+ const raw = strings[i];
5258
+ if (raw) {
5259
+ chunks.push({
5260
+ __isChunk: true,
5261
+ text: raw,
5262
+ attributes: 0
5263
+ });
5566
5264
  }
5567
- currentX += charWidth;
5568
- if (i < text.length - 1) {
5569
- currentX += fontDef.letterspace_size;
5265
+ const val = values[i];
5266
+ if (typeof val === "object" && "__isChunk" in val) {
5267
+ chunks.push(val);
5268
+ } else if (val !== undefined) {
5269
+ const plainTextStr = String(val);
5270
+ chunks.push({
5271
+ __isChunk: true,
5272
+ text: plainTextStr,
5273
+ attributes: 0
5274
+ });
5570
5275
  }
5571
- positions.push(currentX);
5572
5276
  }
5573
- return positions;
5277
+ return new StyledText(chunks);
5574
5278
  }
5575
- function coordinateToCharacterIndex(x, text, font = "tiny") {
5576
- const positions = getCharacterPositions(text, font);
5577
- if (x < 0) {
5578
- return 0;
5579
- }
5580
- for (let i = 0;i < positions.length - 1; i++) {
5581
- const currentPos = positions[i];
5582
- const nextPos = positions[i + 1];
5583
- if (x >= currentPos && x < nextPos) {
5584
- const charMidpoint = currentPos + (nextPos - currentPos) / 2;
5585
- return x < charMidpoint ? i : i + 1;
5279
+
5280
+ // src/lib/hast-styled-text.ts
5281
+ function hastToTextChunks(node, syntaxStyle, parentStyles = []) {
5282
+ const chunks = [];
5283
+ if (node.type === "text") {
5284
+ const stylesToMerge = parentStyles.length > 0 ? parentStyles : ["default"];
5285
+ const mergedStyle = syntaxStyle.mergeStyles(...stylesToMerge);
5286
+ chunks.push({
5287
+ __isChunk: true,
5288
+ text: node.value,
5289
+ fg: mergedStyle.fg,
5290
+ bg: mergedStyle.bg,
5291
+ attributes: mergedStyle.attributes
5292
+ });
5293
+ } else if (node.type === "element") {
5294
+ let currentStyles = [...parentStyles];
5295
+ if (node.properties?.className) {
5296
+ const classes = node.properties.className.split(" ");
5297
+ for (const cls of classes) {
5298
+ currentStyles.push(cls);
5299
+ }
5300
+ }
5301
+ for (const child of node.children) {
5302
+ chunks.push(...hastToTextChunks(child, syntaxStyle, currentStyles));
5586
5303
  }
5587
5304
  }
5588
- if (positions.length > 0 && x >= positions[positions.length - 1]) {
5589
- return text.length;
5590
- }
5591
- return 0;
5305
+ return chunks;
5592
5306
  }
5593
- function renderFontToFrameBuffer(buffer, {
5594
- text,
5595
- x = 0,
5596
- y = 0,
5597
- color = [RGBA.fromInts(255, 255, 255, 255)],
5598
- backgroundColor = RGBA.fromInts(0, 0, 0, 255),
5599
- font = "tiny"
5600
- }) {
5601
- const width = buffer.width;
5602
- const height = buffer.height;
5603
- const fontDef = getParsedFont(font);
5604
- if (!fontDef) {
5605
- console.warn(`Font '${font}' not found`);
5606
- return { width: 0, height: 0 };
5307
+ function hastToStyledText(hast, syntaxStyle) {
5308
+ const chunks = hastToTextChunks(hast, syntaxStyle);
5309
+ return new StyledText(chunks);
5310
+ }
5311
+
5312
+ // src/lib/clock.ts
5313
+ class SystemClock {
5314
+ now() {
5315
+ return Date.now();
5607
5316
  }
5608
- const colors = Array.isArray(color) ? color : [color];
5609
- if (y < 0 || y + fontDef.lines > height) {
5610
- return { width: 0, height: fontDef.lines };
5317
+ setTimeout(fn, delayMs) {
5318
+ return globalThis.setTimeout(fn, delayMs);
5611
5319
  }
5612
- let currentX = x;
5613
- const startX = x;
5614
- for (let i = 0;i < text.length; i++) {
5615
- const char = text[i].toUpperCase();
5616
- const charDef = fontDef.chars[char];
5617
- if (!charDef) {
5618
- const spaceChar = fontDef.chars[" "];
5619
- if (spaceChar && spaceChar[0]) {
5620
- let spaceWidth = 0;
5621
- for (const segment of spaceChar[0]) {
5622
- spaceWidth += segment.text.length;
5623
- }
5624
- currentX += spaceWidth;
5625
- } else {
5626
- currentX += 1;
5627
- }
5628
- continue;
5629
- }
5630
- let charWidth = 0;
5631
- if (charDef[0]) {
5632
- for (const segment of charDef[0]) {
5633
- charWidth += segment.text.length;
5634
- }
5635
- }
5636
- if (currentX >= width)
5637
- break;
5638
- if (currentX + charWidth < 0) {
5639
- currentX += charWidth + fontDef.letterspace_size;
5640
- continue;
5641
- }
5642
- for (let lineIdx = 0;lineIdx < fontDef.lines && lineIdx < charDef.length; lineIdx++) {
5643
- const segments = charDef[lineIdx];
5644
- const renderY = y + lineIdx;
5645
- if (renderY >= 0 && renderY < height) {
5646
- let segmentX = currentX;
5647
- for (const segment of segments) {
5648
- const segmentColor = colors[segment.colorIndex] || colors[0];
5649
- for (let charIdx = 0;charIdx < segment.text.length; charIdx++) {
5650
- const renderX = segmentX + charIdx;
5651
- if (renderX >= 0 && renderX < width) {
5652
- const fontChar = segment.text[charIdx];
5653
- if (fontChar !== " ") {
5654
- buffer.setCellWithAlphaBlending(renderX, renderY, fontChar, parseColor(segmentColor), parseColor(backgroundColor));
5655
- }
5656
- }
5657
- }
5658
- segmentX += segment.text.length;
5659
- }
5660
- }
5661
- }
5662
- currentX += charWidth;
5663
- if (i < text.length - 1) {
5664
- currentX += fontDef.letterspace_size;
5665
- }
5320
+ clearTimeout(handle) {
5321
+ globalThis.clearTimeout(handle);
5666
5322
  }
5323
+ }
5324
+
5325
+ // src/lib/parse.keypress.ts
5326
+ import { Buffer as Buffer2 } from "buffer";
5327
+
5328
+ // src/lib/parse.keypress-kitty.ts
5329
+ var kittyKeyMap = {
5330
+ 27: "escape",
5331
+ 9: "tab",
5332
+ 13: "return",
5333
+ 127: "backspace",
5334
+ 57344: "escape",
5335
+ 57345: "return",
5336
+ 57346: "tab",
5337
+ 57347: "backspace",
5338
+ 57348: "insert",
5339
+ 57349: "delete",
5340
+ 57350: "left",
5341
+ 57351: "right",
5342
+ 57352: "up",
5343
+ 57353: "down",
5344
+ 57354: "pageup",
5345
+ 57355: "pagedown",
5346
+ 57356: "home",
5347
+ 57357: "end",
5348
+ 57364: "f1",
5349
+ 57365: "f2",
5350
+ 57366: "f3",
5351
+ 57367: "f4",
5352
+ 57368: "f5",
5353
+ 57369: "f6",
5354
+ 57370: "f7",
5355
+ 57371: "f8",
5356
+ 57372: "f9",
5357
+ 57373: "f10",
5358
+ 57374: "f11",
5359
+ 57375: "f12",
5360
+ 57376: "f13",
5361
+ 57377: "f14",
5362
+ 57378: "f15",
5363
+ 57379: "f16",
5364
+ 57380: "f17",
5365
+ 57381: "f18",
5366
+ 57382: "f19",
5367
+ 57383: "f20",
5368
+ 57384: "f21",
5369
+ 57385: "f22",
5370
+ 57386: "f23",
5371
+ 57387: "f24",
5372
+ 57388: "f25",
5373
+ 57389: "f26",
5374
+ 57390: "f27",
5375
+ 57391: "f28",
5376
+ 57392: "f29",
5377
+ 57393: "f30",
5378
+ 57394: "f31",
5379
+ 57395: "f32",
5380
+ 57396: "f33",
5381
+ 57397: "f34",
5382
+ 57398: "f35",
5383
+ 57399: "kp0",
5384
+ 57400: "kp1",
5385
+ 57401: "kp2",
5386
+ 57402: "kp3",
5387
+ 57403: "kp4",
5388
+ 57404: "kp5",
5389
+ 57405: "kp6",
5390
+ 57406: "kp7",
5391
+ 57407: "kp8",
5392
+ 57408: "kp9",
5393
+ 57409: "kpdecimal",
5394
+ 57410: "kpdivide",
5395
+ 57411: "kpmultiply",
5396
+ 57412: "kpminus",
5397
+ 57413: "kpplus",
5398
+ 57414: "kpenter",
5399
+ 57415: "kpequal",
5400
+ 57428: "mediaplay",
5401
+ 57429: "mediapause",
5402
+ 57430: "mediaplaypause",
5403
+ 57431: "mediareverse",
5404
+ 57432: "mediastop",
5405
+ 57433: "mediafastforward",
5406
+ 57434: "mediarewind",
5407
+ 57435: "medianext",
5408
+ 57436: "mediaprev",
5409
+ 57437: "mediarecord",
5410
+ 57438: "volumedown",
5411
+ 57439: "volumeup",
5412
+ 57440: "mute",
5413
+ 57441: "leftshift",
5414
+ 57442: "leftctrl",
5415
+ 57443: "leftalt",
5416
+ 57444: "leftsuper",
5417
+ 57445: "lefthyper",
5418
+ 57446: "leftmeta",
5419
+ 57447: "rightshift",
5420
+ 57448: "rightctrl",
5421
+ 57449: "rightalt",
5422
+ 57450: "rightsuper",
5423
+ 57451: "righthyper",
5424
+ 57452: "rightmeta",
5425
+ 57453: "iso_level3_shift",
5426
+ 57454: "iso_level5_shift"
5427
+ };
5428
+ function fromKittyMods(mod) {
5667
5429
  return {
5668
- width: currentX - startX,
5669
- height: fontDef.lines
5430
+ shift: !!(mod & 1),
5431
+ alt: !!(mod & 2),
5432
+ ctrl: !!(mod & 4),
5433
+ super: !!(mod & 8),
5434
+ hyper: !!(mod & 16),
5435
+ meta: !!(mod & 32),
5436
+ capsLock: !!(mod & 64),
5437
+ numLock: !!(mod & 128)
5670
5438
  };
5671
5439
  }
5672
-
5673
- // src/types.ts
5674
- var TextAttributes = {
5675
- NONE: 0,
5676
- BOLD: 1 << 0,
5677
- DIM: 1 << 1,
5678
- ITALIC: 1 << 2,
5679
- UNDERLINE: 1 << 3,
5680
- BLINK: 1 << 4,
5681
- INVERSE: 1 << 5,
5682
- HIDDEN: 1 << 6,
5683
- STRIKETHROUGH: 1 << 7
5440
+ var functionalKeyMap = {
5441
+ A: "up",
5442
+ B: "down",
5443
+ C: "right",
5444
+ D: "left",
5445
+ H: "home",
5446
+ F: "end",
5447
+ P: "f1",
5448
+ Q: "f2",
5449
+ R: "f3",
5450
+ S: "f4"
5684
5451
  };
5685
- var ATTRIBUTE_BASE_BITS = 8;
5686
- var ATTRIBUTE_BASE_MASK = 255;
5687
- function getBaseAttributes(attr) {
5688
- return attr & ATTRIBUTE_BASE_MASK;
5689
- }
5690
- var DebugOverlayCorner;
5691
- ((DebugOverlayCorner2) => {
5692
- DebugOverlayCorner2[DebugOverlayCorner2["topLeft"] = 0] = "topLeft";
5693
- DebugOverlayCorner2[DebugOverlayCorner2["topRight"] = 1] = "topRight";
5694
- DebugOverlayCorner2[DebugOverlayCorner2["bottomLeft"] = 2] = "bottomLeft";
5695
- DebugOverlayCorner2[DebugOverlayCorner2["bottomRight"] = 3] = "bottomRight";
5696
- })(DebugOverlayCorner ||= {});
5697
-
5698
- // src/utils.ts
5699
- function createTextAttributes({
5700
- bold = false,
5701
- italic = false,
5702
- underline = false,
5703
- dim = false,
5704
- blink = false,
5705
- inverse = false,
5706
- hidden = false,
5707
- strikethrough = false
5708
- } = {}) {
5709
- let attributes = TextAttributes.NONE;
5710
- if (bold)
5711
- attributes |= TextAttributes.BOLD;
5712
- if (italic)
5713
- attributes |= TextAttributes.ITALIC;
5714
- if (underline)
5715
- attributes |= TextAttributes.UNDERLINE;
5716
- if (dim)
5717
- attributes |= TextAttributes.DIM;
5718
- if (blink)
5719
- attributes |= TextAttributes.BLINK;
5720
- if (inverse)
5721
- attributes |= TextAttributes.INVERSE;
5722
- if (hidden)
5723
- attributes |= TextAttributes.HIDDEN;
5724
- if (strikethrough)
5725
- attributes |= TextAttributes.STRIKETHROUGH;
5726
- return attributes;
5727
- }
5728
- var ATTRIBUTE_BASE_MASK2 = 255;
5729
- var LINK_ID_SHIFT = 8;
5730
- var LINK_ID_PAYLOAD_MASK = 16777215;
5731
- function attributesWithLink(baseAttributes, linkId) {
5732
- const base = baseAttributes & ATTRIBUTE_BASE_MASK2;
5733
- const linkBits = (linkId & LINK_ID_PAYLOAD_MASK) << LINK_ID_SHIFT;
5734
- return base | linkBits;
5735
- }
5736
- function getLinkId(attributes) {
5737
- return attributes >>> LINK_ID_SHIFT & LINK_ID_PAYLOAD_MASK;
5738
- }
5739
- function visualizeRenderableTree(renderable, maxDepth = 10) {
5740
- function buildTreeLines(node, prefix = "", parentPrefix = "", isLastChild = true, depth = 0) {
5741
- if (depth >= maxDepth) {
5742
- return [`${prefix}${node.id} ... (max depth reached)`];
5743
- }
5744
- const lines = [];
5745
- const children = node.getChildren();
5746
- lines.push(`${prefix}${node.id}`);
5747
- if (children.length > 0) {
5748
- const lastChildIndex = children.length - 1;
5749
- children.forEach((child, index) => {
5750
- const childIsLast = index === lastChildIndex;
5751
- const connector = childIsLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
5752
- const childPrefix = parentPrefix + (isLastChild ? " " : "\u2502 ");
5753
- const childLines = buildTreeLines(child, childPrefix + connector, childPrefix, childIsLast, depth + 1);
5754
- lines.push(...childLines);
5755
- });
5452
+ var tildeKeyMap = {
5453
+ "1": "home",
5454
+ "2": "insert",
5455
+ "3": "delete",
5456
+ "4": "end",
5457
+ "5": "pageup",
5458
+ "6": "pagedown",
5459
+ "7": "home",
5460
+ "8": "end",
5461
+ "11": "f1",
5462
+ "12": "f2",
5463
+ "13": "f3",
5464
+ "14": "f4",
5465
+ "15": "f5",
5466
+ "17": "f6",
5467
+ "18": "f7",
5468
+ "19": "f8",
5469
+ "20": "f9",
5470
+ "21": "f10",
5471
+ "23": "f11",
5472
+ "24": "f12"
5473
+ };
5474
+ function parseKittySpecialKey(sequence) {
5475
+ const specialKeyRe = /^\x1b\[(\d+);(\d+):(\d+)([A-Z~])$/;
5476
+ const match = specialKeyRe.exec(sequence);
5477
+ if (!match)
5478
+ return null;
5479
+ const keyNumOrOne = match[1];
5480
+ const modifierStr = match[2];
5481
+ const eventTypeStr = match[3];
5482
+ const terminator = match[4];
5483
+ let keyName;
5484
+ if (terminator === "~") {
5485
+ keyName = tildeKeyMap[keyNumOrOne];
5486
+ } else {
5487
+ if (keyNumOrOne !== "1")
5488
+ return null;
5489
+ keyName = functionalKeyMap[terminator];
5490
+ }
5491
+ if (!keyName)
5492
+ return null;
5493
+ const key = {
5494
+ name: keyName,
5495
+ ctrl: false,
5496
+ meta: false,
5497
+ shift: false,
5498
+ option: false,
5499
+ number: false,
5500
+ sequence,
5501
+ raw: sequence,
5502
+ eventType: "press",
5503
+ source: "kitty",
5504
+ super: false,
5505
+ hyper: false,
5506
+ capsLock: false,
5507
+ numLock: false
5508
+ };
5509
+ if (modifierStr) {
5510
+ const modifierMask = parseInt(modifierStr, 10);
5511
+ if (!isNaN(modifierMask) && modifierMask > 1) {
5512
+ const mods = fromKittyMods(modifierMask - 1);
5513
+ key.shift = mods.shift;
5514
+ key.ctrl = mods.ctrl;
5515
+ key.meta = mods.alt || mods.meta;
5516
+ key.option = mods.alt;
5517
+ key.super = mods.super;
5518
+ key.hyper = mods.hyper;
5519
+ key.capsLock = mods.capsLock;
5520
+ key.numLock = mods.numLock;
5756
5521
  }
5757
- return lines;
5758
5522
  }
5759
- const treeLines = buildTreeLines(renderable);
5760
- console.log(`Renderable Tree:
5761
- ` + treeLines.join(`
5762
- `));
5763
- }
5764
-
5765
- // src/lib/styled-text.ts
5766
- var BrandedStyledText = Symbol.for("@opentui/core/StyledText");
5767
- function isStyledText(obj) {
5768
- return obj && obj[BrandedStyledText];
5769
- }
5770
-
5771
- class StyledText {
5772
- [BrandedStyledText] = true;
5773
- chunks;
5774
- constructor(chunks) {
5775
- this.chunks = chunks;
5523
+ if (eventTypeStr === "1" || !eventTypeStr) {
5524
+ key.eventType = "press";
5525
+ } else if (eventTypeStr === "2") {
5526
+ key.eventType = "press";
5527
+ key.repeated = true;
5528
+ } else if (eventTypeStr === "3") {
5529
+ key.eventType = "release";
5776
5530
  }
5531
+ return key;
5777
5532
  }
5778
- function stringToStyledText(content) {
5779
- const chunk = {
5780
- __isChunk: true,
5781
- text: content
5533
+ function parseKittyKeyboard(sequence) {
5534
+ const specialResult = parseKittySpecialKey(sequence);
5535
+ if (specialResult)
5536
+ return specialResult;
5537
+ const kittyRe = /^\x1b\[([^\x1b]+)u$/;
5538
+ const match = kittyRe.exec(sequence);
5539
+ if (!match)
5540
+ return null;
5541
+ const params = match[1];
5542
+ const fields = params.split(";");
5543
+ if (fields.length < 1)
5544
+ return null;
5545
+ const key = {
5546
+ name: "",
5547
+ ctrl: false,
5548
+ meta: false,
5549
+ shift: false,
5550
+ option: false,
5551
+ number: false,
5552
+ sequence,
5553
+ raw: sequence,
5554
+ eventType: "press",
5555
+ source: "kitty",
5556
+ super: false,
5557
+ hyper: false,
5558
+ capsLock: false,
5559
+ numLock: false
5782
5560
  };
5783
- return new StyledText([chunk]);
5784
- }
5785
- function applyStyle(input, style) {
5786
- if (typeof input === "object" && "__isChunk" in input) {
5787
- const existingChunk = input;
5788
- const fg = style.fg ? parseColor(style.fg) : existingChunk.fg;
5789
- const bg = style.bg ? parseColor(style.bg) : existingChunk.bg;
5790
- const newAttrs = createTextAttributes(style);
5791
- const mergedAttrs = existingChunk.attributes ? existingChunk.attributes | newAttrs : newAttrs;
5792
- return {
5793
- __isChunk: true,
5794
- text: existingChunk.text,
5795
- fg,
5796
- bg,
5797
- attributes: mergedAttrs,
5798
- link: existingChunk.link
5799
- };
5561
+ let text = "";
5562
+ const field1 = fields[0]?.split(":") || [];
5563
+ const codepointStr = field1[0];
5564
+ if (!codepointStr)
5565
+ return null;
5566
+ const codepoint = parseInt(codepointStr, 10);
5567
+ if (isNaN(codepoint))
5568
+ return null;
5569
+ let shiftedCodepoint;
5570
+ let baseCodepoint;
5571
+ if (field1[1]) {
5572
+ const shifted = parseInt(field1[1], 10);
5573
+ if (!isNaN(shifted) && shifted > 0 && shifted <= 1114111) {
5574
+ shiftedCodepoint = shifted;
5575
+ }
5576
+ }
5577
+ if (field1[2]) {
5578
+ const base = parseInt(field1[2], 10);
5579
+ if (!isNaN(base) && base > 0 && base <= 1114111) {
5580
+ baseCodepoint = base;
5581
+ }
5582
+ }
5583
+ const knownKey = kittyKeyMap[codepoint];
5584
+ if (knownKey) {
5585
+ key.name = knownKey;
5586
+ key.code = `[${codepoint}u`;
5800
5587
  } else {
5801
- const plainTextStr = String(input);
5802
- const fg = style.fg ? parseColor(style.fg) : undefined;
5803
- const bg = style.bg ? parseColor(style.bg) : undefined;
5804
- const attributes = createTextAttributes(style);
5805
- return {
5806
- __isChunk: true,
5807
- text: plainTextStr,
5808
- fg,
5809
- bg,
5810
- attributes
5811
- };
5588
+ if (codepoint > 0 && codepoint <= 1114111) {
5589
+ const char = String.fromCodePoint(codepoint);
5590
+ key.name = char;
5591
+ if (baseCodepoint) {
5592
+ key.baseCode = baseCodepoint;
5593
+ }
5594
+ } else {
5595
+ return null;
5596
+ }
5812
5597
  }
5813
- }
5814
- var black = (input) => applyStyle(input, { fg: "black" });
5815
- var red = (input) => applyStyle(input, { fg: "red" });
5816
- var green = (input) => applyStyle(input, { fg: "green" });
5817
- var yellow = (input) => applyStyle(input, { fg: "yellow" });
5818
- var blue = (input) => applyStyle(input, { fg: "blue" });
5819
- var magenta = (input) => applyStyle(input, { fg: "magenta" });
5820
- var cyan = (input) => applyStyle(input, { fg: "cyan" });
5821
- var white = (input) => applyStyle(input, { fg: "white" });
5822
- var brightBlack = (input) => applyStyle(input, { fg: "brightBlack" });
5823
- var brightRed = (input) => applyStyle(input, { fg: "brightRed" });
5824
- var brightGreen = (input) => applyStyle(input, { fg: "brightGreen" });
5825
- var brightYellow = (input) => applyStyle(input, { fg: "brightYellow" });
5826
- var brightBlue = (input) => applyStyle(input, { fg: "brightBlue" });
5827
- var brightMagenta = (input) => applyStyle(input, { fg: "brightMagenta" });
5828
- var brightCyan = (input) => applyStyle(input, { fg: "brightCyan" });
5829
- var brightWhite = (input) => applyStyle(input, { fg: "brightWhite" });
5830
- var bgBlack = (input) => applyStyle(input, { bg: "black" });
5831
- var bgRed = (input) => applyStyle(input, { bg: "red" });
5832
- var bgGreen = (input) => applyStyle(input, { bg: "green" });
5833
- var bgYellow = (input) => applyStyle(input, { bg: "yellow" });
5834
- var bgBlue = (input) => applyStyle(input, { bg: "blue" });
5835
- var bgMagenta = (input) => applyStyle(input, { bg: "magenta" });
5836
- var bgCyan = (input) => applyStyle(input, { bg: "cyan" });
5837
- var bgWhite = (input) => applyStyle(input, { bg: "white" });
5838
- var bold = (input) => applyStyle(input, { bold: true });
5839
- var italic = (input) => applyStyle(input, { italic: true });
5840
- var underline = (input) => applyStyle(input, { underline: true });
5841
- var strikethrough = (input) => applyStyle(input, { strikethrough: true });
5842
- var dim = (input) => applyStyle(input, { dim: true });
5843
- var reverse = (input) => applyStyle(input, { reverse: true });
5844
- var blink = (input) => applyStyle(input, { blink: true });
5845
- var fg = (color) => (input) => applyStyle(input, { fg: color });
5846
- var bg = (color) => (input) => applyStyle(input, { bg: color });
5847
- var link = (url) => (input) => {
5848
- const chunk = typeof input === "object" && "__isChunk" in input ? input : {
5849
- __isChunk: true,
5850
- text: String(input)
5851
- };
5852
- return {
5853
- ...chunk,
5854
- link: { url }
5855
- };
5856
- };
5857
- function t(strings, ...values) {
5858
- const chunks = [];
5859
- for (let i = 0;i < strings.length; i++) {
5860
- const raw = strings[i];
5861
- if (raw) {
5862
- chunks.push({
5863
- __isChunk: true,
5864
- text: raw,
5865
- attributes: 0
5866
- });
5598
+ if (fields[1]) {
5599
+ const field2 = fields[1].split(":");
5600
+ const modifierStr = field2[0];
5601
+ const eventTypeStr = field2[1];
5602
+ if (modifierStr) {
5603
+ const modifierMask = parseInt(modifierStr, 10);
5604
+ if (!isNaN(modifierMask) && modifierMask > 1) {
5605
+ const mods = fromKittyMods(modifierMask - 1);
5606
+ key.shift = mods.shift;
5607
+ key.ctrl = mods.ctrl;
5608
+ key.meta = mods.alt || mods.meta;
5609
+ key.option = mods.alt;
5610
+ key.super = mods.super;
5611
+ key.hyper = mods.hyper;
5612
+ key.capsLock = mods.capsLock;
5613
+ key.numLock = mods.numLock;
5614
+ }
5867
5615
  }
5868
- const val = values[i];
5869
- if (typeof val === "object" && "__isChunk" in val) {
5870
- chunks.push(val);
5871
- } else if (val !== undefined) {
5872
- const plainTextStr = String(val);
5873
- chunks.push({
5874
- __isChunk: true,
5875
- text: plainTextStr,
5876
- attributes: 0
5877
- });
5616
+ if (eventTypeStr === "1" || !eventTypeStr) {
5617
+ key.eventType = "press";
5618
+ } else if (eventTypeStr === "2") {
5619
+ key.eventType = "press";
5620
+ key.repeated = true;
5621
+ } else if (eventTypeStr === "3") {
5622
+ key.eventType = "release";
5623
+ } else {
5624
+ key.eventType = "press";
5878
5625
  }
5879
5626
  }
5880
- return new StyledText(chunks);
5881
- }
5882
-
5883
- // src/lib/hast-styled-text.ts
5884
- function hastToTextChunks(node, syntaxStyle, parentStyles = []) {
5885
- const chunks = [];
5886
- if (node.type === "text") {
5887
- const stylesToMerge = parentStyles.length > 0 ? parentStyles : ["default"];
5888
- const mergedStyle = syntaxStyle.mergeStyles(...stylesToMerge);
5889
- chunks.push({
5890
- __isChunk: true,
5891
- text: node.value,
5892
- fg: mergedStyle.fg,
5893
- bg: mergedStyle.bg,
5894
- attributes: mergedStyle.attributes
5895
- });
5896
- } else if (node.type === "element") {
5897
- let currentStyles = [...parentStyles];
5898
- if (node.properties?.className) {
5899
- const classes = node.properties.className.split(" ");
5900
- for (const cls of classes) {
5901
- currentStyles.push(cls);
5627
+ if (fields[2]) {
5628
+ const codepoints = fields[2].split(":");
5629
+ for (const cpStr of codepoints) {
5630
+ const cp = parseInt(cpStr, 10);
5631
+ if (!isNaN(cp) && cp > 0 && cp <= 1114111) {
5632
+ text += String.fromCodePoint(cp);
5902
5633
  }
5903
5634
  }
5904
- for (const child of node.children) {
5905
- chunks.push(...hastToTextChunks(child, syntaxStyle, currentStyles));
5635
+ }
5636
+ if (text === "") {
5637
+ const isPrintable = key.name.length > 0 && !kittyKeyMap[codepoint];
5638
+ if (isPrintable) {
5639
+ if (key.shift && shiftedCodepoint) {
5640
+ text = String.fromCodePoint(shiftedCodepoint);
5641
+ } else if (key.shift && key.name.length === 1) {
5642
+ text = key.name.toLocaleUpperCase();
5643
+ } else {
5644
+ text = key.name;
5645
+ }
5646
+ }
5647
+ }
5648
+ if (key.name === " " && key.shift && !key.ctrl && !key.meta) {
5649
+ text = " ";
5650
+ }
5651
+ if (text) {
5652
+ key.sequence = text;
5653
+ }
5654
+ return key;
5655
+ }
5656
+
5657
+ // src/lib/parse.keypress.ts
5658
+ var metaKeyCodeRe = /^(?:\x1b)([a-zA-Z0-9])$/;
5659
+ var fnKeyRe = /^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/;
5660
+ var keyName = {
5661
+ OP: "f1",
5662
+ OQ: "f2",
5663
+ OR: "f3",
5664
+ OS: "f4",
5665
+ "[11~": "f1",
5666
+ "[12~": "f2",
5667
+ "[13~": "f3",
5668
+ "[14~": "f4",
5669
+ "[[A": "f1",
5670
+ "[[B": "f2",
5671
+ "[[C": "f3",
5672
+ "[[D": "f4",
5673
+ "[[E": "f5",
5674
+ "[15~": "f5",
5675
+ "[17~": "f6",
5676
+ "[18~": "f7",
5677
+ "[19~": "f8",
5678
+ "[20~": "f9",
5679
+ "[21~": "f10",
5680
+ "[23~": "f11",
5681
+ "[24~": "f12",
5682
+ "[A": "up",
5683
+ "[B": "down",
5684
+ "[C": "right",
5685
+ "[D": "left",
5686
+ "[E": "clear",
5687
+ "[F": "end",
5688
+ "[H": "home",
5689
+ OA: "up",
5690
+ OB: "down",
5691
+ OC: "right",
5692
+ OD: "left",
5693
+ OE: "clear",
5694
+ OF: "end",
5695
+ OH: "home",
5696
+ "[1~": "home",
5697
+ "[2~": "insert",
5698
+ "[3~": "delete",
5699
+ "[4~": "end",
5700
+ "[5~": "pageup",
5701
+ "[6~": "pagedown",
5702
+ "[[5~": "pageup",
5703
+ "[[6~": "pagedown",
5704
+ "[7~": "home",
5705
+ "[8~": "end",
5706
+ "[a": "up",
5707
+ "[b": "down",
5708
+ "[c": "right",
5709
+ "[d": "left",
5710
+ "[e": "clear",
5711
+ f: "right",
5712
+ b: "left",
5713
+ p: "up",
5714
+ n: "down",
5715
+ "[2$": "insert",
5716
+ "[3$": "delete",
5717
+ "[5$": "pageup",
5718
+ "[6$": "pagedown",
5719
+ "[7$": "home",
5720
+ "[8$": "end",
5721
+ Oa: "up",
5722
+ Ob: "down",
5723
+ Oc: "right",
5724
+ Od: "left",
5725
+ Oe: "clear",
5726
+ "[2^": "insert",
5727
+ "[3^": "delete",
5728
+ "[5^": "pageup",
5729
+ "[6^": "pagedown",
5730
+ "[7^": "home",
5731
+ "[8^": "end",
5732
+ "[Z": "tab"
5733
+ };
5734
+ var nonAlphanumericKeys = [...Object.values(keyName), "backspace"];
5735
+ var isShiftKey = (code) => {
5736
+ return ["[a", "[b", "[c", "[d", "[e", "[2$", "[3$", "[5$", "[6$", "[7$", "[8$", "[Z"].includes(code);
5737
+ };
5738
+ var isCtrlKey = (code) => {
5739
+ return ["Oa", "Ob", "Oc", "Od", "Oe", "[2^", "[3^", "[5^", "[6^", "[7^", "[8^"].includes(code);
5740
+ };
5741
+ var modifyOtherKeysRe = /^\x1b\[27;(\d+);(\d+)~$/;
5742
+ var parseKeypress = (s = "", options = {}) => {
5743
+ let parts;
5744
+ if (Buffer2.isBuffer(s)) {
5745
+ if (s[0] > 127 && s[1] === undefined) {
5746
+ s[0] -= 128;
5747
+ s = "\x1B" + String(s);
5748
+ } else {
5749
+ s = String(s);
5906
5750
  }
5751
+ } else if (s !== undefined && typeof s !== "string") {
5752
+ s = String(s);
5753
+ } else if (!s) {
5754
+ s = "";
5907
5755
  }
5908
- return chunks;
5909
- }
5910
- function hastToStyledText(hast, syntaxStyle) {
5911
- const chunks = hastToTextChunks(hast, syntaxStyle);
5912
- return new StyledText(chunks);
5913
- }
5914
-
5915
- // src/lib/scroll-acceleration.ts
5916
- class LinearScrollAccel {
5917
- tick(_now) {
5918
- return 1;
5919
- }
5920
- reset() {}
5921
- }
5922
-
5923
- class MacOSScrollAccel {
5924
- opts;
5925
- lastTickTime = 0;
5926
- velocityHistory = [];
5927
- historySize = 3;
5928
- streakTimeout = 150;
5929
- minTickInterval = 6;
5930
- constructor(opts = {}) {
5931
- this.opts = opts;
5756
+ if (/^\x1b\[<\d+;\d+;\d+[Mm]$/.test(s)) {
5757
+ return null;
5932
5758
  }
5933
- tick(now = Date.now()) {
5934
- const A = this.opts.A ?? 0.8;
5935
- const tau = this.opts.tau ?? 3;
5936
- const maxMultiplier = this.opts.maxMultiplier ?? 6;
5937
- const dt = this.lastTickTime ? now - this.lastTickTime : Infinity;
5938
- if (dt === Infinity || dt > this.streakTimeout) {
5939
- this.lastTickTime = now;
5940
- this.velocityHistory = [];
5941
- return 1;
5942
- }
5943
- if (dt < this.minTickInterval) {
5944
- return 1;
5945
- }
5946
- this.lastTickTime = now;
5947
- this.velocityHistory.push(dt);
5948
- if (this.velocityHistory.length > this.historySize) {
5949
- this.velocityHistory.shift();
5950
- }
5951
- const avgInterval = this.velocityHistory.reduce((a, b) => a + b, 0) / this.velocityHistory.length;
5952
- const referenceInterval = 100;
5953
- const velocity = referenceInterval / avgInterval;
5954
- const x = velocity / tau;
5955
- const multiplier = 1 + A * (Math.exp(x) - 1);
5956
- return Math.min(multiplier, maxMultiplier);
5759
+ if (/^\[<\d+;\d+;\d+[Mm]$/.test(s)) {
5760
+ return null;
5957
5761
  }
5958
- reset() {
5959
- this.lastTickTime = 0;
5960
- this.velocityHistory = [];
5762
+ if (/^\x1b\[<[\d;]*$/.test(s)) {
5763
+ return null;
5961
5764
  }
5962
- }
5963
-
5964
- // src/lib/stdin-buffer.ts
5965
- import { EventEmitter as EventEmitter2 } from "events";
5966
- var ESC = "\x1B";
5967
- var BRACKETED_PASTE_START = "\x1B[200~";
5968
- var BRACKETED_PASTE_END = "\x1B[201~";
5969
- function isCompleteSequence(data) {
5970
- if (!data.startsWith(ESC)) {
5971
- return "not-escape";
5765
+ if (/^\[<[\d;]*$/.test(s)) {
5766
+ return null;
5972
5767
  }
5973
- if (data.length === 1) {
5974
- return "incomplete";
5768
+ if (s.startsWith("\x1B[M") && s.length >= 6) {
5769
+ return null;
5975
5770
  }
5976
- const afterEsc = data.slice(1);
5977
- if (afterEsc.startsWith(ESC)) {
5978
- return isCompleteSequence(afterEsc);
5771
+ if (/^\x1b\[\d+;\d+;\d+t$/.test(s)) {
5772
+ return null;
5979
5773
  }
5980
- if (afterEsc.startsWith("[")) {
5981
- if (afterEsc.startsWith("[M")) {
5982
- return data.length >= 6 ? "complete" : "incomplete";
5983
- }
5984
- return isCompleteCsiSequence(data);
5774
+ if (/^\x1b\[\d+;\d+R$/.test(s)) {
5775
+ return null;
5985
5776
  }
5986
- if (afterEsc.startsWith("]")) {
5987
- return isCompleteOscSequence(data);
5777
+ if (/^\x1b\[\?[\d;]+c$/.test(s)) {
5778
+ return null;
5988
5779
  }
5989
- if (afterEsc.startsWith("P")) {
5990
- return isCompleteDcsSequence(data);
5780
+ if (/^\x1b\[\?[\d;]+\$y$/.test(s)) {
5781
+ return null;
5991
5782
  }
5992
- if (afterEsc.startsWith("_")) {
5993
- return isCompleteApcSequence(data);
5783
+ if (s === "\x1B[I" || s === "\x1B[O") {
5784
+ return null;
5994
5785
  }
5995
- if (afterEsc.startsWith("O")) {
5996
- return afterEsc.length >= 2 ? "complete" : "incomplete";
5786
+ if (/^\x1b\][\d;].*(\x1b\\|\x07)$/.test(s)) {
5787
+ return null;
5997
5788
  }
5998
- if (afterEsc.length === 1) {
5999
- return "complete";
5789
+ if (s === "\x1B[200~" || s === "\x1B[201~") {
5790
+ return null;
6000
5791
  }
6001
- return "complete";
6002
- }
6003
- function isCompleteCsiSequence(data) {
6004
- if (!data.startsWith(ESC + "[")) {
6005
- return "complete";
6006
- }
6007
- if (data.length < 3) {
6008
- return "incomplete";
6009
- }
6010
- const payload = data.slice(2);
6011
- const lastChar = payload[payload.length - 1];
6012
- const lastCharCode = lastChar.charCodeAt(0);
6013
- if (lastCharCode >= 64 && lastCharCode <= 126) {
6014
- if (payload.startsWith("<")) {
6015
- const mouseMatch = /^<\d+;\d+;\d+[Mm]$/.test(payload);
6016
- if (mouseMatch) {
6017
- return "complete";
6018
- }
6019
- if (lastChar === "M" || lastChar === "m") {
6020
- const parts = payload.slice(1, -1).split(";");
6021
- if (parts.length === 3 && parts.every((p) => /^\d+$/.test(p))) {
6022
- return "complete";
6023
- }
6024
- }
6025
- return "incomplete";
5792
+ const key = {
5793
+ name: "",
5794
+ ctrl: false,
5795
+ meta: false,
5796
+ shift: false,
5797
+ option: false,
5798
+ number: false,
5799
+ sequence: s,
5800
+ raw: s,
5801
+ eventType: "press",
5802
+ source: "raw"
5803
+ };
5804
+ key.sequence = key.sequence || s || key.name;
5805
+ if (options.useKittyKeyboard) {
5806
+ const kittyResult = parseKittyKeyboard(s);
5807
+ if (kittyResult) {
5808
+ return kittyResult;
6026
5809
  }
6027
- return "complete";
6028
5810
  }
6029
- return "incomplete";
6030
- }
6031
- function isCompleteOscSequence(data) {
6032
- if (!data.startsWith(ESC + "]")) {
6033
- return "complete";
6034
- }
6035
- if (data.endsWith(ESC + "\\") || data.endsWith("\x07")) {
6036
- return "complete";
6037
- }
6038
- return "incomplete";
6039
- }
6040
- function isCompleteDcsSequence(data) {
6041
- if (!data.startsWith(ESC + "P")) {
6042
- return "complete";
6043
- }
6044
- if (data.endsWith(ESC + "\\")) {
6045
- return "complete";
6046
- }
6047
- return "incomplete";
6048
- }
6049
- function isCompleteApcSequence(data) {
6050
- if (!data.startsWith(ESC + "_")) {
6051
- return "complete";
6052
- }
6053
- if (data.endsWith(ESC + "\\")) {
6054
- return "complete";
6055
- }
6056
- return "incomplete";
6057
- }
6058
- function isNestedEscapeSequenceStart(char) {
6059
- return char === "[" || char === "]" || char === "O" || char === "N" || char === "P" || char === "_";
6060
- }
6061
- function extractCompleteSequences(buffer) {
6062
- const sequences = [];
6063
- let pos = 0;
6064
- while (pos < buffer.length) {
6065
- const remaining = buffer.slice(pos);
6066
- if (remaining.startsWith(ESC)) {
6067
- let seqEnd = 1;
6068
- while (seqEnd <= remaining.length) {
6069
- const candidate = remaining.slice(0, seqEnd);
6070
- const status = isCompleteSequence(candidate);
6071
- if (status === "complete") {
6072
- sequences.push(candidate);
6073
- pos += seqEnd;
6074
- break;
6075
- } else if (status === "incomplete") {
6076
- if (candidate === ESC + ESC) {
6077
- const nextChar = remaining[seqEnd];
6078
- if (seqEnd < remaining.length && !isNestedEscapeSequenceStart(nextChar)) {
6079
- sequences.push(candidate);
6080
- pos += seqEnd;
6081
- break;
6082
- }
6083
- }
6084
- seqEnd++;
6085
- } else {
6086
- sequences.push(candidate);
6087
- pos += seqEnd;
6088
- break;
6089
- }
6090
- }
6091
- if (seqEnd > remaining.length) {
6092
- return { sequences, remainder: remaining };
6093
- }
5811
+ const modifyOtherKeysMatch = modifyOtherKeysRe.exec(s);
5812
+ if (modifyOtherKeysMatch) {
5813
+ const modifier = parseInt(modifyOtherKeysMatch[1], 10) - 1;
5814
+ const charCode = parseInt(modifyOtherKeysMatch[2], 10);
5815
+ key.ctrl = !!(modifier & 4);
5816
+ key.meta = !!(modifier & 2);
5817
+ key.shift = !!(modifier & 1);
5818
+ key.option = !!(modifier & 2);
5819
+ key.super = !!(modifier & 8);
5820
+ key.hyper = !!(modifier & 16);
5821
+ if (charCode === 13) {
5822
+ key.name = "return";
5823
+ } else if (charCode === 27) {
5824
+ key.name = "escape";
5825
+ } else if (charCode === 9) {
5826
+ key.name = "tab";
5827
+ } else if (charCode === 32) {
5828
+ key.name = "space";
5829
+ } else if (charCode === 127 || charCode === 8) {
5830
+ key.name = "backspace";
6094
5831
  } else {
6095
- const code = remaining.charCodeAt(0);
6096
- if (code >= 55296 && code <= 56319) {
6097
- if (remaining.length === 1) {
6098
- return { sequences, remainder: remaining };
6099
- }
6100
- const next = remaining.charCodeAt(1);
6101
- if (next >= 56320 && next <= 57343) {
6102
- sequences.push(remaining.slice(0, 2));
6103
- pos += 2;
6104
- } else {
6105
- sequences.push(remaining[0]);
6106
- pos++;
6107
- }
6108
- } else {
6109
- sequences.push(remaining[0]);
6110
- pos++;
5832
+ const char = String.fromCharCode(charCode);
5833
+ key.name = char;
5834
+ key.sequence = char;
5835
+ if (charCode >= 48 && charCode <= 57) {
5836
+ key.number = true;
6111
5837
  }
6112
5838
  }
5839
+ return key;
6113
5840
  }
6114
- return { sequences, remainder: "" };
6115
- }
6116
-
6117
- class StdinBuffer extends EventEmitter2 {
6118
- buffer = "";
6119
- timeout = null;
6120
- timeoutMs;
6121
- pasteMode = false;
6122
- pasteBuffer = "";
6123
- constructor(options = {}) {
6124
- super();
6125
- this.timeoutMs = options.timeout ?? 10;
6126
- }
6127
- process(data) {
6128
- if (this.timeout) {
6129
- clearTimeout(this.timeout);
6130
- this.timeout = null;
6131
- }
6132
- let str;
6133
- if (Buffer.isBuffer(data)) {
6134
- if (data.length === 1 && data[0] > 127) {
6135
- const byte = data[0] - 128;
6136
- str = "\x1B" + String.fromCharCode(byte);
6137
- } else {
6138
- str = data.toString();
6139
- }
5841
+ if (s === "\r" || s === "\x1B\r") {
5842
+ key.name = "return";
5843
+ key.meta = s.length === 2;
5844
+ } else if (s === `
5845
+ ` || s === `\x1B
5846
+ `) {
5847
+ key.name = "linefeed";
5848
+ key.meta = s.length === 2;
5849
+ } else if (s === "\t") {
5850
+ key.name = "tab";
5851
+ } else if (s === "\b" || s === "\x1B\b" || s === "\x7F" || s === "\x1B\x7F") {
5852
+ key.name = "backspace";
5853
+ key.meta = s.charAt(0) === "\x1B";
5854
+ } else if (s === "\x1B" || s === "\x1B\x1B") {
5855
+ key.name = "escape";
5856
+ key.meta = s.length === 2;
5857
+ } else if (s === " " || s === "\x1B ") {
5858
+ key.name = "space";
5859
+ key.meta = s.length === 2;
5860
+ } else if (s === "\x00") {
5861
+ key.name = "space";
5862
+ key.ctrl = true;
5863
+ } else if (s.length === 1 && s <= "\x1A") {
5864
+ key.name = String.fromCharCode(s.charCodeAt(0) + 97 - 1);
5865
+ key.ctrl = true;
5866
+ } else if (s.length === 1 && s >= "0" && s <= "9") {
5867
+ key.name = s;
5868
+ key.number = true;
5869
+ } else if (s.length === 1 && s >= "a" && s <= "z") {
5870
+ key.name = s;
5871
+ } else if (s.length === 1 && s >= "A" && s <= "Z") {
5872
+ key.name = s.toLowerCase();
5873
+ key.shift = true;
5874
+ } else if (s.length === 1 || s.length === 2 && s.codePointAt(0) > 65535) {
5875
+ key.name = s;
5876
+ } else if (parts = metaKeyCodeRe.exec(s)) {
5877
+ key.meta = true;
5878
+ const char = parts[1];
5879
+ const isUpperCase = /^[A-Z]$/.test(char);
5880
+ if (char === "F") {
5881
+ key.name = "right";
5882
+ } else if (char === "B") {
5883
+ key.name = "left";
5884
+ } else if (isUpperCase) {
5885
+ key.shift = true;
5886
+ key.name = char;
6140
5887
  } else {
6141
- str = data;
6142
- }
6143
- if (str.length === 0 && this.buffer.length === 0) {
6144
- this.emit("data", "");
6145
- return;
6146
- }
6147
- this.buffer += str;
6148
- if (this.pasteMode) {
6149
- this.pasteBuffer += this.buffer;
6150
- this.buffer = "";
6151
- const endIndex = this.pasteBuffer.indexOf(BRACKETED_PASTE_END);
6152
- if (endIndex !== -1) {
6153
- const pastedContent = this.pasteBuffer.slice(0, endIndex);
6154
- const remaining = this.pasteBuffer.slice(endIndex + BRACKETED_PASTE_END.length);
6155
- this.pasteMode = false;
6156
- this.pasteBuffer = "";
6157
- this.emit("paste", pastedContent);
6158
- if (remaining.length > 0) {
6159
- this.process(remaining);
6160
- }
6161
- }
6162
- return;
6163
- }
6164
- const startIndex = this.buffer.indexOf(BRACKETED_PASTE_START);
6165
- if (startIndex !== -1) {
6166
- if (startIndex > 0) {
6167
- const beforePaste = this.buffer.slice(0, startIndex);
6168
- const result2 = extractCompleteSequences(beforePaste);
6169
- for (const sequence of result2.sequences) {
6170
- this.emit("data", sequence);
6171
- }
6172
- }
6173
- this.buffer = this.buffer.slice(startIndex + BRACKETED_PASTE_START.length);
6174
- this.pasteMode = true;
6175
- this.pasteBuffer = this.buffer;
6176
- this.buffer = "";
6177
- const endIndex = this.pasteBuffer.indexOf(BRACKETED_PASTE_END);
6178
- if (endIndex !== -1) {
6179
- const pastedContent = this.pasteBuffer.slice(0, endIndex);
6180
- const remaining = this.pasteBuffer.slice(endIndex + BRACKETED_PASTE_END.length);
6181
- this.pasteMode = false;
6182
- this.pasteBuffer = "";
6183
- this.emit("paste", pastedContent);
6184
- if (remaining.length > 0) {
6185
- this.process(remaining);
6186
- }
6187
- }
6188
- return;
5888
+ key.name = char;
6189
5889
  }
6190
- const result = extractCompleteSequences(this.buffer);
6191
- this.buffer = result.remainder;
6192
- for (const sequence of result.sequences) {
6193
- this.emit("data", sequence);
5890
+ } else if (s.length === 2 && s[0] === "\x1B" && s[1] <= "\x1A") {
5891
+ key.meta = true;
5892
+ key.ctrl = true;
5893
+ key.name = String.fromCharCode(s.charCodeAt(1) + 97 - 1);
5894
+ } else if (parts = fnKeyRe.exec(s)) {
5895
+ const segs = [...s];
5896
+ if (segs[0] === "\x1B" && segs[1] === "\x1B") {
5897
+ key.option = true;
5898
+ key.meta = true;
6194
5899
  }
6195
- if (this.buffer.length > 0) {
6196
- this.timeout = setTimeout(() => {
6197
- const flushed = this.flush();
6198
- for (const sequence of flushed) {
6199
- this.emit("data", sequence);
6200
- }
6201
- }, this.timeoutMs);
5900
+ const code = [parts[1], parts[2], parts[4], parts[6]].filter(Boolean).join("");
5901
+ const modifier = parseInt(parts[3] || parts[5] || "1", 10) - 1;
5902
+ key.ctrl = key.ctrl || !!(modifier & 4);
5903
+ key.meta = key.meta || !!(modifier & 2);
5904
+ key.shift = key.shift || !!(modifier & 1);
5905
+ key.option = key.option || !!(modifier & 2);
5906
+ key.super = !!(modifier & 8);
5907
+ key.hyper = !!(modifier & 16);
5908
+ key.code = code;
5909
+ const keyNameResult = keyName[code];
5910
+ if (keyNameResult) {
5911
+ key.name = keyNameResult;
5912
+ key.shift = isShiftKey(code) || key.shift;
5913
+ key.ctrl = isCtrlKey(code) || key.ctrl;
5914
+ } else {
5915
+ key.name = "";
5916
+ key.code = undefined;
6202
5917
  }
5918
+ } else if (s === "\x1B[3~") {
5919
+ key.name = "delete";
5920
+ key.meta = false;
5921
+ key.code = "[3~";
5922
+ }
5923
+ return key;
5924
+ };
5925
+
5926
+ // src/lib/scroll-acceleration.ts
5927
+ class LinearScrollAccel {
5928
+ tick(_now) {
5929
+ return 1;
5930
+ }
5931
+ reset() {}
5932
+ }
5933
+
5934
+ class MacOSScrollAccel {
5935
+ opts;
5936
+ lastTickTime = 0;
5937
+ velocityHistory = [];
5938
+ historySize = 3;
5939
+ streakTimeout = 150;
5940
+ minTickInterval = 6;
5941
+ constructor(opts = {}) {
5942
+ this.opts = opts;
6203
5943
  }
6204
- flush() {
6205
- if (this.timeout) {
6206
- clearTimeout(this.timeout);
6207
- this.timeout = null;
5944
+ tick(now = Date.now()) {
5945
+ const A = this.opts.A ?? 0.8;
5946
+ const tau = this.opts.tau ?? 3;
5947
+ const maxMultiplier = this.opts.maxMultiplier ?? 6;
5948
+ const dt = this.lastTickTime ? now - this.lastTickTime : Infinity;
5949
+ if (dt === Infinity || dt > this.streakTimeout) {
5950
+ this.lastTickTime = now;
5951
+ this.velocityHistory = [];
5952
+ return 1;
6208
5953
  }
6209
- if (this.buffer.length === 0) {
6210
- return [];
5954
+ if (dt < this.minTickInterval) {
5955
+ return 1;
6211
5956
  }
6212
- const sequences = [this.buffer];
6213
- this.buffer = "";
6214
- return sequences;
6215
- }
6216
- clear() {
6217
- if (this.timeout) {
6218
- clearTimeout(this.timeout);
6219
- this.timeout = null;
5957
+ this.lastTickTime = now;
5958
+ this.velocityHistory.push(dt);
5959
+ if (this.velocityHistory.length > this.historySize) {
5960
+ this.velocityHistory.shift();
6220
5961
  }
6221
- this.buffer = "";
6222
- this.pasteMode = false;
6223
- this.pasteBuffer = "";
6224
- }
6225
- getBuffer() {
6226
- return this.buffer;
5962
+ const avgInterval = this.velocityHistory.reduce((a, b) => a + b, 0) / this.velocityHistory.length;
5963
+ const referenceInterval = 100;
5964
+ const velocity = referenceInterval / avgInterval;
5965
+ const x = velocity / tau;
5966
+ const multiplier = 1 + A * (Math.exp(x) - 1);
5967
+ return Math.min(multiplier, maxMultiplier);
6227
5968
  }
6228
- destroy() {
6229
- this.clear();
5969
+ reset() {
5970
+ this.lastTickTime = 0;
5971
+ this.velocityHistory = [];
6230
5972
  }
6231
5973
  }
6232
5974
 
@@ -6533,7 +6275,8 @@ class MouseParser {
6533
6275
  this.mouseButtonsPressed.clear();
6534
6276
  }
6535
6277
  decodeInput(data) {
6536
- return data.toString();
6278
+ const buf = Buffer.isBuffer(data) ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
6279
+ return buf.toString("latin1");
6537
6280
  }
6538
6281
  parseMouseEvent(data) {
6539
6282
  const str = this.decodeInput(data);
@@ -6853,200 +6596,1059 @@ class ASCIIFontSelectionHelper {
6853
6596
  startCharIndex = coordinateToCharacterIndex(selStart.x, text, font);
6854
6597
  }
6855
6598
  }
6856
- if (selEnd.y < 0) {
6857
- this.localSelection = null;
6858
- return previousSelection !== null;
6859
- } else if (selEnd.y >= 0 && selEnd.y <= height - 1) {
6860
- if (selEnd.x >= 0) {
6861
- endCharIndex = coordinateToCharacterIndex(selEnd.x, text, font);
6862
- } else {
6863
- endCharIndex = 0;
6599
+ if (selEnd.y < 0) {
6600
+ this.localSelection = null;
6601
+ return previousSelection !== null;
6602
+ } else if (selEnd.y >= 0 && selEnd.y <= height - 1) {
6603
+ if (selEnd.x >= 0) {
6604
+ endCharIndex = coordinateToCharacterIndex(selEnd.x, text, font);
6605
+ } else {
6606
+ endCharIndex = 0;
6607
+ }
6608
+ }
6609
+ if (startCharIndex < endCharIndex && startCharIndex >= 0 && endCharIndex <= text.length) {
6610
+ this.localSelection = { start: startCharIndex, end: endCharIndex };
6611
+ } else {
6612
+ this.localSelection = null;
6613
+ }
6614
+ return previousSelection?.start !== this.localSelection?.start || previousSelection?.end !== this.localSelection?.end;
6615
+ }
6616
+ }
6617
+
6618
+ // src/lib/singleton.ts
6619
+ var singletonCacheSymbol = Symbol.for("@opentui/core/singleton");
6620
+ function singleton(key, factory) {
6621
+ const bag = globalThis[singletonCacheSymbol] ??= {};
6622
+ if (!(key in bag)) {
6623
+ bag[key] = factory();
6624
+ }
6625
+ return bag[key];
6626
+ }
6627
+ function destroySingleton(key) {
6628
+ const bag = globalThis[singletonCacheSymbol];
6629
+ if (bag && key in bag) {
6630
+ delete bag[key];
6631
+ }
6632
+ }
6633
+ function hasSingleton(key) {
6634
+ const bag = globalThis[singletonCacheSymbol];
6635
+ return bag && key in bag;
6636
+ }
6637
+
6638
+ // src/lib/env.ts
6639
+ var envRegistry = singleton("env-registry", () => ({}));
6640
+ function registerEnvVar(config) {
6641
+ const existing = envRegistry[config.name];
6642
+ if (existing) {
6643
+ if (existing.description !== config.description || existing.type !== config.type || existing.default !== config.default) {
6644
+ throw new Error(`Environment variable "${config.name}" is already registered with different configuration. ` + `Existing: ${JSON.stringify(existing)}, New: ${JSON.stringify(config)}`);
6645
+ }
6646
+ return;
6647
+ }
6648
+ envRegistry[config.name] = config;
6649
+ }
6650
+ function normalizeBoolean(value) {
6651
+ const lowerValue = value.toLowerCase();
6652
+ return ["true", "1", "on", "yes"].includes(lowerValue);
6653
+ }
6654
+ function parseEnvValue(config) {
6655
+ const envValue = process.env[config.name];
6656
+ if (envValue === undefined && config.default !== undefined) {
6657
+ return config.default;
6658
+ }
6659
+ if (envValue === undefined) {
6660
+ throw new Error(`Required environment variable ${config.name} is not set. ${config.description}`);
6661
+ }
6662
+ switch (config.type) {
6663
+ case "boolean":
6664
+ return typeof envValue === "boolean" ? envValue : normalizeBoolean(envValue);
6665
+ case "number":
6666
+ const numValue = Number(envValue);
6667
+ if (isNaN(numValue)) {
6668
+ throw new Error(`Environment variable ${config.name} must be a valid number, got: ${envValue}`);
6669
+ }
6670
+ return numValue;
6671
+ case "string":
6672
+ default:
6673
+ return envValue;
6674
+ }
6675
+ }
6676
+
6677
+ class EnvStore {
6678
+ parsedValues = new Map;
6679
+ get(key) {
6680
+ if (this.parsedValues.has(key)) {
6681
+ return this.parsedValues.get(key);
6682
+ }
6683
+ if (!(key in envRegistry)) {
6684
+ throw new Error(`Environment variable ${key} is not registered.`);
6685
+ }
6686
+ try {
6687
+ const value = parseEnvValue(envRegistry[key]);
6688
+ this.parsedValues.set(key, value);
6689
+ return value;
6690
+ } catch (error) {
6691
+ throw new Error(`Failed to parse env var ${key}: ${error instanceof Error ? error.message : String(error)}`);
6692
+ }
6693
+ }
6694
+ has(key) {
6695
+ return key in envRegistry;
6696
+ }
6697
+ clearCache() {
6698
+ this.parsedValues.clear();
6699
+ }
6700
+ }
6701
+ var envStore = singleton("env-store", () => new EnvStore);
6702
+ function clearEnvCache() {
6703
+ envStore.clearCache();
6704
+ }
6705
+ function generateEnvMarkdown() {
6706
+ const configs = Object.values(envRegistry);
6707
+ if (configs.length === 0) {
6708
+ return `# Environment Variables
6709
+
6710
+ No environment variables registered.
6711
+ `;
6712
+ }
6713
+ let markdown = `# Environment Variables
6714
+
6715
+ `;
6716
+ for (const config of configs) {
6717
+ markdown += `## ${config.name}
6718
+
6719
+ `;
6720
+ markdown += `${config.description}
6721
+
6722
+ `;
6723
+ markdown += `**Type:** \`${config.type || "string"}\`
6724
+ `;
6725
+ if (config.default !== undefined) {
6726
+ const defaultValue = typeof config.default === "string" ? `"${config.default}"` : String(config.default);
6727
+ markdown += `**Default:** \`${defaultValue}\`
6728
+ `;
6729
+ } else {
6730
+ markdown += `**Default:** *Required*
6731
+ `;
6732
+ }
6733
+ markdown += `
6734
+ `;
6735
+ }
6736
+ return markdown;
6737
+ }
6738
+ function generateEnvColored() {
6739
+ const configs = Object.values(envRegistry);
6740
+ if (configs.length === 0) {
6741
+ return `\x1B[1;36mEnvironment Variables\x1B[0m
6742
+
6743
+ No environment variables registered.
6744
+ `;
6745
+ }
6746
+ let output = `\x1B[1;36mEnvironment Variables\x1B[0m
6747
+
6748
+ `;
6749
+ for (const config of configs) {
6750
+ output += `\x1B[1;33m${config.name}\x1B[0m
6751
+ `;
6752
+ output += `${config.description}
6753
+ `;
6754
+ output += `\x1B[32mType:\x1B[0m \x1B[36m${config.type || "string"}\x1B[0m
6755
+ `;
6756
+ if (config.default !== undefined) {
6757
+ const defaultValue = typeof config.default === "string" ? `"${config.default}"` : String(config.default);
6758
+ output += `\x1B[32mDefault:\x1B[0m \x1B[35m${defaultValue}\x1B[0m
6759
+ `;
6760
+ } else {
6761
+ output += `\x1B[32mDefault:\x1B[0m \x1B[31mRequired\x1B[0m
6762
+ `;
6763
+ }
6764
+ output += `
6765
+ `;
6766
+ }
6767
+ return output;
6768
+ }
6769
+ var env = new Proxy({}, {
6770
+ get(target, prop) {
6771
+ if (typeof prop !== "string") {
6772
+ return;
6773
+ }
6774
+ return envStore.get(prop);
6775
+ },
6776
+ has(target, prop) {
6777
+ return envStore.has(prop);
6778
+ },
6779
+ ownKeys() {
6780
+ return Object.keys(envRegistry);
6781
+ },
6782
+ getOwnPropertyDescriptor(target, prop) {
6783
+ if (envStore.has(prop)) {
6784
+ return {
6785
+ enumerable: true,
6786
+ configurable: true,
6787
+ get: () => envStore.get(prop)
6788
+ };
6789
+ }
6790
+ return;
6791
+ }
6792
+ });
6793
+
6794
+ // src/lib/stdin-parser.ts
6795
+ import { Buffer as Buffer3 } from "buffer";
6796
+ var DEFAULT_TIMEOUT_MS = 10;
6797
+ var DEFAULT_MAX_PENDING_BYTES = 64 * 1024;
6798
+ var INITIAL_PENDING_CAPACITY = 256;
6799
+ var ESC = 27;
6800
+ var BEL = 7;
6801
+ var BRACKETED_PASTE_START = Buffer3.from("\x1B[200~");
6802
+ var BRACKETED_PASTE_END = Buffer3.from("\x1B[201~");
6803
+ var EMPTY_BYTES = new Uint8Array(0);
6804
+ var KEY_DECODER = new TextDecoder;
6805
+ var RXVT_DOLLAR_CSI_RE = /^\x1b\[\d+\$$/;
6806
+ var SYSTEM_CLOCK = new SystemClock;
6807
+
6808
+ class ByteQueue {
6809
+ buf;
6810
+ start = 0;
6811
+ end = 0;
6812
+ constructor(capacity = INITIAL_PENDING_CAPACITY) {
6813
+ this.buf = new Uint8Array(capacity);
6814
+ }
6815
+ get length() {
6816
+ return this.end - this.start;
6817
+ }
6818
+ get capacity() {
6819
+ return this.buf.length;
6820
+ }
6821
+ view() {
6822
+ return this.buf.subarray(this.start, this.end);
6823
+ }
6824
+ take() {
6825
+ const chunk = this.view();
6826
+ this.start = 0;
6827
+ this.end = 0;
6828
+ return chunk;
6829
+ }
6830
+ append(chunk) {
6831
+ if (chunk.length === 0) {
6832
+ return;
6833
+ }
6834
+ this.ensureCapacity(this.length + chunk.length);
6835
+ this.buf.set(chunk, this.end);
6836
+ this.end += chunk.length;
6837
+ }
6838
+ consume(count) {
6839
+ if (count <= 0) {
6840
+ return;
6841
+ }
6842
+ if (count >= this.length) {
6843
+ this.start = 0;
6844
+ this.end = 0;
6845
+ return;
6846
+ }
6847
+ this.start += count;
6848
+ if (this.start >= this.buf.length / 2) {
6849
+ this.buf.copyWithin(0, this.start, this.end);
6850
+ this.end -= this.start;
6851
+ this.start = 0;
6852
+ }
6853
+ }
6854
+ clear() {
6855
+ this.start = 0;
6856
+ this.end = 0;
6857
+ }
6858
+ reset(capacity = INITIAL_PENDING_CAPACITY) {
6859
+ this.buf = new Uint8Array(capacity);
6860
+ this.start = 0;
6861
+ this.end = 0;
6862
+ }
6863
+ ensureCapacity(requiredLength) {
6864
+ const currentLength = this.length;
6865
+ if (requiredLength <= this.buf.length) {
6866
+ const availableAtEnd = this.buf.length - this.end;
6867
+ if (availableAtEnd >= requiredLength - currentLength) {
6868
+ return;
6869
+ }
6870
+ this.buf.copyWithin(0, this.start, this.end);
6871
+ this.end = currentLength;
6872
+ this.start = 0;
6873
+ if (requiredLength <= this.buf.length) {
6874
+ return;
6864
6875
  }
6865
6876
  }
6866
- if (startCharIndex < endCharIndex && startCharIndex >= 0 && endCharIndex <= text.length) {
6867
- this.localSelection = { start: startCharIndex, end: endCharIndex };
6868
- } else {
6869
- this.localSelection = null;
6877
+ let nextCapacity = this.buf.length;
6878
+ while (nextCapacity < requiredLength) {
6879
+ nextCapacity *= 2;
6870
6880
  }
6871
- return previousSelection?.start !== this.localSelection?.start || previousSelection?.end !== this.localSelection?.end;
6881
+ const next = new Uint8Array(nextCapacity);
6882
+ next.set(this.view(), 0);
6883
+ this.buf = next;
6884
+ this.start = 0;
6885
+ this.end = currentLength;
6872
6886
  }
6873
6887
  }
6874
-
6875
- // src/lib/singleton.ts
6876
- var singletonCacheSymbol = Symbol.for("@opentui/core/singleton");
6877
- function singleton(key, factory) {
6878
- const bag = globalThis[singletonCacheSymbol] ??= {};
6879
- if (!(key in bag)) {
6880
- bag[key] = factory();
6888
+ function normalizePositiveOption(value, fallback) {
6889
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
6890
+ return fallback;
6881
6891
  }
6882
- return bag[key];
6892
+ return Math.floor(value);
6883
6893
  }
6884
- function destroySingleton(key) {
6885
- const bag = globalThis[singletonCacheSymbol];
6886
- if (bag && key in bag) {
6887
- delete bag[key];
6894
+ function utf8SequenceLength(first) {
6895
+ if (first < 128)
6896
+ return 1;
6897
+ if (first >= 194 && first <= 223)
6898
+ return 2;
6899
+ if (first >= 224 && first <= 239)
6900
+ return 3;
6901
+ if (first >= 240 && first <= 244)
6902
+ return 4;
6903
+ return 0;
6904
+ }
6905
+ function bytesEqual(left, right) {
6906
+ if (left.length !== right.length) {
6907
+ return false;
6888
6908
  }
6909
+ for (let index = 0;index < left.length; index += 1) {
6910
+ if (left[index] !== right[index]) {
6911
+ return false;
6912
+ }
6913
+ }
6914
+ return true;
6889
6915
  }
6890
- function hasSingleton(key) {
6891
- const bag = globalThis[singletonCacheSymbol];
6892
- return bag && key in bag;
6916
+ function isMouseSgrSequence(sequence) {
6917
+ if (sequence.length < 7) {
6918
+ return false;
6919
+ }
6920
+ if (sequence[0] !== ESC || sequence[1] !== 91 || sequence[2] !== 60) {
6921
+ return false;
6922
+ }
6923
+ const final = sequence[sequence.length - 1];
6924
+ if (final !== 77 && final !== 109) {
6925
+ return false;
6926
+ }
6927
+ let part = 0;
6928
+ let hasDigit = false;
6929
+ for (let index = 3;index < sequence.length - 1; index += 1) {
6930
+ const byte = sequence[index];
6931
+ if (byte >= 48 && byte <= 57) {
6932
+ hasDigit = true;
6933
+ continue;
6934
+ }
6935
+ if (byte === 59 && hasDigit && part < 2) {
6936
+ part += 1;
6937
+ hasDigit = false;
6938
+ continue;
6939
+ }
6940
+ return false;
6941
+ }
6942
+ return part === 2 && hasDigit;
6893
6943
  }
6894
-
6895
- // src/lib/env.ts
6896
- var envRegistry = singleton("env-registry", () => ({}));
6897
- function registerEnvVar(config) {
6898
- const existing = envRegistry[config.name];
6899
- if (existing) {
6900
- if (existing.description !== config.description || existing.type !== config.type || existing.default !== config.default) {
6901
- throw new Error(`Environment variable "${config.name}" is already registered with different configuration. ` + `Existing: ${JSON.stringify(existing)}, New: ${JSON.stringify(config)}`);
6944
+ function concatBytes(left, right) {
6945
+ if (left.length === 0) {
6946
+ return right;
6947
+ }
6948
+ if (right.length === 0) {
6949
+ return left;
6950
+ }
6951
+ const combined = new Uint8Array(left.length + right.length);
6952
+ combined.set(left, 0);
6953
+ combined.set(right, left.length);
6954
+ return combined;
6955
+ }
6956
+ function indexOfBytes(haystack, needle) {
6957
+ if (needle.length === 0) {
6958
+ return 0;
6959
+ }
6960
+ const limit = haystack.length - needle.length;
6961
+ for (let offset = 0;offset <= limit; offset += 1) {
6962
+ let matched = true;
6963
+ for (let index = 0;index < needle.length; index += 1) {
6964
+ if (haystack[offset + index] !== needle[index]) {
6965
+ matched = false;
6966
+ break;
6967
+ }
6968
+ }
6969
+ if (matched) {
6970
+ return offset;
6902
6971
  }
6903
- return;
6904
6972
  }
6905
- envRegistry[config.name] = config;
6973
+ return -1;
6906
6974
  }
6907
- function normalizeBoolean(value) {
6908
- const lowerValue = value.toLowerCase();
6909
- return ["true", "1", "on", "yes"].includes(lowerValue);
6975
+ function decodeLatin1(bytes) {
6976
+ return Buffer3.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("latin1");
6910
6977
  }
6911
- function parseEnvValue(config) {
6912
- const envValue = process.env[config.name];
6913
- if (envValue === undefined && config.default !== undefined) {
6914
- return config.default;
6978
+ function decodeUtf8(bytes) {
6979
+ return KEY_DECODER.decode(bytes);
6980
+ }
6981
+ function createPasteCollector() {
6982
+ return {
6983
+ tail: EMPTY_BYTES,
6984
+ decoder: new TextDecoder,
6985
+ parts: []
6986
+ };
6987
+ }
6988
+
6989
+ class StdinParser {
6990
+ pending = new ByteQueue(INITIAL_PENDING_CAPACITY);
6991
+ events = [];
6992
+ timeoutMs;
6993
+ maxPendingBytes;
6994
+ armTimeouts;
6995
+ onTimeoutFlush;
6996
+ useKittyKeyboard;
6997
+ mouseParser = new MouseParser;
6998
+ clock;
6999
+ timeoutId = null;
7000
+ destroyed = false;
7001
+ pendingSinceMs = null;
7002
+ forceFlush = false;
7003
+ justFlushedEsc = false;
7004
+ state = { tag: "ground" };
7005
+ cursor = 0;
7006
+ unitStart = 0;
7007
+ paste = null;
7008
+ constructor(options = {}) {
7009
+ this.timeoutMs = normalizePositiveOption(options.timeoutMs, DEFAULT_TIMEOUT_MS);
7010
+ this.maxPendingBytes = normalizePositiveOption(options.maxPendingBytes, DEFAULT_MAX_PENDING_BYTES);
7011
+ this.armTimeouts = options.armTimeouts ?? true;
7012
+ this.onTimeoutFlush = options.onTimeoutFlush ?? null;
7013
+ this.useKittyKeyboard = options.useKittyKeyboard ?? true;
7014
+ this.clock = options.clock ?? SYSTEM_CLOCK;
7015
+ }
7016
+ get bufferCapacity() {
7017
+ return this.pending.capacity;
7018
+ }
7019
+ push(data) {
7020
+ this.ensureAlive();
7021
+ if (data.length === 0) {
7022
+ this.emitKeyOrResponse("unknown", "");
7023
+ return;
7024
+ }
7025
+ let remainder = data;
7026
+ while (remainder.length > 0) {
7027
+ if (this.paste) {
7028
+ remainder = this.consumePasteBytes(remainder);
7029
+ continue;
7030
+ }
7031
+ const immediatePasteStartIndex = this.state.tag === "ground" && this.pending.length === 0 ? indexOfBytes(remainder, BRACKETED_PASTE_START) : -1;
7032
+ const appendEnd = immediatePasteStartIndex === -1 ? remainder.length : immediatePasteStartIndex + BRACKETED_PASTE_START.length;
7033
+ this.pending.append(remainder.subarray(0, appendEnd));
7034
+ remainder = remainder.subarray(appendEnd);
7035
+ this.scanPending();
7036
+ if (this.paste && this.pending.length > 0) {
7037
+ remainder = this.consumePasteBytes(this.takePendingBytes());
7038
+ continue;
7039
+ }
7040
+ if (!this.paste && this.pending.length > this.maxPendingBytes) {
7041
+ this.flushPendingOverflow();
7042
+ this.scanPending();
7043
+ if (this.paste && this.pending.length > 0) {
7044
+ remainder = this.consumePasteBytes(this.takePendingBytes());
7045
+ }
7046
+ }
7047
+ }
7048
+ this.reconcileTimeoutState();
6915
7049
  }
6916
- if (envValue === undefined) {
6917
- throw new Error(`Required environment variable ${config.name} is not set. ${config.description}`);
7050
+ read() {
7051
+ this.ensureAlive();
7052
+ if (this.events.length === 0 && this.forceFlush) {
7053
+ this.scanPending();
7054
+ this.reconcileTimeoutState();
7055
+ }
7056
+ return this.events.shift() ?? null;
6918
7057
  }
6919
- switch (config.type) {
6920
- case "boolean":
6921
- return typeof envValue === "boolean" ? envValue : normalizeBoolean(envValue);
6922
- case "number":
6923
- const numValue = Number(envValue);
6924
- if (isNaN(numValue)) {
6925
- throw new Error(`Environment variable ${config.name} must be a valid number, got: ${envValue}`);
7058
+ drain(onEvent) {
7059
+ this.ensureAlive();
7060
+ while (true) {
7061
+ if (this.destroyed) {
7062
+ return;
7063
+ }
7064
+ const event = this.read();
7065
+ if (!event) {
7066
+ return;
7067
+ }
7068
+ onEvent(event);
7069
+ }
7070
+ }
7071
+ flushTimeout(nowMsValue = this.clock.now()) {
7072
+ this.ensureAlive();
7073
+ if (this.paste || this.pendingSinceMs === null || this.pending.length === 0) {
7074
+ return;
7075
+ }
7076
+ if (nowMsValue < this.pendingSinceMs || nowMsValue - this.pendingSinceMs < this.timeoutMs) {
7077
+ return;
7078
+ }
7079
+ this.forceFlush = true;
7080
+ }
7081
+ reset() {
7082
+ if (this.destroyed) {
7083
+ return;
7084
+ }
7085
+ this.clearTimeout();
7086
+ this.resetState();
7087
+ }
7088
+ resetMouseState() {
7089
+ this.ensureAlive();
7090
+ this.mouseParser.reset();
7091
+ }
7092
+ destroy() {
7093
+ if (this.destroyed) {
7094
+ return;
7095
+ }
7096
+ this.clearTimeout();
7097
+ this.destroyed = true;
7098
+ this.resetState();
7099
+ }
7100
+ ensureAlive() {
7101
+ if (this.destroyed) {
7102
+ throw new Error("StdinParser has been destroyed");
7103
+ }
7104
+ }
7105
+ scanPending() {
7106
+ while (!this.paste) {
7107
+ const bytes = this.pending.view();
7108
+ if (this.state.tag === "ground" && this.cursor >= bytes.length) {
7109
+ this.pending.clear();
7110
+ this.cursor = 0;
7111
+ this.unitStart = 0;
7112
+ this.pendingSinceMs = null;
7113
+ this.forceFlush = false;
7114
+ return;
7115
+ }
7116
+ const byte = this.cursor < bytes.length ? bytes[this.cursor] : -1;
7117
+ switch (this.state.tag) {
7118
+ case "ground": {
7119
+ this.unitStart = this.cursor;
7120
+ if (this.justFlushedEsc) {
7121
+ if (byte === 91) {
7122
+ this.justFlushedEsc = false;
7123
+ this.cursor += 1;
7124
+ this.state = { tag: "esc_recovery" };
7125
+ continue;
7126
+ }
7127
+ this.justFlushedEsc = false;
7128
+ }
7129
+ if (byte === ESC) {
7130
+ this.cursor += 1;
7131
+ this.state = { tag: "esc" };
7132
+ continue;
7133
+ }
7134
+ if (byte < 128) {
7135
+ this.emitKeyOrResponse("unknown", decodeUtf8(bytes.subarray(this.cursor, this.cursor + 1)));
7136
+ this.consumePrefix(this.cursor + 1);
7137
+ continue;
7138
+ }
7139
+ const expected = utf8SequenceLength(byte);
7140
+ if (expected === 0) {
7141
+ if (!this.forceFlush && this.cursor + 1 === bytes.length) {
7142
+ this.markPending();
7143
+ return;
7144
+ }
7145
+ this.emitLegacyHighByte(byte);
7146
+ this.consumePrefix(this.cursor + 1);
7147
+ continue;
7148
+ }
7149
+ this.cursor += 1;
7150
+ this.state = { tag: "utf8", expected, seen: 1 };
7151
+ continue;
7152
+ }
7153
+ case "utf8": {
7154
+ if (this.cursor >= bytes.length) {
7155
+ if (!this.forceFlush) {
7156
+ this.markPending();
7157
+ return;
7158
+ }
7159
+ this.emitLegacyHighByte(bytes[this.unitStart]);
7160
+ this.state = { tag: "ground" };
7161
+ this.consumePrefix(this.unitStart + 1);
7162
+ continue;
7163
+ }
7164
+ if ((byte & 192) !== 128) {
7165
+ this.emitLegacyHighByte(bytes[this.unitStart]);
7166
+ this.state = { tag: "ground" };
7167
+ this.consumePrefix(this.unitStart + 1);
7168
+ continue;
7169
+ }
7170
+ const nextSeen = this.state.seen + 1;
7171
+ this.cursor += 1;
7172
+ if (nextSeen < this.state.expected) {
7173
+ this.state = { tag: "utf8", expected: this.state.expected, seen: nextSeen };
7174
+ continue;
7175
+ }
7176
+ this.emitKeyOrResponse("unknown", decodeUtf8(bytes.subarray(this.unitStart, this.cursor)));
7177
+ this.state = { tag: "ground" };
7178
+ this.consumePrefix(this.cursor);
7179
+ continue;
7180
+ }
7181
+ case "esc": {
7182
+ if (this.cursor >= bytes.length) {
7183
+ if (!this.forceFlush) {
7184
+ this.markPending();
7185
+ return;
7186
+ }
7187
+ const flushedLoneEsc = this.cursor === this.unitStart + 1 && bytes[this.unitStart] === ESC;
7188
+ this.emitKeyOrResponse("unknown", decodeUtf8(bytes.subarray(this.unitStart, this.cursor)));
7189
+ this.justFlushedEsc = flushedLoneEsc;
7190
+ this.state = { tag: "ground" };
7191
+ this.consumePrefix(this.cursor);
7192
+ continue;
7193
+ }
7194
+ switch (byte) {
7195
+ case 91:
7196
+ this.cursor += 1;
7197
+ this.state = { tag: "csi" };
7198
+ continue;
7199
+ case 79:
7200
+ this.cursor += 1;
7201
+ this.state = { tag: "ss3" };
7202
+ continue;
7203
+ case 93:
7204
+ this.cursor += 1;
7205
+ this.state = { tag: "osc", sawEsc: false };
7206
+ continue;
7207
+ case 80:
7208
+ this.cursor += 1;
7209
+ this.state = { tag: "dcs", sawEsc: false };
7210
+ continue;
7211
+ case 95:
7212
+ this.cursor += 1;
7213
+ this.state = { tag: "apc", sawEsc: false };
7214
+ continue;
7215
+ case ESC:
7216
+ this.cursor += 1;
7217
+ continue;
7218
+ default:
7219
+ this.cursor += 1;
7220
+ this.emitKeyOrResponse("unknown", decodeUtf8(bytes.subarray(this.unitStart, this.cursor)));
7221
+ this.state = { tag: "ground" };
7222
+ this.consumePrefix(this.cursor);
7223
+ continue;
7224
+ }
7225
+ }
7226
+ case "ss3": {
7227
+ if (this.cursor >= bytes.length) {
7228
+ if (!this.forceFlush) {
7229
+ this.markPending();
7230
+ return;
7231
+ }
7232
+ this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor));
7233
+ this.state = { tag: "ground" };
7234
+ this.consumePrefix(this.cursor);
7235
+ continue;
7236
+ }
7237
+ if (byte === ESC) {
7238
+ this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor));
7239
+ this.state = { tag: "ground" };
7240
+ this.consumePrefix(this.cursor);
7241
+ continue;
7242
+ }
7243
+ this.cursor += 1;
7244
+ this.emitKeyOrResponse("unknown", decodeUtf8(bytes.subarray(this.unitStart, this.cursor)));
7245
+ this.state = { tag: "ground" };
7246
+ this.consumePrefix(this.cursor);
7247
+ continue;
7248
+ }
7249
+ case "esc_recovery": {
7250
+ if (this.cursor >= bytes.length) {
7251
+ if (!this.forceFlush) {
7252
+ this.markPending();
7253
+ return;
7254
+ }
7255
+ this.emitKeyOrResponse("unknown", decodeUtf8(bytes.subarray(this.unitStart, this.cursor)));
7256
+ this.state = { tag: "ground" };
7257
+ this.consumePrefix(this.cursor);
7258
+ continue;
7259
+ }
7260
+ if (byte === 60) {
7261
+ this.cursor += 1;
7262
+ this.state = { tag: "esc_less_mouse" };
7263
+ continue;
7264
+ }
7265
+ if (byte === 77) {
7266
+ this.cursor += 1;
7267
+ this.state = { tag: "esc_less_x10_mouse" };
7268
+ continue;
7269
+ }
7270
+ this.emitKeyOrResponse("unknown", decodeUtf8(bytes.subarray(this.unitStart, this.unitStart + 1)));
7271
+ this.state = { tag: "ground" };
7272
+ this.consumePrefix(this.unitStart + 1);
7273
+ continue;
7274
+ }
7275
+ case "csi": {
7276
+ if (this.cursor >= bytes.length) {
7277
+ if (!this.forceFlush) {
7278
+ this.markPending();
7279
+ return;
7280
+ }
7281
+ this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor));
7282
+ this.state = { tag: "ground" };
7283
+ this.consumePrefix(this.cursor);
7284
+ continue;
7285
+ }
7286
+ if (byte === ESC) {
7287
+ this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor));
7288
+ this.state = { tag: "ground" };
7289
+ this.consumePrefix(this.cursor);
7290
+ continue;
7291
+ }
7292
+ if (byte === 77 && this.cursor === this.unitStart + 2) {
7293
+ const end = this.cursor + 4;
7294
+ if (bytes.length < end) {
7295
+ if (!this.forceFlush) {
7296
+ this.markPending();
7297
+ return;
7298
+ }
7299
+ this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, bytes.length));
7300
+ this.state = { tag: "ground" };
7301
+ this.consumePrefix(bytes.length);
7302
+ continue;
7303
+ }
7304
+ this.emitMouse(bytes.subarray(this.unitStart, end), "x10");
7305
+ this.state = { tag: "ground" };
7306
+ this.consumePrefix(end);
7307
+ continue;
7308
+ }
7309
+ if (byte === 36) {
7310
+ const candidateEnd = this.cursor + 1;
7311
+ const candidate = decodeUtf8(bytes.subarray(this.unitStart, candidateEnd));
7312
+ if (RXVT_DOLLAR_CSI_RE.test(candidate)) {
7313
+ this.emitKeyOrResponse("csi", candidate);
7314
+ this.state = { tag: "ground" };
7315
+ this.consumePrefix(candidateEnd);
7316
+ continue;
7317
+ }
7318
+ if (!this.forceFlush && candidateEnd >= bytes.length) {
7319
+ this.markPending();
7320
+ return;
7321
+ }
7322
+ }
7323
+ if (byte === 91 && this.cursor === this.unitStart + 2) {
7324
+ this.cursor += 1;
7325
+ continue;
7326
+ }
7327
+ if (byte >= 64 && byte <= 126) {
7328
+ const end = this.cursor + 1;
7329
+ const rawBytes = bytes.subarray(this.unitStart, end);
7330
+ if (bytesEqual(rawBytes, BRACKETED_PASTE_START)) {
7331
+ this.state = { tag: "ground" };
7332
+ this.consumePrefix(end);
7333
+ this.paste = createPasteCollector();
7334
+ continue;
7335
+ }
7336
+ if (isMouseSgrSequence(rawBytes)) {
7337
+ this.emitMouse(rawBytes, "sgr");
7338
+ this.state = { tag: "ground" };
7339
+ this.consumePrefix(end);
7340
+ continue;
7341
+ }
7342
+ this.emitKeyOrResponse("csi", decodeUtf8(rawBytes));
7343
+ this.state = { tag: "ground" };
7344
+ this.consumePrefix(end);
7345
+ continue;
7346
+ }
7347
+ this.cursor += 1;
7348
+ continue;
7349
+ }
7350
+ case "osc": {
7351
+ if (this.cursor >= bytes.length) {
7352
+ if (!this.forceFlush) {
7353
+ this.markPending();
7354
+ return;
7355
+ }
7356
+ this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor));
7357
+ this.state = { tag: "ground" };
7358
+ this.consumePrefix(this.cursor);
7359
+ continue;
7360
+ }
7361
+ if (this.state.sawEsc) {
7362
+ if (byte === 92) {
7363
+ const end = this.cursor + 1;
7364
+ this.emitOpaqueResponse("osc", bytes.subarray(this.unitStart, end));
7365
+ this.state = { tag: "ground" };
7366
+ this.consumePrefix(end);
7367
+ continue;
7368
+ }
7369
+ this.state = { tag: "osc", sawEsc: false };
7370
+ continue;
7371
+ }
7372
+ if (byte === BEL) {
7373
+ const end = this.cursor + 1;
7374
+ this.emitOpaqueResponse("osc", bytes.subarray(this.unitStart, end));
7375
+ this.state = { tag: "ground" };
7376
+ this.consumePrefix(end);
7377
+ continue;
7378
+ }
7379
+ if (byte === ESC) {
7380
+ this.cursor += 1;
7381
+ this.state = { tag: "osc", sawEsc: true };
7382
+ continue;
7383
+ }
7384
+ this.cursor += 1;
7385
+ continue;
7386
+ }
7387
+ case "dcs": {
7388
+ if (this.cursor >= bytes.length) {
7389
+ if (!this.forceFlush) {
7390
+ this.markPending();
7391
+ return;
7392
+ }
7393
+ this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor));
7394
+ this.state = { tag: "ground" };
7395
+ this.consumePrefix(this.cursor);
7396
+ continue;
7397
+ }
7398
+ if (this.state.sawEsc) {
7399
+ if (byte === 92) {
7400
+ const end = this.cursor + 1;
7401
+ this.emitOpaqueResponse("dcs", bytes.subarray(this.unitStart, end));
7402
+ this.state = { tag: "ground" };
7403
+ this.consumePrefix(end);
7404
+ continue;
7405
+ }
7406
+ this.state = { tag: "dcs", sawEsc: false };
7407
+ continue;
7408
+ }
7409
+ if (byte === ESC) {
7410
+ this.cursor += 1;
7411
+ this.state = { tag: "dcs", sawEsc: true };
7412
+ continue;
7413
+ }
7414
+ this.cursor += 1;
7415
+ continue;
7416
+ }
7417
+ case "apc": {
7418
+ if (this.cursor >= bytes.length) {
7419
+ if (!this.forceFlush) {
7420
+ this.markPending();
7421
+ return;
7422
+ }
7423
+ this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor));
7424
+ this.state = { tag: "ground" };
7425
+ this.consumePrefix(this.cursor);
7426
+ continue;
7427
+ }
7428
+ if (this.state.sawEsc) {
7429
+ if (byte === 92) {
7430
+ const end = this.cursor + 1;
7431
+ this.emitOpaqueResponse("apc", bytes.subarray(this.unitStart, end));
7432
+ this.state = { tag: "ground" };
7433
+ this.consumePrefix(end);
7434
+ continue;
7435
+ }
7436
+ this.state = { tag: "apc", sawEsc: false };
7437
+ continue;
7438
+ }
7439
+ if (byte === ESC) {
7440
+ this.cursor += 1;
7441
+ this.state = { tag: "apc", sawEsc: true };
7442
+ continue;
7443
+ }
7444
+ this.cursor += 1;
7445
+ continue;
7446
+ }
7447
+ case "esc_less_mouse": {
7448
+ if (this.cursor >= bytes.length) {
7449
+ if (!this.forceFlush) {
7450
+ this.markPending();
7451
+ return;
7452
+ }
7453
+ this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor));
7454
+ this.state = { tag: "ground" };
7455
+ this.consumePrefix(this.cursor);
7456
+ continue;
7457
+ }
7458
+ if (byte >= 48 && byte <= 57 || byte === 59) {
7459
+ this.cursor += 1;
7460
+ continue;
7461
+ }
7462
+ if (byte === 77 || byte === 109) {
7463
+ const end = this.cursor + 1;
7464
+ this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, end));
7465
+ this.state = { tag: "ground" };
7466
+ this.consumePrefix(end);
7467
+ continue;
7468
+ }
7469
+ this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, this.cursor));
7470
+ this.state = { tag: "ground" };
7471
+ this.consumePrefix(this.cursor);
7472
+ continue;
7473
+ }
7474
+ case "esc_less_x10_mouse": {
7475
+ const end = this.unitStart + 5;
7476
+ if (bytes.length < end) {
7477
+ if (!this.forceFlush) {
7478
+ this.markPending();
7479
+ return;
7480
+ }
7481
+ this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, bytes.length));
7482
+ this.state = { tag: "ground" };
7483
+ this.consumePrefix(bytes.length);
7484
+ continue;
7485
+ }
7486
+ this.emitOpaqueResponse("unknown", bytes.subarray(this.unitStart, end));
7487
+ this.state = { tag: "ground" };
7488
+ this.consumePrefix(end);
7489
+ continue;
7490
+ }
6926
7491
  }
6927
- return numValue;
6928
- case "string":
6929
- default:
6930
- return envValue;
6931
- }
6932
- }
6933
-
6934
- class EnvStore {
6935
- parsedValues = new Map;
6936
- get(key) {
6937
- if (this.parsedValues.has(key)) {
6938
- return this.parsedValues.get(key);
6939
- }
6940
- if (!(key in envRegistry)) {
6941
- throw new Error(`Environment variable ${key} is not registered.`);
6942
7492
  }
6943
- try {
6944
- const value = parseEnvValue(envRegistry[key]);
6945
- this.parsedValues.set(key, value);
6946
- return value;
6947
- } catch (error) {
6948
- throw new Error(`Failed to parse env var ${key}: ${error instanceof Error ? error.message : String(error)}`);
7493
+ }
7494
+ emitKeyOrResponse(protocol, raw) {
7495
+ const parsed = parseKeypress(raw, { useKittyKeyboard: this.useKittyKeyboard });
7496
+ if (parsed) {
7497
+ this.events.push({
7498
+ type: "key",
7499
+ raw: parsed.raw,
7500
+ key: parsed
7501
+ });
7502
+ return;
6949
7503
  }
7504
+ this.events.push({
7505
+ type: "response",
7506
+ protocol,
7507
+ sequence: raw
7508
+ });
6950
7509
  }
6951
- has(key) {
6952
- return key in envRegistry;
7510
+ emitMouse(rawBytes, encoding) {
7511
+ const event = this.mouseParser.parseMouseEvent(rawBytes);
7512
+ if (!event) {
7513
+ this.emitOpaqueResponse("unknown", rawBytes);
7514
+ return;
7515
+ }
7516
+ this.events.push({
7517
+ type: "mouse",
7518
+ raw: decodeLatin1(rawBytes),
7519
+ encoding,
7520
+ event
7521
+ });
6953
7522
  }
6954
- clearCache() {
6955
- this.parsedValues.clear();
7523
+ emitLegacyHighByte(byte) {
7524
+ const parsed = parseKeypress(Buffer3.from([byte]), { useKittyKeyboard: this.useKittyKeyboard });
7525
+ if (parsed) {
7526
+ this.events.push({
7527
+ type: "key",
7528
+ raw: parsed.raw,
7529
+ key: parsed
7530
+ });
7531
+ return;
7532
+ }
7533
+ this.events.push({
7534
+ type: "response",
7535
+ protocol: "unknown",
7536
+ sequence: String.fromCharCode(byte)
7537
+ });
6956
7538
  }
6957
- }
6958
- var envStore = singleton("env-store", () => new EnvStore);
6959
- function clearEnvCache() {
6960
- envStore.clearCache();
6961
- }
6962
- function generateEnvMarkdown() {
6963
- const configs = Object.values(envRegistry);
6964
- if (configs.length === 0) {
6965
- return `# Environment Variables
6966
-
6967
- No environment variables registered.
6968
- `;
7539
+ emitOpaqueResponse(protocol, rawBytes) {
7540
+ this.events.push({
7541
+ type: "response",
7542
+ protocol,
7543
+ sequence: decodeLatin1(rawBytes)
7544
+ });
6969
7545
  }
6970
- let markdown = `# Environment Variables
6971
-
6972
- `;
6973
- for (const config of configs) {
6974
- markdown += `## ${config.name}
6975
-
6976
- `;
6977
- markdown += `${config.description}
6978
-
6979
- `;
6980
- markdown += `**Type:** \`${config.type || "string"}\`
6981
- `;
6982
- if (config.default !== undefined) {
6983
- const defaultValue = typeof config.default === "string" ? `"${config.default}"` : String(config.default);
6984
- markdown += `**Default:** \`${defaultValue}\`
6985
- `;
6986
- } else {
6987
- markdown += `**Default:** *Required*
6988
- `;
7546
+ consumePrefix(endExclusive) {
7547
+ this.pending.consume(endExclusive);
7548
+ this.cursor = 0;
7549
+ this.unitStart = 0;
7550
+ this.pendingSinceMs = null;
7551
+ this.forceFlush = false;
7552
+ }
7553
+ takePendingBytes() {
7554
+ const buffered = this.pending.take();
7555
+ this.cursor = 0;
7556
+ this.unitStart = 0;
7557
+ this.pendingSinceMs = null;
7558
+ this.forceFlush = false;
7559
+ return buffered;
7560
+ }
7561
+ flushPendingOverflow() {
7562
+ if (this.pending.length === 0) {
7563
+ return;
6989
7564
  }
6990
- markdown += `
6991
- `;
6992
- }
6993
- return markdown;
6994
- }
6995
- function generateEnvColored() {
6996
- const configs = Object.values(envRegistry);
6997
- if (configs.length === 0) {
6998
- return `\x1B[1;36mEnvironment Variables\x1B[0m
6999
-
7000
- No environment variables registered.
7001
- `;
7565
+ this.emitOpaqueResponse("unknown", this.pending.view());
7566
+ this.pending.clear();
7567
+ this.cursor = 0;
7568
+ this.unitStart = 0;
7569
+ this.pendingSinceMs = null;
7570
+ this.forceFlush = false;
7571
+ this.state = { tag: "ground" };
7572
+ }
7573
+ markPending() {
7574
+ this.pendingSinceMs = this.clock.now();
7575
+ }
7576
+ consumePasteBytes(chunk) {
7577
+ const paste = this.paste;
7578
+ const combined = concatBytes(paste.tail, chunk);
7579
+ const endIndex = indexOfBytes(combined, BRACKETED_PASTE_END);
7580
+ if (endIndex !== -1) {
7581
+ this.pushPasteText(combined.subarray(0, endIndex));
7582
+ const tailText = paste.decoder.decode();
7583
+ if (tailText.length > 0) {
7584
+ paste.parts.push(tailText);
7585
+ }
7586
+ this.events.push({
7587
+ type: "paste",
7588
+ text: paste.parts.join("")
7589
+ });
7590
+ this.paste = null;
7591
+ return combined.subarray(endIndex + BRACKETED_PASTE_END.length);
7592
+ }
7593
+ const keep = Math.min(BRACKETED_PASTE_END.length - 1, combined.length);
7594
+ const stableLength = combined.length - keep;
7595
+ if (stableLength > 0) {
7596
+ this.pushPasteText(combined.subarray(0, stableLength));
7597
+ }
7598
+ paste.tail = combined.slice(stableLength);
7599
+ return EMPTY_BYTES;
7002
7600
  }
7003
- let output = `\x1B[1;36mEnvironment Variables\x1B[0m
7004
-
7005
- `;
7006
- for (const config of configs) {
7007
- output += `\x1B[1;33m${config.name}\x1B[0m
7008
- `;
7009
- output += `${config.description}
7010
- `;
7011
- output += `\x1B[32mType:\x1B[0m \x1B[36m${config.type || "string"}\x1B[0m
7012
- `;
7013
- if (config.default !== undefined) {
7014
- const defaultValue = typeof config.default === "string" ? `"${config.default}"` : String(config.default);
7015
- output += `\x1B[32mDefault:\x1B[0m \x1B[35m${defaultValue}\x1B[0m
7016
- `;
7017
- } else {
7018
- output += `\x1B[32mDefault:\x1B[0m \x1B[31mRequired\x1B[0m
7019
- `;
7601
+ pushPasteText(bytes) {
7602
+ if (bytes.length === 0) {
7603
+ return;
7604
+ }
7605
+ const text = this.paste.decoder.decode(bytes, { stream: true });
7606
+ if (text.length > 0) {
7607
+ this.paste.parts.push(text);
7020
7608
  }
7021
- output += `
7022
- `;
7023
7609
  }
7024
- return output;
7025
- }
7026
- var env = new Proxy({}, {
7027
- get(target, prop) {
7028
- if (typeof prop !== "string") {
7610
+ reconcileTimeoutState() {
7611
+ if (!this.armTimeouts) {
7029
7612
  return;
7030
7613
  }
7031
- return envStore.get(prop);
7032
- },
7033
- has(target, prop) {
7034
- return envStore.has(prop);
7035
- },
7036
- ownKeys() {
7037
- return Object.keys(envRegistry);
7038
- },
7039
- getOwnPropertyDescriptor(target, prop) {
7040
- if (envStore.has(prop)) {
7041
- return {
7042
- enumerable: true,
7043
- configurable: true,
7044
- get: () => envStore.get(prop)
7045
- };
7614
+ if (this.paste || this.pendingSinceMs === null || this.pending.length === 0) {
7615
+ this.clearTimeout();
7616
+ return;
7046
7617
  }
7047
- return;
7618
+ this.clearTimeout();
7619
+ this.timeoutId = this.clock.setTimeout(() => {
7620
+ this.timeoutId = null;
7621
+ if (this.destroyed) {
7622
+ return;
7623
+ }
7624
+ try {
7625
+ this.flushTimeout(this.clock.now());
7626
+ this.onTimeoutFlush?.();
7627
+ } catch (error) {
7628
+ console.error("stdin parser timeout flush failed", error);
7629
+ }
7630
+ }, this.timeoutMs);
7048
7631
  }
7049
- });
7632
+ clearTimeout() {
7633
+ if (!this.timeoutId) {
7634
+ return;
7635
+ }
7636
+ this.clock.clearTimeout(this.timeoutId);
7637
+ this.timeoutId = null;
7638
+ }
7639
+ resetState() {
7640
+ this.pending.reset(INITIAL_PENDING_CAPACITY);
7641
+ this.events.length = 0;
7642
+ this.pendingSinceMs = null;
7643
+ this.forceFlush = false;
7644
+ this.justFlushedEsc = false;
7645
+ this.state = { tag: "ground" };
7646
+ this.cursor = 0;
7647
+ this.unitStart = 0;
7648
+ this.paste = null;
7649
+ this.mouseParser.reset();
7650
+ }
7651
+ }
7050
7652
 
7051
7653
  // src/lib/tree-sitter-styled-text.ts
7052
7654
  registerEnvVar({ name: "OTUI_TS_STYLE_WARN", default: false, description: "Enable warnings for missing syntax styles" });
@@ -7262,7 +7864,7 @@ async function treeSitterToStyledText(content, filetype, syntaxStyle, client, op
7262
7864
  }
7263
7865
 
7264
7866
  // src/lib/tree-sitter/client.ts
7265
- import { EventEmitter as EventEmitter3 } from "events";
7867
+ import { EventEmitter as EventEmitter2 } from "events";
7266
7868
 
7267
7869
  // src/lib/debounce.ts
7268
7870
  var TIMERS_MAP = new Map;
@@ -7477,7 +8079,7 @@ function addDefaultParsers(parsers) {
7477
8079
  }
7478
8080
  var isUrl = (path) => path.startsWith("http://") || path.startsWith("https://");
7479
8081
 
7480
- class TreeSitterClient extends EventEmitter3 {
8082
+ class TreeSitterClient extends EventEmitter2 {
7481
8083
  initialized = false;
7482
8084
  worker;
7483
8085
  buffers = new Map;
@@ -7929,7 +8531,7 @@ class TreeSitterClient extends EventEmitter3 {
7929
8531
  // src/lib/data-paths.ts
7930
8532
  import os from "os";
7931
8533
  import path from "path";
7932
- import { EventEmitter as EventEmitter4 } from "events";
8534
+ import { EventEmitter as EventEmitter3 } from "events";
7933
8535
 
7934
8536
  // src/lib/validate-dir-name.ts
7935
8537
  function isValidDirectoryName(name) {
@@ -7993,7 +8595,7 @@ registerEnvVar({
7993
8595
  default: ""
7994
8596
  });
7995
8597
 
7996
- class DataPathsManager extends EventEmitter4 {
8598
+ class DataPathsManager extends EventEmitter3 {
7997
8599
  _appName;
7998
8600
  _globalConfigPath;
7999
8601
  _globalConfigFile;
@@ -8125,11 +8727,11 @@ function pathToFiletype(path2) {
8125
8727
  }
8126
8728
 
8127
8729
  // src/lib/tree-sitter/assets/update.ts
8128
- import { readFile, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
8730
+ import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
8129
8731
  import * as path3 from "path";
8130
8732
 
8131
8733
  // src/lib/tree-sitter/download-utils.ts
8132
- import { mkdir, writeFile } from "fs/promises";
8734
+ import { mkdir, readFile, writeFile } from "fs/promises";
8133
8735
  import * as path2 from "path";
8134
8736
 
8135
8737
  class DownloadUtils {
@@ -8155,7 +8757,7 @@ class DownloadUtils {
8155
8757
  const cacheFile = path2.join(cacheDir, cacheSubdir, cacheFileName);
8156
8758
  await mkdir(path2.dirname(cacheFile), { recursive: true });
8157
8759
  try {
8158
- const cachedContent = await Bun.file(cacheFile).arrayBuffer();
8760
+ const cachedContent = await readFile(cacheFile);
8159
8761
  if (cachedContent.byteLength > 0) {
8160
8762
  console.log(`Loaded from cache: ${cacheFile} (${source})`);
8161
8763
  return { content: cachedContent, filePath: cacheFile };
@@ -8167,7 +8769,7 @@ class DownloadUtils {
8167
8769
  if (!response.ok) {
8168
8770
  return { error: `Failed to fetch from ${source}: ${response.statusText}` };
8169
8771
  }
8170
- const content = await response.arrayBuffer();
8772
+ const content = Buffer.from(await response.arrayBuffer());
8171
8773
  try {
8172
8774
  await writeFile(cacheFile, Buffer.from(content));
8173
8775
  console.log(`Cached: ${source}`);
@@ -8181,7 +8783,7 @@ class DownloadUtils {
8181
8783
  } else {
8182
8784
  try {
8183
8785
  console.log(`Loading from local path: ${source}`);
8184
- const content = await Bun.file(source).arrayBuffer();
8786
+ const content = await readFile(source);
8185
8787
  return { content, filePath: source };
8186
8788
  } catch (error) {
8187
8789
  return { error: `Error loading from local path ${source}: ${error}` };
@@ -8198,7 +8800,7 @@ class DownloadUtils {
8198
8800
  if (!response.ok) {
8199
8801
  return { error: `Failed to fetch from ${source}: ${response.statusText}` };
8200
8802
  }
8201
- const content = await response.arrayBuffer();
8803
+ const content = Buffer.from(await response.arrayBuffer());
8202
8804
  await writeFile(targetPath, Buffer.from(content));
8203
8805
  console.log(`Downloaded: ${source} -> ${targetPath}`);
8204
8806
  return { content, filePath: targetPath };
@@ -8208,7 +8810,7 @@ class DownloadUtils {
8208
8810
  } else {
8209
8811
  try {
8210
8812
  console.log(`Copying from local path: ${source}`);
8211
- const content = await Bun.file(source).arrayBuffer();
8813
+ const content = await readFile(source);
8212
8814
  await writeFile(targetPath, Buffer.from(content));
8213
8815
  return { content, filePath: targetPath };
8214
8816
  } catch (error) {
@@ -8259,7 +8861,7 @@ async function loadConfig(configPath) {
8259
8861
  ext = path3.extname(resolvedConfigPath);
8260
8862
  }
8261
8863
  if (ext === ".json") {
8262
- const configContent = await readFile(resolvedConfigPath, "utf-8");
8864
+ const configContent = await readFile2(resolvedConfigPath, "utf-8");
8263
8865
  return JSON.parse(configContent);
8264
8866
  } else if (ext === ".ts" || ext === ".js") {
8265
8867
  const { default: configContent } = await import(resolvedConfigPath);
@@ -8287,7 +8889,7 @@ async function downloadAndCombineQueries(filetype, queryUrls, assetsDir, outputP
8287
8889
  console.log(` Using local query ${i + 1}/${queryUrls.length}: ${queryUrl}`);
8288
8890
  try {
8289
8891
  const localPath = path3.resolve(path3.dirname(configPath), queryUrl);
8290
- const content = await readFile(localPath, "utf-8");
8892
+ const content = await readFile2(localPath, "utf-8");
8291
8893
  if (content.trim()) {
8292
8894
  queryContents.push(content);
8293
8895
  console.log(` \u2713 Loaded ${content.split(`
@@ -9172,80 +9774,136 @@ class TerminalPalette {
9172
9774
  stdin;
9173
9775
  stdout;
9174
9776
  writeFn;
9175
- activeListeners = [];
9176
- activeTimers = [];
9777
+ activeQuerySessions = [];
9177
9778
  inLegacyTmux;
9178
- constructor(stdin, stdout, writeFn, isLegacyTmux) {
9779
+ oscSource;
9780
+ constructor(stdin, stdout, writeFn, isLegacyTmux, oscSource) {
9179
9781
  this.stdin = stdin;
9180
9782
  this.stdout = stdout;
9181
9783
  this.writeFn = writeFn || ((data) => stdout.write(data));
9182
9784
  this.inLegacyTmux = isLegacyTmux ?? false;
9785
+ this.oscSource = oscSource;
9183
9786
  }
9184
9787
  writeOsc(osc) {
9185
9788
  const data = this.inLegacyTmux ? wrapForTmux(osc) : osc;
9186
9789
  return this.writeFn(data);
9187
9790
  }
9188
9791
  cleanup() {
9189
- for (const { event, handler } of this.activeListeners) {
9190
- this.stdin.removeListener(event, handler);
9792
+ for (const cleanupSession of [...this.activeQuerySessions]) {
9793
+ cleanupSession();
9191
9794
  }
9192
- this.activeListeners = [];
9193
- for (const timer of this.activeTimers) {
9194
- clearTimeout(timer);
9795
+ this.activeQuerySessions = [];
9796
+ }
9797
+ subscribeInput(handler) {
9798
+ if (this.oscSource) {
9799
+ return this.oscSource.subscribeOsc((sequence) => {
9800
+ handler(sequence);
9801
+ });
9195
9802
  }
9196
- this.activeTimers = [];
9803
+ this.stdin.on("data", handler);
9804
+ return () => {
9805
+ this.stdin.removeListener("data", handler);
9806
+ };
9807
+ }
9808
+ createQuerySession() {
9809
+ const timers = new Set;
9810
+ const subscriptions = new Set;
9811
+ let closed = false;
9812
+ const cleanup = () => {
9813
+ if (closed)
9814
+ return;
9815
+ closed = true;
9816
+ for (const timer of timers) {
9817
+ clearTimeout(timer);
9818
+ }
9819
+ timers.clear();
9820
+ for (const unsubscribe of subscriptions) {
9821
+ unsubscribe();
9822
+ }
9823
+ subscriptions.clear();
9824
+ const idx = this.activeQuerySessions.indexOf(cleanup);
9825
+ if (idx !== -1)
9826
+ this.activeQuerySessions.splice(idx, 1);
9827
+ };
9828
+ this.activeQuerySessions.push(cleanup);
9829
+ return {
9830
+ setTimer: (fn, ms) => {
9831
+ const timer = setTimeout(fn, ms);
9832
+ timers.add(timer);
9833
+ return timer;
9834
+ },
9835
+ resetTimer: (existing, fn, ms) => {
9836
+ if (existing) {
9837
+ clearTimeout(existing);
9838
+ timers.delete(existing);
9839
+ }
9840
+ const timer = setTimeout(fn, ms);
9841
+ timers.add(timer);
9842
+ return timer;
9843
+ },
9844
+ subscribeInput: (handler) => {
9845
+ const unsubscribe = this.subscribeInput(handler);
9846
+ subscriptions.add(unsubscribe);
9847
+ return () => {
9848
+ if (!subscriptions.has(unsubscribe))
9849
+ return;
9850
+ subscriptions.delete(unsubscribe);
9851
+ unsubscribe();
9852
+ };
9853
+ },
9854
+ cleanup
9855
+ };
9197
9856
  }
9198
9857
  async detectOSCSupport(timeoutMs = 300) {
9199
9858
  const out = this.stdout;
9200
- const inp = this.stdin;
9201
- if (!out.isTTY || !inp.isTTY)
9859
+ if (!out.isTTY || !this.stdin.isTTY)
9202
9860
  return false;
9203
9861
  return new Promise((resolve4) => {
9862
+ const session = this.createQuerySession();
9204
9863
  let buffer = "";
9864
+ let settled = false;
9865
+ const finish = (supported) => {
9866
+ if (settled)
9867
+ return;
9868
+ settled = true;
9869
+ session.cleanup();
9870
+ resolve4(supported);
9871
+ };
9205
9872
  const onData = (chunk) => {
9206
9873
  buffer += chunk.toString();
9207
9874
  OSC4_RESPONSE.lastIndex = 0;
9208
9875
  if (OSC4_RESPONSE.test(buffer)) {
9209
- cleanup();
9210
- resolve4(true);
9876
+ finish(true);
9211
9877
  }
9212
9878
  };
9213
- const onTimeout = () => {
9214
- cleanup();
9215
- resolve4(false);
9216
- };
9217
- const cleanup = () => {
9218
- clearTimeout(timer);
9219
- inp.removeListener("data", onData);
9220
- const listenerIdx = this.activeListeners.findIndex((l) => l.handler === onData);
9221
- if (listenerIdx !== -1)
9222
- this.activeListeners.splice(listenerIdx, 1);
9223
- const timerIdx = this.activeTimers.indexOf(timer);
9224
- if (timerIdx !== -1)
9225
- this.activeTimers.splice(timerIdx, 1);
9226
- };
9227
- const timer = setTimeout(onTimeout, timeoutMs);
9228
- this.activeTimers.push(timer);
9229
- inp.on("data", onData);
9230
- this.activeListeners.push({ event: "data", handler: onData });
9879
+ session.setTimer(() => {
9880
+ finish(false);
9881
+ }, timeoutMs);
9882
+ session.subscribeInput(onData);
9231
9883
  this.writeOsc("\x1B]4;0;?\x07");
9232
9884
  });
9233
9885
  }
9234
9886
  async queryPalette(indices, timeoutMs = 1200) {
9235
9887
  const out = this.stdout;
9236
- const inp = this.stdin;
9237
9888
  const results = new Map;
9238
9889
  indices.forEach((i) => results.set(i, null));
9239
- if (!out.isTTY || !inp.isTTY) {
9890
+ if (!out.isTTY || !this.stdin.isTTY) {
9240
9891
  return results;
9241
9892
  }
9242
9893
  return new Promise((resolve4) => {
9894
+ const session = this.createQuerySession();
9243
9895
  let buffer = "";
9244
- let lastResponseTime = Date.now();
9245
9896
  let idleTimer = null;
9897
+ let settled = false;
9898
+ const finish = () => {
9899
+ if (settled)
9900
+ return;
9901
+ settled = true;
9902
+ session.cleanup();
9903
+ resolve4(results);
9904
+ };
9246
9905
  const onData = (chunk) => {
9247
9906
  buffer += chunk.toString();
9248
- lastResponseTime = Date.now();
9249
9907
  let m;
9250
9908
  OSC4_RESPONSE.lastIndex = 0;
9251
9909
  while (m = OSC4_RESPONSE.exec(buffer)) {
@@ -9257,50 +9915,18 @@ class TerminalPalette {
9257
9915
  buffer = buffer.slice(-4096);
9258
9916
  const done = [...results.values()].filter((v) => v !== null).length;
9259
9917
  if (done === results.size) {
9260
- cleanup();
9261
- resolve4(results);
9918
+ finish();
9262
9919
  return;
9263
9920
  }
9264
- if (idleTimer)
9265
- clearTimeout(idleTimer);
9266
- idleTimer = setTimeout(() => {
9267
- cleanup();
9268
- resolve4(results);
9269
- }, 150);
9270
- if (idleTimer)
9271
- this.activeTimers.push(idleTimer);
9272
- };
9273
- const onTimeout = () => {
9274
- cleanup();
9275
- resolve4(results);
9276
- };
9277
- const cleanup = () => {
9278
- clearTimeout(timer);
9279
- if (idleTimer)
9280
- clearTimeout(idleTimer);
9281
- inp.removeListener("data", onData);
9282
- const listenerIdx = this.activeListeners.findIndex((l) => l.handler === onData);
9283
- if (listenerIdx !== -1)
9284
- this.activeListeners.splice(listenerIdx, 1);
9285
- const timerIdx = this.activeTimers.indexOf(timer);
9286
- if (timerIdx !== -1)
9287
- this.activeTimers.splice(timerIdx, 1);
9288
- if (idleTimer) {
9289
- const idleTimerIdx = this.activeTimers.indexOf(idleTimer);
9290
- if (idleTimerIdx !== -1)
9291
- this.activeTimers.splice(idleTimerIdx, 1);
9292
- }
9921
+ idleTimer = session.resetTimer(idleTimer, finish, 150);
9293
9922
  };
9294
- const timer = setTimeout(onTimeout, timeoutMs);
9295
- this.activeTimers.push(timer);
9296
- inp.on("data", onData);
9297
- this.activeListeners.push({ event: "data", handler: onData });
9923
+ session.setTimer(finish, timeoutMs);
9924
+ session.subscribeInput(onData);
9298
9925
  this.writeOsc(indices.map((i) => `\x1B]4;${i};?\x07`).join(""));
9299
9926
  });
9300
9927
  }
9301
9928
  async querySpecialColors(timeoutMs = 1200) {
9302
9929
  const out = this.stdout;
9303
- const inp = this.stdin;
9304
9930
  const results = {
9305
9931
  10: null,
9306
9932
  11: null,
@@ -9312,12 +9938,21 @@ class TerminalPalette {
9312
9938
  17: null,
9313
9939
  19: null
9314
9940
  };
9315
- if (!out.isTTY || !inp.isTTY) {
9941
+ if (!out.isTTY || !this.stdin.isTTY) {
9316
9942
  return results;
9317
9943
  }
9318
9944
  return new Promise((resolve4) => {
9945
+ const session = this.createQuerySession();
9319
9946
  let buffer = "";
9320
9947
  let idleTimer = null;
9948
+ let settled = false;
9949
+ const finish = () => {
9950
+ if (settled)
9951
+ return;
9952
+ settled = true;
9953
+ session.cleanup();
9954
+ resolve4(results);
9955
+ };
9321
9956
  const onData = (chunk) => {
9322
9957
  buffer += chunk.toString();
9323
9958
  let updated = false;
@@ -9334,46 +9969,15 @@ class TerminalPalette {
9334
9969
  buffer = buffer.slice(-4096);
9335
9970
  const done = Object.values(results).filter((v) => v !== null).length;
9336
9971
  if (done === Object.keys(results).length) {
9337
- cleanup();
9338
- resolve4(results);
9972
+ finish();
9339
9973
  return;
9340
9974
  }
9341
9975
  if (!updated)
9342
9976
  return;
9343
- if (idleTimer)
9344
- clearTimeout(idleTimer);
9345
- idleTimer = setTimeout(() => {
9346
- cleanup();
9347
- resolve4(results);
9348
- }, 150);
9349
- if (idleTimer)
9350
- this.activeTimers.push(idleTimer);
9351
- };
9352
- const onTimeout = () => {
9353
- cleanup();
9354
- resolve4(results);
9355
- };
9356
- const cleanup = () => {
9357
- clearTimeout(timer);
9358
- if (idleTimer)
9359
- clearTimeout(idleTimer);
9360
- inp.removeListener("data", onData);
9361
- const listenerIdx = this.activeListeners.findIndex((l) => l.handler === onData);
9362
- if (listenerIdx !== -1)
9363
- this.activeListeners.splice(listenerIdx, 1);
9364
- const timerIdx = this.activeTimers.indexOf(timer);
9365
- if (timerIdx !== -1)
9366
- this.activeTimers.splice(timerIdx, 1);
9367
- if (idleTimer) {
9368
- const idleTimerIdx = this.activeTimers.indexOf(idleTimer);
9369
- if (idleTimerIdx !== -1)
9370
- this.activeTimers.splice(idleTimerIdx, 1);
9371
- }
9977
+ idleTimer = session.resetTimer(idleTimer, finish, 150);
9372
9978
  };
9373
- const timer = setTimeout(onTimeout, timeoutMs);
9374
- this.activeTimers.push(timer);
9375
- inp.on("data", onData);
9376
- this.activeListeners.push({ event: "data", handler: onData });
9979
+ session.setTimer(finish, timeoutMs);
9980
+ session.subscribeInput(onData);
9377
9981
  this.writeOsc([
9378
9982
  "\x1B]10;?\x07",
9379
9983
  "\x1B]11;?\x07",
@@ -9423,8 +10027,8 @@ class TerminalPalette {
9423
10027
  };
9424
10028
  }
9425
10029
  }
9426
- function createTerminalPalette(stdin, stdout, writeFn, isLegacyTmux) {
9427
- return new TerminalPalette(stdin, stdout, writeFn, isLegacyTmux);
10030
+ function createTerminalPalette(stdin, stdout, writeFn, isLegacyTmux, oscSource) {
10031
+ return new TerminalPalette(stdin, stdout, writeFn, isLegacyTmux, oscSource);
9428
10032
  }
9429
10033
 
9430
10034
  // src/lib/detect-links.ts
@@ -9470,8 +10074,8 @@ function detectLinks(chunks, context) {
9470
10074
  }
9471
10075
  // src/zig.ts
9472
10076
  import { dlopen, toArrayBuffer as toArrayBuffer4, JSCallback, ptr as ptr4 } from "bun:ffi";
9473
- import { existsSync as existsSync2 } from "fs";
9474
- import { EventEmitter as EventEmitter5 } from "events";
10077
+ import { existsSync as existsSync2, writeFileSync } from "fs";
10078
+ import { EventEmitter as EventEmitter4 } from "events";
9475
10079
 
9476
10080
  // src/buffer.ts
9477
10081
  import { toArrayBuffer, ptr } from "bun:ffi";
@@ -10463,19 +11067,19 @@ var EncodedCharStruct = defineStruct([
10463
11067
  ["char", "u32"]
10464
11068
  ]);
10465
11069
  var LineInfoStruct = defineStruct([
10466
- ["starts", ["u32"]],
10467
- ["startsLen", "u32", { lengthOf: "starts" }],
10468
- ["widths", ["u32"]],
10469
- ["widthsLen", "u32", { lengthOf: "widths" }],
11070
+ ["startCols", ["u32"]],
11071
+ ["startColsLen", "u32", { lengthOf: "startCols" }],
11072
+ ["widthCols", ["u32"]],
11073
+ ["widthColsLen", "u32", { lengthOf: "widthCols" }],
10470
11074
  ["sources", ["u32"]],
10471
11075
  ["sourcesLen", "u32", { lengthOf: "sources" }],
10472
11076
  ["wraps", ["u32"]],
10473
11077
  ["wrapsLen", "u32", { lengthOf: "wraps" }],
10474
- ["maxWidth", "u32"]
11078
+ ["widthColsMax", "u32"]
10475
11079
  ]);
10476
11080
  var MeasureResultStruct = defineStruct([
10477
11081
  ["lineCount", "u32"],
10478
- ["maxWidth", "u32"]
11082
+ ["widthColsMax", "u32"]
10479
11083
  ]);
10480
11084
  var CursorStateStruct = defineStruct([
10481
11085
  ["x", "u32"],
@@ -10602,11 +11206,11 @@ registerEnvVar({
10602
11206
  type: "boolean",
10603
11207
  default: false
10604
11208
  });
10605
- var CURSOR_STYLE_TO_ID = { block: 0, line: 1, underline: 2 };
10606
- var CURSOR_ID_TO_STYLE = ["block", "line", "underline"];
11209
+ var CURSOR_STYLE_TO_ID = { block: 0, line: 1, underline: 2, default: 3 };
11210
+ var CURSOR_ID_TO_STYLE = ["block", "line", "underline", "default"];
10607
11211
  var MOUSE_STYLE_TO_ID = { default: 0, pointer: 1, text: 2, crosshair: 3, move: 4, "not-allowed": 5 };
10608
11212
  var globalTraceSymbols = null;
10609
- var globalFFILogWriter = null;
11213
+ var globalFFILogPath = null;
10610
11214
  var exitHandlerRegistered = false;
10611
11215
  function toPointer(value) {
10612
11216
  if (typeof value === "bigint") {
@@ -11595,24 +12199,21 @@ function convertToDebugSymbols(symbols) {
11595
12199
  if (!globalTraceSymbols) {
11596
12200
  globalTraceSymbols = {};
11597
12201
  }
11598
- if (env.OTUI_DEBUG_FFI && !globalFFILogWriter) {
12202
+ if (env.OTUI_DEBUG_FFI && !globalFFILogPath) {
11599
12203
  const now = new Date;
11600
12204
  const timestamp = now.toISOString().replace(/[:.]/g, "-").replace(/T/, "_").split("Z")[0];
11601
- const logFilePath = `ffi_otui_debug_${timestamp}.log`;
11602
- globalFFILogWriter = Bun.file(logFilePath).writer();
12205
+ globalFFILogPath = `ffi_otui_debug_${timestamp}.log`;
11603
12206
  }
11604
12207
  const debugSymbols = {};
11605
12208
  let hasTracing = false;
11606
12209
  Object.entries(symbols).forEach(([key, value]) => {
11607
12210
  debugSymbols[key] = value;
11608
12211
  });
11609
- if (env.OTUI_DEBUG_FFI && globalFFILogWriter) {
11610
- const writer = globalFFILogWriter;
12212
+ if (env.OTUI_DEBUG_FFI && globalFFILogPath) {
12213
+ const logPath = globalFFILogPath;
11611
12214
  const writeSync = (msg) => {
11612
- const buffer = new TextEncoder().encode(msg + `
11613
- `);
11614
- writer.write(buffer);
11615
- writer.flush();
12215
+ writeFileSync(logPath, msg + `
12216
+ `, { flag: "a" });
11616
12217
  };
11617
12218
  Object.entries(symbols).forEach(([key, value]) => {
11618
12219
  if (typeof value === "function") {
@@ -11646,11 +12247,6 @@ function convertToDebugSymbols(symbols) {
11646
12247
  if ((env.OTUI_DEBUG_FFI || env.OTUI_TRACE_FFI) && !exitHandlerRegistered) {
11647
12248
  exitHandlerRegistered = true;
11648
12249
  process.on("exit", () => {
11649
- try {
11650
- if (globalFFILogWriter) {
11651
- globalFFILogWriter.end();
11652
- }
11653
- } catch (e) {}
11654
12250
  if (globalTraceSymbols) {
11655
12251
  const allStats = [];
11656
12252
  for (const [key, timings] of Object.entries(globalTraceSymbols)) {
@@ -11703,15 +12299,15 @@ function convertToDebugSymbols(symbols) {
11703
12299
  const countWidth = Math.max(callsHeader.length, ...allStats.map((s) => String(s.count).length));
11704
12300
  const totalWidth = Math.max(totalHeader.length, ...allStats.map((s) => s.total.toFixed(2).length));
11705
12301
  const avgWidth = Math.max(avgHeader.length, ...allStats.map((s) => s.average.toFixed(2).length));
11706
- const minWidth = Math.max(minHeader.length, ...allStats.map((s) => s.min.toFixed(2).length));
11707
- const maxWidth = Math.max(maxHeader.length, ...allStats.map((s) => s.max.toFixed(2).length));
12302
+ const statWidthMin = Math.max(minHeader.length, ...allStats.map((s) => s.min.toFixed(2).length));
12303
+ const statWidthMax = Math.max(maxHeader.length, ...allStats.map((s) => s.max.toFixed(2).length));
11708
12304
  const medianWidth = Math.max(medHeader.length, ...allStats.map((s) => s.median.toFixed(2).length));
11709
12305
  const p90Width = Math.max(p90Header.length, ...allStats.map((s) => s.p90.toFixed(2).length));
11710
12306
  const p99Width = Math.max(p99Header.length, ...allStats.map((s) => s.p99.toFixed(2).length));
11711
- lines.push(`${nameHeader.padEnd(nameWidth)} | ${callsHeader.padStart(countWidth)} | ${totalHeader.padStart(totalWidth)} | ${avgHeader.padStart(avgWidth)} | ${minHeader.padStart(minWidth)} | ${maxHeader.padStart(maxWidth)} | ${medHeader.padStart(medianWidth)} | ${p90Header.padStart(p90Width)} | ${p99Header.padStart(p99Width)}`);
11712
- lines.push(`${"-".repeat(nameWidth)}-+-${"-".repeat(countWidth)}-+-${"-".repeat(totalWidth)}-+-${"-".repeat(avgWidth)}-+-${"-".repeat(minWidth)}-+-${"-".repeat(maxWidth)}-+-${"-".repeat(medianWidth)}-+-${"-".repeat(p90Width)}-+-${"-".repeat(p99Width)}`);
12307
+ lines.push(`${nameHeader.padEnd(nameWidth)} | ${callsHeader.padStart(countWidth)} | ${totalHeader.padStart(totalWidth)} | ${avgHeader.padStart(avgWidth)} | ${minHeader.padStart(statWidthMin)} | ${maxHeader.padStart(statWidthMax)} | ${medHeader.padStart(medianWidth)} | ${p90Header.padStart(p90Width)} | ${p99Header.padStart(p99Width)}`);
12308
+ lines.push(`${"-".repeat(nameWidth)}-+-${"-".repeat(countWidth)}-+-${"-".repeat(totalWidth)}-+-${"-".repeat(avgWidth)}-+-${"-".repeat(statWidthMin)}-+-${"-".repeat(statWidthMax)}-+-${"-".repeat(medianWidth)}-+-${"-".repeat(p90Width)}-+-${"-".repeat(p99Width)}`);
11713
12309
  allStats.forEach((stat) => {
11714
- lines.push(`${stat.name.padEnd(nameWidth)} | ${String(stat.count).padStart(countWidth)} | ${stat.total.toFixed(2).padStart(totalWidth)} | ${stat.average.toFixed(2).padStart(avgWidth)} | ${stat.min.toFixed(2).padStart(minWidth)} | ${stat.max.toFixed(2).padStart(maxWidth)} | ${stat.median.toFixed(2).padStart(medianWidth)} | ${stat.p90.toFixed(2).padStart(p90Width)} | ${stat.p99.toFixed(2).padStart(p99Width)}`);
12310
+ lines.push(`${stat.name.padEnd(nameWidth)} | ${String(stat.count).padStart(countWidth)} | ${stat.total.toFixed(2).padStart(totalWidth)} | ${stat.average.toFixed(2).padStart(avgWidth)} | ${stat.min.toFixed(2).padStart(statWidthMin)} | ${stat.max.toFixed(2).padStart(statWidthMax)} | ${stat.median.toFixed(2).padStart(medianWidth)} | ${stat.p90.toFixed(2).padStart(p90Width)} | ${stat.p99.toFixed(2).padStart(p99Width)}`);
11715
12311
  });
11716
12312
  }
11717
12313
  lines.push("-------------------------------------------------------------------------------------------------------------------------");
@@ -11745,7 +12341,7 @@ class FFIRenderLib {
11745
12341
  decoder = new TextDecoder;
11746
12342
  logCallbackWrapper;
11747
12343
  eventCallbackWrapper;
11748
- _nativeEvents = new EventEmitter5;
12344
+ _nativeEvents = new EventEmitter4;
11749
12345
  _anyEventHandlers = [];
11750
12346
  nativeSpanFeedCallbackWrapper = null;
11751
12347
  nativeSpanFeedHandlers = new Map;
@@ -12351,10 +12947,13 @@ class FFIRenderLib {
12351
12947
  const outBuffer = new ArrayBuffer(LineInfoStruct.size);
12352
12948
  this.textBufferViewGetLineInfoDirect(view, ptr4(outBuffer));
12353
12949
  const struct = LineInfoStruct.unpack(outBuffer);
12950
+ const lineStartCols = struct.startCols;
12951
+ const lineWidthCols = struct.widthCols;
12952
+ const lineWidthColsMax = struct.widthColsMax;
12354
12953
  return {
12355
- maxLineWidth: struct.maxWidth,
12356
- lineStarts: struct.starts,
12357
- lineWidths: struct.widths,
12954
+ lineStartCols,
12955
+ lineWidthCols,
12956
+ lineWidthColsMax,
12358
12957
  lineSources: struct.sources,
12359
12958
  lineWraps: struct.wraps
12360
12959
  };
@@ -12363,10 +12962,13 @@ class FFIRenderLib {
12363
12962
  const outBuffer = new ArrayBuffer(LineInfoStruct.size);
12364
12963
  this.textBufferViewGetLogicalLineInfoDirect(view, ptr4(outBuffer));
12365
12964
  const struct = LineInfoStruct.unpack(outBuffer);
12965
+ const lineStartCols = struct.startCols;
12966
+ const lineWidthCols = struct.widthCols;
12967
+ const lineWidthColsMax = struct.widthColsMax;
12366
12968
  return {
12367
- maxLineWidth: struct.maxWidth,
12368
- lineStarts: struct.starts,
12369
- lineWidths: struct.widths,
12969
+ lineStartCols,
12970
+ lineWidthCols,
12971
+ lineWidthColsMax,
12370
12972
  lineSources: struct.sources,
12371
12973
  lineWraps: struct.wraps
12372
12974
  };
@@ -12542,10 +13144,13 @@ class FFIRenderLib {
12542
13144
  const outBuffer = new ArrayBuffer(LineInfoStruct.size);
12543
13145
  this.opentui.symbols.editorViewGetLineInfoDirect(view, ptr4(outBuffer));
12544
13146
  const struct = LineInfoStruct.unpack(outBuffer);
13147
+ const lineStartCols = struct.startCols;
13148
+ const lineWidthCols = struct.widthCols;
13149
+ const lineWidthColsMax = struct.widthColsMax;
12545
13150
  return {
12546
- maxLineWidth: struct.maxWidth,
12547
- lineStarts: struct.starts,
12548
- lineWidths: struct.widths,
13151
+ lineStartCols,
13152
+ lineWidthCols,
13153
+ lineWidthColsMax,
12549
13154
  lineSources: struct.sources,
12550
13155
  lineWraps: struct.wraps
12551
13156
  };
@@ -12554,10 +13159,13 @@ class FFIRenderLib {
12554
13159
  const outBuffer = new ArrayBuffer(LineInfoStruct.size);
12555
13160
  this.opentui.symbols.editorViewGetLogicalLineInfoDirect(view, ptr4(outBuffer));
12556
13161
  const struct = LineInfoStruct.unpack(outBuffer);
13162
+ const lineStartCols = struct.startCols;
13163
+ const lineWidthCols = struct.widthCols;
13164
+ const lineWidthColsMax = struct.widthColsMax;
12557
13165
  return {
12558
- maxLineWidth: struct.maxWidth,
12559
- lineStarts: struct.starts,
12560
- lineWidths: struct.widths,
13166
+ lineStartCols,
13167
+ lineWidthCols,
13168
+ lineWidthColsMax,
12561
13169
  lineSources: struct.sources,
12562
13170
  lineWraps: struct.wraps
12563
13171
  };
@@ -13240,7 +13848,7 @@ class TextBuffer {
13240
13848
  }
13241
13849
 
13242
13850
  // src/Renderable.ts
13243
- import { EventEmitter as EventEmitter6 } from "events";
13851
+ import { EventEmitter as EventEmitter5 } from "events";
13244
13852
 
13245
13853
  // src/lib/renderable.validations.ts
13246
13854
  function validateOptions(id, options) {
@@ -13333,7 +13941,7 @@ function isRenderable(obj) {
13333
13941
  return !!obj?.[BrandedRenderable];
13334
13942
  }
13335
13943
 
13336
- class BaseRenderable extends EventEmitter6 {
13944
+ class BaseRenderable extends EventEmitter5 {
13337
13945
  [BrandedRenderable] = true;
13338
13946
  static renderableNumber = 1;
13339
13947
  _id;
@@ -14715,7 +15323,7 @@ function delegate(mapping, vnode) {
14715
15323
  }
14716
15324
 
14717
15325
  // src/console.ts
14718
- import { EventEmitter as EventEmitter8 } from "events";
15326
+ import { EventEmitter as EventEmitter7 } from "events";
14719
15327
  import { Console } from "console";
14720
15328
  import fs from "fs";
14721
15329
  import path4 from "path";
@@ -14723,9 +15331,9 @@ import util2 from "util";
14723
15331
 
14724
15332
  // src/lib/output.capture.ts
14725
15333
  import { Writable } from "stream";
14726
- import { EventEmitter as EventEmitter7 } from "events";
15334
+ import { EventEmitter as EventEmitter6 } from "events";
14727
15335
 
14728
- class Capture extends EventEmitter7 {
15336
+ class Capture extends EventEmitter6 {
14729
15337
  output = [];
14730
15338
  constructor() {
14731
15339
  super();
@@ -14854,7 +15462,7 @@ registerEnvVar({
14854
15462
  default: false
14855
15463
  });
14856
15464
 
14857
- class TerminalConsoleCache extends EventEmitter8 {
15465
+ class TerminalConsoleCache extends EventEmitter7 {
14858
15466
  _cachedLogs = [];
14859
15467
  MAX_CACHE_SIZE = 1000;
14860
15468
  _collectCallerInfo = false;
@@ -14998,7 +15606,7 @@ var DEFAULT_CONSOLE_OPTIONS = {
14998
15606
  };
14999
15607
  var INDENT_WIDTH = 2;
15000
15608
 
15001
- class TerminalConsole extends EventEmitter8 {
15609
+ class TerminalConsole extends EventEmitter7 {
15002
15610
  isVisible = false;
15003
15611
  isFocused = false;
15004
15612
  renderer;
@@ -15841,7 +16449,7 @@ class Clipboard {
15841
16449
  }
15842
16450
 
15843
16451
  // src/renderer.ts
15844
- import { EventEmitter as EventEmitter9 } from "events";
16452
+ import { EventEmitter as EventEmitter8 } from "events";
15845
16453
 
15846
16454
  // src/lib/objects-in-viewport.ts
15847
16455
  function getObjectsInViewport(viewport, objects, direction = "column", padding = 10, minTriggerSize = 16) {
@@ -16036,6 +16644,7 @@ var KITTY_FLAG_EVENT_TYPES = 2;
16036
16644
  var KITTY_FLAG_ALTERNATE_KEYS = 4;
16037
16645
  var KITTY_FLAG_ALL_KEYS_AS_ESCAPES = 8;
16038
16646
  var KITTY_FLAG_REPORT_TEXT = 16;
16647
+ var DEFAULT_STDIN_PARSER_MAX_BUFFER_BYTES = 64 * 1024 * 1024;
16039
16648
  function buildKittyKeyboardFlags(config) {
16040
16649
  if (!config) {
16041
16650
  return 0;
@@ -16169,7 +16778,7 @@ var RendererControlState;
16169
16778
  RendererControlState2["EXPLICIT_STOPPED"] = "explicit_stopped";
16170
16779
  })(RendererControlState ||= {});
16171
16780
 
16172
- class CliRenderer extends EventEmitter9 {
16781
+ class CliRenderer extends EventEmitter8 {
16173
16782
  static animationFrameId = 0;
16174
16783
  lib;
16175
16784
  rendererPtr;
@@ -16231,7 +16840,9 @@ class CliRenderer extends EventEmitter9 {
16231
16840
  _console;
16232
16841
  _resolution = null;
16233
16842
  _keyHandler;
16234
- _stdinBuffer;
16843
+ stdinParser = null;
16844
+ oscSubscribers = new Set;
16845
+ hasLoggedStdinParserError = false;
16235
16846
  animationRequest = new Map;
16236
16847
  resizeTimeoutId = null;
16237
16848
  capabilityTimeoutId = null;
@@ -16260,7 +16871,6 @@ class CliRenderer extends EventEmitter9 {
16260
16871
  }
16261
16872
  };
16262
16873
  _useConsole = true;
16263
- mouseParser = new MouseParser;
16264
16874
  sigwinchHandler = (() => {
16265
16875
  const width = this.stdout.columns || 80;
16266
16876
  const height = this.stdout.rows || 24;
@@ -16279,7 +16889,7 @@ class CliRenderer extends EventEmitter9 {
16279
16889
  _paletteDetectionPromise = null;
16280
16890
  _onDestroy;
16281
16891
  _themeMode = null;
16282
- inputHandlers = [];
16892
+ sequenceHandlers = [];
16283
16893
  prependedInputHandlers = [];
16284
16894
  shouldRestoreModesOnNextFocus = false;
16285
16895
  idleResolvers = [];
@@ -16396,7 +17006,7 @@ Captured output:
16396
17006
  process.on("beforeExit", this.exitHandler);
16397
17007
  const kittyConfig = config.useKittyKeyboard ?? {};
16398
17008
  const useKittyForParsing = kittyConfig !== null;
16399
- this._keyHandler = new InternalKeyHandler(useKittyForParsing);
17009
+ this._keyHandler = new InternalKeyHandler;
16400
17010
  this._keyHandler.on("keypress", (event) => {
16401
17011
  if (this.exitOnCtrlC && event.name === "c" && event.ctrl) {
16402
17012
  process.nextTick(() => {
@@ -16406,7 +17016,17 @@ Captured output:
16406
17016
  }
16407
17017
  });
16408
17018
  this.addExitListeners();
16409
- this._stdinBuffer = new StdinBuffer({ timeout: 5 });
17019
+ const stdinParserMaxBufferBytes = config.stdinParserMaxBufferBytes ?? DEFAULT_STDIN_PARSER_MAX_BUFFER_BYTES;
17020
+ this.stdinParser = new StdinParser({
17021
+ timeoutMs: 10,
17022
+ maxPendingBytes: stdinParserMaxBufferBytes,
17023
+ armTimeouts: true,
17024
+ onTimeoutFlush: () => {
17025
+ this.drainStdinParser();
17026
+ },
17027
+ useKittyKeyboard: useKittyForParsing,
17028
+ clock: config.stdinParserClock
17029
+ });
16410
17030
  this._console = new TerminalConsole(this, config.consoleOptions);
16411
17031
  this.useConsole = config.useConsole ?? true;
16412
17032
  this._openConsoleOnError = config.openConsoleOnError ?? true;
@@ -16714,7 +17334,7 @@ Captured output:
16714
17334
  disableMouse() {
16715
17335
  this._useMouse = false;
16716
17336
  this.setCapturedRenderable(undefined);
16717
- this.mouseParser.reset();
17337
+ this.stdinParser?.resetMouseState();
16718
17338
  this.lib.disableMouse(this.rendererPtr);
16719
17339
  }
16720
17340
  enableKittyKeyboard(flags = 3) {
@@ -16750,20 +17370,31 @@ Captured output:
16750
17370
  }
16751
17371
  this.queryPixelResolution();
16752
17372
  }
16753
- stdinListener = ((data) => {
16754
- if (this._useMouse && this.handleMouseData(data)) {
17373
+ stdinListener = ((chunk) => {
17374
+ const data = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
17375
+ if (!this.stdinParser)
16755
17376
  return;
17377
+ try {
17378
+ this.stdinParser.push(data);
17379
+ this.drainStdinParser();
17380
+ } catch (error) {
17381
+ this.handleStdinParserFailure(error);
16756
17382
  }
16757
- this._stdinBuffer.process(data);
16758
17383
  }).bind(this);
16759
17384
  addInputHandler(handler) {
16760
- this.inputHandlers.push(handler);
17385
+ this.sequenceHandlers.push(handler);
16761
17386
  }
16762
17387
  prependInputHandler(handler) {
16763
- this.inputHandlers.unshift(handler);
17388
+ this.sequenceHandlers.unshift(handler);
16764
17389
  }
16765
17390
  removeInputHandler(handler) {
16766
- this.inputHandlers = this.inputHandlers.filter((h2) => h2 !== handler);
17391
+ this.sequenceHandlers = this.sequenceHandlers.filter((candidate) => candidate !== handler);
17392
+ }
17393
+ subscribeOsc(handler) {
17394
+ this.oscSubscribers.add(handler);
17395
+ return () => {
17396
+ this.oscSubscribers.delete(handler);
17397
+ };
16767
17398
  }
16768
17399
  capabilityHandler = ((sequence) => {
16769
17400
  if (isCapabilityResponse(sequence)) {
@@ -16807,6 +17438,67 @@ Captured output:
16807
17438
  }
16808
17439
  return false;
16809
17440
  }).bind(this);
17441
+ dispatchSequenceHandlers(sequence) {
17442
+ if (this._debugModeEnabled) {
17443
+ this._debugInputs.push({
17444
+ timestamp: new Date().toISOString(),
17445
+ sequence
17446
+ });
17447
+ }
17448
+ for (const handler of this.sequenceHandlers) {
17449
+ if (handler(sequence)) {
17450
+ return true;
17451
+ }
17452
+ }
17453
+ return false;
17454
+ }
17455
+ drainStdinParser() {
17456
+ if (!this.stdinParser)
17457
+ return;
17458
+ this.stdinParser.drain((event) => {
17459
+ this.handleStdinEvent(event);
17460
+ });
17461
+ }
17462
+ handleStdinEvent(event) {
17463
+ switch (event.type) {
17464
+ case "key":
17465
+ if (this.dispatchSequenceHandlers(event.raw)) {
17466
+ return;
17467
+ }
17468
+ this._keyHandler.processParsedKey(event.key);
17469
+ return;
17470
+ case "mouse":
17471
+ if (this._useMouse && this.processSingleMouseEvent(event.event)) {
17472
+ return;
17473
+ }
17474
+ this.dispatchSequenceHandlers(event.raw);
17475
+ return;
17476
+ case "paste":
17477
+ this._keyHandler.processPaste(event.text);
17478
+ return;
17479
+ case "response":
17480
+ if (event.protocol === "osc") {
17481
+ for (const subscriber of this.oscSubscribers) {
17482
+ subscriber(event.sequence);
17483
+ }
17484
+ }
17485
+ this.dispatchSequenceHandlers(event.sequence);
17486
+ return;
17487
+ }
17488
+ }
17489
+ handleStdinParserFailure(error) {
17490
+ if (!this.hasLoggedStdinParserError) {
17491
+ this.hasLoggedStdinParserError = true;
17492
+ if (true) {
17493
+ console.error("[stdin-parser-error] parser failure, resetting parser", error);
17494
+ }
17495
+ }
17496
+ try {
17497
+ this.stdinParser?.reset();
17498
+ } catch (resetError) {
17499
+ console.error("stdin parser reset failed after parser error", resetError);
17500
+ }
17501
+ }
16810
17502
  setupInput() {
16811
17503
  for (const handler of this.prependedInputHandlers) {
16812
17504
  this.addInputHandler(handler);
@@ -16825,31 +17517,11 @@ Captured output:
16825
17517
  this.addInputHandler(this.capabilityHandler);
16826
17518
  this.addInputHandler(this.focusHandler);
16827
17519
  this.addInputHandler(this.themeModeHandler);
16828
- this.addInputHandler((sequence) => {
16829
- return this._keyHandler.processInput(sequence);
16830
- });
16831
17520
  if (this.stdin.setRawMode) {
16832
17521
  this.stdin.setRawMode(true);
16833
17522
  }
16834
17523
  this.stdin.resume();
16835
- this.stdin.setEncoding("utf8");
16836
17524
  this.stdin.on("data", this.stdinListener);
16837
- this._stdinBuffer.on("data", (sequence) => {
16838
- if (this._debugModeEnabled) {
16839
- this._debugInputs.push({
16840
- timestamp: new Date().toISOString(),
16841
- sequence
16842
- });
16843
- }
16844
- for (const handler of this.inputHandlers) {
16845
- if (handler(sequence)) {
16846
- return;
16847
- }
16848
- }
16849
- });
16850
- this._stdinBuffer.on("paste", (data) => {
16851
- this._keyHandler.processPaste(data);
16852
- });
16853
17525
  }
16854
17526
  dispatchMouseEvent(target, attributes) {
16855
17527
  const event = new MouseEvent(target, attributes);
@@ -16866,18 +17538,6 @@ Captured output:
16866
17538
  }
16867
17539
  return event;
16868
17540
  }
16869
- handleMouseData(data) {
16870
- const mouseEvents = this.mouseParser.parseAllMouseEvents(data);
16871
- if (mouseEvents.length === 0)
16872
- return false;
16873
- let anyHandled = false;
16874
- for (const mouseEvent of mouseEvents) {
16875
- if (this.processSingleMouseEvent(mouseEvent)) {
16876
- anyHandled = true;
16877
- }
16878
- }
16879
- return anyHandled;
16880
- }
16881
17541
  processSingleMouseEvent(mouseEvent) {
16882
17542
  if (this._splitHeight > 0) {
16883
17543
  if (mouseEvent.y < this.renderOffset) {
@@ -17099,7 +17759,7 @@ Captured output:
17099
17759
  this._terminalHeight = height;
17100
17760
  this.queryPixelResolution();
17101
17761
  this.setCapturedRenderable(undefined);
17102
- this.mouseParser.reset();
17762
+ this.stdinParser?.resetMouseState();
17103
17763
  if (this._splitHeight > 0) {
17104
17764
  if (width < prevWidth) {
17105
17765
  const start = this._terminalHeight - this._splitHeight * 2;
@@ -17262,7 +17922,7 @@ Captured output:
17262
17922
  this._suspendedMouseEnabled = this._useMouse;
17263
17923
  this.disableMouse();
17264
17924
  this.removeExitListeners();
17265
- this._stdinBuffer.clear();
17925
+ this.stdinParser?.reset();
17266
17926
  this.stdin.removeListener("data", this.stdinListener);
17267
17927
  this.lib.suspendRenderer(this.rendererPtr);
17268
17928
  if (this.stdin.setRawMode) {
@@ -17374,16 +18034,18 @@ Captured output:
17374
18034
  } catch (e) {
17375
18035
  console.error("Error destroying root renderable:", e instanceof Error ? e.stack : String(e));
17376
18036
  }
17377
- this._stdinBuffer.destroy();
18037
+ this.stdin.removeListener("data", this.stdinListener);
18038
+ if (this.stdin.setRawMode) {
18039
+ this.stdin.setRawMode(false);
18040
+ }
18041
+ this.stdinParser?.destroy();
18042
+ this.stdinParser = null;
18043
+ this.oscSubscribers.clear();
17378
18044
  this._console.destroy();
17379
18045
  this.disableStdoutInterception();
17380
18046
  if (this._splitHeight > 0) {
17381
18047
  this.flushStdoutCache(this._splitHeight, true);
17382
18048
  }
17383
- if (this.stdin.setRawMode) {
17384
- this.stdin.setRawMode(false);
17385
- }
17386
- this.stdin.removeListener("data", this.stdinListener);
17387
18049
  this.lib.destroyRenderer(this.rendererPtr);
17388
18050
  rendererTracker.removeRenderer(this);
17389
18051
  if (this._onDestroy) {
@@ -17665,7 +18327,9 @@ Captured output:
17665
18327
  }
17666
18328
  if (!this._paletteDetector) {
17667
18329
  const isLegacyTmux = this.capabilities?.terminal?.name?.toLowerCase()?.includes("tmux") && this.capabilities?.terminal?.version?.localeCompare("3.6") < 0;
17668
- this._paletteDetector = createTerminalPalette(this.stdin, this.stdout, this.writeOut.bind(this), isLegacyTmux);
18330
+ this._paletteDetector = createTerminalPalette(this.stdin, this.stdout, this.writeOut.bind(this), isLegacyTmux, {
18331
+ subscribeOsc: this.subscribeOsc.bind(this)
18332
+ });
17669
18333
  }
17670
18334
  this._paletteDetectionPromise = this._paletteDetector.detect(options).then((result) => {
17671
18335
  this._cachedPalette = result;
@@ -17676,7 +18340,7 @@ Captured output:
17676
18340
  }
17677
18341
  }
17678
18342
 
17679
- export { __toESM, __commonJS, __export, __require, Edge, Gutter, MeasureMode, exports_src, isValidBorderStyle, parseBorderStyle, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, nonAlphanumericKeys, parseKeypress, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, RGBA, hexToRgb, rgbToHex, hsvToRgb, parseColor, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, ATTRIBUTE_BASE_BITS, ATTRIBUTE_BASE_MASK, getBaseAttributes, DebugOverlayCorner, createTextAttributes, attributesWithLink, getLinkId, visualizeRenderableTree, isStyledText, StyledText, stringToStyledText, black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bold, italic, underline, strikethrough, dim, reverse, blink, fg, bg, link, t, hastToStyledText, LinearScrollAccel, MacOSScrollAccel, StdinBuffer, parseAlign, parseAlignItems, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, treeSitterToTextChunks, treeSitterToStyledText, addDefaultParsers, TreeSitterClient, DataPathsManager, getDataPaths, extToFiletype, pathToFiletype, main, getTreeSitterClient, ExtmarksController, createExtmarksController, TerminalPalette, createTerminalPalette, detectLinks, TextBuffer, SpanInfoStruct, LogLevel2 as LogLevel, setRenderLibPath, resolveRenderLib, OptimizedBuffer, h, isVNode, maybeMakeRenderable, wrapWithDelegates, instantiate, delegate, isValidPercentage, LayoutEvents, RenderableEvents, isRenderable, BaseRenderable, Renderable, RootRenderable, ANSI, defaultKeyAliases, mergeKeyAliases, mergeKeyBindings, getKeyBindingKey, buildKeyBindingsMap, capture, ConsolePosition, TerminalConsole, getObjectsInViewport, buildKittyKeyboardFlags, MouseEvent, MouseButton, createCliRenderer, CliRenderEvents, RendererControlState, CliRenderer };
18343
+ export { __toESM, __commonJS, __export, __require, Edge, Gutter, MeasureMode, exports_src, isValidBorderStyle, parseBorderStyle, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, RGBA, hexToRgb, rgbToHex, hsvToRgb, parseColor, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, ATTRIBUTE_BASE_BITS, ATTRIBUTE_BASE_MASK, getBaseAttributes, DebugOverlayCorner, createTextAttributes, attributesWithLink, getLinkId, visualizeRenderableTree, isStyledText, StyledText, stringToStyledText, black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bold, italic, underline, strikethrough, dim, reverse, blink, fg, bg, link, t, hastToStyledText, SystemClock, nonAlphanumericKeys, parseKeypress, LinearScrollAccel, MacOSScrollAccel, parseAlign, parseAlignItems, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, StdinParser, treeSitterToTextChunks, treeSitterToStyledText, addDefaultParsers, TreeSitterClient, DataPathsManager, getDataPaths, extToFiletype, pathToFiletype, main, getTreeSitterClient, ExtmarksController, createExtmarksController, TerminalPalette, createTerminalPalette, detectLinks, TextBuffer, SpanInfoStruct, LogLevel2 as LogLevel, setRenderLibPath, resolveRenderLib, OptimizedBuffer, h, isVNode, maybeMakeRenderable, wrapWithDelegates, instantiate, delegate, isValidPercentage, LayoutEvents, RenderableEvents, isRenderable, BaseRenderable, Renderable, RootRenderable, ANSI, defaultKeyAliases, mergeKeyAliases, mergeKeyBindings, getKeyBindingKey, buildKeyBindingsMap, capture, ConsolePosition, TerminalConsole, getObjectsInViewport, buildKittyKeyboardFlags, MouseEvent, MouseButton, createCliRenderer, CliRenderEvents, RendererControlState, CliRenderer };
17680
18344
 
17681
- //# debugId=18A382B09D14760A64756E2164756E21
17682
- //# sourceMappingURL=index-4sjb8n0n.js.map
18345
+ //# debugId=EFEF7A9F3BA3925B64756E2164756E21
18346
+ //# sourceMappingURL=index-0wbvecnk.js.map