@usecrow/client 0.1.21 → 0.1.26

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.
@@ -0,0 +1,1377 @@
1
+ async function waitFor(e) {
2
+ await new Promise((n) => setTimeout(n, e * 1e3));
3
+ }
4
+ async function movePointerToElement(e) {
5
+ const n = e.getBoundingClientRect(), s = n.left + n.width / 2, i = n.top + n.height / 2;
6
+ window.dispatchEvent(new CustomEvent("PageAgent::MovePointerTo", { detail: { x: s, y: i } })), await waitFor(0.3);
7
+ }
8
+ function getElementByIndex(e, n) {
9
+ const s = e.get(n);
10
+ if (!s)
11
+ throw new Error(`No interactive element found at index ${n}`);
12
+ const i = s.ref;
13
+ if (!i)
14
+ throw new Error(`Element at index ${n} does not have a reference`);
15
+ if (!(i instanceof HTMLElement))
16
+ throw new Error(`Element at index ${n} is not an HTMLElement`);
17
+ return i;
18
+ }
19
+ let lastClickedElement = null;
20
+ function blurLastClickedElement() {
21
+ lastClickedElement && (lastClickedElement.blur(), lastClickedElement.dispatchEvent(
22
+ new MouseEvent("mouseout", { bubbles: !0, cancelable: !0 })
23
+ ), lastClickedElement = null);
24
+ }
25
+ async function clickElement(e) {
26
+ blurLastClickedElement(), lastClickedElement = e, await scrollIntoViewIfNeeded(e), await movePointerToElement(e), window.dispatchEvent(new CustomEvent("PageAgent::ClickPointer")), await waitFor(0.1), e.dispatchEvent(new MouseEvent("mouseenter", { bubbles: !0, cancelable: !0 })), e.dispatchEvent(new MouseEvent("mouseover", { bubbles: !0, cancelable: !0 })), e.dispatchEvent(new MouseEvent("mousedown", { bubbles: !0, cancelable: !0 })), e.focus(), e.dispatchEvent(new MouseEvent("mouseup", { bubbles: !0, cancelable: !0 })), e.dispatchEvent(new MouseEvent("click", { bubbles: !0, cancelable: !0 })), await waitFor(0.1);
27
+ }
28
+ const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
29
+ window.HTMLInputElement.prototype,
30
+ "value"
31
+ ).set, nativeTextAreaValueSetter = Object.getOwnPropertyDescriptor(
32
+ window.HTMLTextAreaElement.prototype,
33
+ "value"
34
+ ).set;
35
+ async function inputTextElement(e, n) {
36
+ if (!(e instanceof HTMLInputElement || e instanceof HTMLTextAreaElement))
37
+ throw new Error("Element is not an input or textarea");
38
+ await clickElement(e), e instanceof HTMLTextAreaElement ? nativeTextAreaValueSetter.call(e, n) : nativeInputValueSetter.call(e, n);
39
+ const s = new Event("input", { bubbles: !0 });
40
+ e.dispatchEvent(s), await waitFor(0.1), blurLastClickedElement();
41
+ }
42
+ async function selectOptionElement(e, n) {
43
+ if (!(e instanceof HTMLSelectElement))
44
+ throw new Error("Element is not a select element");
45
+ const i = Array.from(e.options).find((b) => {
46
+ var d;
47
+ return ((d = b.textContent) == null ? void 0 : d.trim()) === n.trim();
48
+ });
49
+ if (!i)
50
+ throw new Error(`Option with text "${n}" not found in select element`);
51
+ e.value = i.value, e.dispatchEvent(new Event("change", { bubbles: !0 })), await waitFor(0.1);
52
+ }
53
+ async function scrollIntoViewIfNeeded(e) {
54
+ const n = e;
55
+ n.scrollIntoViewIfNeeded ? n.scrollIntoViewIfNeeded() : n.scrollIntoView({ behavior: "auto", block: "center", inline: "nearest" });
56
+ }
57
+ async function scrollVertically(e, n, s) {
58
+ if (s) {
59
+ const l = s;
60
+ console.log(
61
+ "[SCROLL DEBUG] Starting direct container scroll for element:",
62
+ l.tagName
63
+ );
64
+ let h = l, v = !1, w = null, u = 0, f = 0;
65
+ const T = n;
66
+ for (; h && f < 10; ) {
67
+ const F = window.getComputedStyle(h), P = /(auto|scroll|overlay)/.test(F.overflowY), O = h.scrollHeight > h.clientHeight;
68
+ if (console.log(
69
+ "[SCROLL DEBUG] Checking element:",
70
+ h.tagName,
71
+ "hasScrollableY:",
72
+ P,
73
+ "canScrollVertically:",
74
+ O,
75
+ "scrollHeight:",
76
+ h.scrollHeight,
77
+ "clientHeight:",
78
+ h.clientHeight
79
+ ), P && O) {
80
+ const R = h.scrollTop, z = h.scrollHeight - h.clientHeight;
81
+ let H = T / 3;
82
+ H > 0 ? H = Math.min(H, z - R) : H = Math.max(H, -R), h.scrollTop = R + H;
83
+ const D = h.scrollTop, _ = D - R;
84
+ if (console.log(
85
+ "[SCROLL DEBUG] Scroll attempt:",
86
+ h.tagName,
87
+ "before:",
88
+ R,
89
+ "after:",
90
+ D,
91
+ "delta:",
92
+ _
93
+ ), Math.abs(_) > 0.5) {
94
+ v = !0, w = h, u = _, console.log(
95
+ "[SCROLL DEBUG] Successfully scrolled container:",
96
+ h.tagName,
97
+ "delta:",
98
+ _
99
+ );
100
+ break;
101
+ }
102
+ }
103
+ if (h === document.body || h === document.documentElement)
104
+ break;
105
+ h = h.parentElement, f++;
106
+ }
107
+ return v ? `Scrolled container (${w == null ? void 0 : w.tagName}) by ${u}px` : `No scrollable container found for element (${l.tagName})`;
108
+ }
109
+ const i = n, b = (l) => l.clientHeight >= window.innerHeight * 0.5, d = (l) => l && /(auto|scroll|overlay)/.test(getComputedStyle(l).overflowY) && l.scrollHeight > l.clientHeight && b(l);
110
+ let r = document.activeElement;
111
+ for (; r && !d(r) && r !== document.body; ) r = r.parentElement;
112
+ if (r = d(r) ? r : Array.from(document.querySelectorAll("*")).find(d) || document.scrollingElement || document.documentElement, r === document.scrollingElement || r === document.documentElement || r === document.body) {
113
+ const l = window.scrollY, h = document.documentElement.scrollHeight - window.innerHeight;
114
+ window.scrollBy(0, i);
115
+ const v = window.scrollY, w = v - l;
116
+ if (Math.abs(w) < 1)
117
+ return i > 0 ? "⚠️ Already at the bottom of the page, cannot scroll down further." : "⚠️ Already at the top of the page, cannot scroll up further.";
118
+ const u = i > 0 && v >= h - 1, f = i < 0 && v <= 1;
119
+ return u ? `✅ Scrolled page by ${w}px. Reached the bottom of the page.` : f ? `✅ Scrolled page by ${w}px. Reached the top of the page.` : `✅ Scrolled page by ${w}px.`;
120
+ } else {
121
+ const l = r.scrollTop, h = r.scrollHeight - r.clientHeight;
122
+ r.scrollBy({ top: i, behavior: "smooth" }), await waitFor(0.1);
123
+ const v = r.scrollTop, w = v - l;
124
+ if (Math.abs(w) < 1)
125
+ return i > 0 ? `⚠️ Already at the bottom of container (${r.tagName}), cannot scroll down further.` : `⚠️ Already at the top of container (${r.tagName}), cannot scroll up further.`;
126
+ const u = i > 0 && v >= h - 1, f = i < 0 && v <= 1;
127
+ return u ? `✅ Scrolled container (${r.tagName}) by ${w}px. Reached the bottom.` : f ? `✅ Scrolled container (${r.tagName}) by ${w}px. Reached the top.` : `✅ Scrolled container (${r.tagName}) by ${w}px.`;
128
+ }
129
+ }
130
+ async function scrollHorizontally(e, n, s) {
131
+ if (s) {
132
+ const l = s;
133
+ console.log(
134
+ "[SCROLL DEBUG] Starting direct container scroll for element:",
135
+ l.tagName
136
+ );
137
+ let h = l, v = !1, w = null, u = 0, f = 0;
138
+ const T = e ? n : -n;
139
+ for (; h && f < 10; ) {
140
+ const F = window.getComputedStyle(h), P = /(auto|scroll|overlay)/.test(F.overflowX), O = h.scrollWidth > h.clientWidth;
141
+ if (console.log(
142
+ "[SCROLL DEBUG] Checking element:",
143
+ h.tagName,
144
+ "hasScrollableX:",
145
+ P,
146
+ "canScrollHorizontally:",
147
+ O,
148
+ "scrollWidth:",
149
+ h.scrollWidth,
150
+ "clientWidth:",
151
+ h.clientWidth
152
+ ), P && O) {
153
+ const R = h.scrollLeft, z = h.scrollWidth - h.clientWidth;
154
+ let H = T / 3;
155
+ H > 0 ? H = Math.min(H, z - R) : H = Math.max(H, -R), h.scrollLeft = R + H;
156
+ const D = h.scrollLeft, _ = D - R;
157
+ if (console.log(
158
+ "[SCROLL DEBUG] Scroll attempt:",
159
+ h.tagName,
160
+ "before:",
161
+ R,
162
+ "after:",
163
+ D,
164
+ "delta:",
165
+ _
166
+ ), Math.abs(_) > 0.5) {
167
+ v = !0, w = h, u = _, console.log(
168
+ "[SCROLL DEBUG] Successfully scrolled container:",
169
+ h.tagName,
170
+ "delta:",
171
+ _
172
+ );
173
+ break;
174
+ }
175
+ }
176
+ if (h === document.body || h === document.documentElement)
177
+ break;
178
+ h = h.parentElement, f++;
179
+ }
180
+ return v ? `Scrolled container (${w == null ? void 0 : w.tagName}) horizontally by ${u}px` : `No horizontally scrollable container found for element (${l.tagName})`;
181
+ }
182
+ const i = e ? n : -n, b = (l) => l.clientWidth >= window.innerWidth * 0.5, d = (l) => l && /(auto|scroll|overlay)/.test(getComputedStyle(l).overflowX) && l.scrollWidth > l.clientWidth && b(l);
183
+ let r = document.activeElement;
184
+ for (; r && !d(r) && r !== document.body; ) r = r.parentElement;
185
+ if (r = d(r) ? r : Array.from(document.querySelectorAll("*")).find(d) || document.scrollingElement || document.documentElement, r === document.scrollingElement || r === document.documentElement || r === document.body) {
186
+ const l = window.scrollX, h = document.documentElement.scrollWidth - window.innerWidth;
187
+ window.scrollBy(i, 0);
188
+ const v = window.scrollX, w = v - l;
189
+ if (Math.abs(w) < 1)
190
+ return i > 0 ? "⚠️ Already at the right edge of the page, cannot scroll right further." : "⚠️ Already at the left edge of the page, cannot scroll left further.";
191
+ const u = i > 0 && v >= h - 1, f = i < 0 && v <= 1;
192
+ return u ? `✅ Scrolled page by ${w}px. Reached the right edge of the page.` : f ? `✅ Scrolled page by ${w}px. Reached the left edge of the page.` : `✅ Scrolled page horizontally by ${w}px.`;
193
+ } else {
194
+ const l = r.scrollLeft, h = r.scrollWidth - r.clientWidth;
195
+ r.scrollBy({ left: i, behavior: "smooth" }), await waitFor(0.1);
196
+ const v = r.scrollLeft, w = v - l;
197
+ if (Math.abs(w) < 1)
198
+ return i > 0 ? `⚠️ Already at the right edge of container (${r.tagName}), cannot scroll right further.` : `⚠️ Already at the left edge of container (${r.tagName}), cannot scroll left further.`;
199
+ const u = i > 0 && v >= h - 1, f = i < 0 && v <= 1;
200
+ return u ? `✅ Scrolled container (${r.tagName}) by ${w}px. Reached the right edge.` : f ? `✅ Scrolled container (${r.tagName}) by ${w}px. Reached the left edge.` : `✅ Scrolled container (${r.tagName}) horizontally by ${w}px.`;
201
+ }
202
+ }
203
+ const VIEWPORT_EXPANSION = -1, domTree = (e = {
204
+ doHighlightElements: !0,
205
+ focusHighlightIndex: -1,
206
+ viewportExpansion: 0,
207
+ debugMode: !1,
208
+ /**
209
+ * @edit
210
+ */
211
+ /** @type {Element[]} */
212
+ interactiveBlacklist: [],
213
+ /** @type {Element[]} */
214
+ interactiveWhitelist: [],
215
+ highlightOpacity: 0.1,
216
+ highlightLabelOpacity: 0.5
217
+ }) => {
218
+ const { interactiveBlacklist: n, interactiveWhitelist: s, highlightOpacity: i, highlightLabelOpacity: b } = e, { doHighlightElements: d, focusHighlightIndex: r, viewportExpansion: l, debugMode: h } = e;
219
+ let v = 0;
220
+ const w = /* @__PURE__ */ new WeakMap();
221
+ function u(t, o) {
222
+ !t || t.nodeType !== Node.ELEMENT_NODE || w.set(t, { ...w.get(t), ...o });
223
+ }
224
+ const f = {
225
+ boundingRects: /* @__PURE__ */ new WeakMap(),
226
+ clientRects: /* @__PURE__ */ new WeakMap(),
227
+ computedStyles: /* @__PURE__ */ new WeakMap(),
228
+ clearCache: () => {
229
+ f.boundingRects = /* @__PURE__ */ new WeakMap(), f.clientRects = /* @__PURE__ */ new WeakMap(), f.computedStyles = /* @__PURE__ */ new WeakMap();
230
+ }
231
+ };
232
+ function T(t) {
233
+ if (!t) return null;
234
+ if (f.boundingRects.has(t))
235
+ return f.boundingRects.get(t);
236
+ const o = t.getBoundingClientRect();
237
+ return o && f.boundingRects.set(t, o), o;
238
+ }
239
+ function F(t) {
240
+ if (!t) return null;
241
+ if (f.computedStyles.has(t))
242
+ return f.computedStyles.get(t);
243
+ const o = window.getComputedStyle(t);
244
+ return o && f.computedStyles.set(t, o), o;
245
+ }
246
+ function P(t) {
247
+ if (!t) return null;
248
+ if (f.clientRects.has(t))
249
+ return f.clientRects.get(t);
250
+ const o = t.getClientRects();
251
+ return o && f.clientRects.set(t, o), o;
252
+ }
253
+ const O = {}, R = { current: 0 }, z = "playwright-highlight-container";
254
+ function H(t, o, p = null) {
255
+ if (!t) return o;
256
+ const a = [];
257
+ let c = null, x = 20, E = 16, M = null;
258
+ try {
259
+ let m = document.getElementById(z);
260
+ m || (m = document.createElement("div"), m.id = z, m.style.position = "fixed", m.style.pointerEvents = "none", m.style.top = "0", m.style.left = "0", m.style.width = "100%", m.style.height = "100%", m.style.zIndex = "2147483640", m.style.backgroundColor = "transparent", document.body.appendChild(m));
261
+ const L = t.getClientRects();
262
+ if (!L || L.length === 0) return o;
263
+ const A = [
264
+ "#FF0000",
265
+ "#00FF00",
266
+ "#0000FF",
267
+ "#FFA500",
268
+ "#800080",
269
+ "#008080",
270
+ "#FF69B4",
271
+ "#4B0082",
272
+ "#FF4500",
273
+ "#2E8B57",
274
+ "#DC143C",
275
+ "#4682B4"
276
+ ], g = o % A.length;
277
+ let y = A[g];
278
+ const k = y + Math.floor(i * 255).toString(16).padStart(2, "0");
279
+ y = y + Math.floor(b * 255).toString(16).padStart(2, "0");
280
+ let S = { x: 0, y: 0 };
281
+ if (p) {
282
+ const I = p.getBoundingClientRect();
283
+ S.x = I.left, S.y = I.top;
284
+ }
285
+ const B = document.createDocumentFragment();
286
+ for (const I of L) {
287
+ if (I.width === 0 || I.height === 0) continue;
288
+ const $ = document.createElement("div");
289
+ $.style.position = "fixed", $.style.border = `2px solid ${y}`, $.style.backgroundColor = k, $.style.pointerEvents = "none", $.style.boxSizing = "border-box";
290
+ const N = I.top + S.y, q = I.left + S.x;
291
+ $.style.top = `${N}px`, $.style.left = `${q}px`, $.style.width = `${I.width}px`, $.style.height = `${I.height}px`, B.appendChild($), a.push({ element: $, initialRect: I });
292
+ }
293
+ const G = L[0];
294
+ c = document.createElement("div"), c.className = "playwright-highlight-label", c.style.position = "fixed", c.style.background = y, c.style.color = "white", c.style.padding = "1px 4px", c.style.borderRadius = "4px", c.style.fontSize = `${Math.min(12, Math.max(8, G.height / 2))}px`, c.textContent = o.toString(), x = c.offsetWidth > 0 ? c.offsetWidth : x, E = c.offsetHeight > 0 ? c.offsetHeight : E;
295
+ const Y = G.top + S.y, Z = G.left + S.x;
296
+ let j = Y + 2, J = Z + G.width - x - 2;
297
+ (G.width < x + 4 || G.height < E + 4) && (j = Y - E - 2, J = Z + G.width - x, J < S.x && (J = Z)), j = Math.max(0, Math.min(j, window.innerHeight - E)), J = Math.max(0, Math.min(J, window.innerWidth - x)), c.style.top = `${j}px`, c.style.left = `${J}px`, B.appendChild(c);
298
+ const it = ((I, $) => {
299
+ let N = 0;
300
+ return (...q) => {
301
+ const V = performance.now();
302
+ if (!(V - N < $))
303
+ return N = V, I(...q);
304
+ };
305
+ })(() => {
306
+ const I = t.getClientRects();
307
+ let $ = { x: 0, y: 0 };
308
+ if (p) {
309
+ const N = p.getBoundingClientRect();
310
+ $.x = N.left, $.y = N.top;
311
+ }
312
+ if (a.forEach((N, q) => {
313
+ if (q < I.length) {
314
+ const V = I[q], et = V.top + $.y, K = V.left + $.x;
315
+ N.element.style.top = `${et}px`, N.element.style.left = `${K}px`, N.element.style.width = `${V.width}px`, N.element.style.height = `${V.height}px`, N.element.style.display = V.width === 0 || V.height === 0 ? "none" : "block";
316
+ } else
317
+ N.element.style.display = "none";
318
+ }), I.length < a.length)
319
+ for (let N = I.length; N < a.length; N++)
320
+ a[N].element.style.display = "none";
321
+ if (c && I.length > 0) {
322
+ const N = I[0], q = N.top + $.y, V = N.left + $.x;
323
+ let et = q + 2, K = V + N.width - x - 2;
324
+ (N.width < x + 4 || N.height < E + 4) && (et = q - E - 2, K = V + N.width - x, K < $.x && (K = V)), et = Math.max(0, Math.min(et, window.innerHeight - E)), K = Math.max(0, Math.min(K, window.innerWidth - x)), c.style.top = `${et}px`, c.style.left = `${K}px`, c.style.display = "block";
325
+ } else c && (c.style.display = "none");
326
+ }, 16);
327
+ return window.addEventListener("scroll", it, !0), window.addEventListener("resize", it), M = () => {
328
+ window.removeEventListener("scroll", it, !0), window.removeEventListener("resize", it), a.forEach((I) => I.element.remove()), c && c.remove();
329
+ }, m.appendChild(B), o + 1;
330
+ } finally {
331
+ M && (window._highlightCleanupFunctions = window._highlightCleanupFunctions || []).push(
332
+ M
333
+ );
334
+ }
335
+ }
336
+ function D(t) {
337
+ if (!t || t.nodeType !== Node.ELEMENT_NODE)
338
+ return null;
339
+ const o = F(t);
340
+ if (!o) return null;
341
+ const p = o.display;
342
+ if (p === "inline" || p === "inline-block")
343
+ return null;
344
+ const a = o.overflowX, c = o.overflowY, x = a === "auto" || a === "scroll", E = c === "auto" || c === "scroll";
345
+ if (!x && !E)
346
+ return null;
347
+ const M = t.scrollWidth - t.clientWidth, m = t.scrollHeight - t.clientHeight, L = 4;
348
+ if (M < L && m < L || !E && M < L || !x && m < L)
349
+ return null;
350
+ const A = t.scrollTop, g = t.scrollLeft, y = t.scrollWidth - t.clientWidth - t.scrollLeft, k = t.scrollHeight - t.clientHeight - t.scrollTop, S = {
351
+ top: A,
352
+ right: y,
353
+ bottom: k,
354
+ left: g
355
+ };
356
+ return u(t, {
357
+ scrollable: !0,
358
+ scrollData: S
359
+ }), S;
360
+ }
361
+ function _(t) {
362
+ try {
363
+ if (l === -1) {
364
+ const E = t.parentElement;
365
+ if (!E) return !1;
366
+ try {
367
+ return E.checkVisibility({
368
+ checkOpacity: !0,
369
+ checkVisibilityCSS: !0
370
+ });
371
+ } catch {
372
+ const m = window.getComputedStyle(E);
373
+ return m.display !== "none" && m.visibility !== "hidden" && m.opacity !== "0";
374
+ }
375
+ }
376
+ const o = document.createRange();
377
+ o.selectNodeContents(t);
378
+ const p = o.getClientRects();
379
+ if (!p || p.length === 0)
380
+ return !1;
381
+ let a = !1, c = !1;
382
+ for (const E of p)
383
+ if (E.width > 0 && E.height > 0 && (a = !0, !(E.bottom < -l || E.top > window.innerHeight + l || E.right < -l || E.left > window.innerWidth + l))) {
384
+ c = !0;
385
+ break;
386
+ }
387
+ if (!a || !c)
388
+ return !1;
389
+ const x = t.parentElement;
390
+ if (!x) return !1;
391
+ try {
392
+ return x.checkVisibility({
393
+ checkOpacity: !0,
394
+ checkVisibilityCSS: !0
395
+ });
396
+ } catch {
397
+ const M = window.getComputedStyle(x);
398
+ return M.display !== "none" && M.visibility !== "hidden" && M.opacity !== "0";
399
+ }
400
+ } catch (o) {
401
+ return console.warn("Error checking text node visibility:", o), !1;
402
+ }
403
+ }
404
+ function rt(t) {
405
+ if (!t || !t.tagName) return !1;
406
+ const o = /* @__PURE__ */ new Set([
407
+ "body",
408
+ "div",
409
+ "main",
410
+ "article",
411
+ "section",
412
+ "nav",
413
+ "header",
414
+ "footer"
415
+ ]), p = t.tagName.toLowerCase();
416
+ return o.has(p) ? !0 : !(/* @__PURE__ */ new Set([
417
+ "svg",
418
+ "script",
419
+ "style",
420
+ "link",
421
+ "meta",
422
+ "noscript",
423
+ "template"
424
+ ])).has(p);
425
+ }
426
+ function U(t) {
427
+ const o = F(t);
428
+ return t.offsetWidth > 0 && t.offsetHeight > 0 && (o == null ? void 0 : o.visibility) !== "hidden" && (o == null ? void 0 : o.display) !== "none";
429
+ }
430
+ function C(t) {
431
+ var k, S;
432
+ if (!t || t.nodeType !== Node.ELEMENT_NODE || n.includes(t))
433
+ return !1;
434
+ if (s.includes(t))
435
+ return !0;
436
+ const o = t.tagName.toLowerCase(), p = F(t), a = /* @__PURE__ */ new Set([
437
+ "pointer",
438
+ // Link/clickable elements
439
+ "move",
440
+ // Movable elements
441
+ "text",
442
+ // Text selection
443
+ "grab",
444
+ // Grabbable elements
445
+ "grabbing",
446
+ // Currently grabbing
447
+ "cell",
448
+ // Table cell selection
449
+ "copy",
450
+ // Copy operation
451
+ "alias",
452
+ // Alias creation
453
+ "all-scroll",
454
+ // Scrollable content
455
+ "col-resize",
456
+ // Column resize
457
+ "context-menu",
458
+ // Context menu available
459
+ "crosshair",
460
+ // Precise selection
461
+ "e-resize",
462
+ // East resize
463
+ "ew-resize",
464
+ // East-west resize
465
+ "help",
466
+ // Help available
467
+ "n-resize",
468
+ // North resize
469
+ "ne-resize",
470
+ // Northeast resize
471
+ "nesw-resize",
472
+ // Northeast-southwest resize
473
+ "ns-resize",
474
+ // North-south resize
475
+ "nw-resize",
476
+ // Northwest resize
477
+ "nwse-resize",
478
+ // Northwest-southeast resize
479
+ "row-resize",
480
+ // Row resize
481
+ "s-resize",
482
+ // South resize
483
+ "se-resize",
484
+ // Southeast resize
485
+ "sw-resize",
486
+ // Southwest resize
487
+ "vertical-text",
488
+ // Vertical text selection
489
+ "w-resize",
490
+ // West resize
491
+ "zoom-in",
492
+ // Zoom in
493
+ "zoom-out"
494
+ // Zoom out
495
+ ]), c = /* @__PURE__ */ new Set([
496
+ "not-allowed",
497
+ // Action not allowed
498
+ "no-drop",
499
+ // Drop not allowed
500
+ "wait",
501
+ // Processing
502
+ "progress",
503
+ // In progress
504
+ "initial",
505
+ // Initial value
506
+ "inherit"
507
+ // Inherited value
508
+ //? Let's just include all potentially clickable elements that are not specifically blocked
509
+ // 'none', // No cursor
510
+ // 'default', // Default cursor
511
+ // 'auto', // Browser default
512
+ ]);
513
+ function x(B) {
514
+ return B.tagName.toLowerCase() === "html" ? !1 : !!(p != null && p.cursor && a.has(p.cursor));
515
+ }
516
+ if (x(t))
517
+ return !0;
518
+ const M = /* @__PURE__ */ new Set([
519
+ "a",
520
+ // Links
521
+ "button",
522
+ // Buttons
523
+ "input",
524
+ // All input types (text, checkbox, radio, etc.)
525
+ "select",
526
+ // Dropdown menus
527
+ "textarea",
528
+ // Text areas
529
+ "details",
530
+ // Expandable details
531
+ "summary",
532
+ // Summary element (clickable part of details)
533
+ "label",
534
+ // Form labels (often clickable)
535
+ "option",
536
+ // Select options
537
+ "optgroup",
538
+ // Option groups
539
+ "fieldset",
540
+ // Form fieldsets (can be interactive with legend)
541
+ "legend"
542
+ // Fieldset legends
543
+ ]), m = /* @__PURE__ */ new Set([
544
+ "disabled",
545
+ // Standard disabled attribute
546
+ // 'aria-disabled', // ARIA disabled state
547
+ "readonly"
548
+ // Read-only state
549
+ // 'aria-readonly', // ARIA read-only state
550
+ // 'aria-hidden', // Hidden from accessibility
551
+ // 'hidden', // Hidden attribute
552
+ // 'inert', // Inert attribute
553
+ // 'aria-inert', // ARIA inert state
554
+ // 'tabindex="-1"', // Removed from tab order
555
+ // 'aria-hidden="true"' // Hidden from screen readers
556
+ ]);
557
+ if (M.has(o)) {
558
+ if (p != null && p.cursor && c.has(p.cursor))
559
+ return !1;
560
+ for (const B of m)
561
+ if (t.hasAttribute(B) || t.getAttribute(B) === "true" || t.getAttribute(B) === "")
562
+ return !1;
563
+ return !(t.disabled || t.readOnly || t.inert);
564
+ }
565
+ const L = t.getAttribute("role"), A = t.getAttribute("aria-role");
566
+ if (t.getAttribute("contenteditable") === "true" || t.isContentEditable || t.classList && (t.classList.contains("button") || t.classList.contains("dropdown-toggle") || t.getAttribute("data-index") || t.getAttribute("data-toggle") === "dropdown" || t.getAttribute("aria-haspopup") === "true"))
567
+ return !0;
568
+ const g = /* @__PURE__ */ new Set([
569
+ "button",
570
+ // Directly clickable element
571
+ // 'link', // Clickable link
572
+ "menu",
573
+ // Menu container (ARIA menus)
574
+ "menubar",
575
+ // Menu bar container
576
+ "menuitem",
577
+ // Clickable menu item
578
+ "menuitemradio",
579
+ // Radio-style menu item (selectable)
580
+ "menuitemcheckbox",
581
+ // Checkbox-style menu item (toggleable)
582
+ "radio",
583
+ // Radio button (selectable)
584
+ "checkbox",
585
+ // Checkbox (toggleable)
586
+ "tab",
587
+ // Tab (clickable to switch content)
588
+ "switch",
589
+ // Toggle switch (clickable to change state)
590
+ "slider",
591
+ // Slider control (draggable)
592
+ "spinbutton",
593
+ // Number input with up/down controls
594
+ "combobox",
595
+ // Dropdown with text input
596
+ "searchbox",
597
+ // Search input field
598
+ "textbox",
599
+ // Text input field
600
+ "listbox",
601
+ // Selectable list
602
+ "option",
603
+ // Selectable option in a list
604
+ "scrollbar"
605
+ // Scrollable control
606
+ ]);
607
+ if (M.has(o) || L && g.has(L) || A && g.has(A)) return !0;
608
+ try {
609
+ if (typeof getEventListeners == "function") {
610
+ const Y = getEventListeners(t), Z = ["click", "mousedown", "mouseup", "dblclick"];
611
+ for (const j of Z)
612
+ if (Y[j] && Y[j].length > 0)
613
+ return !0;
614
+ }
615
+ const B = ((S = (k = t == null ? void 0 : t.ownerDocument) == null ? void 0 : k.defaultView) == null ? void 0 : S.getEventListenersForNode) || window.getEventListenersForNode;
616
+ if (typeof B == "function") {
617
+ const Y = B(t), Z = [
618
+ "click",
619
+ "mousedown",
620
+ "mouseup",
621
+ "keydown",
622
+ "keyup",
623
+ "submit",
624
+ "change",
625
+ "input",
626
+ "focus",
627
+ "blur"
628
+ ];
629
+ for (const j of Z)
630
+ for (const J of Y)
631
+ if (J.type === j)
632
+ return !0;
633
+ }
634
+ const G = ["onclick", "onmousedown", "onmouseup", "ondblclick"];
635
+ for (const Y of G)
636
+ if (t.hasAttribute(Y) || typeof t[Y] == "function")
637
+ return !0;
638
+ } catch {
639
+ }
640
+ return !!D(t);
641
+ }
642
+ function ot(t) {
643
+ if (l === -1)
644
+ return !0;
645
+ const o = P(t);
646
+ if (!o || o.length === 0)
647
+ return !1;
648
+ let p = !1;
649
+ for (const m of o)
650
+ if (m.width > 0 && m.height > 0 && !// Only check non-empty rects
651
+ (m.bottom < -l || m.top > window.innerHeight + l || m.right < -l || m.left > window.innerWidth + l)) {
652
+ p = !0;
653
+ break;
654
+ }
655
+ if (!p)
656
+ return !1;
657
+ if (t.ownerDocument !== window.document)
658
+ return !0;
659
+ let c = Array.from(o).find((m) => m.width > 0 && m.height > 0);
660
+ if (!c)
661
+ return !1;
662
+ const x = t.getRootNode();
663
+ if (x instanceof ShadowRoot) {
664
+ const m = c.left + c.width / 2, L = c.top + c.height / 2;
665
+ try {
666
+ const A = x.elementFromPoint(m, L);
667
+ if (!A) return !1;
668
+ let g = A;
669
+ for (; g && g !== x; ) {
670
+ if (g === t) return !0;
671
+ g = g.parentElement;
672
+ }
673
+ return !1;
674
+ } catch {
675
+ return !0;
676
+ }
677
+ }
678
+ const E = 5;
679
+ return [
680
+ // Initially only this was used, but it was not enough
681
+ { x: c.left + c.width / 2, y: c.top + c.height / 2 },
682
+ { x: c.left + E, y: c.top + E },
683
+ // top left
684
+ // { x: rect.right - margin, y: rect.top + margin }, // top right
685
+ // { x: rect.left + margin, y: rect.bottom - margin }, // bottom left
686
+ { x: c.right - E, y: c.bottom - E }
687
+ // bottom right
688
+ ].some(({ x: m, y: L }) => {
689
+ try {
690
+ const A = document.elementFromPoint(m, L);
691
+ if (!A) return !1;
692
+ let g = A;
693
+ for (; g && g !== document.documentElement; ) {
694
+ if (g === t) return !0;
695
+ g = g.parentElement;
696
+ }
697
+ return !1;
698
+ } catch {
699
+ return !0;
700
+ }
701
+ });
702
+ }
703
+ function st(t, o) {
704
+ if (o === -1)
705
+ return !0;
706
+ const p = t.getClientRects();
707
+ if (!p || p.length === 0) {
708
+ const a = T(t);
709
+ return !a || a.width === 0 || a.height === 0 ? !1 : !(a.bottom < -o || a.top > window.innerHeight + o || a.right < -o || a.left > window.innerWidth + o);
710
+ }
711
+ for (const a of p)
712
+ if (!(a.width === 0 || a.height === 0) && !(a.bottom < -o || a.top > window.innerHeight + o || a.right < -o || a.left > window.innerWidth + o))
713
+ return !0;
714
+ return !1;
715
+ }
716
+ function W(t) {
717
+ if (!t || t.nodeType !== Node.ELEMENT_NODE) return !1;
718
+ const o = t.tagName.toLowerCase();
719
+ return (/* @__PURE__ */ new Set([
720
+ "a",
721
+ "button",
722
+ "input",
723
+ "select",
724
+ "textarea",
725
+ "details",
726
+ "summary",
727
+ "label"
728
+ ])).has(o) ? !0 : t.hasAttribute("onclick") || t.hasAttribute("role") || t.hasAttribute("tabindex") || t.hasAttribute("aria-") || t.hasAttribute("data-action") || t.getAttribute("contenteditable") === "true";
729
+ }
730
+ const X = /* @__PURE__ */ new Set([
731
+ "a",
732
+ "button",
733
+ "input",
734
+ "select",
735
+ "textarea",
736
+ "summary",
737
+ "details",
738
+ "label",
739
+ "option"
740
+ ]), Q = /* @__PURE__ */ new Set([
741
+ "button",
742
+ "link",
743
+ "menuitem",
744
+ "menuitemradio",
745
+ "menuitemcheckbox",
746
+ "radio",
747
+ "checkbox",
748
+ "tab",
749
+ "switch",
750
+ "slider",
751
+ "spinbutton",
752
+ "combobox",
753
+ "searchbox",
754
+ "textbox",
755
+ "listbox",
756
+ "option",
757
+ "scrollbar"
758
+ ]);
759
+ function nt(t) {
760
+ if (!t || t.nodeType !== Node.ELEMENT_NODE || !U(t)) return !1;
761
+ const o = t.hasAttribute("role") || t.hasAttribute("tabindex") || t.hasAttribute("onclick") || typeof t.onclick == "function", p = /\b(btn|clickable|menu|item|entry|link)\b/i.test(
762
+ t.className || ""
763
+ ), a = !!t.closest('button,a,[role="button"],.menu,.dropdown,.list,.toolbar'), c = [...t.children].some(U), x = t.parentElement && t.parentElement.isSameNode(document.body);
764
+ return (C(t) || o || p) && c && a && !x;
765
+ }
766
+ function lt(t) {
767
+ var a, c;
768
+ if (!t || t.nodeType !== Node.ELEMENT_NODE)
769
+ return !1;
770
+ const o = t.tagName.toLowerCase(), p = t.getAttribute("role");
771
+ if (o === "iframe" || X.has(o) || p && Q.has(p) || t.isContentEditable || t.getAttribute("contenteditable") === "true" || t.hasAttribute("data-testid") || t.hasAttribute("data-cy") || t.hasAttribute("data-test") || t.hasAttribute("onclick") || typeof t.onclick == "function")
772
+ return !0;
773
+ try {
774
+ const x = ((c = (a = t == null ? void 0 : t.ownerDocument) == null ? void 0 : a.defaultView) == null ? void 0 : c.getEventListenersForNode) || window.getEventListenersForNode;
775
+ if (typeof x == "function") {
776
+ const M = x(t), m = [
777
+ "click",
778
+ "mousedown",
779
+ "mouseup",
780
+ "keydown",
781
+ "keyup",
782
+ "submit",
783
+ "change",
784
+ "input",
785
+ "focus",
786
+ "blur"
787
+ ];
788
+ for (const L of m)
789
+ for (const A of M)
790
+ if (A.type === L)
791
+ return !0;
792
+ }
793
+ if ([
794
+ "onmousedown",
795
+ "onmouseup",
796
+ "onkeydown",
797
+ "onkeyup",
798
+ "onsubmit",
799
+ "onchange",
800
+ "oninput",
801
+ "onfocus",
802
+ "onblur"
803
+ ].some((M) => t.hasAttribute(M)))
804
+ return !0;
805
+ } catch {
806
+ }
807
+ return !!nt(t);
808
+ }
809
+ function ct(t, o, p, a) {
810
+ if (!t.isInteractive) return !1;
811
+ let c = !1;
812
+ return a ? lt(o) ? c = !0 : c = !1 : c = !0, c && (t.isInViewport = st(o, l), (t.isInViewport || l === -1) && (t.highlightIndex = v++, d)) ? (r >= 0 ? r === t.highlightIndex && H(o, t.highlightIndex, p) : H(o, t.highlightIndex, p), !0) : !1;
813
+ }
814
+ function tt(t, o = null, p = !1) {
815
+ var E, M, m, L, A;
816
+ if (!t || t.id === z || t.nodeType !== Node.ELEMENT_NODE && t.nodeType !== Node.TEXT_NODE || !t || t.id === z || ((E = t.dataset) == null ? void 0 : E.browserUseIgnore) === "true" || t.getAttribute && t.getAttribute("aria-hidden") === "true")
817
+ return null;
818
+ if (t === document.body) {
819
+ const g = {
820
+ tagName: "body",
821
+ attributes: {},
822
+ xpath: "/body",
823
+ children: []
824
+ };
825
+ for (const k of t.childNodes) {
826
+ const S = tt(k, o, !1);
827
+ S && g.children.push(S);
828
+ }
829
+ const y = `${R.current++}`;
830
+ return O[y] = g, y;
831
+ }
832
+ if (t.nodeType !== Node.ELEMENT_NODE && t.nodeType !== Node.TEXT_NODE)
833
+ return null;
834
+ if (t.nodeType === Node.TEXT_NODE) {
835
+ const g = (M = t.textContent) == null ? void 0 : M.trim();
836
+ if (!g)
837
+ return null;
838
+ const y = t.parentElement;
839
+ if (!y || y.tagName.toLowerCase() === "script")
840
+ return null;
841
+ const k = `${R.current++}`;
842
+ return O[k] = {
843
+ type: "TEXT_NODE",
844
+ text: g,
845
+ isVisible: _(t)
846
+ }, k;
847
+ }
848
+ if (t.nodeType === Node.ELEMENT_NODE && !rt(t))
849
+ return null;
850
+ if (l !== -1 && !t.shadowRoot) {
851
+ const g = T(t), y = F(t), k = y && (y.position === "fixed" || y.position === "sticky"), S = t.offsetWidth > 0 || t.offsetHeight > 0;
852
+ if (!g || !k && !S && (g.bottom < -l || g.top > window.innerHeight + l || g.right < -l || g.left > window.innerWidth + l))
853
+ return null;
854
+ }
855
+ const a = {
856
+ tagName: t.tagName.toLowerCase(),
857
+ attributes: {},
858
+ /**
859
+ * @edit no need for xpath
860
+ */
861
+ // xpath: getXPathTree(node, true),
862
+ children: []
863
+ };
864
+ if (W(t) || t.tagName.toLowerCase() === "iframe" || t.tagName.toLowerCase() === "body") {
865
+ const g = ((m = t.getAttributeNames) == null ? void 0 : m.call(t)) || [];
866
+ for (const y of g) {
867
+ const k = t.getAttribute(y);
868
+ a.attributes[y] = k;
869
+ }
870
+ t.tagName.toLowerCase() === "input" && (t.type === "checkbox" || t.type === "radio") && (a.attributes.checked = t.checked ? "true" : "false");
871
+ }
872
+ let c = !1;
873
+ if (t.nodeType === Node.ELEMENT_NODE && (a.isVisible = U(t), a.isVisible)) {
874
+ a.isTopElement = ot(t);
875
+ const g = t.getAttribute("role"), y = g === "menu" || g === "menubar" || g === "listbox";
876
+ (a.isTopElement || y) && (a.isInteractive = C(t), c = ct(a, t, o, p), a.ref = t);
877
+ }
878
+ if (t.tagName) {
879
+ const g = t.tagName.toLowerCase();
880
+ if (g === "iframe")
881
+ try {
882
+ const y = t.contentDocument || ((L = t.contentWindow) == null ? void 0 : L.document);
883
+ if (y)
884
+ for (const k of y.childNodes) {
885
+ const S = tt(k, t, !1);
886
+ S && a.children.push(S);
887
+ }
888
+ } catch (y) {
889
+ console.warn("Unable to access iframe:", y);
890
+ }
891
+ else if (t.isContentEditable || t.getAttribute("contenteditable") === "true" || t.id === "tinymce" || t.classList.contains("mce-content-body") || g === "body" && ((A = t.getAttribute("data-id")) != null && A.startsWith("mce_")))
892
+ for (const y of t.childNodes) {
893
+ const k = tt(y, o, c);
894
+ k && a.children.push(k);
895
+ }
896
+ else {
897
+ if (t.shadowRoot) {
898
+ a.shadowRoot = !0;
899
+ for (const y of t.shadowRoot.childNodes) {
900
+ const k = tt(y, o, c);
901
+ k && a.children.push(k);
902
+ }
903
+ }
904
+ for (const y of t.childNodes) {
905
+ const S = tt(y, o, c || p);
906
+ S && a.children.push(S);
907
+ }
908
+ }
909
+ }
910
+ if (a.tagName === "a" && a.children.length === 0 && !a.attributes.href) {
911
+ const g = T(t);
912
+ if (!(g && g.width > 0 && g.height > 0 || t.offsetWidth > 0 || t.offsetHeight > 0))
913
+ return null;
914
+ }
915
+ a.extra = w.get(t) || null;
916
+ const x = `${R.current++}`;
917
+ return O[x] = a, x;
918
+ }
919
+ const at = tt(document.body);
920
+ return f.clearCache(), { rootId: at, map: O };
921
+ }, newElementsCache = /* @__PURE__ */ new WeakMap();
922
+ function getFlatTree(e) {
923
+ const n = [];
924
+ for (const d of e.interactiveBlacklist || [])
925
+ typeof d == "function" ? n.push(d()) : n.push(d);
926
+ const s = [];
927
+ for (const d of e.interactiveWhitelist || [])
928
+ typeof d == "function" ? s.push(d()) : s.push(d);
929
+ const i = domTree({
930
+ doHighlightElements: !0,
931
+ debugMode: !0,
932
+ focusHighlightIndex: -1,
933
+ viewportExpansion: VIEWPORT_EXPANSION,
934
+ interactiveBlacklist: n,
935
+ interactiveWhitelist: s,
936
+ highlightOpacity: e.highlightOpacity ?? 0,
937
+ highlightLabelOpacity: e.highlightLabelOpacity ?? 0.1
938
+ }), b = window.location.href;
939
+ for (const d in i.map) {
940
+ const r = i.map[d];
941
+ if (r.isInteractive && r.ref) {
942
+ const l = r.ref;
943
+ newElementsCache.has(l) || (newElementsCache.set(l, b), r.isNew = !0);
944
+ }
945
+ }
946
+ return i;
947
+ }
948
+ function flatTreeToString(e, n) {
949
+ const s = [
950
+ "title",
951
+ "type",
952
+ "checked",
953
+ "name",
954
+ "role",
955
+ "value",
956
+ "placeholder",
957
+ "data-date-format",
958
+ "alt",
959
+ "aria-label",
960
+ "aria-expanded",
961
+ "data-state",
962
+ "aria-checked",
963
+ // @edit added for better form handling
964
+ "id",
965
+ "for",
966
+ // for jump check
967
+ "target",
968
+ // absolute 定位的下拉菜单
969
+ "aria-haspopup",
970
+ "aria-controls",
971
+ "aria-owns"
972
+ ], i = [...n || [], ...s], b = (u, f) => u.length > f ? u.substring(0, f) + "..." : u, d = (u) => {
973
+ const f = e.map[u];
974
+ if (!f) return null;
975
+ if (f.type === "TEXT_NODE") {
976
+ const T = f;
977
+ return {
978
+ type: "text",
979
+ text: T.text,
980
+ isVisible: T.isVisible,
981
+ parent: null,
982
+ children: []
983
+ };
984
+ } else {
985
+ const T = f, F = [];
986
+ if (T.children)
987
+ for (const P of T.children) {
988
+ const O = d(P);
989
+ O && (O.parent = null, F.push(O));
990
+ }
991
+ return {
992
+ type: "element",
993
+ tagName: T.tagName,
994
+ attributes: T.attributes ?? {},
995
+ isVisible: T.isVisible ?? !1,
996
+ isInteractive: T.isInteractive ?? !1,
997
+ isTopElement: T.isTopElement ?? !1,
998
+ isNew: T.isNew ?? !1,
999
+ highlightIndex: T.highlightIndex,
1000
+ parent: null,
1001
+ children: F,
1002
+ extra: T.extra ?? {}
1003
+ };
1004
+ }
1005
+ }, r = (u, f = null) => {
1006
+ u.parent = f;
1007
+ for (const T of u.children)
1008
+ r(T, u);
1009
+ }, l = d(e.rootId);
1010
+ if (!l) return "";
1011
+ r(l);
1012
+ const h = (u) => {
1013
+ let f = u.parent;
1014
+ for (; f; ) {
1015
+ if (f.type === "element" && f.highlightIndex !== void 0)
1016
+ return !0;
1017
+ f = f.parent;
1018
+ }
1019
+ return !1;
1020
+ }, v = (u, f, T) => {
1021
+ var O, R, z, H;
1022
+ let F = f;
1023
+ const P = " ".repeat(f);
1024
+ if (u.type === "element") {
1025
+ if (u.highlightIndex !== void 0) {
1026
+ F += 1;
1027
+ const D = getAllTextTillNextClickableElement(u);
1028
+ let _ = "";
1029
+ if (i.length > 0 && u.attributes) {
1030
+ const C = {};
1031
+ for (const W of i) {
1032
+ const X = u.attributes[W];
1033
+ X && X.trim() !== "" && (C[W] = X.trim());
1034
+ }
1035
+ const ot = i.filter((W) => W in C);
1036
+ if (ot.length > 1) {
1037
+ const W = /* @__PURE__ */ new Set(), X = {};
1038
+ for (const Q of ot) {
1039
+ const nt = C[Q];
1040
+ nt.length > 5 && (nt in X ? W.add(Q) : X[nt] = Q);
1041
+ }
1042
+ for (const Q of W)
1043
+ delete C[Q];
1044
+ }
1045
+ C.role === u.tagName && delete C.role;
1046
+ const st = ["aria-label", "placeholder", "title"];
1047
+ for (const W of st)
1048
+ C[W] && C[W].toLowerCase().trim() === D.toLowerCase().trim() && delete C[W];
1049
+ Object.keys(C).length > 0 && (_ = Object.entries(C).map(([W, X]) => `${W}=${b(X, 20)}`).join(" "));
1050
+ }
1051
+ const rt = u.isNew ? `*[${u.highlightIndex}]` : `[${u.highlightIndex}]`;
1052
+ let U = `${P}${rt}<${u.tagName ?? ""}`;
1053
+ if (_ && (U += ` ${_}`), u.extra && u.extra.scrollable) {
1054
+ let C = "";
1055
+ (O = u.extra.scrollData) != null && O.left && (C += `left=${u.extra.scrollData.left}, `), (R = u.extra.scrollData) != null && R.top && (C += `top=${u.extra.scrollData.top}, `), (z = u.extra.scrollData) != null && z.right && (C += `right=${u.extra.scrollData.right}, `), (H = u.extra.scrollData) != null && H.bottom && (C += `bottom=${u.extra.scrollData.bottom}`), U += ` data-scrollable="${C}"`;
1056
+ }
1057
+ if (D) {
1058
+ const C = D.trim();
1059
+ _ || (U += " "), U += `>${C}`;
1060
+ } else _ || (U += " ");
1061
+ U += " />", T.push(U);
1062
+ }
1063
+ for (const D of u.children)
1064
+ v(D, F, T);
1065
+ } else if (u.type === "text") {
1066
+ if (h(u))
1067
+ return;
1068
+ u.parent && u.parent.type === "element" && u.parent.isVisible && u.parent.isTopElement && T.push(`${P}${u.text ?? ""}`);
1069
+ }
1070
+ }, w = [];
1071
+ return v(l, 0, w), w.join(`
1072
+ `);
1073
+ }
1074
+ const getAllTextTillNextClickableElement = (e, n = -1) => {
1075
+ const s = [], i = (b, d) => {
1076
+ if (!(n !== -1 && d > n) && !(b.type === "element" && b !== e && b.highlightIndex !== void 0)) {
1077
+ if (b.type === "text" && b.text)
1078
+ s.push(b.text);
1079
+ else if (b.type === "element")
1080
+ for (const r of b.children)
1081
+ i(r, d + 1);
1082
+ }
1083
+ };
1084
+ return i(e, 0), s.join(`
1085
+ `).trim();
1086
+ };
1087
+ function getSelectorMap(e) {
1088
+ const n = /* @__PURE__ */ new Map(), s = Object.keys(e.map);
1089
+ for (const i of s) {
1090
+ const b = e.map[i];
1091
+ b.isInteractive && typeof b.highlightIndex == "number" && n.set(b.highlightIndex, b);
1092
+ }
1093
+ return n;
1094
+ }
1095
+ function getElementTextMap(e) {
1096
+ const n = e.split(`
1097
+ `).map((i) => i.trim()).filter((i) => i.length > 0), s = /* @__PURE__ */ new Map();
1098
+ for (const i of n) {
1099
+ const d = /^\[(\d+)\]<[^>]+>([^<]*)/.exec(i);
1100
+ if (d) {
1101
+ const r = parseInt(d[1], 10);
1102
+ s.set(r, i);
1103
+ }
1104
+ }
1105
+ return s;
1106
+ }
1107
+ function cleanUpHighlights() {
1108
+ const e = window._highlightCleanupFunctions || [];
1109
+ for (const n of e)
1110
+ typeof n == "function" && n();
1111
+ window._highlightCleanupFunctions = [];
1112
+ }
1113
+ window.addEventListener("popstate", () => {
1114
+ cleanUpHighlights();
1115
+ });
1116
+ window.addEventListener("hashchange", () => {
1117
+ cleanUpHighlights();
1118
+ });
1119
+ window.addEventListener("beforeunload", () => {
1120
+ cleanUpHighlights();
1121
+ });
1122
+ const navigation = window.navigation;
1123
+ if (navigation && typeof navigation.addEventListener == "function")
1124
+ navigation.addEventListener("navigate", () => {
1125
+ cleanUpHighlights();
1126
+ });
1127
+ else {
1128
+ let e = window.location.href;
1129
+ setInterval(() => {
1130
+ window.location.href !== e && (e = window.location.href, cleanUpHighlights());
1131
+ }, 500);
1132
+ }
1133
+ function getPageInfo() {
1134
+ const e = window.innerWidth, n = window.innerHeight, s = Math.max(document.documentElement.scrollWidth, document.body.scrollWidth || 0), i = Math.max(
1135
+ document.documentElement.scrollHeight,
1136
+ document.body.scrollHeight || 0
1137
+ ), b = window.scrollX || window.pageXOffset || document.documentElement.scrollLeft || 0, d = window.scrollY || window.pageYOffset || document.documentElement.scrollTop || 0, r = Math.max(0, i - (window.innerHeight + d)), l = Math.max(0, s - (window.innerWidth + b));
1138
+ return {
1139
+ // Current viewport dimensions
1140
+ viewport_width: e,
1141
+ viewport_height: n,
1142
+ // Total page dimensions
1143
+ page_width: s,
1144
+ page_height: i,
1145
+ // Current scroll position
1146
+ scroll_x: b,
1147
+ scroll_y: d,
1148
+ pixels_above: d,
1149
+ pixels_below: r,
1150
+ pages_above: n > 0 ? d / n : 0,
1151
+ pages_below: n > 0 ? r / n : 0,
1152
+ total_pages: n > 0 ? i / n : 0,
1153
+ current_page_position: d / Math.max(1, i - n),
1154
+ pixels_left: b,
1155
+ pixels_right: l
1156
+ };
1157
+ }
1158
+ function patchReact(e) {
1159
+ const n = document.querySelectorAll(
1160
+ '[data-reactroot], [data-reactid], [data-react-checksum], #root, #app, [id^="root-"], [id^="app-"], #adex-wrapper, #adex-root'
1161
+ );
1162
+ for (const s of n)
1163
+ s.setAttribute("data-page-agent-not-interactive", "true");
1164
+ }
1165
+ class PageController extends EventTarget {
1166
+ constructor(e = {}) {
1167
+ super(), this.flatTree = null, this.selectorMap = /* @__PURE__ */ new Map(), this.elementTextMap = /* @__PURE__ */ new Map(), this.simplifiedHTML = "<EMPTY>", this.lastTimeUpdate = 0, this.isIndexed = !1, this.mask = null, this.maskReady = null, this.config = e, patchReact(), e.enableMask && this.initMask();
1168
+ }
1169
+ /**
1170
+ * Initialize mask asynchronously (dynamic import to avoid CSS loading in Node)
1171
+ */
1172
+ initMask() {
1173
+ this.maskReady === null && (this.maskReady = (async () => {
1174
+ const { SimulatorMask: e } = await import("./SimulatorMask-CgaoHOve.js");
1175
+ this.mask = new e();
1176
+ })());
1177
+ }
1178
+ // ======= State Queries =======
1179
+ /**
1180
+ * Get current page URL
1181
+ */
1182
+ async getCurrentUrl() {
1183
+ return window.location.href;
1184
+ }
1185
+ /**
1186
+ * Get last tree update timestamp
1187
+ */
1188
+ async getLastUpdateTime() {
1189
+ return this.lastTimeUpdate;
1190
+ }
1191
+ /**
1192
+ * Get structured browser state for LLM consumption.
1193
+ * Automatically calls updateTree() to refresh the DOM state.
1194
+ */
1195
+ async getBrowserState() {
1196
+ const e = window.location.href, n = document.title, s = getPageInfo(), i = this.config.viewportExpansion ?? VIEWPORT_EXPANSION;
1197
+ await this.updateTree();
1198
+ const b = this.simplifiedHTML, d = `Current Page: [${n}](${e})`, r = `Page info: ${s.viewport_width}x${s.viewport_height}px viewport, ${s.page_width}x${s.page_height}px total page size, ${s.pages_above.toFixed(1)} pages above, ${s.pages_below.toFixed(1)} pages below, ${s.total_pages.toFixed(1)} total pages, at ${(s.current_page_position * 100).toFixed(0)}% of page`, l = i === -1 ? "Interactive elements from top layer of the current page (full page):" : "Interactive elements from top layer of the current page inside the viewport:", v = s.pixels_above > 4 && i !== -1 ? `... ${s.pixels_above} pixels above (${s.pages_above.toFixed(1)} pages) - scroll to see more ...` : "[Start of page]", w = `${d}
1199
+ ${r}
1200
+
1201
+ ${l}
1202
+
1203
+ ${v}`, f = s.pixels_below > 4 && i !== -1 ? `... ${s.pixels_below} pixels below (${s.pages_below.toFixed(1)} pages) - scroll to see more ...` : "[End of page]";
1204
+ return { url: e, title: n, header: w, content: b, footer: f };
1205
+ }
1206
+ // ======= DOM Tree Operations =======
1207
+ /**
1208
+ * Update DOM tree, returns simplified HTML for LLM.
1209
+ * This is the main method to refresh the page state.
1210
+ * Automatically bypasses mask during DOM extraction if enabled.
1211
+ */
1212
+ async updateTree() {
1213
+ this.dispatchEvent(new Event("beforeUpdate")), this.lastTimeUpdate = Date.now(), this.mask && (this.mask.wrapper.style.pointerEvents = "none"), cleanUpHighlights();
1214
+ const e = [
1215
+ ...this.config.interactiveBlacklist || [],
1216
+ ...document.querySelectorAll("[data-page-agent-not-interactive]").values()
1217
+ ];
1218
+ return this.flatTree = getFlatTree({
1219
+ ...this.config,
1220
+ interactiveBlacklist: e
1221
+ }), this.simplifiedHTML = flatTreeToString(this.flatTree, this.config.include_attributes), this.selectorMap.clear(), this.selectorMap = getSelectorMap(this.flatTree), this.elementTextMap.clear(), this.elementTextMap = getElementTextMap(this.simplifiedHTML), this.isIndexed = !0, this.mask && (this.mask.wrapper.style.pointerEvents = "auto"), this.dispatchEvent(new Event("afterUpdate")), this.simplifiedHTML;
1222
+ }
1223
+ /**
1224
+ * Clean up all element highlights
1225
+ */
1226
+ async cleanUpHighlights() {
1227
+ cleanUpHighlights();
1228
+ }
1229
+ // ======= Element Actions =======
1230
+ /**
1231
+ * Ensure the tree has been indexed before any index-based operation.
1232
+ * Throws if updateTree() hasn't been called yet.
1233
+ */
1234
+ assertIndexed() {
1235
+ if (!this.isIndexed)
1236
+ throw new Error("DOM tree not indexed yet. Can not perform actions on elements.");
1237
+ }
1238
+ /**
1239
+ * Click element by index
1240
+ */
1241
+ async clickElement(e) {
1242
+ try {
1243
+ this.assertIndexed();
1244
+ const n = getElementByIndex(this.selectorMap, e), s = this.elementTextMap.get(e);
1245
+ return await clickElement(n), n instanceof HTMLAnchorElement && n.target === "_blank" ? {
1246
+ success: !0,
1247
+ message: `✅ Clicked element (${s ?? e}). ⚠️ Link opens in a new tab. You are not capable of reading new tabs.`
1248
+ } : {
1249
+ success: !0,
1250
+ message: `✅ Clicked element (${s ?? e}).`
1251
+ };
1252
+ } catch (n) {
1253
+ return {
1254
+ success: !1,
1255
+ message: `❌ Failed to click element: ${n}`
1256
+ };
1257
+ }
1258
+ }
1259
+ /**
1260
+ * Input text into element by index
1261
+ */
1262
+ async inputText(e, n) {
1263
+ try {
1264
+ this.assertIndexed();
1265
+ const s = getElementByIndex(this.selectorMap, e), i = this.elementTextMap.get(e);
1266
+ return await inputTextElement(s, n), {
1267
+ success: !0,
1268
+ message: `✅ Input text (${n}) into element (${i ?? e}).`
1269
+ };
1270
+ } catch (s) {
1271
+ return {
1272
+ success: !1,
1273
+ message: `❌ Failed to input text: ${s}`
1274
+ };
1275
+ }
1276
+ }
1277
+ /**
1278
+ * Select dropdown option by index and option text
1279
+ */
1280
+ async selectOption(e, n) {
1281
+ try {
1282
+ this.assertIndexed();
1283
+ const s = getElementByIndex(this.selectorMap, e), i = this.elementTextMap.get(e);
1284
+ return await selectOptionElement(s, n), {
1285
+ success: !0,
1286
+ message: `✅ Selected option (${n}) in element (${i ?? e}).`
1287
+ };
1288
+ } catch (s) {
1289
+ return {
1290
+ success: !1,
1291
+ message: `❌ Failed to select option: ${s}`
1292
+ };
1293
+ }
1294
+ }
1295
+ /**
1296
+ * Scroll vertically
1297
+ */
1298
+ async scroll(e) {
1299
+ try {
1300
+ const { down: n, numPages: s, pixels: i, index: b } = e;
1301
+ this.assertIndexed();
1302
+ const d = i ?? s * (n ? 1 : -1) * window.innerHeight, r = b !== void 0 ? getElementByIndex(this.selectorMap, b) : null;
1303
+ return {
1304
+ success: !0,
1305
+ message: await scrollVertically(n, d, r)
1306
+ };
1307
+ } catch (n) {
1308
+ return {
1309
+ success: !1,
1310
+ message: `❌ Failed to scroll: ${n}`
1311
+ };
1312
+ }
1313
+ }
1314
+ /**
1315
+ * Scroll horizontally
1316
+ */
1317
+ async scrollHorizontally(e) {
1318
+ try {
1319
+ const { right: n, pixels: s, index: i } = e;
1320
+ this.assertIndexed();
1321
+ const b = s * (n ? 1 : -1), d = i !== void 0 ? getElementByIndex(this.selectorMap, i) : null;
1322
+ return {
1323
+ success: !0,
1324
+ message: await scrollHorizontally(n, b, d)
1325
+ };
1326
+ } catch (n) {
1327
+ return {
1328
+ success: !1,
1329
+ message: `❌ Failed to scroll horizontally: ${n}`
1330
+ };
1331
+ }
1332
+ }
1333
+ /**
1334
+ * Execute arbitrary JavaScript on the page
1335
+ */
1336
+ async executeJavascript(script) {
1337
+ try {
1338
+ const asyncFunction = eval(`(async () => { ${script} })`), result = await asyncFunction();
1339
+ return {
1340
+ success: !0,
1341
+ message: `✅ Executed JavaScript. Result: ${result}`
1342
+ };
1343
+ } catch (e) {
1344
+ return {
1345
+ success: !1,
1346
+ message: `❌ Error executing JavaScript: ${e}`
1347
+ };
1348
+ }
1349
+ }
1350
+ // ======= Mask Operations =======
1351
+ /**
1352
+ * Show the visual mask overlay.
1353
+ * Only works after mask is setup.
1354
+ */
1355
+ async showMask() {
1356
+ var e;
1357
+ await this.maskReady, (e = this.mask) == null || e.show();
1358
+ }
1359
+ /**
1360
+ * Hide the visual mask overlay.
1361
+ * Only works after mask is setup.
1362
+ */
1363
+ async hideMask() {
1364
+ var e;
1365
+ await this.maskReady, (e = this.mask) == null || e.hide();
1366
+ }
1367
+ /**
1368
+ * Dispose and clean up resources
1369
+ */
1370
+ dispose() {
1371
+ var e;
1372
+ cleanUpHighlights(), this.flatTree = null, this.selectorMap.clear(), this.elementTextMap.clear(), this.simplifiedHTML = "<EMPTY>", this.isIndexed = !1, (e = this.mask) == null || e.dispose(), this.mask = null;
1373
+ }
1374
+ }
1375
+ export {
1376
+ PageController
1377
+ };