@opentui/core 0.1.85 → 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
- }
6029
- return "incomplete";
6030
- }
6031
- function isCompleteOscSequence(data) {
6032
- if (!data.startsWith(ESC + "]")) {
6033
- return "complete";
6034
5810
  }
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;
6908
+ }
6909
+ for (let index = 0;index < left.length; index += 1) {
6910
+ if (left[index] !== right[index]) {
6911
+ return false;
6912
+ }
6888
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,64 +9938,46 @@ 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();
9958
+ let updated = false;
9323
9959
  let m;
9324
9960
  OSC_SPECIAL_RESPONSE.lastIndex = 0;
9325
9961
  while (m = OSC_SPECIAL_RESPONSE.exec(buffer)) {
9326
9962
  const idx = parseInt(m[1], 10);
9327
9963
  if (idx in results) {
9328
9964
  results[idx] = toHex(m[2], m[3], m[4], m[5]);
9965
+ updated = true;
9329
9966
  }
9330
9967
  }
9331
9968
  if (buffer.length > 8192)
9332
9969
  buffer = buffer.slice(-4096);
9333
9970
  const done = Object.values(results).filter((v) => v !== null).length;
9334
9971
  if (done === Object.keys(results).length) {
9335
- cleanup();
9336
- resolve4(results);
9972
+ finish();
9337
9973
  return;
9338
9974
  }
9339
- if (idleTimer)
9340
- clearTimeout(idleTimer);
9341
- idleTimer = setTimeout(() => {
9342
- cleanup();
9343
- resolve4(results);
9344
- }, 150);
9345
- if (idleTimer)
9346
- this.activeTimers.push(idleTimer);
9347
- };
9348
- const onTimeout = () => {
9349
- cleanup();
9350
- resolve4(results);
9351
- };
9352
- const cleanup = () => {
9353
- clearTimeout(timer);
9354
- if (idleTimer)
9355
- clearTimeout(idleTimer);
9356
- inp.removeListener("data", onData);
9357
- const listenerIdx = this.activeListeners.findIndex((l) => l.handler === onData);
9358
- if (listenerIdx !== -1)
9359
- this.activeListeners.splice(listenerIdx, 1);
9360
- const timerIdx = this.activeTimers.indexOf(timer);
9361
- if (timerIdx !== -1)
9362
- this.activeTimers.splice(timerIdx, 1);
9363
- if (idleTimer) {
9364
- const idleTimerIdx = this.activeTimers.indexOf(idleTimer);
9365
- if (idleTimerIdx !== -1)
9366
- this.activeTimers.splice(idleTimerIdx, 1);
9367
- }
9975
+ if (!updated)
9976
+ return;
9977
+ idleTimer = session.resetTimer(idleTimer, finish, 150);
9368
9978
  };
9369
- const timer = setTimeout(onTimeout, timeoutMs);
9370
- this.activeTimers.push(timer);
9371
- inp.on("data", onData);
9372
- this.activeListeners.push({ event: "data", handler: onData });
9979
+ session.setTimer(finish, timeoutMs);
9980
+ session.subscribeInput(onData);
9373
9981
  this.writeOsc([
9374
9982
  "\x1B]10;?\x07",
9375
9983
  "\x1B]11;?\x07",
@@ -9419,8 +10027,8 @@ class TerminalPalette {
9419
10027
  };
9420
10028
  }
9421
10029
  }
