@alchemy.run/sigil 0.0.0-alpha.3 → 0.0.0-alpha.5

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.
Files changed (207) hide show
  1. package/README.md +23 -13
  2. package/THIRD_PARTY_NOTICES.md +70 -23
  3. package/dist/Text-D5HUf3Fj.d.ts +452 -0
  4. package/dist/ansi.d.ts +137 -143
  5. package/dist/ansi.js +87 -2
  6. package/dist/capabilities.d.ts +5 -0
  7. package/dist/capabilities.js +3 -0
  8. package/dist/cell-_ZVhbfl0.js +44 -0
  9. package/dist/color-CkbalRqK.js +2 -0
  10. package/dist/color-policy-BMzMwV7Q.d.ts +22 -0
  11. package/dist/color-policy-SVj1pYTA.js +560 -0
  12. package/dist/color-profile-DHhQHY55.js +36 -0
  13. package/dist/color-profile-u0Nhe9Nv.d.ts +97 -0
  14. package/dist/color.d.ts +21 -0
  15. package/dist/color.js +3 -0
  16. package/dist/cursor-position-D2LAkRG0.d.ts +7 -0
  17. package/dist/detect-Bh4yGP6w.d.ts +186 -0
  18. package/dist/detect-BuTXtY6e.js +373 -0
  19. package/dist/{devtools-BhYGjb7h.js → devtools-DbthxoD1.js} +22 -23
  20. package/dist/env-YVw64yZS.js +9 -0
  21. package/dist/escapes-CB_6CWOE.d.ts +72 -0
  22. package/dist/geometry-BxXOzJgo.d.ts +11 -0
  23. package/dist/index-Bmc2tRPk.d.ts +21 -0
  24. package/dist/index.d.ts +235 -754
  25. package/dist/index.js +1362 -3001
  26. package/dist/osc-CCH7xDoS.js +71 -0
  27. package/dist/osc-Cn0fw77g.d.ts +23 -0
  28. package/dist/paint-C19minOS.d.ts +81 -0
  29. package/dist/query-vaIeGOkH.d.ts +152 -0
  30. package/dist/router.d.ts +392 -0
  31. package/dist/router.js +709 -0
  32. package/dist/sample-Cqw1bjUL.js +445 -0
  33. package/dist/screen-BOh__-65.js +324 -0
  34. package/dist/screen-BReKIheE.d.ts +40 -0
  35. package/dist/screen.d.ts +5 -0
  36. package/dist/screen.js +5 -0
  37. package/dist/semantic-text-style-DIMzC7xt.js +91 -0
  38. package/dist/serialize-BTkAZgw1.js +79 -0
  39. package/dist/session-BJmzX2NJ.js +664 -0
  40. package/dist/sgr-BhwaWAJB.js +246 -0
  41. package/dist/store-CgrG9K4y.d.ts +72 -0
  42. package/dist/string-width-CijQwpIk.js +69 -0
  43. package/dist/strip-BvU4toXG.js +6 -0
  44. package/dist/terminal.d.ts +118 -0
  45. package/dist/terminal.js +2 -0
  46. package/dist/tokenize-AjqbvtiT.js +1242 -0
  47. package/dist/tokenize-Dx1y_l5H.d.ts +57 -0
  48. package/dist/truncate-D31fhU6i.js +562 -0
  49. package/dist/use-focus-C2sciZOo.js +1335 -0
  50. package/package.json +43 -17
  51. package/src/ansi/chalk.ts +12 -53
  52. package/src/ansi/cursor.ts +2 -4
  53. package/src/ansi/east-asian-width.ts +44 -0
  54. package/src/ansi/escapes.ts +18 -26
  55. package/src/ansi/graphemes.ts +8 -0
  56. package/src/ansi/hyperlink.ts +44 -0
  57. package/src/ansi/index.ts +14 -14
  58. package/src/ansi/osc.ts +77 -0
  59. package/src/ansi/sgr.ts +2 -5
  60. package/src/ansi/slice.ts +1 -1
  61. package/src/ansi/string-width.ts +91 -206
  62. package/src/ansi/strip.ts +13 -33
  63. package/src/ansi/tokenize.ts +96 -169
  64. package/src/ansi/truncate.ts +5 -3
  65. package/src/ansi/wrap.ts +13 -14
  66. package/src/ansi-tokenizer.ts +1 -1
  67. package/src/capabilities/color-policy.ts +34 -0
  68. package/src/capabilities/detect.ts +594 -0
  69. package/src/capabilities/index.ts +37 -0
  70. package/src/capabilities/query.ts +657 -0
  71. package/src/capabilities/store.ts +379 -0
  72. package/src/color/index.ts +3 -0
  73. package/src/color/paint.ts +169 -0
  74. package/src/color/palette.ts +48 -0
  75. package/src/color/sample.ts +323 -0
  76. package/src/color.ts +1 -0
  77. package/src/components/AnsiText.tsx +42 -0
  78. package/src/components/App.tsx +109 -22
  79. package/src/components/BackgroundContext.ts +2 -3
  80. package/src/components/Box.tsx +43 -60
  81. package/src/components/CursorContext.ts +1 -1
  82. package/src/components/ErrorBoundary.tsx +1 -1
  83. package/src/components/ErrorOverview.tsx +8 -7
  84. package/src/components/Hyperlink.tsx +56 -0
  85. package/src/components/Spacer.tsx +1 -1
  86. package/src/components/Static.tsx +1 -1
  87. package/src/components/StderrContext.ts +0 -2
  88. package/src/components/StdinContext.ts +0 -1
  89. package/src/components/StdoutContext.ts +1 -3
  90. package/src/components/TerminalOscContext.ts +25 -0
  91. package/src/components/Text.tsx +23 -46
  92. package/src/components/Transform.tsx +2 -2
  93. package/src/cursor-position.ts +1 -1
  94. package/src/devtools.ts +84 -24
  95. package/src/dom.ts +11 -8
  96. package/src/env.ts +12 -0
  97. package/src/get-max-width.ts +1 -1
  98. package/src/global.d.ts +6 -4
  99. package/src/{boxes.ts → glyphs.ts} +17 -18
  100. package/src/hooks/use-animation.ts +1 -1
  101. package/src/hooks/use-app.ts +1 -1
  102. package/src/hooks/use-box-metrics.ts +1 -1
  103. package/src/hooks/use-capabilities.ts +73 -0
  104. package/src/hooks/use-cursor.ts +3 -3
  105. package/src/hooks/use-focus-manager.ts +1 -1
  106. package/src/hooks/use-focus.ts +5 -6
  107. package/src/hooks/use-input.ts +4 -4
  108. package/src/hooks/use-is-screen-reader-enabled.ts +1 -1
  109. package/src/hooks/use-paste.ts +2 -2
  110. package/src/hooks/use-stderr.ts +1 -1
  111. package/src/hooks/use-stdin.ts +1 -1
  112. package/src/hooks/use-stdout.ts +1 -1
  113. package/src/hooks/use-terminal-osc.ts +59 -0
  114. package/src/hooks/use-window-size.ts +2 -2
  115. package/src/index.ts +88 -44
  116. package/src/ink.tsx +620 -745
  117. package/src/input-parser.ts +1 -1
  118. package/src/instances.ts +1 -1
  119. package/src/kitty-keyboard.ts +128 -0
  120. package/src/measure-element.ts +1 -1
  121. package/src/measure-text.ts +2 -2
  122. package/src/{render-node-to-output.ts → paint-tree.ts} +78 -53
  123. package/src/parse-keypress.ts +4 -5
  124. package/src/parse-stack-line.ts +0 -1
  125. package/src/patch-console.ts +44 -0
  126. package/src/reconciler.ts +36 -62
  127. package/src/render-background.ts +37 -16
  128. package/src/render-border.ts +97 -64
  129. package/src/render-frame.ts +83 -0
  130. package/src/render-to-string.ts +24 -9
  131. package/src/render.ts +24 -16
  132. package/src/router/components.tsx +343 -0
  133. package/src/router/context.ts +41 -0
  134. package/src/router/history.ts +194 -0
  135. package/src/router/hooks.tsx +391 -0
  136. package/src/router/index.ts +34 -0
  137. package/src/router/matcher.ts +571 -0
  138. package/src/sanitize-ansi.ts +1 -1
  139. package/src/screen/ansi.ts +184 -0
  140. package/src/screen/canvas.ts +137 -0
  141. package/src/screen/cell.ts +138 -0
  142. package/src/screen/color-profile.ts +47 -0
  143. package/src/screen/geometry.ts +9 -0
  144. package/src/screen/index.ts +6 -0
  145. package/src/screen/screen.ts +272 -0
  146. package/src/screen/serialize.ts +129 -0
  147. package/src/screen.ts +1 -0
  148. package/src/semantic-text-style.ts +118 -0
  149. package/src/signal-exit.ts +4 -5
  150. package/src/squash-text-nodes.ts +4 -7
  151. package/src/stream.ts +2 -4
  152. package/src/structured-text.ts +321 -0
  153. package/src/styles.ts +16 -17
  154. package/src/terminal/index.ts +2 -0
  155. package/src/terminal/inline-presenter.ts +120 -0
  156. package/src/terminal/input.ts +86 -0
  157. package/src/terminal/render-scheduler.ts +37 -0
  158. package/src/terminal/screen-presenter.ts +188 -0
  159. package/src/terminal/session.ts +407 -0
  160. package/src/terminal-size.ts +9 -8
  161. package/src/terminal.ts +1 -0
  162. package/src/testing/browser.ts +588 -0
  163. package/src/testing/emulators.ts +205 -0
  164. package/src/testing/explorer-app/index.html +12 -0
  165. package/src/testing/explorer-app/main.ts +381 -0
  166. package/src/testing/explorer-app/style.css +194 -0
  167. package/src/testing/explorer-app/tsconfig.json +15 -0
  168. package/src/testing/explorer-app/vite-env.d.ts +1 -0
  169. package/src/testing/index.ts +26 -0
  170. package/src/testing/keys.ts +56 -0
  171. package/src/testing/live.ts +85 -0
  172. package/src/testing/matchers.ts +70 -0
  173. package/src/testing/public.ts +94 -0
  174. package/src/testing/terminal.ts +349 -0
  175. package/src/testing/vitest.ts +157 -0
  176. package/src/transform-adapter.ts +14 -0
  177. package/src/types.ts +1 -6
  178. package/src/utils.ts +2 -2
  179. package/src/wrap-text.ts +4 -4
  180. package/src/yoga/config.ts +2 -2
  181. package/src/yoga/core/absoluteLayout.ts +15 -15
  182. package/src/yoga/core/baseline.ts +3 -3
  183. package/src/yoga/core/cache.ts +4 -4
  184. package/src/yoga/core/calculateLayout.ts +33 -27
  185. package/src/yoga/core/config.ts +1 -1
  186. package/src/yoga/core/flexLine.ts +3 -3
  187. package/src/yoga/core/helpers.ts +3 -3
  188. package/src/yoga/core/layoutResults.ts +4 -4
  189. package/src/yoga/core/node.ts +16 -16
  190. package/src/yoga/core/pixelGrid.ts +4 -4
  191. package/src/yoga/core/style.ts +11 -11
  192. package/src/yoga/core/types.ts +2 -2
  193. package/src/yoga/index.ts +6 -6
  194. package/src/yoga/node.ts +8 -8
  195. package/dist/sgr-CMfEpjSk.d.ts +0 -91
  196. package/dist/truncate-CBiyyZzw.js +0 -2156
  197. package/src/ansi/supports-color.ts +0 -213
  198. package/src/ansi/widest-line.ts +0 -12
  199. package/src/auto-bind.ts +0 -41
  200. package/src/colorize.ts +0 -60
  201. package/src/devtools-window-polyfill.ts +0 -73
  202. package/src/indent-string.ts +0 -16
  203. package/src/is-in-ci.ts +0 -7
  204. package/src/log-update.ts +0 -370
  205. package/src/output.ts +0 -308
  206. package/src/renderer.ts +0 -73
  207. package/src/write-synchronized.ts +0 -9
