ax-grep 0.1.0 → 0.1.2
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/LICENSE +21 -0
- package/README.md +72 -121
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +1 -1
- package/dist/browser.js.map +0 -0
- package/dist/{chunk-U3GDKPLQ.js → chunk-HPZ32BKV.js} +37 -3
- package/dist/chunk-HPZ32BKV.js.map +1 -0
- package/dist/{chunk-Z7V6PIPH.js → chunk-ZXTURCRT.js} +214 -24
- package/dist/chunk-ZXTURCRT.js.map +1 -0
- package/dist/cli.d.ts +10 -0
- package/dist/cli.js +22407 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +38 -4
- package/dist/index.js.map +1 -1
- package/dist/static.d.ts +1 -1
- package/dist/static.js +1 -1
- package/dist/static.js.map +0 -0
- package/dist/types-K1hqb7Pq.d.ts +3660 -0
- package/docs/README.md +21 -0
- package/docs/agent-handoff.md +95 -0
- package/docs/agent-readiness.md +38 -0
- package/docs/assets/ax-grep-benchmark.png +0 -0
- package/docs/assets/ax-grep-og.png +0 -0
- package/docs/assets/ax-grep-search.png +0 -0
- package/docs/benchmarks.md +157 -0
- package/docs/cli-agent.md +194 -0
- package/docs/comparison-baseline.md +625 -0
- package/docs/features.md +28 -0
- package/docs/library-api.md +211 -0
- package/docs/progress.md +1306 -0
- package/docs/release.md +24 -0
- package/docs/server-agent.md +71 -0
- package/docs/webview.md +70 -0
- package/package.json +35 -3
- package/skills/ax-grep-cli/SKILL.md +89 -0
- package/skills.sh +24 -0
- package/dist/chunk-U3GDKPLQ.js.map +0 -1
- package/dist/chunk-Z7V6PIPH.js.map +0 -1
- package/dist/types-dgf3brcf.d.ts +0 -74
package/docs/release.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Release
|
|
2
|
+
|
|
3
|
+
## npm Trusted Publisher
|
|
4
|
+
|
|
5
|
+
Configure npm once before publishing from GitHub Actions:
|
|
6
|
+
|
|
7
|
+
- Package settings: `https://www.npmjs.com/package/ax-grep/access`
|
|
8
|
+
- Publisher: GitHub Actions
|
|
9
|
+
- Organization or user: `hmmhmmhm`
|
|
10
|
+
- Repository: `ax-grep`
|
|
11
|
+
- Workflow filename: `publish.yml`
|
|
12
|
+
- Environment name: leave blank
|
|
13
|
+
- Allowed actions: `npm publish`
|
|
14
|
+
|
|
15
|
+
After the trusted publisher is saved, publish a release by pushing a version tag:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
git tag v0.1.2
|
|
19
|
+
git push origin v0.1.2
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The workflow uses GitHub OIDC instead of an npm token and runs `npm publish`.
|
|
23
|
+
For GitHub Actions and public packages, npm automatically publishes provenance
|
|
24
|
+
attestations when trusted publishing is used.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Server Agent Integration
|
|
2
|
+
|
|
3
|
+
Use `ax-grep` in an agent service when you already fetched HTML and want a
|
|
4
|
+
compact, accessibility-style source view before paying for browser automation.
|
|
5
|
+
This is useful in Codex SDK, OpenRouter, queue workers, and custom agent loops.
|
|
6
|
+
|
|
7
|
+
## Minimal Pattern
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { extract, formatSemanticTreeText } from "ax-grep";
|
|
11
|
+
|
|
12
|
+
export async function readForAgent(url: string) {
|
|
13
|
+
const response = await fetch(url, {
|
|
14
|
+
headers: {
|
|
15
|
+
accept: "text/html,application/xhtml+xml",
|
|
16
|
+
"user-agent": "my-agent/1.0",
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const html = await response.text();
|
|
21
|
+
const tree = extract(html, {
|
|
22
|
+
includeAttributes: false,
|
|
23
|
+
includeHidden: false,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
url: response.url || url,
|
|
28
|
+
status: response.status,
|
|
29
|
+
text: formatSemanticTreeText(tree),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Pass `text` into the model as source evidence. Escalate to a browser only when
|
|
35
|
+
the fetched HTML is thin, blocked, or client-rendered.
|
|
36
|
+
|
|
37
|
+
## Agent Prompt Shape
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
const page = await readForAgent("https://example.com");
|
|
41
|
+
|
|
42
|
+
const messages = [
|
|
43
|
+
{
|
|
44
|
+
role: "system",
|
|
45
|
+
content: "Use the provided semantic tree as page evidence. Ask for browser automation only when the evidence is insufficient.",
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
role: "user",
|
|
49
|
+
content: `URL: ${page.url}\nHTTP: ${page.status}\n\n${page.text}`,
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
For live URLs, the CLI can also produce an agent handoff with challenge
|
|
55
|
+
detection and search metadata:
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
npx --yes ax-grep@latest https://example.com --agent-brief
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Use that command when you want `agent.executor`, `agent.handoff`, `pageCheck`,
|
|
62
|
+
and challenge reason codes without building the fetch layer yourself.
|
|
63
|
+
|
|
64
|
+
## Failure Policy
|
|
65
|
+
|
|
66
|
+
- If a challenge marker is detected, return a browser-required message instead
|
|
67
|
+
of retrying in a loop.
|
|
68
|
+
- If HTML is mostly an app shell, fetch browser-captured HTML or run WebView
|
|
69
|
+
injection.
|
|
70
|
+
- Keep server fetches sequential for release smoke checks. Browser-backed
|
|
71
|
+
comparisons must use `pnpm check:processes` before and after the run.
|
package/docs/webview.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# WebView and In-Page Usage
|
|
2
|
+
|
|
3
|
+
Use `createExtractorScript()` when the current page already exists in a mobile
|
|
4
|
+
WebView, Playwright page, Puppeteer page, browser extension, or in-app browser.
|
|
5
|
+
It builds an accessibility-style semantic tree from the live DOM without
|
|
6
|
+
opening a separate browser.
|
|
7
|
+
|
|
8
|
+
## Playwright
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import { createExtractorScript } from "ax-grep";
|
|
12
|
+
|
|
13
|
+
const text = await page.evaluate(createExtractorScript({
|
|
14
|
+
format: "text",
|
|
15
|
+
mode: "interactive",
|
|
16
|
+
includeBounds: false,
|
|
17
|
+
includeAttributes: false,
|
|
18
|
+
}));
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Android WebView
|
|
22
|
+
|
|
23
|
+
```kotlin
|
|
24
|
+
webView.evaluateJavascript(scriptFromServer) { jsonEncodedResult ->
|
|
25
|
+
// scriptFromServer is createExtractorScript({ format: "text" }).
|
|
26
|
+
// jsonEncodedResult contains the semantic tree text.
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Generate the script in your JavaScript bundle or server:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { createExtractorScript } from "ax-grep";
|
|
34
|
+
|
|
35
|
+
export const scriptFromServer = createExtractorScript({
|
|
36
|
+
format: "text",
|
|
37
|
+
mode: "interactive",
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## iOS WKWebView
|
|
42
|
+
|
|
43
|
+
```swift
|
|
44
|
+
webView.evaluateJavaScript(scriptFromServer) { result, error in
|
|
45
|
+
if let text = result as? String {
|
|
46
|
+
// Send text to the local model or agent parser.
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## In-Page Bundle
|
|
52
|
+
|
|
53
|
+
When your code already runs inside the page, use the browser entry point:
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import { extract, formatSemanticTreeText } from "ax-grep/browser";
|
|
57
|
+
|
|
58
|
+
const tree = extract({
|
|
59
|
+
mode: "interactive",
|
|
60
|
+
includeBounds: false,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
console.log(formatSemanticTreeText(tree));
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Mobile Agent Policy
|
|
67
|
+
|
|
68
|
+
For local sLLM search or parsing, run extraction in the current WebView first.
|
|
69
|
+
Escalate to network search or remote browser automation only when the semantic
|
|
70
|
+
tree lacks the target evidence, login state, or post-interaction content.
|
package/package.json
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ax-grep",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "A browser-native semantic accessibility tree extractor that runs without DevTools or CDP.",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=18"
|
|
8
|
+
},
|
|
6
9
|
"packageManager": "pnpm@10.33.4",
|
|
7
10
|
"publishConfig": {
|
|
8
11
|
"access": "public"
|
|
9
12
|
},
|
|
10
13
|
"repository": {
|
|
11
14
|
"type": "git",
|
|
12
|
-
"url": "git+https://github.com/hmmhmmhm/ax-
|
|
15
|
+
"url": "git+https://github.com/hmmhmmhm/ax-grep.git"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://github.com/hmmhmmhm/ax-grep#readme",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/hmmhmmhm/ax-grep/issues"
|
|
13
20
|
},
|
|
14
21
|
"exports": {
|
|
15
22
|
".": {
|
|
@@ -25,19 +32,40 @@
|
|
|
25
32
|
"import": "./dist/static.js"
|
|
26
33
|
}
|
|
27
34
|
},
|
|
35
|
+
"bin": {
|
|
36
|
+
"ax-grep": "./dist/cli.js"
|
|
37
|
+
},
|
|
28
38
|
"files": [
|
|
29
|
-
"dist"
|
|
39
|
+
"dist",
|
|
40
|
+
"docs",
|
|
41
|
+
"skills",
|
|
42
|
+
"skills.sh"
|
|
30
43
|
],
|
|
31
44
|
"scripts": {
|
|
32
45
|
"build": "tsup && tsc --noEmit",
|
|
33
46
|
"check": "tsc --noEmit",
|
|
47
|
+
"check:processes": "tsx scripts/check-project-processes.ts",
|
|
48
|
+
"readiness:audit": "tsx scripts/check-agent-readiness.ts",
|
|
49
|
+
"readiness:real-page-smoke": "tsx scripts/check-real-page-smoke.ts",
|
|
50
|
+
"readiness:search-smoke": "tsx scripts/check-search-smoke.ts",
|
|
51
|
+
"readiness:published-smoke": "tsx scripts/check-published-package-smoke.ts",
|
|
52
|
+
"readiness:agent-browser-smoke": "tsx scripts/check-agent-browser-smoke.ts",
|
|
53
|
+
"readiness:agent-browser-text-heavy-smoke": "tsx scripts/check-agent-browser-text-heavy-smoke.ts",
|
|
34
54
|
"test": "vitest run",
|
|
55
|
+
"test:coverage": "vitest run --coverage",
|
|
35
56
|
"test:watch": "vitest",
|
|
36
57
|
"compare": "tsx scripts/compare.ts",
|
|
37
58
|
"compare:static": "tsx scripts/compare-static.ts",
|
|
38
59
|
"compare:tokens": "tsx scripts/compare-token-cost.ts",
|
|
60
|
+
"benchmark:agent-cost": "tsx scripts/benchmark-agent-cost.ts",
|
|
61
|
+
"benchmark:library-cost": "node --expose-gc --import tsx scripts/benchmark-library-cost.ts",
|
|
62
|
+
"compare:browser:fixture": "tsx scripts/compare-browser-fixture.ts",
|
|
63
|
+
"compare:gate": "tsx scripts/check-comparison-gates.ts",
|
|
39
64
|
"compare:sample": "tsx scripts/compare.ts https://example.com https://www.wikipedia.org https://developer.mozilla.org/en-US/docs/Web/Accessibility https://news.ycombinator.com https://github.com/features https://libraries.io/npm/typescript https://www.npmjs.com/package/typescript",
|
|
40
65
|
"compare:korea": "tsx scripts/compare.ts https://ko.wikipedia.org/wiki/%EB%8C%80%ED%95%9C%EB%AF%BC%EA%B5%AD https://www.hani.co.kr/ https://www.korea.kr/ https://www.yonhapnewstv.co.kr/",
|
|
66
|
+
"compare:static:fixtures": "tsx scripts/compare-static.ts --target-set agent-fixtures",
|
|
67
|
+
"compare:static:fixtures:gate": "tsx scripts/check-fixture-static-gate.ts",
|
|
68
|
+
"compare:static:agent": "tsx scripts/compare-static.ts --target-set agent-executor",
|
|
41
69
|
"compare:static:korea-social": "tsx scripts/compare-static.ts --target-set korea-social",
|
|
42
70
|
"compare:tokens:korea-social": "tsx scripts/compare-token-cost.ts --target-set korea-social",
|
|
43
71
|
"compare:static:china-japan": "tsx scripts/compare-static.ts --target-set china-japan",
|
|
@@ -55,6 +83,7 @@
|
|
|
55
83
|
"license": "MIT",
|
|
56
84
|
"devDependencies": {
|
|
57
85
|
"@types/node": "^25.0.0",
|
|
86
|
+
"@vitest/coverage-v8": "4.1.8",
|
|
58
87
|
"agent-browser": "^0.27.0",
|
|
59
88
|
"puppeteer": "^24.31.0",
|
|
60
89
|
"tsup": "^8.5.1",
|
|
@@ -66,5 +95,8 @@
|
|
|
66
95
|
"domhandler": "^6.0.1",
|
|
67
96
|
"htmlparser2": "^12.0.0",
|
|
68
97
|
"js-tiktoken": "^1.0.21"
|
|
98
|
+
},
|
|
99
|
+
"optionalDependencies": {
|
|
100
|
+
"impit": "^0.14.1"
|
|
69
101
|
}
|
|
70
102
|
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ax-grep-cli
|
|
3
|
+
description: Use ax-grep as a CLI-first page search and page-check tool before opening a browser. Best for agents that need compact semantic trees, source links, hidden app signals, forms, tables, citations, and browser handoff guidance.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ax-grep CLI
|
|
7
|
+
|
|
8
|
+
Use `ax-grep` before browser automation when a subagent needs to inspect a
|
|
9
|
+
search result, URL, HTML file, or captured page.
|
|
10
|
+
|
|
11
|
+
## First Command
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
ax-grep "https://example.com" --agent
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
If `ax-grep` is not on `PATH`, use the npm executable:
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
npx --yes ax-grep@latest "https://example.com" --agent
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
For smaller context:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
ax-grep "https://example.com" --agent-brief
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Search
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
ax-grep --search "official docs pricing" --agent
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Use the returned `agent.*CommandArgs` fields when continuing. They are JSON argv
|
|
36
|
+
arrays in execution order. Use `agent.*Command` when you need a shell string.
|
|
37
|
+
|
|
38
|
+
## Agent Policy
|
|
39
|
+
|
|
40
|
+
- Prefer `--agent` or `--agent-brief` over raw text output for subagents.
|
|
41
|
+
- Read `agent.executor`, `agent.handoff`, `agent.next`, `agent.readTargets`,
|
|
42
|
+
and any returned `agent.sourceChoices` or `agent.resultChoices` before
|
|
43
|
+
deciding.
|
|
44
|
+
- If `agent.executor.decision` is `return`, answer from the referenced
|
|
45
|
+
`readFrom` payload instead of opening a browser.
|
|
46
|
+
- If a URL follow-up is needed, run the provided `commandArgs` one command at a
|
|
47
|
+
time.
|
|
48
|
+
- Escalate to browser automation only when `needsBrowserHtml`,
|
|
49
|
+
`needsBrowserInteraction`, or the executor/handoff fields say it is needed.
|
|
50
|
+
- Do not run multiple browser-backed checks in parallel.
|
|
51
|
+
|
|
52
|
+
## Useful Patterns
|
|
53
|
+
|
|
54
|
+
Inspect a result and open the best match in one step:
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
ax-grep --search "site:example.com api reference" --open-result best --agent
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
If an engine rejects `best`, open the top ranked result directly:
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
ax-grep --search "site:example.com api reference" --open-result 1 --agent
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Check a page for specific terms:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
ax-grep "https://example.com/docs" --find "rate limit" --find "authentication" --agent
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Read static HTML from another tool:
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
curl -fsSL "https://example.com" | ax-grep --stdin --agent
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## What ax-grep Sees
|
|
79
|
+
|
|
80
|
+
`ax-grep --agent` can expose:
|
|
81
|
+
|
|
82
|
+
- semantic headings, landmarks, links, buttons, forms, tables, and lists
|
|
83
|
+
- source-like links and ranked search choices
|
|
84
|
+
- JSON-LD schema facts, metadata, policies, topics, provenance, and citations
|
|
85
|
+
- hydration URLs, API endpoints, runtime hints, app config, and mobile hints
|
|
86
|
+
- recommended next commands and browser handoff reasons
|
|
87
|
+
|
|
88
|
+
Treat the full JSON payload as source of truth; top-level shortcuts are for
|
|
89
|
+
fast routing.
|
package/skills.sh
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
skill_name="ax-grep-cli"
|
|
5
|
+
target_root="${CODEX_HOME:-"$HOME/.codex"}/skills"
|
|
6
|
+
target_dir="$target_root/$skill_name"
|
|
7
|
+
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" 2>/dev/null && pwd)
|
|
8
|
+
local_skill="$script_dir/skills/$skill_name/SKILL.md"
|
|
9
|
+
remote_skill="${AX_GREP_SKILL_URL:-https://raw.githubusercontent.com/hmmhmmhm/ax-grep/main/skills/ax-grep-cli/SKILL.md}"
|
|
10
|
+
|
|
11
|
+
mkdir -p "$target_dir"
|
|
12
|
+
|
|
13
|
+
if [ -f "$local_skill" ]; then
|
|
14
|
+
cp "$local_skill" "$target_dir/SKILL.md"
|
|
15
|
+
elif command -v curl >/dev/null 2>&1; then
|
|
16
|
+
curl -fsSL "$remote_skill" -o "$target_dir/SKILL.md"
|
|
17
|
+
elif command -v wget >/dev/null 2>&1; then
|
|
18
|
+
wget -qO "$target_dir/SKILL.md" "$remote_skill"
|
|
19
|
+
else
|
|
20
|
+
echo "Could not find local skill file, curl, or wget." >&2
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
echo "Installed $skill_name skill to $target_dir"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/browser.ts"],"sourcesContent":["import type {\n SemanticNode,\n SemanticNodeState,\n SemanticTreeChange,\n SemanticTreeObserverOptions,\n SemanticTreeOptions,\n} from \"./types\";\n\ntype WalkContext = {\n options: Required<SemanticTreeOptions>;\n nextId: number;\n rootDocument: Document;\n};\n\nconst defaultOptions: Required<SemanticTreeOptions> = {\n mode: \"compact\",\n includeBounds: true,\n includeAttributes: true,\n includeTextNodes: true,\n includeHidden: false,\n includeSelectOptions: true,\n excludeLikelyAds: false,\n excludeLikelyBoilerplate: false,\n pruneCustomElementWrappers: true,\n pruneCollapsedSubtrees: true,\n pruneLikelyClosedOverlays: false,\n summarizeLargeSubtrees: false,\n summarizeLikelyLinkFarms: false,\n summarizeRepeatedSubtrees: false,\n maxChildrenPerNode: 80,\n maxLinkFarmChildren: 24,\n maxRepeatedSubtreeInstances: 3,\n maxTextLength: 240,\n};\n\nconst defaultObserverOptions: Required<Pick<SemanticTreeObserverOptions, \"debounceMs\">> = {\n debounceMs: 50,\n};\n\nconst interactiveRoles = new Set([\n \"button\",\n \"checkbox\",\n \"combobox\",\n \"link\",\n \"listbox\",\n \"menuitem\",\n \"menuitemcheckbox\",\n \"menuitemradio\",\n \"option\",\n \"radio\",\n \"searchbox\",\n \"slider\",\n \"spinbutton\",\n \"switch\",\n \"tab\",\n \"textbox\",\n \"treeitem\",\n]);\n\nconst landmarkTags: Record<string, string> = {\n article: \"article\",\n aside: \"complementary\",\n footer: \"contentinfo\",\n form: \"form\",\n header: \"banner\",\n main: \"main\",\n nav: \"navigation\",\n section: \"region\",\n};\n\nconst rolesNamedFromContents = new Set([\n \"button\",\n \"cell\",\n \"checkbox\",\n \"columnheader\",\n \"heading\",\n \"link\",\n \"menuitem\",\n \"menuitemcheckbox\",\n \"menuitemradio\",\n \"option\",\n \"radio\",\n \"rowheader\",\n \"switch\",\n \"tab\",\n \"treeitem\",\n]);\n\nexport function extractSemanticTree(options: SemanticTreeOptions = {}): SemanticNode {\n const rootDocument = document;\n const context: WalkContext = {\n options: { ...defaultOptions, ...options },\n nextId: 1,\n rootDocument,\n };\n\n return (\n walkElement(rootDocument.body ?? rootDocument.documentElement, context) ??\n unavailableNode(context, \"document\", \"Document has no inspectable body\")\n );\n}\n\nexport { extractSemanticTree as extract };\n\nexport function formatSemanticTreeText(node: SemanticNode): string {\n const lines: string[] = [];\n\n function visit(current: SemanticNode, depth: number): void {\n const prefix = \" \".repeat(depth);\n const role = current.role ?? current.tag;\n const marker = current.interactive ? \"[i] \" : \"\";\n const name = current.name ? ` '${current.name}'` : \"\";\n const state = formatState(current.state);\n const unavailable = current.unavailableReason ? ` (${current.unavailableReason})` : \"\";\n lines.push(`${prefix}${marker}${role}${name}${state}${unavailable}`);\n for (const child of current.children) visit(child, depth + 1);\n }\n\n visit(node, 0);\n return lines.join(\"\\n\");\n}\n\nexport function observeSemanticTree(\n onChange: (change: SemanticTreeChange) => void,\n options: SemanticTreeObserverOptions = {},\n): { disconnect: () => void; snapshot: () => SemanticNode } {\n const root = document.documentElement;\n const observerOptions = { ...defaultObserverOptions, ...options };\n let mutationCount = 0;\n let timeoutId: number | undefined;\n\n function snapshot(): SemanticNode {\n return extractSemanticTree(options);\n }\n\n function emit(): void {\n timeoutId = undefined;\n onChange({\n tree: snapshot(),\n changedAt: Date.now(),\n mutationCount,\n });\n mutationCount = 0;\n }\n\n const observer = new MutationObserver((mutations) => {\n mutationCount += mutations.length;\n if (timeoutId !== undefined) window.clearTimeout(timeoutId);\n timeoutId = window.setTimeout(emit, observerOptions.debounceMs);\n });\n\n observer.observe(root, {\n attributes: true,\n characterData: true,\n childList: true,\n subtree: true,\n });\n\n return {\n disconnect() {\n if (timeoutId !== undefined) window.clearTimeout(timeoutId);\n observer.disconnect();\n },\n snapshot,\n };\n}\n\nfunction walkElement(element: Element, context: WalkContext): SemanticNode | null {\n if (!context.options.includeHidden && isHidden(element)) return null;\n if (context.options.excludeLikelyAds && isLikelyAd(element)) return null;\n\n const role = getRole(element);\n const state = getState(element);\n const focusable = isFocusable(element);\n const interactive = isInteractive(element, role, focusable);\n const name = role ? computeName(element, role, context) : \"\";\n const description = computeDescription(element, context);\n const tag = element.tagName.toLowerCase();\n const children = collectChildren(element, context);\n\n if (context.options.mode === \"interactive\" && !interactive) {\n return children.length > 0\n ? containerNode(context, tag, children)\n : null;\n }\n\n if (shouldPrune(element, role, name, interactive, children, context)) {\n return children.length === 1 ? children[0] ?? null : containerNode(context, tag, children);\n }\n\n const node: SemanticNode = {\n id: nextId(context),\n tag,\n role,\n name,\n interactive,\n focusable,\n children,\n };\n\n if (description) node.description = description;\n const text = getDirectText(element, context.options.maxTextLength);\n if (text) node.text = text;\n const value = getValue(element);\n if (value) node.value = value;\n if (Object.keys(state).length > 0) node.state = state;\n node.selector = getCssPath(element);\n node.xpath = getXPath(element);\n if (context.options.includeBounds) node.bounds = getBounds(element);\n if (context.options.includeAttributes) node.attributes = getAttributes(element);\n\n appendSpecialChildren(element, node, context);\n appendShadowChildren(element, node, context);\n appendFrameChildren(element, node, context);\n\n return node;\n}\n\nfunction collectChildren(element: Element, context: WalkContext): SemanticNode[] {\n const children: SemanticNode[] = [];\n for (const child of Array.from(element.childNodes)) {\n if (child.nodeType === Node.ELEMENT_NODE) {\n if (!context.options.includeSelectOptions && element instanceof HTMLSelectElement) continue;\n const semanticChild = walkElement(child as Element, context);\n if (semanticChild) children.push(semanticChild);\n continue;\n }\n\n if (context.options.includeTextNodes && child.nodeType === Node.TEXT_NODE) {\n const text = normalizeText(child.textContent ?? \"\", context.options.maxTextLength);\n if (text) {\n children.push({\n id: nextId(context),\n tag: \"#text\",\n role: \"text\",\n name: text,\n text,\n interactive: false,\n focusable: false,\n children: [],\n });\n }\n }\n }\n return children;\n}\n\nfunction shouldPrune(\n element: Element,\n role: string | null,\n name: string,\n interactive: boolean,\n children: SemanticNode[],\n context: WalkContext,\n): boolean {\n if (context.options.mode === \"full\") return false;\n if (role === \"none\" || role === \"presentation\") return true;\n if (interactive) return false;\n if (context.options.pruneCustomElementWrappers && isCustomElement(element)) return children.length > 0;\n if (role && role !== \"generic\") return false;\n if (name) return false;\n if (element.id || element.getAttribute(\"aria-label\") || element.getAttribute(\"aria-labelledby\")) return false;\n return children.length > 0;\n}\n\nfunction getRole(element: Element): string | null {\n const explicit = firstToken(element.getAttribute(\"role\"));\n if (explicit) return explicit;\n\n const tag = element.tagName.toLowerCase();\n if (tag === \"section\" && !hasExplicitNameSource(element)) return null;\n if (tag === \"form\" && !hasExplicitNameSource(element)) return null;\n if (tag in landmarkTags) return landmarkTags[tag] ?? null;\n if (/^h[1-6]$/.test(tag)) return \"heading\";\n\n if (tag === \"a\" || tag === \"area\") return element.hasAttribute(\"href\") ? \"link\" : null;\n if (tag === \"button\") return \"button\";\n if (tag === \"details\") return \"group\";\n if (tag === \"dialog\") return \"dialog\";\n if (tag === \"fieldset\") return \"group\";\n if (tag === \"figure\") return \"figure\";\n if (tag === \"iframe\") return \"iframe\";\n if (tag === \"img\") return hasEmptyAlt(element) ? \"presentation\" : \"img\";\n if (tag === \"li\") return \"listitem\";\n if (tag === \"ol\" || tag === \"ul\") return \"list\";\n if (tag === \"optgroup\") return \"group\";\n if (tag === \"option\") return \"option\";\n if (tag === \"output\") return \"status\";\n if (tag === \"progress\") return \"progressbar\";\n if (tag === \"select\") return element.hasAttribute(\"multiple\") ? \"listbox\" : \"combobox\";\n if (tag === \"summary\") return \"button\";\n if (tag === \"table\") return \"table\";\n if (tag === \"caption\") return \"caption\";\n if (tag === \"tbody\" || tag === \"tfoot\" || tag === \"thead\") return \"rowgroup\";\n if (tag === \"td\") return \"cell\";\n if (tag === \"textarea\") return \"textbox\";\n if (tag === \"th\") return element.getAttribute(\"scope\") === \"row\" ? \"rowheader\" : \"columnheader\";\n if (tag === \"tr\") return \"row\";\n\n if (tag === \"input\") return inputRole(element as HTMLInputElement);\n return null;\n}\n\nfunction inputRole(input: HTMLInputElement): string | null {\n const type = (input.getAttribute(\"type\") || \"text\").toLowerCase();\n if (type === \"button\" || type === \"image\" || type === \"reset\" || type === \"submit\") return \"button\";\n if (type === \"checkbox\") return \"checkbox\";\n if (type === \"email\" || type === \"tel\" || type === \"text\" || type === \"url\") return \"textbox\";\n if (type === \"number\") return \"spinbutton\";\n if (type === \"radio\") return \"radio\";\n if (type === \"range\") return \"slider\";\n if (type === \"search\") return \"searchbox\";\n if (type === \"hidden\") return null;\n return \"textbox\";\n}\n\nfunction computeName(element: Element, role: string, context: WalkContext): string {\n if (element.getAttribute(\"aria-labelledby\")) {\n const labelled = textFromIds(element.getAttribute(\"aria-labelledby\") ?? \"\", context.rootDocument);\n if (labelled) return labelled;\n }\n\n const ariaLabel = element.getAttribute(\"aria-label\");\n if (ariaLabel) return normalizeText(ariaLabel, context.options.maxTextLength);\n\n if (element instanceof HTMLInputElement && isButtonLikeInput(element)) {\n return normalizeText(element.value || element.getAttribute(\"value\") || inputFallbackName(element), context.options.maxTextLength);\n }\n\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement) {\n const label = labelText(element, context);\n if (label) return label;\n const placeholder = element.getAttribute(\"placeholder\");\n if (placeholder) return normalizeText(placeholder, context.options.maxTextLength);\n }\n\n if (element instanceof HTMLImageElement) {\n return normalizeText(element.alt || element.getAttribute(\"title\") || \"\", context.options.maxTextLength);\n }\n\n if (element instanceof HTMLFieldSetElement) {\n const legend = element.querySelector(\":scope > legend\");\n if (legend) return getVisibleText(legend, context.options.maxTextLength);\n }\n\n if (rolesNamedFromContents.has(role)) {\n const ownText = getVisibleText(element, context.options.maxTextLength);\n if (ownText) return ownText;\n }\n\n return normalizeText(element.getAttribute(\"title\") ?? \"\", context.options.maxTextLength);\n}\n\nfunction computeDescription(element: Element, context: WalkContext): string {\n const describedBy = element.getAttribute(\"aria-describedby\");\n if (describedBy) return textFromIds(describedBy, context.rootDocument);\n return normalizeText(element.getAttribute(\"title\") ?? \"\", context.options.maxTextLength);\n}\n\nfunction labelText(\n element: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement,\n context: WalkContext,\n): string {\n if (element.labels && element.labels.length > 0) {\n return normalizeText(Array.from(element.labels).map((label) => getVisibleText(label, context.options.maxTextLength)).join(\" \"), context.options.maxTextLength);\n }\n return \"\";\n}\n\nfunction getState(element: Element): SemanticNodeState {\n const state: SemanticNodeState = {};\n if (isHidden(element)) state.hidden = true;\n if (isDisabled(element)) state.disabled = true;\n if (element === document.activeElement) state.focused = true;\n\n const checked = ariaBooleanOrMixed(element.getAttribute(\"aria-checked\"));\n if (checked !== undefined) state.checked = checked;\n else if (element instanceof HTMLInputElement && (element.type === \"checkbox\" || element.type === \"radio\")) {\n state.checked = element.checked;\n }\n\n const selected = ariaBoolean(element.getAttribute(\"aria-selected\"));\n if (selected !== undefined) state.selected = selected;\n else if (element instanceof HTMLOptionElement) state.selected = element.selected;\n\n const expanded = ariaBoolean(element.getAttribute(\"aria-expanded\"));\n if (expanded !== undefined) state.expanded = expanded;\n\n const pressed = ariaBooleanOrMixed(element.getAttribute(\"aria-pressed\"));\n if (pressed !== undefined) state.pressed = pressed;\n\n const required = ariaBoolean(element.getAttribute(\"aria-required\"));\n if (required !== undefined) state.required = required;\n else if (\"required\" in element && Boolean((element as HTMLInputElement).required)) state.required = true;\n\n const invalid = element.getAttribute(\"aria-invalid\");\n if (invalid && invalid !== \"false\") state.invalid = invalid === \"true\" ? true : invalid;\n\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {\n if (element.readOnly) state.readonly = true;\n }\n\n return state;\n}\n\nfunction isHidden(element: Element): boolean {\n if (element.hasAttribute(\"hidden\")) return true;\n if (element.getAttribute(\"aria-hidden\") === \"true\") return true;\n\n const style = getComputedStyle(element);\n if (\n style.display === \"none\" ||\n style.visibility === \"hidden\" ||\n style.contentVisibility === \"hidden\"\n ) return true;\n if (Number(style.opacity) === 0) return true;\n return false;\n}\n\nfunction isLikelyAd(element: Element): boolean {\n const haystack = [\n element.id,\n element.getAttribute(\"class\"),\n element.getAttribute(\"aria-label\"),\n element.getAttribute(\"data-testid\"),\n element.getAttribute(\"data-test-id\"),\n element.getAttribute(\"data-name\"),\n ].filter(Boolean).join(\" \").toLowerCase();\n if (/\\b(ad|ads|advert|advertisement|sponsor|sponsored|placement)\\b/.test(haystack)) return true;\n if (element instanceof HTMLAnchorElement && normalizeText(element.textContent ?? \"\", 80).toLowerCase() === \"ad\") return true;\n return false;\n}\n\nfunction isDisabled(element: Element): boolean {\n if (element.getAttribute(\"aria-disabled\") === \"true\") return true;\n return \"disabled\" in element && Boolean((element as HTMLButtonElement).disabled);\n}\n\nfunction isFocusable(element: Element): boolean {\n if (isDisabled(element) || isHidden(element)) return false;\n const tabindex = element.getAttribute(\"tabindex\");\n if (tabindex !== null) return Number(tabindex) >= 0;\n return element.matches(\"a[href],area[href],button,input,select,textarea,summary,iframe,[contenteditable=''],[contenteditable='true']\");\n}\n\nfunction isInteractive(element: Element, role: string | null, focusable: boolean): boolean {\n if (role && interactiveRoles.has(role)) return true;\n if (element.matches(\"a[href],button,input,select,textarea,summary,option\")) return true;\n if (element.hasAttribute(\"onclick\")) return true;\n return focusable && Boolean(role);\n}\n\nfunction appendSpecialChildren(element: Element, node: SemanticNode, context: WalkContext): void {\n if (!context.options.includeSelectOptions) return;\n if (element instanceof HTMLSelectElement) {\n for (const option of Array.from(element.options)) {\n node.children.push({\n id: nextId(context),\n tag: \"option\",\n role: \"option\",\n name: normalizeText(option.textContent ?? \"\", context.options.maxTextLength),\n value: option.value,\n state: { selected: option.selected, disabled: option.disabled },\n interactive: false,\n focusable: false,\n selector: getCssPath(option),\n xpath: getXPath(option),\n children: [],\n });\n }\n }\n}\n\nfunction isCustomElement(element: Element): boolean {\n return element.tagName.includes(\"-\");\n}\n\nfunction appendShadowChildren(element: Element, node: SemanticNode, context: WalkContext): void {\n const shadowRoot = element.shadowRoot;\n if (!shadowRoot) return;\n for (const child of Array.from(shadowRoot.children)) {\n const semanticChild = walkElement(child, context);\n if (semanticChild) node.children.push(semanticChild);\n }\n}\n\nfunction appendFrameChildren(element: Element, node: SemanticNode, context: WalkContext): void {\n if (!(element instanceof HTMLIFrameElement)) return;\n try {\n const frameDocument = element.contentDocument;\n if (!frameDocument?.body) {\n node.children.push(unavailableNode(context, \"iframe\", \"iframe document unavailable\"));\n return;\n }\n const previousDocument = context.rootDocument;\n context.rootDocument = frameDocument;\n const child = walkElement(frameDocument.body, context);\n context.rootDocument = previousDocument;\n if (child) node.children.push(child);\n } catch {\n node.children.push(unavailableNode(context, \"iframe\", \"cross-origin iframe\"));\n }\n}\n\nfunction unavailableNode(context: WalkContext, tag: string, reason: string): SemanticNode {\n return {\n id: nextId(context),\n tag,\n role: null,\n name: \"\",\n interactive: false,\n focusable: false,\n unavailableReason: reason,\n children: [],\n };\n}\n\nfunction containerNode(context: WalkContext, tag: string, children: SemanticNode[]): SemanticNode {\n return {\n id: nextId(context),\n tag,\n role: null,\n name: \"\",\n interactive: false,\n focusable: false,\n children,\n };\n}\n\nfunction getValue(element: Element): string {\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement) {\n return element.value;\n }\n return normalizeText(element.getAttribute(\"aria-valuetext\") ?? element.getAttribute(\"aria-valuenow\") ?? \"\", 80);\n}\n\nfunction getDirectText(element: Element, maxLength: number): string {\n return normalizeText(\n Array.from(element.childNodes)\n .filter((node) => node.nodeType === Node.TEXT_NODE)\n .map((node) => node.textContent ?? \"\")\n .join(\" \"),\n maxLength,\n );\n}\n\nfunction getVisibleText(element: Element, maxLength: number): string {\n const parts: string[] = [];\n\n function visit(node: Node): void {\n if (node.nodeType === Node.TEXT_NODE) {\n parts.push(node.textContent ?? \"\");\n return;\n }\n\n if (node.nodeType !== Node.ELEMENT_NODE) return;\n const childElement = node as Element;\n if (isHidden(childElement)) return;\n for (const child of Array.from(childElement.childNodes)) visit(child);\n }\n\n visit(element);\n return normalizeText(parts.join(\" \"), maxLength);\n}\n\nfunction getAttributes(element: Element): Record<string, string> {\n const attributes: Record<string, string> = {};\n for (const attribute of Array.from(element.attributes)) {\n if (\n attribute.name === \"id\" ||\n attribute.name === \"href\" ||\n attribute.name === \"type\" ||\n attribute.name === \"role\" ||\n attribute.name === \"alt\" ||\n attribute.name === \"title\" ||\n attribute.name.startsWith(\"aria-\") ||\n attribute.name.startsWith(\"data-\")\n ) {\n attributes[attribute.name] = attribute.value;\n }\n }\n return attributes;\n}\n\nfunction getBounds(element: Element) {\n const rect = element.getBoundingClientRect();\n return {\n x: round(rect.x),\n y: round(rect.y),\n width: round(rect.width),\n height: round(rect.height),\n };\n}\n\nfunction getCssPath(element: Element): string {\n if (element.id) return `#${cssEscape(element.id)}`;\n const segments: string[] = [];\n let current: Element | null = element;\n while (current && current.nodeType === Node.ELEMENT_NODE && current !== document.documentElement) {\n const elementAtLevel: Element = current;\n const tag = elementAtLevel.tagName.toLowerCase();\n const parent: Element | null = elementAtLevel.parentElement;\n if (!parent) {\n segments.unshift(tag);\n break;\n }\n const siblings = Array.from(parent.children).filter((child) => child.tagName === elementAtLevel.tagName);\n const index = siblings.indexOf(elementAtLevel) + 1;\n segments.unshift(siblings.length > 1 ? `${tag}:nth-of-type(${index})` : tag);\n current = parent;\n }\n return segments.join(\" > \");\n}\n\nfunction getXPath(element: Element): string {\n const segments: string[] = [];\n let current: Element | null = element;\n while (current && current.nodeType === Node.ELEMENT_NODE) {\n const elementAtLevel: Element = current;\n const tag = elementAtLevel.tagName.toLowerCase();\n const parent: Element | null = elementAtLevel.parentElement;\n if (!parent) {\n segments.unshift(`/${tag}[1]`);\n break;\n }\n const sameTag = Array.from(parent.children).filter((child) => child.tagName === elementAtLevel.tagName);\n segments.unshift(`/${tag}[${sameTag.indexOf(elementAtLevel) + 1}]`);\n current = parent;\n }\n return segments.join(\"\");\n}\n\nfunction textFromIds(ids: string, rootDocument: Document): string {\n return normalizeText(\n ids\n .split(/\\s+/)\n .map((id) => {\n const element = rootDocument.getElementById(id);\n return element ? getVisibleText(element, 240) : \"\";\n })\n .filter(Boolean)\n .join(\" \"),\n 240,\n );\n}\n\nfunction normalizeText(value: string, maxLength: number): string {\n const normalized = value.replace(/\\s+/g, \" \").trim();\n return normalized.length > maxLength ? `${normalized.slice(0, maxLength - 1)}…` : normalized;\n}\n\nfunction firstToken(value: string | null): string | null {\n return value?.trim().split(/\\s+/)[0] || null;\n}\n\nfunction hasExplicitNameSource(element: Element): boolean {\n return Boolean(\n element.getAttribute(\"aria-label\") ||\n element.getAttribute(\"aria-labelledby\") ||\n element.getAttribute(\"title\"),\n );\n}\n\nfunction hasEmptyAlt(element: Element): boolean {\n return element.hasAttribute(\"alt\") && element.getAttribute(\"alt\") === \"\";\n}\n\nfunction isButtonLikeInput(input: HTMLInputElement): boolean {\n return [\"button\", \"image\", \"reset\", \"submit\"].includes((input.getAttribute(\"type\") || \"\").toLowerCase());\n}\n\nfunction inputFallbackName(input: HTMLInputElement): string {\n const type = (input.getAttribute(\"type\") || \"\").toLowerCase();\n if (type === \"submit\") return \"Submit\";\n if (type === \"reset\") return \"Reset\";\n return \"\";\n}\n\nfunction ariaBoolean(value: string | null): boolean | undefined {\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n return undefined;\n}\n\nfunction ariaBooleanOrMixed(value: string | null): boolean | \"mixed\" | undefined {\n if (value === \"mixed\") return \"mixed\";\n return ariaBoolean(value);\n}\n\nfunction formatState(state: SemanticNodeState | undefined): string {\n if (!state) return \"\";\n const entries = Object.entries(state).filter(([, value]) => value !== undefined);\n return entries.length > 0\n ? ` [${entries.map(([key, value]) => `${key}=${String(value)}`).join(\" \")}]`\n : \"\";\n}\n\nfunction nextId(context: WalkContext): string {\n const id = `n${context.nextId}`;\n context.nextId += 1;\n return id;\n}\n\nfunction round(value: number): number {\n return Math.round(value * 100) / 100;\n}\n\nfunction cssEscape(value: string): string {\n if (typeof CSS !== \"undefined\" && typeof CSS.escape === \"function\") {\n return CSS.escape(value);\n }\n return value.replace(/[^a-zA-Z0-9_-]/g, (char) => `\\\\${char}`);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/static.ts"],"sourcesContent":["import { DomUtils, parseDocument } from \"htmlparser2\";\nimport { Element as DomElement } from \"domhandler\";\nimport type { AnyNode, Element, Text } from \"domhandler\";\nimport type { SemanticNode, SemanticNodeState, SemanticTreeOptions } from \"./types\";\n\ntype StaticContext = {\n options: Required<Pick<\n SemanticTreeOptions,\n \"excludeLikelyAds\" | \"excludeLikelyBoilerplate\" | \"includeAttributes\" | \"includeHidden\" | \"includeSelectOptions\" | \"includeTextNodes\" | \"maxChildrenPerNode\" | \"maxLinkFarmChildren\" | \"maxRepeatedSubtreeInstances\" | \"maxTextLength\" | \"mode\" | \"pruneCollapsedSubtrees\" | \"pruneLikelyClosedOverlays\" | \"summarizeLargeSubtrees\" | \"summarizeLikelyLinkFarms\" | \"summarizeRepeatedSubtrees\"\n >>;\n nextId: number;\n ids: Map<string, Element>;\n collapsedControlledIds: Set<string>;\n labelsByFor: Map<string, string>;\n};\n\nconst defaultOptions = {\n includeAttributes: true,\n excludeLikelyAds: false,\n includeHidden: false,\n includeSelectOptions: true,\n includeTextNodes: false,\n maxTextLength: 240,\n mode: \"compact\",\n excludeLikelyBoilerplate: false,\n maxChildrenPerNode: 80,\n maxLinkFarmChildren: 24,\n maxRepeatedSubtreeInstances: 3,\n pruneCollapsedSubtrees: true,\n pruneLikelyClosedOverlays: true,\n summarizeLargeSubtrees: true,\n summarizeLikelyLinkFarms: true,\n summarizeRepeatedSubtrees: true,\n} satisfies StaticContext[\"options\"];\n\nconst interactiveRoles = new Set([\n \"button\",\n \"checkbox\",\n \"combobox\",\n \"link\",\n \"listbox\",\n \"menuitem\",\n \"menuitemcheckbox\",\n \"menuitemradio\",\n \"option\",\n \"radio\",\n \"searchbox\",\n \"slider\",\n \"spinbutton\",\n \"switch\",\n \"tab\",\n \"textbox\",\n \"treeitem\",\n]);\n\nconst landmarkTags: Record<string, string> = {\n article: \"article\",\n aside: \"complementary\",\n footer: \"contentinfo\",\n header: \"banner\",\n main: \"main\",\n nav: \"navigation\",\n section: \"region\",\n};\n\nconst rolesNamedFromContents = new Set([\n \"button\",\n \"cell\",\n \"checkbox\",\n \"columnheader\",\n \"heading\",\n \"link\",\n \"listitem\",\n \"menuitem\",\n \"menuitemcheckbox\",\n \"menuitemradio\",\n \"option\",\n \"radio\",\n \"rowheader\",\n \"switch\",\n \"tab\",\n \"treeitem\",\n]);\n\nconst hiddenStylePattern = /(?:^|;)\\s*(display\\s*:\\s*none|visibility\\s*:\\s*hidden|content-visibility\\s*:\\s*hidden|opacity\\s*:\\s*0(?:\\.0+)?)(?:;|$)/i;\nconst nonSemanticTags = new Set([\"head\", \"link\", \"meta\", \"script\", \"style\", \"template\"]);\n\nexport type StaticSemanticTreeOptions = Pick<\n SemanticTreeOptions,\n \"excludeLikelyAds\" | \"excludeLikelyBoilerplate\" | \"includeAttributes\" | \"includeHidden\" | \"includeSelectOptions\" | \"includeTextNodes\" | \"maxChildrenPerNode\" | \"maxLinkFarmChildren\" | \"maxRepeatedSubtreeInstances\" | \"maxTextLength\" | \"mode\" | \"pruneCollapsedSubtrees\" | \"pruneLikelyClosedOverlays\" | \"summarizeLargeSubtrees\" | \"summarizeLikelyLinkFarms\" | \"summarizeRepeatedSubtrees\"\n>;\n\nexport function extractStaticSemanticTree(html: string, options: StaticSemanticTreeOptions = {}): SemanticNode {\n const document = parseDocument(html, {\n lowerCaseAttributeNames: true,\n lowerCaseTags: true,\n recognizeSelfClosing: true,\n });\n const context: StaticContext = {\n options: resolveStaticOptions(document.children, html, options),\n nextId: 1,\n ids: new Map(),\n collapsedControlledIds: new Set(),\n labelsByFor: new Map(),\n };\n indexDocument(document.children, context);\n const root = findElement(document.children, \"body\") ?? findElement(document.children, \"html\") ?? fragmentRoot(document.children);\n return walkElement(root, context) ?? unavailableNode(context, \"document\", \"HTML has no inspectable root\");\n}\n\nexport { extractStaticSemanticTree as extract };\n\nfunction resolveStaticOptions(nodes: AnyNode[], html: string, options: StaticSemanticTreeOptions): StaticContext[\"options\"] {\n const inferred = inferStaticSourceProfile(nodes, html);\n const resolved = { ...defaultOptions };\n\n if (inferred.wikiLike) {\n resolved.maxChildrenPerNode = 400;\n resolved.maxLinkFarmChildren = 80;\n }\n if (inferred.forumLike) {\n resolved.maxLinkFarmChildren = 19;\n }\n\n return { ...resolved, ...options };\n}\n\nfunction inferStaticSourceProfile(nodes: AnyNode[], html: string): { wikiLike: boolean; forumLike: boolean } {\n const root = findElement(nodes, \"html\") ?? fragmentRoot(nodes);\n const body = findElement(nodes, \"body\");\n const profileText = [\n attr(root, \"class\"),\n attr(root, \"id\"),\n body ? attr(body, \"class\") : \"\",\n body ? attr(body, \"id\") : \"\",\n firstMetaContent(root, \"generator\"),\n firstMetaContent(root, \"application-name\"),\n firstMetaContent(root, \"twitter:site\"),\n ].filter(Boolean).join(\" \").toLowerCase();\n\n return {\n wikiLike: /\\b(mediawiki|mw-parser-output|wikipedia|wikimedia)\\b/.test(profileText)\n || /\\b(?:id|class)=[\"'][^\"']*\\bmw-parser-output\\b/i.test(html),\n forumLike: /\\b(5ch|2ch|dcinside|ruliweb|clien|bbs|board|forum|gallery|gall|thread|subback)\\b/.test(profileText)\n || /\\b(?:id|class)=[\"'][^\"']*\\b(?:gall_list|threadlist|thread-list|board-list|article-list|subback|bbs|forum)\\b/i.test(html)\n || /(?:갤러리|게시판|댓글|개념글|스레드|レス|話題度)/.test(html),\n };\n}\n\nfunction firstMetaContent(root: Element | undefined, name: string): string {\n if (!root) return \"\";\n const stack = [...root.children];\n while (stack.length > 0) {\n const node = stack.shift();\n if (!node) continue;\n if (!isElement(node)) continue;\n if (node.name === \"meta\" && (attr(node, \"name\") === name || attr(node, \"property\") === name)) {\n return attr(node, \"content\") ?? \"\";\n }\n stack.unshift(...node.children);\n }\n return \"\";\n}\n\nfunction indexDocument(nodes: AnyNode[], context: StaticContext): void {\n for (const node of nodes) {\n if (!isElement(node)) continue;\n const id = attr(node, \"id\");\n if (id) context.ids.set(id, node);\n if (attr(node, \"aria-expanded\") === \"false\") {\n for (const controlledId of (attr(node, \"aria-controls\") ?? \"\").split(/\\s+/)) {\n if (controlledId) context.collapsedControlledIds.add(controlledId);\n }\n }\n if (node.name === \"label\") {\n const target = attr(node, \"for\");\n if (target) context.labelsByFor.set(target, normalizeText(descendantText(node), context.options.maxTextLength));\n }\n indexDocument(node.children, context);\n }\n}\n\nfunction walkElement(element: Element | undefined, context: StaticContext): SemanticNode | null {\n if (!element) return null;\n if (shouldSkipElement(element, context)) return null;\n if (!context.options.includeHidden && isHidden(element)) return null;\n if (context.options.excludeLikelyAds && isLikelyAd(element)) return null;\n if (context.options.excludeLikelyBoilerplate && isLikelyBoilerplateTable(element)) return flattenBoilerplateTable(element, context);\n if (context.options.excludeLikelyBoilerplate && isLikelyBoilerplate(element)) return null;\n if (!context.options.includeHidden && isCollapsedControlledElement(element, context)) return null;\n if (!context.options.includeHidden && isLikelyClosedOverlay(element, context)) return null;\n\n const role = getRole(element);\n const state = getState(element);\n const focusable = isFocusable(element, role);\n const interactive = isInteractive(element, role, focusable);\n const name = role ? computeName(element, role, context) : \"\";\n const tag = element.name;\n const children = shouldSkipChildrenForCollapsedElement(element, context) ? [] : collectChildren(element, context);\n\n if (context.options.mode === \"interactive\" && !interactive) {\n return children.length > 0 ? containerNode(context, tag, children) : null;\n }\n if (shouldPruneListItemWrapper(role, children, context)) {\n return children.length === 1 ? children[0] ?? null : containerNode(context, tag, children);\n }\n if (shouldPrune(element, role, name, interactive, children, context)) {\n if (children.length === 0) return null;\n return children.length === 1 ? children[0] ?? null : containerNode(context, tag, children);\n }\n\n const node: SemanticNode = {\n id: nextId(context),\n tag,\n role,\n name,\n interactive,\n focusable,\n selector: getSelector(element),\n xpath: getXPath(element),\n children,\n };\n const text = directText(element, context.options.maxTextLength);\n if (text) node.text = text;\n const value = getValue(element);\n if (value) node.value = value;\n if (Object.keys(state).length > 0) node.state = state;\n if (context.options.includeAttributes) node.attributes = { ...element.attribs };\n return node;\n}\n\nfunction collectChildren(element: Element, context: StaticContext): SemanticNode[] {\n const children: SemanticNode[] = [];\n const repeatedSignatures = new Map<string, number>();\n let omitted = 0;\n for (const child of element.children) {\n if (isElement(child)) {\n if (!context.options.includeSelectOptions && element.name === \"select\") continue;\n const semanticChild = walkElement(child, context);\n if (semanticChild) {\n if (shouldSummarizeRepeatedChild(element, semanticChild, repeatedSignatures, context)) {\n omitted += countSemanticNodes(semanticChild);\n continue;\n }\n if (shouldSummarizeMoreChildren(element, children, context)) {\n omitted += countSemanticNodes(semanticChild);\n } else {\n children.push(semanticChild);\n }\n }\n } else if (context.options.includeTextNodes && isText(child)) {\n const text = normalizeText(child.data, context.options.maxTextLength);\n if (text) {\n const textNode: SemanticNode = {\n id: nextId(context),\n tag: \"#text\",\n role: \"text\",\n name: text,\n text,\n interactive: false,\n focusable: false,\n children: [],\n };\n if (shouldSummarizeMoreChildren(element, children, context)) {\n omitted += 1;\n } else {\n children.push(textNode);\n }\n }\n }\n }\n const linkFarmSummary = summarizeLikelyLinkFarmChildren(element, children, context);\n if (linkFarmSummary.omitted > 0) {\n children.splice(0, children.length, ...linkFarmSummary.children);\n omitted += linkFarmSummary.omitted;\n }\n if (omitted > 0) children.push(omittedNode(context, omitted));\n return children;\n}\n\nfunction shouldSkipElement(element: Element, context: StaticContext): boolean {\n if (context.options.mode === \"full\") return false;\n if (nonSemanticTags.has(element.name)) return true;\n if (element.name === \"noscript\") return true;\n return false;\n}\n\nfunction shouldSummarizeMoreChildren(element: Element, children: SemanticNode[], context: StaticContext): boolean {\n if (!context.options.summarizeLargeSubtrees || context.options.mode === \"full\") return false;\n if (!isLargeSubtreeCandidate(element)) return false;\n return children.length >= context.options.maxChildrenPerNode;\n}\n\nfunction isLargeSubtreeCandidate(element: Element): boolean {\n return [\"nav\", \"ul\", \"ol\", \"div\", \"section\", \"footer\", \"header\", \"main\"].includes(element.name);\n}\n\nfunction summarizeLikelyLinkFarmChildren(\n element: Element,\n children: SemanticNode[],\n context: StaticContext,\n): { children: SemanticNode[]; omitted: number } {\n if (!context.options.summarizeLikelyLinkFarms || context.options.mode === \"full\") return { children, omitted: 0 };\n if (children.length <= context.options.maxLinkFarmChildren) return { children, omitted: 0 };\n if (!isLikelyLinkFarmContainer(element)) return { children, omitted: 0 };\n const stats = childLinkFarmStats(children);\n if (stats.linkishChildren < Math.max(8, Math.floor(children.length * 0.65))) return { children, omitted: 0 };\n if (stats.contentRichChildren > Math.max(2, Math.floor(children.length * 0.2))) return { children, omitted: 0 };\n\n const kept: SemanticNode[] = [];\n let omitted = 0;\n let keptLinkish = 0;\n for (const child of children) {\n if (!isLinkishSummaryChild(child)) {\n kept.push(child);\n continue;\n }\n if (keptLinkish < context.options.maxLinkFarmChildren) {\n kept.push(child);\n keptLinkish += 1;\n } else {\n omitted += countSemanticNodes(child);\n }\n }\n return omitted > 0 ? { children: kept, omitted } : { children, omitted: 0 };\n}\n\nfunction isLikelyLinkFarmContainer(element: Element): boolean {\n if ([\"nav\", \"ul\", \"ol\", \"aside\", \"footer\", \"header\"].includes(element.name)) return true;\n if (![\"div\", \"section\"].includes(element.name)) return false;\n const value = [\n attr(element, \"id\"),\n attr(element, \"class\"),\n attr(element, \"role\"),\n attr(element, \"aria-label\"),\n attr(element, \"title\"),\n ].filter(Boolean).join(\" \").toLowerCase();\n if (/\\b(article|body|content|contents|entry|main|post|story|text|view)\\b/.test(value)) return false;\n return /\\b(board|category|comment|footer|gallery|gnb|header|issue|list|menu|nav|popular|recent|recommend|related|reply|sidebar|tab)\\b/.test(value)\n || /갤러리|댓글|개념글|관련|목록|베스트|인기|최근|추천|카테고리/.test(value);\n}\n\nfunction childLinkFarmStats(children: SemanticNode[]): { linkishChildren: number; contentRichChildren: number } {\n let linkishChildren = 0;\n let contentRichChildren = 0;\n for (const child of children) {\n if (isLinkishSummaryChild(child)) linkishChildren += 1;\n if (isContentRichSummaryChild(child)) contentRichChildren += 1;\n }\n return { linkishChildren, contentRichChildren };\n}\n\nfunction isLinkishSummaryChild(node: SemanticNode): boolean {\n const stats = semanticRoleStats(node);\n return stats.links > 0\n && stats.formControls === 0\n && stats.tables === 0\n && stats.paragraphs <= 1\n && stats.contentContainers === 0;\n}\n\nfunction isContentRichSummaryChild(node: SemanticNode): boolean {\n const stats = semanticRoleStats(node);\n return stats.paragraphs > 1 || stats.tables > 0 || stats.contentContainers > 0 || stats.formControls > 0;\n}\n\nfunction semanticRoleStats(node: SemanticNode): {\n links: number;\n paragraphs: number;\n tables: number;\n formControls: number;\n contentContainers: number;\n} {\n const role = node.role ?? node.tag;\n const stats = {\n links: role === \"link\" ? 1 : 0,\n paragraphs: role === \"p\" || role === \"text\" ? 1 : 0,\n tables: role === \"table\" || role === \"row\" || role === \"cell\" ? 1 : 0,\n formControls: role === \"textbox\" || role === \"searchbox\" || role === \"combobox\" || role === \"listbox\" || role === \"checkbox\" || role === \"radio\" || role === \"slider\" || role === \"spinbutton\" || role === \"switch\" ? 1 : 0,\n contentContainers: role === \"article\" || role === \"main\" ? 1 : 0,\n };\n for (const child of node.children) {\n const childStats = semanticRoleStats(child);\n stats.links += childStats.links;\n stats.paragraphs += childStats.paragraphs;\n stats.tables += childStats.tables;\n stats.formControls += childStats.formControls;\n stats.contentContainers += childStats.contentContainers;\n }\n return stats;\n}\n\nfunction shouldSummarizeRepeatedChild(\n parent: Element,\n child: SemanticNode,\n signatures: Map<string, number>,\n context: StaticContext,\n): boolean {\n if (!context.options.summarizeRepeatedSubtrees || context.options.mode === \"full\") return false;\n if (!isRepeatedSubtreeCandidate(parent)) return false;\n const signature = semanticSignature(child);\n const count = signatures.get(signature) ?? 0;\n signatures.set(signature, count + 1);\n return count >= context.options.maxRepeatedSubtreeInstances;\n}\n\nfunction isRepeatedSubtreeCandidate(element: Element): boolean {\n return [\"body\", \"main\", \"nav\", \"ul\", \"ol\", \"div\", \"section\", \"footer\", \"header\", \"aside\"].includes(element.name);\n}\n\nfunction semanticSignature(node: SemanticNode): string {\n const childSignatures = node.children.map(semanticSignature).join(\",\");\n return `${node.tag}|${node.role ?? \"\"}|${node.name}|${node.text ?? \"\"}|${node.value ?? \"\"}|${node.interactive ? \"i\" : \"\"}[${childSignatures}]`;\n}\n\nfunction countSemanticNodes(node: SemanticNode): number {\n let count = 1;\n for (const child of node.children) count += countSemanticNodes(child);\n return count;\n}\n\nfunction shouldSkipChildrenForCollapsedElement(element: Element, context: StaticContext): boolean {\n if (!context.options.pruneCollapsedSubtrees || context.options.includeHidden) return false;\n if (attr(element, \"aria-expanded\") === \"false\") return true;\n if (element.name === \"details\" && attr(element, \"open\") === null) return true;\n if (element.name === \"dialog\" && attr(element, \"open\") === null) return true;\n if (attr(element, \"popover\") !== null && attr(element, \"open\") === null) return true;\n return false;\n}\n\nfunction isCollapsedControlledElement(element: Element, context: StaticContext): boolean {\n const id = attr(element, \"id\");\n return Boolean(id && context.options.pruneCollapsedSubtrees && context.collapsedControlledIds.has(id));\n}\n\nfunction isLikelyClosedOverlay(element: Element, context: StaticContext): boolean {\n if (!context.options.pruneLikelyClosedOverlays || context.options.mode === \"full\") return false;\n if (hasUsefulOpenSignal(element)) return false;\n if (!hasOverlaySignal(element)) return false;\n if (hasDirectFocusableIntent(element)) return false;\n return hasOffscreenOrClosedStyle(element) || hasClosedClassSignal(element) || hasInertSignal(element);\n}\n\nfunction hasUsefulOpenSignal(element: Element): boolean {\n return attr(element, \"open\") !== null\n || attr(element, \"aria-expanded\") === \"true\"\n || attr(element, \"aria-modal\") === \"true\"\n || attr(element, \"data-open\") === \"true\"\n || attr(element, \"data-state\") === \"open\";\n}\n\nfunction hasOverlaySignal(element: Element): boolean {\n const value = [element.name, attr(element, \"id\"), attr(element, \"class\"), attr(element, \"role\"), attr(element, \"aria-label\")]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase();\n return /\\b(drawer|modal|dialog|popover|overlay|hamburger|menu|sidebar|sheet|flyout|dropdown)\\b/.test(value);\n}\n\nfunction hasDirectFocusableIntent(element: Element): boolean {\n const tabindex = attr(element, \"tabindex\");\n return tabindex !== null && Number(tabindex) >= 0;\n}\n\nfunction hasInertSignal(element: Element): boolean {\n return attr(element, \"inert\") !== null || attr(element, \"aria-hidden\") === \"true\";\n}\n\nfunction hasClosedClassSignal(element: Element): boolean {\n const className = attr(element, \"class\") ?? \"\";\n return /\\b(closed|collapsed|hidden|inactive|is-closed|is-hidden)\\b/i.test(className);\n}\n\nfunction hasOffscreenOrClosedStyle(element: Element): boolean {\n const style = attr(element, \"style\") ?? \"\";\n if (!style) return false;\n const normalized = style.replace(/\\s+/g, \"\").toLowerCase();\n return /(?:^|;)(?:left|right|top|bottom):-\\d{2,}(?:px|rem|em|vw|vh|%)/.test(normalized)\n || /(?:^|;)transform:translate[xy]?\\(-[1-9]\\d*%/.test(normalized)\n || /(?:^|;)(?:max-height|height):0(?:px|rem|em|%)?/.test(normalized)\n || /(?:^|;)pointer-events:none/.test(normalized);\n}\n\nfunction shouldPrune(\n element: Element,\n role: string | null,\n name: string,\n interactive: boolean,\n children: SemanticNode[],\n context: StaticContext,\n): boolean {\n if (context.options.mode === \"full\") return false;\n if (role === \"none\" || role === \"presentation\") return true;\n if (interactive) return false;\n if (role && role !== \"generic\") return false;\n if (name) return false;\n if (children.length === 0) return true;\n if (attr(element, \"id\") || attr(element, \"aria-label\") || attr(element, \"aria-labelledby\")) return false;\n return children.length > 0;\n}\n\nfunction shouldPruneListItemWrapper(role: string | null, children: SemanticNode[], context: StaticContext): boolean {\n if (context.options.mode === \"full\") return false;\n if (role !== \"listitem\") return false;\n return children.some((child) => child.role === \"link\" || child.role === \"button\");\n}\n\nfunction getRole(element: Element): string | null {\n const explicit = firstToken(attr(element, \"role\"));\n if (explicit) return explicit;\n const tag = element.name;\n if (tag === \"section\" && !hasExplicitNameSource(element)) return null;\n if (tag === \"form\" && !hasExplicitNameSource(element)) return null;\n if (tag in landmarkTags) return landmarkTags[tag] ?? null;\n if (/^h[1-6]$/.test(tag)) return \"heading\";\n if (tag === \"a\" || tag === \"area\") return attr(element, \"href\") ? \"link\" : null;\n if (tag === \"button\") return \"button\";\n if (tag === \"details\" || tag === \"fieldset\") return \"group\";\n if (tag === \"dialog\") return \"dialog\";\n if (tag === \"figure\") return \"figure\";\n if (tag === \"form\") return \"form\";\n if (tag === \"img\") return \"img\";\n if (tag === \"input\") return inputRole(element);\n if (tag === \"li\") return \"listitem\";\n if (tag === \"ol\" || tag === \"ul\") return \"list\";\n if (tag === \"option\") return \"option\";\n if (tag === \"p\") return \"p\";\n if (tag === \"progress\") return \"progressbar\";\n if (tag === \"select\") return attr(element, \"multiple\") !== null ? \"listbox\" : \"combobox\";\n if (tag === \"summary\") return \"button\";\n if (tag === \"table\") return \"table\";\n if (tag === \"td\") return \"cell\";\n if (tag === \"textarea\") return \"textbox\";\n if (tag === \"th\") return attr(element, \"scope\") === \"row\" ? \"rowheader\" : \"columnheader\";\n if (tag === \"tr\") return \"row\";\n return null;\n}\n\nfunction inputRole(element: Element): string | null {\n const type = (attr(element, \"type\") ?? \"text\").toLowerCase();\n if (type === \"hidden\") return null;\n if (type === \"button\" || type === \"submit\" || type === \"reset\") return \"button\";\n if (type === \"checkbox\") return \"checkbox\";\n if (type === \"image\") return \"button\";\n if (type === \"radio\") return \"radio\";\n if (type === \"range\") return \"slider\";\n if (type === \"search\") return \"searchbox\";\n if (type === \"number\") return \"spinbutton\";\n return \"textbox\";\n}\n\nfunction computeName(element: Element, role: string, context: StaticContext): string {\n const labelledBy = attr(element, \"aria-labelledby\");\n if (labelledBy) {\n const value = labelledBy\n .split(/\\s+/)\n .map((id) => context.ids.get(id))\n .filter((item): item is Element => Boolean(item))\n .map((item) => descendantText(item))\n .join(\" \");\n const normalized = normalizeText(value, context.options.maxTextLength);\n if (normalized) return normalized;\n }\n\n const ariaLabel = normalizeText(attr(element, \"aria-label\") ?? \"\", context.options.maxTextLength);\n if (ariaLabel) return ariaLabel;\n\n const labelled = labelName(element, context);\n if (labelled) return labelled;\n\n const valueName = elementValueName(element);\n if (valueName) return normalizeText(valueName, context.options.maxTextLength);\n\n if (role === \"img\") {\n const alt = normalizeText(attr(element, \"alt\") ?? \"\", context.options.maxTextLength);\n if (alt) return alt;\n }\n\n if (rolesNamedFromContents.has(role)) {\n const contents = normalizeText(descendantText(element), context.options.maxTextLength);\n if (contents) return contents;\n }\n\n const title = normalizeText(attr(element, \"title\") ?? \"\", context.options.maxTextLength);\n if (title) return title;\n\n return \"\";\n}\n\nfunction labelName(element: Element, context: StaticContext): string {\n const id = attr(element, \"id\");\n if (id) {\n const value = context.labelsByFor.get(id);\n if (value) return value;\n }\n const label = findClosestLabel(element);\n return label ? normalizeText(descendantText(label), context.options.maxTextLength) : \"\";\n}\n\nfunction findClosestLabel(element: Element): Element | null {\n let parent = element.parent;\n while (parent) {\n if (isElement(parent) && parent.name === \"label\") return parent;\n parent = parent.parent;\n }\n return null;\n}\n\nfunction elementValueName(element: Element): string {\n if (element.name === \"input\") {\n const type = (attr(element, \"type\") ?? \"text\").toLowerCase();\n if (type === \"button\" || type === \"submit\" || type === \"reset\") return attr(element, \"value\") ?? \"\";\n }\n return \"\";\n}\n\nfunction getState(element: Element): SemanticNodeState {\n const state: SemanticNodeState = {};\n if (attr(element, \"disabled\") !== null || attr(element, \"aria-disabled\") === \"true\") state.disabled = true;\n if (attr(element, \"required\") !== null || attr(element, \"aria-required\") === \"true\") state.required = true;\n if (attr(element, \"readonly\") !== null || attr(element, \"aria-readonly\") === \"true\") state.readonly = true;\n const checked = attr(element, \"aria-checked\") ?? (attr(element, \"checked\") !== null ? \"true\" : null);\n if (checked === \"true\") state.checked = true;\n if (checked === \"false\") state.checked = false;\n if (checked === \"mixed\") state.checked = \"mixed\";\n if (attr(element, \"selected\") !== null || attr(element, \"aria-selected\") === \"true\") state.selected = true;\n const expanded = attr(element, \"aria-expanded\");\n if (expanded === \"true\") state.expanded = true;\n if (expanded === \"false\") state.expanded = false;\n const pressed = attr(element, \"aria-pressed\");\n if (pressed === \"true\") state.pressed = true;\n if (pressed === \"false\") state.pressed = false;\n if (pressed === \"mixed\") state.pressed = \"mixed\";\n const invalid = attr(element, \"aria-invalid\");\n if (invalid && invalid !== \"false\") state.invalid = invalid === \"true\" ? true : invalid;\n return state;\n}\n\nfunction isInteractive(element: Element, role: string | null, focusable: boolean): boolean {\n if (role && interactiveRoles.has(role)) return true;\n if (focusable) return true;\n return [\"button\", \"input\", \"select\", \"textarea\"].includes(element.name);\n}\n\nfunction isFocusable(element: Element, role: string | null): boolean {\n if (attr(element, \"disabled\") !== null) return false;\n const tabindex = attr(element, \"tabindex\");\n if (tabindex !== null && Number(tabindex) >= 0) return true;\n if (role && interactiveRoles.has(role)) return true;\n return element.name === \"a\" && attr(element, \"href\") !== null;\n}\n\nfunction isHidden(element: Element): boolean {\n if (attr(element, \"hidden\") !== null) return true;\n if (attr(element, \"aria-hidden\") === \"true\") return true;\n const style = attr(element, \"style\");\n return style ? hiddenStylePattern.test(style) : false;\n}\n\nfunction isLikelyAd(element: Element): boolean {\n const value = [\n attr(element, \"id\"),\n attr(element, \"class\"),\n attr(element, \"aria-label\"),\n attr(element, \"title\"),\n attr(element, \"data-testid\"),\n ].filter(Boolean).join(\" \").toLowerCase();\n return /\\b(ad|ads|advert|advertisement|banner|sponsor|sponsored|promotion|promoted|powerlink)\\b/.test(value)\n || /파워링크|광고|직접홍보|홍보/.test(value);\n}\n\nfunction isLikelyBoilerplate(element: Element): boolean {\n if (element.name === \"footer\") return true;\n if (element.name === \"main\" || element.name === \"article\") return false;\n const role = firstToken(attr(element, \"role\"));\n if (role === \"main\" || role === \"article\") return false;\n const value = [\n attr(element, \"id\"),\n attr(element, \"class\"),\n attr(element, \"aria-label\"),\n attr(element, \"title\"),\n ].filter(Boolean).join(\" \").toLowerCase();\n if (!value) return false;\n if (/\\b(content|contents|entry|post-body|article-body|story-body|view-content)\\b/.test(value)) return false;\n return /\\b(footer|sidebar)\\b/.test(value) || /푸터/.test(value);\n}\n\nfunction isLikelyBoilerplateTable(element: Element): boolean {\n if (element.name !== \"table\") return false;\n const value = [\n attr(element, \"id\"),\n attr(element, \"class\"),\n attr(element, \"aria-label\"),\n attr(element, \"title\"),\n ].filter(Boolean).join(\" \").toLowerCase();\n return /\\bgall[_-]?list\\b/.test(value) || /\\bbottom[_-]?list\\w*\\b/.test(value);\n}\n\nfunction flattenBoilerplateTable(element: Element, context: StaticContext): SemanticNode | null {\n const children = collectFlattenedBoilerplateItems(element, context);\n if (children.length === 0) return null;\n return containerNode(context, element.name, children);\n}\n\nfunction collectFlattenedBoilerplateItems(element: Element, context: StaticContext): SemanticNode[] {\n const children: SemanticNode[] = [];\n for (const child of element.children) {\n if (!isElement(child)) continue;\n if (shouldSkipElement(child, context)) continue;\n if (!context.options.includeHidden && isHidden(child)) continue;\n if (context.options.excludeLikelyAds && isLikelyAd(child)) continue;\n const role = getRole(child);\n const focusable = isFocusable(child, role);\n const interactive = isInteractive(child, role, focusable);\n const name = role ? computeName(child, role, context) : \"\";\n if (role && name && (interactive || role === \"heading\" || role === \"img\")) {\n const node: SemanticNode = {\n id: nextId(context),\n tag: child.name,\n role,\n name,\n interactive,\n focusable,\n selector: getSelector(child),\n xpath: getXPath(child),\n children: [],\n };\n const value = getValue(child);\n if (value) node.value = value;\n const state = getState(child);\n if (Object.keys(state).length > 0) node.state = state;\n if (context.options.includeAttributes) node.attributes = { ...child.attribs };\n children.push(node);\n continue;\n }\n children.push(...collectFlattenedBoilerplateItems(child, context));\n }\n return children;\n}\n\nfunction hasExplicitNameSource(element: Element): boolean {\n return attr(element, \"aria-label\") !== null || attr(element, \"aria-labelledby\") !== null || attr(element, \"title\") !== null;\n}\n\nfunction directText(element: Element, maxLength: number): string {\n return normalizeText(\n element.children\n .filter(isText)\n .map((node) => node.data)\n .join(\" \"),\n maxLength,\n );\n}\n\nfunction descendantText(element: Element): string {\n const parts: string[] = [];\n collectDescendantText(element.children, parts);\n return parts.join(\" \");\n}\n\nfunction collectDescendantText(nodes: AnyNode[], parts: string[]): void {\n for (const node of nodes) {\n if (isText(node)) {\n parts.push(node.data);\n continue;\n }\n if (!isElement(node)) continue;\n if (nonSemanticTags.has(node.name) || node.name === \"noscript\") continue;\n collectDescendantText(node.children, parts);\n }\n}\n\nfunction normalizeText(value: string, maxLength: number): string {\n const normalized = value.replace(/\\s+/g, \" \").trim();\n return normalized.length > maxLength ? `${normalized.slice(0, maxLength - 1)}...` : normalized;\n}\n\nfunction getValue(element: Element): string {\n return normalizeText(attr(element, \"value\") ?? \"\", 240);\n}\n\nfunction getSelector(element: Element): string {\n const id = attr(element, \"id\");\n if (id) return `#${cssEscape(id)}`;\n const parent = element.parent;\n if (!parent || !(\"children\" in parent)) return element.name;\n const siblings = parent.children.filter((node): node is Element => isElement(node) && node.name === element.name);\n const index = siblings.indexOf(element);\n return index > 0 ? `${element.name}:nth-of-type(${index + 1})` : element.name;\n}\n\nfunction getXPath(element: Element): string {\n const parts: string[] = [];\n let current: Element | null = element;\n while (current) {\n const parent: AnyNode | null = current.parent;\n if (!parent || !(\"children\" in parent)) {\n parts.unshift(current.name);\n break;\n }\n const siblings = parent.children.filter((node): node is Element => isElement(node) && node.name === current?.name);\n const index = siblings.indexOf(current) + 1;\n parts.unshift(`${current.name}[${index}]`);\n current = isElement(parent) ? parent : null;\n }\n return `/${parts.join(\"/\")}`;\n}\n\nfunction containerNode(context: StaticContext, tag: string, children: SemanticNode[]): SemanticNode {\n return {\n id: nextId(context),\n tag,\n role: null,\n name: \"\",\n interactive: false,\n focusable: false,\n children,\n };\n}\n\nfunction unavailableNode(context: StaticContext, tag: string, unavailableReason: string): SemanticNode {\n return {\n id: nextId(context),\n tag,\n role: null,\n name: \"\",\n interactive: false,\n focusable: false,\n children: [],\n unavailableReason,\n };\n}\n\nfunction omittedNode(context: StaticContext, omitted: number): SemanticNode {\n return {\n id: nextId(context),\n tag: \"omitted\",\n role: \"note\",\n name: `${omitted} static nodes omitted`,\n interactive: false,\n focusable: false,\n children: [],\n };\n}\n\nfunction nextId(context: StaticContext): string {\n return `static-${context.nextId++}`;\n}\n\nfunction attr(element: Element, name: string): string | null {\n return Object.prototype.hasOwnProperty.call(element.attribs, name) ? element.attribs[name] ?? \"\" : null;\n}\n\nfunction firstToken(value: string | null): string | null {\n return value?.trim().split(/\\s+/)[0] || null;\n}\n\nfunction cssEscape(value: string): string {\n return value.replace(/[^a-zA-Z0-9_-]/g, (char) => `\\\\${char}`);\n}\n\nfunction isElement(node: AnyNode): node is Element {\n return node.type === \"tag\" || node.type === \"script\" || node.type === \"style\";\n}\n\nfunction isText(node: AnyNode): node is Text {\n return node.type === \"text\";\n}\n\nfunction findElement(nodes: AnyNode[], name: string): Element | undefined {\n for (const node of nodes) {\n if (!isElement(node)) continue;\n if (node.name === name) return node;\n const child = findElement(node.children, name);\n if (child) return child;\n }\n return undefined;\n}\n\nfunction fragmentRoot(children: AnyNode[]): Element {\n return new DomElement(\"fragment\", {}, children);\n}\n"],"mappings":"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","names":[]}
|