@simon_he/vue-tui 0.0.8 → 1.0.0

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 (249) hide show
  1. package/README.md +142 -30
  2. package/dist/TSelect-BwJJbuTt.js +6089 -0
  3. package/dist/TTree-DK_DQBYm.js +6480 -0
  4. package/dist/agent.cjs +39416 -0
  5. package/dist/agent.d.cts +44 -0
  6. package/dist/agent.d.ts +44 -0
  7. package/dist/agent.js +828 -0
  8. package/dist/ansi-palette-CNXqFciC.js +57 -0
  9. package/dist/ansi-styles.d.ts +200 -0
  10. package/dist/block-source-CKUOnkgT.js +1663 -0
  11. package/dist/cli/headless-renderer.d.ts +29 -0
  12. package/dist/cli/input.d.ts +49 -0
  13. package/dist/cli/node-file-writers.d.ts +13 -0
  14. package/dist/cli/node-module.d.ts +2 -0
  15. package/dist/cli/parse-kitty.d.ts +2 -0
  16. package/dist/cli/parse-mouse.d.ts +2 -0
  17. package/dist/cli/parse-utils.d.ts +14 -0
  18. package/dist/cli/parse-xterm.d.ts +2 -0
  19. package/dist/cli/path-provider-types.d.ts +1 -0
  20. package/dist/cli/path-provider.d.ts +4 -0
  21. package/dist/cli/path-suggest-core.d.ts +1 -0
  22. package/dist/cli/path-suggest.d.ts +15 -0
  23. package/dist/cli/recording.d.ts +4 -0
  24. package/dist/cli/stdin-buffer.d.ts +33 -0
  25. package/dist/cli.cjs +11061 -0
  26. package/dist/cli.d.cts +23 -0
  27. package/dist/cli.d.ts +23 -0
  28. package/dist/cli.js +9875 -0
  29. package/dist/core/ansi/capability.d.ts +20 -0
  30. package/dist/core/ansi/colors.d.ts +41 -0
  31. package/dist/core/ansi/sgr.d.ts +7 -0
  32. package/dist/core/ansi/theme.d.ts +6 -0
  33. package/dist/core/ansi-palette.d.ts +14 -0
  34. package/dist/core/buffer/buffer.d.ts +54 -0
  35. package/dist/core/buffer/width.d.ts +4 -0
  36. package/dist/core/debug-logger.d.ts +18 -0
  37. package/dist/core/hyperlink.d.ts +9 -0
  38. package/dist/core/index.d.ts +4 -0
  39. package/dist/core/path-provider-types.d.ts +24 -0
  40. package/dist/core/path-suggest.d.ts +35 -0
  41. package/dist/core/render-plane.d.ts +3 -0
  42. package/dist/core/terminal/create-terminal.d.ts +8 -0
  43. package/dist/core/terminal/emitter.d.ts +7 -0
  44. package/dist/core/types.d.ts +107 -0
  45. package/dist/core.cjs +3153 -0
  46. package/dist/core.d.cts +14 -0
  47. package/dist/core.d.ts +14 -0
  48. package/dist/core.js +424 -0
  49. package/dist/create-terminal-C2oiWFJU.js +1434 -0
  50. package/dist/create-terminal-app.d.ts +36 -0
  51. package/dist/dom-renderer-BqGijQID.js +1173 -0
  52. package/dist/env-Cl8qmNFN.js +19 -0
  53. package/dist/events/index.d.ts +6 -0
  54. package/dist/events/manager/cli-event-manager.d.ts +22 -0
  55. package/dist/events/manager/event-manager.d.ts +30 -0
  56. package/dist/events/manager/selection-suppression.d.ts +3 -0
  57. package/dist/events/manager/types.d.ts +108 -0
  58. package/dist/events/recording.d.ts +44 -0
  59. package/dist/experimental.cjs +4412 -1641
  60. package/dist/experimental.d.cts +42 -0
  61. package/dist/experimental.d.ts +42 -825
  62. package/dist/experimental.js +31 -7392
  63. package/dist/frame-perf-C6Xfg85O.js +24 -0
  64. package/dist/hyperlink-Bn02UXJb.js +419 -0
  65. package/dist/index.cjs +14765 -17582
  66. package/dist/index.d.cts +35 -0
  67. package/dist/index.d.ts +35 -1528
  68. package/dist/index.js +17 -20026
  69. package/dist/linkify-D_gzn9Xq.js +562 -0
  70. package/dist/markdown.cjs +9321 -7623
  71. package/dist/markdown.d.cts +11 -0
  72. package/dist/markdown.d.ts +11 -112
  73. package/dist/markdown.js +36 -1427
  74. package/dist/observability/cli-latency-node.d.ts +3 -0
  75. package/dist/observability/cli-latency-types.d.ts +41 -0
  76. package/dist/observability/cli-latency.d.ts +3 -0
  77. package/dist/observability/frame-perf-store.d.ts +18 -0
  78. package/dist/observability/frame-perf.d.ts +40 -0
  79. package/dist/observability/perf-sink.d.ts +56 -0
  80. package/dist/observability/trace.d.ts +40 -0
  81. package/dist/observability/tui-profiler.d.ts +33 -0
  82. package/dist/observability.cjs +221 -0
  83. package/dist/observability.d.cts +8 -0
  84. package/dist/observability.d.ts +8 -0
  85. package/dist/observability.js +4 -0
  86. package/dist/path-mnSgEpCm.js +81 -0
  87. package/dist/path-suggest-BNqcuE3-.js +274 -0
  88. package/dist/path-suggest-Dk9TRLh5.js +3 -0
  89. package/dist/{path-suggest-DmrmeueH.js → path-suggest-bvR9SY6Q.js} +86 -18
  90. package/dist/renderer/capabilities.d.ts +13 -0
  91. package/dist/renderer/cli/index.d.ts +2 -0
  92. package/dist/renderer/cli/stdout-metrics.d.ts +18 -0
  93. package/dist/renderer/cli/stdout-renderer.d.ts +48 -0
  94. package/dist/renderer/dom/dom-renderer.d.ts +157 -0
  95. package/dist/renderer/dom/index.d.ts +2 -0
  96. package/dist/renderer/index.d.ts +2 -0
  97. package/dist/renderer-dom.cjs +1505 -0
  98. package/dist/renderer-dom.d.cts +4 -0
  99. package/dist/renderer-dom.d.ts +4 -0
  100. package/dist/renderer-dom.js +7 -0
  101. package/dist/runtime/index.d.ts +36 -0
  102. package/dist/runtime/osc52.d.ts +9 -0
  103. package/dist/runtime-rfcZCyJq.js +1197 -0
  104. package/dist/runtime.cjs +1698 -0
  105. package/dist/runtime.d.cts +9 -0
  106. package/dist/runtime.d.ts +9 -0
  107. package/dist/runtime.js +4 -0
  108. package/dist/selection/terminal-selection.d.ts +123 -0
  109. package/dist/sgr-BmzxEjAO.js +304 -0
  110. package/dist/terminal-selection-DBinO6p5.js +330 -0
  111. package/dist/tlog-theme-qPBt5rge.js +9254 -0
  112. package/dist/trace-CjzYeIxN.js +182 -0
  113. package/dist/utils/env.d.ts +3 -0
  114. package/dist/utils/grapheme.d.ts +5 -0
  115. package/dist/utils/newlines.d.ts +1 -0
  116. package/dist/utils/path.d.ts +7 -0
  117. package/dist/utils/url-safety.d.ts +2 -0
  118. package/dist/vue/agent/view-models.d.ts +98 -0
  119. package/dist/vue/components/TAnchor.d.ts +108 -0
  120. package/dist/vue/components/TBox.d.ts +144 -0
  121. package/dist/vue/components/TCommandPalette.d.ts +587 -0
  122. package/dist/vue/components/TDataTable.d.ts +367 -0
  123. package/dist/vue/components/TDebugOverlay.d.ts +43 -0
  124. package/dist/vue/components/TDialog.d.ts +255 -0
  125. package/dist/vue/components/TFeedback.d.ts +635 -0
  126. package/dist/vue/components/TFlow.d.ts +85 -0
  127. package/dist/vue/components/TForm.d.ts +1230 -0
  128. package/dist/vue/components/TInput.d.ts +545 -0
  129. package/dist/vue/components/TInputBox.d.ts +158 -0
  130. package/dist/vue/components/TJsonEditor.d.ts +165 -0
  131. package/dist/vue/components/TLink.d.ts +239 -0
  132. package/dist/vue/components/TLinkifyText.d.ts +141 -0
  133. package/dist/vue/components/TList.d.ts +119 -0
  134. package/dist/vue/components/TLogLinksPanel.d.ts +238 -0
  135. package/dist/vue/components/TLogMinimap.d.ts +263 -0
  136. package/dist/vue/components/TLogScrollbar.d.ts +236 -0
  137. package/dist/vue/components/TLogSearchBar.d.ts +267 -0
  138. package/dist/vue/components/TLogSearchPager.d.ts +162 -0
  139. package/dist/vue/components/TLogSearchResults.d.ts +200 -0
  140. package/dist/vue/components/TLogView.d.ts +536 -0
  141. package/dist/vue/components/TLogVirtualLinksPanel.d.ts +141 -0
  142. package/dist/vue/components/TLogVirtualSearchResults.d.ts +146 -0
  143. package/dist/vue/components/TMarkdownText.d.ts +134 -0
  144. package/dist/vue/components/TMultilineModal.d.ts +62 -0
  145. package/dist/vue/components/TNavigation.d.ts +324 -0
  146. package/dist/vue/components/TOverlay.d.ts +366 -0
  147. package/dist/vue/components/TPanels.d.ts +244 -0
  148. package/dist/vue/components/TPathPicker.d.ts +213 -0
  149. package/dist/vue/components/TRenderLayer.d.ts +16 -0
  150. package/dist/vue/components/TRenderPlane.d.ts +17 -0
  151. package/dist/vue/components/TSelect.d.ts +335 -0
  152. package/dist/vue/components/TTable.d.ts +317 -0
  153. package/dist/vue/components/TText.d.ts +116 -0
  154. package/dist/vue/components/TThinkingView.d.ts +233 -0
  155. package/dist/vue/components/TToolCallView.d.ts +384 -0
  156. package/dist/vue/components/TTranscriptView.d.ts +221 -0
  157. package/dist/vue/components/TTransition.d.ts +83 -0
  158. package/dist/vue/components/TTree.d.ts +200 -0
  159. package/dist/vue/components/TUserMessageView.d.ts +344 -0
  160. package/dist/vue/components/TView.d.ts +127 -0
  161. package/dist/vue/components/TVirtualList.d.ts +182 -0
  162. package/dist/vue/components/TVirtualMarkdown.d.ts +168 -0
  163. package/dist/vue/components/TVirtualRows.d.ts +247 -0
  164. package/dist/vue/components/TerminalProvider.d.ts +218 -0
  165. package/dist/vue/components/input/host.d.ts +17 -0
  166. package/dist/vue/components/input/plugins/hostPlugin.d.ts +7 -0
  167. package/dist/vue/components/input/plugins/hostPlugin.node.d.ts +15 -0
  168. package/dist/vue/components/input/plugins/mentionUtils.d.ts +17 -0
  169. package/dist/vue/components/input/plugins/nodeMentionPathProvider.d.ts +2 -0
  170. package/dist/vue/components/input/plugins/promptMentionPlugin.d.ts +8 -0
  171. package/dist/vue/components/input/plugins/promptMentionState.d.ts +98 -0
  172. package/dist/vue/components/input/plugins/restrictText.d.ts +27 -0
  173. package/dist/vue/components/input/plugins/types.d.ts +90 -0
  174. package/dist/vue/components/input/utils/inlineText.d.ts +57 -0
  175. package/dist/vue/components/input/utils/inlineTextTokens.d.ts +34 -0
  176. package/dist/vue/components/input/utils/primitives.d.ts +3 -0
  177. package/dist/vue/components/input/utils/wordNavigation.d.ts +6 -0
  178. package/dist/vue/components/link/host.d.ts +15 -0
  179. package/dist/vue/components/list/list-geometry.d.ts +16 -0
  180. package/dist/vue/components/list/list-paint.d.ts +1 -0
  181. package/dist/vue/components/list/scroll-state.d.ts +25 -0
  182. package/dist/vue/components/list/selection-state.d.ts +6 -0
  183. package/dist/vue/components/simple-utils.d.ts +5 -0
  184. package/dist/vue/components/terminal-provider/copy-toast.d.ts +6 -0
  185. package/dist/vue/components/terminal-provider/portals.d.ts +17 -0
  186. package/dist/vue/components/terminal-provider/scheduler.d.ts +29 -0
  187. package/dist/vue/components/terminal-provider/selection-config.d.ts +15 -0
  188. package/dist/vue/components/terminal-provider/utils.d.ts +5 -0
  189. package/dist/vue/composables/use-layout.d.ts +2 -0
  190. package/dist/vue/composables/use-render-node.d.ts +19 -0
  191. package/dist/vue/composables/use-render-stack.d.ts +3 -0
  192. package/dist/vue/composables/use-runtime.d.ts +5 -0
  193. package/dist/vue/composables/use-terminal-node.d.ts +14 -0
  194. package/dist/vue/composables/use-terminal.d.ts +2 -0
  195. package/dist/vue/composables/use-visibility.d.ts +12 -0
  196. package/dist/vue/context.d.ts +153 -0
  197. package/dist/vue/index.d.ts +69 -0
  198. package/dist/vue/injection-key.d.ts +2 -0
  199. package/dist/vue/linkify.d.ts +11 -0
  200. package/dist/vue/log/append-only-log-store.d.ts +2 -0
  201. package/dist/vue/log/tlog-keymap.d.ts +28 -0
  202. package/dist/vue/log/tlog-plugins.d.ts +144 -0
  203. package/dist/vue/log/tlog-session.d.ts +81 -0
  204. package/dist/vue/log/tlog-theme.d.ts +68 -0
  205. package/dist/vue/log/types.d.ts +43 -0
  206. package/dist/vue/log/use-tlog-link-controller.d.ts +31 -0
  207. package/dist/vue/log/use-tlog-retained-index.d.ts +26 -0
  208. package/dist/vue/log/use-tlog-search-controller.d.ts +51 -0
  209. package/dist/vue/log/use-tlog-search-results-page.d.ts +31 -0
  210. package/dist/vue/log/use-tlog-virtual-search-results.d.ts +22 -0
  211. package/dist/vue/markdown/ast.d.ts +3 -0
  212. package/dist/vue/markdown/block-source.d.ts +22 -0
  213. package/dist/vue/markdown/document.d.ts +20 -0
  214. package/dist/vue/markdown/layout.d.ts +21 -0
  215. package/dist/vue/markdown/parser.d.ts +11 -0
  216. package/dist/vue/markdown/render.d.ts +10 -0
  217. package/dist/vue/markdown/theme.d.ts +186 -0
  218. package/dist/vue/markdown/types.d.ts +59 -0
  219. package/dist/vue/overlay.d.ts +27 -0
  220. package/dist/vue/render/context.d.ts +3 -0
  221. package/dist/vue/render/render-manager.d.ts +94 -0
  222. package/dist/vue/router/RouterView.d.ts +25 -0
  223. package/dist/vue/router/composables.d.ts +4 -0
  224. package/dist/vue/router/context.d.ts +4 -0
  225. package/dist/vue/router/router.d.ts +7 -0
  226. package/dist/vue/router/types.d.ts +29 -0
  227. package/dist/vue/scheduler/frame-mailbox.d.ts +55 -0
  228. package/dist/vue/scheduler/frame-scheduler.d.ts +51 -0
  229. package/dist/vue/theme.d.ts +48 -0
  230. package/dist/vue/transcript/hit-regions.d.ts +2 -0
  231. package/dist/vue/transcript/layout.d.ts +20 -0
  232. package/dist/vue/transcript/plain-text.d.ts +2 -0
  233. package/dist/vue/transcript/types.d.ts +122 -0
  234. package/dist/vue/utils/frame-task.d.ts +6 -0
  235. package/dist/vue/utils/rect.d.ts +4 -0
  236. package/dist/vue/utils/row-scroll.d.ts +25 -0
  237. package/dist/vue/utils/style-cache.d.ts +3 -0
  238. package/dist/vue/utils/text.d.ts +27 -0
  239. package/dist/vue/utils/wheel-scroll.d.ts +18 -0
  240. package/dist/vue.cjs +23668 -0
  241. package/dist/vue.d.cts +1 -0
  242. package/dist/vue.d.ts +1 -0
  243. package/dist/vue.js +3957 -0
  244. package/dist/{wheel-scroll-CiNsasLf.js → wheel-scroll-vBRaQ7p-.js} +404 -405
  245. package/package.json +185 -35
  246. package/dist/path-suggest-BeV6n7m-.js +0 -3
  247. package/dist/sgr-Tko2EQ0U.js +0 -484
  248. package/dist/theme-Bsm65g8k.d.ts +0 -32
  249. package/dist/types-ClIV2h1o.d.ts +0 -103
