runline 0.23.0 → 0.24.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.
- package/dist/plugins/shiftTranscription/src/index.js +1 -1
- package/dist/plugins/shiftTranscription/src/transcription.js +12 -0
- package/dist/plugins/steel/src/browser.js +11 -79
- package/dist/plugins/steel/src/index.js +2 -0
- package/dist/plugins/steel/src/page/bundle.generated.js +11 -0
- package/dist/plugins/steel/src/page/cdp.js +232 -0
- package/dist/plugins/steel/src/page/driver.js +286 -0
- package/dist/plugins/steel/src/page/entry.js +91 -0
- package/dist/plugins/steel/src/page/install.js +3 -0
- package/dist/plugins/steel/src/page/page-snapshot.js +330 -0
- package/dist/plugins/steel/src/page/tools.js +649 -0
- package/dist/plugins/steel/src/page/vendor/aria-snapshot/ariaSnapshot.js +411 -0
- package/dist/plugins/steel/src/page/vendor/aria-snapshot/ariaSnapshotDistiller.js +207 -0
- package/dist/plugins/steel/src/page/vendor/aria-snapshot/ariaTypes.js +62 -0
- package/dist/plugins/steel/src/page/vendor/aria-snapshot/cssTokenizer.js +949 -0
- package/dist/plugins/steel/src/page/vendor/aria-snapshot/domUtils.js +157 -0
- package/dist/plugins/steel/src/page/vendor/aria-snapshot/roleUtils.js +1193 -0
- package/dist/plugins/steel/src/page/vendor/aria-snapshot/stringUtils.js +194 -0
- package/dist/plugins/steel/src/page/vendor/aria-snapshot/yaml.js +80 -0
- package/dist/plugins/steel/src/page/wait-for.js +30 -0
- package/dist/plugins/steel/src/sessions.js +2 -7
- package/dist/plugins/steel/src/shared.js +12 -0
- package/package.json +1 -1
|
@@ -9,7 +9,7 @@ import { registerTranscriptionActions } from "./transcription.js";
|
|
|
9
9
|
*/
|
|
10
10
|
export default function shiftTranscription(rl) {
|
|
11
11
|
rl.setName("shiftTranscription");
|
|
12
|
-
rl.setVersion("0.
|
|
12
|
+
rl.setVersion("0.2.0");
|
|
13
13
|
rl.setConnectionSchema(t.Object({
|
|
14
14
|
apiKey: t.String({
|
|
15
15
|
description: "Shift Labs API key",
|
|
@@ -94,6 +94,18 @@ export function registerTranscriptionActions(rl) {
|
|
|
94
94
|
return request(ctx, `/v1/services/transcription/jobs/${pathSegment(id)}/cancel`, { method: "POST" });
|
|
95
95
|
},
|
|
96
96
|
});
|
|
97
|
+
rl.registerAction("transcription.job.delete", {
|
|
98
|
+
access: "write",
|
|
99
|
+
description: "Permanently delete a finished (succeeded, failed, or canceled) " +
|
|
100
|
+
"transcription job, its transcript artifacts, and its uploaded " +
|
|
101
|
+
"source media when no other job shares it. Cancel live jobs first. " +
|
|
102
|
+
"This cannot be undone.",
|
|
103
|
+
inputSchema: t.Object({ id: Id }, STRICT_OBJECT),
|
|
104
|
+
async execute(input, ctx) {
|
|
105
|
+
const { id } = input;
|
|
106
|
+
return request(ctx, `/v1/services/transcription/jobs/${pathSegment(id)}`, { method: "DELETE" });
|
|
107
|
+
},
|
|
108
|
+
});
|
|
97
109
|
rl.registerAction("transcription.artifact.list", {
|
|
98
110
|
access: "read",
|
|
99
111
|
description: "List the available transcript artifacts for a job.",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as t from "typebox";
|
|
2
|
-
import { SESSION_OPTIONS_SCHEMA, api,
|
|
2
|
+
import { SESSION_OPTIONS_SCHEMA, api, cdpUrl, compactRecord } from "./shared.js";
|
|
3
3
|
const SCRAPE_SCHEMA = {
|
|
4
4
|
url: t.String({ description: "URL to scrape" }),
|
|
5
5
|
format: t.Optional(t.Array(t.String(), { description: "Formats: html, cleaned_html, markdown, readability" })),
|
|
@@ -20,67 +20,6 @@ async function scrape(input, ctx) {
|
|
|
20
20
|
async function screenshot(input, ctx) {
|
|
21
21
|
return api(ctx, "/v1/screenshot", { method: "POST", body: compactRecord(input) });
|
|
22
22
|
}
|
|
23
|
-
async function connectMiniCdp(cdpUrl) {
|
|
24
|
-
const ws = new WebSocket(cdpUrl);
|
|
25
|
-
let nextId = 0;
|
|
26
|
-
const pending = new Map();
|
|
27
|
-
await new Promise((resolve, reject) => {
|
|
28
|
-
const timer = setTimeout(() => reject(new Error("CDP websocket connection timed out")), 30000);
|
|
29
|
-
ws.addEventListener("open", () => { clearTimeout(timer); resolve(); }, { once: true });
|
|
30
|
-
ws.addEventListener("error", () => { clearTimeout(timer); reject(new Error("CDP websocket connection failed")); }, { once: true });
|
|
31
|
-
});
|
|
32
|
-
ws.addEventListener("message", (event) => {
|
|
33
|
-
let message;
|
|
34
|
-
try {
|
|
35
|
-
message = JSON.parse(String(event.data));
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
if (typeof message.id !== "number")
|
|
41
|
-
return;
|
|
42
|
-
const wait = pending.get(message.id);
|
|
43
|
-
if (!wait)
|
|
44
|
-
return;
|
|
45
|
-
pending.delete(message.id);
|
|
46
|
-
if (message.error)
|
|
47
|
-
wait.reject(new Error(JSON.stringify(message.error)));
|
|
48
|
-
else
|
|
49
|
-
wait.resolve(message.result);
|
|
50
|
-
});
|
|
51
|
-
const send = (method, params = {}, sessionId) => new Promise((resolve, reject) => {
|
|
52
|
-
const id = ++nextId;
|
|
53
|
-
pending.set(id, { resolve, reject });
|
|
54
|
-
ws.send(JSON.stringify({ id, method, params, ...(sessionId ? { sessionId } : {}) }));
|
|
55
|
-
setTimeout(() => {
|
|
56
|
-
if (pending.delete(id))
|
|
57
|
-
reject(new Error(`CDP ${method} timed out`));
|
|
58
|
-
}, 30000);
|
|
59
|
-
});
|
|
60
|
-
const targets = await send("Target.getTargets");
|
|
61
|
-
const target = targets.targetInfos?.find((info) => info.type === "page") ?? targets.targetInfos?.[0];
|
|
62
|
-
if (!target)
|
|
63
|
-
throw new Error("Steel CDP session has no browser target");
|
|
64
|
-
const attached = await send("Target.attachToTarget", { targetId: target.targetId, flatten: true });
|
|
65
|
-
const sid = attached.sessionId;
|
|
66
|
-
const evaluate = async (expression) => {
|
|
67
|
-
const result = await send("Runtime.evaluate", { expression, returnByValue: true, awaitPromise: true }, sid);
|
|
68
|
-
return result.result?.value;
|
|
69
|
-
};
|
|
70
|
-
const page = {
|
|
71
|
-
async goto(url, _options) {
|
|
72
|
-
await send("Page.navigate", { url }, sid);
|
|
73
|
-
await new Promise((resolve) => setTimeout(resolve, 1500));
|
|
74
|
-
return null;
|
|
75
|
-
},
|
|
76
|
-
title: () => evaluate("document.title"),
|
|
77
|
-
url: () => evaluate("location.href"),
|
|
78
|
-
text: () => evaluate("document.body?.innerText ?? ''"),
|
|
79
|
-
html: () => evaluate("document.documentElement?.outerHTML ?? ''"),
|
|
80
|
-
evaluate: (expression) => evaluate(`(${expression})()`),
|
|
81
|
-
};
|
|
82
|
-
return { page, browser: { close: () => ws.close() }, context: {}, close: () => ws.close() };
|
|
83
|
-
}
|
|
84
23
|
export function registerBrowserActions(rl) {
|
|
85
24
|
rl.registerAction("scrape", {
|
|
86
25
|
access: "write",
|
|
@@ -134,7 +73,7 @@ export function registerBrowserActions(rl) {
|
|
|
134
73
|
});
|
|
135
74
|
rl.registerAction("browser.run", {
|
|
136
75
|
access: "write",
|
|
137
|
-
description: "Create a Steel session, connect with Playwright over CDP, run an async JavaScript script, then release by default. The script receives { page, browser, context
|
|
76
|
+
description: "Create a Steel session, connect with real Playwright over CDP, run an async JavaScript script, then release by default. The script receives the genuine Playwright { page, browser, context } plus session. Requires the host app to have playwright installed — this action fails rather than degrading if it is missing. For automation that works without a Playwright install, prefer the page.* actions, which drive the page semantically over CDP.",
|
|
138
77
|
inputSchema: t.Object({
|
|
139
78
|
script: t.String({ description: "Async JavaScript body. Example: await page.goto('https://example.com'); return { title: await page.title() };" }),
|
|
140
79
|
release: t.Optional(t.Boolean({ description: "Release the Steel session after the script finishes (default true)" })),
|
|
@@ -147,26 +86,19 @@ export function registerBrowserActions(rl) {
|
|
|
147
86
|
playwright = await import("playwright");
|
|
148
87
|
}
|
|
149
88
|
catch (_error) {
|
|
150
|
-
throw new Error("steel.browser.run
|
|
89
|
+
throw new Error("steel.browser.run needs playwright installed in the host project. " +
|
|
90
|
+
"Install it, or use the steel.page.* actions, which need nothing installed.");
|
|
151
91
|
}
|
|
152
92
|
const session = await api(ctx, "/v1/sessions", { method: "POST", body: compactRecord(sessionOptions) });
|
|
153
|
-
const
|
|
93
|
+
const endpoint = cdpUrl(ctx, String(session.id));
|
|
154
94
|
let browser;
|
|
155
95
|
try {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
page = context.pages()[0] ?? await context.newPage();
|
|
163
|
-
}
|
|
164
|
-
catch {
|
|
165
|
-
const mini = await connectMiniCdp(cdpUrl);
|
|
166
|
-
browser = mini.browser;
|
|
167
|
-
context = mini.context;
|
|
168
|
-
page = mini.page;
|
|
169
|
-
}
|
|
96
|
+
// No fallback shim on purpose. A hand-rolled lookalike that
|
|
97
|
+
// answers to the same names but implements a fraction of the API
|
|
98
|
+
// does not fail — it returns wrong results, which is worse.
|
|
99
|
+
browser = await playwright.chromium.connectOverCDP(endpoint, { timeout: 30000 });
|
|
100
|
+
const context = browser.contexts()[0] ?? await browser.newContext();
|
|
101
|
+
const page = context.pages()[0] ?? await context.newPage();
|
|
170
102
|
const fn = new Function("page", "browser", "context", "session", `return (async () => {\n${script}\n})();`);
|
|
171
103
|
const result = await fn(page, browser, context, session);
|
|
172
104
|
return { session, result };
|
|
@@ -4,6 +4,7 @@ import { registerCaptchaActions } from "./captchas.js";
|
|
|
4
4
|
import { registerCredentialActions } from "./credentials.js";
|
|
5
5
|
import { registerExtensionActions } from "./extensions.js";
|
|
6
6
|
import { registerFileActions } from "./files.js";
|
|
7
|
+
import { registerPageActions } from "./page/tools.js";
|
|
7
8
|
import { registerProfileActions } from "./profiles.js";
|
|
8
9
|
import { registerSessionActions } from "./sessions.js";
|
|
9
10
|
export default function steel(rl) {
|
|
@@ -17,6 +18,7 @@ export default function steel(rl) {
|
|
|
17
18
|
}));
|
|
18
19
|
registerSessionActions(rl);
|
|
19
20
|
registerBrowserActions(rl);
|
|
21
|
+
registerPageActions(rl);
|
|
20
22
|
registerFileActions(rl);
|
|
21
23
|
registerCredentialActions(rl);
|
|
22
24
|
registerProfileActions(rl);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// GENERATED FILE — DO NOT EDIT.
|
|
2
|
+
// Built from steel/src/page/ by scripts/build-steel-page-bundle.ts.
|
|
3
|
+
// Regenerate with: bun run build:steel-page-bundle
|
|
4
|
+
//
|
|
5
|
+
// A self-contained IIFE evaluated inside the Steel session's page. It
|
|
6
|
+
// installs the snapshot bridge on the page's global and returns nothing;
|
|
7
|
+
// the driver calls into it afterwards via Runtime.evaluate.
|
|
8
|
+
/** Contract version the bundle installs; must match entry.ts. */
|
|
9
|
+
export const PAGE_BRIDGE_VERSION = 1;
|
|
10
|
+
export const PAGE_BRIDGE_GLOBAL = "__steelPageBridge";
|
|
11
|
+
export const PAGE_BRIDGE_SOURCE = "(()=>{function hasPointerCursor(ariaNode){return ariaNode.box.cursor===\"pointer\"}var normalizedWhitespaceCache;function normalizeWhiteSpace(text){let result=normalizedWhitespaceCache?.get(text);if(result===void 0)result=text.replace(/[\\u200b\\u00ad]/g,\"\").trim().replace(/\\s+/g,\" \"),normalizedWhitespaceCache?.set(text,result);return result}function truncateDataUrl(url){if(!url.startsWith(\"data:\"))return url;let comma=url.indexOf(\",\");if(comma===-1)return url;return url.slice(0,comma+1)+\"…\"}function escapeRegExp(s){return s.replace(/[.*+?^${}()|[\\]\\\\]/g,\"\\\\$&\")}function longestCommonSubstring(s1,s2){let n=s1.length,m=s2.length,maxLen=0,endingIndex=0,dp=Array(n+1).fill(null).map(()=>Array(m+1).fill(0));for(let i=1;i<=n;i++)for(let j=1;j<=m;j++)if(s1[i-1]===s2[j-1]){if(dp[i][j]=dp[i-1][j-1]+1,dp[i][j]>maxLen)maxLen=dp[i][j],endingIndex=i}return s1.slice(endingIndex-maxLen,endingIndex)}var ansiRegex=new RegExp(\"([\\\\u001B\\\\u009B][[\\\\]()#?]*(?:(?:(?:[a-zA-Z\\\\d]*(?:;[-a-zA-Z\\\\d\\\\/#&.:=?%@~_]*)*)?\\\\u0007)|(?:(?:\\\\d{0,4}(?:;\\\\d{0,4})*)?[\\\\dA-PR-TZcf-ntqry=><~])))\",\"g\");function yamlEscapeKeyIfNeeded(str){if(!yamlStringNeedsQuotes(str))return str;return\"'\"+str.replace(/'/g,\"''\")+\"'\"}function yamlEscapeValueIfNeeded(str){if(!yamlStringNeedsQuotes(str))return str;return'\"'+str.replace(/[\\\\\"\\x00-\\x1f\\x7f-\\x9f]/g,(c)=>{switch(c){case\"\\\\\":return\"\\\\\\\\\";case'\"':return\"\\\\\\\"\";case\"\\b\":return\"\\\\b\";case\"\\f\":return\"\\\\f\";case`\n`:return\"\\\\n\";case\"\\r\":return\"\\\\r\";case\"\\t\":return\"\\\\t\";default:return\"\\\\x\"+c.charCodeAt(0).toString(16).padStart(2,\"0\")}})+'\"'}function yamlStringNeedsQuotes(str){if(str.length===0)return!0;if(/^\\s|\\s$/.test(str))return!0;if(/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f-\\x9f]/.test(str))return!0;if(/^-/.test(str))return!0;if(/[\\n:](\\s|$)/.test(str))return!0;if(/\\s#/.test(str))return!0;if(/[\\n\\r]/.test(str))return!0;if(/^[&*\\],?!>|@\"'#%]/.test(str))return!0;if(/[{}`]/.test(str))return!0;if(/^\\[/.test(str))return!0;if(!isNaN(Number(str))||[\"y\",\"n\",\"yes\",\"no\",\"true\",\"false\",\"on\",\"off\",\"null\"].includes(str.toLowerCase()))return!0;return!1}function distillAriaSnapshot(snapshot,options){runPlugins(snapshot,options.mode===\"ai\"?aiPlugins:normalizePlugins,options)}function runPlugins(snapshot,plugins,options){let ctx={snapshot,depth:-1,maxDepth:options.depth,ancestors:[],pendingContentRefs:new Set},traverse=(node,depth)=>{let children=[],visitChild=(child)=>{if(typeof child===\"string\"){children.push(child);return}ctx.depth=depth+1;for(let plugin of plugins){let result=plugin.enter?.(child,ctx);if(result===\"remove\")return;if(result===\"unwrap\"){child.children.forEach(visitChild);return}}traverse(child,depth+1),ctx.depth=depth+1;for(let plugin of plugins){let result=plugin.exit?.(child,ctx);if(result===\"remove\")return;if(result===\"unwrap\"){children.push(...child.children);return}}children.push(child)};ctx.ancestors.push(node),node.children.forEach(visitChild),ctx.ancestors.pop(),node.children=children};for(let plugin of plugins)plugin.enter?.(snapshot.root,ctx);traverse(snapshot.root,-1),ctx.depth=-1;for(let plugin of plugins)plugin.exit?.(snapshot.root,ctx)}function isLeafGeneric(node){return node.role===\"generic\"&&node.children.every((child)=>typeof child===\"string\")}var mergeStringChildren={name:\"mergeStringChildren\",exit(node){let children=[],buffer=[],flush=()=>{if(!buffer.length)return;let text=normalizeWhiteSpace(buffer.join(\"\"));if(text)children.push(text);buffer.length=0};for(let child of node.children)if(typeof child===\"string\")buffer.push(child);else flush(),children.push(child);if(flush(),node.children=children,node.children.length===1&&node.children[0]===node.name)node.children=[]}},unwrapSingleChildGenerics={name:\"unwrapSingleChildGenerics\",exit(node){if(node.role===\"generic\"&&!node.name&&node.children.length<=1&&node.children.every((child)=>typeof child!==\"string\"&&!!child.ref))return\"unwrap\"}},removeNamelessImages={name:\"removeNamelessImages\",exit(node){if(node.role===\"img\"&&!node.name&&!node.children.length)return\"remove\"}},removeRedundantNames={name:\"removeRedundantNames\",enter(node,ctx){if(!node.ref)return;for(let ref of ctx.snapshot.info.get(node.ref)?.nameFromContentRefs||[])ctx.pendingContentRefs.add(ref);if(!(!!ctx.maxDepth&&ctx.depth>ctx.maxDepth)&&!isLeafGeneric(node))ctx.pendingContentRefs.delete(node.ref)},exit(node,ctx){if(!node.ref)return;let nameFromContentRefs=ctx.snapshot.info.get(node.ref)?.nameFromContentRefs;if(!nameFromContentRefs?.length)return;if(nameFromContentRefs.every((ref)=>!ctx.pendingContentRefs.has(ref)))node.name=\"\";else for(let ref of nameFromContentRefs)ctx.pendingContentRefs.delete(ref)}},removeNameRepeatingChild={name:\"removeNameRepeatingChild\",exit(node,ctx){let parent=ctx.ancestors[ctx.ancestors.length-1];if(!parent?.name||node.role!==\"generic\"||node.active||Object.keys(node.props).length)return;let singleTextChild=node.children.length===1&&typeof node.children[0]===\"string\"?node.children[0]:void 0,text=node.name?node.children.length?void 0:node.name:singleTextChild;if(text&&text===parent.name)return\"remove\"}},inlineTextIntoGeneric={name:\"inlineTextIntoGeneric\",exit(node){if(node.role!==\"generic\"||Object.keys(node.props).length||node.children.length!==1)return;let child=node.children[0];if(typeof child===\"string\")return;if(child.role!==\"generic\"||child.name||child.active||Object.keys(child.props).length)return;if(child.children.length===1&&typeof child.children[0]===\"string\")node.children=[child.children[0]]}},normalizePlugins=[mergeStringChildren,unwrapSingleChildGenerics],aiPlugins=[mergeStringChildren,removeNamelessImages,removeRedundantNames,inlineTextIntoGeneric,removeNameRepeatingChild,unwrapSingleChildGenerics];var globalOptions={};function parentElementOrShadowHost(element){if(element.parentElement)return element.parentElement;if(!element.parentNode)return;if(element.parentNode.nodeType===11&&element.parentNode.host)return element.parentNode.host}function enclosingShadowRootOrDocument(element){let node=element;while(node.parentNode)node=node.parentNode;if(node.nodeType===11||node.nodeType===9)return node}function enclosingShadowHost(element){while(element.parentElement)element=element.parentElement;return parentElementOrShadowHost(element)}function closestCrossShadow(element,css,scope){while(element){let closest=element.closest(css);if(scope&&closest!==scope&&closest?.contains(scope))return;if(closest)return closest;element=enclosingShadowHost(element)}}function getElementComputedStyle(element,pseudo){let cache=pseudo===\"::before\"?cacheStyleBefore:pseudo===\"::after\"?cacheStyleAfter:cacheStyle;if(cache&&cache.has(element))return cache.get(element);let style=element.ownerDocument&&element.ownerDocument.defaultView?element.ownerDocument.defaultView.getComputedStyle(element,pseudo):void 0;return cache?.set(element,style),style}function isElementStyleVisibilityVisible(element,style){if(style=style??getElementComputedStyle(element),!style)return!0;if(Element.prototype.checkVisibility&&globalOptions.browserNameForWorkarounds!==\"webkit\"){if(!element.checkVisibility())return!1}else{let detailsOrSummary=element.closest(\"details,summary\");if(detailsOrSummary!==element&&detailsOrSummary?.nodeName===\"DETAILS\"&&!detailsOrSummary.open)return!1}if(style.visibility!==\"visible\")return!1;return!0}function computeBox(element){let style=getElementComputedStyle(element);if(!style)return{visible:!0,inline:!1};let cursor=style.cursor;if(style.display===\"contents\"){for(let child=element.firstChild;child;child=child.nextSibling){if(child.nodeType===1&&isElementVisible(child))return{visible:!0,inline:!1,cursor};if(child.nodeType===3&&isVisibleTextNode(child))return{visible:!0,inline:!0,cursor}}return{visible:!1,inline:!1,cursor}}if(!isElementStyleVisibilityVisible(element,style))return{cursor,visible:!1,inline:!1};let rect=element.getBoundingClientRect();return{cursor,visible:rect.width>0&&rect.height>0,inline:style.display===\"inline\"}}function isElementVisible(element){return computeBox(element).visible}function isVisibleTextNode(node){let range=node.ownerDocument.createRange();range.selectNode(node);let rect=range.getBoundingClientRect();return rect.width>0&&rect.height>0}function elementSafeTagName(element){let tagName=element.tagName;if(typeof tagName===\"string\")return tagName.toUpperCase();if(element instanceof HTMLFormElement)return\"FORM\";return element.tagName.toUpperCase()}var cacheStyle,cacheStyleBefore,cacheStyleAfter,cachesCounter=0;function beginDOMCaches(){++cachesCounter,cacheStyle??=new Map,cacheStyleBefore??=new Map,cacheStyleAfter??=new Map}function endDOMCaches(){if(!--cachesCounter)cacheStyle=void 0,cacheStyleBefore=void 0,cacheStyleAfter=void 0}var between=function(num,first,last){return num>=first&&num<=last};function digit(code){return between(code,48,57)}function hexdigit(code){return digit(code)||between(code,65,70)||between(code,97,102)}function uppercaseletter(code){return between(code,65,90)}function lowercaseletter(code){return between(code,97,122)}function letter(code){return uppercaseletter(code)||lowercaseletter(code)}function nonascii(code){return code>=128}function namestartchar(code){return letter(code)||nonascii(code)||code===95}function namechar(code){return namestartchar(code)||digit(code)||code===45}function nonprintable(code){return between(code,0,8)||code===11||between(code,14,31)||code===127}function newline(code){return code===10}function whitespace(code){return newline(code)||code===9||code===32}var maximumallowedcodepoint=1114111;class InvalidCharacterError extends Error{constructor(message){super(message);this.name=\"InvalidCharacterError\"}}function preprocess(str){let codepoints=[];for(let i=0;i<str.length;i++){let code=str.charCodeAt(i);if(code===13&&str.charCodeAt(i+1)===10)code=10,i++;if(code===13||code===12)code=10;if(code===0)code=65533;if(between(code,55296,56319)&&between(str.charCodeAt(i+1),56320,57343)){let lead=code-55296,trail=str.charCodeAt(i+1)-56320;code=Math.pow(2,16)+lead*Math.pow(2,10)+trail,i++}codepoints.push(code)}return codepoints}function stringFromCode(code){if(code<=65535)return String.fromCharCode(code);code-=Math.pow(2,16);let lead=Math.floor(code/Math.pow(2,10))+55296,trail=code%Math.pow(2,10)+56320;return String.fromCharCode(lead)+String.fromCharCode(trail)}function tokenize(str1){let str=preprocess(str1),i=-1,tokens=[],code,line=0,column=0,lastLineLength=0,incrLineno=function(){line+=1,lastLineLength=column,column=0},locStart={line,column},codepoint=function(i2){if(i2>=str.length)return-1;return str[i2]},next=function(num){if(num===void 0)num=1;if(num>3)throw\"Spec Error: no more than three codepoints of lookahead.\";return codepoint(i+num)},consume=function(num){if(num===void 0)num=1;if(i+=num,code=codepoint(i),newline(code))incrLineno();else column+=num;return!0},reconsume=function(){if(i-=1,newline(code))line-=1,column=lastLineLength;else column-=1;return locStart.line=line,locStart.column=column,!0},eof=function(codepoint2){if(codepoint2===void 0)codepoint2=code;return codepoint2===-1},donothing=function(){},parseerror=function(){},consumeAToken=function(){if(consumeComments(),consume(),whitespace(code)){while(whitespace(next()))consume();return new WhitespaceToken}else if(code===34)return consumeAStringToken();else if(code===35)if(namechar(next())||areAValidEscape(next(1),next(2))){let token=new HashToken(\"\");if(wouldStartAnIdentifier(next(1),next(2),next(3)))token.type=\"id\";return token.value=consumeAName(),token}else return new DelimToken(code);else if(code===36)if(next()===61)return consume(),new SuffixMatchToken;else return new DelimToken(code);else if(code===39)return consumeAStringToken();else if(code===40)return new OpenParenToken;else if(code===41)return new CloseParenToken;else if(code===42)if(next()===61)return consume(),new SubstringMatchToken;else return new DelimToken(code);else if(code===43)if(startsWithANumber())return reconsume(),consumeANumericToken();else return new DelimToken(code);else if(code===44)return new CommaToken;else if(code===45)if(startsWithANumber())return reconsume(),consumeANumericToken();else if(next(1)===45&&next(2)===62)return consume(2),new CDCToken;else if(startsWithAnIdentifier())return reconsume(),consumeAnIdentlikeToken();else return new DelimToken(code);else if(code===46)if(startsWithANumber())return reconsume(),consumeANumericToken();else return new DelimToken(code);else if(code===58)return new ColonToken;else if(code===59)return new SemicolonToken;else if(code===60)if(next(1)===33&&next(2)===45&&next(3)===45)return consume(3),new CDOToken;else return new DelimToken(code);else if(code===64)if(wouldStartAnIdentifier(next(1),next(2),next(3)))return new AtKeywordToken(consumeAName());else return new DelimToken(code);else if(code===91)return new OpenSquareToken;else if(code===92)if(startsWithAValidEscape())return reconsume(),consumeAnIdentlikeToken();else return parseerror(),new DelimToken(code);else if(code===93)return new CloseSquareToken;else if(code===94)if(next()===61)return consume(),new PrefixMatchToken;else return new DelimToken(code);else if(code===123)return new OpenCurlyToken;else if(code===124)if(next()===61)return consume(),new DashMatchToken;else if(next()===124)return consume(),new ColumnToken;else return new DelimToken(code);else if(code===125)return new CloseCurlyToken;else if(code===126)if(next()===61)return consume(),new IncludeMatchToken;else return new DelimToken(code);else if(digit(code))return reconsume(),consumeANumericToken();else if(namestartchar(code))return reconsume(),consumeAnIdentlikeToken();else if(eof())return new EOFToken;else return new DelimToken(code)},consumeComments=function(){while(next(1)===47&&next(2)===42){consume(2);while(!0)if(consume(),code===42&&next()===47){consume();break}else if(eof()){parseerror();return}}},consumeANumericToken=function(){let num=consumeANumber();if(wouldStartAnIdentifier(next(1),next(2),next(3))){let token=new DimensionToken;return token.value=num.value,token.repr=num.repr,token.type=num.type,token.unit=consumeAName(),token}else if(next()===37){consume();let token=new PercentageToken;return token.value=num.value,token.repr=num.repr,token}else{let token=new NumberToken;return token.value=num.value,token.repr=num.repr,token.type=num.type,token}},consumeAnIdentlikeToken=function(){let str2=consumeAName();if(str2.toLowerCase()===\"url\"&&next()===40){consume();while(whitespace(next(1))&&whitespace(next(2)))consume();if(next()===34||next()===39)return new FunctionToken(str2);else if(whitespace(next())&&(next(2)===34||next(2)===39))return new FunctionToken(str2);else return consumeAURLToken()}else if(next()===40)return consume(),new FunctionToken(str2);else return new IdentToken(str2)},consumeAStringToken=function(endingCodePoint){if(endingCodePoint===void 0)endingCodePoint=code;let string=\"\";while(consume())if(code===endingCodePoint||eof())return new StringToken(string);else if(newline(code))return parseerror(),reconsume(),new BadStringToken;else if(code===92)if(eof(next()))donothing();else if(newline(next()))consume();else string+=stringFromCode(consumeEscape());else string+=stringFromCode(code);throw Error(\"Internal error\")},consumeAURLToken=function(){let token=new URLToken(\"\");while(whitespace(next()))consume();if(eof(next()))return token;while(consume())if(code===41||eof())return token;else if(whitespace(code)){while(whitespace(next()))consume();if(next()===41||eof(next()))return consume(),token;else return consumeTheRemnantsOfABadURL(),new BadURLToken}else if(code===34||code===39||code===40||nonprintable(code))return parseerror(),consumeTheRemnantsOfABadURL(),new BadURLToken;else if(code===92)if(startsWithAValidEscape())token.value+=stringFromCode(consumeEscape());else return parseerror(),consumeTheRemnantsOfABadURL(),new BadURLToken;else token.value+=stringFromCode(code);throw Error(\"Internal error\")},consumeEscape=function(){if(consume(),hexdigit(code)){let digits=[code];for(let total=0;total<5;total++)if(hexdigit(next()))consume(),digits.push(code);else break;if(whitespace(next()))consume();let value=parseInt(digits.map(function(x){return String.fromCharCode(x)}).join(\"\"),16);if(value>maximumallowedcodepoint)value=65533;return value}else if(eof())return 65533;else return code},areAValidEscape=function(c1,c2){if(c1!==92)return!1;if(newline(c2))return!1;return!0},startsWithAValidEscape=function(){return areAValidEscape(code,next())},wouldStartAnIdentifier=function(c1,c2,c3){if(c1===45)return namestartchar(c2)||c2===45||areAValidEscape(c2,c3);else if(namestartchar(c1))return!0;else if(c1===92)return areAValidEscape(c1,c2);else return!1},startsWithAnIdentifier=function(){return wouldStartAnIdentifier(code,next(1),next(2))},wouldStartANumber=function(c1,c2,c3){if(c1===43||c1===45){if(digit(c2))return!0;if(c2===46&&digit(c3))return!0;return!1}else if(c1===46){if(digit(c2))return!0;return!1}else if(digit(c1))return!0;else return!1},startsWithANumber=function(){return wouldStartANumber(code,next(1),next(2))},consumeAName=function(){let result=\"\";while(consume())if(namechar(code))result+=stringFromCode(code);else if(startsWithAValidEscape())result+=stringFromCode(consumeEscape());else return reconsume(),result;throw Error(\"Internal parse error\")},consumeANumber=function(){let repr=\"\",type=\"integer\";if(next()===43||next()===45)consume(),repr+=stringFromCode(code);while(digit(next()))consume(),repr+=stringFromCode(code);if(next(1)===46&&digit(next(2))){consume(),repr+=stringFromCode(code),consume(),repr+=stringFromCode(code),type=\"number\";while(digit(next()))consume(),repr+=stringFromCode(code)}let c1=next(1),c2=next(2),c3=next(3);if((c1===69||c1===101)&&digit(c2)){consume(),repr+=stringFromCode(code),consume(),repr+=stringFromCode(code),type=\"number\";while(digit(next()))consume(),repr+=stringFromCode(code)}else if((c1===69||c1===101)&&(c2===43||c2===45)&&digit(c3)){consume(),repr+=stringFromCode(code),consume(),repr+=stringFromCode(code),consume(),repr+=stringFromCode(code),type=\"number\";while(digit(next()))consume(),repr+=stringFromCode(code)}let value=convertAStringToANumber(repr);return{type,value,repr}},convertAStringToANumber=function(string){return+string},consumeTheRemnantsOfABadURL=function(){while(consume())if(code===41||eof())return;else if(startsWithAValidEscape())consumeEscape(),donothing();else donothing()},iterationCount=0;while(!eof(next()))if(tokens.push(consumeAToken()),iterationCount++,iterationCount>str.length*2)throw Error(\"I'm infinite-looping!\");return tokens}class CSSParserToken{tokenType=\"\";value;toJSON(){return{token:this.tokenType}}toString(){return this.tokenType}toSource(){return\"\"+this}}class BadStringToken extends CSSParserToken{tokenType=\"BADSTRING\"}class BadURLToken extends CSSParserToken{tokenType=\"BADURL\"}class WhitespaceToken extends CSSParserToken{tokenType=\"WHITESPACE\";toString(){return\"WS\"}toSource(){return\" \"}}class CDOToken extends CSSParserToken{tokenType=\"CDO\";toSource(){return\"<!--\"}}class CDCToken extends CSSParserToken{tokenType=\"CDC\";toSource(){return\"-->\"}}class ColonToken extends CSSParserToken{tokenType=\":\"}class SemicolonToken extends CSSParserToken{tokenType=\";\"}class CommaToken extends CSSParserToken{tokenType=\",\"}class GroupingToken extends CSSParserToken{value=\"\";mirror=\"\"}class OpenCurlyToken extends GroupingToken{tokenType=\"{\";constructor(){super();this.value=\"{\",this.mirror=\"}\"}}class CloseCurlyToken extends GroupingToken{tokenType=\"}\";constructor(){super();this.value=\"}\",this.mirror=\"{\"}}class OpenSquareToken extends GroupingToken{tokenType=\"[\";constructor(){super();this.value=\"[\",this.mirror=\"]\"}}class CloseSquareToken extends GroupingToken{tokenType=\"]\";constructor(){super();this.value=\"]\",this.mirror=\"[\"}}class OpenParenToken extends GroupingToken{tokenType=\"(\";constructor(){super();this.value=\"(\",this.mirror=\")\"}}class CloseParenToken extends GroupingToken{tokenType=\")\";constructor(){super();this.value=\")\",this.mirror=\"(\"}}class IncludeMatchToken extends CSSParserToken{tokenType=\"~=\"}class DashMatchToken extends CSSParserToken{tokenType=\"|=\"}class PrefixMatchToken extends CSSParserToken{tokenType=\"^=\"}class SuffixMatchToken extends CSSParserToken{tokenType=\"$=\"}class SubstringMatchToken extends CSSParserToken{tokenType=\"*=\"}class ColumnToken extends CSSParserToken{tokenType=\"||\"}class EOFToken extends CSSParserToken{tokenType=\"EOF\";toSource(){return\"\"}}class DelimToken extends CSSParserToken{tokenType=\"DELIM\";value=\"\";constructor(code){super();this.value=stringFromCode(code)}toString(){return\"DELIM(\"+this.value+\")\"}toJSON(){let json=this.constructor.prototype.constructor.prototype.toJSON.call(this);return json.value=this.value,json}toSource(){if(this.value===\"\\\\\")return\"\\\\\\n\";else return this.value}}class StringValuedToken extends CSSParserToken{value=\"\";ASCIIMatch(str){return this.value.toLowerCase()===str.toLowerCase()}toJSON(){let json=this.constructor.prototype.constructor.prototype.toJSON.call(this);return json.value=this.value,json}}class IdentToken extends StringValuedToken{constructor(val){super();this.value=val}tokenType=\"IDENT\";toString(){return\"IDENT(\"+this.value+\")\"}toSource(){return escapeIdent(this.value)}}class FunctionToken extends StringValuedToken{tokenType=\"FUNCTION\";mirror;constructor(val){super();this.value=val,this.mirror=\")\"}toString(){return\"FUNCTION(\"+this.value+\")\"}toSource(){return escapeIdent(this.value)+\"(\"}}class AtKeywordToken extends StringValuedToken{tokenType=\"AT-KEYWORD\";constructor(val){super();this.value=val}toString(){return\"AT(\"+this.value+\")\"}toSource(){return\"@\"+escapeIdent(this.value)}}class HashToken extends StringValuedToken{tokenType=\"HASH\";type;constructor(val){super();this.value=val,this.type=\"unrestricted\"}toString(){return\"HASH(\"+this.value+\")\"}toJSON(){let json=this.constructor.prototype.constructor.prototype.toJSON.call(this);return json.value=this.value,json.type=this.type,json}toSource(){if(this.type===\"id\")return\"#\"+escapeIdent(this.value);else return\"#\"+escapeHash(this.value)}}class StringToken extends StringValuedToken{tokenType=\"STRING\";constructor(val){super();this.value=val}toString(){return'\"'+escapeString(this.value)+'\"'}}class URLToken extends StringValuedToken{tokenType=\"URL\";constructor(val){super();this.value=val}toString(){return\"URL(\"+this.value+\")\"}toSource(){return'url(\"'+escapeString(this.value)+'\")'}}class NumberToken extends CSSParserToken{tokenType=\"NUMBER\";type;repr;constructor(){super();this.type=\"integer\",this.repr=\"\"}toString(){if(this.type===\"integer\")return\"INT(\"+this.value+\")\";return\"NUMBER(\"+this.value+\")\"}toJSON(){let json=super.toJSON();return json.value=this.value,json.type=this.type,json.repr=this.repr,json}toSource(){return this.repr}}class PercentageToken extends CSSParserToken{tokenType=\"PERCENTAGE\";repr;constructor(){super();this.repr=\"\"}toString(){return\"PERCENTAGE(\"+this.value+\")\"}toJSON(){let json=this.constructor.prototype.constructor.prototype.toJSON.call(this);return json.value=this.value,json.repr=this.repr,json}toSource(){return this.repr+\"%\"}}class DimensionToken extends CSSParserToken{tokenType=\"DIMENSION\";type;repr;unit;constructor(){super();this.type=\"integer\",this.repr=\"\",this.unit=\"\"}toString(){return\"DIM(\"+this.value+\",\"+this.unit+\")\"}toJSON(){let json=this.constructor.prototype.constructor.prototype.toJSON.call(this);return json.value=this.value,json.type=this.type,json.repr=this.repr,json.unit=this.unit,json}toSource(){let source=this.repr,unit=escapeIdent(this.unit);if(unit[0].toLowerCase()===\"e\"&&(unit[1]===\"-\"||between(unit.charCodeAt(1),48,57)))unit=\"\\\\65 \"+unit.slice(1,unit.length);return source+unit}}function escapeIdent(string){string=\"\"+string;let result=\"\",firstcode=string.charCodeAt(0);for(let i=0;i<string.length;i++){let code=string.charCodeAt(i);if(code===0)throw new InvalidCharacterError(\"Invalid character: the input contains U+0000.\");if(between(code,1,31)||code===127||i===0&&between(code,48,57)||i===1&&between(code,48,57)&&firstcode===45)result+=\"\\\\\"+code.toString(16)+\" \";else if(code>=128||code===45||code===95||between(code,48,57)||between(code,65,90)||between(code,97,122))result+=string[i];else result+=\"\\\\\"+string[i]}return result}function escapeHash(string){string=\"\"+string;let result=\"\";for(let i=0;i<string.length;i++){let code=string.charCodeAt(i);if(code===0)throw new InvalidCharacterError(\"Invalid character: the input contains U+0000.\");if(code>=128||code===45||code===95||between(code,48,57)||between(code,65,90)||between(code,97,122))result+=string[i];else result+=\"\\\\\"+code.toString(16)+\" \"}return result}function escapeString(string){string=\"\"+string;let result=\"\";for(let i=0;i<string.length;i++){let code=string.charCodeAt(i);if(code===0)throw new InvalidCharacterError(\"Invalid character: the input contains U+0000.\");if(between(code,1,31)||code===127)result+=\"\\\\\"+code.toString(16)+\" \";else if(code===34||code===92)result+=\"\\\\\"+string[i];else result+=string[i]}return result}function hasExplicitAccessibleName(e){return e.hasAttribute(\"aria-label\")||e.hasAttribute(\"aria-labelledby\")}var kAncestorPreventingLandmark=\"article:not([role]), aside:not([role]), main:not([role]), nav:not([role]), section:not([role]), [role=article], [role=complementary], [role=main], [role=navigation], [role=region]\",kGlobalAriaAttributes=[[\"aria-atomic\",void 0],[\"aria-busy\",void 0],[\"aria-controls\",void 0],[\"aria-current\",void 0],[\"aria-describedby\",void 0],[\"aria-details\",void 0],[\"aria-dropeffect\",void 0],[\"aria-flowto\",void 0],[\"aria-grabbed\",void 0],[\"aria-hidden\",void 0],[\"aria-keyshortcuts\",void 0],[\"aria-label\",[\"caption\",\"code\",\"deletion\",\"emphasis\",\"generic\",\"insertion\",\"paragraph\",\"presentation\",\"strong\",\"subscript\",\"superscript\"]],[\"aria-labelledby\",[\"caption\",\"code\",\"deletion\",\"emphasis\",\"generic\",\"insertion\",\"paragraph\",\"presentation\",\"strong\",\"subscript\",\"superscript\"]],[\"aria-live\",void 0],[\"aria-owns\",void 0],[\"aria-relevant\",void 0],[\"aria-roledescription\",[\"generic\"]]];function hasGlobalAriaAttribute(element,forRole){return kGlobalAriaAttributes.some(([attr,prohibited])=>{return!prohibited?.includes(forRole||\"\")&&element.hasAttribute(attr)})}function hasTabIndex(element){return!Number.isNaN(Number(String(element.getAttribute(\"tabindex\"))))}function isFocusable(element){return!isNativelyDisabled(element)&&(isNativelyFocusable(element)||hasTabIndex(element))}function isNativelyFocusable(element){let tagName=elementSafeTagName(element);if([\"BUTTON\",\"DETAILS\",\"SELECT\",\"TEXTAREA\"].includes(tagName))return!0;if(tagName===\"A\"||tagName===\"AREA\")return element.hasAttribute(\"href\");if(tagName===\"INPUT\")return!element.hidden;return!1}var kImplicitRoleByTagName={A:(e)=>{return e.hasAttribute(\"href\")?\"link\":null},AREA:(e)=>{return e.hasAttribute(\"href\")?\"link\":null},ARTICLE:()=>\"article\",ASIDE:()=>\"complementary\",BLOCKQUOTE:()=>\"blockquote\",BUTTON:()=>\"button\",CAPTION:()=>\"caption\",CODE:()=>\"code\",DATALIST:()=>\"listbox\",DD:()=>\"definition\",DEL:()=>\"deletion\",DETAILS:()=>\"group\",DFN:()=>\"term\",DIALOG:()=>\"dialog\",DT:()=>\"term\",EM:()=>\"emphasis\",FIELDSET:()=>\"group\",FIGURE:()=>\"figure\",FOOTER:(e)=>closestCrossShadow(e,kAncestorPreventingLandmark)?null:\"contentinfo\",FORM:(e)=>hasExplicitAccessibleName(e)?\"form\":null,H1:()=>\"heading\",H2:()=>\"heading\",H3:()=>\"heading\",H4:()=>\"heading\",H5:()=>\"heading\",H6:()=>\"heading\",HEADER:(e)=>closestCrossShadow(e,kAncestorPreventingLandmark)?null:\"banner\",HR:()=>\"separator\",HTML:()=>\"document\",IMG:(e)=>e.getAttribute(\"alt\")===\"\"&&!e.getAttribute(\"title\")&&!hasGlobalAriaAttribute(e)&&!hasTabIndex(e)?\"presentation\":\"img\",INPUT:(e)=>{let type=e.type.toLowerCase();if(type===\"search\")return e.hasAttribute(\"list\")?\"combobox\":\"searchbox\";if([\"email\",\"tel\",\"text\",\"url\",\"\"].includes(type)){let list=getIdRefs(e,e.getAttribute(\"list\"))[0];return list&&elementSafeTagName(list)===\"DATALIST\"?\"combobox\":\"textbox\"}if(type===\"hidden\")return null;if(type===\"file\")return\"button\";return inputTypeToRole[type]||\"textbox\"},INS:()=>\"insertion\",LI:()=>\"listitem\",MAIN:()=>\"main\",MARK:()=>\"mark\",MATH:()=>\"math\",MENU:()=>\"list\",METER:()=>\"meter\",NAV:()=>\"navigation\",OL:()=>\"list\",OPTGROUP:()=>\"group\",OPTION:()=>\"option\",OUTPUT:()=>\"status\",P:()=>\"paragraph\",PROGRESS:()=>\"progressbar\",SEARCH:()=>\"search\",SECTION:(e)=>hasExplicitAccessibleName(e)?\"region\":null,SELECT:(e)=>e.hasAttribute(\"multiple\")||e.size>1?\"listbox\":\"combobox\",STRONG:()=>\"strong\",SUB:()=>\"subscript\",SUP:()=>\"superscript\",SVG:()=>\"img\",TABLE:()=>\"table\",TBODY:()=>\"rowgroup\",TD:(e)=>{let table=closestCrossShadow(e,\"table\"),role=table?getExplicitAriaRole(table):\"\";return role===\"grid\"||role===\"treegrid\"?\"gridcell\":\"cell\"},TEXTAREA:()=>\"textbox\",TFOOT:()=>\"rowgroup\",TH:(e)=>{let scope=e.getAttribute(\"scope\");if(scope===\"col\"||scope===\"colgroup\")return\"columnheader\";if(scope===\"row\"||scope===\"rowgroup\")return\"rowheader\";let{nextElementSibling:nextSibling,previousElementSibling:prevSibling}=e,row=!!e.parentElement&&elementSafeTagName(e.parentElement)===\"TR\"?e.parentElement:void 0;if(!nextSibling&&!prevSibling){if(row){let table=closestCrossShadow(row,\"table\");if(table&&table.rows.length<=1)return null}return\"columnheader\"}if(isHeaderCell(nextSibling)&&isHeaderCell(prevSibling))return\"columnheader\";if(isNonEmptyDataCell(nextSibling)||isNonEmptyDataCell(prevSibling))return\"rowheader\";return\"columnheader\"},THEAD:()=>\"rowgroup\",TIME:()=>\"time\",TR:()=>\"row\",UL:()=>\"list\"};function isHeaderCell(element){return!!element&&elementSafeTagName(element)===\"TH\"}function isNonEmptyDataCell(element){if(!element||elementSafeTagName(element)!==\"TD\")return!1;return!!(element.textContent?.trim()||element.children.length>0)}var kPresentationInheritanceParents={DD:[\"DL\",\"DIV\"],DIV:[\"DL\"],DT:[\"DL\",\"DIV\"],LI:[\"OL\",\"UL\"],TBODY:[\"TABLE\"],TD:[\"TR\"],TFOOT:[\"TABLE\"],TH:[\"TR\"],THEAD:[\"TABLE\"],TR:[\"THEAD\",\"TBODY\",\"TFOOT\",\"TABLE\"]};function getImplicitAriaRole(element){let implicitRole=kImplicitRoleByTagName[elementSafeTagName(element)]?.(element)||\"\";if(!implicitRole)return null;let ancestor=element;while(ancestor){let parent=parentElementOrShadowHost(ancestor),parents=kPresentationInheritanceParents[elementSafeTagName(ancestor)];if(!parents||!parent||!parents.includes(elementSafeTagName(parent)))break;let parentExplicitRole=getExplicitAriaRole(parent);if((parentExplicitRole===\"none\"||parentExplicitRole===\"presentation\")&&!hasPresentationConflictResolution(parent,parentExplicitRole))return parentExplicitRole;ancestor=parent}return implicitRole}var validRoles=[\"alert\",\"alertdialog\",\"application\",\"article\",\"banner\",\"blockquote\",\"button\",\"caption\",\"cell\",\"checkbox\",\"code\",\"columnheader\",\"combobox\",\"complementary\",\"contentinfo\",\"definition\",\"deletion\",\"dialog\",\"directory\",\"document\",\"emphasis\",\"feed\",\"figure\",\"form\",\"generic\",\"grid\",\"gridcell\",\"group\",\"heading\",\"img\",\"insertion\",\"link\",\"list\",\"listbox\",\"listitem\",\"log\",\"main\",\"mark\",\"marquee\",\"math\",\"meter\",\"menu\",\"menubar\",\"menuitem\",\"menuitemcheckbox\",\"menuitemradio\",\"navigation\",\"none\",\"note\",\"option\",\"paragraph\",\"presentation\",\"progressbar\",\"radio\",\"radiogroup\",\"region\",\"row\",\"rowgroup\",\"rowheader\",\"scrollbar\",\"search\",\"searchbox\",\"separator\",\"slider\",\"spinbutton\",\"status\",\"strong\",\"subscript\",\"superscript\",\"switch\",\"tab\",\"table\",\"tablist\",\"tabpanel\",\"term\",\"textbox\",\"time\",\"timer\",\"toolbar\",\"tooltip\",\"tree\",\"treegrid\",\"treeitem\"];function getExplicitAriaRole(element){return(element.getAttribute(\"role\")||\"\").split(\" \").map((role)=>role.trim()).find((role)=>validRoles.includes(role))||null}function hasPresentationConflictResolution(element,role){return hasGlobalAriaAttribute(element,role)||isFocusable(element)}function getAriaRole(element){let explicitRole=getExplicitAriaRole(element);if(!explicitRole)return getImplicitAriaRole(element);if(explicitRole===\"none\"||explicitRole===\"presentation\"){let implicitRole=getImplicitAriaRole(element);if(hasPresentationConflictResolution(element,implicitRole))return implicitRole}return explicitRole}function getAriaBoolean(attr){return attr===null?void 0:attr.toLowerCase()===\"true\"}function isElementIgnoredForAria(element){return[\"STYLE\",\"SCRIPT\",\"NOSCRIPT\",\"TEMPLATE\"].includes(elementSafeTagName(element))}function isElementHiddenForAria(element){if(isElementIgnoredForAria(element))return!0;let style=getElementComputedStyle(element),isSlot=element.nodeName===\"SLOT\";if(style?.display===\"contents\"&&!isSlot){for(let child=element.firstChild;child;child=child.nextSibling){if(child.nodeType===1&&!isElementHiddenForAria(child))return!1;if(child.nodeType===3&&isVisibleTextNode(child))return!1}return!0}if(!(element.nodeName===\"OPTION\"&&!!element.closest(\"select\"))&&!isSlot&&!isElementStyleVisibilityVisible(element,style))return!0;return belongsToDisplayNoneOrAriaHiddenOrNonSlotted(element)}function belongsToDisplayNoneOrAriaHiddenOrNonSlotted(element){let hidden=cacheIsHidden?.get(element);if(hidden===void 0){if(hidden=!1,element.parentElement&&element.parentElement.shadowRoot&&!element.assignedSlot)hidden=!0;if(!hidden){let style=getElementComputedStyle(element);hidden=!style||style.display===\"none\"||getAriaBoolean(element.getAttribute(\"aria-hidden\"))===!0}if(!hidden){let parent=parentElementOrShadowHost(element);if(parent)hidden=belongsToDisplayNoneOrAriaHiddenOrNonSlotted(parent)}cacheIsHidden?.set(element,hidden)}return hidden}function getIdRefs(element,ref){if(!ref)return[];let root=enclosingShadowRootOrDocument(element);if(!root)return[];try{let ids=ref.split(\" \").filter((id)=>!!id),result=[];for(let id of ids){let firstElement=root.querySelector(\"#\"+CSS.escape(id));if(firstElement&&!result.includes(firstElement))result.push(firstElement)}return result}catch(e){return[]}}function trimFlatString(s){return s.trim()}function asFlatString(s){return s.split(\" \").map((chunk)=>chunk.replace(/\\r\\n/g,`\n`).replace(/[\\u200b\\u00ad]/g,\"\").replace(/\\s\\s*/g,\" \")).join(\" \").trim()}function queryInAriaOwned(element,selector){let result=[...element.querySelectorAll(selector)];for(let owned of getIdRefs(element,element.getAttribute(\"aria-owns\"))){if(owned.matches(selector))result.push(owned);result.push(...owned.querySelectorAll(selector))}return result}function getCSSContent(element,pseudo){let cache=pseudo===\"::before\"?cachePseudoContentBefore:pseudo===\"::after\"?cachePseudoContentAfter:cachePseudoContent;if(cache?.has(element))return cache?.get(element);let style=getElementComputedStyle(element,pseudo),content;if(style){let contentValue=style.content;if(contentValue&&contentValue!==\"none\"&&contentValue!==\"normal\"){if(style.display!==\"none\"&&style.visibility!==\"hidden\")content=parseCSSContentPropertyAsString(element,contentValue,!!pseudo)}}if(pseudo&&content!==void 0){if((style?.display||\"inline\")!==\"inline\")content=\" \"+content+\" \"}if(cache)cache.set(element,content);return content}function parseCSSContentPropertyAsString(element,content,isPseudo){if(!content||content===\"none\"||content===\"normal\")return;try{let tokens=tokenize(content).filter((token)=>!(token instanceof WhitespaceToken)),delimIndex=tokens.findIndex((token)=>token instanceof DelimToken&&token.value===\"/\");if(delimIndex!==-1)tokens=tokens.slice(delimIndex+1);else if(!isPseudo)return;let accumulated=[],index=0;while(index<tokens.length)if(tokens[index]instanceof StringToken)accumulated.push(tokens[index].value),index++;else if(index+2<tokens.length&&tokens[index]instanceof FunctionToken&&tokens[index].value===\"attr\"&&tokens[index+1]instanceof IdentToken&&tokens[index+2]instanceof CloseParenToken){let attrName=tokens[index+1].value;accumulated.push(element.getAttribute(attrName)||\"\"),index+=3}else return;return accumulated.join(\"\")}catch{}}function getAriaLabelledByElements(element){let ref=element.getAttribute(\"aria-labelledby\");if(ref===null)return null;let refs=getIdRefs(element,ref);return refs.length?refs:null}function allowsNameFromContent(role,targetDescendant){let alwaysAllowsNameFromContent=[\"button\",\"cell\",\"checkbox\",\"columnheader\",\"gridcell\",\"heading\",\"link\",\"menuitem\",\"menuitemcheckbox\",\"menuitemradio\",\"option\",\"radio\",\"row\",\"rowheader\",\"switch\",\"tab\",\"tooltip\",\"treeitem\"].includes(role),descendantAllowsNameFromContent=targetDescendant&&[\"\",\"caption\",\"code\",\"contentinfo\",\"definition\",\"deletion\",\"emphasis\",\"insertion\",\"list\",\"listitem\",\"mark\",\"none\",\"paragraph\",\"presentation\",\"region\",\"row\",\"rowgroup\",\"section\",\"strong\",\"subscript\",\"superscript\",\"table\",\"term\",\"time\"].includes(role);return alwaysAllowsNameFromContent||descendantAllowsNameFromContent}function computeAccessibleNameComposite(element,includeHidden,collectElements){if([\"caption\",\"code\",\"definition\",\"deletion\",\"emphasis\",\"generic\",\"insertion\",\"mark\",\"paragraph\",\"presentation\",\"strong\",\"subscript\",\"suggestion\",\"superscript\",\"term\",\"time\"].includes(getAriaRole(element)||\"\"))return emptyCompositeString();let result=getTextAlternativeInternal(element,{includeHidden,collectElements,visitedElements:new Set,embeddedInTargetElement:\"self\"});return{text:asFlatString(result.text),elements:result.elements}}function getElementAccessibleName(element,includeHidden){let cache=includeHidden?cacheAccessibleNameHidden:cacheAccessibleName,accessibleName=cache?.get(element);if(accessibleName===void 0)accessibleName=computeAccessibleNameComposite(element,includeHidden,!0),cache?.set(element,accessibleName);return accessibleName}var kAriaInvalidRoles=[\"application\",\"checkbox\",\"columnheader\",\"combobox\",\"gridcell\",\"listbox\",\"radiogroup\",\"rowheader\",\"searchbox\",\"slider\",\"spinbutton\",\"switch\",\"textbox\",\"tree\"];function getAriaInvalid(element){let ariaInvalid=element.getAttribute(\"aria-invalid\");if(!ariaInvalid||ariaInvalid.trim()===\"\"||ariaInvalid.toLocaleLowerCase()===\"false\")return\"false\";if(ariaInvalid===\"true\"||ariaInvalid===\"grammar\"||ariaInvalid===\"spelling\")return ariaInvalid;return\"true\"}function getTextAlternativeInternal(element,options){if(options.visitedElements.has(element))return emptyCompositeString();let childOptions={...options,embeddedInTargetElement:options.embeddedInTargetElement===\"self\"?\"descendant\":options.embeddedInTargetElement};if(!options.includeHidden){let isEmbeddedInHiddenReferenceTraversal=!!options.embeddedInLabelledBy?.hidden||!!options.embeddedInDescribedBy?.hidden||!!options.embeddedInNativeTextAlternative?.hidden||!!options.embeddedInLabel?.hidden;if(isElementIgnoredForAria(element)||!isEmbeddedInHiddenReferenceTraversal&&isElementHiddenForAria(element))return options.visitedElements.add(element),emptyCompositeString()}let labelledBy=getAriaLabelledByElements(element);if(!options.embeddedInLabelledBy){let accessibleName=joinCompositeString((labelledBy||[]).map((ref)=>getTextAlternativeInternal(ref,{...options,embeddedInLabelledBy:{element:ref,hidden:isElementHiddenForAria(ref)},embeddedInDescribedBy:void 0,embeddedInTargetElement:void 0,embeddedInLabel:void 0,embeddedInNativeTextAlternative:void 0})),\" \",options.collectElements);if(accessibleName.text)return accessibleName}let role=getAriaRole(element)||\"\",tagName=elementSafeTagName(element);if(!!options.embeddedInLabel||!!options.embeddedInLabelledBy||options.embeddedInTargetElement===\"descendant\"){let isOwnLabel=[...element.labels||[]].includes(element),isOwnLabelledBy=(labelledBy||[]).includes(element);if(!isOwnLabel&&!isOwnLabelledBy){if(role===\"textbox\"){if(options.visitedElements.add(element),tagName===\"INPUT\"||tagName===\"TEXTAREA\")return compositeString(element.value,element,options.collectElements);return compositeString(element.textContent,element,options.collectElements)}if([\"combobox\",\"listbox\"].includes(role)){options.visitedElements.add(element);let selectedOptions;if(tagName===\"SELECT\"){if(selectedOptions=[...element.selectedOptions],!selectedOptions.length&&element.options.length)selectedOptions.push(element.options[0])}else{let listbox=role===\"combobox\"?queryInAriaOwned(element,\"*\").find((e)=>getAriaRole(e)===\"listbox\"):element;selectedOptions=listbox?queryInAriaOwned(listbox,'[aria-selected=\"true\"]').filter((e)=>getAriaRole(e)===\"option\"):[]}if(!selectedOptions.length&&tagName===\"INPUT\")return compositeString(element.value,element,options.collectElements);return joinCompositeString(selectedOptions.map((option)=>getTextAlternativeInternal(option,childOptions)),\" \",options.collectElements)}if([\"progressbar\",\"scrollbar\",\"slider\",\"spinbutton\",\"meter\"].includes(role)){if(options.visitedElements.add(element),element.hasAttribute(\"aria-valuetext\"))return compositeString(element.getAttribute(\"aria-valuetext\"),element,options.collectElements);if(element.hasAttribute(\"aria-valuenow\"))return compositeString(element.getAttribute(\"aria-valuenow\"),element,options.collectElements);return compositeString(element.getAttribute(\"value\"),element,options.collectElements)}if([\"menu\"].includes(role))return options.visitedElements.add(element),emptyCompositeString()}}let ariaLabel=element.getAttribute(\"aria-label\")||\"\";if(trimFlatString(ariaLabel))return options.visitedElements.add(element),compositeString(ariaLabel,element,options.collectElements);if(![\"presentation\",\"none\"].includes(role)){if(tagName===\"INPUT\"&&[\"button\",\"submit\",\"reset\"].includes(element.type)){options.visitedElements.add(element);let value=element.value||\"\";if(trimFlatString(value))return compositeString(value,element,options.collectElements);if(element.type===\"submit\")return compositeString(\"Submit\",element,options.collectElements);if(element.type===\"reset\")return compositeString(\"Reset\",element,options.collectElements);let title=element.getAttribute(\"title\")||\"\";return compositeString(title,element,options.collectElements)}if(tagName===\"INPUT\"&&element.type===\"file\"){options.visitedElements.add(element);let labels=element.labels||[];if(labels.length&&!options.embeddedInLabelledBy)return getAccessibleNameFromAssociatedLabels(labels,options);return compositeString(\"Choose File\",element,options.collectElements)}if(tagName===\"INPUT\"&&element.type===\"image\"){options.visitedElements.add(element);let labels=element.labels||[];if(labels.length&&!options.embeddedInLabelledBy)return getAccessibleNameFromAssociatedLabels(labels,options);let alt=element.getAttribute(\"alt\")||\"\";if(trimFlatString(alt))return compositeString(alt,element,options.collectElements);let title=element.getAttribute(\"title\")||\"\";if(trimFlatString(title))return compositeString(title,element,options.collectElements);return compositeString(\"Submit\",element,options.collectElements)}if(!labelledBy&&tagName===\"BUTTON\"){options.visitedElements.add(element);let labels=element.labels||[];if(labels.length)return getAccessibleNameFromAssociatedLabels(labels,options)}if(!labelledBy&&tagName===\"OUTPUT\"){options.visitedElements.add(element);let labels=element.labels||[];if(labels.length)return getAccessibleNameFromAssociatedLabels(labels,options);return compositeString(element.getAttribute(\"title\")||\"\",element,options.collectElements)}if(!labelledBy&&(tagName===\"TEXTAREA\"||tagName===\"SELECT\"||tagName===\"INPUT\")){options.visitedElements.add(element);let labels=element.labels||[];if(labels.length)return getAccessibleNameFromAssociatedLabels(labels,options);let usePlaceholder=tagName===\"INPUT\"&&[\"text\",\"password\",\"number\",\"search\",\"tel\",\"email\",\"url\"].includes(element.type)||tagName===\"TEXTAREA\",placeholder=element.getAttribute(\"placeholder\")||\"\",title=element.getAttribute(\"title\")||\"\";if(!usePlaceholder||title)return compositeString(title,element,options.collectElements);return compositeString(placeholder,element,options.collectElements)}if(!labelledBy&&tagName===\"FIELDSET\"){options.visitedElements.add(element);for(let child=element.firstElementChild;child;child=child.nextElementSibling)if(elementSafeTagName(child)===\"LEGEND\")return getTextAlternativeInternal(child,{...childOptions,embeddedInNativeTextAlternative:{element:child,hidden:isElementHiddenForAria(child)}});let title=element.getAttribute(\"title\")||\"\";return compositeString(title,element,options.collectElements)}if(!labelledBy&&tagName===\"FIGURE\"){options.visitedElements.add(element);for(let child=element.firstElementChild;child;child=child.nextElementSibling)if(elementSafeTagName(child)===\"FIGCAPTION\")return getTextAlternativeInternal(child,{...childOptions,embeddedInNativeTextAlternative:{element:child,hidden:isElementHiddenForAria(child)}});let title=element.getAttribute(\"title\")||\"\";return compositeString(title,element,options.collectElements)}if(tagName===\"IMG\"){options.visitedElements.add(element);let alt=element.getAttribute(\"alt\")||\"\";if(trimFlatString(alt))return compositeString(alt,element,options.collectElements);let title=element.getAttribute(\"title\")||\"\";return compositeString(title,element,options.collectElements)}if(tagName===\"TABLE\"){options.visitedElements.add(element);for(let child=element.firstElementChild;child;child=child.nextElementSibling)if(elementSafeTagName(child)===\"CAPTION\")return getTextAlternativeInternal(child,{...childOptions,embeddedInNativeTextAlternative:{element:child,hidden:isElementHiddenForAria(child)}});let summary=element.getAttribute(\"summary\")||\"\";if(summary)return compositeString(summary,element,options.collectElements)}if(tagName===\"AREA\"){options.visitedElements.add(element);let alt=element.getAttribute(\"alt\")||\"\";if(trimFlatString(alt))return compositeString(alt,element,options.collectElements);let title=element.getAttribute(\"title\")||\"\";return compositeString(title,element,options.collectElements)}if(tagName===\"SVG\"||element.ownerSVGElement){options.visitedElements.add(element);for(let child=element.firstElementChild;child;child=child.nextElementSibling)if(elementSafeTagName(child)===\"TITLE\"&&child.ownerSVGElement)return getTextAlternativeInternal(child,{...childOptions,embeddedInLabelledBy:{element:child,hidden:isElementHiddenForAria(child)}})}if(element.ownerSVGElement&&tagName===\"A\"){let title=element.getAttribute(\"xlink:title\")||\"\";if(trimFlatString(title))return options.visitedElements.add(element),compositeString(title,element,options.collectElements)}}let shouldNameFromContentForSummary=tagName===\"SUMMARY\"&&![\"presentation\",\"none\"].includes(role);if(allowsNameFromContent(role,options.embeddedInTargetElement===\"descendant\")||shouldNameFromContentForSummary||!!options.embeddedInLabelledBy||!!options.embeddedInDescribedBy||!!options.embeddedInLabel||!!options.embeddedInNativeTextAlternative){options.visitedElements.add(element);let accessibleName=innerAccumulatedElementText(element,childOptions);if(options.embeddedInTargetElement===\"self\"?trimFlatString(accessibleName.text):accessibleName.text)return accessibleName.elements?.add(element),accessibleName}if(![\"presentation\",\"none\"].includes(role)||tagName===\"IFRAME\"){options.visitedElements.add(element);let title=element.getAttribute(\"title\")||\"\";if(trimFlatString(title))return compositeString(title,element,options.collectElements)}return options.visitedElements.add(element),emptyCompositeString()}function innerAccumulatedElementText(element,options){let tokens=[],elements=options.collectElements?new Set:void 0,visit=(node,skipSlotted)=>{if(skipSlotted&&node.assignedSlot)return;if(node.nodeType===1){let display=getElementComputedStyle(node)?.display||\"inline\",childComposite=getTextAlternativeInternal(node,options),token=childComposite.text;for(let contributor of childComposite.elements||[])elements?.add(contributor);if(display!==\"inline\"||node.nodeName===\"BR\")token=\" \"+token+\" \";tokens.push(token)}else if(node.nodeType===3)tokens.push(node.textContent||\"\")};tokens.push(getCSSContent(element,\"::before\")||\"\");let content=getCSSContent(element);if(content!==void 0)tokens.push(content);else{let assignedNodes=element.nodeName===\"SLOT\"?element.assignedNodes():[];if(assignedNodes.length)for(let child of assignedNodes)visit(child,!1);else{for(let child=element.firstChild;child;child=child.nextSibling)visit(child,!0);if(element.shadowRoot)for(let child=element.shadowRoot.firstChild;child;child=child.nextSibling)visit(child,!0);for(let owned of getIdRefs(element,element.getAttribute(\"aria-owns\")))visit(owned,!0)}}return tokens.push(getCSSContent(element,\"::after\")||\"\"),{text:tokens.join(\"\"),elements}}var kAriaSelectedRoles=[\"gridcell\",\"option\",\"row\",\"tab\",\"rowheader\",\"columnheader\",\"treeitem\"];function getAriaSelected(element){if(elementSafeTagName(element)===\"OPTION\")return element.selected;if(kAriaSelectedRoles.includes(getAriaRole(element)||\"\"))return getAriaBoolean(element.getAttribute(\"aria-selected\"))===!0;return!1}var kAriaCheckedRoles=[\"checkbox\",\"menuitemcheckbox\",\"option\",\"radio\",\"switch\",\"menuitemradio\",\"treeitem\"];function getAriaChecked(element){let result=getChecked(element,!0);return result===\"error\"?!1:result}function getChecked(element,allowMixed){let tagName=elementSafeTagName(element);if(allowMixed&&tagName===\"INPUT\"&&element.indeterminate)return\"mixed\";if(tagName===\"INPUT\"&&[\"checkbox\",\"radio\"].includes(element.type))return element.checked;if(kAriaCheckedRoles.includes(getAriaRole(element)||\"\")){let checked=element.getAttribute(\"aria-checked\");if(checked===\"true\")return!0;if(allowMixed&&checked===\"mixed\")return\"mixed\";return!1}return\"error\"}var kAriaPressedRoles=[\"button\"];function getAriaPressed(element){if(kAriaPressedRoles.includes(getAriaRole(element)||\"\")){let pressed=element.getAttribute(\"aria-pressed\");if(pressed===\"true\")return!0;if(pressed===\"mixed\")return\"mixed\"}return!1}var kAriaExpandedRoles=[\"application\",\"button\",\"checkbox\",\"combobox\",\"gridcell\",\"link\",\"listbox\",\"menuitem\",\"row\",\"rowheader\",\"tab\",\"treeitem\",\"columnheader\",\"menuitemcheckbox\",\"menuitemradio\",\"rowheader\",\"switch\"];function getAriaExpanded(element){if(elementSafeTagName(element)===\"DETAILS\")return element.open;if(kAriaExpandedRoles.includes(getAriaRole(element)||\"\")){let expanded=element.getAttribute(\"aria-expanded\");if(expanded===null)return;if(expanded===\"true\")return!0;return!1}return}var kAriaLevelRoles=[\"heading\",\"listitem\",\"row\",\"treeitem\"];function getAriaLevel(element){let native={H1:1,H2:2,H3:3,H4:4,H5:5,H6:6}[elementSafeTagName(element)];if(native)return native;if(kAriaLevelRoles.includes(getAriaRole(element)||\"\")){let attr=element.getAttribute(\"aria-level\"),value=attr===null?Number.NaN:Number(attr);if(Number.isInteger(value)&&value>=1)return value}return 0}var kAriaDisabledRoles=[\"application\",\"button\",\"composite\",\"gridcell\",\"group\",\"input\",\"link\",\"menuitem\",\"scrollbar\",\"separator\",\"tab\",\"checkbox\",\"columnheader\",\"combobox\",\"grid\",\"listbox\",\"menu\",\"menubar\",\"menuitemcheckbox\",\"menuitemradio\",\"option\",\"radio\",\"radiogroup\",\"row\",\"rowheader\",\"searchbox\",\"select\",\"slider\",\"spinbutton\",\"switch\",\"tablist\",\"textbox\",\"toolbar\",\"tree\",\"treegrid\",\"treeitem\"];function getAriaDisabled(element){return isNativelyDisabled(element)||hasExplicitAriaDisabled(element)}function isNativelyDisabled(element){return[\"BUTTON\",\"INPUT\",\"SELECT\",\"TEXTAREA\",\"OPTION\",\"OPTGROUP\"].includes(elementSafeTagName(element))&&(element.hasAttribute(\"disabled\")||belongsToDisabledOptGroup(element)||belongsToDisabledFieldSet(element))}function belongsToDisabledOptGroup(element){return elementSafeTagName(element)===\"OPTION\"&&!!element.closest(\"OPTGROUP[DISABLED]\")}function belongsToDisabledFieldSet(element){let fieldSetElement=element?.closest(\"FIELDSET[DISABLED]\");if(!fieldSetElement)return!1;let legendElement=fieldSetElement.querySelector(\":scope > LEGEND\");return!legendElement||!legendElement.contains(element)}function hasExplicitAriaDisabled(element,isAncestor=!1){if(!element)return!1;if(isAncestor||kAriaDisabledRoles.includes(getAriaRole(element)||\"\")){let attribute=(element.getAttribute(\"aria-disabled\")||\"\").toLowerCase();if(attribute===\"true\")return!0;if(attribute===\"false\")return!1;return hasExplicitAriaDisabled(parentElementOrShadowHost(element),!0)}return!1}function getAccessibleNameFromAssociatedLabels(labels,options){return joinCompositeString([...labels].map((label)=>getTextAlternativeInternal(label,{...options,embeddedInLabel:{element:label,hidden:isElementHiddenForAria(label)},embeddedInNativeTextAlternative:void 0,embeddedInLabelledBy:void 0,embeddedInDescribedBy:void 0,embeddedInTargetElement:void 0})).filter((accessibleName)=>!!accessibleName.text),\" \",options.collectElements)}function receivesPointerEvents(element){let cache=cachePointerEvents,e=element,result,parents=[];for(;e;e=parentElementOrShadowHost(e)){let cached=cache.get(e);if(cached!==void 0){result=cached;break}parents.push(e);let style=getElementComputedStyle(e);if(!style){result=!0;break}let value=style.pointerEvents;if(value){result=value!==\"none\";break}}if(result===void 0)result=!0;for(let parent of parents)cache.set(parent,result);return result}var cacheAccessibleName,cacheAccessibleNameHidden,cacheAccessibleNameText,cacheAccessibleNameTextHidden,cacheAccessibleDescription,cacheAccessibleDescriptionHidden,cacheAccessibleErrorMessage,cacheIsHidden,cachePseudoContent,cachePseudoContentBefore,cachePseudoContentAfter,cachePointerEvents,cachesCounter2=0;function beginAriaCaches(){beginDOMCaches(),++cachesCounter2,cacheAccessibleName??=new Map,cacheAccessibleNameHidden??=new Map,cacheAccessibleNameText??=new Map,cacheAccessibleNameTextHidden??=new Map,cacheAccessibleDescription??=new Map,cacheAccessibleDescriptionHidden??=new Map,cacheAccessibleErrorMessage??=new Map,cacheIsHidden??=new Map,cachePseudoContent??=new Map,cachePseudoContentBefore??=new Map,cachePseudoContentAfter??=new Map,cachePointerEvents??=new Map}function endAriaCaches(){if(!--cachesCounter2)cacheAccessibleName=void 0,cacheAccessibleNameHidden=void 0,cacheAccessibleNameText=void 0,cacheAccessibleNameTextHidden=void 0,cacheAccessibleDescription=void 0,cacheAccessibleDescriptionHidden=void 0,cacheAccessibleErrorMessage=void 0,cacheIsHidden=void 0,cachePseudoContent=void 0,cachePseudoContentBefore=void 0,cachePseudoContentAfter=void 0,cachePointerEvents=void 0;endDOMCaches()}var inputTypeToRole={button:\"button\",checkbox:\"checkbox\",image:\"button\",number:\"spinbutton\",radio:\"radio\",range:\"slider\",reset:\"button\",submit:\"button\"};function emptyCompositeString(){return{text:\"\"}}function compositeString(text,element,collectElements){return{text:text||\"\",elements:text&&collectElements?new Set([element]):void 0}}function joinCompositeString(parts,separator,collectElements){let elements;if(collectElements){elements=new Set;for(let part of parts)for(let element of part.elements||[])elements.add(element)}return{text:parts.map((part)=>part.text).join(separator),elements}}var SENSITIVE_VALUE_MARKER=\"[REDACTED]\",lastRef=0;function toInternalOptions(options){let renderBoxes=options.boxes;if(options.mode===\"ai\")return{visibility:\"ariaOrVisible\",refs:\"interactable\",refPrefix:options.refPrefix,includeGenericRole:!0,renderActive:!options.doNotRenderActive,renderCursorPointer:!0,renderBoxes};if(options.mode===\"autoexpect\")return{visibility:\"ariaAndVisible\",refs:\"none\",renderBoxes};if(options.mode===\"codegen\")return{visibility:\"aria\",refs:\"none\",renderStringsAsRegex:!0,renderBoxes};return{visibility:\"aria\",refs:\"none\",renderBoxes}}function generateAriaTree(rootElement,publicOptions){let options=toInternalOptions(publicOptions),visited=new Set,nameSourceElements=new Map,snapshot={root:{role:\"fragment\",name:\"\",children:[],props:{},box:computeBox(rootElement),receivesPointerEvents:!0},info:new Map,refs:new Map,iframeRefs:[]};setAriaNodeElement(snapshot.root,rootElement);let visit=(ariaNode,node,parentElementVisible)=>{if(visited.has(node))return;if(visited.add(node),node.nodeType===Node.TEXT_NODE&&node.nodeValue){if(!parentElementVisible)return;let text=node.nodeValue;if(ariaNode.role!==\"textbox\"&&text)ariaNode.children.push(node.nodeValue||\"\");return}if(node.nodeType!==Node.ELEMENT_NODE)return;let element=node,isElementVisibleForAria=!isElementHiddenForAria(element),visible=isElementVisibleForAria;if(options.visibility===\"ariaOrVisible\")visible=isElementVisibleForAria||isElementVisible(element);if(options.visibility===\"ariaAndVisible\")visible=isElementVisibleForAria&&isElementVisible(element);if(options.visibility===\"aria\"&&!visible)return;let ariaChildren=[];if(element.hasAttribute(\"aria-owns\")){let ids=element.getAttribute(\"aria-owns\").split(/\\s+/);for(let id of ids){let ownedElement=rootElement.ownerDocument.getElementById(id);if(ownedElement)ariaChildren.push(ownedElement)}}let childAriaNode=visible?toAriaNode(element,options,nameSourceElements):null,elementInfo;if(childAriaNode){if(childAriaNode.ref){if(elementInfo={element,nameFromContentRefs:[]},snapshot.info.set(childAriaNode.ref,elementInfo),snapshot.refs.set(element,childAriaNode.ref),childAriaNode.role===\"iframe\")snapshot.iframeRefs.push(childAriaNode.ref)}ariaNode.children.push(childAriaNode)}if(processElement(childAriaNode||ariaNode,element,ariaChildren,visible),elementInfo)for(let contributor of nameSourceElements.get(childAriaNode)||[]){let ref=snapshot.refs.get(contributor);if(ref&&ref!==childAriaNode.ref)elementInfo.nameFromContentRefs.push(ref)}};function processElement(ariaNode,element,ariaChildren,parentElementVisible){let treatAsBlock=(getElementComputedStyle(element)?.display||\"inline\")!==\"inline\"||element.nodeName===\"BR\"?\" \":\"\";if(treatAsBlock)ariaNode.children.push(treatAsBlock);ariaNode.children.push(getCSSContent(element,\"::before\")||\"\");let assignedNodes=element.nodeName===\"SLOT\"?element.assignedNodes():[];if(assignedNodes.length)for(let child of assignedNodes)visit(ariaNode,child,parentElementVisible);else{for(let child=element.firstChild;child;child=child.nextSibling)if(!child.assignedSlot)visit(ariaNode,child,parentElementVisible);if(element.shadowRoot)for(let child=element.shadowRoot.firstChild;child;child=child.nextSibling)visit(ariaNode,child,parentElementVisible)}for(let child of ariaChildren)visit(ariaNode,child,parentElementVisible);if(ariaNode.children.push(getCSSContent(element,\"::after\")||\"\"),treatAsBlock)ariaNode.children.push(treatAsBlock);if(ariaNode.children.length===1&&ariaNode.name===ariaNode.children[0])ariaNode.children=[];if(ariaNode.role===\"link\"&&element.hasAttribute(\"href\")){let href=element.getAttribute(\"href\");ariaNode.props.url=truncateDataUrl(href)}if(ariaNode.role===\"textbox\"&&element.hasAttribute(\"placeholder\")&&element.getAttribute(\"placeholder\")!==ariaNode.name){let placeholder=element.getAttribute(\"placeholder\");ariaNode.props.placeholder=placeholder}}beginAriaCaches();try{visit(snapshot.root,rootElement,!0)}finally{endAriaCaches()}return distillAriaSnapshot(snapshot,publicOptions),snapshot}function computeAriaRef(ariaNode,options){if(options.refs===\"none\")return;if(options.refs===\"interactable\"&&(!ariaNode.box.visible||!ariaNode.receivesPointerEvents))return;let element=ariaNodeElement(ariaNode),ariaRef=element._ariaRef;if(!ariaRef||ariaRef.role!==ariaNode.role||ariaRef.name!==ariaNode.name)ariaRef={role:ariaNode.role,name:ariaNode.name,ref:(options.refPrefix??\"\")+\"e\"+ ++lastRef},element._ariaRef=ariaRef;ariaNode.ref=ariaRef.ref}function toAriaNode(element,options,nameSourceElements){let active=element.ownerDocument.activeElement===element&&element.ownerDocument.hasFocus();if(element.nodeName===\"IFRAME\"){let ariaNode={role:\"iframe\",name:\"\",children:[],props:{},box:computeBox(element),receivesPointerEvents:!0,active};return setAriaNodeElement(ariaNode,element),computeAriaRef(ariaNode,options),ariaNode}let defaultRole=options.includeGenericRole?\"generic\":null,role=getAriaRole(element)??defaultRole;if(!role||role===\"presentation\"||role===\"none\")return null;let name=getElementAccessibleName(element,!1),receivesPointerEvents2=receivesPointerEvents(element),box=computeBox(element);if(role===\"generic\"&&box.inline&&element.childNodes.length===1&&element.childNodes[0].nodeType===Node.TEXT_NODE)return null;let result={role,name:normalizeWhiteSpace(name.text),children:[],props:{},box,receivesPointerEvents:receivesPointerEvents2,active};if(setAriaNodeElement(result,element),nameSourceElements.set(result,name.elements),computeAriaRef(result,options),kAriaCheckedRoles.includes(role))result.checked=getAriaChecked(element);if(kAriaDisabledRoles.includes(role))result.disabled=getAriaDisabled(element);if(kAriaExpandedRoles.includes(role))result.expanded=getAriaExpanded(element);if(kAriaInvalidRoles.includes(role)){let invalid=getAriaInvalid(element);result.invalid=invalid===\"false\"?!1:invalid===\"true\"?!0:invalid}if(kAriaLevelRoles.includes(role))result.level=getAriaLevel(element);if(kAriaPressedRoles.includes(role))result.pressed=getAriaPressed(element);if(kAriaSelectedRoles.includes(role))result.selected=getAriaSelected(element);if(element instanceof HTMLInputElement||element instanceof HTMLTextAreaElement){if(element.type!==\"checkbox\"&&element.type!==\"radio\"&&element.type!==\"file\")result.children=[element instanceof HTMLInputElement&&element.type===\"password\"?SENSITIVE_VALUE_MARKER:element.value]}return result}function indent(depth){return\" \".repeat(depth)}function renderAriaTree(ariaSnapshot,publicOptions){let options=toInternalOptions(publicOptions),lines=[],iframeDepths={},includeText=options.renderStringsAsRegex?textContributesInfo:()=>!0,renderString=options.renderStringsAsRegex?convertToBestGuessRegex:(str)=>str,nodesToRender=ariaSnapshot.root.role===\"fragment\"?ariaSnapshot.root.children:[ariaSnapshot.root],visitText=(text,depth)=>{if(publicOptions.depth&&depth>publicOptions.depth)return;let escaped=yamlEscapeValueIfNeeded(renderString(text));if(escaped)lines.push(indent(depth)+\"- text: \"+escaped)},createKey=(ariaNode,renderCursorPointer)=>{let key=ariaNode.role;if(ariaNode.name&&ariaNode.name.length<=900){let name=renderString(ariaNode.name);if(name){let stringifiedName=name.startsWith(\"/\")&&name.endsWith(\"/\")?name:JSON.stringify(name);key+=\" \"+stringifiedName}}if(ariaNode.checked===\"mixed\")key+=\" [checked=mixed]\";if(ariaNode.checked===!0)key+=\" [checked]\";if(ariaNode.disabled)key+=\" [disabled]\";if(ariaNode.expanded)key+=\" [expanded]\";if(ariaNode.active&&options.renderActive)key+=\" [active]\";if(ariaNode.invalid===\"grammar\"||ariaNode.invalid===\"spelling\")key+=` [invalid=${ariaNode.invalid}]`;if(ariaNode.invalid===!0)key+=\" [invalid]\";if(ariaNode.level)key+=` [level=${ariaNode.level}]`;if(ariaNode.pressed===\"mixed\")key+=\" [pressed=mixed]\";if(ariaNode.pressed===!0)key+=\" [pressed]\";if(ariaNode.selected===!0)key+=\" [selected]\";if(ariaNode.ref){if(key+=` [ref=${ariaNode.ref}]`,renderCursorPointer&&hasPointerCursor(ariaNode))key+=\" [cursor=pointer]\"}if(options.renderBoxes){let element=ariaNodeElement(ariaNode);if(element){let r=element.getBoundingClientRect();key+=` [box=${Math.round(r.x)},${Math.round(r.y)},${Math.round(r.width)},${Math.round(r.height)}]`}}return key},getSingleTextChild=(ariaNode)=>{return ariaNode.children.length===1&&typeof ariaNode.children[0]===\"string\"&&!Object.keys(ariaNode.props).length?ariaNode.children[0]:void 0},visit=(ariaNode,depth,renderCursorPointer)=>{if(publicOptions.depth&&depth>publicOptions.depth)return;if(ariaNode.role===\"iframe\"&&ariaNode.ref)iframeDepths[ariaNode.ref]=depth;let escapedKey=indent(depth)+\"- \"+yamlEscapeKeyIfNeeded(createKey(ariaNode,renderCursorPointer)),singleTextChild=getSingleTextChild(ariaNode),isAtDepthLimit=!!publicOptions.depth&&depth===publicOptions.depth;if(!singleTextChild&&(!ariaNode.children.length||isAtDepthLimit)&&!Object.keys(ariaNode.props).length)lines.push(escapedKey);else if(singleTextChild!==void 0)if(includeText(ariaNode,singleTextChild))lines.push(escapedKey+\": \"+yamlEscapeValueIfNeeded(renderString(singleTextChild)));else lines.push(escapedKey);else{lines.push(escapedKey+\":\");for(let[name,value]of Object.entries(ariaNode.props))lines.push(indent(depth+1)+\"- /\"+name+\": \"+yamlEscapeValueIfNeeded(value));let inCursorPointer=!!ariaNode.ref&&renderCursorPointer&&hasPointerCursor(ariaNode);for(let child of ariaNode.children)if(typeof child===\"string\")visitText(includeText(ariaNode,child)?child:\"\",depth+1);else visit(child,depth+1,renderCursorPointer&&!inCursorPointer)}};for(let nodeToRender of nodesToRender)if(typeof nodeToRender===\"string\")visitText(nodeToRender,0);else visit(nodeToRender,0,!!options.renderCursorPointer);return{text:lines.join(`\n`),iframeDepths}}function convertToBestGuessRegex(text){let dynamicContent=[{regex:/\\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\\b/,replacement:\"[0-9a-fA-F-]+\"},{regex:/\\b[\\d,.]+[bkmBKM]+\\b/,replacement:\"[\\\\d,.]+[bkmBKM]+\"},{regex:/\\b\\d+[hmsp]+\\b/,replacement:\"\\\\d+[hmsp]+\"},{regex:/\\b[\\d,.]+[hmsp]+\\b/,replacement:\"[\\\\d,.]+[hmsp]+\"},{regex:/\\b\\d+,\\d+\\b/,replacement:\"\\\\d+,\\\\d+\"},{regex:/\\b\\d+\\.\\d{2,}\\b/,replacement:\"\\\\d+\\\\.\\\\d+\"},{regex:/\\b\\d{2,}\\.\\d+\\b/,replacement:\"\\\\d+\\\\.\\\\d+\"},{regex:/\\b\\d{2,}\\b/,replacement:\"\\\\d+\"}],pattern=\"\",lastIndex=0,combinedRegex=new RegExp(dynamicContent.map((r)=>\"(\"+r.regex.source+\")\").join(\"|\"),\"g\");if(text.replace(combinedRegex,(match,...args)=>{let offset=args[args.length-2],groups=args.slice(0,-2);pattern+=escapeRegExp(text.slice(lastIndex,offset));for(let i=0;i<groups.length;i++)if(groups[i]){let{replacement}=dynamicContent[i];pattern+=replacement;break}return lastIndex=offset+match.length,match}),!pattern)return text;return pattern+=escapeRegExp(text.slice(lastIndex)),String(new RegExp(pattern))}function textContributesInfo(node,text){if(!text.length)return!1;if(!node.name)return!0;let substr=text.length<=200&&node.name.length<=200?longestCommonSubstring(text,node.name):\"\",filtered=text;while(substr&&filtered.includes(substr))filtered=filtered.replace(substr,\"\");return filtered.trim().length/text.length>0.1}var elementSymbol=Symbol(\"element\");function ariaNodeElement(ariaNode){return ariaNode[elementSymbol]}function setAriaNodeElement(ariaNode,element){ariaNode[elementSymbol]=element}var ARIA_REF=/^(?:f\\d+)?e\\d+$/,DEFAULT_MAX_CHARS=60000,TARGET_ATTRIBUTE=\"data-steel-page-target\",locatorCounter=0;function nextLocatorToken(){return locatorCounter+=1,`t${Date.now().toString(36)}-${locatorCounter}`}class BrowserToolError extends Error{code;retryable;constructor(code,message,retryable=!0){super(message);this.code=code;this.retryable=retryable;this.name=\"BrowserToolError\"}}class PageSnapshotService{document;current=null;maxChars;refPrefix;constructor(document2,options={}){this.document=document2;this.maxChars=options.maxChars??DEFAULT_MAX_CHARS,this.refPrefix=options.refPrefix}capture(options={}){return this.clearPreparedTargets(),this.captureCurrent(options)}captureCurrent(options={}){let root=this.document.body??this.document.documentElement;if(!root)throw new BrowserToolError(\"page_unavailable\",\"The page has no document root\");this.current=generateAriaTree(root,{mode:\"ai\",refPrefix:this.refPrefix,depth:options.depth,boxes:options.boxes});let rendered=renderAriaTree(this.current,{mode:\"ai\",depth:options.depth,boxes:options.boxes}).text,snapshot=truncateAtLine(rendered,this.maxChars),view=this.document.defaultView,documentElement=this.document.documentElement,body=this.document.body,scrollHeight=Math.max(documentElement?.scrollHeight??0,body?.scrollHeight??0),viewportHeight=view?.visualViewport?.height??documentElement?.clientHeight??view?.innerHeight??0;return{url:this.document.location?.href??\"\",title:this.document.title,snapshot:snapshot.text,scroll:{y:Math.round(view?.scrollY??documentElement?.scrollTop??0),max:Math.max(0,Math.round(scrollHeight-viewportHeight))},truncated:snapshot.omittedChars>0,omittedChars:snapshot.omittedChars}}resolveOptions(target,values){let element=this.resolve(target);if(!(element instanceof HTMLSelectElement))throw new BrowserToolError(\"element_not_select\",`Target ${target} is not a select element`,!1);let requested=new Set(values),matched=new Set,selected=[];for(let option of element.options){let matches=[option.value,option.label,option.text].filter((value)=>requested.has(value));if(matches.length>0){selected.push(option.value);for(let match of matches)matched.add(match)}}if(matched.size!==requested.size)throw new BrowserToolError(\"option_not_found\",`Could not match all requested options: ${values.join(\", \")}`);return selected}async prepareTarget(target,options={}){let element=this.resolve(target);if(isDisabled(element))throw new BrowserToolError(\"element_disabled\",`Target ${target} is disabled`);element.scrollIntoView?.({block:\"center\",inline:\"center\"});let rect=await stableRect(element,options);if(!rect||rect.width<=0||rect.height<=0||!isVisible(element))throw new BrowserToolError(\"element_not_visible\",`Target ${target} is not visible`);let center={x:rect.x+rect.width/2,y:rect.y+rect.height/2},hit=this.document.elementFromPoint?.(center.x,center.y);if(hit&&!belongsToTarget(hit,element))throw new BrowserToolError(\"element_obscured\",`Target ${target} is covered by another element`);let locatorToken=nextLocatorToken();return element.setAttribute(TARGET_ATTRIBUTE,locatorToken),{editable:isEditable(element),locatorToken}}async prepareEditableTarget(target,mode,options={}){let prepared=await this.prepareTarget(target,options);if(!prepared.editable)throw new BrowserToolError(\"element_not_editable\",`Target ${target} does not accept text input`,!1);let element=this.preparedElement(prepared.locatorToken),previous=editableValue(element);return{...prepared,previousValue:previous.value,sensitive:previous.sensitive,selectionPrepared:prepareEditableSelection(element,mode)}}readEditableValue(target){let element=this.resolve(target);if(!hasEditableValue(element))throw new BrowserToolError(\"element_not_editable\",`Target ${target} does not have an editable text value`,!1);return editableValue(element)}preparedElement(locatorToken){let element=this.document.querySelector(`[${TARGET_ATTRIBUTE}=\"${locatorToken}\"]`);if(!element)throw new BrowserToolError(\"stale_ref\",\"Prepared browser target is no longer attached\");return element}clearPreparedTargets(){for(let element of this.document.querySelectorAll(`[${TARGET_ATTRIBUTE}]`))element.removeAttribute(TARGET_ATTRIBUTE)}resolve(target){let normalized=target.trim();if(!normalized)throw new BrowserToolError(\"element_not_found\",\"Element target cannot be empty\");if(ARIA_REF.test(normalized)){this.captureCurrent();let element=this.current?.info.get(normalized)?.element;if(!element?.isConnected)throw new BrowserToolError(\"stale_ref\",`Ref ${normalized} is not present in the current page snapshot. Capture a fresh snapshot and retry.`);return element}let matches;try{matches=this.document.querySelectorAll(normalized)}catch{throw new BrowserToolError(\"element_not_found\",`Invalid element selector: ${normalized}`,!1)}if(matches.length===0)throw new BrowserToolError(\"element_not_found\",`Selector ${JSON.stringify(normalized)} did not match any elements`);if(matches.length>1)throw new BrowserToolError(\"ambiguous_target\",`Selector ${JSON.stringify(normalized)} matched ${matches.length} elements; use an exact ref from browser_read_page`);return matches[0]}}function isEditable(element){if(!hasEditableValue(element))return!1;if(element instanceof HTMLTextAreaElement)return!element.readOnly;if(element instanceof HTMLInputElement)return!element.readOnly;return!0}function hasEditableValue(element){if(element instanceof HTMLTextAreaElement)return!0;if(element instanceof HTMLInputElement)return![\"button\",\"checkbox\",\"color\",\"file\",\"hidden\",\"image\",\"radio\",\"range\",\"reset\",\"submit\"].includes(element.type);return element instanceof HTMLElement&&element.isContentEditable}function editableValue(element){if(element instanceof HTMLInputElement)return{value:element.value,sensitive:element.type===\"password\"};if(element instanceof HTMLTextAreaElement)return{value:element.value,sensitive:!1};let html=element;return{value:typeof html.innerText===\"string\"?html.innerText:html.textContent??\"\",sensitive:!1}}function prepareEditableSelection(element,mode){if(element.focus({preventScroll:!0}),element instanceof HTMLInputElement||element instanceof HTMLTextAreaElement)try{if(mode===\"replace\")element.select();else element.setSelectionRange(element.value.length,element.value.length);return element.selectionStart===(mode===\"replace\"?0:element.value.length)&&element.selectionEnd===element.value.length}catch{return!1}let selection=element.ownerDocument.defaultView?.getSelection();if(!selection)return!1;let range=element.ownerDocument.createRange();if(range.selectNodeContents(element),mode===\"append\")range.collapse(!1);return selection.removeAllRanges(),selection.addRange(range),!0}function isDisabled(element){return\"disabled\"in element&&element.disabled===!0||element.getAttribute(\"aria-disabled\")===\"true\"}function isVisible(element){let style=element.ownerDocument.defaultView?.getComputedStyle(element);return style?.display!==\"none\"&&style?.visibility!==\"hidden\"&&style?.visibility!==\"collapse\"&&style?.opacity!==\"0\"}async function stableRect(element,options){let interval=options.stabilityIntervalMs,timeout=options.timeoutMs??1000,started=Date.now(),previous=null;while(Date.now()-started<=timeout){let current=element.getBoundingClientRect();if(!element.isConnected)return null;if(previous&&rectsEqual(previous,current))return current;previous=current,await nextLayoutFrame(element.ownerDocument.defaultView,interval)}throw new BrowserToolError(\"element_unstable\",\"Target element did not settle before the action timeout\")}async function nextLayoutFrame(view,interval){if(interval!==void 0||!view?.requestAnimationFrame){await new Promise((resolve)=>setTimeout(resolve,interval??50));return}await new Promise((resolve)=>view.requestAnimationFrame(()=>resolve()))}function rectsEqual(a,b){return Math.abs(a.x-b.x)<0.5&&Math.abs(a.y-b.y)<0.5&&Math.abs(a.width-b.width)<0.5&&Math.abs(a.height-b.height)<0.5}function belongsToTarget(hit,target){if(hit===target||target.contains(hit))return!0;let current=hit;while(current){let root=current.getRootNode();if(!(root instanceof ShadowRoot))return!1;if(root.host===target||target.contains(root.host))return!0;current=root.host}return!1}function truncateAtLine(text,maxChars){if(text.length<=maxChars)return{text,omittedChars:0};let cut=text.lastIndexOf(`\n`,Math.max(0,maxChars)),end=cut>0?cut:maxChars;return{text:text.slice(0,end),omittedChars:text.length-end}}async function waitForPage(document2,request,options={}){let now=options.now??Date.now,sleep=options.sleep??(async(ms)=>{await new Promise((resolve)=>setTimeout(resolve,ms))}),timeoutMs=Math.min(30,Math.max(0,request.time??5))*1000,started=now();if(!request.text&&!request.textGone)return await sleep(timeoutMs),{matched:!0,timedOut:!1,elapsedMs:Math.max(0,now()-started)};while(!0){let text=document2.body?.innerText??document2.body?.textContent??\"\",found=!request.text||text.includes(request.text),gone=!request.textGone||!text.includes(request.textGone),elapsedMs=Math.max(0,now()-started);if(found&&gone)return{matched:!0,timedOut:!1,elapsedMs};if(elapsedMs>=timeoutMs)return{matched:!1,timedOut:!0,elapsedMs};await sleep(Math.min(100,timeoutMs-elapsedMs))}}var PAGE_BRIDGE_VERSION=1,PAGE_BRIDGE_GLOBAL=\"__steelPageBridge\";function createPageBridge(document2){let service=new PageSnapshotService(document2),maxChars;return{version:PAGE_BRIDGE_VERSION,async handle(request){try{return{ok:!0,value:await dispatch(request)}}catch(error){if(error instanceof BrowserToolError)return{ok:!1,error:{code:error.code,message:error.message,retryable:error.retryable}};return{ok:!1,error:{code:\"page_error\",message:error instanceof Error?error.message:String(error),retryable:!0}}}}};async function dispatch(request){switch(request.action){case\"snapshot\":{if(request.maxChars!==void 0&&request.maxChars!==maxChars)maxChars=request.maxChars,service=new PageSnapshotService(document2,{maxChars});return service.capture({...request.depth!==void 0?{depth:request.depth}:{},...request.boxes!==void 0?{boxes:request.boxes}:{}})}case\"prepare_target\":return await service.prepareTarget(request.target);case\"prepare_editable\":return await service.prepareEditableTarget(request.target,request.mode);case\"editable_value\":return service.readEditableValue(request.target);case\"resolve_options\":return{selected:service.resolveOptions(request.target,request.values)};case\"wait_for\":return await waitForPage(document2,request)}}}function installPageBridge(){let existing=globalThis[PAGE_BRIDGE_GLOBAL];if(existing?.version===PAGE_BRIDGE_VERSION)return existing;let bridge=createPageBridge(document);return globalThis[PAGE_BRIDGE_GLOBAL]=bridge,bridge}installPageBridge();})();\n";
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A minimal Chrome DevTools Protocol client over the Steel session's
|
|
3
|
+
* websocket, and the page-bridge channel built on top of it.
|
|
4
|
+
*
|
|
5
|
+
* This exists because the Steel plugin cannot assume Playwright: the host
|
|
6
|
+
* app may not have it installed, and quietly substituting a lookalike is
|
|
7
|
+
* what made `browser.run` report wrong results instead of failing. Here
|
|
8
|
+
* the dependency is the protocol itself, which Steel always speaks.
|
|
9
|
+
*
|
|
10
|
+
* Scope is deliberate. This is not a browser automation library — it is
|
|
11
|
+
* the transport for two things: evaluating the page bridge, and
|
|
12
|
+
* dispatching trusted input. Anything richer belongs in the page bridge,
|
|
13
|
+
* where it is ordinary DOM code.
|
|
14
|
+
*/
|
|
15
|
+
import { PAGE_BRIDGE_GLOBAL, PAGE_BRIDGE_SOURCE, PAGE_BRIDGE_VERSION, } from "./bundle.generated.js";
|
|
16
|
+
const CONNECT_TIMEOUT_MS = 30_000;
|
|
17
|
+
const COMMAND_TIMEOUT_MS = 30_000;
|
|
18
|
+
export class CdpError extends Error {
|
|
19
|
+
code;
|
|
20
|
+
retryable;
|
|
21
|
+
constructor(code, message, retryable = true) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.code = code;
|
|
24
|
+
this.retryable = retryable;
|
|
25
|
+
this.name = "CdpError";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Connect to a CDP endpoint and resolve once the socket is open. */
|
|
29
|
+
export async function connectCdp(url) {
|
|
30
|
+
const ws = new WebSocket(url);
|
|
31
|
+
const pending = new Map();
|
|
32
|
+
const handlers = new Set();
|
|
33
|
+
let nextId = 0;
|
|
34
|
+
let closed = null;
|
|
35
|
+
const failAll = (error) => {
|
|
36
|
+
closed = error;
|
|
37
|
+
for (const [id, wait] of pending) {
|
|
38
|
+
clearTimeout(wait.timer);
|
|
39
|
+
pending.delete(id);
|
|
40
|
+
wait.reject(error);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
await new Promise((resolve, reject) => {
|
|
44
|
+
const timer = setTimeout(() => reject(new CdpError("cdp_unavailable", `Timed out connecting to the browser after ${CONNECT_TIMEOUT_MS}ms`)), CONNECT_TIMEOUT_MS);
|
|
45
|
+
ws.addEventListener("open", () => {
|
|
46
|
+
clearTimeout(timer);
|
|
47
|
+
resolve();
|
|
48
|
+
}, { once: true });
|
|
49
|
+
ws.addEventListener("error", () => {
|
|
50
|
+
clearTimeout(timer);
|
|
51
|
+
reject(new CdpError("cdp_unavailable", "Could not connect to the browser"));
|
|
52
|
+
}, { once: true });
|
|
53
|
+
});
|
|
54
|
+
ws.addEventListener("close", () => failAll(new CdpError("cdp_closed", "The browser connection closed")));
|
|
55
|
+
ws.addEventListener("message", (event) => {
|
|
56
|
+
let message;
|
|
57
|
+
try {
|
|
58
|
+
message = JSON.parse(String(event.data));
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (typeof message.id === "number") {
|
|
64
|
+
const wait = pending.get(message.id);
|
|
65
|
+
if (!wait)
|
|
66
|
+
return;
|
|
67
|
+
clearTimeout(wait.timer);
|
|
68
|
+
pending.delete(message.id);
|
|
69
|
+
if (message.error) {
|
|
70
|
+
const error = message.error;
|
|
71
|
+
wait.reject(new CdpError("cdp_command_failed", error.message ?? "CDP error"));
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
wait.resolve(message.result ?? {});
|
|
75
|
+
}
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (typeof message.method === "string") {
|
|
79
|
+
// The originating target is on the envelope, not in params. Dropping
|
|
80
|
+
// it here would make every per-page subscription see every page's
|
|
81
|
+
// events.
|
|
82
|
+
const from = typeof message.sessionId === "string" ? message.sessionId : undefined;
|
|
83
|
+
for (const handler of handlers) {
|
|
84
|
+
handler(message.method, (message.params ?? {}), from);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
return {
|
|
89
|
+
get alive() {
|
|
90
|
+
return closed === null;
|
|
91
|
+
},
|
|
92
|
+
send(method, params = {}, sessionId) {
|
|
93
|
+
if (closed)
|
|
94
|
+
return Promise.reject(closed);
|
|
95
|
+
return new Promise((resolve, reject) => {
|
|
96
|
+
const id = ++nextId;
|
|
97
|
+
const timer = setTimeout(() => {
|
|
98
|
+
pending.delete(id);
|
|
99
|
+
reject(new CdpError("cdp_timeout", `${method} timed out`));
|
|
100
|
+
}, COMMAND_TIMEOUT_MS);
|
|
101
|
+
pending.set(id, {
|
|
102
|
+
resolve: resolve,
|
|
103
|
+
reject,
|
|
104
|
+
timer,
|
|
105
|
+
});
|
|
106
|
+
ws.send(JSON.stringify({
|
|
107
|
+
id,
|
|
108
|
+
method,
|
|
109
|
+
params,
|
|
110
|
+
...(sessionId ? { sessionId } : {}),
|
|
111
|
+
}));
|
|
112
|
+
});
|
|
113
|
+
},
|
|
114
|
+
on(handler) {
|
|
115
|
+
handlers.add(handler);
|
|
116
|
+
return () => handlers.delete(handler);
|
|
117
|
+
},
|
|
118
|
+
close() {
|
|
119
|
+
failAll(new CdpError("cdp_closed", "The browser connection was closed"));
|
|
120
|
+
try {
|
|
121
|
+
ws.close();
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// Already closing; nothing to recover.
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* One attached page target, with the page bridge kept installed on it.
|
|
131
|
+
*/
|
|
132
|
+
export class CdpPage {
|
|
133
|
+
cdp;
|
|
134
|
+
targetId;
|
|
135
|
+
sessionId;
|
|
136
|
+
constructor(cdp, targetId, sessionId) {
|
|
137
|
+
this.cdp = cdp;
|
|
138
|
+
this.targetId = targetId;
|
|
139
|
+
this.sessionId = sessionId;
|
|
140
|
+
}
|
|
141
|
+
send(method, params = {}) {
|
|
142
|
+
return this.cdp.send(method, params, this.sessionId);
|
|
143
|
+
}
|
|
144
|
+
/** Subscribe to this page's protocol events; returns an unsubscribe. */
|
|
145
|
+
onEvent(handler) {
|
|
146
|
+
return this.cdp.on((method, params, from) => {
|
|
147
|
+
if (from !== undefined && from !== this.sessionId)
|
|
148
|
+
return;
|
|
149
|
+
handler(method, params);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/** Evaluate an expression in the page and return its value. */
|
|
153
|
+
async evaluate(expression) {
|
|
154
|
+
const result = (await this.send("Runtime.evaluate", {
|
|
155
|
+
expression,
|
|
156
|
+
returnByValue: true,
|
|
157
|
+
awaitPromise: true,
|
|
158
|
+
}));
|
|
159
|
+
if (result.exceptionDetails) {
|
|
160
|
+
const detail = result.exceptionDetails;
|
|
161
|
+
throw new CdpError("page_error", detail.exception?.description ?? detail.text ?? "Page evaluation failed");
|
|
162
|
+
}
|
|
163
|
+
return result.result?.value;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Call the page bridge, installing it first when the world does not
|
|
167
|
+
* have it. Navigation destroys the world, so this self-heals rather
|
|
168
|
+
* than requiring callers to track page lifetime.
|
|
169
|
+
*/
|
|
170
|
+
async bridge(request) {
|
|
171
|
+
let response = await this.callBridge(request);
|
|
172
|
+
if (response === undefined) {
|
|
173
|
+
await this.installBridge();
|
|
174
|
+
response = await this.callBridge(request);
|
|
175
|
+
}
|
|
176
|
+
if (response === undefined) {
|
|
177
|
+
throw new CdpError("page_unavailable", "The page bridge did not install; the page may have navigated mid-action");
|
|
178
|
+
}
|
|
179
|
+
const outcome = response;
|
|
180
|
+
if (!outcome.ok) {
|
|
181
|
+
throw new CdpError(outcome.error.code, outcome.error.message, outcome.error.retryable);
|
|
182
|
+
}
|
|
183
|
+
return outcome.value;
|
|
184
|
+
}
|
|
185
|
+
async callBridge(request) {
|
|
186
|
+
return await this.evaluate(`(() => {
|
|
187
|
+
const bridge = window[${JSON.stringify(PAGE_BRIDGE_GLOBAL)}];
|
|
188
|
+
if (!bridge || bridge.version !== ${PAGE_BRIDGE_VERSION}) return undefined;
|
|
189
|
+
return bridge.handle(${JSON.stringify(request)});
|
|
190
|
+
})()`);
|
|
191
|
+
}
|
|
192
|
+
async installBridge() {
|
|
193
|
+
await this.evaluate(PAGE_BRIDGE_SOURCE);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Install the bridge on every future document too. Without this the
|
|
197
|
+
* first call after any navigation pays a reinstall round trip, and a
|
|
198
|
+
* page that navigates itself mid-action could be observed bridgeless.
|
|
199
|
+
*/
|
|
200
|
+
async installOnNewDocuments() {
|
|
201
|
+
await this.send("Page.addScriptToEvaluateOnNewDocument", {
|
|
202
|
+
source: PAGE_BRIDGE_SOURCE,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/** Attach to the session's first page target. */
|
|
207
|
+
export async function attachToPage(cdp) {
|
|
208
|
+
const { targetInfos } = (await cdp.send("Target.getTargets"));
|
|
209
|
+
const pages = (targetInfos ?? []).filter((info) => info.type === "page");
|
|
210
|
+
const target = pages[0];
|
|
211
|
+
if (!target) {
|
|
212
|
+
throw new CdpError("page_unavailable", "The browser session has no page to control", false);
|
|
213
|
+
}
|
|
214
|
+
return await attachToTarget(cdp, target.targetId);
|
|
215
|
+
}
|
|
216
|
+
export async function attachToTarget(cdp, targetId) {
|
|
217
|
+
const { sessionId } = (await cdp.send("Target.attachToTarget", {
|
|
218
|
+
targetId,
|
|
219
|
+
flatten: true,
|
|
220
|
+
}));
|
|
221
|
+
const page = new CdpPage(cdp, targetId, sessionId);
|
|
222
|
+
await page.send("Page.enable");
|
|
223
|
+
await page.send("Runtime.enable");
|
|
224
|
+
await page.send("DOM.enable");
|
|
225
|
+
// Needed before cookies can be written on the target.
|
|
226
|
+
await page.send("Network.enable");
|
|
227
|
+
await page.installOnNewDocuments();
|
|
228
|
+
// The bridge is installed lazily by the first `bridge()` call, which
|
|
229
|
+
// already probes for it and self-heals. Installing here as well would
|
|
230
|
+
// re-evaluate the whole bundle on every attach for no benefit.
|
|
231
|
+
return page;
|
|
232
|
+
}
|