@@ -0,0 +1,1335 @@
1
+ import { U as kittyQuery } from "./sgr-BhwaWAJB.js";
2
+ import { d as tokenize, h as tokenizeAnsi, l as styledCharsFromTokens, m as hasAnsiControlCharacters } from "./tokenize-AjqbvtiT.js";
3
+ import { n as widestLine } from "./string-width-CijQwpIk.js";
4
+ import { r as wrapAnsi, t as cliTruncate } from "./truncate-D31fhU6i.js";
5
+ import { i as isSigilDev } from "./env-YVw64yZS.js";
6
+ import { t as Yoga } from "./yoga-5jKhYCJC.js";
7
+ import { t as cellAttributes } from "./cell-_ZVhbfl0.js";
8
+ import { r as parseSemanticColor } from "./semantic-text-style-DIMzC7xt.js";
9
+ import { createContext, useContext, useEffect, useEffectEvent, useId } from "react";
10
+ import createReconciler from "react-reconciler";
11
+ import { DefaultEventPriority, NoEventPriority } from "react-reconciler/constants.js";
12
+ import { EventEmitter } from "node:events";
13
+ import { jsx } from "react/jsx-runtime";
14
+ import * as Scheduler from "scheduler";
15
+ //#region src/components/AccessibilityContext.ts
16
+ const accessibilityContext = createContext({ isScreenReaderEnabled: false });
17
+ //#endregion
18
+ //#region src/quick-lru.ts
19
+ var QuickLru = class {
20
+ #size = 0;
21
+ #cache = /* @__PURE__ */ new Map();
22
+ #oldCache = /* @__PURE__ */ new Map();
23
+ #maxSize;
24
+ constructor({ maxSize }) {
25
+ if (!(maxSize && maxSize > 0)) throw new TypeError("`maxSize` must be a number greater than 0");
26
+ this.#maxSize = maxSize;
27
+ }
28
+ get size() {
29
+ let oldCacheSize = 0;
30
+ for (const key of this.#oldCache.keys()) if (!this.#cache.has(key)) oldCacheSize++;
31
+ return Math.min(this.#size + oldCacheSize, this.#maxSize);
32
+ }
33
+ get(key) {
34
+ if (this.#cache.has(key)) return this.#cache.get(key);
35
+ if (this.#oldCache.has(key)) {
36
+ const value = this.#oldCache.get(key);
37
+ this.#oldCache.delete(key);
38
+ this.#set(key, value);
39
+ return value;
40
+ }
41
+ }
42
+ set(key, value) {
43
+ if (this.#cache.has(key)) this.#cache.set(key, value);
44
+ else this.#set(key, value);
45
+ return this;
46
+ }
47
+ has(key) {
48
+ return this.#cache.has(key) || this.#oldCache.has(key);
49
+ }
50
+ delete(key) {
51
+ const deleted = this.#cache.delete(key);
52
+ if (deleted) this.#size--;
53
+ return this.#oldCache.delete(key) || deleted;
54
+ }
55
+ clear() {
56
+ this.#cache.clear();
57
+ this.#oldCache.clear();
58
+ this.#size = 0;
59
+ }
60
+ #set(key, value) {
61
+ this.#cache.set(key, value);
62
+ this.#size++;
63
+ if (this.#size >= this.#maxSize) {
64
+ this.#size = 0;
65
+ this.#oldCache = this.#cache;
66
+ this.#cache = /* @__PURE__ */ new Map();
67
+ }
68
+ }
69
+ };
70
+ //#endregion
71
+ //#region src/measure-text.ts
72
+ const cache = new QuickLru({ maxSize: 4096 });
73
+ const measureText = (text) => {
74
+ if (text.length === 0) return {
75
+ width: 0,
76
+ height: 0
77
+ };
78
+ const cachedDimensions = cache.get(text);
79
+ if (cachedDimensions) return cachedDimensions;
80
+ const dimensions = {
81
+ width: widestLine(text),
82
+ height: text.split("\n").length
83
+ };
84
+ cache.set(text, dimensions);
85
+ return dimensions;
86
+ };
87
+ //#endregion
88
+ //#region src/sanitize-ansi.ts
89
+ const sgrParametersRegex = /^[\d:;]*$/;
90
+ const sanitizeAnsi = (text) => {
91
+ if (!hasAnsiControlCharacters(text)) return text;
92
+ let output = "";
93
+ for (const token of tokenizeAnsi(text)) {
94
+ if (token.type === "text" || token.type === "osc") {
95
+ output += token.value;
96
+ continue;
97
+ }
98
+ if (token.type === "csi" && token.finalCharacter === "m" && token.intermediateString === "" && sgrParametersRegex.test(token.parameterString)) output += token.value;
99
+ }
100
+ return output;
101
+ };
102
+ //#endregion
103
+ //#region src/squash-text-nodes.ts
104
+ const squashTextNodes = (node) => {
105
+ let text = "";
106
+ for (let index = 0; index < node.childNodes.length; index++) {
107
+ const childNode = node.childNodes[index];
108
+ if (childNode === void 0) continue;
109
+ let nodeText = "";
110
+ if (childNode.nodeName === "#text") nodeText = childNode.nodeValue;
111
+ else {
112
+ if (childNode.nodeName === "ink-text" || childNode.nodeName === "ink-virtual-text") nodeText = squashTextNodes(childNode);
113
+ if (nodeText.length > 0 && typeof childNode.internal_transform === "function") nodeText = childNode.internal_transform(nodeText, index);
114
+ }
115
+ text += nodeText;
116
+ }
117
+ return sanitizeAnsi(text);
118
+ };
119
+ //#endregion
120
+ //#region src/styles.ts
121
+ const positionEdges = [
122
+ ["top", Yoga.EDGE_TOP],
123
+ ["right", Yoga.EDGE_RIGHT],
124
+ ["bottom", Yoga.EDGE_BOTTOM],
125
+ ["left", Yoga.EDGE_LEFT]
126
+ ];
127
+ const applyPositionStyles = (node, style) => {
128
+ if ("position" in style) {
129
+ let positionType = Yoga.POSITION_TYPE_RELATIVE;
130
+ if (style.position === "absolute") positionType = Yoga.POSITION_TYPE_ABSOLUTE;
131
+ else if (style.position === "static") positionType = Yoga.POSITION_TYPE_STATIC;
132
+ node.setPositionType(positionType);
133
+ }
134
+ for (const [property, edge] of positionEdges) {
135
+ if (!(property in style)) continue;
136
+ const value = style[property];
137
+ if (typeof value === "string") {
138
+ node.setPositionPercent(edge, Number.parseFloat(value));
139
+ continue;
140
+ }
141
+ node.setPosition(edge, value);
142
+ }
143
+ };
144
+ const applyMarginStyles = (node, style) => {
145
+ if ("margin" in style) node.setMargin(Yoga.EDGE_ALL, style.margin ?? 0);
146
+ if ("marginX" in style) node.setMargin(Yoga.EDGE_HORIZONTAL, style.marginX ?? 0);
147
+ if ("marginY" in style) node.setMargin(Yoga.EDGE_VERTICAL, style.marginY ?? 0);
148
+ if ("marginLeft" in style) node.setMargin(Yoga.EDGE_START, style.marginLeft ?? 0);
149
+ if ("marginRight" in style) node.setMargin(Yoga.EDGE_END, style.marginRight ?? 0);
150
+ if ("marginTop" in style) node.setMargin(Yoga.EDGE_TOP, style.marginTop ?? 0);
151
+ if ("marginBottom" in style) node.setMargin(Yoga.EDGE_BOTTOM, style.marginBottom ?? 0);
152
+ };
153
+ const applyPaddingStyles = (node, style) => {
154
+ if ("padding" in style) node.setPadding(Yoga.EDGE_ALL, style.padding ?? 0);
155
+ if ("paddingX" in style) node.setPadding(Yoga.EDGE_HORIZONTAL, style.paddingX ?? 0);
156
+ if ("paddingY" in style) node.setPadding(Yoga.EDGE_VERTICAL, style.paddingY ?? 0);
157
+ if ("paddingLeft" in style) node.setPadding(Yoga.EDGE_LEFT, style.paddingLeft ?? 0);
158
+ if ("paddingRight" in style) node.setPadding(Yoga.EDGE_RIGHT, style.paddingRight ?? 0);
159
+ if ("paddingTop" in style) node.setPadding(Yoga.EDGE_TOP, style.paddingTop ?? 0);
160
+ if ("paddingBottom" in style) node.setPadding(Yoga.EDGE_BOTTOM, style.paddingBottom ?? 0);
161
+ };
162
+ const applyFlexStyles = (node, style) => {
163
+ if ("flexGrow" in style) node.setFlexGrow(style.flexGrow ?? 0);
164
+ if ("flexShrink" in style) node.setFlexShrink(typeof style.flexShrink === "number" ? style.flexShrink : 1);
165
+ if ("flexWrap" in style) {
166
+ if (style.flexWrap === "nowrap") node.setFlexWrap(Yoga.WRAP_NO_WRAP);
167
+ if (style.flexWrap === "wrap") node.setFlexWrap(Yoga.WRAP_WRAP);
168
+ if (style.flexWrap === "wrap-reverse") node.setFlexWrap(Yoga.WRAP_WRAP_REVERSE);
169
+ }
170
+ if ("flexDirection" in style) {
171
+ if (style.flexDirection === "row") node.setFlexDirection(Yoga.FLEX_DIRECTION_ROW);
172
+ if (style.flexDirection === "row-reverse") node.setFlexDirection(Yoga.FLEX_DIRECTION_ROW_REVERSE);
173
+ if (style.flexDirection === "column") node.setFlexDirection(Yoga.FLEX_DIRECTION_COLUMN);
174
+ if (style.flexDirection === "column-reverse") node.setFlexDirection(Yoga.FLEX_DIRECTION_COLUMN_REVERSE);
175
+ }
176
+ if ("flexBasis" in style) {
177
+ if (typeof style.flexBasis === "number") node.setFlexBasis(style.flexBasis);
178
+ else if (typeof style.flexBasis === "string") node.setFlexBasisPercent(Number.parseInt(style.flexBasis, 10));
179
+ else node.setFlexBasisAuto();
180
+ }
181
+ if ("alignItems" in style) {
182
+ if (style.alignItems === "stretch" || !style.alignItems) node.setAlignItems(Yoga.ALIGN_STRETCH);
183
+ if (style.alignItems === "flex-start") node.setAlignItems(Yoga.ALIGN_FLEX_START);
184
+ if (style.alignItems === "center") node.setAlignItems(Yoga.ALIGN_CENTER);
185
+ if (style.alignItems === "flex-end") node.setAlignItems(Yoga.ALIGN_FLEX_END);
186
+ if (style.alignItems === "baseline") node.setAlignItems(Yoga.ALIGN_BASELINE);
187
+ }
188
+ if ("alignSelf" in style) {
189
+ if (style.alignSelf === "auto" || !style.alignSelf) node.setAlignSelf(Yoga.ALIGN_AUTO);
190
+ if (style.alignSelf === "flex-start") node.setAlignSelf(Yoga.ALIGN_FLEX_START);
191
+ if (style.alignSelf === "center") node.setAlignSelf(Yoga.ALIGN_CENTER);
192
+ if (style.alignSelf === "flex-end") node.setAlignSelf(Yoga.ALIGN_FLEX_END);
193
+ if (style.alignSelf === "stretch") node.setAlignSelf(Yoga.ALIGN_STRETCH);
194
+ if (style.alignSelf === "baseline") node.setAlignSelf(Yoga.ALIGN_BASELINE);
195
+ }
196
+ if ("alignContent" in style) {
197
+ if (style.alignContent === "flex-start" || !style.alignContent) node.setAlignContent(Yoga.ALIGN_FLEX_START);
198
+ if (style.alignContent === "center") node.setAlignContent(Yoga.ALIGN_CENTER);
199
+ if (style.alignContent === "flex-end") node.setAlignContent(Yoga.ALIGN_FLEX_END);
200
+ if (style.alignContent === "space-between") node.setAlignContent(Yoga.ALIGN_SPACE_BETWEEN);
201
+ if (style.alignContent === "space-around") node.setAlignContent(Yoga.ALIGN_SPACE_AROUND);
202
+ if (style.alignContent === "space-evenly") node.setAlignContent(Yoga.ALIGN_SPACE_EVENLY);
203
+ if (style.alignContent === "stretch") node.setAlignContent(Yoga.ALIGN_STRETCH);
204
+ }
205
+ if ("justifyContent" in style) {
206
+ if (style.justifyContent === "flex-start" || !style.justifyContent) node.setJustifyContent(Yoga.JUSTIFY_FLEX_START);
207
+ if (style.justifyContent === "center") node.setJustifyContent(Yoga.JUSTIFY_CENTER);
208
+ if (style.justifyContent === "flex-end") node.setJustifyContent(Yoga.JUSTIFY_FLEX_END);
209
+ if (style.justifyContent === "space-between") node.setJustifyContent(Yoga.JUSTIFY_SPACE_BETWEEN);
210
+ if (style.justifyContent === "space-around") node.setJustifyContent(Yoga.JUSTIFY_SPACE_AROUND);
211
+ if (style.justifyContent === "space-evenly") node.setJustifyContent(Yoga.JUSTIFY_SPACE_EVENLY);
212
+ }
213
+ };
214
+ const applyDimensionStyles = (node, style) => {
215
+ if ("width" in style) {
216
+ if (typeof style.width === "number") node.setWidth(style.width);
217
+ else if (typeof style.width === "string") node.setWidthPercent(Number.parseInt(style.width, 10));
218
+ else node.setWidthAuto();
219
+ }
220
+ if ("height" in style) {
221
+ if (typeof style.height === "number") node.setHeight(style.height);
222
+ else if (typeof style.height === "string") node.setHeightPercent(Number.parseInt(style.height, 10));
223
+ else node.setHeightAuto();
224
+ }
225
+ if ("minWidth" in style) {
226
+ if (typeof style.minWidth === "string") node.setMinWidthPercent(Number.parseInt(style.minWidth, 10));
227
+ else node.setMinWidth(style.minWidth ?? 0);
228
+ }
229
+ if ("minHeight" in style) {
230
+ if (typeof style.minHeight === "string") node.setMinHeightPercent(Number.parseInt(style.minHeight, 10));
231
+ else node.setMinHeight(style.minHeight ?? 0);
232
+ }
233
+ if ("maxWidth" in style) {
234
+ if (typeof style.maxWidth === "string") node.setMaxWidthPercent(Number.parseInt(style.maxWidth, 10));
235
+ else node.setMaxWidth(style.maxWidth);
236
+ }
237
+ if ("maxHeight" in style) {
238
+ if (typeof style.maxHeight === "string") node.setMaxHeightPercent(Number.parseInt(style.maxHeight, 10));
239
+ else node.setMaxHeight(style.maxHeight);
240
+ }
241
+ if ("aspectRatio" in style) node.setAspectRatio(style.aspectRatio);
242
+ };
243
+ const applyDisplayStyles = (node, style) => {
244
+ if ("display" in style) node.setDisplay(style.display === "flex" ? Yoga.DISPLAY_FLEX : Yoga.DISPLAY_NONE);
245
+ };
246
+ const applyBorderStyles = (node, style, currentStyle) => {
247
+ if (!("borderStyle" in style || "borderTop" in style || "borderBottom" in style || "borderLeft" in style || "borderRight" in style)) return;
248
+ const borderWidth = currentStyle.borderStyle ? 1 : 0;
249
+ node.setBorder(Yoga.EDGE_TOP, currentStyle.borderTop === false ? 0 : borderWidth);
250
+ node.setBorder(Yoga.EDGE_BOTTOM, currentStyle.borderBottom === false ? 0 : borderWidth);
251
+ node.setBorder(Yoga.EDGE_LEFT, currentStyle.borderLeft === false ? 0 : borderWidth);
252
+ node.setBorder(Yoga.EDGE_RIGHT, currentStyle.borderRight === false ? 0 : borderWidth);
253
+ };
254
+ const applyGapStyles = (node, style) => {
255
+ if ("gap" in style) node.setGap(Yoga.GUTTER_ALL, style.gap ?? 0);
256
+ if ("columnGap" in style) node.setGap(Yoga.GUTTER_COLUMN, style.columnGap ?? 0);
257
+ if ("rowGap" in style) node.setGap(Yoga.GUTTER_ROW, style.rowGap ?? 0);
258
+ };
259
+ const styles = (node, style = {}, currentStyle = style) => {
260
+ applyPositionStyles(node, style);
261
+ applyMarginStyles(node, style);
262
+ applyPaddingStyles(node, style);
263
+ applyFlexStyles(node, style);
264
+ applyDimensionStyles(node, style);
265
+ applyDisplayStyles(node, style);
266
+ applyBorderStyles(node, style, currentStyle);
267
+ applyGapStyles(node, style);
268
+ };
269
+ //#endregion
270
+ //#region src/transform-adapter.ts
271
+ /** The single ANSI compatibility boundary used by Transform and external styled strings. */
272
+ function transformAnsiLine(serializedSubtree, lineIndex, transformers) {
273
+ let transformed = serializedSubtree;
274
+ for (const transformer of transformers) transformed = transformer(transformed, lineIndex);
275
+ return styledCharsFromTokens(tokenize(transformed));
276
+ }
277
+ //#endregion
278
+ //#region src/wrap-text.ts
279
+ const wrapTextCache = new QuickLru({ maxSize: 4096 });
280
+ const wrapText = (text, maxWidth, wrapType) => {
281
+ const cacheKey = text + String(maxWidth) + String(wrapType);
282
+ const cachedText = wrapTextCache.get(cacheKey);
283
+ if (cachedText !== void 0) return cachedText;
284
+ let wrappedText = text;
285
+ if (wrapType === "wrap") wrappedText = wrapAnsi(text, maxWidth, {
286
+ trim: false,
287
+ hard: true
288
+ });
289
+ if (wrapType === "hard") wrappedText = wrapAnsi(text, maxWidth, {
290
+ trim: false,
291
+ hard: true,
292
+ wordWrap: false
293
+ });
294
+ if (wrapType.startsWith("truncate")) {
295
+ let position = "end";
296
+ if (wrapType === "truncate-middle") position = "middle";
297
+ if (wrapType === "truncate-start") position = "start";
298
+ wrappedText = cliTruncate(text, maxWidth, { position });
299
+ }
300
+ wrapTextCache.set(cacheKey, wrappedText);
301
+ return wrappedText;
302
+ };
303
+ //#endregion
304
+ //#region src/dom.ts
305
+ const createNode = (nodeName) => {
306
+ const node = {
307
+ nodeName,
308
+ style: {},
309
+ attributes: {},
310
+ childNodes: [],
311
+ parentNode: void 0,
312
+ yogaNode: nodeName === "ink-virtual-text" ? void 0 : Yoga.Node.create(),
313
+ internal_accessibility: {}
314
+ };
315
+ if (nodeName === "ink-text") node.yogaNode?.setMeasureFunc((width) => measureTextNode(node, width));
316
+ return node;
317
+ };
318
+ const appendChildNode = (node, childNode) => {
319
+ if (childNode.parentNode) removeChildNode(childNode.parentNode, childNode);
320
+ childNode.parentNode = node;
321
+ node.childNodes.push(childNode);
322
+ if (childNode.yogaNode) node.yogaNode?.insertChild(childNode.yogaNode, node.yogaNode.getChildCount());
323
+ if (node.nodeName === "ink-text" || node.nodeName === "ink-virtual-text") markNodeAsDirty(node);
324
+ };
325
+ const insertBeforeNode = (node, newChildNode, beforeChildNode) => {
326
+ if (newChildNode.parentNode) removeChildNode(newChildNode.parentNode, newChildNode);
327
+ newChildNode.parentNode = node;
328
+ const index = node.childNodes.indexOf(beforeChildNode);
329
+ if (index >= 0) {
330
+ node.childNodes.splice(index, 0, newChildNode);
331
+ if (newChildNode.yogaNode) node.yogaNode?.insertChild(newChildNode.yogaNode, index);
332
+ } else {
333
+ node.childNodes.push(newChildNode);
334
+ if (newChildNode.yogaNode) node.yogaNode?.insertChild(newChildNode.yogaNode, node.yogaNode.getChildCount());
335
+ }
336
+ if (node.nodeName === "ink-text" || node.nodeName === "ink-virtual-text") markNodeAsDirty(node);
337
+ };
338
+ const removeChildNode = (node, removeNode) => {
339
+ if (removeNode.yogaNode) removeNode.parentNode?.yogaNode?.removeChild(removeNode.yogaNode);
340
+ removeNode.parentNode = void 0;
341
+ const index = node.childNodes.indexOf(removeNode);
342
+ if (index >= 0) node.childNodes.splice(index, 1);
343
+ if (node.nodeName === "ink-text" || node.nodeName === "ink-virtual-text") markNodeAsDirty(node);
344
+ };
345
+ const nullifyYogaNodes = (node) => {
346
+ node.yogaNode = void 0;
347
+ if (node.nodeName !== "#text") for (const childNode of node.childNodes) nullifyYogaNodes(childNode);
348
+ };
349
+ /**
350
+ Detach a removed subtree from the layout engine: drop the measure callback
351
+ and null the `yogaNode` reference on every DOM node within it.
352
+
353
+ Nulling the references makes every `?.yogaNode` guard in the codebase
354
+ effective for removed nodes, turns lingering access into a safe no-op (see
355
+ QwenLM/qwen-code#6820), and lets the garbage collector reclaim the Yoga
356
+ tree along with its closures.
357
+ */
358
+ const detachYogaSubtree = (removeNode) => {
359
+ removeNode.yogaNode?.unsetMeasureFunc();
360
+ nullifyYogaNodes(removeNode);
361
+ };
362
+ const setAttribute = (node, key, value) => {
363
+ if (key === "internal_accessibility") {
364
+ node.internal_accessibility = value;
365
+ return;
366
+ }
367
+ node.attributes[key] = value;
368
+ };
369
+ const setStyle = (node, style) => {
370
+ node.style = style ?? {};
371
+ };
372
+ const createTextNode = (text) => {
373
+ const node = {
374
+ nodeName: "#text",
375
+ nodeValue: text,
376
+ yogaNode: void 0,
377
+ parentNode: void 0,
378
+ style: {}
379
+ };
380
+ setTextNodeValue(node, text);
381
+ return node;
382
+ };
383
+ const measureTextNode = function(node, width) {
384
+ const text = node.nodeName === "#text" ? node.nodeValue : squashTextNodes(node);
385
+ const dimensions = measureText(text);
386
+ if (dimensions.width <= width) return dimensions;
387
+ if (dimensions.width >= 1 && width > 0 && width < 1) return dimensions;
388
+ const textWrap = node.style?.textWrap ?? "wrap";
389
+ const wrappedText = wrapText(text, width, textWrap);
390
+ return measureText(wrappedText);
391
+ };
392
+ const findClosestYogaNode = (node) => {
393
+ if (!node?.parentNode) return;
394
+ return node.yogaNode ?? findClosestYogaNode(node.parentNode);
395
+ };
396
+ const markNodeAsDirty = (node) => {
397
+ findClosestYogaNode(node)?.markDirty();
398
+ };
399
+ const setTextNodeValue = (node, text) => {
400
+ if (typeof text !== "string") text = String(text);
401
+ node.nodeValue = text;
402
+ markNodeAsDirty(node);
403
+ };
404
+ const addLayoutListener = (rootNode, listener) => {
405
+ if (rootNode.nodeName !== "ink-root") return () => {};
406
+ rootNode.internal_layoutListeners ??= /* @__PURE__ */ new Set();
407
+ rootNode.internal_layoutListeners.add(listener);
408
+ return () => {
409
+ rootNode.internal_layoutListeners?.delete(listener);
410
+ };
411
+ };
412
+ const emitLayoutListeners = (rootNode) => {
413
+ if (rootNode.nodeName !== "ink-root" || !rootNode.internal_layoutListeners) return;
414
+ for (const listener of rootNode.internal_layoutListeners) listener();
415
+ };
416
+ //#endregion
417
+ //#region src/components/Text.tsx
418
+ /** @jsxImportSource react */
419
+ /**
420
+ This component can display text and change its style to make it bold, underlined, italic, or strikethrough.
421
+ */
422
+ function Text({ color, backgroundColor, dimColor = false, bold = false, italic = false, underline = false, strikethrough = false, inverse = false, wrap = "wrap", children, "aria-label": ariaLabel, "aria-hidden": ariaHidden = false }) {
423
+ const { isScreenReaderEnabled } = useContext(accessibilityContext);
424
+ const childrenOrAriaLabel = isScreenReaderEnabled && ariaLabel ? ariaLabel : children;
425
+ if (childrenOrAriaLabel === void 0 || childrenOrAriaLabel === null) return null;
426
+ const foreground = typeof color === "object" ? color : parseSemanticColor(color);
427
+ const background = typeof backgroundColor === "object" ? backgroundColor : parseSemanticColor(backgroundColor);
428
+ const semanticStyle = {
429
+ ...foreground ? { foreground } : {},
430
+ ...background ? { background } : {},
431
+ ...color === "" ? { resetForeground: true } : {},
432
+ ...backgroundColor === "" ? { resetBackground: true } : {},
433
+ ...underline ? { underline: "single" } : {},
434
+ attributes: (dimColor ? cellAttributes.faint : 0) + (bold ? cellAttributes.bold : 0) + (italic ? cellAttributes.italic : 0) + (strikethrough ? cellAttributes.strikethrough : 0) + (inverse ? cellAttributes.inverse : 0)
435
+ };
436
+ if (isScreenReaderEnabled && ariaHidden) return null;
437
+ return /* @__PURE__ */ jsx("ink-text", {
438
+ style: {
439
+ flexGrow: 0,
440
+ flexShrink: 1,
441
+ flexDirection: "row",
442
+ textWrap: wrap
443
+ },
444
+ internal_textStyle: semanticStyle,
445
+ children: childrenOrAriaLabel
446
+ });
447
+ }
448
+ //#endregion
449
+ //#region src/components/FocusContext.ts
450
+ const FocusContext = createContext({
451
+ activeId: void 0,
452
+ add() {},
453
+ remove() {},
454
+ activate() {},
455
+ deactivate() {},
456
+ enableFocus() {},
457
+ disableFocus() {},
458
+ focusNext() {},
459
+ focusPrevious() {},
460
+ focus() {}
461
+ });
462
+ FocusContext.displayName = "InternalFocusContext";
463
+ //#endregion
464
+ //#region src/components/StdinContext.ts
465
+ /**
466
+ `StdinContext` is a React context that exposes the input stream.
467
+ */
468
+ const StdinContext = createContext({
469
+ stdin: process.stdin,
470
+ internal_eventEmitter: new EventEmitter(),
471
+ setRawMode() {},
472
+ setBracketedPasteMode() {},
473
+ isRawModeSupported: false,
474
+ internal_exitOnCtrlC: true
475
+ });
476
+ StdinContext.displayName = "InternalStdinContext";
477
+ //#endregion
478
+ //#region src/kitty-keyboard.ts
479
+ const kittyFlags = {
480
+ disambiguateEscapeCodes: 1,
481
+ reportEventTypes: 2,
482
+ reportAlternateKeys: 4,
483
+ reportAllKeysAsEscapeCodes: 8,
484
+ reportAssociatedText: 16
485
+ };
486
+ function resolveFlags(flags) {
487
+ let result = 0;
488
+ for (const flag of flags) result |= kittyFlags[flag];
489
+ return result;
490
+ }
491
+ const kittyModifiers = {
492
+ shift: 1,
493
+ alt: 2,
494
+ ctrl: 4,
495
+ super: 8,
496
+ hyper: 16,
497
+ meta: 32,
498
+ capsLock: 64,
499
+ numLock: 128
500
+ };
501
+ const textEncoder = new TextEncoder();
502
+ const kittyQueryEscapeByte = 27;
503
+ const kittyQueryOpenBracketByte = 91;
504
+ const kittyQueryQuestionMarkByte = 63;
505
+ const kittyQueryLetterByte = 117;
506
+ const zeroByte = 48;
507
+ const nineByte = 57;
508
+ const isDigitByte = (byte) => byte >= zeroByte && byte <= nineByte;
509
+ const matchKittyQueryResponse = (buffer, startIndex) => {
510
+ if (buffer[startIndex] !== kittyQueryEscapeByte || buffer[startIndex + 1] !== kittyQueryOpenBracketByte || buffer[startIndex + 2] !== kittyQueryQuestionMarkByte) return;
511
+ let index = startIndex + 3;
512
+ const digitsStartIndex = index;
513
+ while (index < buffer.length && isDigitByte(buffer[index])) index++;
514
+ if (index === digitsStartIndex) return;
515
+ if (index === buffer.length) return { state: "partial" };
516
+ if (buffer[index] === kittyQueryLetterByte) return {
517
+ state: "complete",
518
+ endIndex: index
519
+ };
520
+ };
521
+ const hasCompleteKittyQueryResponse = (buffer) => {
522
+ for (let index = 0; index < buffer.length; index++) if (matchKittyQueryResponse(buffer, index)?.state === "complete") return true;
523
+ return false;
524
+ };
525
+ const stripKittyQueryResponsesAndTrailingPartial = (buffer) => {
526
+ const keptBytes = [];
527
+ let index = 0;
528
+ while (index < buffer.length) {
529
+ const match = matchKittyQueryResponse(buffer, index);
530
+ if (match?.state === "complete") {
531
+ index = match.endIndex + 1;
532
+ continue;
533
+ }
534
+ if (match?.state === "partial") break;
535
+ keptBytes.push(buffer[index]);
536
+ index++;
537
+ }
538
+ return keptBytes;
539
+ };
540
+ const detectKittySupport = (stdin, stdout, onSupported) => {
541
+ let responseBuffer = [];
542
+ const cleanup = () => {
543
+ clearTimeout(timer);
544
+ stdin.removeListener("data", onData);
545
+ const remaining = stripKittyQueryResponsesAndTrailingPartial(responseBuffer);
546
+ responseBuffer = [];
547
+ if (remaining.length > 0) stdin.unshift(Uint8Array.from(remaining));
548
+ };
549
+ const onData = (data) => {
550
+ const chunk = typeof data === "string" ? textEncoder.encode(data) : data;
551
+ for (const byte of chunk) responseBuffer.push(byte);
552
+ if (hasCompleteKittyQueryResponse(responseBuffer)) {
553
+ cleanup();
554
+ onSupported();
555
+ }
556
+ };
557
+ stdin.on("data", onData);
558
+ const timer = setTimeout(cleanup, 200);
559
+ stdout.write(kittyQuery);
560
+ return cleanup;
561
+ };
562
+ //#endregion
563
+ //#region package.json
564
+ var name = "@alchemy.run/sigil";
565
+ var version = "0.0.0-alpha.5";
566
+ //#endregion
567
+ //#region src/reconciler.ts
568
+ if (isSigilDev) await import("./devtools-DbthxoD1.js").catch(() => {});
569
+ const diff = (before, after) => {
570
+ if (before === after) return;
571
+ if (!before) return after;
572
+ const changed = {};
573
+ let isChanged = false;
574
+ for (const key of Object.keys(before)) if (after ? !Object.hasOwn(after, key) : true) {
575
+ changed[key] = void 0;
576
+ isChanged = true;
577
+ }
578
+ if (after) {
579
+ for (const key of Object.keys(after)) if (after[key] !== before[key]) {
580
+ changed[key] = after[key];
581
+ isChanged = true;
582
+ }
583
+ }
584
+ return isChanged ? changed : void 0;
585
+ };
586
+ const findRootNode = (node) => {
587
+ let current = node;
588
+ while (current) {
589
+ if (current.nodeName === "ink-root") return current;
590
+ current = current.parentNode;
591
+ }
592
+ };
593
+ /**
594
+ * Clear the root's cached `staticNode` when the node it points at is being
595
+ * removed as part of a larger subtree.
596
+ *
597
+ * The previous identity check (`staticNode === removeNode`) only caught direct
598
+ * removal of the `<Static>` element. When an *ancestor* of `<Static>` is
599
+ * removed, the stale `staticNode` reference survives and the next render would
600
+ * replay stale static output (and, before `detachYogaSubtree`, trap on detached
601
+ * WASM memory — see QwenLM/qwen-code#6820).
602
+ *
603
+ * The owning root is derived from the host parent passed to the removal hook,
604
+ * not a module-level global, so instances with separate stdout streams don't
605
+ * clobber each other's pointers.
606
+ */
607
+ const clearStaticNodeIfContained = (rootNode, removeNode) => {
608
+ if (!rootNode?.staticNode) return;
609
+ let current = rootNode.staticNode;
610
+ while (current) {
611
+ if (current === removeNode) {
612
+ rootNode.staticNode = void 0;
613
+ return;
614
+ }
615
+ current = current.parentNode;
616
+ }
617
+ };
618
+ let currentUpdatePriority = NoEventPriority;
619
+ const reconciler = createReconciler({
620
+ getRootHostContext: () => ({ isInsideText: false }),
621
+ prepareForCommit: () => null,
622
+ preparePortalMount: () => null,
623
+ clearContainer: () => false,
624
+ resetAfterCommit(rootNode) {
625
+ if (typeof rootNode.onComputeLayout === "function") rootNode.onComputeLayout();
626
+ emitLayoutListeners(rootNode);
627
+ if (rootNode.staticNode !== rootNode.previousStaticNode) {
628
+ rootNode.previousStaticNode = rootNode.staticNode;
629
+ if (typeof rootNode.onStaticChange === "function") rootNode.onStaticChange();
630
+ }
631
+ if (rootNode.isStaticDirty) {
632
+ rootNode.isStaticDirty = false;
633
+ if (typeof rootNode.onImmediateRender === "function") rootNode.onImmediateRender();
634
+ return;
635
+ }
636
+ if (typeof rootNode.onRender === "function") rootNode.onRender();
637
+ },
638
+ getChildHostContext(parentHostContext, type) {
639
+ const previousIsInsideText = parentHostContext.isInsideText;
640
+ const isInsideText = type === "ink-text" || type === "ink-virtual-text";
641
+ if (previousIsInsideText === isInsideText) return parentHostContext;
642
+ return { isInsideText };
643
+ },
644
+ shouldSetTextContent: () => false,
645
+ createInstance(originalType, newProps, rootNode, hostContext) {
646
+ if (hostContext.isInsideText && originalType === "ink-box") throw new Error(`<Box> can't be nested inside <Text> component`);
647
+ const type = originalType === "ink-text" && hostContext.isInsideText ? "ink-virtual-text" : originalType;
648
+ const node = createNode(type);
649
+ for (const [key, value] of Object.entries(newProps)) {
650
+ if (key === "children") continue;
651
+ if (key === "style") {
652
+ setStyle(node, value);
653
+ if (node.yogaNode) styles(node.yogaNode, value);
654
+ continue;
655
+ }
656
+ if (key === "internal_transform") {
657
+ node.internal_transform = value;
658
+ continue;
659
+ }
660
+ if (key === "internal_ansi") {
661
+ node.internal_ansi = value === true;
662
+ continue;
663
+ }
664
+ if (key === "internal_textStyle") {
665
+ node.internal_textStyle = value;
666
+ continue;
667
+ }
668
+ if (key === "internal_static") {
669
+ node.internal_static = true;
670
+ rootNode.isStaticDirty = true;
671
+ rootNode.staticNode = node;
672
+ continue;
673
+ }
674
+ setAttribute(node, key, value);
675
+ }
676
+ return node;
677
+ },
678
+ createTextInstance(text, _root, hostContext) {
679
+ if (!hostContext.isInsideText) throw new Error(`Text string "${text}" must be rendered inside <Text> component`);
680
+ return createTextNode(text);
681
+ },
682
+ resetTextContent() {},
683
+ hideTextInstance(node) {
684
+ setTextNodeValue(node, "");
685
+ },
686
+ unhideTextInstance(node, text) {
687
+ setTextNodeValue(node, text);
688
+ },
689
+ getPublicInstance: (instance) => instance,
690
+ hideInstance(node) {
691
+ node.yogaNode?.setDisplay(Yoga.DISPLAY_NONE);
692
+ },
693
+ unhideInstance(node) {
694
+ node.yogaNode?.setDisplay(Yoga.DISPLAY_FLEX);
695
+ },
696
+ appendInitialChild: appendChildNode,
697
+ appendChild: appendChildNode,
698
+ insertBefore: insertBeforeNode,
699
+ finalizeInitialChildren() {
700
+ return false;
701
+ },
702
+ isPrimaryRenderer: true,
703
+ supportsMutation: true,
704
+ supportsPersistence: false,
705
+ supportsHydration: false,
706
+ supportsMicrotasks: true,
707
+ scheduleMicrotask: queueMicrotask,
708
+ scheduleCallback: Scheduler.unstable_scheduleCallback,
709
+ cancelCallback: Scheduler.unstable_cancelCallback,
710
+ shouldYield: Scheduler.unstable_shouldYield,
711
+ now: Scheduler.unstable_now,
712
+ scheduleTimeout: setTimeout,
713
+ cancelTimeout: clearTimeout,
714
+ noTimeout: -1,
715
+ beforeActiveInstanceBlur() {},
716
+ afterActiveInstanceBlur() {},
717
+ detachDeletedInstance() {},
718
+ getInstanceFromNode: () => null,
719
+ prepareScopeUpdate() {},
720
+ getInstanceFromScope: () => null,
721
+ appendChildToContainer: appendChildNode,
722
+ insertInContainerBefore: insertBeforeNode,
723
+ removeChildFromContainer(node, removeNode) {
724
+ clearStaticNodeIfContained(findRootNode(node), removeNode);
725
+ removeChildNode(node, removeNode);
726
+ detachYogaSubtree(removeNode);
727
+ },
728
+ commitUpdate(node, _type, oldProps, newProps) {
729
+ if (node.internal_static) {
730
+ const rootNode = findRootNode(node);
731
+ if (rootNode) rootNode.isStaticDirty = true;
732
+ }
733
+ const props = diff(oldProps, newProps);
734
+ const style = diff(oldProps["style"], newProps["style"]);
735
+ if (!props && !style) return;
736
+ if (props) for (const [key, value] of Object.entries(props)) {
737
+ if (key === "style") {
738
+ setStyle(node, value);
739
+ continue;
740
+ }
741
+ if (key === "internal_transform") {
742
+ node.internal_transform = value;
743
+ continue;
744
+ }
745
+ if (key === "internal_ansi") {
746
+ node.internal_ansi = value === true;
747
+ continue;
748
+ }
749
+ if (key === "internal_textStyle") {
750
+ node.internal_textStyle = value;
751
+ continue;
752
+ }
753
+ if (key === "internal_static") {
754
+ node.internal_static = true;
755
+ continue;
756
+ }
757
+ setAttribute(node, key, value);
758
+ }
759
+ if (style && node.yogaNode) styles(node.yogaNode, style, newProps["style"] ?? {});
760
+ },
761
+ commitTextUpdate(node, _oldText, newText) {
762
+ setTextNodeValue(node, newText);
763
+ },
764
+ removeChild(node, removeNode) {
765
+ clearStaticNodeIfContained(findRootNode(node), removeNode);
766
+ removeChildNode(node, removeNode);
767
+ detachYogaSubtree(removeNode);
768
+ },
769
+ setCurrentUpdatePriority(newPriority) {
770
+ currentUpdatePriority = newPriority;
771
+ },
772
+ getCurrentUpdatePriority: () => currentUpdatePriority,
773
+ resolveUpdatePriority() {
774
+ if (currentUpdatePriority !== NoEventPriority) return currentUpdatePriority;
775
+ return DefaultEventPriority;
776
+ },
777
+ maySuspendCommit() {
778
+ return true;
779
+ },
780
+ NotPendingTransition: void 0,
781
+ HostTransitionContext: createContext(null),
782
+ resetFormInstance() {},
783
+ requestPostPaintCallback() {},
784
+ shouldAttemptEagerTransition() {
785
+ return false;
786
+ },
787
+ trackSchedulerEvent() {},
788
+ resolveEventType() {
789
+ return null;
790
+ },
791
+ resolveEventTimeStamp() {
792
+ return -1.1;
793
+ },
794
+ preloadInstance() {
795
+ return true;
796
+ },
797
+ startSuspendingCommit() {},
798
+ suspendInstance() {},
799
+ waitForCommitToBeReady() {
800
+ return null;
801
+ },
802
+ rendererPackageName: name,
803
+ rendererVersion: version
804
+ });
805
+ //#endregion
806
+ //#region src/hooks/use-stdin.ts
807
+ /**
808
+ A React hook that returns the stdin stream and stdin-related utilities.
809
+ */
810
+ const useStdin = () => useContext(StdinContext);
811
+ const useStdinContext = () => useContext(StdinContext);
812
+ //#endregion
813
+ //#region src/parse-keypress.ts
814
+ const textDecoder = new TextDecoder();
815
+ const metaKeyCodeRe = /^(?:\x1b)([a-zA-Z0-9])$/;
816
+ const fnKeyRe = /^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/;
817
+ const keyName = {
818
+ OP: "f1",
819
+ OQ: "f2",
820
+ OR: "f3",
821
+ OS: "f4",
822
+ "[P": "f1",
823
+ "[Q": "f2",
824
+ "[R": "f3",
825
+ "[S": "f4",
826
+ "[11~": "f1",
827
+ "[12~": "f2",
828
+ "[13~": "f3",
829
+ "[14~": "f4",
830
+ "[[A": "f1",
831
+ "[[B": "f2",
832
+ "[[C": "f3",
833
+ "[[D": "f4",
834
+ "[[E": "f5",
835
+ "[15~": "f5",
836
+ "[17~": "f6",
837
+ "[18~": "f7",
838
+ "[19~": "f8",
839
+ "[20~": "f9",
840
+ "[21~": "f10",
841
+ "[23~": "f11",
842
+ "[24~": "f12",
843
+ "[A": "up",
844
+ "[B": "down",
845
+ "[C": "right",
846
+ "[D": "left",
847
+ "[E": "clear",
848
+ "[F": "end",
849
+ "[H": "home",
850
+ OA: "up",
851
+ OB: "down",
852
+ OC: "right",
853
+ OD: "left",
854
+ OE: "clear",
855
+ OF: "end",
856
+ OH: "home",
857
+ "[1~": "home",
858
+ "[2~": "insert",
859
+ "[3~": "delete",
860
+ "[4~": "end",
861
+ "[5~": "pageup",
862
+ "[6~": "pagedown",
863
+ "[[5~": "pageup",
864
+ "[[6~": "pagedown",
865
+ "[7~": "home",
866
+ "[8~": "end",
867
+ "[a": "up",
868
+ "[b": "down",
869
+ "[c": "right",
870
+ "[d": "left",
871
+ "[e": "clear",
872
+ "[2$": "insert",
873
+ "[3$": "delete",
874
+ "[5$": "pageup",
875
+ "[6$": "pagedown",
876
+ "[7$": "home",
877
+ "[8$": "end",
878
+ Oa: "up",
879
+ Ob: "down",
880
+ Oc: "right",
881
+ Od: "left",
882
+ Oe: "clear",
883
+ "[2^": "insert",
884
+ "[3^": "delete",
885
+ "[5^": "pageup",
886
+ "[6^": "pagedown",
887
+ "[7^": "home",
888
+ "[8^": "end",
889
+ "[Z": "tab"
890
+ };
891
+ const nonAlphanumericKeys = [...Object.values(keyName), "backspace"];
892
+ const isShiftKey = (code) => {
893
+ return [
894
+ "[a",
895
+ "[b",
896
+ "[c",
897
+ "[d",
898
+ "[e",
899
+ "[2$",
900
+ "[3$",
901
+ "[5$",
902
+ "[6$",
903
+ "[7$",
904
+ "[8$",
905
+ "[Z"
906
+ ].includes(code);
907
+ };
908
+ const isCtrlKey = (code) => {
909
+ return [
910
+ "Oa",
911
+ "Ob",
912
+ "Oc",
913
+ "Od",
914
+ "Oe",
915
+ "[2^",
916
+ "[3^",
917
+ "[5^",
918
+ "[6^",
919
+ "[7^",
920
+ "[8^"
921
+ ].includes(code);
922
+ };
923
+ const kittyKeyRe = /^\x1b\[(\d+)(?:;(\d+)(?::(\d+))?(?:;([\d:]+))?)?u$/;
924
+ const kittySpecialKeyRe = /^\x1b\[(\d+);(\d+):(\d+)([A-Za-z~])$/;
925
+ const kittySpecialLetterKeys = {
926
+ A: "up",
927
+ B: "down",
928
+ C: "right",
929
+ D: "left",
930
+ E: "clear",
931
+ F: "end",
932
+ H: "home",
933
+ P: "f1",
934
+ Q: "f2",
935
+ R: "f3",
936
+ S: "f4"
937
+ };
938
+ const kittySpecialNumberKeys = {
939
+ 2: "insert",
940
+ 3: "delete",
941
+ 5: "pageup",
942
+ 6: "pagedown",
943
+ 7: "home",
944
+ 8: "end",
945
+ 11: "f1",
946
+ 12: "f2",
947
+ 13: "f3",
948
+ 14: "f4",
949
+ 15: "f5",
950
+ 17: "f6",
951
+ 18: "f7",
952
+ 19: "f8",
953
+ 20: "f9",
954
+ 21: "f10",
955
+ 23: "f11",
956
+ 24: "f12"
957
+ };
958
+ const kittyCodepointNames = {
959
+ 27: "escape",
960
+ 9: "tab",
961
+ 127: "backspace",
962
+ 8: "backspace",
963
+ 57358: "capslock",
964
+ 57359: "scrolllock",
965
+ 57360: "numlock",
966
+ 57361: "printscreen",
967
+ 57362: "pause",
968
+ 57363: "menu",
969
+ 57376: "f13",
970
+ 57377: "f14",
971
+ 57378: "f15",
972
+ 57379: "f16",
973
+ 57380: "f17",
974
+ 57381: "f18",
975
+ 57382: "f19",
976
+ 57383: "f20",
977
+ 57384: "f21",
978
+ 57385: "f22",
979
+ 57386: "f23",
980
+ 57387: "f24",
981
+ 57388: "f25",
982
+ 57389: "f26",
983
+ 57390: "f27",
984
+ 57391: "f28",
985
+ 57392: "f29",
986
+ 57393: "f30",
987
+ 57394: "f31",
988
+ 57395: "f32",
989
+ 57396: "f33",
990
+ 57397: "f34",
991
+ 57398: "f35",
992
+ 57399: "kp0",
993
+ 57400: "kp1",
994
+ 57401: "kp2",
995
+ 57402: "kp3",
996
+ 57403: "kp4",
997
+ 57404: "kp5",
998
+ 57405: "kp6",
999
+ 57406: "kp7",
1000
+ 57407: "kp8",
1001
+ 57408: "kp9",
1002
+ 57409: "kpdecimal",
1003
+ 57410: "kpdivide",
1004
+ 57411: "kpmultiply",
1005
+ 57412: "kpsubtract",
1006
+ 57413: "kpadd",
1007
+ 57414: "kpenter",
1008
+ 57415: "kpequal",
1009
+ 57416: "kpseparator",
1010
+ 57417: "kpleft",
1011
+ 57418: "kpright",
1012
+ 57419: "kpup",
1013
+ 57420: "kpdown",
1014
+ 57421: "kppageup",
1015
+ 57422: "kppagedown",
1016
+ 57423: "kphome",
1017
+ 57424: "kpend",
1018
+ 57425: "kpinsert",
1019
+ 57426: "kpdelete",
1020
+ 57427: "kpbegin",
1021
+ 57428: "mediaplay",
1022
+ 57429: "mediapause",
1023
+ 57430: "mediaplaypause",
1024
+ 57431: "mediareverse",
1025
+ 57432: "mediastop",
1026
+ 57433: "mediafastforward",
1027
+ 57434: "mediarewind",
1028
+ 57435: "mediatracknext",
1029
+ 57436: "mediatrackprevious",
1030
+ 57437: "mediarecord",
1031
+ 57438: "lowervolume",
1032
+ 57439: "raisevolume",
1033
+ 57440: "mutevolume",
1034
+ 57441: "leftshift",
1035
+ 57442: "leftcontrol",
1036
+ 57443: "leftalt",
1037
+ 57444: "leftsuper",
1038
+ 57445: "lefthyper",
1039
+ 57446: "leftmeta",
1040
+ 57447: "rightshift",
1041
+ 57448: "rightcontrol",
1042
+ 57449: "rightalt",
1043
+ 57450: "rightsuper",
1044
+ 57451: "righthyper",
1045
+ 57452: "rightmeta",
1046
+ 57453: "isoLevel3Shift",
1047
+ 57454: "isoLevel5Shift"
1048
+ };
1049
+ const isValidCodepoint = (cp) => cp >= 0 && cp <= 1114111 && !(cp >= 55296 && cp <= 57343);
1050
+ const safeFromCodePoint = (cp) => isValidCodepoint(cp) ? String.fromCodePoint(cp) : "?";
1051
+ function resolveEventType(value) {
1052
+ if (value === 3) return "release";
1053
+ if (value === 2) return "repeat";
1054
+ return "press";
1055
+ }
1056
+ function parseKittyModifiers(modifiers) {
1057
+ return {
1058
+ ctrl: !!(modifiers & kittyModifiers.ctrl),
1059
+ shift: !!(modifiers & kittyModifiers.shift),
1060
+ meta: !!(modifiers & (kittyModifiers.meta | kittyModifiers.alt)),
1061
+ super: !!(modifiers & kittyModifiers.super),
1062
+ hyper: !!(modifiers & kittyModifiers.hyper),
1063
+ capsLock: !!(modifiers & kittyModifiers.capsLock),
1064
+ numLock: !!(modifiers & kittyModifiers.numLock)
1065
+ };
1066
+ }
1067
+ const parseKittyKeypress = (s) => {
1068
+ const match = kittyKeyRe.exec(s);
1069
+ if (!match) return null;
1070
+ const codepoint = parseInt(match[1], 10);
1071
+ const modifiers = match[2] ? Math.max(0, parseInt(match[2], 10) - 1) : 0;
1072
+ const eventType = match[3] ? parseInt(match[3], 10) : 1;
1073
+ const textField = match[4];
1074
+ if (!isValidCodepoint(codepoint)) return null;
1075
+ let text;
1076
+ if (textField) text = textField.split(":").map((cp) => safeFromCodePoint(parseInt(cp, 10))).join("");
1077
+ let name;
1078
+ let isPrintable;
1079
+ if (codepoint === 32) {
1080
+ name = "space";
1081
+ isPrintable = true;
1082
+ } else if (codepoint === 13) {
1083
+ name = "return";
1084
+ isPrintable = true;
1085
+ } else if (kittyCodepointNames[codepoint]) {
1086
+ name = kittyCodepointNames[codepoint];
1087
+ isPrintable = false;
1088
+ } else if (codepoint >= 1 && codepoint <= 26) {
1089
+ name = String.fromCodePoint(codepoint + 96);
1090
+ isPrintable = false;
1091
+ } else {
1092
+ name = safeFromCodePoint(codepoint).toLowerCase();
1093
+ isPrintable = true;
1094
+ }
1095
+ if (isPrintable && !text) text = safeFromCodePoint(codepoint);
1096
+ return {
1097
+ name,
1098
+ ...parseKittyModifiers(modifiers),
1099
+ eventType: resolveEventType(eventType),
1100
+ sequence: s,
1101
+ raw: s,
1102
+ isKittyProtocol: true,
1103
+ isPrintable,
1104
+ text
1105
+ };
1106
+ };
1107
+ const parseKittySpecialKey = (s) => {
1108
+ const match = kittySpecialKeyRe.exec(s);
1109
+ if (!match) return null;
1110
+ const number = parseInt(match[1], 10);
1111
+ const modifiers = Math.max(0, parseInt(match[2], 10) - 1);
1112
+ const eventType = parseInt(match[3], 10);
1113
+ const terminator = match[4];
1114
+ const name = terminator === "~" ? kittySpecialNumberKeys[number] : kittySpecialLetterKeys[terminator];
1115
+ if (!name) return null;
1116
+ return {
1117
+ name,
1118
+ ...parseKittyModifiers(modifiers),
1119
+ eventType: resolveEventType(eventType),
1120
+ sequence: s,
1121
+ raw: s,
1122
+ isKittyProtocol: true,
1123
+ isPrintable: false
1124
+ };
1125
+ };
1126
+ const parseKeypress = (s = "") => {
1127
+ let parts;
1128
+ if (s instanceof Uint8Array) {
1129
+ if (s[0] > 127 && s[1] === void 0) s = "\x1B" + textDecoder.decode(Uint8Array.of(s[0] - 128));
1130
+ else s = textDecoder.decode(s);
1131
+ } else if (s !== void 0 && typeof s !== "string") s = String(s);
1132
+ else if (!s) s = "";
1133
+ const kittyResult = parseKittyKeypress(s);
1134
+ if (kittyResult) return kittyResult;
1135
+ const kittySpecialResult = parseKittySpecialKey(s);
1136
+ if (kittySpecialResult) return kittySpecialResult;
1137
+ if (kittyKeyRe.test(s)) return {
1138
+ name: "",
1139
+ ctrl: false,
1140
+ meta: false,
1141
+ shift: false,
1142
+ sequence: s,
1143
+ raw: s,
1144
+ isKittyProtocol: true,
1145
+ isPrintable: false
1146
+ };
1147
+ const key = {
1148
+ name: "",
1149
+ ctrl: false,
1150
+ meta: false,
1151
+ shift: false,
1152
+ sequence: s,
1153
+ raw: s
1154
+ };
1155
+ key.sequence = key.sequence || s || key.name;
1156
+ if (s === "\r" || s === "\x1B\r") {
1157
+ key.raw = void 0;
1158
+ key.name = "return";
1159
+ key.meta = s.length === 2;
1160
+ } else if (s === "\n") key.name = "enter";
1161
+ else if (s === " ") key.name = "tab";
1162
+ else if (s === "\b" || s === "\x1B\b") {
1163
+ key.name = "backspace";
1164
+ key.meta = s.charAt(0) === "\x1B";
1165
+ } else if (s === "" || s === "\x1B") {
1166
+ key.name = "backspace";
1167
+ key.meta = s.charAt(0) === "\x1B";
1168
+ } else if (s === "\x1B" || s === "\x1B\x1B") {
1169
+ key.name = "escape";
1170
+ key.meta = s.length === 2;
1171
+ } else if (s === " " || s === "\x1B ") {
1172
+ key.name = "space";
1173
+ key.meta = s.length === 2;
1174
+ } else if (s.length === 1 && s <= "") {
1175
+ key.name = String.fromCharCode(s.charCodeAt(0) + "a".charCodeAt(0) - 1);
1176
+ key.ctrl = true;
1177
+ } else if (s.length === 1 && s >= "0" && s <= "9") key.name = "number";
1178
+ else if (s.length === 1 && s >= "a" && s <= "z") key.name = s;
1179
+ else if (s.length === 1 && s >= "A" && s <= "Z") {
1180
+ key.name = s.toLowerCase();
1181
+ key.shift = true;
1182
+ } else if (parts = metaKeyCodeRe.exec(s)) {
1183
+ key.name = parts[1].toLowerCase();
1184
+ key.meta = true;
1185
+ key.shift = /^[A-Z]$/.test(parts[1]);
1186
+ } else if (parts = fnKeyRe.exec(s)) {
1187
+ const segs = [...s];
1188
+ if (segs[0] === "\x1B" && segs[1] === "\x1B") key.meta = true;
1189
+ const code = [
1190
+ parts[1],
1191
+ parts[2],
1192
+ parts[4],
1193
+ parts[6]
1194
+ ].filter(Boolean).join("");
1195
+ const modifier = Number(parts[3] || parts[5] || 1) - 1;
1196
+ key.ctrl = !!(modifier & 4);
1197
+ key.meta = key.meta || !!(modifier & 10);
1198
+ key.shift = !!(modifier & 1);
1199
+ key.code = code;
1200
+ key.name = keyName[code] ?? "";
1201
+ key.shift = isShiftKey(code) || key.shift;
1202
+ key.ctrl = isCtrlKey(code) || key.ctrl;
1203
+ }
1204
+ return key;
1205
+ };
1206
+ //#endregion
1207
+ //#region src/hooks/use-input.ts
1208
+ /**
1209
+ A React hook that returns `void` and handles user input.
1210
+ It's a more convenient alternative to using `StdinContext` and listening for `data` events. The callback you pass to `useInput` is called for each character when the user enters any input. However, if the user pastes text and it's more than one character, the callback will be called only once, and the whole string will be passed as `input`.
1211
+
1212
+ ```
1213
+ import {useInput} from 'ink';
1214
+
1215
+ const UserInput = () => {
1216
+ useInput((input, key) => {
1217
+ if (input === 'q') {
1218
+ // Exit program
1219
+ }
1220
+
1221
+ if (key.leftArrow) {
1222
+ // Left arrow key pressed
1223
+ }
1224
+ });
1225
+
1226
+ return …
1227
+ };
1228
+ ```
1229
+ */
1230
+ const useInput = (inputHandler, options = {}) => {
1231
+ const { setRawMode, internal_exitOnCtrlC, internal_eventEmitter } = useStdinContext();
1232
+ useEffect(() => {
1233
+ if (options.isActive === false) return;
1234
+ setRawMode(true);
1235
+ return () => {
1236
+ setRawMode(false);
1237
+ };
1238
+ }, [options.isActive, setRawMode]);
1239
+ const handleData = useEffectEvent((data) => {
1240
+ const keypress = parseKeypress(data);
1241
+ const key = {
1242
+ upArrow: keypress.name === "up",
1243
+ downArrow: keypress.name === "down",
1244
+ leftArrow: keypress.name === "left",
1245
+ rightArrow: keypress.name === "right",
1246
+ pageDown: keypress.name === "pagedown",
1247
+ pageUp: keypress.name === "pageup",
1248
+ home: keypress.name === "home",
1249
+ end: keypress.name === "end",
1250
+ return: keypress.name === "return",
1251
+ escape: keypress.name === "escape",
1252
+ ctrl: keypress.ctrl,
1253
+ shift: keypress.shift,
1254
+ tab: keypress.name === "tab",
1255
+ backspace: keypress.name === "backspace",
1256
+ delete: keypress.name === "delete",
1257
+ meta: keypress.meta,
1258
+ super: keypress.super ?? false,
1259
+ hyper: keypress.hyper ?? false,
1260
+ capsLock: keypress.capsLock ?? false,
1261
+ numLock: keypress.numLock ?? false,
1262
+ eventType: keypress.eventType
1263
+ };
1264
+ let input;
1265
+ if (keypress.isKittyProtocol) {
1266
+ if (keypress.isPrintable) input = keypress.text ?? keypress.name;
1267
+ else if (keypress.ctrl && keypress.name.length === 1) input = keypress.name;
1268
+ else input = "";
1269
+ } else if (keypress.ctrl) input = keypress.name ?? "";
1270
+ else input = keypress.sequence;
1271
+ if (!keypress.isKittyProtocol && nonAlphanumericKeys.includes(keypress.name)) input = "";
1272
+ if (input.startsWith("\x1B")) input = input.slice(1);
1273
+ if (input.length === 1 && /[A-Z]/.test(input)) key.shift = true;
1274
+ if (input === "c" && key.ctrl && internal_exitOnCtrlC) return;
1275
+ reconciler.discreteUpdates(() => {
1276
+ inputHandler(input, key);
1277
+ });
1278
+ });
1279
+ useEffect(() => {
1280
+ if (options.isActive === false) return;
1281
+ internal_eventEmitter.on("input", handleData);
1282
+ return () => {
1283
+ internal_eventEmitter.removeListener("input", handleData);
1284
+ };
1285
+ }, [options.isActive, internal_eventEmitter]);
1286
+ };
1287
+ //#endregion
1288
+ //#region src/hooks/use-focus.ts
1289
+ /**
1290
+ A React hook that returns focus state and focus controls for the current component.
1291
+ A component that uses the `useFocus` hook becomes "focusable" to Ink, so when the user presses <kbd>Tab</kbd>, Ink will switch focus to this component. If there are multiple components that execute the `useFocus` hook, focus will be given to them in the order in which these components are rendered.
1292
+ */
1293
+ const useFocus = ({ isActive = true, autoFocus = false, id: customId } = {}) => {
1294
+ const { isRawModeSupported, setRawMode } = useStdin();
1295
+ const { activeId, add, remove, activate, deactivate, focus } = useContext(FocusContext);
1296
+ const autoId = useId();
1297
+ const id = customId ?? autoId;
1298
+ useEffect(() => {
1299
+ add(id, { autoFocus });
1300
+ return () => {
1301
+ remove(id);
1302
+ };
1303
+ }, [
1304
+ id,
1305
+ autoFocus,
1306
+ add,
1307
+ remove
1308
+ ]);
1309
+ useEffect(() => {
1310
+ if (isActive) activate(id);
1311
+ else deactivate(id);
1312
+ }, [
1313
+ isActive,
1314
+ id,
1315
+ activate,
1316
+ deactivate
1317
+ ]);
1318
+ useEffect(() => {
1319
+ if (!isRawModeSupported || !isActive) return;
1320
+ setRawMode(true);
1321
+ return () => {
1322
+ setRawMode(false);
1323
+ };
1324
+ }, [
1325
+ isActive,
1326
+ isRawModeSupported,
1327
+ setRawMode
1328
+ ]);
1329
+ return {
1330
+ isFocused: Boolean(id) && activeId === id,
1331
+ focus
1332
+ };
1333
+ };
1334
+ //#endregion
1335
+ export { squashTextNodes as _, reconciler as a, kittyModifiers as c, FocusContext as d, Text as f, transformAnsiLine as g, emitLayoutListeners as h, useStdinContext as i, resolveFlags as l, createNode as m, useInput as n, detectKittySupport as o, addLayoutListener as p, useStdin as r, kittyFlags as s, useFocus as t, StdinContext as u, accessibilityContext as v };