@@ -0,0 +1,1197 @@
1
+ //#region src/events/manager/selection-suppression.ts
2
+ const SUPPRESS_TERMINAL_POINTER_UP = "__vueTuiSuppressTerminalPointerUp";
3
+ const SUPPRESS_TERMINAL_POINTER_DOWN = "__vueTuiSuppressTerminalPointerDown";
4
+ const SUPPRESS_TERMINAL_POINTER_MOVE = "__vueTuiSuppressTerminalPointerMove";
5
+
6
+ //#endregion
7
+ //#region src/events/manager/event-manager.ts
8
+ function contains(rect, x, y) {
9
+ return x >= rect.x && y >= rect.y && x < rect.x + rect.w && y < rect.y + rect.h;
10
+ }
11
+ function isVisible(node) {
12
+ return node.visible !== false;
13
+ }
14
+ function containsRect(outer, inner) {
15
+ return inner.x >= outer.x && inner.y >= outer.y && inner.x + inner.w <= outer.x + outer.w && inner.y + inner.h <= outer.y + outer.h;
16
+ }
17
+ function area(rect) {
18
+ return Math.max(0, rect.w) * Math.max(0, rect.h);
19
+ }
20
+ function sameRect(a, b) {
21
+ return a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;
22
+ }
23
+ function now() {
24
+ return typeof performance !== "undefined" ? performance.now() : Date.now();
25
+ }
26
+ function rectRowRange(rect) {
27
+ const y0 = Math.floor(rect.y);
28
+ const y1 = Math.ceil(rect.y + rect.h) - 1;
29
+ if (!Number.isFinite(y0) || !Number.isFinite(y1)) return null;
30
+ if (y1 < y0) return null;
31
+ return {
32
+ y0,
33
+ y1
34
+ };
35
+ }
36
+ let nextId = 0;
37
+ function createEventManager(container, metrics, options) {
38
+ let currentMetrics = metrics;
39
+ const nodes = new Map();
40
+ const rowBuckets = new Map();
41
+ const rowRangeById = new Map();
42
+ let focusedId = null;
43
+ let capturedId = null;
44
+ let hoverPath = [];
45
+ let lastPointerMoveEvent = null;
46
+ const rawRecord = options?.record;
47
+ const recordStart = now();
48
+ const record = rawRecord ? (event) => {
49
+ rawRecord({
50
+ ...event,
51
+ time: now() - recordStart
52
+ });
53
+ } : void 0;
54
+ const onFocusChange = options?.onFocusChange;
55
+ const textInputTarget = options?.textInputTarget ?? null;
56
+ const MODAL_FOCUS_Z_THRESHOLD = 100;
57
+ const MODAL_ROOT_MIN_AREA = 40;
58
+ function focusLockTarget() {
59
+ let bestRoot = null;
60
+ let bestAny = null;
61
+ for (const n of nodes.values()) {
62
+ if (!n.focusable || !isVisible(n)) continue;
63
+ const z = n.zIndex ?? 0;
64
+ if (z < MODAL_FOCUS_Z_THRESHOLD) continue;
65
+ const a = area(n.rect);
66
+ if (!bestAny || z > bestAny.zIndex || z === bestAny.zIndex && a > bestAny.area) bestAny = {
67
+ id: n.id,
68
+ zIndex: z,
69
+ area: a
70
+ };
71
+ if (a >= MODAL_ROOT_MIN_AREA && (!bestRoot || z > bestRoot.zIndex || z === bestRoot.zIndex && a > bestRoot.area)) bestRoot = {
72
+ id: n.id,
73
+ zIndex: z,
74
+ area: a
75
+ };
76
+ }
77
+ const best = bestRoot ?? bestAny;
78
+ return best ? {
79
+ id: best.id,
80
+ zIndex: best.zIndex
81
+ } : null;
82
+ }
83
+ function resolveLockedFocusTarget(type) {
84
+ const lock = focusLockTarget();
85
+ let target = focusedId ? nodes.get(focusedId) ?? null : null;
86
+ const shouldRetarget = lock && (!target || !isVisible(target) || (target.zIndex ?? 0) < lock.zIndex);
87
+ if (!shouldRetarget || !lock) return target;
88
+ let best = null;
89
+ let bestScore = -Infinity;
90
+ for (const node of nodes.values()) {
91
+ if (!node.focusable || !isVisible(node)) continue;
92
+ const z = node.zIndex ?? 0;
93
+ if (z < lock.zIndex) continue;
94
+ const handlers = node.handlers ?? {};
95
+ const canHandle = type ? typeof handlers[type] === "function" : false;
96
+ const a = area(node.rect);
97
+ const score = z * 1e9 + (canHandle ? 1e6 : 0) - a;
98
+ if (score > bestScore) {
99
+ bestScore = score;
100
+ best = node;
101
+ }
102
+ }
103
+ if (best) {
104
+ setFocus(best.id);
105
+ target = best;
106
+ }
107
+ return target;
108
+ }
109
+ function resolveModalLockNode() {
110
+ const lock = focusLockTarget();
111
+ if (!lock) return null;
112
+ const node = nodes.get(lock.id) ?? null;
113
+ return node && isVisible(node) ? node : null;
114
+ }
115
+ function isAllowedModalPointerNode(node, target, lockNode) {
116
+ const nodeZ = node.zIndex ?? 0;
117
+ const targetZ = target.zIndex ?? 0;
118
+ const lockZ = lockNode.zIndex ?? 0;
119
+ if (nodeZ >= lockZ) return true;
120
+ return targetZ < lockZ && nodeZ >= targetZ && containsRect(node.rect, lockNode.rect);
121
+ }
122
+ const shouldDebugIme = () => Boolean(options?.debugIme) || Boolean(globalThis.__VT_DEBUG_IME__);
123
+ const imeLog = (msg, extra) => {
124
+ if (!shouldDebugIme()) return;
125
+ console.debug(`[vue-terminal][ime] ${msg}`, extra ?? {});
126
+ };
127
+ let domComposing = false;
128
+ const defaultUserSelect = container.style.userSelect || "text";
129
+ if (!container.hasAttribute("tabindex")) container.tabIndex = 0;
130
+ if (!container.style.userSelect) container.style.userSelect = defaultUserSelect;
131
+ let containerRect = null;
132
+ let containerRectDirty = true;
133
+ function markContainerRectDirty() {
134
+ containerRectDirty = true;
135
+ }
136
+ function getContainerRect() {
137
+ if (!containerRect || containerRectDirty) {
138
+ containerRect = container.getBoundingClientRect();
139
+ containerRectDirty = false;
140
+ }
141
+ return containerRect;
142
+ }
143
+ function removeFromRowBuckets(id) {
144
+ const prev = rowRangeById.get(id);
145
+ if (!prev) return;
146
+ for (let y = prev.y0; y <= prev.y1; y++) {
147
+ const bucket = rowBuckets.get(y);
148
+ if (!bucket) continue;
149
+ bucket.delete(id);
150
+ if (bucket.size === 0) rowBuckets.delete(y);
151
+ }
152
+ rowRangeById.delete(id);
153
+ }
154
+ function addToRowBuckets(id, node) {
155
+ if (!isVisible(node)) return;
156
+ const range = rectRowRange(node.rect);
157
+ if (!range) return;
158
+ rowRangeById.set(id, range);
159
+ for (let y = range.y0; y <= range.y1; y++) {
160
+ let bucket = rowBuckets.get(y);
161
+ if (!bucket) {
162
+ bucket = new Set();
163
+ rowBuckets.set(y, bucket);
164
+ }
165
+ bucket.add(id);
166
+ }
167
+ }
168
+ function updateRowBuckets(id, node) {
169
+ if (!isVisible(node)) {
170
+ removeFromRowBuckets(id);
171
+ return;
172
+ }
173
+ const next = rectRowRange(node.rect);
174
+ const prev = rowRangeById.get(id);
175
+ if (!next) {
176
+ removeFromRowBuckets(id);
177
+ return;
178
+ }
179
+ if (prev && prev.y0 === next.y0 && prev.y1 === next.y1) return;
180
+ removeFromRowBuckets(id);
181
+ rowRangeById.set(id, next);
182
+ for (let y = next.y0; y <= next.y1; y++) {
183
+ let bucket = rowBuckets.get(y);
184
+ if (!bucket) {
185
+ bucket = new Set();
186
+ rowBuckets.set(y, bucket);
187
+ }
188
+ bucket.add(id);
189
+ }
190
+ }
191
+ function candidatesAt(cellX, cellY) {
192
+ const list = [];
193
+ const bucket = rowBuckets.get(cellY);
194
+ if (!bucket) return list;
195
+ for (const id of bucket) {
196
+ const node = nodes.get(id);
197
+ if (!node) continue;
198
+ if (!isVisible(node)) continue;
199
+ if (contains(node.rect, cellX, cellY)) list.push(node);
200
+ }
201
+ return list.sort((a, b) => area(b.rect) - area(a.rect) || a.zIndex - b.zIndex);
202
+ }
203
+ function pickTarget(list) {
204
+ if (list.length === 0) return null;
205
+ let target = list[0];
206
+ for (const n of list) if (n.zIndex > target.zIndex) target = n;
207
+ else if (n.zIndex === target.zIndex && area(n.rect) <= area(target.rect)) target = n;
208
+ return target;
209
+ }
210
+ function pathOuterToInner(list, target) {
211
+ if (!target) return [];
212
+ const filtered = list.filter((n) => n.id !== target.id && (!n.focusable || !target.focusable || n.zIndex !== target.zIndex || !sameRect(n.rect, target.rect)));
213
+ return [...filtered, target];
214
+ }
215
+ function ancestorsForTarget(target) {
216
+ const range = rectRowRange(target.rect);
217
+ const seedBucket = range ? rowBuckets.get(range.y0) : null;
218
+ if (!seedBucket) {
219
+ const list$1 = [];
220
+ for (const node of nodes.values()) {
221
+ if (!isVisible(node)) continue;
222
+ if (containsRect(node.rect, target.rect)) list$1.push(node);
223
+ }
224
+ const sorted$1 = list$1.sort((a, b) => a.zIndex - b.zIndex || area(b.rect) - area(a.rect));
225
+ return pathOuterToInner(sorted$1, target);
226
+ }
227
+ const list = [];
228
+ for (const id of seedBucket) {
229
+ const node = nodes.get(id);
230
+ if (!node) continue;
231
+ if (!isVisible(node)) continue;
232
+ if (containsRect(node.rect, target.rect)) list.push(node);
233
+ }
234
+ const sorted = list.sort((a, b) => a.zIndex - b.zIndex || area(b.rect) - area(a.rect));
235
+ return pathOuterToInner(sorted, target);
236
+ }
237
+ function makeBaseEvent(type, path, nativeEvent) {
238
+ const e = {
239
+ type,
240
+ target: null,
241
+ currentTarget: null,
242
+ eventPhase: 2,
243
+ bubbles: true,
244
+ cancelable: true,
245
+ defaultPrevented: Boolean(nativeEvent?.defaultPrevented),
246
+ timeStamp: now(),
247
+ __stopped: false,
248
+ stopPropagation() {
249
+ this.__stopped = true;
250
+ },
251
+ preventDefault() {
252
+ this.defaultPrevented = true;
253
+ nativeEvent?.preventDefault?.();
254
+ },
255
+ composedPath() {
256
+ return [...path].reverse();
257
+ },
258
+ nativeEvent
259
+ };
260
+ return e;
261
+ }
262
+ function dispatchToNode(handlerKey, node, event) {
263
+ event.currentTarget = node;
264
+ if (!node) return;
265
+ const handler = node.handlers[handlerKey];
266
+ handler?.(event);
267
+ }
268
+ function dispatchWithPhases(type, path, target, event) {
269
+ event.target = target;
270
+ const captureKey = `${type}Capture`;
271
+ event.eventPhase = 1;
272
+ for (const node of path) {
273
+ dispatchToNode(captureKey, node, event);
274
+ if (event.__stopped) return;
275
+ }
276
+ if (target) {
277
+ event.eventPhase = 2;
278
+ dispatchToNode(type, target, event);
279
+ if (event.__stopped) return;
280
+ }
281
+ if (!event.bubbles) return;
282
+ event.eventPhase = 3;
283
+ for (let i = path.length - 2; i >= 0; i--) {
284
+ dispatchToNode(type, path[i], event);
285
+ if (event.__stopped) return;
286
+ }
287
+ }
288
+ function sharedPrefixLenById(a, b) {
289
+ const min = Math.min(a.length, b.length);
290
+ let i = 0;
291
+ for (; i < min; i++) if (a[i].id !== b[i].id) break;
292
+ return i;
293
+ }
294
+ function updateHover(nextTarget, native) {
295
+ const nextPath = nextTarget ? ancestorsForTarget(nextTarget) : [];
296
+ const shared = sharedPrefixLenById(hoverPath, nextPath);
297
+ for (let i = hoverPath.length - 1; i >= shared; i--) {
298
+ const target = hoverPath[i] ?? null;
299
+ if (!target) continue;
300
+ const path = hoverPath.slice(0, i + 1);
301
+ const ev = buildPointerEvent("pointerleave", path, native);
302
+ ev.bubbles = false;
303
+ dispatchWithPhases("pointerleave", path, target, ev);
304
+ }
305
+ for (let i = shared; i < nextPath.length; i++) {
306
+ const target = nextPath[i] ?? null;
307
+ if (!target) continue;
308
+ const path = nextPath.slice(0, i + 1);
309
+ const ev = buildPointerEvent("pointerenter", path, native);
310
+ ev.bubbles = false;
311
+ dispatchWithPhases("pointerenter", path, target, ev);
312
+ }
313
+ hoverPath = nextPath;
314
+ }
315
+ function setFocus(nextId$1) {
316
+ const lock = focusLockTarget();
317
+ if (lock) if (!nextId$1) nextId$1 = lock.id;
318
+ else {
319
+ const want = nodes.get(nextId$1) ?? null;
320
+ const wantZ = want?.zIndex ?? 0;
321
+ if (want && isVisible(want) && wantZ < lock.zIndex) return;
322
+ }
323
+ if (focusedId === nextId$1) return;
324
+ const prev = focusedId ? nodes.get(focusedId) ?? null : null;
325
+ const nextRaw = nextId$1 ? nodes.get(nextId$1) ?? null : null;
326
+ const next = nextRaw && isVisible(nextRaw) ? nextRaw : null;
327
+ focusedId = next?.id ?? null;
328
+ onFocusChange?.(prev?.id ?? null, focusedId);
329
+ if (prev) {
330
+ const path = ancestorsForTarget(prev);
331
+ const ev = makeBaseEvent("blur", path);
332
+ dispatchWithPhases("blur", path, prev, ev);
333
+ }
334
+ if (next) {
335
+ const path = ancestorsForTarget(next);
336
+ const ev = makeBaseEvent("focus", path);
337
+ dispatchWithPhases("focus", path, next, ev);
338
+ }
339
+ }
340
+ function toCell(clientX, clientY) {
341
+ const rect = getContainerRect();
342
+ const x = clientX - rect.left;
343
+ const y = clientY - rect.top;
344
+ return {
345
+ cellX: Math.max(0, Math.floor(x / currentMetrics.cellWidth)),
346
+ cellY: Math.max(0, Math.floor(y / currentMetrics.cellHeight))
347
+ };
348
+ }
349
+ function buildPointerEvent(type, path, native) {
350
+ const base = makeBaseEvent(type, path, native);
351
+ const { cellX, cellY } = toCell(native.clientX, native.clientY);
352
+ return Object.assign(base, {
353
+ clientX: native.clientX,
354
+ clientY: native.clientY,
355
+ cellX,
356
+ cellY,
357
+ button: "button" in native ? native.button : void 0,
358
+ buttons: "buttons" in native ? native.buttons : void 0,
359
+ ctrlKey: native.ctrlKey,
360
+ shiftKey: native.shiftKey,
361
+ altKey: native.altKey,
362
+ metaKey: native.metaKey,
363
+ deltaY: "deltaY" in native ? native.deltaY : void 0,
364
+ deltaMode: "deltaMode" in native ? native.deltaMode : void 0
365
+ });
366
+ }
367
+ function keyCombo(native) {
368
+ let out = "";
369
+ if (native.metaKey) out += "Meta+";
370
+ if (native.ctrlKey) out += "Ctrl+";
371
+ if (native.altKey) out += "Alt+";
372
+ if (native.shiftKey) out += "Shift+";
373
+ out += native.key;
374
+ return out;
375
+ }
376
+ function buildKeyboardEvent(type, path, native) {
377
+ const base = makeBaseEvent(type, path, native);
378
+ return Object.assign(base, {
379
+ key: native.key,
380
+ code: native.code,
381
+ combo: keyCombo(native),
382
+ ctrlKey: native.ctrlKey,
383
+ shiftKey: native.shiftKey,
384
+ altKey: native.altKey,
385
+ metaKey: native.metaKey,
386
+ repeat: native.repeat
387
+ });
388
+ }
389
+ function dispatchPointer(type, native, targetOverride) {
390
+ const { cellX, cellY } = toCell(native.clientX, native.clientY);
391
+ const list = candidatesAt(cellX, cellY);
392
+ const target = targetOverride ?? pickTarget(list);
393
+ const lockNode = resolveModalLockNode();
394
+ if (lockNode && target && !isAllowedModalPointerNode(target, target, lockNode)) return;
395
+ let path = target ? ancestorsForTarget(target) : [];
396
+ if (lockNode && target && path.length > 0) path = path.filter((n) => isAllowedModalPointerNode(n, target, lockNode));
397
+ const ev = buildPointerEvent(type, path, native);
398
+ dispatchWithPhases(type, path, target, ev);
399
+ }
400
+ function dispatchToFocused(type, native) {
401
+ const target = resolveLockedFocusTarget(type);
402
+ const path = target ? ancestorsForTarget(target) : [];
403
+ const ev = buildKeyboardEvent(type, path, native);
404
+ dispatchWithPhases(type, path, target, ev);
405
+ if (ev.defaultPrevented) native.preventDefault();
406
+ }
407
+ function buildInputEvent(type, path, native) {
408
+ const base = makeBaseEvent(type, path, native);
409
+ const anyNative = native;
410
+ const data = typeof anyNative.data === "string" ? anyNative.data : void 0;
411
+ const inputType = typeof anyNative.inputType === "string" ? anyNative.inputType : void 0;
412
+ const isComposing = Boolean(anyNative.isComposing);
413
+ let text;
414
+ if (type === "paste") {
415
+ const clipboard = anyNative.clipboardData;
416
+ if (clipboard?.getData) text = clipboard.getData("text/plain") || clipboard.getData("text") || "";
417
+ }
418
+ return Object.assign(base, {
419
+ data,
420
+ inputType,
421
+ isComposing,
422
+ text
423
+ });
424
+ }
425
+ function dispatchToFocusedText(type, native) {
426
+ const target = resolveLockedFocusTarget(type);
427
+ const path = target ? ancestorsForTarget(target) : [];
428
+ const ev = buildInputEvent(type, path, native);
429
+ dispatchWithPhases(type, path, target, ev);
430
+ if (ev.defaultPrevented) native.preventDefault?.();
431
+ }
432
+ function onPointerDown(e) {
433
+ if (e[SUPPRESS_TERMINAL_POINTER_DOWN]) {
434
+ if (textInputTarget && !container.contains(textInputTarget)) try {
435
+ textInputTarget.focus?.({ preventScroll: true });
436
+ } catch {
437
+ textInputTarget.focus?.();
438
+ }
439
+ else try {
440
+ container.focus?.({ preventScroll: true });
441
+ } catch {
442
+ container.focus?.();
443
+ }
444
+ const { cellX: cellX$1, cellY: cellY$1 } = toCell(e.clientX, e.clientY);
445
+ const list$1 = candidatesAt(cellX$1, cellY$1);
446
+ const target$1 = pickTarget(list$1);
447
+ if (target$1?.focusable) setFocus(target$1.id);
448
+ capturedId = target$1?.id ?? null;
449
+ updateHover(target$1, e);
450
+ record?.({
451
+ type: "pointerdown",
452
+ cellX: cellX$1,
453
+ cellY: cellY$1,
454
+ clientX: e.clientX,
455
+ clientY: e.clientY,
456
+ button: e.button,
457
+ buttons: e.buttons,
458
+ ctrlKey: e.ctrlKey,
459
+ shiftKey: e.shiftKey,
460
+ altKey: e.altKey,
461
+ metaKey: e.metaKey
462
+ });
463
+ return;
464
+ }
465
+ if (textInputTarget && !container.contains(textInputTarget)) {
466
+ try {
467
+ textInputTarget.focus?.({ preventScroll: true });
468
+ } catch {
469
+ textInputTarget.focus?.();
470
+ }
471
+ if (shouldDebugIme()) {
472
+ const active = typeof document !== "undefined" ? document.activeElement?.tagName ?? null : null;
473
+ imeLog("pointerdown focus textInputTarget", { active });
474
+ }
475
+ } else try {
476
+ container.focus?.({ preventScroll: true });
477
+ } catch {
478
+ container.focus?.();
479
+ }
480
+ const { cellX, cellY } = toCell(e.clientX, e.clientY);
481
+ const list = candidatesAt(cellX, cellY);
482
+ const target = pickTarget(list);
483
+ const lockNode = resolveModalLockNode();
484
+ if (lockNode && target && !isAllowedModalPointerNode(target, target, lockNode)) return;
485
+ let path = target ? ancestorsForTarget(target) : [];
486
+ if (lockNode && target && path.length > 0) path = path.filter((n) => isAllowedModalPointerNode(n, target, lockNode));
487
+ const allowSelection = target ? target.selectable ?? !target.focusable : true;
488
+ container.style.userSelect = allowSelection ? defaultUserSelect : "none";
489
+ if (target) if (target.focusable) setFocus(target.id);
490
+ else for (let i = path.length - 2; i >= 0; i--) {
491
+ const n = path[i];
492
+ if (n?.focusable) {
493
+ setFocus(n.id);
494
+ break;
495
+ }
496
+ }
497
+ capturedId = target?.id ?? null;
498
+ updateHover(target, e);
499
+ record?.({
500
+ type: "pointerdown",
501
+ cellX,
502
+ cellY,
503
+ clientX: e.clientX,
504
+ clientY: e.clientY,
505
+ button: e.button,
506
+ buttons: e.buttons,
507
+ ctrlKey: e.ctrlKey,
508
+ shiftKey: e.shiftKey,
509
+ altKey: e.altKey,
510
+ metaKey: e.metaKey
511
+ });
512
+ const ev = buildPointerEvent("pointerdown", path, e);
513
+ dispatchWithPhases("pointerdown", path, target, ev);
514
+ }
515
+ function onMouseDown(e) {
516
+ onPointerDown(e);
517
+ }
518
+ function onMouseMove(e) {
519
+ lastPointerMoveEvent = e;
520
+ onPointerMove(e);
521
+ }
522
+ function onMouseUp(e) {
523
+ onPointerUp(e);
524
+ }
525
+ function onMouseLeave(e) {
526
+ const native = lastPointerMoveEvent ?? e;
527
+ updateHover(null, native);
528
+ }
529
+ function onPointerMove(e) {
530
+ if (e[SUPPRESS_TERMINAL_POINTER_MOVE]) return;
531
+ lastPointerMoveEvent = e;
532
+ const { cellX, cellY } = toCell(e.clientX, e.clientY);
533
+ record?.({
534
+ type: "pointermove",
535
+ cellX,
536
+ cellY,
537
+ clientX: e.clientX,
538
+ clientY: e.clientY,
539
+ button: e.button,
540
+ buttons: e.buttons,
541
+ ctrlKey: e.ctrlKey,
542
+ shiftKey: e.shiftKey,
543
+ altKey: e.altKey,
544
+ metaKey: e.metaKey
545
+ });
546
+ if (capturedId) {
547
+ const target$1 = nodes.get(capturedId) ?? null;
548
+ if (!target$1) return;
549
+ updateHover(target$1, e);
550
+ const path = ancestorsForTarget(target$1);
551
+ const ev = buildPointerEvent("pointermove", path, e);
552
+ dispatchWithPhases("pointermove", path, target$1, ev);
553
+ return;
554
+ }
555
+ const list = candidatesAt(cellX, cellY);
556
+ const target = pickTarget(list);
557
+ updateHover(target, e);
558
+ dispatchPointer("pointermove", e, target);
559
+ }
560
+ function onPointerUp(e) {
561
+ const { cellX, cellY } = toCell(e.clientX, e.clientY);
562
+ record?.({
563
+ type: "pointerup",
564
+ cellX,
565
+ cellY,
566
+ clientX: e.clientX,
567
+ clientY: e.clientY,
568
+ button: e.button,
569
+ buttons: e.buttons,
570
+ ctrlKey: e.ctrlKey,
571
+ shiftKey: e.shiftKey,
572
+ altKey: e.altKey,
573
+ metaKey: e.metaKey
574
+ });
575
+ if (e[SUPPRESS_TERMINAL_POINTER_UP]) {
576
+ capturedId = null;
577
+ container.style.userSelect = defaultUserSelect;
578
+ return;
579
+ }
580
+ if (capturedId) {
581
+ const target = nodes.get(capturedId) ?? null;
582
+ const path = target ? ancestorsForTarget(target) : [];
583
+ const ev = buildPointerEvent("pointerup", path, e);
584
+ dispatchWithPhases("pointerup", path, target, ev);
585
+ } else dispatchPointer("pointerup", e);
586
+ capturedId = null;
587
+ container.style.userSelect = defaultUserSelect;
588
+ }
589
+ function onClick(e) {
590
+ const { cellX, cellY } = toCell(e.clientX, e.clientY);
591
+ record?.({
592
+ type: "click",
593
+ cellX,
594
+ cellY,
595
+ clientX: e.clientX,
596
+ clientY: e.clientY,
597
+ button: e.button,
598
+ buttons: e.buttons,
599
+ ctrlKey: e.ctrlKey,
600
+ shiftKey: e.shiftKey,
601
+ altKey: e.altKey,
602
+ metaKey: e.metaKey
603
+ });
604
+ dispatchPointer("click", e);
605
+ }
606
+ function onDblClick(e) {
607
+ const { cellX, cellY } = toCell(e.clientX, e.clientY);
608
+ record?.({
609
+ type: "dblclick",
610
+ cellX,
611
+ cellY,
612
+ clientX: e.clientX,
613
+ clientY: e.clientY,
614
+ button: e.button,
615
+ buttons: e.buttons,
616
+ ctrlKey: e.ctrlKey,
617
+ shiftKey: e.shiftKey,
618
+ altKey: e.altKey,
619
+ metaKey: e.metaKey
620
+ });
621
+ dispatchPointer("dblclick", e);
622
+ }
623
+ function onContextMenu(e) {
624
+ const { cellX, cellY } = toCell(e.clientX, e.clientY);
625
+ record?.({
626
+ type: "contextmenu",
627
+ cellX,
628
+ cellY,
629
+ clientX: e.clientX,
630
+ clientY: e.clientY,
631
+ button: e.button,
632
+ buttons: e.buttons,
633
+ ctrlKey: e.ctrlKey,
634
+ shiftKey: e.shiftKey,
635
+ altKey: e.altKey,
636
+ metaKey: e.metaKey
637
+ });
638
+ const list = candidatesAt(cellX, cellY);
639
+ const target = pickTarget(list);
640
+ const path = target ? ancestorsForTarget(target) : [];
641
+ const ev = buildPointerEvent("contextmenu", path, e);
642
+ dispatchWithPhases("contextmenu", path, target, ev);
643
+ if (ev.defaultPrevented) e.preventDefault();
644
+ }
645
+ function onWheel(e) {
646
+ const { cellX, cellY } = toCell(e.clientX, e.clientY);
647
+ const list = candidatesAt(cellX, cellY);
648
+ if (list.length > 0) e.preventDefault();
649
+ record?.({
650
+ type: "wheel",
651
+ cellX,
652
+ cellY,
653
+ clientX: e.clientX,
654
+ clientY: e.clientY,
655
+ deltaY: e.deltaY,
656
+ ctrlKey: e.ctrlKey,
657
+ shiftKey: e.shiftKey,
658
+ altKey: e.altKey,
659
+ metaKey: e.metaKey,
660
+ deltaMode: e.deltaMode
661
+ });
662
+ dispatchPointer("wheel", e);
663
+ }
664
+ function onKeyDown(e) {
665
+ const targetIsTextInput = Boolean(textInputTarget && (e.target === textInputTarget || e.target instanceof Node && textInputTarget.contains(e.target)));
666
+ if (targetIsTextInput) {
667
+ const anyNative = e;
668
+ const isComposing = Boolean(anyNative.isComposing);
669
+ const keyCode = typeof anyNative.keyCode === "number" ? anyNative.keyCode : void 0;
670
+ const key = e.key;
671
+ const isImeKey = domComposing || isComposing || key === "Process" || key === "Unidentified" || keyCode === 229;
672
+ if (isImeKey) {
673
+ imeLog("keydown ignored (ime composing)", {
674
+ key,
675
+ code: e.code,
676
+ keyCode,
677
+ isComposing,
678
+ domComposing,
679
+ focusedId
680
+ });
681
+ return;
682
+ }
683
+ const isPlainTextKey = key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey;
684
+ if (isPlainTextKey) {
685
+ imeLog("keydown ignored (textInput)", {
686
+ key,
687
+ code: e.code,
688
+ keyCode,
689
+ isComposing,
690
+ domComposing,
691
+ focusedId
692
+ });
693
+ return;
694
+ }
695
+ }
696
+ record?.({
697
+ type: "keydown",
698
+ key: e.key,
699
+ code: e.code,
700
+ ctrlKey: e.ctrlKey,
701
+ shiftKey: e.shiftKey,
702
+ altKey: e.altKey,
703
+ metaKey: e.metaKey,
704
+ repeat: e.repeat
705
+ });
706
+ dispatchToFocused("keydown", e);
707
+ }
708
+ function onKeyUp(e) {
709
+ const targetIsTextInput = Boolean(textInputTarget && (e.target === textInputTarget || e.target instanceof Node && textInputTarget.contains(e.target)));
710
+ if (targetIsTextInput) {
711
+ const anyNative = e;
712
+ const isComposing = Boolean(anyNative.isComposing);
713
+ const keyCode = typeof anyNative.keyCode === "number" ? anyNative.keyCode : void 0;
714
+ const key = e.key;
715
+ const isImeKey = domComposing || isComposing || key === "Process" || key === "Unidentified" || keyCode === 229;
716
+ if (isImeKey) {
717
+ imeLog("keyup ignored (ime composing)", {
718
+ key,
719
+ code: e.code,
720
+ keyCode,
721
+ isComposing,
722
+ domComposing,
723
+ focusedId
724
+ });
725
+ return;
726
+ }
727
+ const isPlainTextKey = key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey;
728
+ if (isPlainTextKey) {
729
+ imeLog("keyup ignored (textInput)", {
730
+ key,
731
+ code: e.code,
732
+ keyCode,
733
+ isComposing,
734
+ domComposing,
735
+ focusedId
736
+ });
737
+ return;
738
+ }
739
+ }
740
+ record?.({
741
+ type: "keyup",
742
+ key: e.key,
743
+ code: e.code,
744
+ ctrlKey: e.ctrlKey,
745
+ shiftKey: e.shiftKey,
746
+ altKey: e.altKey,
747
+ metaKey: e.metaKey,
748
+ repeat: e.repeat
749
+ });
750
+ dispatchToFocused("keyup", e);
751
+ }
752
+ function onBeforeInput(e) {
753
+ const anyNative = e;
754
+ if (anyNative && typeof anyNative.isComposing === "boolean") domComposing = anyNative.isComposing;
755
+ const targetIsTextInput = Boolean(textInputTarget && (e.target === textInputTarget || e.target instanceof Node && textInputTarget.contains(e.target)));
756
+ const data = typeof anyNative.data === "string" ? anyNative.data : void 0;
757
+ const inputType = typeof anyNative.inputType === "string" ? anyNative.inputType : void 0;
758
+ const isPasteLike = inputType === "insertFromPaste" || inputType === "insertFromDrop";
759
+ if (targetIsTextInput && isPasteLike) {
760
+ anyNative?.preventDefault?.();
761
+ e?.preventDefault?.();
762
+ return;
763
+ }
764
+ const isLineBreakLike = inputType === "insertLineBreak" || inputType === "insertParagraph" || data?.includes("\n") && !isPasteLike;
765
+ if (targetIsTextInput && isLineBreakLike) {
766
+ anyNative?.preventDefault?.();
767
+ e?.preventDefault?.();
768
+ return;
769
+ }
770
+ record?.({
771
+ type: "beforeinput",
772
+ data,
773
+ inputType,
774
+ isComposing: Boolean(anyNative.isComposing)
775
+ });
776
+ dispatchToFocusedText("beforeinput", e);
777
+ }
778
+ function onInput(e) {
779
+ const anyNative = e;
780
+ if (anyNative && typeof anyNative.isComposing === "boolean") domComposing = anyNative.isComposing;
781
+ const targetIsTextInput = Boolean(textInputTarget && (e.target === textInputTarget || e.target instanceof Node && textInputTarget.contains(e.target)));
782
+ const data = typeof anyNative.data === "string" ? anyNative.data : void 0;
783
+ const inputType = typeof anyNative.inputType === "string" ? anyNative.inputType : void 0;
784
+ const isPasteLike = inputType === "insertFromPaste" || inputType === "insertFromDrop";
785
+ if (targetIsTextInput && isPasteLike) {
786
+ anyNative?.preventDefault?.();
787
+ e?.preventDefault?.();
788
+ return;
789
+ }
790
+ const isLineBreakLike = inputType === "insertLineBreak" || inputType === "insertParagraph" || data?.includes("\n") && !isPasteLike;
791
+ if (targetIsTextInput && isLineBreakLike) {
792
+ anyNative?.preventDefault?.();
793
+ e?.preventDefault?.();
794
+ return;
795
+ }
796
+ record?.({
797
+ type: "input",
798
+ data,
799
+ inputType,
800
+ isComposing: Boolean(anyNative.isComposing)
801
+ });
802
+ dispatchToFocusedText("input", e);
803
+ }
804
+ function onCompositionStart(e) {
805
+ const anyNative = e;
806
+ domComposing = true;
807
+ record?.({
808
+ type: "compositionstart",
809
+ data: typeof anyNative.data === "string" ? anyNative.data : void 0,
810
+ isComposing: Boolean(anyNative.isComposing)
811
+ });
812
+ imeLog("compositionstart", {
813
+ data: typeof anyNative.data === "string" ? anyNative.data : void 0,
814
+ isComposing: Boolean(anyNative.isComposing),
815
+ focusedId
816
+ });
817
+ dispatchToFocusedText("compositionstart", e);
818
+ }
819
+ function onCompositionUpdate(e) {
820
+ const anyNative = e;
821
+ record?.({
822
+ type: "compositionupdate",
823
+ data: typeof anyNative.data === "string" ? anyNative.data : void 0,
824
+ isComposing: Boolean(anyNative.isComposing)
825
+ });
826
+ imeLog("compositionupdate", {
827
+ data: typeof anyNative.data === "string" ? anyNative.data : void 0,
828
+ isComposing: Boolean(anyNative.isComposing),
829
+ focusedId
830
+ });
831
+ dispatchToFocusedText("compositionupdate", e);
832
+ }
833
+ function onCompositionEnd(e) {
834
+ const anyNative = e;
835
+ domComposing = false;
836
+ record?.({
837
+ type: "compositionend",
838
+ data: typeof anyNative.data === "string" ? anyNative.data : void 0,
839
+ isComposing: Boolean(anyNative.isComposing)
840
+ });
841
+ imeLog("compositionend", {
842
+ data: typeof anyNative.data === "string" ? anyNative.data : void 0,
843
+ isComposing: Boolean(anyNative.isComposing),
844
+ focusedId
845
+ });
846
+ dispatchToFocusedText("compositionend", e);
847
+ }
848
+ function onDragOver(e) {
849
+ e.preventDefault();
850
+ }
851
+ function onDrop(e) {
852
+ e.preventDefault();
853
+ let text = "";
854
+ if (e.dataTransfer) {
855
+ if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
856
+ const files = Array.from(e.dataTransfer.files);
857
+ const paths = files.map((file) => String(file?.path || file?.name || "").trim()).filter(Boolean);
858
+ text = paths.join("\n");
859
+ } else if (e.dataTransfer.types.includes("text/plain")) text = e.dataTransfer.getData("text/plain");
860
+ }
861
+ if (text) {
862
+ record?.({
863
+ type: "paste",
864
+ text
865
+ });
866
+ if (textInputTarget) try {
867
+ textInputTarget.focus?.({ preventScroll: true });
868
+ } catch {
869
+ textInputTarget.focus?.();
870
+ }
871
+ else try {
872
+ container.focus?.({ preventScroll: true });
873
+ } catch {
874
+ container.focus?.();
875
+ }
876
+ const focusableNodes = Array.from(nodes.values()).filter((n) => n.focusable && isVisible(n));
877
+ if (focusableNodes.length > 0) {
878
+ const targetNode = focusableNodes[0];
879
+ setFocus(targetNode.id);
880
+ const path = targetNode ? ancestorsForTarget(targetNode) : [];
881
+ const ev = buildInputEvent("paste", path, e);
882
+ ev.text = text;
883
+ dispatchWithPhases("paste", path, targetNode, ev);
884
+ }
885
+ }
886
+ }
887
+ function onPaste(e) {
888
+ const anyNative = e;
889
+ const clipboard = anyNative.clipboardData;
890
+ let text = "";
891
+ if (clipboard?.files && clipboard.files.length > 0) {
892
+ const file = clipboard.files[0];
893
+ text = file.path || file.name;
894
+ } else if (clipboard?.getData) text = clipboard.getData("text/plain") || clipboard.getData("text") || "";
895
+ record?.({
896
+ type: "paste",
897
+ text
898
+ });
899
+ if (focusedId) {
900
+ const targetNode = nodes.get(focusedId);
901
+ if (targetNode) {
902
+ const path = ancestorsForTarget(targetNode);
903
+ const ev = buildInputEvent("paste", path, e);
904
+ ev.text = text;
905
+ dispatchWithPhases("paste", path, targetNode, ev);
906
+ if (ev.defaultPrevented) {
907
+ anyNative?.preventDefault?.();
908
+ e?.preventDefault?.();
909
+ }
910
+ }
911
+ }
912
+ }
913
+ const textTargets = [container];
914
+ if (textInputTarget && textInputTarget !== container && !container.contains(textInputTarget)) textTargets.push(textInputTarget);
915
+ const keyboardTargets = [container];
916
+ if (textInputTarget && textInputTarget !== container && !container.contains(textInputTarget)) keyboardTargets.push(textInputTarget);
917
+ let attached = false;
918
+ function attach() {
919
+ if (attached) return;
920
+ attached = true;
921
+ container.addEventListener("pointerdown", onPointerDown);
922
+ container.addEventListener("pointermove", onPointerMove);
923
+ container.addEventListener("pointerup", onPointerUp);
924
+ container.addEventListener("mousedown", onMouseDown);
925
+ container.addEventListener("mousemove", onMouseMove);
926
+ container.addEventListener("mouseup", onMouseUp);
927
+ container.addEventListener("mouseleave", onMouseLeave);
928
+ container.addEventListener("click", onClick);
929
+ container.addEventListener("dblclick", onDblClick);
930
+ container.addEventListener("contextmenu", onContextMenu);
931
+ container.addEventListener("wheel", onWheel, { passive: false });
932
+ container.addEventListener("dragover", onDragOver);
933
+ container.addEventListener("drop", onDrop);
934
+ for (const target of keyboardTargets) {
935
+ target.addEventListener("keydown", onKeyDown);
936
+ target.addEventListener("keyup", onKeyUp);
937
+ }
938
+ for (const target of textTargets) {
939
+ target.addEventListener("beforeinput", onBeforeInput);
940
+ target.addEventListener("input", onInput);
941
+ target.addEventListener("compositionstart", onCompositionStart);
942
+ target.addEventListener("compositionupdate", onCompositionUpdate);
943
+ target.addEventListener("compositionend", onCompositionEnd);
944
+ target.addEventListener("paste", onPaste);
945
+ }
946
+ window.addEventListener("scroll", markContainerRectDirty, {
947
+ capture: true,
948
+ passive: true
949
+ });
950
+ window.addEventListener("resize", markContainerRectDirty, { passive: true });
951
+ }
952
+ if (!options?.deferAttach) attach();
953
+ return {
954
+ register(node) {
955
+ const id = node.id ?? `n${nextId++}`;
956
+ const focusable = node.focusable;
957
+ const full = {
958
+ id,
959
+ rect: node.rect,
960
+ zIndex: node.zIndex ?? 0,
961
+ visible: node.visible ?? true,
962
+ focusable,
963
+ selectable: node.selectable ?? !focusable,
964
+ selectionScrollBy: node.selectionScrollBy,
965
+ handlers: node.handlers ?? {}
966
+ };
967
+ if (nodes.has(id)) removeFromRowBuckets(id);
968
+ nodes.set(id, full);
969
+ addToRowBuckets(id, full);
970
+ return full;
971
+ },
972
+ update(id, next) {
973
+ const prev = nodes.get(id);
974
+ if (!prev) return;
975
+ const nextVisible = next.visible ?? prev.visible;
976
+ if (nextVisible === false) {
977
+ if (focusedId === id) setFocus(null);
978
+ if (capturedId === id) capturedId = null;
979
+ if (hoverPath.some((n) => n.id === id)) hoverPath = [];
980
+ }
981
+ nodes.set(id, {
982
+ ...prev,
983
+ ...next,
984
+ rect: next.rect ?? prev.rect,
985
+ zIndex: next.zIndex ?? prev.zIndex,
986
+ visible: nextVisible,
987
+ handlers: next.handlers ?? prev.handlers
988
+ });
989
+ const updated = nodes.get(id);
990
+ if (updated) updateRowBuckets(id, updated);
991
+ },
992
+ unregister(id) {
993
+ if (capturedId === id) capturedId = null;
994
+ if (hoverPath.some((n) => n.id === id)) hoverPath = [];
995
+ removeFromRowBuckets(id);
996
+ nodes.delete(id);
997
+ if (focusedId === id) setFocus(null);
998
+ },
999
+ setMetrics(next) {
1000
+ currentMetrics = next;
1001
+ markContainerRectDirty();
1002
+ },
1003
+ canSelectAt(cellX, cellY) {
1004
+ const list = candidatesAt(cellX, cellY);
1005
+ const target = pickTarget(list);
1006
+ const lockNode = resolveModalLockNode();
1007
+ if (lockNode) {
1008
+ if (!target) return false;
1009
+ if (!isAllowedModalPointerNode(target, target, lockNode)) return false;
1010
+ }
1011
+ return target ? Boolean(target.selectable) : true;
1012
+ },
1013
+ autoScrollSelectionAt(originCellX, originCellY, pointerCellY) {
1014
+ const target = pickTarget(candidatesAt(originCellX, originCellY));
1015
+ if (!target) return 0;
1016
+ const lockNode = resolveModalLockNode();
1017
+ if (lockNode && !isAllowedModalPointerNode(target, target, lockNode)) return 0;
1018
+ const path = ancestorsForTarget(target);
1019
+ let owner = null;
1020
+ for (let i = path.length - 1; i >= 0; i--) {
1021
+ const node = path[i];
1022
+ if (typeof node.selectionScrollBy === "function") {
1023
+ owner = node;
1024
+ break;
1025
+ }
1026
+ }
1027
+ if (!owner) return 0;
1028
+ const rect = owner.rect;
1029
+ const y = Math.floor(pointerCellY);
1030
+ let delta = 0;
1031
+ if (y <= rect.y) delta = -1;
1032
+ else if (y >= rect.y + rect.h - 1) delta = 1;
1033
+ if (!delta) return 0;
1034
+ const scrolled = owner.selectionScrollBy?.(delta);
1035
+ return scrolled === false ? 0 : delta;
1036
+ },
1037
+ focus(id) {
1038
+ setFocus(id);
1039
+ },
1040
+ getFocused() {
1041
+ return focusedId;
1042
+ },
1043
+ debugNodes() {
1044
+ return Array.from(nodes.values()).map((n) => ({
1045
+ id: n.id,
1046
+ rect: n.rect,
1047
+ zIndex: n.zIndex,
1048
+ visible: isVisible(n),
1049
+ focusable: Boolean(n.focusable)
1050
+ }));
1051
+ },
1052
+ attach,
1053
+ dispose() {
1054
+ window.removeEventListener("scroll", markContainerRectDirty, true);
1055
+ window.removeEventListener("resize", markContainerRectDirty);
1056
+ if (!attached) return;
1057
+ attached = false;
1058
+ container.removeEventListener("pointerdown", onPointerDown);
1059
+ container.removeEventListener("pointermove", onPointerMove);
1060
+ container.removeEventListener("pointerup", onPointerUp);
1061
+ container.removeEventListener("mousedown", onMouseDown);
1062
+ container.removeEventListener("mousemove", onMouseMove);
1063
+ container.removeEventListener("mouseup", onMouseUp);
1064
+ container.removeEventListener("mouseleave", onMouseLeave);
1065
+ container.removeEventListener("click", onClick);
1066
+ container.removeEventListener("dblclick", onDblClick);
1067
+ container.removeEventListener("contextmenu", onContextMenu);
1068
+ container.removeEventListener("wheel", onWheel);
1069
+ for (const target of keyboardTargets) {
1070
+ target.removeEventListener("keydown", onKeyDown);
1071
+ target.removeEventListener("keyup", onKeyUp);
1072
+ }
1073
+ for (const target of textTargets) {
1074
+ target.removeEventListener("beforeinput", onBeforeInput);
1075
+ target.removeEventListener("input", onInput);
1076
+ target.removeEventListener("compositionstart", onCompositionStart);
1077
+ target.removeEventListener("compositionupdate", onCompositionUpdate);
1078
+ target.removeEventListener("compositionend", onCompositionEnd);
1079
+ target.removeEventListener("paste", onPaste);
1080
+ }
1081
+ rowBuckets.clear();
1082
+ rowRangeById.clear();
1083
+ nodes.clear();
1084
+ focusedId = null;
1085
+ capturedId = null;
1086
+ hoverPath = [];
1087
+ }
1088
+ };
1089
+ }
1090
+
1091
+ //#endregion
1092
+ //#region src/runtime/index.ts
1093
+ function isNodeLike() {
1094
+ const proc = globalThis.process;
1095
+ return typeof proc?.versions?.node === "string";
1096
+ }
1097
+ function detectEnv() {
1098
+ const isBrowser = typeof window !== "undefined" && typeof document !== "undefined";
1099
+ if (isBrowser) return "browser";
1100
+ if (isNodeLike()) return "terminal";
1101
+ return "unknown";
1102
+ }
1103
+ function createUnsupportedClipboard() {
1104
+ return {
1105
+ supported: false,
1106
+ async readText() {
1107
+ throw new Error("Clipboard not available in this runtime");
1108
+ },
1109
+ async writeText() {
1110
+ throw new Error("Clipboard not available in this runtime");
1111
+ }
1112
+ };
1113
+ }
1114
+ function createClipboard(kind) {
1115
+ if (kind === "browser") {
1116
+ const supported = typeof navigator !== "undefined" && !!navigator.clipboard?.writeText && !!navigator.clipboard?.readText;
1117
+ return {
1118
+ supported,
1119
+ async readText() {
1120
+ if (!supported) throw new Error("Clipboard not available in this runtime");
1121
+ return navigator.clipboard.readText();
1122
+ },
1123
+ async writeText(text) {
1124
+ if (!supported) throw new Error("Clipboard not available in this runtime");
1125
+ await navigator.clipboard.writeText(text);
1126
+ }
1127
+ };
1128
+ }
1129
+ return createUnsupportedClipboard();
1130
+ }
1131
+ function nowMs() {
1132
+ return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
1133
+ }
1134
+ function createRaf(kind, timer) {
1135
+ const g = globalThis;
1136
+ if (kind === "browser" && typeof g.requestAnimationFrame === "function" && typeof g.cancelAnimationFrame === "function") return {
1137
+ request: (cb) => g.requestAnimationFrame(cb),
1138
+ cancel: (id) => g.cancelAnimationFrame(id)
1139
+ };
1140
+ return {
1141
+ request(cb) {
1142
+ return timer.setTimeout(() => cb(nowMs()), 16);
1143
+ },
1144
+ cancel(id) {
1145
+ timer.clearTimeout(id);
1146
+ }
1147
+ };
1148
+ }
1149
+ function createMeasureText(kind) {
1150
+ if (kind !== "browser") return () => null;
1151
+ return (text, opts) => {
1152
+ try {
1153
+ const doc = typeof document !== "undefined" ? document : null;
1154
+ if (!doc || !("createElement" in doc)) return null;
1155
+ const canvas = doc.createElement("canvas");
1156
+ const ctx = canvas?.getContext?.("2d");
1157
+ if (!ctx) return null;
1158
+ if (opts?.font) ctx.font = opts.font;
1159
+ const m = ctx.measureText(text);
1160
+ return typeof m.width === "number" && Number.isFinite(m.width) ? m.width : null;
1161
+ } catch {
1162
+ return null;
1163
+ }
1164
+ };
1165
+ }
1166
+ function createRuntime(kind = detectEnv(), options = {}) {
1167
+ const timer = {
1168
+ setTimeout: globalThis.setTimeout.bind(globalThis),
1169
+ clearTimeout: globalThis.clearTimeout.bind(globalThis),
1170
+ setInterval: globalThis.setInterval.bind(globalThis),
1171
+ clearInterval: globalThis.clearInterval.bind(globalThis)
1172
+ };
1173
+ const env = Object.freeze({
1174
+ kind,
1175
+ isBrowser: kind === "browser",
1176
+ isTerminal: kind === "terminal"
1177
+ });
1178
+ return {
1179
+ env,
1180
+ now() {
1181
+ return nowMs();
1182
+ },
1183
+ timer,
1184
+ raf: createRaf(kind, timer),
1185
+ clipboard: options.clipboard ?? createClipboard(kind),
1186
+ getWindow() {
1187
+ return env.isBrowser && typeof window !== "undefined" ? window : null;
1188
+ },
1189
+ getDocument() {
1190
+ return env.isBrowser && typeof document !== "undefined" ? document : null;
1191
+ },
1192
+ measureText: createMeasureText(kind)
1193
+ };
1194
+ }
1195
+
1196
+ //#endregion
1197
+ export { SUPPRESS_TERMINAL_POINTER_DOWN, SUPPRESS_TERMINAL_POINTER_MOVE, SUPPRESS_TERMINAL_POINTER_UP, createEventManager, createRuntime };