9422
- function createTerminalPalette(stdin, stdout, writeFn, isLegacyTmux) {
9423
- return new TerminalPalette(stdin, stdout, writeFn, isLegacyTmux);
10030
+ function createTerminalPalette(stdin, stdout, writeFn, isLegacyTmux, oscSource) {
10031
+ return new TerminalPalette(stdin, stdout, writeFn, isLegacyTmux, oscSource);
9424
10032
  }
9425
10033
 
9426
10034
  // src/lib/detect-links.ts
@@ -9466,8 +10074,8 @@ function detectLinks(chunks, context) {
9466
10074
  }
9467
10075
  // src/zig.ts
9468
10076
  import { dlopen, toArrayBuffer as toArrayBuffer4, JSCallback, ptr as ptr4 } from "bun:ffi";
9469
- import { existsSync as existsSync2 } from "fs";
9470
- import { EventEmitter as EventEmitter5 } from "events";
10077
+ import { existsSync as existsSync2, writeFileSync } from "fs";
10078
+ import { EventEmitter as EventEmitter4 } from "events";
9471
10079
 
9472
10080
  // src/buffer.ts
9473
10081
  import { toArrayBuffer, ptr } from "bun:ffi";
@@ -10459,19 +11067,19 @@ var EncodedCharStruct = defineStruct([
10459
11067
  ["char", "u32"]
10460
11068
  ]);
10461
11069
  var LineInfoStruct = defineStruct([
10462
- ["starts", ["u32"]],
10463
- ["startsLen", "u32", { lengthOf: "starts" }],
10464
- ["widths", ["u32"]],
10465
- ["widthsLen", "u32", { lengthOf: "widths" }],
11070
+ ["startCols", ["u32"]],
11071
+ ["startColsLen", "u32", { lengthOf: "startCols" }],
11072
+ ["widthCols", ["u32"]],
11073
+ ["widthColsLen", "u32", { lengthOf: "widthCols" }],
10466
11074
  ["sources", ["u32"]],
10467
11075
  ["sourcesLen", "u32", { lengthOf: "sources" }],
10468
11076
  ["wraps", ["u32"]],
10469
11077
  ["wrapsLen", "u32", { lengthOf: "wraps" }],
10470
- ["maxWidth", "u32"]
11078
+ ["widthColsMax", "u32"]
10471
11079
  ]);
10472
11080
  var MeasureResultStruct = defineStruct([
10473
11081
  ["lineCount", "u32"],
10474
- ["maxWidth", "u32"]
11082
+ ["widthColsMax", "u32"]
10475
11083
  ]);
10476
11084
  var CursorStateStruct = defineStruct([
10477
11085
  ["x", "u32"],
@@ -10598,11 +11206,11 @@ registerEnvVar({
10598
11206
  type: "boolean",
10599
11207
  default: false
10600
11208
  });
10601
- var CURSOR_STYLE_TO_ID = { block: 0, line: 1, underline: 2 };
10602
- 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"];
10603
11211
  var MOUSE_STYLE_TO_ID = { default: 0, pointer: 1, text: 2, crosshair: 3, move: 4, "not-allowed": 5 };
10604
11212
  var globalTraceSymbols = null;
10605
- var globalFFILogWriter = null;
11213
+ var globalFFILogPath = null;
10606
11214
  var exitHandlerRegistered = false;
10607
11215
  function toPointer(value) {
10608
11216
  if (typeof value === "bigint") {
@@ -11591,24 +12199,21 @@ function convertToDebugSymbols(symbols) {
11591
12199
  if (!globalTraceSymbols) {
11592
12200
  globalTraceSymbols = {};
11593
12201
  }
11594
- if (env.OTUI_DEBUG_FFI && !globalFFILogWriter) {
12202
+ if (env.OTUI_DEBUG_FFI && !globalFFILogPath) {
11595
12203
  const now = new Date;
11596
12204
  const timestamp = now.toISOString().replace(/[:.]/g, "-").replace(/T/, "_").split("Z")[0];
11597
- const logFilePath = `ffi_otui_debug_${timestamp}.log`;
11598
- globalFFILogWriter = Bun.file(logFilePath).writer();
12205
+ globalFFILogPath = `ffi_otui_debug_${timestamp}.log`;
11599
12206
  }
11600
12207
  const debugSymbols = {};
11601
12208
  let hasTracing = false;
11602
12209
  Object.entries(symbols).forEach(([key, value]) => {
11603
12210
  debugSymbols[key] = value;
11604
12211
  });
11605
- if (env.OTUI_DEBUG_FFI && globalFFILogWriter) {
11606
- const writer = globalFFILogWriter;
12212
+ if (env.OTUI_DEBUG_FFI && globalFFILogPath) {
12213
+ const logPath = globalFFILogPath;
11607
12214
  const writeSync = (msg) => {
11608
- const buffer = new TextEncoder().encode(msg + `
11609
- `);
11610
- writer.write(buffer);
11611
- writer.flush();
12215
+ writeFileSync(logPath, msg + `
12216
+ `, { flag: "a" });
11612
12217
  };
11613
12218
  Object.entries(symbols).forEach(([key, value]) => {
11614
12219
  if (typeof value === "function") {
@@ -11642,11 +12247,6 @@ function convertToDebugSymbols(symbols) {
11642
12247
  if ((env.OTUI_DEBUG_FFI || env.OTUI_TRACE_FFI) && !exitHandlerRegistered) {
11643
12248
  exitHandlerRegistered = true;
11644
12249
  process.on("exit", () => {
11645
- try {
11646
- if (globalFFILogWriter) {
11647
- globalFFILogWriter.end();
11648
- }
11649
- } catch (e) {}
11650
12250
  if (globalTraceSymbols) {
11651
12251
  const allStats = [];
11652
12252
  for (const [key, timings] of Object.entries(globalTraceSymbols)) {
@@ -11699,15 +12299,15 @@ function convertToDebugSymbols(symbols) {
11699
12299
  const countWidth = Math.max(callsHeader.length, ...allStats.map((s) => String(s.count).length));
11700
12300
  const totalWidth = Math.max(totalHeader.length, ...allStats.map((s) => s.total.toFixed(2).length));
11701
12301
  const avgWidth = Math.max(avgHeader.length, ...allStats.map((s) => s.average.toFixed(2).length));
11702
- const minWidth = Math.max(minHeader.length, ...allStats.map((s) => s.min.toFixed(2).length));
11703
- 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));
11704
12304
  const medianWidth = Math.max(medHeader.length, ...allStats.map((s) => s.median.toFixed(2).length));
11705
12305
  const p90Width = Math.max(p90Header.length, ...allStats.map((s) => s.p90.toFixed(2).length));
11706
12306
  const p99Width = Math.max(p99Header.length, ...allStats.map((s) => s.p99.toFixed(2).length));
11707
- 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)}`);
11708
- 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)}`);
11709
12309
  allStats.forEach((stat) => {
11710
- 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)}`);
11711
12311
  });
11712
12312
  }
11713
12313
  lines.push("-------------------------------------------------------------------------------------------------------------------------");
@@ -11741,7 +12341,7 @@ class FFIRenderLib {
11741
12341
  decoder = new TextDecoder;
11742
12342
  logCallbackWrapper;
11743
12343
  eventCallbackWrapper;
11744
- _nativeEvents = new EventEmitter5;
12344
+ _nativeEvents = new EventEmitter4;
11745
12345
  _anyEventHandlers = [];
11746
12346
  nativeSpanFeedCallbackWrapper = null;
11747
12347
  nativeSpanFeedHandlers = new Map;
@@ -12347,10 +12947,13 @@ class FFIRenderLib {
12347
12947
  const outBuffer = new ArrayBuffer(LineInfoStruct.size);
12348
12948
  this.textBufferViewGetLineInfoDirect(view, ptr4(outBuffer));
12349
12949
  const struct = LineInfoStruct.unpack(outBuffer);
12950
+ const lineStartCols = struct.startCols;
12951
+ const lineWidthCols = struct.widthCols;
12952
+ const lineWidthColsMax = struct.widthColsMax;
12350
12953
  return {
12351
- maxLineWidth: struct.maxWidth,
12352
- lineStarts: struct.starts,
12353
- lineWidths: struct.widths,
12954
+ lineStartCols,
12955
+ lineWidthCols,
12956
+ lineWidthColsMax,
12354
12957
  lineSources: struct.sources,
12355
12958
  lineWraps: struct.wraps
12356
12959
  };
@@ -12359,10 +12962,13 @@ class FFIRenderLib {
12359
12962
  const outBuffer = new ArrayBuffer(LineInfoStruct.size);
12360
12963
  this.textBufferViewGetLogicalLineInfoDirect(view, ptr4(outBuffer));
12361
12964
  const struct = LineInfoStruct.unpack(outBuffer);
12965
+ const lineStartCols = struct.startCols;
12966
+ const lineWidthCols = struct.widthCols;
12967
+ const lineWidthColsMax = struct.widthColsMax;
12362
12968
  return {
12363
- maxLineWidth: struct.maxWidth,
12364
- lineStarts: struct.starts,
12365
- lineWidths: struct.widths,
12969
+ lineStartCols,
12970
+ lineWidthCols,
12971
+ lineWidthColsMax,
12366
12972
  lineSources: struct.sources,
12367
12973
  lineWraps: struct.wraps
12368
12974
  };
@@ -12538,10 +13144,13 @@ class FFIRenderLib {
12538
13144
  const outBuffer = new ArrayBuffer(LineInfoStruct.size);
12539
13145
  this.opentui.symbols.editorViewGetLineInfoDirect(view, ptr4(outBuffer));
12540
13146
  const struct = LineInfoStruct.unpack(outBuffer);
13147
+ const lineStartCols = struct.startCols;
13148
+ const lineWidthCols = struct.widthCols;
13149
+ const lineWidthColsMax = struct.widthColsMax;
12541
13150
  return {
12542
- maxLineWidth: struct.maxWidth,
12543
- lineStarts: struct.starts,
12544
- lineWidths: struct.widths,
13151
+ lineStartCols,
13152
+ lineWidthCols,
13153
+ lineWidthColsMax,
12545
13154
  lineSources: struct.sources,
12546
13155
  lineWraps: struct.wraps
12547
13156
  };
@@ -12550,10 +13159,13 @@ class FFIRenderLib {
12550
13159
  const outBuffer = new ArrayBuffer(LineInfoStruct.size);
12551
13160
  this.opentui.symbols.editorViewGetLogicalLineInfoDirect(view, ptr4(outBuffer));
12552
13161
  const struct = LineInfoStruct.unpack(outBuffer);
13162
+ const lineStartCols = struct.startCols;
13163
+ const lineWidthCols = struct.widthCols;
13164
+ const lineWidthColsMax = struct.widthColsMax;
12553
13165
  return {
12554
- maxLineWidth: struct.maxWidth,
12555
- lineStarts: struct.starts,
12556
- lineWidths: struct.widths,
13166
+ lineStartCols,
13167
+ lineWidthCols,
13168
+ lineWidthColsMax,
12557
13169
  lineSources: struct.sources,
12558
13170
  lineWraps: struct.wraps
12559
13171
  };
@@ -13236,7 +13848,7 @@ class TextBuffer {
13236
13848
  }
13237
13849
 
13238
13850
  // src/Renderable.ts
13239
- import { EventEmitter as EventEmitter6 } from "events";
13851
+ import { EventEmitter as EventEmitter5 } from "events";
13240
13852
 
13241
13853
  // src/lib/renderable.validations.ts
13242
13854
  function validateOptions(id, options) {
@@ -13329,7 +13941,7 @@ function isRenderable(obj) {
13329
13941
  return !!obj?.[BrandedRenderable];
13330
13942
  }
13331
13943
 
13332
- class BaseRenderable extends EventEmitter6 {
13944
+ class BaseRenderable extends EventEmitter5 {
13333
13945
  [BrandedRenderable] = true;
13334
13946
  static renderableNumber = 1;
13335
13947
  _id;
@@ -14711,7 +15323,7 @@ function delegate(mapping, vnode) {
14711
15323
  }
14712
15324
 
14713
15325
  // src/console.ts
14714
- import { EventEmitter as EventEmitter8 } from "events";
15326
+ import { EventEmitter as EventEmitter7 } from "events";
14715
15327
  import { Console } from "console";
14716
15328
  import fs from "fs";
14717
15329
  import path4 from "path";
@@ -14719,9 +15331,9 @@ import util2 from "util";
14719
15331
 
14720
15332
  // src/lib/output.capture.ts
14721
15333
  import { Writable } from "stream";
14722
- import { EventEmitter as EventEmitter7 } from "events";
15334
+ import { EventEmitter as EventEmitter6 } from "events";
14723
15335
 
14724
- class Capture extends EventEmitter7 {
15336
+ class Capture extends EventEmitter6 {
14725
15337
  output = [];
14726
15338
  constructor() {
14727
15339
  super();
@@ -14850,7 +15462,7 @@ registerEnvVar({
14850
15462
  default: false
14851
15463
  });
14852
15464
 
14853
- class TerminalConsoleCache extends EventEmitter8 {
15465
+ class TerminalConsoleCache extends EventEmitter7 {
14854
15466
  _cachedLogs = [];
14855
15467
  MAX_CACHE_SIZE = 1000;
14856
15468
  _collectCallerInfo = false;
@@ -14994,7 +15606,7 @@ var DEFAULT_CONSOLE_OPTIONS = {
14994
15606
  };
14995
15607
  var INDENT_WIDTH = 2;
14996
15608
 
14997
- class TerminalConsole extends EventEmitter8 {
15609
+ class TerminalConsole extends EventEmitter7 {
14998
15610
  isVisible = false;
14999
15611
  isFocused = false;
15000
15612
  renderer;
@@ -15837,7 +16449,7 @@ class Clipboard {
15837
16449
  }
15838
16450
 
15839
16451
  // src/renderer.ts
15840
- import { EventEmitter as EventEmitter9 } from "events";
16452
+ import { EventEmitter as EventEmitter8 } from "events";
15841
16453
 
15842
16454
  // src/lib/objects-in-viewport.ts
15843
16455
  function getObjectsInViewport(viewport, objects, direction = "column", padding = 10, minTriggerSize = 16) {
@@ -16032,6 +16644,7 @@ var KITTY_FLAG_EVENT_TYPES = 2;
16032
16644
  var KITTY_FLAG_ALTERNATE_KEYS = 4;
16033
16645
  var KITTY_FLAG_ALL_KEYS_AS_ESCAPES = 8;
16034
16646
  var KITTY_FLAG_REPORT_TEXT = 16;
16647
+ var DEFAULT_STDIN_PARSER_MAX_BUFFER_BYTES = 64 * 1024 * 1024;
16035
16648
  function buildKittyKeyboardFlags(config) {
16036
16649
  if (!config) {
16037
16650
  return 0;
@@ -16165,7 +16778,7 @@ var RendererControlState;
16165
16778
  RendererControlState2["EXPLICIT_STOPPED"] = "explicit_stopped";
16166
16779
  })(RendererControlState ||= {});
16167
16780
 
16168
- class CliRenderer extends EventEmitter9 {
16781
+ class CliRenderer extends EventEmitter8 {
16169
16782
  static animationFrameId = 0;
16170
16783
  lib;
16171
16784
  rendererPtr;
@@ -16227,7 +16840,9 @@ class CliRenderer extends EventEmitter9 {
16227
16840
  _console;
16228
16841
  _resolution = null;
16229
16842
  _keyHandler;
16230
- _stdinBuffer;
16843
+ stdinParser = null;
16844
+ oscSubscribers = new Set;
16845
+ hasLoggedStdinParserError = false;
16231
16846
  animationRequest = new Map;
16232
16847
  resizeTimeoutId = null;
16233
16848
  capabilityTimeoutId = null;
@@ -16256,7 +16871,6 @@ class CliRenderer extends EventEmitter9 {
16256
16871
  }
16257
16872
  };
16258
16873
  _useConsole = true;
16259
- mouseParser = new MouseParser;
16260
16874
  sigwinchHandler = (() => {
16261
16875
  const width = this.stdout.columns || 80;
16262
16876
  const height = this.stdout.rows || 24;
@@ -16275,8 +16889,9 @@ class CliRenderer extends EventEmitter9 {
16275
16889
  _paletteDetectionPromise = null;
16276
16890
  _onDestroy;
16277
16891
  _themeMode = null;
16278
- inputHandlers = [];
16892
+ sequenceHandlers = [];
16279
16893
  prependedInputHandlers = [];
16894
+ shouldRestoreModesOnNextFocus = false;
16280
16895
  idleResolvers = [];
16281
16896
  _debugInputs = [];
16282
16897
  _debugModeEnabled = env.OTUI_DEBUG;
@@ -16391,7 +17006,7 @@ Captured output:
16391
17006
  process.on("beforeExit", this.exitHandler);
16392
17007
  const kittyConfig = config.useKittyKeyboard ?? {};
16393
17008
  const useKittyForParsing = kittyConfig !== null;
16394
- this._keyHandler = new InternalKeyHandler(useKittyForParsing);
17009
+ this._keyHandler = new InternalKeyHandler;
16395
17010
  this._keyHandler.on("keypress", (event) => {
16396
17011
  if (this.exitOnCtrlC && event.name === "c" && event.ctrl) {
16397
17012
  process.nextTick(() => {
@@ -16401,7 +17016,17 @@ Captured output:
16401
17016
  }
16402
17017
  });
16403
17018
  this.addExitListeners();
16404
- 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
+ });
16405
17030
  this._console = new TerminalConsole(this, config.consoleOptions);
16406
17031
  this.useConsole = config.useConsole ?? true;
16407
17032
  this._openConsoleOnError = config.openConsoleOnError ?? true;
@@ -16709,7 +17334,7 @@ Captured output:
16709
17334
  disableMouse() {
16710
17335
  this._useMouse = false;
16711
17336
  this.setCapturedRenderable(undefined);
16712
- this.mouseParser.reset();
17337
+ this.stdinParser?.resetMouseState();
16713
17338
  this.lib.disableMouse(this.rendererPtr);
16714
17339
  }
16715
17340
  enableKittyKeyboard(flags = 3) {
@@ -16745,20 +17370,31 @@ Captured output:
16745
17370
  }
16746
17371
  this.queryPixelResolution();
16747
17372
  }
16748
- stdinListener = ((data) => {
16749
- if (this._useMouse && this.handleMouseData(data)) {
17373
+ stdinListener = ((chunk) => {
17374
+ const data = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
17375
+ if (!this.stdinParser)
16750
17376
  return;
17377
+ try {
17378
+ this.stdinParser.push(data);
17379
+ this.drainStdinParser();
17380
+ } catch (error) {
17381
+ this.handleStdinParserFailure(error);
16751
17382
  }
16752
- this._stdinBuffer.process(data);
16753
17383
  }).bind(this);
16754
17384
  addInputHandler(handler) {
16755
- this.inputHandlers.push(handler);
17385
+ this.sequenceHandlers.push(handler);
16756
17386
  }
16757
17387
  prependInputHandler(handler) {
16758
- this.inputHandlers.unshift(handler);
17388
+ this.sequenceHandlers.unshift(handler);
16759
17389
  }
16760
17390
  removeInputHandler(handler) {
16761
- 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
+ };
16762
17398
  }
16763
17399
  capabilityHandler = ((sequence) => {
16764
17400
  if (isCapabilityResponse(sequence)) {
@@ -16771,11 +17407,15 @@ Captured output:
16771
17407
  }).bind(this);
16772
17408
  focusHandler = ((sequence) => {
16773
17409
  if (sequence === "\x1B[I") {
16774
- this.lib.restoreTerminalModes(this.rendererPtr);
17410
+ if (this.shouldRestoreModesOnNextFocus) {
17411
+ this.lib.restoreTerminalModes(this.rendererPtr);
17412
+ this.shouldRestoreModesOnNextFocus = false;
17413
+ }
16775
17414
  this.emit("focus");
16776
17415
  return true;
16777
17416
  }
16778
17417
  if (sequence === "\x1B[O") {
17418
+ this.shouldRestoreModesOnNextFocus = true;
16779
17419
  this.emit("blur");
16780
17420
  return true;
16781
17421
  }
@@ -16798,6 +17438,67 @@ Captured output:
16798
17438
  }
16799
17439
  return false;
16800
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
+ }
16801
17502
  setupInput() {
16802
17503
  for (const handler of this.prependedInputHandlers) {
16803
17504
  this.addInputHandler(handler);
@@ -16816,31 +17517,11 @@ Captured output:
16816
17517
  this.addInputHandler(this.capabilityHandler);
16817
17518
  this.addInputHandler(this.focusHandler);
16818
17519
  this.addInputHandler(this.themeModeHandler);
16819
- this.addInputHandler((sequence) => {
16820
- return this._keyHandler.processInput(sequence);
16821
- });
16822
17520
  if (this.stdin.setRawMode) {
16823
17521
  this.stdin.setRawMode(true);
16824
17522
  }
16825
17523
  this.stdin.resume();
16826
- this.stdin.setEncoding("utf8");
16827
17524
  this.stdin.on("data", this.stdinListener);
16828
- this._stdinBuffer.on("data", (sequence) => {
16829
- if (this._debugModeEnabled) {
16830
- this._debugInputs.push({
16831
- timestamp: new Date().toISOString(),
16832
- sequence
16833
- });
16834
- }
16835
- for (const handler of this.inputHandlers) {
16836
- if (handler(sequence)) {
16837
- return;
16838
- }
16839
- }
16840
- });
16841
- this._stdinBuffer.on("paste", (data) => {
16842
- this._keyHandler.processPaste(data);
16843
- });
16844
17525
  }
16845
17526
  dispatchMouseEvent(target, attributes) {
16846
17527
  const event = new MouseEvent(target, attributes);
@@ -16857,18 +17538,6 @@ Captured output:
16857
17538
  }
16858
17539
  return event;
16859
17540
  }
16860
- handleMouseData(data) {
16861
- const mouseEvents = this.mouseParser.parseAllMouseEvents(data);
16862
- if (mouseEvents.length === 0)
16863
- return false;
16864
- let anyHandled = false;
16865
- for (const mouseEvent of mouseEvents) {
16866
- if (this.processSingleMouseEvent(mouseEvent)) {
16867
- anyHandled = true;
16868
- }
16869
- }
16870
- return anyHandled;
16871
- }
16872
17541
  processSingleMouseEvent(mouseEvent) {
16873
17542
  if (this._splitHeight > 0) {
16874
17543
  if (mouseEvent.y < this.renderOffset) {
@@ -17090,7 +17759,7 @@ Captured output:
17090
17759
  this._terminalHeight = height;
17091
17760
  this.queryPixelResolution();
17092
17761
  this.setCapturedRenderable(undefined);
17093
- this.mouseParser.reset();
17762
+ this.stdinParser?.resetMouseState();
17094
17763
  if (this._splitHeight > 0) {
17095
17764
  if (width < prevWidth) {
17096
17765
  const start = this._terminalHeight - this._splitHeight * 2;
@@ -17253,7 +17922,7 @@ Captured output:
17253
17922
  this._suspendedMouseEnabled = this._useMouse;
17254
17923
  this.disableMouse();
17255
17924
  this.removeExitListeners();
17256
- this._stdinBuffer.clear();
17925
+ this.stdinParser?.reset();
17257
17926
  this.stdin.removeListener("data", this.stdinListener);
17258
17927
  this.lib.suspendRenderer(this.rendererPtr);
17259
17928
  if (this.stdin.setRawMode) {
@@ -17365,16 +18034,18 @@ Captured output:
17365
18034
  } catch (e) {
17366
18035
  console.error("Error destroying root renderable:", e instanceof Error ? e.stack : String(e));
17367
18036
  }
17368
- 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();
17369
18044
  this._console.destroy();
17370
18045
  this.disableStdoutInterception();
17371
18046
  if (this._splitHeight > 0) {
17372
18047
  this.flushStdoutCache(this._splitHeight, true);
17373
18048
  }
17374
- if (this.stdin.setRawMode) {
17375
- this.stdin.setRawMode(false);
17376
- }
17377
- this.stdin.removeListener("data", this.stdinListener);
17378
18049
  this.lib.destroyRenderer(this.rendererPtr);
17379
18050
  rendererTracker.removeRenderer(this);
17380
18051
  if (this._onDestroy) {
@@ -17656,7 +18327,9 @@ Captured output:
17656
18327
  }
17657
18328
  if (!this._paletteDetector) {
17658
18329
  const isLegacyTmux = this.capabilities?.terminal?.name?.toLowerCase()?.includes("tmux") && this.capabilities?.terminal?.version?.localeCompare("3.6") < 0;
17659
- 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
+ });
17660
18333
  }
17661
18334
  this._paletteDetectionPromise = this._paletteDetector.detect(options).then((result) => {
17662
18335
  this._cachedPalette = result;
@@ -17667,7 +18340,7 @@ Captured output:
17667
18340
  }
17668
18341
  }
17669
18342
 
17670
- 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 };
17671
18344
 
17672
- //# debugId=DA268A08ACDF5B0364756E2164756E21
17673
- //# sourceMappingURL=index-2yz42vd4.js.map
18345
+ //# debugId=EFEF7A9F3BA3925B64756E2164756E21
18346
+ //# sourceMappingURL=index-0wbvecnk.js.map