webforai 3.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/README.md +47 -5
  2. package/dist/bin.js +3109 -490
  3. package/dist/cjs/detect-client-shell.js +78 -0
  4. package/dist/cjs/extract-mdast.js +58 -0
  5. package/dist/cjs/extract-meta-refresh.js +71 -0
  6. package/dist/cjs/extractors/index.js +5 -0
  7. package/dist/cjs/extractors/lib/block-features.js +465 -0
  8. package/dist/cjs/extractors/lib/block-model.generated.js +45 -0
  9. package/dist/cjs/extractors/lib/block-model.js +72 -0
  10. package/dist/cjs/extractors/lib/blocks.js +212 -0
  11. package/dist/cjs/extractors/lib/code-tabs.js +191 -0
  12. package/dist/cjs/extractors/lib/constants.js +1 -1
  13. package/dist/cjs/extractors/lib/layout-tables.js +123 -0
  14. package/dist/cjs/extractors/lib/sanitize.js +146 -26
  15. package/dist/cjs/extractors/lib/takumi-signal.js +76 -0
  16. package/dist/cjs/extractors/lib/ui-chrome.js +7 -0
  17. package/dist/cjs/extractors/presets/auto.js +3 -3
  18. package/dist/cjs/extractors/presets/kiwame.js +231 -0
  19. package/dist/cjs/extractors/presets/takumi.js +34 -3
  20. package/dist/cjs/html-to-markdown.js +58 -4
  21. package/dist/cjs/html-to-mdast.js +4 -3
  22. package/dist/cjs/index.js +16 -0
  23. package/dist/cjs/link-replacer.js +19 -13
  24. package/dist/cjs/loaders/cf-puppeteer.js +14 -7
  25. package/dist/cjs/loaders/fetch.js +14 -2
  26. package/dist/cjs/loaders/playwright.js +32 -30
  27. package/dist/cjs/loaders/puppeteer.js +14 -7
  28. package/dist/cjs/md-splitter.js +24 -11
  29. package/dist/cjs/mdast-handlers/custom-code-handler.js +32 -9
  30. package/dist/cjs/mdast-handlers/custom-div-handler.js +14 -35
  31. package/dist/cjs/mdast-handlers/custom-img-handler.js +10 -1
  32. package/dist/cjs/mdast-handlers/custom-table-handler.js +18 -1
  33. package/dist/cjs/mdast-handlers/definition-list-handler.js +17 -6
  34. package/dist/cjs/mdast-handlers/table-cell-flatten.js +195 -0
  35. package/dist/cjs/mdast-handlers/twoslash.js +71 -0
  36. package/dist/cjs/mdast-to-markdown.js +2 -5
  37. package/dist/cjs/metadata/index.js +4 -3
  38. package/dist/cjs/normalize/index.js +11 -2
  39. package/dist/cjs/platform/client.js +73 -16
  40. package/dist/cjs/platform/index.js +4 -0
  41. package/dist/cjs/platform/types.js +7 -1
  42. package/dist/cjs/utils/hast-fast.js +1 -1
  43. package/dist/cjs/utils/parse-html.js +113 -0
  44. package/dist/cjs/utils/pre-text.js +104 -0
  45. package/dist/detect-client-shell.js +53 -0
  46. package/dist/extract-mdast.js +58 -0
  47. package/dist/extract-meta-refresh.js +47 -0
  48. package/dist/extractors/index.js +3 -0
  49. package/dist/extractors/lib/block-features.js +437 -0
  50. package/dist/extractors/lib/block-model.generated.js +21 -0
  51. package/dist/extractors/lib/block-model.js +48 -0
  52. package/dist/extractors/lib/blocks.js +185 -0
  53. package/dist/extractors/lib/code-tabs.js +168 -0
  54. package/dist/extractors/lib/constants.js +1 -1
  55. package/dist/extractors/lib/layout-tables.js +99 -0
  56. package/dist/extractors/lib/sanitize.js +144 -26
  57. package/dist/extractors/lib/takumi-signal.js +53 -0
  58. package/dist/extractors/lib/ui-chrome.js +5 -0
  59. package/dist/extractors/presets/auto.js +3 -3
  60. package/dist/extractors/presets/kiwame.js +206 -0
  61. package/dist/extractors/presets/takumi.js +34 -3
  62. package/dist/html-to-markdown.js +57 -4
  63. package/dist/html-to-mdast.js +4 -3
  64. package/dist/index.js +18 -0
  65. package/dist/link-replacer.js +19 -13
  66. package/dist/loaders/cf-puppeteer.js +15 -8
  67. package/dist/loaders/fetch.js +14 -2
  68. package/dist/loaders/playwright.js +32 -30
  69. package/dist/loaders/puppeteer.js +15 -8
  70. package/dist/md-splitter.js +24 -11
  71. package/dist/mdast-handlers/custom-code-handler.js +30 -9
  72. package/dist/mdast-handlers/custom-div-handler.js +14 -35
  73. package/dist/mdast-handlers/custom-img-handler.js +10 -1
  74. package/dist/mdast-handlers/custom-table-handler.js +19 -2
  75. package/dist/mdast-handlers/definition-list-handler.js +17 -6
  76. package/dist/mdast-handlers/table-cell-flatten.js +170 -0
  77. package/dist/mdast-handlers/twoslash.js +48 -0
  78. package/dist/mdast-to-markdown.js +2 -5
  79. package/dist/metadata/index.js +4 -3
  80. package/dist/normalize/index.js +12 -2
  81. package/dist/platform/client.js +73 -16
  82. package/dist/platform/index.js +4 -0
  83. package/dist/platform/types.js +5 -1
  84. package/dist/types/cli/bin.js.map +1 -1
  85. package/dist/types/cli/commands/jobs/files.d.ts +28 -0
  86. package/dist/types/cli/commands/jobs/files.js.map +1 -0
  87. package/dist/types/cli/commands/jobs/llms-txt.d.ts +33 -0
  88. package/dist/types/cli/commands/jobs/llms-txt.js.map +1 -0
  89. package/dist/types/cli/commands/jobs/options.d.ts +58 -0
  90. package/dist/types/cli/commands/jobs/options.js.map +1 -0
  91. package/dist/types/cli/commands/jobs/run.d.ts +44 -0
  92. package/dist/types/cli/commands/jobs/run.js.map +1 -0
  93. package/dist/types/cli/commands/skill/content.js.map +1 -1
  94. package/dist/types/cli/commands/webforai/interactive.d.ts +1 -1
  95. package/dist/types/cli/commands/webforai/interactive.js.map +1 -1
  96. package/dist/types/cli/commands/webforai/options.d.ts +9 -2
  97. package/dist/types/cli/commands/webforai/options.js.map +1 -1
  98. package/dist/types/cli/commands/webforai/run.js.map +1 -1
  99. package/dist/types/cli/constants.d.ts +3 -1
  100. package/dist/types/cli/constants.js.map +1 -1
  101. package/dist/types/cli/utils.d.ts +8 -1
  102. package/dist/types/cli/utils.js.map +1 -1
  103. package/dist/types/detect-client-shell.d.ts +24 -0
  104. package/dist/types/detect-client-shell.js.map +1 -0
  105. package/dist/types/extract-mdast.js.map +1 -1
  106. package/dist/types/extract-meta-refresh.d.ts +29 -0
  107. package/dist/types/extract-meta-refresh.js.map +1 -0
  108. package/dist/types/extractors/index.d.ts +1 -0
  109. package/dist/types/extractors/index.js.map +1 -1
  110. package/dist/types/extractors/lib/block-features.d.ts +43 -0
  111. package/dist/types/extractors/lib/block-features.js.map +1 -0
  112. package/dist/types/extractors/lib/block-model.d.ts +28 -0
  113. package/dist/types/extractors/lib/block-model.generated.d.ts +5 -0
  114. package/dist/types/extractors/lib/block-model.generated.js.map +1 -0
  115. package/dist/types/extractors/lib/block-model.js.map +1 -0
  116. package/dist/types/extractors/lib/blocks.d.ts +53 -0
  117. package/dist/types/extractors/lib/blocks.js.map +1 -0
  118. package/dist/types/extractors/lib/code-tabs.d.ts +30 -0
  119. package/dist/types/extractors/lib/code-tabs.js.map +1 -0
  120. package/dist/types/extractors/lib/constants.js.map +1 -1
  121. package/dist/types/extractors/lib/layout-tables.d.ts +17 -0
  122. package/dist/types/extractors/lib/layout-tables.js.map +1 -0
  123. package/dist/types/extractors/lib/sanitize.d.ts +33 -3
  124. package/dist/types/extractors/lib/sanitize.js.map +1 -1
  125. package/dist/types/extractors/lib/takumi-signal.d.ts +12 -0
  126. package/dist/types/extractors/lib/takumi-signal.js.map +1 -0
  127. package/dist/types/extractors/lib/ui-chrome.d.ts +8 -0
  128. package/dist/types/extractors/lib/ui-chrome.js.map +1 -1
  129. package/dist/types/extractors/presets/auto.d.ts +6 -1
  130. package/dist/types/extractors/presets/auto.js.map +1 -1
  131. package/dist/types/extractors/presets/kiwame.d.ts +31 -0
  132. package/dist/types/extractors/presets/kiwame.js.map +1 -0
  133. package/dist/types/extractors/presets/takumi.js.map +1 -1
  134. package/dist/types/html-to-markdown.d.ts +9 -0
  135. package/dist/types/html-to-markdown.js.map +1 -1
  136. package/dist/types/html-to-mdast.js.map +1 -1
  137. package/dist/types/index.d.ts +3 -1
  138. package/dist/types/index.js.map +1 -1
  139. package/dist/types/link-replacer.d.ts +3 -1
  140. package/dist/types/link-replacer.js.map +1 -1
  141. package/dist/types/loaders/cf-puppeteer.js.map +1 -1
  142. package/dist/types/loaders/fetch.d.ts +4 -0
  143. package/dist/types/loaders/fetch.js.map +1 -1
  144. package/dist/types/loaders/playwright.js.map +1 -1
  145. package/dist/types/loaders/puppeteer.js.map +1 -1
  146. package/dist/types/md-splitter.d.ts +1 -1
  147. package/dist/types/md-splitter.js.map +1 -1
  148. package/dist/types/mdast-handlers/custom-code-handler.d.ts +9 -0
  149. package/dist/types/mdast-handlers/custom-code-handler.js.map +1 -1
  150. package/dist/types/mdast-handlers/custom-div-handler.js.map +1 -1
  151. package/dist/types/mdast-handlers/custom-img-handler.js.map +1 -1
  152. package/dist/types/mdast-handlers/custom-table-handler.js.map +1 -1
  153. package/dist/types/mdast-handlers/definition-list-handler.d.ts +0 -11
  154. package/dist/types/mdast-handlers/definition-list-handler.js.map +1 -1
  155. package/dist/types/mdast-handlers/table-cell-flatten.d.ts +18 -0
  156. package/dist/types/mdast-handlers/table-cell-flatten.js.map +1 -0
  157. package/dist/types/mdast-handlers/twoslash.d.ts +14 -0
  158. package/dist/types/mdast-handlers/twoslash.js.map +1 -0
  159. package/dist/types/mdast-to-markdown.js.map +1 -1
  160. package/dist/types/metadata/index.js.map +1 -1
  161. package/dist/types/normalize/index.js.map +1 -1
  162. package/dist/types/platform/client.d.ts +2 -1
  163. package/dist/types/platform/client.js.map +1 -1
  164. package/dist/types/platform/error.d.ts +5 -3
  165. package/dist/types/platform/error.js.map +1 -1
  166. package/dist/types/platform/fetch.d.ts +2 -0
  167. package/dist/types/platform/fetch.js.map +1 -1
  168. package/dist/types/platform/index.d.ts +1 -1
  169. package/dist/types/platform/index.js.map +1 -1
  170. package/dist/types/platform/types.d.ts +35 -6
  171. package/dist/types/platform/types.js.map +1 -1
  172. package/dist/types/utils/hast-fast.d.ts +1 -1
  173. package/dist/types/utils/hast-fast.js.map +1 -1
  174. package/dist/types/utils/parse-html.d.ts +33 -0
  175. package/dist/types/utils/parse-html.js.map +1 -0
  176. package/dist/types/utils/pre-text.d.ts +12 -0
  177. package/dist/types/utils/pre-text.js.map +1 -0
  178. package/dist/utils/hast-fast.js +1 -1
  179. package/dist/utils/parse-html.js +87 -0
  180. package/dist/utils/pre-text.js +81 -0
  181. package/package.json +18 -5
package/dist/bin.js CHANGED
@@ -6,24 +6,35 @@ import { CommanderError, program } from "commander";
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "webforai",
9
- version: "3.0.0",
10
- description: "A library that provides a web interface for AI",
9
+ version: "4.1.0",
10
+ description: "Convert web pages and local HTML to clean, LLM-ready Markdown: library, CLI (npx webforai) and hosted-API client.",
11
11
  author: "inaridiy",
12
12
  license: "Apache-2.0",
13
13
  keywords: [
14
- "web",
14
+ "html-to-markdown",
15
+ "markdown",
16
+ "llm",
15
17
  "ai",
18
+ "scraper",
19
+ "crawler",
20
+ "readability",
21
+ "web-scraping",
22
+ "cli",
23
+ "rag",
16
24
  "html",
17
25
  "html2md",
18
- "markdown",
19
26
  "mdast",
20
27
  "hast"
21
28
  ],
22
29
  repository: {
23
30
  type: "git",
24
- url: "https://github.com/inaridiy/webforai.git"
31
+ url: "https://github.com/inaridiy/webforai.git",
32
+ directory: "packages/webforai"
25
33
  },
26
34
  homepage: "https://webforai.dev/",
35
+ bugs: {
36
+ url: "https://github.com/inaridiy/webforai/issues"
37
+ },
27
38
  scripts: {
28
39
  "copy:package.cjs.json": "pnpm ncp ./package.cjs.json ./dist/cjs/package.json && pnpm ncp ./package.cjs.json ./dist/types/package.json ",
29
40
  clean: "rimraf dist",
@@ -121,6 +132,7 @@ var package_default = {
121
132
  boxen: "^8.0.1",
122
133
  commander: "^12.1.0",
123
134
  "hast-util-from-html": "^2.0.3",
135
+ "hast-util-from-parse5": "^8.0.1",
124
136
  "hast-util-select": "^6.0.2",
125
137
  "hast-util-to-html": "^9.0.3",
126
138
  "hast-util-to-mdast": "^10.1.0",
@@ -130,6 +142,7 @@ var package_default = {
130
142
  "mdast-util-gfm": "^3.0.0",
131
143
  "mdast-util-math": "^3.0.0",
132
144
  "mdast-util-to-markdown": "^2.1.0",
145
+ parse5: "^7.1.2",
133
146
  picocolors: "^1.0.1",
134
147
  "trim-trailing-lines": "^2.1.0",
135
148
  "unist-util-filter": "^5.0.1"
@@ -154,163 +167,6 @@ var package_default = {
154
167
  }
155
168
  };
156
169
 
157
- // src/cli/commands/skill/index.ts
158
- import { spawn } from "node:child_process";
159
- import fs from "node:fs/promises";
160
- import os from "node:os";
161
- import path from "node:path";
162
-
163
- // src/cli/commands/skill/content.ts
164
- var renderSkillMarkdown = (version) => `---
165
- name: webforai
166
- description: Convert web pages or local HTML files to clean, LLM-ready Markdown with the webforai CLI. Use when a task needs page content as Markdown - reading documentation or articles, scraping, summarising URLs, building text corpora - including JavaScript-heavy or bot-protected pages via the hosted platform.
167
- ---
168
-
169
- # webforai CLI${version ? ` (v${version})` : ""}
170
-
171
- Convert a URL or local HTML file to Markdown. Non-interactive by default: the Markdown goes
172
- to stdout, every log goes to stderr, so output can be piped or captured directly.
173
-
174
- ## Basic usage
175
-
176
- \`\`\`bash
177
- npx webforai https://example.com/article # Markdown to stdout
178
- npx webforai https://example.com/article -o out.md # write to a file instead
179
- npx webforai ./page.html # convert a local HTML file
180
- npx webforai https://example.com --json # machine-readable envelope (see below)
181
- \`\`\`
182
-
183
- ## Flags
184
-
185
- - \`-o, --output <path>\` \u2014 write Markdown to a file instead of stdout.
186
- - \`-l, --loader <fetch|playwright|platform>\` \u2014 how HTML is acquired. Default: \`fetch\` for
187
- URLs, automatic \`local\` for file paths. \`playwright\` renders JavaScript locally (needs
188
- \`npx playwright install chromium\`). \`platform\` uses the hosted API (below).
189
- - \`-m, --mode <default|ai>\` \u2014 \`ai\` strips links/tables/images down to plain text
190
- (local conversion only).
191
- - \`--extractor <auto|takumi|minimal|none>\` \u2014 main-content extraction preset
192
- (\`none\` converts the whole page).
193
- - \`--frontmatter\` \u2014 prepend YAML front matter (title, author, canonical URL, ...).
194
- - \`--json\` \u2014 print a JSON envelope to stdout instead of raw Markdown.
195
- - \`--engine <fetch|browser|proxy-fetch|proxy-browser>\` \u2014 platform acquisition engine
196
- (implies \`-l platform\`). \`browser\`/\`proxy-browser\` render JavaScript; \`proxy-*\` engines
197
- egress through rotating proxies for bot-protected sites.
198
- - \`--region <auto|us|eu|uk|jp|asia>\` \u2014 platform proxy egress region (implies \`-l platform\`).
199
- - \`--screenshot\` \u2014 platform browser engines only; the envelope carries an expiring
200
- \`screenshotUrl\`.
201
- - \`--api-key <key>\` / \`--platform-url <url>\` \u2014 platform credentials and host; usually set
202
- via env vars instead.
203
- - \`-i, --interactive\` \u2014 guided prompt flow (for humans; do not use from an agent).
204
- - \`-d, --debug\` \u2014 verbose logs on stderr.
205
-
206
- ## JSON envelope (\`--json\`)
207
-
208
- \`\`\`json
209
- {
210
- "source": "https://example.com",
211
- "loader": "fetch",
212
- "url": "https://example.com",
213
- "markdown": "# ...",
214
- "metadata": { "title": "..." },
215
- "engine": "browser",
216
- "region": "auto",
217
- "credits": 5,
218
- "screenshotUrl": "https://...",
219
- "output": "out.md"
220
- }
221
- \`\`\`
222
-
223
- \`engine\`/\`region\`/\`credits\`/\`screenshotUrl\` appear only for the platform loader; \`output\`
224
- only when \`-o\` also wrote a file.
225
-
226
- ## Hosted platform
227
-
228
- For JavaScript-heavy or bot-protected pages, the hosted platform fetches server-side:
229
-
230
- \`\`\`bash
231
- export WEBFORAI_API_KEY=wfa_... # from https://platform.webforai.dev/dashboard
232
- npx webforai https://example.com --engine browser --json
233
- \`\`\`
234
-
235
- \`WEBFORAI_PLATFORM_URL\` overrides the host for self-hosted deployments. Requests are metered
236
- in credits (fetch 1, proxy-fetch 2, browser/proxy-browser 5); failures are never billed.
237
-
238
- ## Exit codes
239
-
240
- - \`0\` \u2014 success.
241
- - \`1\` \u2014 runtime failure (network, conversion, platform error; message on stderr).
242
- - \`2\` \u2014 usage error (unknown flag or invalid value; message on stderr).
243
-
244
- ## Errors worth handling
245
-
246
- - \`payment_required\` on stderr \u2192 platform credits exhausted.
247
- - \`rate_limited\` \u2192 back off (a \`retryAfter\` seconds hint is included when known).
248
- - Playwright loader errors explain the exact \`npx playwright install\` command to run.
249
- `;
250
-
251
- // src/cli/commands/skill/index.ts
252
- var buildSkillsAddArgs = (source, flags) => {
253
- const args = ["-y", "skills", "add", source];
254
- if (flags.global) {
255
- args.push("--global");
256
- }
257
- if (flags.agent) {
258
- args.push("--agent", flags.agent);
259
- }
260
- if (flags.yes) {
261
- args.push("-y");
262
- }
263
- if (flags.copy) {
264
- args.push("--copy");
265
- }
266
- if (flags.all) {
267
- args.push("--all");
268
- }
269
- return args;
270
- };
271
- var runSkillsAdd = (args) => new Promise((resolve, reject) => {
272
- const child = spawn("npx", args, { stdio: ["inherit", "inherit", "inherit"] });
273
- child.on("error", reject);
274
- child.on("close", (code) => resolve(code ?? 1));
275
- });
276
- var skillCommand = async (flags) => {
277
- const markdown = renderSkillMarkdown(package_default.version);
278
- if (!(flags.install || flags.dir)) {
279
- process.stdout.write(markdown);
280
- return;
281
- }
282
- if (flags.dir) {
283
- const target = path.join(flags.dir, "webforai", "SKILL.md");
284
- await fs.mkdir(path.dirname(target), { recursive: true });
285
- await fs.writeFile(target, markdown);
286
- console.error(`[webforai] Agent Skill written to ${target}`);
287
- return;
288
- }
289
- const stage = await fs.mkdtemp(path.join(os.tmpdir(), "webforai-skill-"));
290
- try {
291
- await fs.mkdir(path.join(stage, "webforai"), { recursive: true });
292
- await fs.writeFile(path.join(stage, "webforai", "SKILL.md"), markdown);
293
- const args = buildSkillsAddArgs(stage, flags);
294
- console.error(`[webforai] running: npx ${args.join(" ")}`);
295
- const code = await runSkillsAdd(args).catch((error) => {
296
- console.error(
297
- `[webforai] could not launch the skills CLI (${error instanceof Error ? error.message : String(error)}).`
298
- );
299
- console.error("[webforai] fallback: `webforai skill --dir .claude/skills` writes the file directly.");
300
- return 1;
301
- });
302
- if (code !== 0) {
303
- process.exitCode = 1;
304
- }
305
- } finally {
306
- await fs.rm(stage, { recursive: true, force: true });
307
- }
308
- };
309
-
310
- // src/cli/commands/webforai/interactive.ts
311
- import { intro, log, outro, select as select7, spinner, text as text5 } from "@clack/prompts";
312
- import pc2 from "picocolors";
313
-
314
170
  // src/platform/error.ts
315
171
  var PlatformApiError = class extends Error {
316
172
  constructor(code, message, status, retryAfter) {
@@ -336,7 +192,9 @@ var resolveFetch = (custom) => {
336
192
 
337
193
  // src/platform/types.ts
338
194
  var ENGINES = ["fetch", "browser", "proxy-fetch", "proxy-browser"];
339
- var REGIONS = ["auto", "us", "eu", "uk", "jp", "asia"];
195
+ var REQUESTED_ENGINES = [...ENGINES, "auto"];
196
+ var REGIONS = ["auto", "jp"];
197
+ var CRAWL_SITEMAP_MODES = ["skip", "include", "only"];
340
198
  var isStoredPageStub = (item) => item.status === "ok" && "resultUrl" in item;
341
199
 
342
200
  // src/platform/client.ts
@@ -365,16 +223,30 @@ var parseRetryAfter = (body, response) => {
365
223
  const header = Number(response.headers.get("retry-after"));
366
224
  return Number.isFinite(header) && header > 0 ? header : void 0;
367
225
  };
368
- var toApiError = (response, body) => {
226
+ var dashboardHint = (status, dashboardUrl) => {
227
+ if (status === 401) {
228
+ return `create or check API keys at ${dashboardUrl}`;
229
+ }
230
+ if (status === 402) {
231
+ return `manage billing, credits and the spend cap at ${dashboardUrl}`;
232
+ }
233
+ return void 0;
234
+ };
235
+ var toApiError = (response, body, dashboardUrl) => {
369
236
  const envelope = body;
370
237
  const code = typeof envelope?.error?.code === "string" ? envelope.error.code : "invalid_response";
371
- const message = typeof envelope?.error?.message === "string" ? envelope.error.message : `unexpected response (HTTP ${response.status})`;
238
+ let message = typeof envelope?.error?.message === "string" ? envelope.error.message : `unexpected response (HTTP ${response.status})`;
239
+ const hint = code === "invalid_response" ? void 0 : dashboardHint(response.status, dashboardUrl);
240
+ if (hint && !message.includes("/dashboard")) {
241
+ message = `${message} (${hint})`;
242
+ }
372
243
  return new PlatformApiError(code, message, response.status, parseRetryAfter(body, response));
373
244
  };
374
245
  var createPlatformClient = (options = {}) => {
375
246
  const baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
247
+ const dashboardUrl = `${baseUrl}/dashboard`;
376
248
  const fetchImpl = resolveFetch(options.fetch);
377
- const request = async (path4, init) => {
249
+ const request = async (path6, init) => {
378
250
  const headers = { accept: "application/json" };
379
251
  if (init.body !== void 0) {
380
252
  headers["content-type"] = "application/json";
@@ -383,27 +255,28 @@ var createPlatformClient = (options = {}) => {
383
255
  if (!options.apiKey) {
384
256
  throw new PlatformApiError(
385
257
  "missing_api_key",
386
- "This endpoint needs an API key: pass `apiKey` to createPlatformClient (create one on the platform dashboard).",
258
+ `This endpoint needs an API key: pass \`apiKey\` to createPlatformClient (create one at ${dashboardUrl}; 1,000 free credits/month).`,
387
259
  0
388
260
  );
389
261
  }
390
262
  headers.authorization = `Bearer ${options.apiKey}`;
391
263
  }
392
- const response = await fetchImpl(`${baseUrl}${path4}`, {
264
+ const response = await fetchImpl(`${baseUrl}${path6}`, {
393
265
  method: init.method,
394
266
  headers,
395
- body: init.body === void 0 ? void 0 : JSON.stringify(init.body)
267
+ body: init.body === void 0 ? void 0 : JSON.stringify(init.body),
268
+ ...init.signal ? { signal: init.signal } : {}
396
269
  });
397
270
  const body = await response.json().catch(() => void 0);
398
271
  if (!response.ok) {
399
- throw toApiError(response, body);
272
+ throw toApiError(response, body, dashboardUrl);
400
273
  }
401
274
  if (body === void 0) {
402
275
  throw new PlatformApiError("invalid_response", "response body is not JSON", response.status);
403
276
  }
404
277
  return body;
405
278
  };
406
- const getJob = (jobId) => request(`/v1/jobs/${encodeURIComponent(jobId)}`, { method: "GET", auth: true });
279
+ const getJob = (jobId, signal) => request(`/v1/jobs/${encodeURIComponent(jobId)}`, { method: "GET", auth: true, signal });
407
280
  const getJobResults = (jobId, opts) => {
408
281
  const query = opts?.cursor ? `?cursor=${encodeURIComponent(opts.cursor)}` : "";
409
282
  return request(`/v1/jobs/${encodeURIComponent(jobId)}/results${query}`, { method: "GET", auth: true });
@@ -419,6 +292,17 @@ var createPlatformClient = (options = {}) => {
419
292
  }
420
293
  return await response.json();
421
294
  };
295
+ const getJobOrBackOff = async (jobId, signal, interval) => {
296
+ try {
297
+ return await getJob(jobId, signal);
298
+ } catch (error) {
299
+ if (!(error instanceof PlatformApiError && error.status === 429)) {
300
+ throw error;
301
+ }
302
+ await sleep(error.retryAfter !== void 0 ? error.retryAfter * 1e3 : interval, signal);
303
+ return void 0;
304
+ }
305
+ };
422
306
  return {
423
307
  scrape: (opts) => request("/v1/scrape", { method: "POST", body: opts, auth: true }),
424
308
  scrapeAsync: (opts) => request("/v1/scrape", { method: "POST", body: { ...opts, async: true }, auth: true }),
@@ -429,17 +313,48 @@ var createPlatformClient = (options = {}) => {
429
313
  waitForJob: async (jobId, opts = {}) => {
430
314
  const interval = opts.pollIntervalMs ?? 2e3;
431
315
  const timeout = opts.timeoutMs ?? 10 * 60 * 1e3;
432
- const startedAt = Date.now();
433
- for (; ; ) {
434
- const status = await getJob(jobId);
435
- opts.onStatus?.(status);
436
- if (TERMINAL_STATES.has(status.status)) {
437
- return status;
438
- }
439
- if (Date.now() - startedAt + interval > timeout) {
440
- throw new PlatformApiError("poll_timeout", `job ${jobId} still ${status.status} after ${timeout}ms`, 0);
316
+ if (!Number.isFinite(interval) || interval < 0 || interval > 2147483647) {
317
+ throw new RangeError("pollIntervalMs must be between 0 and 2147483647");
318
+ }
319
+ if (!Number.isFinite(timeout) || timeout <= 0 || timeout > 2147483647) {
320
+ throw new RangeError("timeoutMs must be greater than 0 and at most 2147483647");
321
+ }
322
+ opts.signal?.throwIfAborted();
323
+ const controller = new AbortController();
324
+ const { signal } = controller;
325
+ const onAbort = () => controller.abort(opts.signal?.reason);
326
+ opts.signal?.addEventListener("abort", onAbort, { once: true });
327
+ const timer = setTimeout(
328
+ () => controller.abort(new PlatformApiError("poll_timeout", `job ${jobId} did not finish within ${timeout}ms`, 0)),
329
+ timeout
330
+ );
331
+ let rejectOnAbort = () => {
332
+ };
333
+ const aborted = new Promise((_resolve, reject) => {
334
+ rejectOnAbort = () => reject(signal.reason);
335
+ signal.addEventListener("abort", rejectOnAbort, { once: true });
336
+ });
337
+ const poll = async () => {
338
+ for (; ; ) {
339
+ signal.throwIfAborted();
340
+ const status = await getJobOrBackOff(jobId, signal, interval);
341
+ signal.throwIfAborted();
342
+ if (status === void 0) {
343
+ continue;
344
+ }
345
+ opts.onStatus?.(status);
346
+ if (TERMINAL_STATES.has(status.status)) {
347
+ return status;
348
+ }
349
+ await sleep(interval, signal);
441
350
  }
442
- await sleep(interval, opts.signal);
351
+ };
352
+ try {
353
+ return await Promise.race([poll(), aborted]);
354
+ } finally {
355
+ clearTimeout(timer);
356
+ opts.signal?.removeEventListener("abort", onAbort);
357
+ signal.removeEventListener("abort", rejectOnAbort);
443
358
  }
444
359
  },
445
360
  jobResults: async function* (jobId) {
@@ -456,30 +371,24 @@ var createPlatformClient = (options = {}) => {
456
371
  };
457
372
  };
458
373
 
374
+ // src/cli/commands/jobs/options.ts
375
+ import fs3 from "node:fs";
376
+
459
377
  // src/cli/constants.ts
460
378
  var DEFAULT_PATH = "https://example.com";
461
379
  var LOADERS = ["fetch", "playwright", "platform"];
462
380
  var MODES = ["default", "ai"];
463
- var EXTRACTORS = ["auto", "takumi", "minimal", "none"];
381
+ var EXTRACTORS = ["auto", "kiwame", "takumi", "minimal", "none"];
382
+ var PLATFORM_EXTRACTORS = ["auto", "takumi", "minimal", "none"];
464
383
  var API_KEY_ENV = "WEBFORAI_API_KEY";
465
384
  var PLATFORM_URL_ENV = "WEBFORAI_PLATFORM_URL";
466
385
 
467
- // src/cli/helpers/assertContinue.ts
468
- import { cancel, isCancel } from "@clack/prompts";
469
- function assertContinue(message, cancelMessage = "Canceled.") {
470
- if (isCancel(message)) {
471
- cancel(cancelMessage);
472
- process.exit(1);
473
- }
474
- }
475
-
476
- // src/cli/helpers/inputOutputPath.ts
477
- import fs3 from "node:fs";
478
- import { confirm, text } from "@clack/prompts";
386
+ // src/cli/commands/webforai/options.ts
387
+ import fs2 from "node:fs";
479
388
 
480
389
  // src/cli/utils.ts
481
- import fs2 from "node:fs";
482
- import path2 from "node:path";
390
+ import fs from "node:fs";
391
+ import path from "node:path";
483
392
  var isUrl = (maybeUrl) => {
484
393
  try {
485
394
  new URL(maybeUrl);
@@ -535,28 +444,804 @@ function urlToFilename(url) {
535
444
  var sourcePathToOutputPath = (sourcePath) => {
536
445
  return isUrl(sourcePath) ? `${urlToFilename(sourcePath)}.md` : changeFileExtension(sourcePath, "md");
537
446
  };
538
- function getNextAvailableFilePath(filePath) {
539
- const parsedPath = path2.parse(filePath);
447
+ function getNextAvailableFilePath(filePath, exists = fs.existsSync) {
448
+ const parsedPath = path.parse(filePath);
540
449
  const directory = parsedPath.dir;
541
450
  const fullName = parsedPath.base;
542
451
  const [firstPart, ...restParts] = fullName.split(".");
543
452
  const restName = restParts.length > 0 ? `.${restParts.join(".")}` : "";
544
453
  const baseName = firstPart.replace(/_\d+$/, "");
545
- let counter = 1;
454
+ const match = firstPart.match(/_(\d+)$/);
455
+ let counter = match ? Number.parseInt(match[1], 10) + 1 : 1;
546
456
  let nextFilePath = filePath;
547
- while (fs2.existsSync(nextFilePath)) {
548
- const match = firstPart.match(/_(\d+)$/);
549
- if (match) {
550
- counter = Number.parseInt(match[1], 10) + 1;
457
+ while (exists(nextFilePath)) {
458
+ const newName = `${baseName}_${counter}${restName}`;
459
+ nextFilePath = path.join(directory, newName);
460
+ counter++;
461
+ }
462
+ return nextFilePath;
463
+ }
464
+ var platformDashboardUrl = (platformUrl) => `${(platformUrl || DEFAULT_BASE_URL).replace(/\/+$/u, "")}/dashboard`;
465
+
466
+ // src/cli/commands/webforai/options.ts
467
+ var UsageError = class extends Error {
468
+ };
469
+ var oneOf = (name, value, allowed) => {
470
+ if (!allowed.includes(value)) {
471
+ throw new UsageError(`invalid --${name} "${value}" (expected: ${allowed.join(" | ")})`);
472
+ }
473
+ return value;
474
+ };
475
+ var impliesPlatform = (flags) => flags.engine !== void 0 || flags.region !== void 0;
476
+ var resolveLoader = (sourceIsUrl, flags) => {
477
+ if (flags.loader) {
478
+ const loader = oneOf("loader", flags.loader, LOADERS);
479
+ if (impliesPlatform(flags) && loader !== "platform") {
480
+ throw new UsageError(`--engine/--region require --loader platform (received --loader ${loader})`);
481
+ }
482
+ return loader;
483
+ }
484
+ if (impliesPlatform(flags)) {
485
+ return "platform";
486
+ }
487
+ return sourceIsUrl ? "fetch" : "local";
488
+ };
489
+ var assertUsableLocalSource = (source, loader, flags) => {
490
+ if (loader !== "local" && flags.loader) {
491
+ throw new UsageError(`--loader ${loader} needs a URL source, but "${source}" is a local path`);
492
+ }
493
+ if (impliesPlatform(flags)) {
494
+ throw new UsageError("--engine/--region need a URL source (the platform cannot read local files)");
495
+ }
496
+ if (!fs2.existsSync(source)) {
497
+ throw new UsageError(`source not found: "${source}" (URLs must start with http:// or https://)`);
498
+ }
499
+ };
500
+ var applyPlatformFields = (resolved, flags, env) => {
501
+ resolved.engine = flags.engine ? oneOf("engine", flags.engine, REQUESTED_ENGINES) : void 0;
502
+ resolved.region = flags.region ? oneOf("region", flags.region, REGIONS) : void 0;
503
+ resolved.apiKey = flags.apiKey ?? env[API_KEY_ENV];
504
+ resolved.platformUrl = flags.platformUrl ?? env[PLATFORM_URL_ENV];
505
+ if (!resolved.apiKey) {
506
+ throw missingApiKeyError(resolved.platformUrl);
507
+ }
508
+ };
509
+ var missingApiKeyError = (platformUrl) => new UsageError(
510
+ `the platform loader needs an API key: pass --api-key or set ${API_KEY_ENV} (create one at ${platformDashboardUrl(
511
+ platformUrl
512
+ )}; 1,000 free credits/month, no card)`
513
+ );
514
+ var resolveRunOptions = (source, flags, env = process.env) => {
515
+ const sourceIsUrl = isUrl(source);
516
+ const loader = resolveLoader(sourceIsUrl, flags);
517
+ if (!sourceIsUrl) {
518
+ assertUsableLocalSource(source, loader, flags);
519
+ }
520
+ const resolved = {
521
+ source,
522
+ loader: sourceIsUrl ? loader : "local",
523
+ mode: flags.mode ? oneOf("mode", flags.mode, MODES) : "default",
524
+ extractor: flags.extractor ? oneOf("extractor", flags.extractor, EXTRACTORS) : "auto",
525
+ frontmatter: flags.frontmatter ?? false,
526
+ output: flags.output,
527
+ json: flags.json ?? false,
528
+ debug: flags.debug ?? false,
529
+ screenshot: flags.screenshot ?? false,
530
+ respectRobotsTxt: flags.respectRobots ?? false
531
+ };
532
+ if (resolved.loader === "platform") {
533
+ if (resolved.extractor === "kiwame") {
534
+ throw new UsageError("--extractor kiwame is only available for local conversion");
535
+ }
536
+ applyPlatformFields(resolved, flags, env);
537
+ } else if (flags.screenshot) {
538
+ throw new UsageError("--screenshot is only available with the platform loader (browser engines)");
539
+ } else if (flags.respectRobots) {
540
+ throw new UsageError("--respect-robots is only available with the platform loader");
541
+ }
542
+ return resolved;
543
+ };
544
+
545
+ // src/cli/commands/jobs/options.ts
546
+ var MAX_BATCH_URLS = 100;
547
+ var MAX_CRAWL_DEPTH = 5;
548
+ var MAX_CRAWL_LIMIT = 500;
549
+ var DEFAULT_TIMEOUT_SECONDS = 30 * 60;
550
+ var isHttpUrl = (value) => {
551
+ try {
552
+ const { protocol } = new URL(value);
553
+ return protocol === "http:" || protocol === "https:";
554
+ } catch {
555
+ return false;
556
+ }
557
+ };
558
+ var oneOf2 = (name, value, allowed) => {
559
+ if (!allowed.includes(value)) {
560
+ throw new UsageError(`invalid --${name} "${value}" (expected: ${allowed.join(" | ")})`);
561
+ }
562
+ return value;
563
+ };
564
+ var integerIn = (name, value, min, max) => {
565
+ if (value === void 0) {
566
+ return void 0;
567
+ }
568
+ const parsed = Number(value);
569
+ if (!Number.isInteger(parsed) || parsed < min || parsed > max) {
570
+ throw new UsageError(`invalid --${name} "${value}" (expected an integer from ${min} to ${max})`);
571
+ }
572
+ return parsed;
573
+ };
574
+ var patterns = (name, values) => {
575
+ if (!values || values.length === 0) {
576
+ return void 0;
577
+ }
578
+ for (const value of values) {
579
+ try {
580
+ new RegExp(value);
581
+ } catch {
582
+ throw new UsageError(`invalid --${name} pattern "${value}" (expected a regular expression)`);
583
+ }
584
+ }
585
+ return values;
586
+ };
587
+ var parseUrlList = (text6) => text6.split(/\r?\n/u).map((line) => line.trim()).filter((line) => line !== "" && !line.startsWith("#"));
588
+ var readUrlFile = (file, readFile) => {
589
+ try {
590
+ return parseUrlList(readFile(file));
591
+ } catch (error) {
592
+ throw new UsageError(`cannot read --file "${file}": ${error instanceof Error ? error.message : String(error)}`);
593
+ }
594
+ };
595
+ var defaultReadFile = (file) => fs3.readFileSync(file === "-" ? 0 : file, "utf-8");
596
+ var resolveJobOptions = (kind, sources, flags, env = process.env, readFile = defaultReadFile) => {
597
+ const fromFile = kind === "batch" && flags.file ? readUrlFile(flags.file, readFile) : [];
598
+ const urls = [.../* @__PURE__ */ new Set([...sources, ...fromFile])];
599
+ if (kind === "crawl" && urls.length !== 1) {
600
+ throw new UsageError("crawl takes exactly one seed URL");
601
+ }
602
+ if (urls.length === 0) {
603
+ throw new UsageError("batch needs at least one URL (as arguments or via --file <path|->)");
604
+ }
605
+ if (urls.length > MAX_BATCH_URLS) {
606
+ throw new UsageError(
607
+ `batch takes at most ${MAX_BATCH_URLS} URLs per job (received ${urls.length}); split the list`
608
+ );
609
+ }
610
+ const invalid = urls.find((url) => !isHttpUrl(url));
611
+ if (invalid !== void 0) {
612
+ throw new UsageError(`not an http(s) URL: "${invalid}"`);
613
+ }
614
+ if (!flags.output) {
615
+ throw new UsageError(`${kind} writes one Markdown file per page: pass -o, --output <dir>`);
616
+ }
617
+ const apiKey = flags.apiKey ?? env[API_KEY_ENV];
618
+ const platformUrl = flags.platformUrl ?? env[PLATFORM_URL_ENV];
619
+ if (!apiKey) {
620
+ throw missingApiKeyError(platformUrl);
621
+ }
622
+ const timeoutSeconds = integerIn("timeout", flags.timeout, 1, 24 * 60 * 60) ?? DEFAULT_TIMEOUT_SECONDS;
623
+ return {
624
+ kind,
625
+ urls,
626
+ outputDir: flags.output,
627
+ engine: flags.engine ? oneOf2("engine", flags.engine, REQUESTED_ENGINES) : void 0,
628
+ region: flags.region ? oneOf2("region", flags.region, REGIONS) : void 0,
629
+ extractor: flags.extractor ? oneOf2("extractor", flags.extractor, PLATFORM_EXTRACTORS) : "auto",
630
+ frontmatter: flags.frontmatter ?? false,
631
+ respectRobotsTxt: flags.respectRobots,
632
+ apiKey,
633
+ platformUrl,
634
+ json: flags.json ?? false,
635
+ debug: flags.debug ?? false,
636
+ timeoutMs: timeoutSeconds * 1e3,
637
+ maxDepth: integerIn("max-depth", flags.maxDepth, 0, MAX_CRAWL_DEPTH),
638
+ limit: integerIn("limit", flags.limit, 1, MAX_CRAWL_LIMIT),
639
+ includePaths: patterns("include", flags.include),
640
+ excludePaths: patterns("exclude", flags.exclude),
641
+ sitemap: flags.sitemap ? oneOf2("sitemap", flags.sitemap, CRAWL_SITEMAP_MODES) : void 0,
642
+ llmsTxt: flags.llmsTxt ?? false
643
+ };
644
+ };
645
+
646
+ // src/cli/commands/jobs/run.ts
647
+ import fs4 from "node:fs/promises";
648
+ import path3 from "node:path";
649
+
650
+ // src/cli/commands/jobs/files.ts
651
+ import { createHash } from "node:crypto";
652
+ import path2 from "node:path";
653
+ var MAX_SEGMENT_LENGTH = 80;
654
+ var MAX_DEPTH = 12;
655
+ var PAGE_EXTENSION = /\.(?:html?|php|aspx?|jsp|md)$/iu;
656
+ var shortHash = (value) => createHash("sha256").update(value).digest("hex").slice(0, 8);
657
+ var decodeSegment = (segment) => {
658
+ try {
659
+ return decodeURIComponent(segment);
660
+ } catch {
661
+ return segment;
662
+ }
663
+ };
664
+ var sanitizeSegment = (segment) => {
665
+ const cleaned = decodeSegment(segment).normalize("NFC").replace(/[<>:"/\\|?*\u0000-\u001f\u007f]+/gu, "-").replace(/\s+/gu, "-").replace(/-{2,}/gu, "-").replace(/^[-.]+|[-.]+$/gu, "");
666
+ if (cleaned.length <= MAX_SEGMENT_LENGTH) {
667
+ return cleaned;
668
+ }
669
+ return `${cleaned.slice(0, MAX_SEGMENT_LENGTH - 9)}-${shortHash(cleaned)}`;
670
+ };
671
+ var pageRelativePath = (pageUrl, options = {}) => {
672
+ const url = new URL(pageUrl);
673
+ const rawSegments = url.pathname.split("/");
674
+ const trailingSlash = url.pathname.endsWith("/");
675
+ const segments = rawSegments.map(sanitizeSegment).filter(Boolean).slice(0, MAX_DEPTH);
676
+ let leaf = trailingSlash || segments.length === 0 ? "index" : segments.pop() ?? "index";
677
+ leaf = leaf.replace(PAGE_EXTENSION, "") || "index";
678
+ if (url.search.length > 1) {
679
+ leaf = `${leaf}_q-${shortHash(url.search)}`;
680
+ }
681
+ const directories = options.includeHost ? [sanitizeSegment(url.host) || "host", ...segments] : segments;
682
+ return path2.posix.join(...directories, `${leaf}.md`);
683
+ };
684
+ var planOutputFiles = (urls, options = {}) => {
685
+ const taken = /* @__PURE__ */ new Set();
686
+ const sorted = [...new Set(urls)].sort();
687
+ return sorted.map((url) => {
688
+ const candidate = pageRelativePath(url, options);
689
+ const relativePath = getNextAvailableFilePath(candidate, (name) => taken.has(name.toLowerCase()));
690
+ taken.add(relativePath.toLowerCase());
691
+ return { url, relativePath };
692
+ });
693
+ };
694
+ var resolveInside = (outputDir, relativePath) => {
695
+ const root = path2.resolve(outputDir);
696
+ const target = path2.resolve(root, ...relativePath.split("/"));
697
+ if (target !== root && !target.startsWith(`${root}${path2.sep}`)) {
698
+ throw new Error(`refusing to write outside the output directory: ${relativePath}`);
699
+ }
700
+ return target;
701
+ };
702
+
703
+ // src/cli/commands/jobs/llms-txt.ts
704
+ var str = (value) => typeof value === "string" && value.trim() !== "" ? value.trim().replace(/\s+/gu, " ") : void 0;
705
+ var firstHeading = (markdown) => {
706
+ const match = /^#{1,2}[ \t]+(.+?)[ \t#]*$/mu.exec(markdown);
707
+ return match ? str(match[1]) : void 0;
708
+ };
709
+ var escapeLinkText = (text6) => text6.replace(/([\\[\]])/gu, "\\$1");
710
+ var pageTitle = (page) => str(page.metadata.title) ?? firstHeading(page.markdown) ?? (new URL(page.url).pathname || page.url);
711
+ var normalizeUrl = (value) => {
712
+ const url = new URL(value);
713
+ url.hash = "";
714
+ return url.href;
715
+ };
716
+ var findSeed = (site) => {
717
+ const seed = normalizeUrl(site.seedUrl);
718
+ return site.pages.find((page) => normalizeUrl(page.url) === seed);
719
+ };
720
+ var siteTitle = (site, seed) => str(seed?.metadata.siteName) ?? str(site.pages.find((page) => str(page.metadata.siteName))?.metadata.siteName) ?? str(seed?.metadata.title) ?? new URL(site.seedUrl).host;
721
+ var sectionOf = (pageUrl) => {
722
+ const { pathname } = new URL(pageUrl);
723
+ const segments = pathname.split("/").filter(Boolean);
724
+ const first = segments[0];
725
+ if (!first || segments.length === 1 && !pathname.endsWith("/")) {
726
+ return "";
727
+ }
728
+ let decoded = first;
729
+ try {
730
+ decoded = decodeURIComponent(first);
731
+ } catch {
732
+ }
733
+ const words = decoded.replace(/[-_]+/gu, " ").trim();
734
+ return words.charAt(0).toUpperCase() + words.slice(1);
735
+ };
736
+ var orderPages = (pages) => {
737
+ const groups = /* @__PURE__ */ new Map();
738
+ for (const page of [...pages].sort((a, b) => a.url < b.url ? -1 : a.url > b.url ? 1 : 0)) {
739
+ const section = sectionOf(page.url);
740
+ groups.set(section, [...groups.get(section) ?? [], page]);
741
+ }
742
+ return [...groups.entries()].sort(([a], [b]) => a === "" ? -1 : b === "" ? 1 : a.localeCompare(b)).map(([section, grouped]) => ({ section, pages: grouped }));
743
+ };
744
+ var renderLlmsTxt = (site) => {
745
+ const seed = findSeed(site);
746
+ const lines = [`# ${siteTitle(site, seed)}`, ""];
747
+ const summary = str(seed?.metadata.description);
748
+ if (summary) {
749
+ lines.push(`> ${summary}`, "");
750
+ }
751
+ for (const { section, pages } of orderPages(site.pages)) {
752
+ lines.push(`## ${section || "Pages"}`, "");
753
+ for (const page of pages) {
754
+ const description = str(page.metadata.description);
755
+ const link = `- [${escapeLinkText(pageTitle(page))}](${page.url})`;
756
+ lines.push(description ? `${link}: ${description}` : link);
757
+ }
758
+ lines.push("");
759
+ }
760
+ return `${lines.join("\n").trimEnd()}
761
+ `;
762
+ };
763
+ var renderLlmsFullTxt = (site) => {
764
+ const seed = findSeed(site);
765
+ const parts = [`# ${siteTitle(site, seed)}`];
766
+ for (const { pages } of orderPages(site.pages)) {
767
+ for (const page of pages) {
768
+ const body = page.markdown.trim();
769
+ const heading2 = /^#[ \t]/u.test(body) ? "" : `# ${pageTitle(page)}
770
+
771
+ `;
772
+ parts.push(`${heading2}Source: ${page.url}
773
+
774
+ ${body}`);
775
+ }
776
+ }
777
+ return `${parts.join("\n\n---\n\n")}
778
+ `;
779
+ };
780
+
781
+ // src/cli/commands/jobs/run.ts
782
+ var POLL_INTERVAL_MS = 2e3;
783
+ var MAX_RATE_LIMIT_RETRIES = 5;
784
+ var MAX_LISTED_FAILURES = 20;
785
+ var defaultIo = () => ({
786
+ stdout: (text6) => process.stdout.write(text6),
787
+ stderr: (text6) => process.stderr.write(text6),
788
+ isTTY: Boolean(process.stderr.isTTY),
789
+ sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
790
+ fetch: globalThis.fetch.bind(globalThis)
791
+ });
792
+ var JobIncompleteError = class extends Error {
793
+ };
794
+ var progressLine = (kind, status) => {
795
+ const total = status.total > 0 ? `/${status.total}` : "";
796
+ const failed = status.failed > 0 ? ` \xB7 ${status.failed} failed` : "";
797
+ return `${kind} ${status.jobId} \xB7 ${status.status} \xB7 ${status.completed}${total} pages${failed} \xB7 ${status.credits} credits`;
798
+ };
799
+ var withRateLimitRetry = async (io, log2, call) => {
800
+ for (let attempt = 1; ; attempt++) {
801
+ try {
802
+ return await call();
803
+ } catch (error) {
804
+ if (!(error instanceof PlatformApiError) || error.code !== "rate_limited" || attempt > MAX_RATE_LIMIT_RETRIES) {
805
+ throw error;
806
+ }
807
+ const seconds = Math.min(error.retryAfter ?? 2 ** attempt, 120);
808
+ log2(`rate limited; retrying in ${seconds}s`);
809
+ await io.sleep(seconds * 1e3);
810
+ }
811
+ }
812
+ };
813
+ var submit = (client, job) => {
814
+ const common = {
815
+ engine: job.engine,
816
+ region: job.region,
817
+ respectRobotsTxt: job.respectRobotsTxt,
818
+ convert: { extractor: job.extractor, frontmatter: job.frontmatter || void 0 }
819
+ };
820
+ if (job.kind === "batch") {
821
+ return client.batch({ urls: job.urls, ...common });
822
+ }
823
+ return client.crawl({
824
+ url: job.urls[0],
825
+ maxDepth: job.maxDepth,
826
+ limit: job.limit,
827
+ includePaths: job.includePaths,
828
+ excludePaths: job.excludePaths,
829
+ sitemap: job.sitemap,
830
+ ...common
831
+ });
832
+ };
833
+ var resolveItem = async (io, item) => {
834
+ if (!isStoredPageStub(item)) {
835
+ return item;
836
+ }
837
+ const response = await io.fetch(item.resultUrl);
838
+ if (!response.ok) {
839
+ throw new PlatformApiError(
840
+ "artifact_fetch_failed",
841
+ `stored result for ${item.url} could not be downloaded (HTTP ${response.status})`,
842
+ response.status
843
+ );
844
+ }
845
+ return await response.json();
846
+ };
847
+ var createReporter = (io, job) => {
848
+ let liveLine = false;
849
+ const clearLive = () => {
850
+ if (liveLine) {
851
+ io.stderr("\r\x1B[2K");
852
+ liveLine = false;
853
+ }
854
+ };
855
+ const log2 = (line) => {
856
+ clearLive();
857
+ io.stderr(`[webforai] ${line}
858
+ `);
859
+ };
860
+ const status = (current) => {
861
+ if (io.isTTY) {
862
+ io.stderr(`\r\x1B[2K[webforai] ${progressLine(job.kind, current)}`);
863
+ liveLine = true;
864
+ } else if (job.debug) {
865
+ log2(progressLine(job.kind, current));
866
+ }
867
+ };
868
+ return { log: log2, status, clearLive };
869
+ };
870
+ var waitWithProgress = async (client, job, jobId, io, reporter) => {
871
+ const deadline = Date.now() + job.timeoutMs;
872
+ try {
873
+ return await withRateLimitRetry(
874
+ io,
875
+ reporter.log,
876
+ () => client.waitForJob(jobId, {
877
+ pollIntervalMs: POLL_INTERVAL_MS,
878
+ timeoutMs: Math.max(1, deadline - Date.now()),
879
+ onStatus: reporter.status
880
+ })
881
+ );
882
+ } catch (error) {
883
+ if (error instanceof PlatformApiError && error.code === "poll_timeout") {
884
+ throw new PlatformApiError(
885
+ "poll_timeout",
886
+ `${error.message}; the job keeps running on the platform and its results stay available for 7 days (GET /v1/jobs/${jobId}/results)`,
887
+ 0
888
+ );
889
+ }
890
+ throw error;
891
+ } finally {
892
+ reporter.clearLive();
893
+ }
894
+ };
895
+ var collectResults = async (client, jobId, io, reporter) => {
896
+ const successes = [];
897
+ const failures = [];
898
+ let cursor;
899
+ do {
900
+ const page = await withRateLimitRetry(io, reporter.log, () => client.getJobResults(jobId, { cursor }));
901
+ for (const item of page.results) {
902
+ const result = await resolveItem(io, item);
903
+ if (result.status === "ok") {
904
+ successes.push(result);
905
+ } else {
906
+ failures.push(result);
907
+ }
908
+ }
909
+ cursor = page.cursor;
910
+ } while (cursor);
911
+ return { successes, failures };
912
+ };
913
+ var writePages = async (job, successes) => {
914
+ const byUrl = new Map(successes.map((page) => [page.url, page]));
915
+ const written = [];
916
+ await fs4.mkdir(job.outputDir, { recursive: true });
917
+ for (const { url, relativePath } of planOutputFiles([...byUrl.keys()], { includeHost: job.kind === "batch" })) {
918
+ const page = byUrl.get(url);
919
+ const target = resolveInside(job.outputDir, relativePath);
920
+ await fs4.mkdir(path3.dirname(target), { recursive: true });
921
+ await fs4.writeFile(target, page.markdown.endsWith("\n") ? page.markdown : `${page.markdown}
922
+ `);
923
+ written.push({
924
+ url,
925
+ file: path3.join(job.outputDir, relativePath),
926
+ title: typeof page.metadata.title === "string" ? page.metadata.title : void 0,
927
+ engine: page.engine,
928
+ credits: page.credits,
929
+ warning: page.warning
930
+ });
931
+ }
932
+ return written;
933
+ };
934
+ var writeLlmsFiles = async (job, successes, envelope) => {
935
+ const pages = [...new Map(successes.map((page) => [page.url, page])).values()];
936
+ const site = { seedUrl: job.urls[0], pages };
937
+ envelope.llmsTxt = path3.join(job.outputDir, "llms.txt");
938
+ envelope.llmsFullTxt = path3.join(job.outputDir, "llms-full.txt");
939
+ await fs4.writeFile(envelope.llmsTxt, renderLlmsTxt(site));
940
+ await fs4.writeFile(envelope.llmsFullTxt, renderLlmsFullTxt(site));
941
+ };
942
+ var report = (job, envelope, io, log2) => {
943
+ if (job.json) {
944
+ io.stdout(`${JSON.stringify(envelope, null, 2)}
945
+ `);
946
+ } else {
947
+ for (const page of envelope.pages) {
948
+ io.stdout(`${page.file}
949
+ `);
950
+ }
951
+ }
952
+ const failed = envelope.failures.length;
953
+ log2(
954
+ `${job.kind} ${envelope.jobId} ${envelope.status}: ${envelope.pages.length} page(s) written to ${job.outputDir}${failed > 0 ? `, ${failed} failed` : ""} \xB7 ${envelope.credits} credits`
955
+ );
956
+ if (envelope.llmsTxt) {
957
+ log2(`llms.txt and llms-full.txt written to ${job.outputDir}`);
958
+ }
959
+ for (const failure of envelope.failures.slice(0, MAX_LISTED_FAILURES)) {
960
+ log2(` failed ${failure.url} \u2014 ${failure.code}: ${failure.message}`);
961
+ }
962
+ if (failed > MAX_LISTED_FAILURES) {
963
+ log2(` \u2026 and ${failed - MAX_LISTED_FAILURES} more (see --json)`);
964
+ }
965
+ };
966
+ var runJobCommand = async (job, io = defaultIo()) => {
967
+ const client = createPlatformClient({ apiKey: job.apiKey, baseUrl: job.platformUrl, fetch: io.fetch });
968
+ const reporter = createReporter(io, job);
969
+ const { jobId } = await withRateLimitRetry(io, reporter.log, () => submit(client, job));
970
+ reporter.log(
971
+ `${job.kind} job ${jobId} submitted (${job.kind === "crawl" ? job.urls[0] : `${job.urls.length} URLs`})`
972
+ );
973
+ const final = await waitWithProgress(client, job, jobId, io, reporter);
974
+ const { successes, failures } = await collectResults(client, jobId, io, reporter);
975
+ const envelope = {
976
+ jobId,
977
+ type: job.kind,
978
+ status: final.status,
979
+ outputDir: job.outputDir,
980
+ credits: final.credits,
981
+ pages: await writePages(job, successes),
982
+ failures: failures.map(({ url, error }) => ({ url, code: error.code, message: error.message })),
983
+ error: final.error
984
+ };
985
+ if (job.llmsTxt && successes.length > 0) {
986
+ await writeLlmsFiles(job, successes, envelope);
987
+ }
988
+ report(job, envelope, io, reporter.log);
989
+ if (final.status === "failed") {
990
+ throw new JobIncompleteError(`${job.kind} job ${jobId} failed${final.error ? `: ${final.error}` : ""}`);
991
+ }
992
+ if (envelope.pages.length === 0) {
993
+ throw new JobIncompleteError(`${job.kind} job ${jobId} converted no pages`);
994
+ }
995
+ return envelope;
996
+ };
997
+
998
+ // src/cli/commands/skill/index.ts
999
+ import { spawn } from "node:child_process";
1000
+ import fs5 from "node:fs/promises";
1001
+ import os from "node:os";
1002
+ import path4 from "node:path";
1003
+
1004
+ // src/cli/commands/skill/content.ts
1005
+ var renderSkillMarkdown = (version) => `---
1006
+ name: webforai
1007
+ description: Convert web pages or local HTML files to clean, LLM-ready Markdown with the webforai CLI. Use when a task needs page content as Markdown - reading documentation or articles, scraping, summarising URLs, crawling a docs site into files or llms.txt, building text corpora - including JavaScript-heavy or bot-protected pages via the hosted platform.
1008
+ ---
1009
+
1010
+ # webforai CLI${version ? ` (v${version})` : ""}
1011
+
1012
+ Convert a URL or local HTML file to Markdown. Non-interactive by default: the Markdown goes
1013
+ to stdout, every log goes to stderr, so output can be piped or captured directly.
1014
+
1015
+ ## Basic usage
1016
+
1017
+ \`\`\`bash
1018
+ npx webforai https://example.com/article # Markdown to stdout
1019
+ npx webforai https://example.com/article -o out.md # write to a file instead
1020
+ npx webforai ./page.html # convert a local HTML file
1021
+ npx webforai https://example.com --json # machine-readable envelope (see below)
1022
+ \`\`\`
1023
+
1024
+ ## Which command
1025
+
1026
+ - One page, or a handful you will read right away \u2192 \`npx webforai <url>\` (free, local;
1027
+ add \`--engine auto\` when the page needs JavaScript or blocks plain fetches).
1028
+ - A known list of URLs (2\u2013100) to keep as files \u2192 \`npx webforai batch\` (hosted platform).
1029
+ - A whole site or docs section \u2192 \`npx webforai crawl\` (hosted platform); add \`--llms-txt\`
1030
+ for a single \`llms-full.txt\` you can read in one go.
1031
+
1032
+ ## Flags
1033
+
1034
+ - \`-o, --output <path>\` \u2014 write Markdown to a file instead of stdout.
1035
+ - \`-l, --loader <fetch|playwright|platform>\` \u2014 how HTML is acquired. Default: \`fetch\` for
1036
+ URLs, automatic \`local\` for file paths. \`playwright\` renders JavaScript locally (needs
1037
+ \`npx playwright install chromium\`). \`platform\` uses the hosted API (below).
1038
+ - \`-m, --mode <default|ai>\` \u2014 \`ai\` strips links/tables/images down to plain text
1039
+ (local conversion only).
1040
+ - \`--extractor <auto|kiwame|takumi|minimal|none>\` \u2014 main-content extraction preset
1041
+ (\`kiwame\` is the learned block classifier, \`takumi\` the heuristic; \`none\` converts the whole page).
1042
+ - \`--frontmatter\` \u2014 prepend YAML front matter (title, author, canonical URL, ...).
1043
+ - \`--json\` \u2014 print a JSON envelope to stdout instead of raw Markdown.
1044
+ - \`--engine <auto|fetch|browser|proxy-fetch|proxy-browser>\` \u2014 platform acquisition engine
1045
+ (implies \`-l platform\`). \`auto\` (the platform default) starts with a plain fetch and
1046
+ escalates to browser rendering when the page is a client-rendered shell;
1047
+ \`browser\`/\`proxy-browser\` always render JavaScript; \`proxy-*\` engines egress through
1048
+ rotating proxies for bot-protected sites (paid plan only).
1049
+ - \`--region <auto|jp>\` \u2014 platform proxy egress region (implies \`-l platform\`); \`jp\` runs
1050
+ on the proxy tier, so it needs a paid plan too.
1051
+ - \`--screenshot\` \u2014 platform browser engines only; the envelope carries an expiring
1052
+ \`screenshotUrl\`.
1053
+ - \`--respect-robots\` \u2014 platform loader only; honor the target site's robots.txt rules
1054
+ (off by default). A disallowed URL fails with \`robots_disallowed\` and is not billed.
1055
+ - \`--api-key <key>\` / \`--platform-url <url>\` \u2014 platform credentials and host; usually set
1056
+ via env vars instead.
1057
+ - \`-i, --interactive\` \u2014 guided prompt flow (for humans; do not use from an agent).
1058
+ - \`-d, --debug\` \u2014 verbose logs on stderr.
1059
+
1060
+ ## JSON envelope (\`--json\`)
1061
+
1062
+ \`\`\`json
1063
+ {
1064
+ "source": "https://example.com",
1065
+ "loader": "fetch",
1066
+ "url": "https://example.com",
1067
+ "markdown": "# ...",
1068
+ "metadata": { "title": "..." },
1069
+ "engine": "browser",
1070
+ "region": "auto",
1071
+ "credits": 5,
1072
+ "screenshotUrl": "https://...",
1073
+ "output": "out.md"
1074
+ }
1075
+ \`\`\`
1076
+
1077
+ \`engine\`/\`region\`/\`credits\`/\`screenshotUrl\` appear only for the platform loader; \`output\`
1078
+ only when \`-o\` also wrote a file. A \`warning\` field appears when the result is probably
1079
+ degraded \u2014 most commonly a client-rendered shell fetched without JavaScript; rerun with
1080
+ \`--engine auto\` (or \`-l playwright\`) when you see one.
1081
+
1082
+ ## Hosted platform
1083
+
1084
+ For JavaScript-heavy or bot-protected pages, the hosted platform fetches server-side:
1085
+
1086
+ \`\`\`bash
1087
+ export WEBFORAI_API_KEY=wfa_... # from https://platform.webforai.dev/dashboard
1088
+ npx webforai https://example.com --engine auto --json
1089
+ \`\`\`
1090
+
1091
+ \`WEBFORAI_PLATFORM_URL\` overrides the host for self-hosted deployments. Accounts get 1,000
1092
+ free credits per month; failures are never billed.
1093
+
1094
+ | operation | credits |
1095
+ | --- | --- |
1096
+ | \`fetch\` | 1 |
1097
+ | \`browser\` | 2 |
1098
+ | \`proxy-fetch\` (paid plan only) | 2 |
1099
+ | \`proxy-browser\` (paid plan only) | 3 |
1100
+ | \`--screenshot\` | +1 |
1101
+ | image rehosting (API \`rehostImages\`) | +1 per started 5 images |
1102
+
1103
+ \`auto\` bills the engine that actually ran (1, or 2 when it needed a browser). The proxy
1104
+ engines \u2014 and \`--region jp\`, which runs on them \u2014 need an active subscription; on the free
1105
+ allowance they fail with \`payment_required\`. Prefer \`--engine auto\` unless a site blocks
1106
+ it. Batch and crawl jobs bill per converted page.
1107
+
1108
+ ## Crawl and batch (hosted platform)
1109
+
1110
+ \`\`\`bash
1111
+ # a docs site \u2192 one .md per page, mirroring URL paths, plus llms.txt / llms-full.txt
1112
+ npx webforai crawl https://docs.example.com -o docs --limit 100 --include '^/docs' --llms-txt
1113
+
1114
+ # a list of URLs (arguments, or one per line via --file; '-' reads stdin)
1115
+ npx webforai batch https://a.example/post https://b.example/news -o pages
1116
+ npx webforai batch --file urls.txt -o pages --json
1117
+ \`\`\`
1118
+
1119
+ Both submit an async job, wait for it, then write every converted page under \`-o <dir>\`
1120
+ (\`/docs/intro\` \u2192 \`docs/intro.md\`; batch prefixes the host: \`a.example/post.md\`). stdout
1121
+ lists the written files, one per line; \`--json\` prints \`{ jobId, status, credits, pages:
1122
+ [{ url, file, title }], failures: [{ url, code, message }], llmsTxt?, llmsFullTxt? }\`
1123
+ instead. Progress and the summary go to stderr. Exit code 1 when the job failed or no page
1124
+ converted; individual failed pages are listed but do not fail the command.
1125
+
1126
+ - \`crawl <url>\` \u2014 same-origin only. \`--max-depth <0-5>\` (default 2), \`--limit <1-500>\`
1127
+ (default 50), \`--include <regex>\` / \`--exclude <regex>\` on the pathname (repeatable).
1128
+ \`--sitemap <skip|include|only>\`: \`include\` adds the site's sitemap URLs to the links it
1129
+ follows, \`only\` crawls just the seed plus sitemap URLs (best for blogs and large docs with
1130
+ a good sitemap). Honors robots.txt by default; \`--no-respect-robots\` turns that off.
1131
+ - \`--llms-txt\` (crawl) \u2014 also write \`llms.txt\` (site title, summary, \`- [title](url):
1132
+ description\` links grouped by top-level path) and \`llms-full.txt\` (every page's Markdown
1133
+ concatenated) per llmstxt.org. Read \`llms-full.txt\` when you need the whole site in context.
1134
+ - \`batch [urls...]\` \u2014 up to 100 URLs per job; \`-f, --file <path|->\` adds URLs from a file.
1135
+ \`--respect-robots\` opts in to robots.txt checks.
1136
+ - Shared: \`--engine\`, \`--region\`, \`--extractor\`, \`--frontmatter\`, \`--json\`,
1137
+ \`--timeout <seconds>\` (default 1800; the job keeps running after a timeout and results stay
1138
+ available for 7 days), \`--api-key\`, \`--platform-url\`, \`-d\`.
1139
+
1140
+ ## Exit codes
1141
+
1142
+ - \`0\` \u2014 success.
1143
+ - \`1\` \u2014 runtime failure (network, conversion, platform error; message on stderr).
1144
+ - \`2\` \u2014 usage error (unknown flag or invalid value; message on stderr).
1145
+
1146
+ ## Errors worth handling
1147
+
1148
+ Platform errors print as \`error: <code>: <message>\` on stderr (exit 1). What to do:
1149
+
1150
+ - \`invalid_api_key\` (401) \u2192 the key is missing, revoked or mistyped. Do not retry; ask the
1151
+ user for a key from the dashboard named in the message.
1152
+ - \`payment_required\` (402) \u2192 the free monthly allowance is used up, or a proxy engine /
1153
+ \`--region jp\` was requested without a subscription. Do not retry; fall back to
1154
+ \`--engine auto\` (or the local loaders) for proxy requests, otherwise tell the user.
1155
+ - \`spend_cap_reached\` (402) \u2192 the account's monthly spend cap (default $50) is reached; the
1156
+ user can raise it on the dashboard. Do not retry.
1157
+ - \`rate_limited\` (429) \u2192 per-account limit: 60 requests/minute (free), 600 (paid). Wait the
1158
+ \`retryAfter\` seconds shown, then retry; for many URLs use one \`batch\` job instead of a
1159
+ loop of single requests. \`crawl\`/\`batch\` retry this automatically.
1160
+ - \`too_many_jobs\` (429) \u2192 3 (free) / 20 (paid) batch/crawl jobs already queued or running.
1161
+ Wait for one to finish, then resubmit.
1162
+ - \`robots_disallowed\` (403) \u2192 robots.txt disallows the URL (\`--respect-robots\`, or a crawl
1163
+ by default). Not billed; respect it unless the user explicitly decides otherwise.
1164
+ - \`invalid_request\` (400) \u2192 a bad flag value or URL; fix the input.
1165
+ - \`engine_unavailable\` / \`scheduling_unknown\` / \`result_unavailable\` (503) \u2192 transient;
1166
+ retry later.
1167
+ - Playwright loader errors explain the exact \`npx playwright install\` command to run.
1168
+ `;
1169
+
1170
+ // src/cli/commands/skill/index.ts
1171
+ var buildSkillsAddArgs = (source, flags) => {
1172
+ const args = ["-y", "skills", "add", source];
1173
+ if (flags.global) {
1174
+ args.push("--global");
1175
+ }
1176
+ if (flags.agent) {
1177
+ args.push("--agent", flags.agent);
1178
+ }
1179
+ if (flags.yes) {
1180
+ args.push("-y");
1181
+ }
1182
+ if (flags.copy) {
1183
+ args.push("--copy");
1184
+ }
1185
+ if (flags.all) {
1186
+ args.push("--all");
1187
+ }
1188
+ return args;
1189
+ };
1190
+ var runSkillsAdd = (args) => new Promise((resolve, reject) => {
1191
+ const child = spawn("npx", args, { stdio: ["inherit", "inherit", "inherit"] });
1192
+ child.on("error", reject);
1193
+ child.on("close", (code) => resolve(code ?? 1));
1194
+ });
1195
+ var skillCommand = async (flags) => {
1196
+ const markdown = renderSkillMarkdown(package_default.version);
1197
+ if (!(flags.install || flags.dir)) {
1198
+ process.stdout.write(markdown);
1199
+ return;
1200
+ }
1201
+ if (flags.dir) {
1202
+ const target = path4.join(flags.dir, "webforai", "SKILL.md");
1203
+ await fs5.mkdir(path4.dirname(target), { recursive: true });
1204
+ await fs5.writeFile(target, markdown);
1205
+ console.error(`[webforai] Agent Skill written to ${target}`);
1206
+ return;
1207
+ }
1208
+ const stage = await fs5.mkdtemp(path4.join(os.tmpdir(), "webforai-skill-"));
1209
+ try {
1210
+ await fs5.mkdir(path4.join(stage, "webforai"), { recursive: true });
1211
+ await fs5.writeFile(path4.join(stage, "webforai", "SKILL.md"), markdown);
1212
+ const args = buildSkillsAddArgs(stage, flags);
1213
+ console.error(`[webforai] running: npx ${args.join(" ")}`);
1214
+ const code = await runSkillsAdd(args).catch((error) => {
1215
+ console.error(
1216
+ `[webforai] could not launch the skills CLI (${error instanceof Error ? error.message : String(error)}).`
1217
+ );
1218
+ console.error("[webforai] fallback: `webforai skill --dir .claude/skills` writes the file directly.");
1219
+ return 1;
1220
+ });
1221
+ if (code !== 0) {
1222
+ process.exitCode = 1;
551
1223
  }
552
- const newName = `${baseName}_${counter}${restName}`;
553
- nextFilePath = path2.join(directory, newName);
554
- counter++;
1224
+ } finally {
1225
+ await fs5.rm(stage, { recursive: true, force: true });
1226
+ }
1227
+ };
1228
+
1229
+ // src/cli/commands/webforai/interactive.ts
1230
+ import { intro, log, outro, select as select7, spinner, text as text5 } from "@clack/prompts";
1231
+ import pc2 from "picocolors";
1232
+
1233
+ // src/cli/helpers/assertContinue.ts
1234
+ import { cancel, isCancel } from "@clack/prompts";
1235
+ function assertContinue(message, cancelMessage = "Canceled.") {
1236
+ if (isCancel(message)) {
1237
+ cancel(cancelMessage);
1238
+ process.exit(1);
555
1239
  }
556
- return nextFilePath;
557
1240
  }
558
1241
 
559
1242
  // src/cli/helpers/inputOutputPath.ts
1243
+ import fs6 from "node:fs";
1244
+ import { confirm, text } from "@clack/prompts";
560
1245
  var inputOutputPath = async (sourcePath) => {
561
1246
  const outputPath = await text({
562
1247
  message: "Enter the output file path:",
@@ -566,16 +1251,16 @@ var inputOutputPath = async (sourcePath) => {
566
1251
  if (value.trim() === "") {
567
1252
  return "Output path is required";
568
1253
  }
569
- if (fs3.existsSync(value) && fs3.statSync(value).isDirectory()) {
1254
+ if (fs6.existsSync(value) && fs6.statSync(value).isDirectory()) {
570
1255
  return "No directory can be specified.";
571
1256
  }
572
- if (!fs3.existsSync(value) && value.endsWith("/")) {
1257
+ if (!fs6.existsSync(value) && value.endsWith("/")) {
573
1258
  return "No directory can be specified.";
574
1259
  }
575
1260
  }
576
1261
  });
577
1262
  assertContinue(outputPath);
578
- if (!fs3.existsSync(outputPath)) {
1263
+ if (!fs6.existsSync(outputPath)) {
579
1264
  return outputPath;
580
1265
  }
581
1266
  const isOutputFileOverwrite = await confirm({
@@ -594,10 +1279,10 @@ var inputOutputPath = async (sourcePath) => {
594
1279
  if (value.trim() === "") {
595
1280
  return "Output path is required";
596
1281
  }
597
- if (fs3.existsSync(value)) {
1282
+ if (fs6.existsSync(value)) {
598
1283
  return "The file already exists";
599
1284
  }
600
- if (!fs3.existsSync(value) && value.endsWith("/")) {
1285
+ if (!fs6.existsSync(value) && value.endsWith("/")) {
601
1286
  return "No directory can be specified.";
602
1287
  }
603
1288
  }
@@ -607,7 +1292,7 @@ var inputOutputPath = async (sourcePath) => {
607
1292
  };
608
1293
 
609
1294
  // src/cli/helpers/inputSourcePath.ts
610
- import fs4 from "node:fs";
1295
+ import fs7 from "node:fs";
611
1296
  import { text as text2 } from "@clack/prompts";
612
1297
  var inputSourcePath = async () => {
613
1298
  const result = await text2({
@@ -619,10 +1304,10 @@ var inputSourcePath = async () => {
619
1304
  return "Source is required";
620
1305
  }
621
1306
  if (!isUrl(value)) {
622
- if (!fs4.existsSync(value)) {
1307
+ if (!fs7.existsSync(value)) {
623
1308
  return "It appears that you are specifying a local file, but the file cannot be found. hint: when specifying a url, start with http or https.";
624
1309
  }
625
- if (fs4.statSync(value).isDirectory()) {
1310
+ if (fs7.statSync(value).isDirectory()) {
626
1311
  return "You are specifying a local file, but you cannot specify a directory. hint: when specifying a url, start with http or https.";
627
1312
  }
628
1313
  }
@@ -662,14 +1347,92 @@ var selectLoader = async () => {
662
1347
  };
663
1348
 
664
1349
  // src/cli/commands/webforai/run.ts
665
- import fs6 from "node:fs/promises";
666
- import path3 from "node:path";
1350
+ import fs9 from "node:fs/promises";
1351
+ import path5 from "node:path";
667
1352
 
668
- // src/html-to-markdown.ts
669
- import { fromHtml as fromHtml2 } from "hast-util-from-html";
1353
+ // src/utils/parse-html.ts
1354
+ import { fromParse5 } from "hast-util-from-parse5";
1355
+ import { parse, parseFragment } from "parse5";
1356
+ var MAX_ELEMENT_DEPTH = 256;
1357
+ var isParent = (node) => "childNodes" in node;
1358
+ var LINE_ELEMENTS = /* @__PURE__ */ new Set([
1359
+ "p",
1360
+ "div",
1361
+ "li",
1362
+ "tr",
1363
+ "td",
1364
+ "th",
1365
+ "h1",
1366
+ "h2",
1367
+ "h3",
1368
+ "h4",
1369
+ "h5",
1370
+ "h6",
1371
+ "br",
1372
+ "section",
1373
+ "article",
1374
+ "pre",
1375
+ "blockquote"
1376
+ ]);
1377
+ var textNode = (value, parentNode) => ({ nodeName: "#text", value, parentNode });
1378
+ var coalesceText = (parent) => {
1379
+ const merged = [];
1380
+ for (const child of parent.childNodes) {
1381
+ const previous = merged.at(-1);
1382
+ if (child.nodeName === "#text" && previous?.nodeName === "#text") {
1383
+ previous.value += child.value;
1384
+ } else {
1385
+ merged.push(child);
1386
+ }
1387
+ }
1388
+ parent.childNodes = merged;
1389
+ };
1390
+ var flattenDeep = (root, maxDepth) => {
1391
+ const stack = [[root, 0]];
1392
+ while (stack.length > 0) {
1393
+ const [parent, depth] = stack.pop();
1394
+ const children = parent.childNodes;
1395
+ let unwrapped = false;
1396
+ for (let index = 0; index < children.length; index++) {
1397
+ const child = children[index];
1398
+ if (!isParent(child)) {
1399
+ continue;
1400
+ }
1401
+ if (depth + 1 > maxDepth && "tagName" in child) {
1402
+ const replacement = [...child.childNodes];
1403
+ if (LINE_ELEMENTS.has(child.tagName)) {
1404
+ replacement.unshift(textNode("\n", parent));
1405
+ replacement.push(textNode("\n", parent));
1406
+ }
1407
+ for (const node of replacement) {
1408
+ node.parentNode = parent;
1409
+ }
1410
+ children.splice(index, 1, ...replacement);
1411
+ index -= 1;
1412
+ unwrapped = true;
1413
+ continue;
1414
+ }
1415
+ stack.push([child, depth + 1]);
1416
+ }
1417
+ if (unwrapped) {
1418
+ coalesceText(parent);
1419
+ }
1420
+ }
1421
+ };
1422
+ var SCRIPT_OR_STYLE = /<(script|style)\b([^>]*)>[\s\S]*?<\/\1\s*>/gi;
1423
+ var LARGE_DOCUMENT_CHARS = 2e6;
1424
+ var stripScriptBodies = (html) => html.replace(
1425
+ SCRIPT_OR_STYLE,
1426
+ (match, tag, attributes) => /application\/ld\+json/i.test(attributes) ? match : `<${tag}${attributes}></${tag}>`
1427
+ );
1428
+ var parseHtml = (html, options = {}) => {
1429
+ const source = html.length > LARGE_DOCUMENT_CHARS ? stripScriptBodies(html) : html;
1430
+ const document2 = options.fragment ? parseFragment(source, { scriptingEnabled: false }) : parse(source, { scriptingEnabled: false });
1431
+ flattenDeep(document2, MAX_ELEMENT_DEPTH);
1432
+ return fromParse5(document2);
1433
+ };
670
1434
 
671
1435
  // src/html-to-mdast.ts
672
- import { fromHtml } from "hast-util-from-html";
673
1436
  import { toMdast } from "hast-util-to-mdast";
674
1437
 
675
1438
  // src/extract-mdast.ts
@@ -684,6 +1447,61 @@ var emptyDeclarationFilter = (node) => {
684
1447
  }
685
1448
  return true;
686
1449
  };
1450
+ var trimEdge = (children, edge) => {
1451
+ const index = edge === "start" ? 0 : children.length - 1;
1452
+ const node = children[index];
1453
+ if (node?.type !== "text") {
1454
+ return children;
1455
+ }
1456
+ const value = edge === "start" ? node.value.trimStart() : node.value.trimEnd();
1457
+ const copy = [...children];
1458
+ if (value.length === 0) {
1459
+ copy.splice(index, 1);
1460
+ } else {
1461
+ copy[index] = { ...node, value };
1462
+ }
1463
+ return copy;
1464
+ };
1465
+ var liftDisplayMath = (paragraph2) => {
1466
+ if (!paragraph2.children.some((child) => child.type === "math")) {
1467
+ return void 0;
1468
+ }
1469
+ const out = [];
1470
+ let run = [];
1471
+ const flush = () => {
1472
+ const trimmed = trimEdge(trimEdge(run, "start"), "end");
1473
+ if (trimmed.length > 0) {
1474
+ out.push({ ...paragraph2, children: trimmed });
1475
+ }
1476
+ run = [];
1477
+ };
1478
+ for (const child of paragraph2.children) {
1479
+ if (child.type === "math") {
1480
+ flush();
1481
+ out.push(child);
1482
+ } else {
1483
+ run.push(child);
1484
+ }
1485
+ }
1486
+ flush();
1487
+ return out;
1488
+ };
1489
+ var liftDisplayMathIn = (node) => {
1490
+ if (!("children" in node)) {
1491
+ return;
1492
+ }
1493
+ const parent = node;
1494
+ for (let index = 0; index < parent.children.length; index++) {
1495
+ const child = parent.children[index];
1496
+ const lifted = child.type === "paragraph" ? liftDisplayMath(child) : void 0;
1497
+ if (lifted) {
1498
+ parent.children.splice(index, 1, ...lifted);
1499
+ index += lifted.length - 1;
1500
+ continue;
1501
+ }
1502
+ liftDisplayMathIn(child);
1503
+ }
1504
+ };
687
1505
  var extractMdast = (node) => {
688
1506
  const extracted = filter(node, (node2) => {
689
1507
  if (!emptyDeclarationFilter(node2)) {
@@ -691,6 +1509,9 @@ var extractMdast = (node) => {
691
1509
  }
692
1510
  return true;
693
1511
  });
1512
+ if (extracted) {
1513
+ liftDisplayMathIn(extracted);
1514
+ }
694
1515
  return extracted;
695
1516
  };
696
1517
 
@@ -700,7 +1521,7 @@ var COMMA_REGEX = /[,、,،]/g;
700
1521
  var PARAGRAPH_LIKE = /* @__PURE__ */ new Set(["p", "pre", "li", "blockquote", "figcaption", "dd", "dt"]);
701
1522
  var NON_PROSE_TAGS = /* @__PURE__ */ new Set(["script", "style", "noscript", "template", "svg", "math", "iframe", "object"]);
702
1523
  var isElement = (node) => typeof node === "object" && node !== null && node.type === "element";
703
- var isParent = (node) => typeof node === "object" && node !== null && Array.isArray(node.children);
1524
+ var isParent2 = (node) => typeof node === "object" && node !== null && Array.isArray(node.children);
704
1525
  var classList = (element3) => {
705
1526
  const className = element3.properties?.className;
706
1527
  if (Array.isArray(className)) {
@@ -735,7 +1556,7 @@ var MetricsCollector = class {
735
1556
  elements: 0
736
1557
  };
737
1558
  }
738
- if (!isParent(node)) {
1559
+ if (!isParent2(node)) {
739
1560
  return EMPTY_METRICS;
740
1561
  }
741
1562
  const cached = this.#cache.get(node);
@@ -785,7 +1606,7 @@ var MetricsCollector = class {
785
1606
  }
786
1607
  };
787
1608
  var pruneInPlace = (tree, keep) => {
788
- if (!isParent(tree)) {
1609
+ if (!isParent2(tree)) {
789
1610
  return tree;
790
1611
  }
791
1612
  const stack = [tree];
@@ -795,11 +1616,11 @@ var pruneInPlace = (tree, keep) => {
795
1616
  let write = 0;
796
1617
  for (let read = 0; read < children.length; read++) {
797
1618
  const child = children[read];
798
- if (!keep(child)) {
1619
+ if (!keep(child, parent)) {
799
1620
  continue;
800
1621
  }
801
1622
  children[write++] = child;
802
- if (isParent(child)) {
1623
+ if (isParent2(child)) {
803
1624
  stack.push(child);
804
1625
  }
805
1626
  }
@@ -814,7 +1635,7 @@ var walk = (tree, visit) => {
814
1635
  if (visit(node, parent) === false) {
815
1636
  continue;
816
1637
  }
817
- if (isParent(node)) {
1638
+ if (isParent2(node)) {
818
1639
  for (let i = node.children.length - 1; i >= 0; i--) {
819
1640
  stack.push({ node: node.children[i], parent: node });
820
1641
  }
@@ -916,6 +1737,171 @@ var isTruthyAttribute = (element3, key) => {
916
1737
  return true;
917
1738
  };
918
1739
 
1740
+ // src/extractors/lib/code-tabs.ts
1741
+ var MAX_LABEL_LENGTH = 80;
1742
+ var CodeTabCollector = class {
1743
+ #groups = [];
1744
+ /** Groups whose tab list's parent is still being traversed, innermost last. */
1745
+ #open = [];
1746
+ #isHidden;
1747
+ #radioStrips = [];
1748
+ /** @param isHidden - Elements whose text a reader never sees, excluded from labels. */
1749
+ constructor(isHidden2) {
1750
+ this.#isHidden = isHidden2;
1751
+ }
1752
+ #applyRadioStrip(strip, parent) {
1753
+ const labels = strip.children.filter((child) => isElement(child) && child.tagName === "label");
1754
+ const panels = radioStripPanels(strip, parent);
1755
+ if (!panels || panels.length !== labels.length) {
1756
+ return;
1757
+ }
1758
+ panels.forEach((panel, index) => labelCode(panel, tabLabel(labels[index], this.#isHidden)));
1759
+ parent.children.splice(parent.children.indexOf(strip), 1);
1760
+ }
1761
+ /**
1762
+ * Call for every element, in document order, with its depth.
1763
+ *
1764
+ * A group only collects panels inside the tab list's parent: a page-level tab strip must not
1765
+ * lend its labels to an unrelated code switcher further down, and an inner group closes before
1766
+ * the outer group's next panel.
1767
+ */
1768
+ visit(element3, depth, parent) {
1769
+ if (isRadioTabStrip(element3)) {
1770
+ this.#radioStrips.push({ strip: element3, parent });
1771
+ return;
1772
+ }
1773
+ while (this.#open.length > 0 && depth < (this.#open.at(-1)?.depth ?? 0)) {
1774
+ this.#open.pop();
1775
+ }
1776
+ const role = stringProperty(element3, "role");
1777
+ if (role === "tablist") {
1778
+ const group2 = { tabs: [], panels: [] };
1779
+ this.#groups.push(group2);
1780
+ this.#open.push({ group: group2, depth });
1781
+ return;
1782
+ }
1783
+ const group = this.#open.at(-1)?.group;
1784
+ if (!group) {
1785
+ return;
1786
+ }
1787
+ if (role === "tab") {
1788
+ group.tabs.push(element3);
1789
+ } else if (role === "tabpanel") {
1790
+ group.panels.push(element3);
1791
+ }
1792
+ }
1793
+ /** Labels the code block of every panel whose tab could be identified. */
1794
+ apply() {
1795
+ for (const { strip, parent } of this.#radioStrips) {
1796
+ this.#applyRadioStrip(strip, parent);
1797
+ }
1798
+ for (const group of this.#groups) {
1799
+ if (group.tabs.length < 2 || group.panels.length === 0) {
1800
+ continue;
1801
+ }
1802
+ for (const [panel, tab] of matchTabs(group)) {
1803
+ labelCode(panel, tabLabel(tab, this.#isHidden));
1804
+ }
1805
+ }
1806
+ }
1807
+ };
1808
+ var radioStripPanels = (strip, parent) => {
1809
+ const index = parent.children.indexOf(strip);
1810
+ for (let cursor = index + 1; cursor < parent.children.length; cursor++) {
1811
+ const sibling = parent.children[cursor];
1812
+ if (isElement(sibling)) {
1813
+ return sibling.children.filter(isElement);
1814
+ }
1815
+ }
1816
+ return void 0;
1817
+ };
1818
+ var isRadioTabStrip = (element3) => {
1819
+ const first = element3.children.find(isElement);
1820
+ if (!(first?.tagName === "input" && stringProperty(first, "type") === "radio")) {
1821
+ return false;
1822
+ }
1823
+ let labels = 0;
1824
+ for (const child of element3.children) {
1825
+ if (!isElement(child)) {
1826
+ continue;
1827
+ }
1828
+ if (child.tagName === "label") {
1829
+ labels += 1;
1830
+ } else if (!(child.tagName === "input" && stringProperty(child, "type") === "radio")) {
1831
+ return false;
1832
+ }
1833
+ }
1834
+ return labels >= 2;
1835
+ };
1836
+ var indexById = (elements) => {
1837
+ const byId = /* @__PURE__ */ new Map();
1838
+ for (const element3 of elements) {
1839
+ const id = stringProperty(element3, "id");
1840
+ if (id) {
1841
+ byId.set(id, element3);
1842
+ }
1843
+ }
1844
+ return byId;
1845
+ };
1846
+ var matchTabs = ({ tabs, panels }) => {
1847
+ const tabById = indexById(tabs);
1848
+ const panelById = indexById(panels);
1849
+ const tabOf = /* @__PURE__ */ new Map();
1850
+ for (const panel of panels) {
1851
+ const tab = tabById.get(stringProperty(panel, "ariaLabelledBy") ?? "");
1852
+ if (tab) {
1853
+ tabOf.set(panel, tab);
1854
+ }
1855
+ }
1856
+ for (const tab of tabs) {
1857
+ const panel = panelById.get(stringProperty(tab, "ariaControls") ?? "");
1858
+ if (panel && !tabOf.has(panel)) {
1859
+ tabOf.set(panel, tab);
1860
+ }
1861
+ }
1862
+ if (tabOf.size === 0 && tabs.length === panels.length) {
1863
+ panels.forEach((panel, index) => tabOf.set(panel, tabs[index]));
1864
+ }
1865
+ return tabOf;
1866
+ };
1867
+ var tabLabel = (tab, isHidden2) => {
1868
+ const label = (textOf(tab, isHidden2) || stringProperty(tab, "dataTitle") || "").replace(/\s+/g, " ").trim();
1869
+ return label.length > 0 && label.length <= MAX_LABEL_LENGTH ? label : void 0;
1870
+ };
1871
+ var labelCode = (panel, label) => {
1872
+ if (!label) {
1873
+ return;
1874
+ }
1875
+ const blocks = [];
1876
+ collectPre(panel, blocks);
1877
+ if (blocks.length === 1 && stringProperty(blocks[0], "dataTitle") === void 0) {
1878
+ blocks[0].properties.dataTitle = label;
1879
+ }
1880
+ };
1881
+ var collectPre = (element3, into) => {
1882
+ for (const child of element3.children) {
1883
+ if (!isElement(child) || into.length > 1) {
1884
+ continue;
1885
+ }
1886
+ if (child.tagName === "pre") {
1887
+ into.push(child);
1888
+ continue;
1889
+ }
1890
+ collectPre(child, into);
1891
+ }
1892
+ };
1893
+ var textOf = (element3, isHidden2) => {
1894
+ let text6 = "";
1895
+ for (const child of element3.children) {
1896
+ if (child.type === "text") {
1897
+ text6 += child.value;
1898
+ } else if (isElement(child) && !isHidden2(child)) {
1899
+ text6 += textOf(child, isHidden2);
1900
+ }
1901
+ }
1902
+ return text6;
1903
+ };
1904
+
919
1905
  // src/extractors/lib/constants.ts
920
1906
  var REGEXPS = {
921
1907
  /**
@@ -926,7 +1912,7 @@ var REGEXPS = {
926
1912
  * `class="post-header"`), so matching them here deletes the page's headings. The landmark
927
1913
  * versions of those elements are handled structurally instead.
928
1914
  */
929
- unlikelyCandidates: /-ad-|ai2html|banner|breadcrumb|combx|comment(?!ary)|community|cover-wrap|disqus|gdpr|legends|menu|related|remark|replies|rss|shoutbox|sidebar|site-index|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote|speechify-ignore|avatar|subscribe|newsletter|paywall|consent|cookie|toolbar|masthead|promo|share|sharing|widget|tooltip|dropdown|modal|overlay|backdrop|carousel|announcement|notification|toast|skip-link|screen-reader|visually-hidden|sr-only/i,
1915
+ unlikelyCandidates: /-ad-|ai2html|banner|breadcrumb|combx|comment(?!ary)|community|cover-wrap|disqus|gdpr|legends|menu|related|remark|replies|rss|shoutbox|sidebar|site-index|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote|speechify-ignore|avatar|subscribe|newsletter|paywall|consent|cookie|toolbar|masthead|promo|share|sharing|widget|tooltip|dropdown|modal|overlay|backdrop|carousel|announcement|notification|toast|skip-link|screen-reader|(?<!not-)visually-hidden|(?<!not-)sr-only/i,
930
1916
  /** Rescues containers whose class merely happens to contain an unlikely substring. */
931
1917
  okMaybeItsaCandidate: /and|article|body|column|content|main|shadow|code|post|entry|story|markdown|prose|doc/i,
932
1918
  /** Very high-confidence boilerplate, not rescued by the clause above. */
@@ -1144,26 +2130,43 @@ var isUiChromeText = (text6) => {
1144
2130
  }
1145
2131
  return UI_PHRASES.has(normalized);
1146
2132
  };
2133
+ var CONSENT_PLACEHOLDER = /^(this content (isn['’]?t|is not) (visible|available) (due to|because of) your (cookie|privacy) (preferences|settings)|we need your (consent|permission) to load|to (view|see|load) this (content|embed|video|post)[, ]+(please )?(enable|accept|allow|update)|(please )?(accept|allow|enable) (all |marketing |functional )?cookies to (view|see|load|watch)|このコンテンツを表示するには.{0,30}(cookie|クッキー|同意|許可))/i;
2134
+ var MAX_CONSENT_PLACEHOLDER_LENGTH = 400;
2135
+ var isConsentPlaceholderText = (text6) => text6.length <= MAX_CONSENT_PLACEHOLDER_LENGTH && CONSENT_PLACEHOLDER.test(text6.trimStart());
1147
2136
 
1148
2137
  // src/extractors/lib/sanitize.ts
1149
2138
  var INVISIBLE_STYLE = /(^|;)\s*(display\s*:\s*none|visibility\s*:\s*hidden)\s*(;|$)/i;
1150
2139
  var hasHiddenClass = (element3) => {
1151
2140
  const classes = classList(element3);
1152
2141
  if (!classes.some((name) => HIDDEN_CLASS_NAMES.has(name))) {
1153
- return classes.some((name) => REGEXPS.hidden.test(name));
2142
+ return classes.some((name) => REGEXPS.hidden.test(name) || isScreenReaderOnlyClass(name));
1154
2143
  }
1155
2144
  return !classes.some((name) => RESPONSIVE_DISPLAY_OVERRIDE.test(name));
1156
2145
  };
2146
+ var SCREEN_READER_ONLY = /^(sronly|visuallyhidden|screenreader(only|text))(focusable|styles\w*)?$/;
2147
+ var isScreenReaderOnlyClass = (name) => {
2148
+ const first = name.charCodeAt(0) | 32;
2149
+ if (first !== 115 && first !== 118) {
2150
+ return false;
2151
+ }
2152
+ return SCREEN_READER_ONLY.test(name.toLowerCase().replace(/[-_]/g, ""));
2153
+ };
1157
2154
  var isNonContent = (node) => {
1158
2155
  if (node.type === "comment" || node.type === "doctype") {
1159
2156
  return true;
1160
2157
  }
1161
2158
  return isElement(node) && NON_CONTENT_TAGS.has(node.tagName);
1162
2159
  };
1163
- var isHidden = (element3) => {
2160
+ var isHidden = (element3, parent, siblingCode) => {
2161
+ if (!looksHidden(element3)) {
2162
+ return false;
2163
+ }
1164
2164
  if (containsMath(element3)) {
1165
2165
  return false;
1166
2166
  }
2167
+ return !isHiddenCodePanel(element3, parent, siblingCode);
2168
+ };
2169
+ var looksHidden = (element3) => {
1167
2170
  if (isTruthyAttribute(element3, "hidden")) {
1168
2171
  return true;
1169
2172
  }
@@ -1176,10 +2179,57 @@ var isHidden = (element3) => {
1176
2179
  }
1177
2180
  const width = numericProperty(element3, "data-rwidth");
1178
2181
  const height = numericProperty(element3, "data-rheight");
1179
- if (width === 0 && height === 0) {
2182
+ return width === 0 && height === 0;
2183
+ };
2184
+ var MAX_CODE_PANEL_PROSE = 200;
2185
+ var panelCode = (element3) => {
2186
+ let code = "";
2187
+ let prose = 0;
2188
+ const visit = (node, insideCode) => {
2189
+ for (const child of node.children) {
2190
+ if (child.type === "text") {
2191
+ if (insideCode) {
2192
+ code += child.value;
2193
+ } else {
2194
+ prose += child.value.trim().length;
2195
+ if (prose > MAX_CODE_PANEL_PROSE) {
2196
+ return false;
2197
+ }
2198
+ }
2199
+ } else if (isElement(child) && !visit(child, insideCode || child.tagName === "pre")) {
2200
+ return false;
2201
+ }
2202
+ }
1180
2203
  return true;
2204
+ };
2205
+ return visit(element3, element3.tagName === "pre") && code.trim().length > 0 ? code : void 0;
2206
+ };
2207
+ var visibleSiblingCode = (parent, cache) => {
2208
+ let codes = cache.get(parent);
2209
+ if (!codes) {
2210
+ codes = /* @__PURE__ */ new Set();
2211
+ for (const child of parent.children) {
2212
+ if (isElement(child) && !looksHidden(child)) {
2213
+ const code = panelCode(child);
2214
+ if (code !== void 0) {
2215
+ codes.add(code);
2216
+ }
2217
+ }
2218
+ }
2219
+ cache.set(parent, codes);
1181
2220
  }
1182
- return false;
2221
+ return codes;
2222
+ };
2223
+ var isHiddenCodePanel = (element3, parent, cache) => {
2224
+ const code = panelCode(element3);
2225
+ if (code === void 0) {
2226
+ return false;
2227
+ }
2228
+ const siblings = visibleSiblingCode(parent, cache);
2229
+ if (siblings.has(code)) {
2230
+ return false;
2231
+ }
2232
+ return stringProperty(element3, "role") === "tabpanel" || siblings.size > 0;
1183
2233
  };
1184
2234
  var PLACEHOLDER_IMAGE_SRC = /^data:image\/|^about:blank$|spacer\.gif$|blank\.(gif|png)$/i;
1185
2235
  var isPlaceholderImage = (element3) => {
@@ -1197,15 +2247,16 @@ var isPlaceholderImage = (element3) => {
1197
2247
  }
1198
2248
  return false;
1199
2249
  };
1200
- var hoistNoscriptImages = (tree) => {
1201
- const visit = (parent) => {
2250
+ var hoistNoscriptImages = (tree, onElement) => {
2251
+ const visit = (parent, depth) => {
1202
2252
  for (let index = 0; index < parent.children.length; index++) {
1203
2253
  const child = parent.children[index];
1204
2254
  if (!isElement(child)) {
1205
2255
  continue;
1206
2256
  }
1207
2257
  if (child.tagName !== "noscript") {
1208
- visit(child);
2258
+ onElement?.(child, depth, parent);
2259
+ visit(child, depth + 1);
1209
2260
  continue;
1210
2261
  }
1211
2262
  const hasImage = child.children.some(
@@ -1225,7 +2276,7 @@ var hoistNoscriptImages = (tree) => {
1225
2276
  }
1226
2277
  };
1227
2278
  if ("children" in tree) {
1228
- visit(tree);
2279
+ visit(tree, 0);
1229
2280
  }
1230
2281
  };
1231
2282
  var containsMath = (element3) => {
@@ -1240,12 +2291,15 @@ var containsMath = (element3) => {
1240
2291
  return false;
1241
2292
  };
1242
2293
  var stripNonContent = (tree) => {
1243
- hoistNoscriptImages(tree);
1244
- return pruneInPlace(tree, (node) => {
2294
+ const tabs = new CodeTabCollector((element3) => looksHidden(element3) || NON_CONTENT_TAGS.has(element3.tagName));
2295
+ hoistNoscriptImages(tree, (element3, depth, parent) => tabs.visit(element3, depth, parent));
2296
+ tabs.apply();
2297
+ const siblingCode = /* @__PURE__ */ new WeakMap();
2298
+ return pruneInPlace(tree, (node, parent) => {
1245
2299
  if (isNonContent(node)) {
1246
2300
  return false;
1247
2301
  }
1248
- if (isElement(node) && isHidden(node)) {
2302
+ if (isElement(node) && isHidden(node, parent, siblingCode)) {
1249
2303
  return false;
1250
2304
  }
1251
2305
  return true;
@@ -1272,32 +2326,32 @@ var findLandmarkChrome = (tree) => {
1272
2326
  visit(tree, 0, false);
1273
2327
  return chrome;
1274
2328
  };
1275
- var isUnlikelyCandidate = (element3) => {
2329
+ var unlikelyTier = (element3) => {
1276
2330
  if (element3.tagName === "article" || element3.tagName === "main" || element3.tagName === "body") {
1277
- return false;
2331
+ return void 0;
1278
2332
  }
1279
2333
  const role = stringProperty(element3, "role");
1280
2334
  if (role && UNLIKELY_ROLES.has(role)) {
1281
- return true;
2335
+ return "strong";
1282
2336
  }
1283
2337
  if (CHROME_TAGS.has(element3.tagName)) {
1284
- return true;
2338
+ return "strong";
1285
2339
  }
1286
2340
  const match = matchString(element3);
1287
2341
  if (REGEXPS.specialUnlikelyCandidates.test(match)) {
1288
- return true;
2342
+ return "strong";
1289
2343
  }
1290
2344
  for (const name of [...classList(element3), stringProperty(element3, "id") ?? ""]) {
1291
2345
  if (REGEXPS.stronglyUnlikely.test(name)) {
1292
- return true;
2346
+ return "strong";
1293
2347
  }
1294
2348
  }
1295
2349
  if (REGEXPS.unlikelyCandidates.test(match) && !REGEXPS.okMaybeItsaCandidate.test(match)) {
1296
- return true;
2350
+ return "weak";
1297
2351
  }
1298
- return false;
2352
+ return void 0;
1299
2353
  };
1300
- var findUnlikelyElements = (tree) => {
2354
+ var findUnlikelyElements = (tree, spareWeak) => {
1301
2355
  const landmarks = findLandmarkChrome(tree);
1302
2356
  const doomed = [];
1303
2357
  const visit = (node) => {
@@ -1308,7 +2362,15 @@ var findUnlikelyElements = (tree) => {
1308
2362
  if (!isElement(child)) {
1309
2363
  continue;
1310
2364
  }
1311
- if (landmarks.has(child) || isUnlikelyCandidate(child)) {
2365
+ if (landmarks.has(child)) {
2366
+ doomed.push(child);
2367
+ continue;
2368
+ }
2369
+ if (PREFORMATTED_TAGS.has(child.tagName)) {
2370
+ continue;
2371
+ }
2372
+ const tier = unlikelyTier(child);
2373
+ if (tier === "strong" || tier === "weak" && !spareWeak?.(child)) {
1312
2374
  doomed.push(child);
1313
2375
  continue;
1314
2376
  }
@@ -1347,14 +2409,14 @@ var collectPreformattedElements = (tree) => {
1347
2409
  return protectedElements;
1348
2410
  };
1349
2411
  var dropEmptyElements = (tree, collector) => {
1350
- const preformatted = collectPreformattedElements(tree);
2412
+ const preformatted2 = collectPreformattedElements(tree);
1351
2413
  const visit = (parent) => {
1352
2414
  for (let index = 0; index < parent.children.length; index++) {
1353
2415
  const child = parent.children[index];
1354
2416
  if (!isElement(child)) {
1355
2417
  continue;
1356
2418
  }
1357
- if (preformatted.has(child) || !DROP_WHEN_EMPTY_TAGS.has(child.tagName)) {
2419
+ if (preformatted2.has(child) || !DROP_WHEN_EMPTY_TAGS.has(child.tagName)) {
1358
2420
  visit(child);
1359
2421
  continue;
1360
2422
  }
@@ -1449,11 +2511,15 @@ var findCleanupTargets = (tree, collector) => {
1449
2511
  visit(child);
1450
2512
  continue;
1451
2513
  }
2514
+ if (LITERAL_TEXT_TAGS.has(child.tagName)) {
2515
+ collectButtons(child, doomed);
2516
+ continue;
2517
+ }
1452
2518
  if (isLinkOnlyBlock(child, collector)) {
1453
2519
  condemnLinkBlock(child, siblings, index, collector, doomed);
1454
2520
  continue;
1455
2521
  }
1456
- if (isMidArticleWidget(child)) {
2522
+ if (isMidArticleWidget(child, collector)) {
1457
2523
  doomed.push(child);
1458
2524
  continue;
1459
2525
  }
@@ -1494,15 +2560,53 @@ var countAnchors = (element3) => {
1494
2560
  }
1495
2561
  return count;
1496
2562
  };
1497
- var isMidArticleWidget = (element3) => {
2563
+ var LITERAL_TEXT_TAGS = /* @__PURE__ */ new Set(["code", "kbd", "samp", "var", "pre"]);
2564
+ var PREFORMATTED_TAGS = /* @__PURE__ */ new Set(["pre", "code"]);
2565
+ var collectButtons = (element3, into) => {
2566
+ for (const child of element3.children) {
2567
+ if (!isElement(child)) {
2568
+ continue;
2569
+ }
2570
+ if (child.tagName === "button") {
2571
+ into.push(child);
2572
+ continue;
2573
+ }
2574
+ collectButtons(child, into);
2575
+ }
2576
+ };
2577
+ var isMidArticleWidget = (element3, collector) => {
1498
2578
  if (element3.tagName === "form" || element3.tagName === "fieldset") {
1499
2579
  return true;
1500
2580
  }
1501
2581
  if (element3.tagName === "button") {
1502
2582
  return true;
1503
2583
  }
1504
- return isUiChromeText(elementText(element3));
2584
+ if (collector.metrics(element3).text > MAX_CONSENT_PLACEHOLDER_LENGTH) {
2585
+ return false;
2586
+ }
2587
+ const text6 = elementText(element3);
2588
+ return isUiChromeText(text6) || isConsentPlaceholderText(text6) && !hasBlockDescendant(element3);
1505
2589
  };
2590
+ var BLOCK_TAGS = /* @__PURE__ */ new Set([
2591
+ "p",
2592
+ "div",
2593
+ "section",
2594
+ "article",
2595
+ "figure",
2596
+ "figcaption",
2597
+ "blockquote",
2598
+ "ul",
2599
+ "ol",
2600
+ "table",
2601
+ "pre",
2602
+ "h1",
2603
+ "h2",
2604
+ "h3",
2605
+ "h4",
2606
+ "h5",
2607
+ "h6"
2608
+ ]);
2609
+ var hasBlockDescendant = (element3) => element3.children.some((child) => isElement(child) && (BLOCK_TAGS.has(child.tagName) || hasBlockDescendant(child)));
1506
2610
  var cleanContent = (tree, collector) => {
1507
2611
  const doomed = new Set(findCleanupTargets(tree, collector));
1508
2612
  if (doomed.size > 0) {
@@ -2097,11 +3201,177 @@ var runAdapters = (context, adapters = BUILTIN_ADAPTERS) => {
2097
3201
  } catch {
2098
3202
  return void 0;
2099
3203
  }
2100
- if (!extracted) {
2101
- return void 0;
3204
+ if (!extracted) {
3205
+ return void 0;
3206
+ }
3207
+ stripNonContent(extracted);
3208
+ return new MetricsCollector().textLength(extracted) >= MIN_ADAPTER_TEXT ? extracted : void 0;
3209
+ };
3210
+
3211
+ // src/extractors/lib/blocks.ts
3212
+ var BLOCK_TAGS2 = /* @__PURE__ */ new Set([
3213
+ "address",
3214
+ "article",
3215
+ "aside",
3216
+ "blockquote",
3217
+ "body",
3218
+ "caption",
3219
+ "center",
3220
+ "dd",
3221
+ "details",
3222
+ "dialog",
3223
+ "div",
3224
+ "dl",
3225
+ "dt",
3226
+ "fieldset",
3227
+ "figcaption",
3228
+ "figure",
3229
+ "footer",
3230
+ "form",
3231
+ "h1",
3232
+ "h2",
3233
+ "h3",
3234
+ "h4",
3235
+ "h5",
3236
+ "h6",
3237
+ "header",
3238
+ "hgroup",
3239
+ "hr",
3240
+ "html",
3241
+ "li",
3242
+ "main",
3243
+ "menu",
3244
+ "nav",
3245
+ "ol",
3246
+ "p",
3247
+ "pre",
3248
+ "section",
3249
+ "summary",
3250
+ "table",
3251
+ "tbody",
3252
+ "td",
3253
+ "tfoot",
3254
+ "th",
3255
+ "thead",
3256
+ "tr",
3257
+ "ul"
3258
+ ]);
3259
+ var SKIP_TAGS = /* @__PURE__ */ new Set(["script", "style", "noscript", "template", "svg", "math", "head", "title", "iframe"]);
3260
+ var collapse = (value) => value.replace(/\s+/g, " ");
3261
+ var segmentBlocks = (root, maxBlocks = 2e4) => {
3262
+ const blocks = [];
3263
+ let frame;
3264
+ const enter = (element3) => {
3265
+ frame = { element: element3, parent: frame, depth: (frame?.depth ?? 0) + 1 };
3266
+ };
3267
+ const leave = () => {
3268
+ frame = frame?.parent;
3269
+ };
3270
+ let text6 = "";
3271
+ let linkChars = 0;
3272
+ let links = 0;
3273
+ let images = 0;
3274
+ const flush = () => {
3275
+ const trimmed = text6.trim();
3276
+ if (frame && (trimmed.length > 0 || images > 0) && blocks.length < maxBlocks) {
3277
+ blocks.push({
3278
+ index: blocks.length,
3279
+ owner: frame.element,
3280
+ frame,
3281
+ text: trimmed,
3282
+ linkChars: Math.min(linkChars, trimmed.length),
3283
+ links,
3284
+ images
3285
+ });
3286
+ }
3287
+ text6 = "";
3288
+ linkChars = 0;
3289
+ links = 0;
3290
+ images = 0;
3291
+ };
3292
+ const visitInline = (node, inLink) => {
3293
+ if (node.type === "text") {
3294
+ const value = collapse(node.value);
3295
+ text6 += value;
3296
+ if (inLink) {
3297
+ linkChars += value.trim().length;
3298
+ }
3299
+ return;
3300
+ }
3301
+ if (!isElement(node)) {
3302
+ return;
3303
+ }
3304
+ visit(node, inLink);
3305
+ };
3306
+ const visit = (element3, inLink) => {
3307
+ const tag = element3.tagName;
3308
+ if (SKIP_TAGS.has(tag)) {
3309
+ return;
3310
+ }
3311
+ if (tag === "br") {
3312
+ text6 += " ";
3313
+ return;
3314
+ }
3315
+ if (tag === "img") {
3316
+ images += 1;
3317
+ return;
3318
+ }
3319
+ if (tag === "pre") {
3320
+ flush();
3321
+ enter(element3);
3322
+ text6 = preformatted(element3);
3323
+ flush();
3324
+ leave();
3325
+ return;
3326
+ }
3327
+ if (BLOCK_TAGS2.has(tag)) {
3328
+ flush();
3329
+ enter(element3);
3330
+ for (const child of element3.children) {
3331
+ visitInline(child, inLink);
3332
+ }
3333
+ flush();
3334
+ leave();
3335
+ return;
3336
+ }
3337
+ const isLink = tag === "a" && stringProperty(element3, "href") !== void 0;
3338
+ if (isLink) {
3339
+ links += 1;
3340
+ }
3341
+ for (const child of element3.children) {
3342
+ visitInline(child, inLink || isLink);
3343
+ }
3344
+ };
3345
+ if (isElement(root)) {
3346
+ visit(root, false);
3347
+ } else if ("children" in root) {
3348
+ for (const child of root.children) {
3349
+ visitInline(child, false);
3350
+ }
3351
+ flush();
3352
+ }
3353
+ return blocks;
3354
+ };
3355
+ var preformatted = (element3) => {
3356
+ let value = "";
3357
+ const walk2 = (node) => {
3358
+ if (node.type === "text") {
3359
+ value += node.value;
3360
+ } else if (isElement(node) && !SKIP_TAGS.has(node.tagName)) {
3361
+ for (const child of node.children) {
3362
+ walk2(child);
3363
+ }
3364
+ }
3365
+ };
3366
+ walk2(element3);
3367
+ return value;
3368
+ };
3369
+ var ancestorAt = (block, up) => {
3370
+ let current = block.frame;
3371
+ for (let step = 0; step < up && current; step++) {
3372
+ current = current.parent;
2102
3373
  }
2103
- stripNonContent(extracted);
2104
- return new MetricsCollector().textLength(extracted) >= MIN_ADAPTER_TEXT ? extracted : void 0;
3374
+ return current?.element;
2105
3375
  };
2106
3376
 
2107
3377
  // src/extractors/lib/score.ts
@@ -2329,6 +3599,588 @@ var climbToArticleBoundary = (top, candidates, context) => {
2329
3599
  return current;
2330
3600
  };
2331
3601
 
3602
+ // src/extractors/lib/block-features.ts
3603
+ var FEATURE_NAMES = [
3604
+ "bias",
3605
+ "logLen",
3606
+ "linkDensity",
3607
+ "logLinks",
3608
+ "hasImage",
3609
+ "textless",
3610
+ "punctDensity",
3611
+ "digitRatio",
3612
+ "sentenceEnds",
3613
+ "tag_p",
3614
+ "tag_li",
3615
+ "tag_cell",
3616
+ "tag_h1",
3617
+ "tag_h2_6",
3618
+ "tag_pre",
3619
+ "tag_div",
3620
+ "tag_dtdd",
3621
+ "tag_blockquote",
3622
+ "tag_figcaption",
3623
+ "in_nav",
3624
+ "in_header",
3625
+ "in_footer",
3626
+ "in_aside",
3627
+ "in_article",
3628
+ "in_main",
3629
+ "in_form",
3630
+ "in_table",
3631
+ "in_list",
3632
+ "role_chrome",
3633
+ "role_content",
3634
+ "cls_unlikely",
3635
+ "cls_positive",
3636
+ "cls_negative",
3637
+ "cls_strong",
3638
+ "cls_special",
3639
+ "cls_byline",
3640
+ "cls_comment",
3641
+ "landmark",
3642
+ "doom_strong",
3643
+ "doom_weak",
3644
+ "depth",
3645
+ "relPos",
3646
+ "relCharPos",
3647
+ "prev_logLen",
3648
+ "prev_linkDensity",
3649
+ "next_logLen",
3650
+ "next_linkDensity",
3651
+ "win_linkDensity",
3652
+ "win_logLen",
3653
+ "parent_linkDensity",
3654
+ "parent_logText",
3655
+ "gparent_linkDensity",
3656
+ "gparent_logText",
3657
+ "inTopCandidate",
3658
+ "candidateScore",
3659
+ "inTopSibling",
3660
+ "takumi_kept"
3661
+ ];
3662
+ var FEATURE_COUNT = FEATURE_NAMES.length;
3663
+ var PUNCT = /* @__PURE__ */ new Set([...".,;:!?\u3001\u3002\uFF0C\uFF0E\uFF01\uFF1F\uFF1B\uFF1A"]);
3664
+ var SENTENCE_END = /* @__PURE__ */ new Set([...".!?\u3002\uFF01\uFF1F"]);
3665
+ var textStats = (text6) => {
3666
+ let punct = 0;
3667
+ let digits = 0;
3668
+ let sentences = 0;
3669
+ for (let index = 0; index < text6.length; index++) {
3670
+ const char = text6[index];
3671
+ const code = text6.charCodeAt(index);
3672
+ if (code >= 48 && code <= 57) {
3673
+ digits += 1;
3674
+ } else if (PUNCT.has(char)) {
3675
+ punct += 1;
3676
+ const next = text6.charCodeAt(index + 1);
3677
+ if (SENTENCE_END.has(char) && (Number.isNaN(next) || next === 32 || next === 10 || code > 12288)) {
3678
+ sentences += 1;
3679
+ }
3680
+ }
3681
+ }
3682
+ return { punct, digits, sentences };
3683
+ };
3684
+ var COMMENT = /comment|disqus|reply|respond/i;
3685
+ var log1p = (value) => Math.log(1 + value);
3686
+ var signalsOf = (element3, cache) => {
3687
+ let signals = cache.get(element3);
3688
+ if (signals) {
3689
+ return signals;
3690
+ }
3691
+ const match = matchString(element3);
3692
+ const role = stringProperty(element3, "role") ?? "";
3693
+ const names = [...classList(element3), stringProperty(element3, "id") ?? ""];
3694
+ signals = {
3695
+ unlikely: REGEXPS.unlikelyCandidates.test(match) && !REGEXPS.okMaybeItsaCandidate.test(match),
3696
+ positive: REGEXPS.positive.test(match),
3697
+ negative: REGEXPS.negative.test(match),
3698
+ strong: names.some((name) => REGEXPS.stronglyUnlikely.test(name)),
3699
+ special: REGEXPS.specialUnlikelyCandidates.test(match),
3700
+ byline: REGEXPS.byline.test(match),
3701
+ comment: COMMENT.test(match),
3702
+ roleChrome: UNLIKELY_ROLES.has(role),
3703
+ roleContent: CONTENT_ROLES.has(role)
3704
+ };
3705
+ cache.set(element3, signals);
3706
+ return signals;
3707
+ };
3708
+ var SIGNAL_LEVELS = 6;
3709
+ var SIGNAL_COUNT = 9;
3710
+ var RowWriter = class {
3711
+ constructor(out) {
3712
+ this.out = out;
3713
+ this.offset = 0;
3714
+ }
3715
+ push(value) {
3716
+ this.out[this.offset++] = value;
3717
+ }
3718
+ flag(condition) {
3719
+ this.out[this.offset++] = condition ? 1 : 0;
3720
+ }
3721
+ };
3722
+ var EMPTY_CHAIN = {
3723
+ inNav: 0,
3724
+ inHeader: 0,
3725
+ inFooter: 0,
3726
+ inAside: 0,
3727
+ inArticle: 0,
3728
+ inMain: 0,
3729
+ inForm: 0,
3730
+ inTable: 0,
3731
+ inList: 0,
3732
+ landmark: 0,
3733
+ doomStrong: 0,
3734
+ doomWeak: 0,
3735
+ inTop: 0,
3736
+ inTopSibling: 0,
3737
+ nearestScore: 0,
3738
+ distance: new Array(SIGNAL_COUNT).fill(Number.POSITIVE_INFINITY)
3739
+ };
3740
+ var signalFlags = (signals) => [
3741
+ signals.roleChrome,
3742
+ signals.roleContent,
3743
+ signals.unlikely,
3744
+ signals.positive,
3745
+ signals.negative,
3746
+ signals.strong,
3747
+ signals.special,
3748
+ signals.byline,
3749
+ signals.comment
3750
+ ];
3751
+ var any = (parent, condition) => parent || condition ? 1 : 0;
3752
+ var ChainResolver = class {
3753
+ constructor(landmarks, candidateScore, parents, top) {
3754
+ this.landmarks = landmarks;
3755
+ this.candidateScore = candidateScore;
3756
+ this.parents = parents;
3757
+ this.top = top;
3758
+ }
3759
+ #chains = /* @__PURE__ */ new Map();
3760
+ #signals = /* @__PURE__ */ new WeakMap();
3761
+ /** Iterative, so a deeply nested page cannot exhaust the call stack. */
3762
+ resolve(frame) {
3763
+ const pending = [];
3764
+ let current = frame;
3765
+ let chain = EMPTY_CHAIN;
3766
+ while (current) {
3767
+ const memo = this.#chains.get(current.element);
3768
+ if (memo) {
3769
+ chain = memo;
3770
+ break;
3771
+ }
3772
+ pending.push(current);
3773
+ current = current.parent;
3774
+ }
3775
+ for (let index = pending.length - 1; index >= 0; index--) {
3776
+ chain = this.#derive(chain, pending[index].element);
3777
+ this.#chains.set(pending[index].element, chain);
3778
+ }
3779
+ return chain;
3780
+ }
3781
+ #derive(parent, element3) {
3782
+ const tag = element3.tagName;
3783
+ const tier = unlikelyTier(element3);
3784
+ const flags = signalFlags(signalsOf(element3, this.#signals));
3785
+ const top = this.top;
3786
+ const topParent = top ? this.parents.get(top) : void 0;
3787
+ return {
3788
+ inNav: any(parent.inNav, tag === "nav"),
3789
+ inHeader: any(parent.inHeader, tag === "header"),
3790
+ inFooter: any(parent.inFooter, tag === "footer"),
3791
+ inAside: any(parent.inAside, tag === "aside"),
3792
+ inArticle: any(parent.inArticle, tag === "article"),
3793
+ inMain: any(parent.inMain, tag === "main"),
3794
+ inForm: any(parent.inForm, tag === "form"),
3795
+ inTable: any(parent.inTable, tag === "table"),
3796
+ inList: any(parent.inList, tag === "ul" || tag === "ol"),
3797
+ landmark: any(parent.landmark, this.landmarks.has(element3)),
3798
+ doomStrong: any(parent.doomStrong, tier === "strong"),
3799
+ doomWeak: any(parent.doomWeak, tier === "weak"),
3800
+ inTop: any(parent.inTop, element3 === top),
3801
+ inTopSibling: any(
3802
+ parent.inTopSibling,
3803
+ topParent !== void 0 && element3 !== top && this.parents.get(element3) === topParent
3804
+ ),
3805
+ nearestScore: this.candidateScore.get(element3) ?? parent.nearestScore,
3806
+ distance: parent.distance.map((distance, signal) => flags[signal] ? 0 : distance + 1)
3807
+ };
3808
+ }
3809
+ };
3810
+ var evidence = (distance) => distance < SIGNAL_LEVELS ? 1 / (1 + distance) : 0;
3811
+ var writeText = (row, block, density) => {
3812
+ const length = block.text.length;
3813
+ const stats = textStats(block.text);
3814
+ row.push(1);
3815
+ row.push(log1p(length));
3816
+ row.push(density);
3817
+ row.push(log1p(block.links));
3818
+ row.flag(block.images > 0);
3819
+ row.flag(length === 0);
3820
+ row.push(length === 0 ? 0 : stats.punct / length);
3821
+ row.push(length === 0 ? 0 : stats.digits / length);
3822
+ row.push(log1p(stats.sentences));
3823
+ };
3824
+ var writeTag = (row, tag) => {
3825
+ row.flag(tag === "p");
3826
+ row.flag(tag === "li");
3827
+ row.flag(tag === "td" || tag === "th");
3828
+ row.flag(tag === "h1");
3829
+ row.flag(/^h[2-6]$/.test(tag));
3830
+ row.flag(tag === "pre");
3831
+ row.flag(tag === "div" || tag === "section");
3832
+ row.flag(tag === "dt" || tag === "dd");
3833
+ row.flag(tag === "blockquote");
3834
+ row.flag(tag === "figcaption");
3835
+ };
3836
+ var writeChain = (row, chain) => {
3837
+ for (const value of [
3838
+ chain.inNav,
3839
+ chain.inHeader,
3840
+ chain.inFooter,
3841
+ chain.inAside,
3842
+ chain.inArticle,
3843
+ chain.inMain,
3844
+ chain.inForm,
3845
+ chain.inTable,
3846
+ chain.inList
3847
+ ]) {
3848
+ row.push(value);
3849
+ }
3850
+ for (const distance of chain.distance) {
3851
+ row.push(evidence(distance));
3852
+ }
3853
+ row.push(chain.landmark);
3854
+ row.push(chain.doomStrong);
3855
+ row.push(chain.doomWeak);
3856
+ };
3857
+ var windowMeans = (textLen, density, index, radius) => {
3858
+ let link = 0;
3859
+ let len = 0;
3860
+ let size = 0;
3861
+ for (let near = Math.max(0, index - radius); near <= Math.min(textLen.length - 1, index + radius); near++) {
3862
+ link += density[near];
3863
+ len += log1p(textLen[near]);
3864
+ size += 1;
3865
+ }
3866
+ return [link / size, len / size];
3867
+ };
3868
+ var writeNeighbourhood = (row, index, textLen, density) => {
3869
+ const hasPrevious = index > 0;
3870
+ const hasNext = index < textLen.length - 1;
3871
+ row.push(hasPrevious ? log1p(textLen[index - 1]) : 0);
3872
+ row.push(hasPrevious ? density[index - 1] : 0);
3873
+ row.push(hasNext ? log1p(textLen[index + 1]) : 0);
3874
+ row.push(hasNext ? density[index + 1] : 0);
3875
+ const [windowLink, windowLen] = windowMeans(textLen, density, index, 2);
3876
+ row.push(windowLink);
3877
+ row.push(windowLen);
3878
+ };
3879
+ var writeContainers = (row, block, collector) => {
3880
+ for (const container of [ancestorAt(block, 1), ancestorAt(block, 2)]) {
3881
+ row.push(container ? collector.linkDensity(container) : 0);
3882
+ row.push(container ? log1p(collector.textLength(container)) : 0);
3883
+ }
3884
+ };
3885
+ var blockFeatures = ({ root, blocks, collector, lang, takumiKept }) => {
3886
+ const count = blocks.length;
3887
+ const out = new Float32Array(count * FEATURE_COUNT);
3888
+ const context = buildScoringContext(root, collector, lang);
3889
+ const candidates = scoreCandidates(root, context);
3890
+ const topScore = candidates[0]?.score ?? 1;
3891
+ const candidateScore = /* @__PURE__ */ new WeakMap();
3892
+ for (const candidate of candidates) {
3893
+ candidateScore.set(candidate.element, candidate.score / topScore);
3894
+ }
3895
+ const chains = new ChainResolver(findLandmarkChrome(root), candidateScore, context.parents, candidates[0]?.element);
3896
+ const textLen = blocks.map((block) => block.text.length);
3897
+ const density = blocks.map((block) => block.text.length === 0 ? 0 : block.linkChars / block.text.length);
3898
+ const totalChars = textLen.reduce((sum, length) => sum + length, 0) || 1;
3899
+ let charsBefore = 0;
3900
+ for (let index = 0; index < count; index++) {
3901
+ const block = blocks[index];
3902
+ const row = new RowWriter(out.subarray(index * FEATURE_COUNT, (index + 1) * FEATURE_COUNT));
3903
+ const chain = chains.resolve(block.frame);
3904
+ writeText(row, block, density[index]);
3905
+ writeTag(row, block.owner.tagName);
3906
+ writeChain(row, chain);
3907
+ row.push(Math.min(block.frame.depth, 40) / 40);
3908
+ row.push(count <= 1 ? 0 : index / (count - 1));
3909
+ row.push(charsBefore / totalChars);
3910
+ charsBefore += textLen[index];
3911
+ writeNeighbourhood(row, index, textLen, density);
3912
+ writeContainers(row, block, collector);
3913
+ row.push(chain.inTop);
3914
+ row.push(chain.nearestScore);
3915
+ row.push(chain.inTopSibling);
3916
+ row.flag(takumiKept?.has(block.owner));
3917
+ }
3918
+ return out;
3919
+ };
3920
+ var STACK_FEATURE_NAMES = [
3921
+ "s1_logit",
3922
+ "s1_win1",
3923
+ "s1_win3",
3924
+ "s1_parent",
3925
+ "s1_gparent",
3926
+ "s1_ggparent",
3927
+ "s1_parentShare",
3928
+ "s1_distHigh",
3929
+ "s1_docShare"
3930
+ ];
3931
+ var STACKED_FEATURE_COUNT = FEATURE_COUNT + STACK_FEATURE_NAMES.length;
3932
+ var logit = (p) => Math.log(Math.max(1e-6, p) / Math.max(1e-6, 1 - p));
3933
+ var ancestorMass = (blocks, probabilities) => {
3934
+ const mass = /* @__PURE__ */ new Map();
3935
+ const add = (element3, p, weight) => {
3936
+ if (!element3) {
3937
+ return;
3938
+ }
3939
+ const entry = mass.get(element3);
3940
+ if (entry) {
3941
+ entry.p += p * weight;
3942
+ entry.w += weight;
3943
+ } else {
3944
+ mass.set(element3, { p: p * weight, w: weight });
3945
+ }
3946
+ };
3947
+ let docP = 0;
3948
+ let docW = 0;
3949
+ for (const block of blocks) {
3950
+ const weight = block.text.length + 10;
3951
+ const p = probabilities[block.index];
3952
+ add(ancestorAt(block, 1), p, weight);
3953
+ add(ancestorAt(block, 2), p, weight);
3954
+ add(ancestorAt(block, 3), p, weight);
3955
+ docP += p * weight;
3956
+ docW += weight;
3957
+ }
3958
+ const parentWeightShare = (element3) => {
3959
+ const entry = element3 ? mass.get(element3) : void 0;
3960
+ return entry && docW > 0 ? entry.w / docW : 0;
3961
+ };
3962
+ return { mass, docShare: docW === 0 ? 0 : docP / docW, parentWeightShare };
3963
+ };
3964
+ var distanceToHigh = (probabilities) => {
3965
+ const count = probabilities.length;
3966
+ const distance = new Float32Array(count).fill(count);
3967
+ let last = -1;
3968
+ for (let index = 0; index < count; index++) {
3969
+ if (probabilities[index] >= 0.5) {
3970
+ last = index;
3971
+ }
3972
+ if (last >= 0) {
3973
+ distance[index] = index - last;
3974
+ }
3975
+ }
3976
+ last = -1;
3977
+ for (let index = count - 1; index >= 0; index--) {
3978
+ if (probabilities[index] >= 0.5) {
3979
+ last = index;
3980
+ }
3981
+ if (last >= 0) {
3982
+ distance[index] = Math.min(distance[index], last - index);
3983
+ }
3984
+ }
3985
+ return distance;
3986
+ };
3987
+ var stackedFeatures = (blocks, base, probabilities) => {
3988
+ const count = blocks.length;
3989
+ const stride = STACKED_FEATURE_COUNT;
3990
+ const out = new Float32Array(count * stride);
3991
+ const { mass, docShare, parentWeightShare } = ancestorMass(blocks, probabilities);
3992
+ const meanOf = (element3, fallback) => {
3993
+ const entry = element3 ? mass.get(element3) : void 0;
3994
+ return entry ? entry.p / entry.w : fallback;
3995
+ };
3996
+ const distance = distanceToHigh(probabilities);
3997
+ for (let index = 0; index < count; index++) {
3998
+ const row = index * stride;
3999
+ out.set(base.subarray(index * FEATURE_COUNT, (index + 1) * FEATURE_COUNT), row);
4000
+ const p = probabilities[index];
4001
+ const window = (radius) => {
4002
+ let sum = 0;
4003
+ let n = 0;
4004
+ for (let near = Math.max(0, index - radius); near <= Math.min(count - 1, index + radius); near++) {
4005
+ if (near !== index) {
4006
+ sum += probabilities[near];
4007
+ n += 1;
4008
+ }
4009
+ }
4010
+ return n === 0 ? p : sum / n;
4011
+ };
4012
+ const block = blocks[index];
4013
+ let f = row + FEATURE_COUNT;
4014
+ out[f++] = logit(p);
4015
+ out[f++] = window(1);
4016
+ out[f++] = window(3);
4017
+ out[f++] = meanOf(ancestorAt(block, 1), p);
4018
+ out[f++] = meanOf(ancestorAt(block, 2), p);
4019
+ out[f++] = meanOf(ancestorAt(block, 3), p);
4020
+ out[f++] = parentWeightShare(ancestorAt(block, 1));
4021
+ out[f++] = Math.log1p(distance[index]);
4022
+ out[f++] = docShare;
4023
+ }
4024
+ return out;
4025
+ };
4026
+
4027
+ // src/extractors/lib/block-model.ts
4028
+ var isUsableModel = (model, stride = FEATURE_COUNT) => {
4029
+ if (model.kind === "linear") {
4030
+ return model.weights.length === stride;
4031
+ }
4032
+ const internal = 2 ** model.depth - 1;
4033
+ const trees = model.features.length / internal;
4034
+ return Number.isInteger(trees) && trees > 0 && model.thresholds.length === model.features.length && model.leaves.length === trees * (internal + 1) && model.features.every((feature) => feature < stride);
4035
+ };
4036
+ var scoreBlocks = (features, count, model, stride = FEATURE_COUNT) => {
4037
+ const out = new Float32Array(count);
4038
+ if (model.kind === "linear") {
4039
+ const { weights } = model;
4040
+ for (let index = 0; index < count; index++) {
4041
+ const row = index * stride;
4042
+ let sum = 0;
4043
+ for (let feature = 0; feature < stride; feature++) {
4044
+ sum += weights[feature] * features[row + feature];
4045
+ }
4046
+ out[index] = 1 / (1 + Math.exp(-sum));
4047
+ }
4048
+ return out;
4049
+ }
4050
+ const internal = 2 ** model.depth - 1;
4051
+ const leafCount = internal + 1;
4052
+ const trees = model.features.length / internal;
4053
+ const { features: splitFeatures, thresholds, leaves, base } = model;
4054
+ for (let index = 0; index < count; index++) {
4055
+ const row = index * stride;
4056
+ let sum = base;
4057
+ for (let tree = 0; tree < trees; tree++) {
4058
+ const offset = tree * internal;
4059
+ let node = 0;
4060
+ while (node < internal) {
4061
+ const feature = splitFeatures[offset + node];
4062
+ node = feature < 0 || features[row + feature] <= thresholds[offset + node] ? 2 * node + 1 : 2 * node + 2;
4063
+ }
4064
+ sum += leaves[tree * leafCount + node - internal];
4065
+ }
4066
+ out[index] = 1 / (1 + Math.exp(-sum));
4067
+ }
4068
+ return out;
4069
+ };
4070
+
4071
+ // src/extractors/lib/block-model.generated.ts
4072
+ var BLOCK_MODEL = {
4073
+ kind: "trees",
4074
+ depth: 5,
4075
+ base: -0.422449,
4076
+ features: [56, 32, 53, 54, 51, 32, 2, 53, 3, 38, 12, 2, 49, 15, 3, 48, 51, 38, 47, 41, -1, 26, -1, 8, 23, 42, 12, 38, 6, 30, 6, 56, 32, 53, 54, 51, 32, 50, 47, 38, 38, 12, 51, 31, 38, 2, 42, 53, 25, -1, 40, -1, 35, -1, 15, 54, 49, 38, 49, -1, 30, 3, 56, 32, 53, 54, 47, 32, 15, 42, 49, 40, 12, 42, 37, 30, 6, 38, 8, 41, 6, 48, 38, 54, -1, 41, 47, 49, -1, 21, 50, 49, 50, 56, 32, 2, 38, 51, 50, 32, 54, 30, 38, 26, 37, 31, 6, 10, 7, 37, 47, -1, 41, -1, 35, 53, 42, -1, 15, 52, 31, 48, 40, -1, 56, 32, 6, 38, 47, 31, 21, 42, 53, 38, 12, 53, 38, 50, 55, 6, 54, -1, 54, 40, -1, 54, -1, 51, 52, 15, -1, 38, 25, -1, -1, 56, 32, 51, 54, 51, 15, 32, 8, 37, 38, 26, 21, 42, 42, 24, 53, 4, 27, -1, 41, -1, 35, 53, 30, -1, 6, 50, 48, 42, 12, 54, 56, 38, 53, 37, 53, 42, 50, 49, 12, 16, 47, 41, 54, 47, 15, 25, 32, -1, -1, -1, 51, 54, -1, 23, 38, 54, 41, 48, 32, 30, 50, 56, 38, 48, 37, 53, 42, 2, 27, 12, 16, 47, 38, 47, 39, 3, 42, 53, -1, -1, -1, 48, 28, -1, 47, 41, 53, 32, 21, 31, 49, -1, 56, 38, 48, 37, 53, 31, 8, 3, 12, 16, 47, 53, 42, 3, 30, 54, 32, -1, -1, -1, 43, 54, -1, 24, 41, 15, 47, 15, 48, 42, 45, 56, 38, 6, 42, 53, 38, 50, 6, 40, 16, 28, 31, 32, 37, 31, 32, 42, 48, 54, -1, -1, 48, 51, 40, 47, -1, -1, 42, -1, 52, 2, 38, 53, 24, 37, 15, -1, 32, 3, 12, 48, 43, -1, -1, 47, 28, 42, 31, -1, -1, 47, 11, 40, 2, -1, -1, -1, -1, -1, -1, 43, -1, 38, 48, 47, 42, 31, 24, -1, 37, 32, 50, 8, -1, 32, -1, -1, 49, 12, 54, 40, 42, 52, 3, 7, -1, -1, 52, -1, -1, -1, -1, -1, 38, 6, 24, 12, 41, 23, 32, 32, 41, 48, 32, -1, -1, 51, 41, 42, 40, -1, 42, 54, 2, 7, 24, -1, -1, -1, -1, -1, -1, 40, 30, 38, 31, 32, 32, 49, 51, -1, 25, 31, 48, 42, 24, -1, -1, -1, 43, 41, 45, 47, 25, 41, 40, 52, 45, 48, -1, -1, -1, -1, -1, -1, 37, 2, 12, 23, 30, -1, -1, 43, 30, 13, 12, -1, -1, -1, -1, 32, 41, 51, 32, 45, 54, 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, 45, 24, 37, 42, 23, 32, 42, 12, 25, 43, -1, -1, 51, 41, 31, 52, -1, -1, 11, 54, 24, 40, -1, -1, -1, -1, -1, -1, 40, 30, 38, 21, 53, 45, 35, -1, 32, 23, 11, -1, 52, -1, -1, 41, 28, 42, 42, 40, 42, -1, -1, -1, -1, -1, -1, -1, -1, 54, 54, -1, -1, 32, 6, 47, 25, 50, 40, 54, 12, 31, 42, 40, 52, 38, 1, 51, 47, 41, 40, 51, 43, 47, 8, -1, 42, 9, 21, 28, -1, -1, -1, -1, 37, 30, 12, 42, 48, -1, -1, 41, 41, 12, 31, -1, -1, -1, -1, 54, 8, 47, 24, 51, -1, 1, 47, -1, -1, -1, -1, -1, -1, -1, -1, 38, 12, 24, 48, 41, -1, 47, 47, 31, -1, 41, -1, -1, 48, 41, 25, 40, 39, 8, -1, -1, 1, -1, -1, -1, -1, -1, -1, 40, -1, -1, 37, 45, 12, 32, 30, -1, -1, 15, 40, 46, 3, -1, -1, -1, -1, 48, 50, 52, 31, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 37, 12, 12, 6, 41, -1, -1, 42, 42, -1, 41, -1, -1, -1, -1, 7, 30, 30, 43, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, 42, 47, 42, 41, 32, 52, 43, 25, 26, 24, 54, 30, -1, -1, 7, 25, 2, 6, 54, 48, 52, 52, 1, -1, -1, -1, -1, -1, -1, -1, 37, 12, 12, 47, 41, 13, -1, 43, 7, -1, 41, -1, -1, -1, -1, 43, 25, 48, 42, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, 30, 53, 21, 31, 51, 41, 23, 55, 7, 43, 39, -1, 28, 54, 52, 30, -1, -1, 50, -1, 1, 52, 42, -1, -1, -1, -1, -1, 40, -1, 42, 42, 40, 54, 12, 52, 53, 45, 2, 38, 1, 55, 47, 54, 45, -1, 40, 31, 7, 30, 47, -1, 49, 40, -1, 43, -1, 51, -1, -1, 43, 37, 45, 12, 15, 42, 47, -1, 44, 40, 1, 40, -1, -1, -1, -1, 48, 40, 31, 4, 46, 40, 1, 50, -1, -1, -1, -1, -1, -1, -1, -1, 31, 50, 40, 53, 40, 52, 54, 54, 47, 49, 52, 41, 3, 54, 52, 32, 4, 42, 40, -1, -1, -1, -1, 4, 42, 31, -1, 50, 51, 42, 3, 21, 12, 55, 43, 41, 50, 54, 30, 1, -1, 40, -1, -1, -1, -1, 40, 40, 26, 40, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 25, 49, 31, 36, 30, 50, 49, 42, 32, 40, 47, 7, 40, 26, 42, 42, 31, -1, 41, 24, 40, -1, 52, 54, 48, 24, -1, 51, -1, -1, -1, 42, 41, 52, 54, 54, 40, 47, 13, 48, 32, 54, 55, 47, 54, 51, 24, -1, 52, 6, 48, 56, 51, 48, 42, -1, 54, 53, 52, 52, -1, -1, 21, 7, 55, 52, 48, -1, 54, 7, 47, -1, 52, -1, -1, -1, -1, 49, 1, 30, -1, -1, -1, 31, 45, -1, -1, -1, -1, -1, -1, -1, -1, 12, 38, 41, 7, 53, -1, 49, 25, 48, 24, 41, -1, -1, 42, -1, 30, 31, -1, 52, -1, 42, 54, 54, -1, -1, -1, -1, -1, 48, -1, -1, 37, 20, 12, 15, 27, 47, -1, 52, 1, 51, 10, -1, -1, -1, -1, 48, 30, 54, 7, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 42, 21, 40, 40, 35, 52, 53, 42, 52, -1, -1, 8, 47, 54, 54, 7, 54, 52, -1, -1, -1, -1, -1, 42, -1, 6, -1, 24, -1, -1, 48, 45, 3, 40, 26, 26, 50, 40, 25, 1, 8, -1, -1, 52, 50, 50, 42, 39, 40, 47, 51, 54, -1, -1, -1, -1, -1, -1, 46, 10, 46, 9, 23, 41, 30, 8, 41, 2, 32, 13, -1, 38, 24, 48, 53, 24, 56, 24, -1, -1, -1, 51, 28, 42, 32, 42, 31, 1, 7, -1, -1, 49, 41, 12, 47, 1, 51, 40, 54, 49, 52, 54, 50, 54, -1, -1, 41, -1, 40, 54, 40, 1, 7, 51, 54, 29, -1, -1, -1, -1, 41, -1, -1, -1, 37, 20, 51, 7, 27, 54, -1, 52, 52, 51, 47, -1, -1, -1, -1, 52, 47, 48, 40, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 37, 1, 25, 47, 54, 46, 47, 31, -1, -1, -1, -1, 41, -1, 41, 40, 50, 49, -1, -1, -1, -1, -1, -1, -1, -1, -1, 42, -1, -1, 41, 49, 42, 42, 29, 23, 51, 52, 47, 48, -1, 47, 30, 31, 1, 50, 8, 51, 7, 52, 31, -1, -1, 40, 7, 3, 49, 1, 40, 43, 54, 40, 40, 52, 54, 1, 52, -1, 50, 24, -1, 52, 45, 2, -1, -1, 48, 40, 54, 51, -1, -1, -1, -1, 31, 46, -1, -1, -1, -1, -1, -1, 7, 7, 48, 41, 1, -1, 52, 8, 51, 42, -1, -1, -1, 52, 40, 13, 26, 42, 32, 40, 50, -1, -1, -1, -1, -1, -1, 9, 50, -1, -1, 12, 42, 1, 40, 54, 54, 46, 7, -1, 11, 54, -1, -1, 41, -1, -1, -1, -1, -1, 31, 51, 51, 51, -1, -1, -1, -1, -1, 42, -1, -1, 45, 32, 40, 15, 40, 6, 31, 52, 50, 32, 31, 31, -1, 50, 52, 48, 48, 45, 40, 42, 51, 31, 54, 47, 1, -1, -1, 49, 49, 46, 1, 40, 52, 52, 52, 31, 48, -1, 40, 54, 26, 51, 6, 44, -1, -1, 52, 51, 42, 42, 40, -1, 2, 52, 48, -1, 42, -1, -1, -1, -1, -1, 21, 12, 7, 45, 1, 39, -1, 30, 50, 54, 49, -1, -1, -1, -1, 52, 40, 48, 40, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, 41, 54, 48, 51, 51, 48, 15, -1, 42, 56, -1, 55, 10, 51, -1, -1, -1, -1, 48, 31, 43, 43, -1, -1, -1, -1, 8, 54, 2, 54, 30, 47, 31, 54, 7, 40, 43, 50, 51, 41, 50, 51, 50, 47, 31, 30, 40, 52, 1, 40, 24, 6, 42, 54, -1, -1, -1, -1, -1, -1, -1, 21, 7, 55, 19, 56, 50, -1, 52, -1, 54, 9, -1, -1, -1, -1, 52, 30, -1, -1, -1, 48, 45, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29, 42, 40, 8, 41, 1, 39, 7, 6, 47, 51, -1, -1, 1, 54, 40, 1, 30, 41, 52, 56, 26, 40, -1, -1, -1, -1, 54, 6, -1, -1, 40, 52, 39, 52, 31, 46, 52, 40, 47, 9, 36, 42, -1, 56, -1, 40, 50, 48, 47, 26, 41, 23, 49, -1, -1, -1, -1, -1, -1, -1, -1, 12, 5, 48, 48, 11, -1, 42, 1, 11, 40, 54, -1, -1, 41, 41, 40, -1, 48, 48, 48, 54, -1, 47, -1, -1, -1, -1, -1, -1, -1, 45, 54, 50, 54, 50, 50, 51, 52, 56, 32, 31, 56, 46, 55, 40, 51, 47, 43, 48, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 11, 31, 32, 47, 25, 1, 52, 7, 51, 51, 31, 40, 9, 6, 52, 52, 42, 54, 24, 45, 50, 40, 1, -1, 50, -1, 48, 40, 45, 47, 1, 27, 3, 50, 38, 40, 49, 48, 39, 31, -1, 54, 7, 1, 52, 41, 39, -1, -1, 51, 54, 23, 51, -1, 42, 56, -1, 32, -1, 54, -1, -1, -1, -1, -1, 42, 21, 31, 41, 30, 50, 40, 51, 51, 40, -1, 54, 53, 50, 47, 40, 40, 40, 41, -1, -1, -1, -1, 32, 1, 54, 45, -1, 50, -1, -1, 12, 42, 48, 43, 42, -1, 2, 7, 6, 50, 16, -1, -1, 40, -1, 45, -1, 54, -1, 52, 54, 40, 54, -1, -1, -1, -1, 42, -1, -1, -1, 25, 47, 6, 41, 40, 31, 48, 56, 40, 40, 51, 1, 26, 7, 31, 54, 15, 45, 52, 7, 51, 56, 52, 54, 9, 50, -1, -1, -1, -1, 7, 54, 23, 54, 31, 51, 51, 52, 32, 11, -1, -1, 46, 55, 40, 42, 43, -1, 30, 42, -1, -1, -1, -1, -1, -1, -1, -1, 41, 11, 41, 43, 12, 38, 41, 5, 53, 46, 1, 48, 11, 6, 41, 52, -1, -1, -1, 40, 11, 32, 40, 31, -1, 54, 54, -1, -1, -1, -1, -1, -1, -1, -1, 30, 32, 31, 47, 51, 40, 43, 54, 1, 40, 2, 52, 1, 48, 52, 40, 27, 24, 51, 52, 31, -1, -1, -1, 48, -1, -1, -1, -1, -1, -1, 37, 20, 51, 31, 27, 42, -1, 52, 40, 54, -1, -1, -1, -1, -1, 40, 52, 8, 48, 51, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, 50, 54, 42, 50, 15, 48, 41, 31, 49, 56, 53, 24, 54, 54, 48, 40, 43, 51, -1, -1, -1, -1, -1, 52, -1, 43, -1, 50, 42, 52, 42, 45, 12, -1, 54, 1, 42, -1, -1, 50, -1, 11, 48, 43, 41, -1, -1, -1, -1, -1, -1, -1, -1, 42, 40, 51, 11, -1, -1, -1, 45, 30, 25, 41, 50, 31, 31, 43, 8, 2, 1, 51, 54, 42, 42, 40, 40, 31, 51, 51, 54, 51, 6, -1, 41, -1, -1, -1, -1, -1, -1, -1, 41, 49, 42, 42, 42, 29, 41, 26, 47, -1, 53, 23, 1, 48, 41, 8, 52, 54, 47, -1, -1, 48, 51, 32, 49, 44, -1, 26, 26, 26, 24, 29, 42, 40, 7, 41, 1, 39, 44, 47, 47, 16, -1, -1, 50, 42, 41, 23, 45, 54, 40, 50, 54, 54, -1, -1, -1, -1, 44, 43, -1, -1, 7, 7, 52, 6, 1, 52, 40, 1, 54, 42, 48, 31, 49, -1, -1, 49, 48, 51, 7, 40, 47, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 54, 50, 54, 52, 50, 2, 56, 42, 15, 49, 51, 50, 51, 55, 53, 43, 43, 48, -1, -1, -1, -1, -1, -1, -1, 44, -1, 52, 54, 54, 54, 41, 13, 51, 2, 47, 51, 50, 40, 7, 42, -1, 40, 27, 32, 32, 41, 15, 23, 54, 45, -1, -1, -1, 20, 54, 40, 29, 56, 52, 40, 52, 21, 12, 7, 42, 41, -1, 47, 40, 1, 46, 1, -1, -1, -1, -1, 52, -1, 11, 1, 52, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 25, 30, 6, 50, 54, 40, 48, 32, 7, 49, -1, 9, 52, 7, 31, 52, 51, 30, -1, 52, -1, -1, -1, 1, 51, -1, -1, -1, -1, -1, 7, 48, 3, 56, 48, 42, 41, 41, 54, 51, 40, 27, 54, 47, 54, 24, -1, 42, 51, -1, -1, -1, 50, 49, 32, 54, -1, 3, 46, 40, 42, 42, 15, 44, 47, 31, 1, 45, 54, 45, 56, 40, 40, 51, 8, 50, 53, 50, 52, 40, 42, 47, 1, 54, 51, 31, 54, 1, 40, 56, -1, 51, -1, 37, 20, 51, 54, 27, 42, -1, 23, 54, 1, -1, -1, -1, -1, -1, 31, 45, 15, 54, 41, 54, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, 51, 52, 54, 42, -1, 31, 47, 24, 43, 31, -1, -1, 47, 40, 8, 40, 53, 6, -1, 7, 40, 3, -1, -1, -1, -1, 41, -1, -1, 45, 21, 12, 7, 33, 41, -1, 54, 41, -1, 46, 1, -1, -1, -1, -1, 40, 40, -1, -1, 52, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 52, 26, 52, 43, 51, -1, 52, 40, 30, 2, 6, 41, -1, -1, 52, 26, 47, 39, 49, -1, -1, -1, 44, 2, -1, -1, -1, -1, -1, -1, 40, 43, 40, 48, 43, 41, 52, 42, 45, 45, 40, 43, 30, 30, 52, 1, 54, -1, 42, 50, 52, 31, 43, 24, 50, 7, -1, 52, 40, 1, 31, 25, 36, 7, 32, 32, 2, 48, 32, 40, 50, 41, 9, 26, 15, 1, 16, 47, 41, 54, -1, -1, -1, -1, 54, 39, -1, -1, -1, -1, 51, 7, 21, 42, 55, 41, 51, 52, -1, 24, 24, 51, 42, -1, -1, -1, -1, 54, 54, 1, 47, 54, 50, 41, 50, -1, -1, -1, -1, -1, -1, -1, -1, 54, 50, 54, 42, 45, 51, 52, 41, 31, -1, 31, -1, -1, 54, 42, 31, 39, 43, 51, -1, -1, -1, -1, -1, -1, -1, -1, 54, 31, 47, 16, 6, 6, 51, 29, 47, 45, 56, 42, 40, 47, 1, 43, 54, 52, 45, 8, 14, -1, 39, 32, 43, 7, 40, -1, -1, 54, 48, -1, 41, 54, -1, 7, 47, 1, 40, 54, 32, 48, 40, 48, 53, 53, 13, 54, 41, 43, 52, 50, 48, 54, 27, 24, 23, 48, 40, 54, 3, 41, -1, 15, 40, 2, 41, 40, 49, 40, 48, 26, 1, 52, 52, 40, 47, 51, 41, 24, 39, 31, 25, 51, -1, 24, 52, 52, -1, 31, 16, 1, 1, 40, 54, 52, 53, 52, 52, 51, 40, 10, 52, 54, 2, 1, 50, -1, 54, 31, -1, 1, 52, 40, 3, 54, 31, 41, -1, -1, 44, 41, 9, 51, -1, -1, -1, -1, 12, 5, 42, 48, 11, 41, 41, 51, 11, 31, 40, 52, -1, -1, -1, 1, -1, 1, 48, 40, 30, 54, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, 23, 54, 45, 40, 51, 6, 55, 41, -1, -1, -1, -1, 6, 51, 6, -1, 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, 48, 45, 56, 7, 31, 1, 41, 40, 47, 6, 6, 50, 54, 52, 47, 52, -1, 7, 49, 43, 26, 51, 52, 30, -1, -1, 49, 54, 43, 54, -1, -1, 32, -1, 12, 33, 30, 42, -1, 52, -1, 51, 1, -1, -1, 54, 43, -1, -1, 54, -1, 11, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 42, 50, 41, 13, 8, 47, 52, 9, 47, 50, 39, 52, 11, 30, 30, 31, 40, 2, -1, 3, 49, 40, -1, -1, -1, 54, -1, 32, 40, 24, 51, 12, 33, 42, 41, -1, 41, 44, 47, 37, -1, -1, 31, -1, 45, -1, -1, 7, 42, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, 50, 54, 52, 50, 2, 30, 48, 48, 52, 51, -1, 51, 48, 41, 42, 41, 42, 56, -1, -1, -1, -1, -1, -1, -1, -1, 10, 48, 1, 50, 7, 55, 1, 50, 54, 49, 48, 40, 30, 24, 52, 24, 1, 41, 43, 41, 54, -1, -1, 52, 51, -1, 43, 45, 54, 40, 8, -1, 45, 45, 54, 42, 41, 29, 52, -1, 41, 31, 50, 32, -1, -1, 6, 8, 24, -1, 54, 47, 43, 54, -1, -1, -1, -1, 45, 51, 52, 43, 54, 45, -1, -1, 54, 54, 24, 52, 26, 52, 8, 52, 51, 52, 45, 8, 40, 51, 41, 50, 39, 25, 52, 42, 40, -1, 42, 31, 45, 47, 25, 44, 48, -1, -1, 50, 43, 40, 8, 39, 43, 2, 40, 43, 23, 6, 51, 49, 42, 40, 1, 1, 2, 1, 47, -1, -1, -1, 9, 3, 44, 47, 7, 32, 51, -1, 19, 42, -1, 41, 40, -1, -1, 40, 49, 51, 47, -1, -1, -1, -1, 40, 26, 1, 45, 49, 53, 50, 52, -1, -1, -1, -1, -1, -1, -1, -1, 51, 52, 52, 51, 54, 42, 2, 31, 40, 52, 47, 7, 3, 47, 48, 52, 54, 50, 50, 40, 7, 51, 50, 31, 45, 49, 40, -1, -1, -1, -1, 12, 33, 42, 42, -1, 41, 41, 51, 5, -1, -1, 52, -1, -1, -1, 41, -1, 48, 11, -1, -1, -1, -1, 51, -1, -1, -1, -1, -1, -1, -1, 1, 8, 7, 3, 40, 45, 50, 45, 32, 50, 48, 26, 48, -1, -1, 51, 43, -1, -1, 27, 52, -1, -1, 49, 43, 7, 31, -1, -1, -1, -1, 12, 37, 6, 41, 47, 43, -1, 52, 7, -1, -1, 51, -1, -1, -1, -1, 52, 15, 1, -1, -1, -1, -1, -1, 51, -1, -1, -1, -1, -1, -1, 50, 48, 40, 50, 41, 24, 40, 52, 27, -1, 52, 44, 42, 1, 31, 40, 54, 40, 54, -1, -1, -1, 31, 43, 40, 23, -1, 31, 6, 41, 41, 21, 12, 55, 47, 6, 52, -1, 24, 40, 31, -1, -1, -1, -1, -1, 15, 54, 40, 51, -1, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 43, 48, 8, 52, 45, 1, 46, 52, 51, 40, 31, 54, 46, 40, -1, 52, 40, 42, -1, -1, -1, 43, 50, 40, 47, -1, -1, 48, 54, -1, -1, 52, 52, 43, 43, 6, 49, 2, 50, 39, 51, 52, 40, -1, -1, -1, 14, 8, 45, 27, -1, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30, 25, 45, 31, 31, 41, 1, 3, 56, 42, 41, 31, -1, -1, 48, 53, 26, 52, 55, 41, 7, 40, 1, -1, -1, -1, -1, -1, -1, 45, -1, 19, 42, -1, 35, 29, -1, -1, 13, 41, 40, 49, -1, -1, -1, -1, 29, 30, 15, -1, 32, 53, 54, 47, -1, -1, -1, -1, -1, -1, -1, -1, 54, 23, 54, 11, 40, 48, 54, 31, 50, -1, -1, 24, 53, 10, 35, 32, 30, -1, -1, -1, -1, -1, -1, -1, 31, 3, 52, 26, 52, 47, 1, 42, 45, 42, -1, 52, 51, 41, -1, -1, -1, -1, 7, 52, 40, 51, -1, -1, -1, -1, -1, -1, -1, -1, 10, 51, 24, -1, 52, 54, 49, 27, 52, 52, 11, 32, 43, 51, 50, 32, 47, 48, 23, 47, 39, 49, 8, 52, 40, 48, 40, -1, 48, 6, 40, 54, 51, 48, -1, 42, 48, 53, -1, 51, 27, 40, 20, 1, 46, 52, 42, 1, 1, 9, -1, 42, 53, 52, 52, 7, -1, 40, 52, 50, 6, -1, -1, -1, -1, -1, 24, 50, 47, -1, 41, 43, 42, 43, 52, -1, 42, 13, 48, 49, -1, -1, -1, 29, 41, 1, 45, 50, 2, 54, -1, -1, -1, -1, -1, -1, -1, 1, 1, 51, 14, 50, 50, 40, 16, 54, 31, 40, 48, 53, 7, 1, 31, 42, 54, 24, 8, 41, 31, 43, 45, -1, -1, -1, 40, 31, 54, 24, 42, 1, 9, -1, 6, 6, 51, 47, 47, 45, 27, 40, 23, 47, 1, 43, 54, 50, 43, 6, 6, 40, 31, 50, 48, 7, 41, -1, -1, 54, 48, 53, -1, -1, -1, 21, 12, 7, 38, 41, -1, -1, 7, 24, 47, 42, -1, -1, -1, -1, 7, 45, 32, 54, 45, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30, 25, 31, 50, 43, 40, 43, 50, 42, 13, 26, 54, 1, -1, 52, 50, 6, 54, -1, 54, -1, 9, 1, 53, -1, -1, -1, -1, -1, -1, -1, 54, 50, 54, 31, 50, 2, 47, 31, 48, -1, 41, -1, 46, 47, 26, 42, -1, 52, 41, -1, -1, -1, 56, -1, -1, -1, -1, 50, 45, 40, 7, 41, 52, 42, 48, 45, -1, 42, -1, -1, 31, 45, -1, -1, 51, 51, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 48, 52, 51, 40, 30, 47, 46, 24, 40, 40, -1, 15, 54, 40, 51, 36, 43, -1, -1, 50, 50, 54, 40, 51, 52, 9, 46, 54, -1, -1, -1, -1, -1, -1, -1, 6, 6, 51, 52, 47, 43, 27, 52, 40, 47, 1, 32, 46, 44, 43, 52, 47, 31, -1, 52, 48, 52, 52, 41, -1, -1, -1, 40, -1, -1, -1, 54, 53, 35, 47, 47, 41, 6, 54, 4, 54, 48, 26, 7, -1, -1, 54, 51, 11, 45, 54, 31, -1, -1, 52, 50, 32, 46, -1, -1, -1, -1, 42, 41, 24, 24, 24, 50, 41, 54, 39, 40, 50, 54, 54, 52, 42, 53, 54, 6, 52, 32, 48, 54, 31, 52, 48, 40, 49, 39, 40, 54, 48, 54, 40, 54, 50, -1, 2, 48, 41, 50, -1, -1, -1, 46, 39, 48, 42, -1, -1, 42, -1, -1, -1, -1, -1, -1, -1, -1, 31, -1, 43, 40, 45, 1, 45, 6, 43, 31, 48, 50, 51, 24, 7, 41, 39, 2, 31, 50, 43, 6, 6, 40, 50, 48, -1, 48, 52, 52, 32, 45, 51, 3, 49, 21, 42, 7, 41, 31, -1, -1, 42, 2, 52, 41, -1, -1, -1, -1, 25, 7, 24, 50, 54, 51, 52, 49, -1, -1, -1, -1, -1, -1, -1, -1, 47, 52, 48, 43, 52, 8, 3, 39, 31, 48, 51, 1, 31, 54, 40, 52, 42, 24, 7, 49, 54, 40, 1, 32, 40, 40, 51, 54, 50, 46, -1, 12, 38, 42, 1, 31, 41, 44, 11, 1, 41, 50, 52, -1, -1, -1, 42, 42, 54, 52, 32, -1, -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, 37, 54, 54, 6, 54, -1, -1, 1, 7, 40, 31, -1, -1, -1, -1, 50, 56, -1, -1, 47, 50, 53, 40, -1, -1, -1, -1, -1, -1, -1, -1, 50, 48, 40, 16, 41, 31, 40, 42, 52, -1, 52, 31, 41, 1, 24, 23, 40, 42, 51, -1, -1, -1, 31, 40, 45, 8, 24, 31, 6, 53, -1, 12, 38, 42, 1, 52, 41, 41, 11, 1, 54, -1, 52, -1, -1, -1, 54, 42, 52, 41, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, 55, 1, 44, 54, 40, 48, 25, 54, 2, 47, 1, 50, 8, 43, 50, 42, 43, 41, 43, -1, 54, 52, 7, 7, 1, 54, -1, -1, 41, 54],
4077
+ thresholds: [0, 0, 0, 0.1651376, 0.1222076, 0, 0.4375, 0, 0, 0, 0, 0.2533333, 0.04799343, 0, 1.098612, 4.153444, 0.9995694, 0, 0.2428571, 0.7044025, 0, 0, 0, 0.6931472, 0, 0.5077296, 0, 0, 0, 0, 0.02316602, 0, 0, 0, 0.3807987, 0.09414381, 0, 5.57973, 0.3230769, 0, 0, 0, 0.3636364, 0.2, 0, 0.5827814, 0.735, 0, 0, 0, 0.2, 0, 0, 0, 0, 0.2781682, 0, 0, 0.2517483, 0, 0.25, 1.098612, 0, 0, 0, 0.1493049, 0.3230769, 0, 0, 0.7175612, 0.68, 0.275, 0, 0.4674693, 0, 0, 0.01591512, 0, 1.386294, 0.9088849, 0.04255319, 4.559038, 0, 0.6849968, 0, 0.09111514, 0.07707246, 0.04799343, 0, 0, 6.186209, 0.1234112, 10.24495, 0, 0, 0.2533333, 0, 0.1222076, 6.186209, 0, 923186e-8, 0.5, 0, 0, 0, 0, 0.01219512, 0, 0.1875, 0, 0.1655462, 0, 0.7829458, 0, 0, 0, 0.7175612, 0, 0, 0, 0.2, 2.649369, 0.25, 0, 0, 0, 0, 0, 0.3230769, 0.2, 0, 0.7683557, 0, 0, 0, 0, 0, 6.478509, 0, 0.01219512, 0.2781682, 0, 0.7836897, 0.275, 0, 0.6849968, 0, 0.2993237, 7.920083, 0, 0, 0, 0, 0, 0, 0, 0, 0.1966292, 0.06774194, 0.1578185, 0, 0, 1.386294, 0, 0, 0, 0, 0.6257396, 0.4674693, 0, 0, 0, 0, 0, 0.6886503, 0, 0, 0, 0.1666667, 0, 0.01591512, 7.698483, 2.163539, 0.8172206, 0, 0.1935484, 0, 0, 0, 0, 0, 0.4674693, 5.57973, 0.08144234, 0, 0, 0.1655462, 0.09111514, 0.6849968, 0.03896104, 0, 0, 0, 0, 0, 0, 0.6842105, 0.09378118, 0, 0, 0, 4077529e-10, 0.8929385, 1.098612, 0.1666667, 0.5, 10.24495, 0, 0, 3.853134, 0, 0, 0.7175612, 0.75, 0, 0, 0, 0.1655462, 0, 0.1655462, 0, 1.098612, 0.6057872, 0, 0, 0, 0, 2.223656, 0.25, 0, 5405406e-9, 0.8773364, 0, 0.1666667, 0, 0, 0.3408666, 0, 0, 0, 3.38491, 0, 0, 0.2, 0, 0, 0, 0, 0.1655462, 0, 0.566474, 1.098612, 0.2, 0.3807987, 0, 0, 0, 0, 1.791759, 0.7836897, 0, 0, 0.7987013, 0, 0.03896104, 0, 3.711259, 0.5859071, 3.465736, 0, 0, 0, 0.7683557, 0, 0, 6.343881, 0.01219512, 0.225, 0, 0.25, 0, 0.1666667, 0, 0, 0, 0.3702046, 4.559038, 0.07975792, 0, 0, 3.590021, 0.09414381, 0.2, 5405406e-9, 0, 0, 0.8172206, 0, 7.698029, 0.4375, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.470899, 2.639057, 0, 0, 0.1655462, 0.25, 0.8010488, 0.25, 0, 0, 0.07707246, 0, 0.225, 0.75, 0, 0, 0, 0, 0, 0, 0.6931472, 0, 0, 4.001706, 0.07707246, 0.6257396, 0.1666667, 0, 0, 0, 0, 5.57973, 0, 0, 0.25, 0, 0, 0.68, 0, 0.5889103, 0.275, 0.7175612, 7.698029, 1.098612, 0.05263158, 0, 0, 5.278115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.9245283, 0, 0, 0, 0.01279318, 4.327618, 0, 0, 0, 0.1578185, 0.7514793, 0.04676814, 0.25, 0, 0.735, 0.2781682, 0.75, 0.05263158, 0, 0, 0, 0, 0, 0, 0, 0.325, 0.2, 0, 0.2, 0, 0, 0.1234112, 0.2429577, 0, 0, 0, 3.853134, 0.7848276, 0, 0, 0, 0, 2.944439, 0.7358209, 4.859812, 0.5458733, 0, 0.8773364, 0.15, 7.920083, 2.995732, 2.589959, 0, 0, 0, 0, 0, 0, 0, 0.2533333, 0, 0, 0, 0, 0, 2.397895, 0, 0, 0, 0, 0, 0, 0, 0.1666667, 0.9245283, 0.4859494, 0.3333333, 4.859812, 0.06774194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.859812, 0, 0, 0.5859071, 0, 0, 0.8896571, 0, 0, 4.110874, 0, 0, 0.0494359, 0.7358209, 0.2, 6.660575, 0, 0, 0, 0.1765268, 0, 0.225, 0, 0, 0, 0, 0, 0, 0.325, 0.2, 0, 0, 0, 4.859812, 0, 0, 0.1666667, 0, 0, 0, 5.278115, 0, 0, 0.6415094, 0.2, 0.01820779, 0.5077296, 0.475, 0.1913043, 0, 0, 0, 0, 0, 0, 0, 0, 0.1146875, 0.7836897, 0, 0, 0.1666667, 0.01219512, 0.7, 0, 6.620073, 0.15, 0.6849968, 0, 0.3333333, 0.7175612, 0.525, 6.349139, 0, 0.6931472, 0, 0.07707246, 0.02836879, 0.325, 0.2429577, 0.6931472, 0.1655462, 0, 0, 0.2786465, 0, 0, 0.2, 0, 0, 0, 0, 0, 0, 0, 0.4674693, 4.327618, 0, 0, 0.09111514, 0.9716312, 0, 0.2, 0, 0, 0, 0, 0.3807987, 1.098612, 0.1655462, 0, 0.1966292, 0, 4.859812, 0.07707246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.001706, 0.01279318, 0, 0.07707246, 0.2, 0.25, 0, 0.8460699, 0, 0, 2.560159, 0.7358209, 0, 0.15, 0, 0, 0, 0, 2.079442, 0, 0, 0, 0, 0, 0, 0.2, 0, 0, 0, 4.110874, 0, 0, 0.5, 0, 0, 0, 0.2, 0.9814815, 0, 0, 0, 0, 0, 1.277376, 0, 6.028278, 0, 0, 0.05263158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.01279318, 0, 0, 0.0700191, 0.4674693, 0, 0.8460699, 0, 0, 0, 0, 0.05263158, 0, 0.5, 0.6931472, 0, 0, 2.484907, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5859071, 0.2, 0.01820779, 0.9245283, 0, 2.833213, 1.609438, 0, 0, 0, 0.5889103, 0, 0, 0, 0.05263158, 0, 0.05882353, 0.01591512, 0.6849968, 1.098612, 6.224558, 6.760415, 3.7612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.03896104, 0.01279318, 0, 0, 1.098612, 0, 0, 0.8616044, 0, 0, 0, 0, 0, 0, 4.153444, 0.4878399, 0, 0, 2.484907, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0, 0.3333333, 0.6842105, 0.6729858, 0, 0, 0.09302326, 2.890372, 0, 0, 0.25, 0.7836897, 7.920083, 0, 0, 0, 0, 0, 2.302585, 7.698029, 0.7520133, 0, 0, 0, 0, 0, 0.25, 0, 0.8896571, 0.01820779, 0.25, 0.3807987, 0, 6.907755, 0, 2.772589, 0, 0, 2.079442, 0, 0.5458733, 0.5889103, 1.098612, 0, 0.2, 0.3333333, 0, 0.5, 0.2, 0, 0.9102251, 0.225, 0, 5.231109, 0, 0.06930693, 0, 0, 4.110874, 0, 4.859812, 0, 0, 0.6057872, 0, 0, 0.2115385, 0.125, 3.258096, 0.225, 0, 0, 0, 0, 1.277376, 0.1, 0.3333333, 0, 0, 0.375, 4.007333, 8.007034, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7.251345, 0.075, 0, 0.125, 8.091627, 923186e-8, 0, 0.7, 0.0346841, 7.698029, 0.8460699, 0.6931472, 0, 9.083983, 0, 0, 0.3341523, 0.25, 0, 0, 0, 0, 0, 0.5077296, 0.3333333, 0, 3.78419, 0.8297873, 0.3341523, 0, 0, 0, 0, 2.639057, 0.04424779, 6.343881, 0.2978621, 0, 4.859812, 0, 0.1, 0, 0, 0, 0, 0.15, 0.275, 0, 0.375, 0, 0, 0, 2.302585, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.08144234, 0.3333333, 0, 0.25, 5.686975, 0, 0.4095238, 0.3333333, 0.15, 0.03896104, 0, 0.3, 0, 0.260274, 3111111e-9, 0, 0, 0.72, 0, 0.275, 0, 3.526361, 0.07347349, 2.331571, 0, 0, 0, 0, 0, 0, 0.8896571, 0.09111514, 6.660575, 0.3807987, 0, 0.25, 0.5458733, 0, 2.649369, 0.2, 923186e-8, 0, 0.3230769, 0.2781682, 0.9007138, 0, 0, 5.693732, 0.03703704, 1.098612, 0, 0.8297873, 2.252276, 0.9029938, 0, 0.898181, 0, 8.091627, 7.698029, 0, 0, 0, 0.75, 0, 9.083983, 1.098612, 0, 0.3309545, 0.09302326, 0.8, 0, 6.55108, 0, 0, 0, 0, 0.1234112, 4.859812, 0, 0, 0, 0, 0, 2.639057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.04424779, 0.75, 0, 0, 0.8974359, 0, 1.098612, 0, 0.6415094, 0, 0, 0.5275567, 0, 0.5, 0.3333333, 0, 6.55108, 0, 0.644637, 0.0542577, 0.7836897, 0, 0, 0, 0, 0, 2.792088, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.836282, 0, 0.8297873, 0, 0, 0, 0, 0, 1.579311, 0.5, 0.0600245, 0, 2.302585, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.8896571, 0, 0.25, 0.475, 0, 6.907755, 0, 0.02698599, 8.2933, 0, 0, 1.098612, 0.5458733, 0.5889103, 0.1935484, 0, 0, 6.55108, 0, 0, 0, 0, 0, 0.9029938, 0, 0, 0, 0, 0, 0, 2.719441, 4.110874, 1.098612, 0.075, 0, 0, 4.430817, 0.225, 0, 1.098612, 0.6931472, 0, 0, 6.55108, 6.478509, 7.251345, 0.5077296, 0, 0.275, 0.976508, 0.9521739, 0.2781682, 0, 0, 0, 0, 0, 0, 0.04643963, 0, 0.7142857, 0, 0, 0.09111514, 0, 1.386294, 0.9245283, 0.75, 0.2, 0, 0, 0, 0, 2.825013, 0, 0, 0, 0, 0, 0, 0, 0.9698997, 0.25, 0.2428695, 0.1666667, 0.4486312, 0.1666667, 3.7612, 0.01111111, 0, 0, 0.04799343, 0.5785877, 0, 0, 2.484907, 0, 0.15, 0.1355838, 0.9102251, 8.091627, 0.4973886, 6.186209, 0.01857929, 0, 0, 0.8143564, 0, 0.275, 0.4324605, 0.225, 2.772589, 0, 0.9007138, 0, 0, 0, 0, 0, 0, 0.0754717, 0, 0, 0, 0, 0, 0, 0.75, 0, 0.1935484, 0, 9.083983, 6.55108, 0.8297873, 0.5948718, 0, 0, 0, 0, 8.501063, 0.8, 1.098612, 0.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.484907, 0, 0, 0.1355838, 0.9814815, 0.3230769, 0.3333333, 0, 0, 0, 0, 0.0754717, 0, 0.8301887, 0.275, 5.686975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5275567, 0, 0, 0.2485207, 0.9102251, 0.3341523, 0.2254693, 0, 0, 0.9995694, 5.521461, 5405406e-9, 1.783998, 0, 0.7846154, 0, 0.2, 2.397895, 5.17615, 1.098612, 0, 0.1875, 6.028278, 0, 0, 0, 0.125, 0.05263158, 0.6931472, 0, 0, 0.275, 2.397895, 5396655e-9, 0.475, 0.45, 8.2933, 0.6849968, 2.995732, 6.55108, 0, 7.251345, 0, 0, 5.857933, 1.098612, 0.05882353, 0, 0, 4.559038, 0.2, 0.898181, 0.9908676, 0, 0, 0, 0, 0.1666667, 0.2093023, 0, 0, 0, 0, 0, 0, 0.75, 0.1875, 1.098612, 0.2485207, 4.859812, 0, 6.55108, 1.098612, 0.9521739, 0.3894129, 0, 0, 0, 4.644391, 0.2, 0, 0, 0.3341523, 0, 0.325, 4.143135, 0, 0, 0, 0, 0, 0, 0, 4.624973, 0, 0, 0, 3111111e-9, 2.484907, 0.2, 0, 0.1355838, 0.9814815, 0.07142857, 0, 0, 5396655e-9, 0, 0, 0.0754717, 0, 0, 0, 0, 0, 0.1666667, 0.2993237, 0.621134, 0.9521739, 0, 0, 0, 0, 0, 0.5275567, 0, 0, 3.465736, 0, 0.075, 0, 0.25, 0.05, 0.25, 4.574711, 0, 0.3333333, 0.5, 0, 0, 8.007034, 6.349139, 1.676732, 3.172406, 0, 0.125, 0.3523154, 0, 0, 0.7836897, 0.1655462, 3.258096, 0, 0, 5307856e-9, 5307856e-9, 0, 2.944439, 0.475, 7.698029, 8.2933, 7.257003, 0.2, 2.923849, 0, 0.15, 0.1355838, 0, 0.7972973, 0.04255319, 0.5555556, 0, 0, 6.224558, 0.7972973, 0.1264647, 0.6819527, 0.125, 0, 0.4375, 10.0538, 1.494614, 0, 0.7520133, 0, 0, 0, 0, 0, 0, 0, 0.07142857, 2.564949, 2.484907, 0, 0, 0, 7.251345, 0.1355838, 0.9102251, 0, 0, 0, 0, 7.553287, 0.275, 4.559038, 0.225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.1856436, 5396655e-9, 2.19474, 0.9007138, 0.621134, 2.252276, 0, 0, 0.4486312, 0, 0, 0, 0, 0.4210526, 0, 0, 0, 0, 1.494614, 0.25, 1.609438, 2.197225, 0, 0, 0, 0, 0, 0.898181, 0, 0.898181, 0.5, 0, 0.3333333, 0.5889103, 0, 0.225, 2.890372, 7.017506, 0, 0.5, 5.252274, 0.1578185, 2.772589, 0.2, 0.5, 0.2, 0.275, 8.091627, 2.833213, 0.15, 0, 0.1111111, 0.260274, 0.5889103, 0, 0, 0, 0, 0, 0, 0, 0, 0.75, 0, 0, 0, 6.186209, 0, 9.083983, 0, 0.1651376, 0, 0, 0, 0, 0, 8.501063, 0, 0, 0, 0, 1.494614, 2.772589, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.3341523, 0.1, 1.098612, 0.3113497, 3.401197, 0, 0.05263158, 0.08333334, 5405406e-9, 0.9698997, 0, 0, 2.484907, 0.07347349, 0.125, 4.859812, 0.5, 0.6886503, 4.836282, 0, 0, 0.225, 0, 0, 0, 0, 0.5889103, 0.03191489, 0, 0, 0.525, 7.553287, 0, 7.257003, 0.2, 0.2093023, 8.2933, 0.375, 0.4, 0, 0, 0.4878399, 0, 0, 0, 0.35, 6.620073, 4.559038, 0.5948718, 0, 0.8301887, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.735862, 1.098612, 0, 0, 0.2428695, 2.639057, 0, 0.075, 0.01857929, 0, 0, 0.0754717, 0.5628141, 0.175, 0, 2.683568, 2.792088, 1.579311, 0.04629841, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3.091043, 0, 4.356709, 5396655e-9, 3.258096, 5.686975, 0.7972973, 4.41884, 0, 0.2, 0, 0, 0, 0, 0.175, 0.9698997, 0.03896104, 1.94591, 2.252276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.639057, 0, 0.25, 0, 0, 0, 2.484907, 5.693732, 0, 0.4210526, 0.4210526, 0.3333333, 0.225, 0, 0.01219512, 6.55108, 7.920083, 0.1264647, 0.04629841, 0, 2.397895, 5.17615, 0.275, 3.401197, 0, 6.052089, 0, 2.560159, 0.25, 2.397895, 0.4, 5.733341, 0, 0, 6.343881, 0, 0.525, 0.814433, 4.559038, 0, 0.2, 0, 0, 0, 1.609438, 8.2933, 0.7358209, 0, 0, 0, 0.9995694, 5396655e-9, 0, 0, 0, 0.4674693, 0, 0, 0, 0, 0.2781682, 0, 0, 0, 0, 0, 0.8896571, 0, 0.3333333, 0.5315315, 0.1666667, 4.007333, 0.3, 0.8297873, 0.9521739, 0.175, 0, 0.3309545, 0, 6.186209, 0.2, 0.1, 0.275, 0.4, 0.6886503, 0, 0, 0, 0, 0, 2.197225, 0.1255986, 1.098612, 0, 7.470224, 0, 0, 0, 0.02698599, 1.735862, 2.484907, 0.735, 0, 0.4375, 0.09302326, 0.03191489, 8.669914, 0, 0, 0, 0.225, 0, 3.367296, 0, 0.1493049, 0, 7.257003, 0.5889103, 0.25, 0.2781682, 0, 0, 0, 0, 0.4878399, 0, 0, 0, 0, 0.3230769, 0.02702703, 0.8301887, 0.275, 0.3333333, 2.331571, 0, 0.25, 0.2, 580011e-8, 3.555348, 0, 0.1875, 0.1666667, 0.898181, 0, 3.871201, 5.361292, 0, 0.9995694, 0, 7.920083, 0.2781682, 0, 5.252274, 0, 0, 0, 0, 0.01111111, 0, 0, 5396655e-9, 0.1666667, 0.1578185, 0.7972973, 4.41884, 0, 0, 0, 0, 0, 0, 0.175, 0.6257396, 1.098612, 0, 0.1666667, 0.1913043, 0, 0, 0, 0, 0, 0, 0, 0, 0.7358209, 0, 0.8301887, 0.6931472, 0, 0, 0.2955975, 0, 0, 0.9814815, 2.639057, 1.277376, 0, 0.02702703, 0.6415094, 4.41884, 0, 0, 0, 0.2, 0, 0.5, 0.2, 0.5, 0, 0.08483563, 0.7836897, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0.5, 0.3333333, 0, 0.6842105, 0.225, 2.890372, 0.5889103, 2.302585, 0.15, 0.5827814, 5.768321, 2.302585, 2.719441, 7.698029, 0.275, 0, 0, 0.4210526, 7.095064, 0.5, 0, 0, 0, 3.112789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0.2428695, 0, 7.257003, 0.425, 0.1012539, 0, 0, 0, 0, 0, 0.375, 7.553287, 0, 2.560159, 0.2993237, 2.302585, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.356709, 923186e-8, 0.7175612, 5.686975, 0, 2.252276, 0.5471264, 0.25, 0.04799343, 0, 0, 0, 0.01857929, 0.01183109, 2.19474, 0.275, 2.995732, 0.2993237, 0, 0, 0, 0, 0, 5.129899, 0, 2.397895, 0, 5.252274, 0.2786465, 8.501063, 3111111e-9, 1.791759, 0, 0, 0.3807987, 0, 0.2428695, 0, 0, 4.143135, 0, 0, 1.098612, 2.772589, 0.5315315, 0, 0, 0, 0, 0, 0, 0, 0, 0.4486312, 0.2, 0, 0, 0, 0, 0, 2.890372, 0.5, 0, 0.5471264, 6.478509, 0.3333333, 0.3333333, 2.833213, 0, 0.05882353, 3.663562, 0.2429577, 0.2978621, 0.1913043, 0.566474, 0.2, 0.125, 0.5, 0, 0.4859494, 0.2781682, 0.5546955, 0.01923077, 0, 0.3270142, 0, 0, 0, 0, 0, 0, 0, 0.2485207, 0.9102251, 0.3702046, 0.1913043, 0.08259411, 0.2, 0.5, 0, 5405406e-9, 0, 0, 0, 4.110874, 2.683568, 0.9716312, 1.098612, 5.521461, 0.6849968, 0.425, 0, 0, 1.960601, 0.9521739, 0.1666667, 0.6, 0.5555556, 0, 0, 0, 0, 0, 0, 0.5077296, 0.1, 0, 0.4055944, 3.401197, 0, 0.4375, 0.2428571, 0.07707246, 0, 0, 0, 3.555348, 0.566474, 0.7672956, 0, 2.302585, 0.3807987, 0.275, 3.637586, 0.6849968, 0.2781682, 0, 0, 0, 0, 0.2115385, 4.394449, 0, 0, 0.75, 0.1875, 6.55108, 0.1111111, 4.859812, 4.836282, 0.2, 2.995732, 0.2228809, 0.3894129, 3.711259, 0.5, 0.7526882, 0, 0, 0.3408666, 1.386294, 0.2429577, 0, 0.275, 0.8556951, 0, 0, 2.302585, 0, 1.94591, 0, 0, 0, 0, 0, 0, 4.356709, 5396655e-9, 3.637586, 5.686975, 0.5827814, 0, 0.7175612, 0, 0.04799343, 0.9007138, 4.691348, 0.9844254, 0, 0, 2.079442, 2.890372, 2.252276, 0, 0, 0, 0, 0, 0, 0, 0.9047619, 0, 4.644391, 0.3807987, 0.898181, 0.0600245, 0.2485207, 0, 0.9698997, 0.75, 0.7, 0.6842105, 3.931826, 0.3, 0.1875, 0.2428695, 0, 0.275, 0, 0.3333333, 0, 0.09111514, 0, 0, 0.2228809, 3.555348, 0, 0, 0, 0, 0.1651376, 0.25, 0, 0, 3.526361, 0.275, 4.41884, 0, 0, 0.03149606, 3111111e-9, 0.2955975, 0, 0.38, 0.2, 0, 0.9, 2.639057, 0, 0, 0, 0, 0, 0, 0, 0.6931472, 4.41884, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0.02702703, 8.669914, 0.898181, 0.4, 2.331571, 0.5, 0.03149606, 0.08144234, 0, 0, 5.438079, 0.1875, 0.1666667, 8.501063, 0.6842105, 0.1666667, 0, 5.9428, 0, 0, 0, 4.234107, 0.01565826, 0, 0, 0, 0, 0, 0.01111111, 1.579311, 0, 0, 0.5278115, 0.1745893, 0.9245283, 0.8929385, 0.0600245, 0.4210526, 0.25, 0, 0.04975546, 0.38, 4077529e-10, 0, 0, 0.3160217, 0, 0, 0, 0, 4.691348, 0.3408666, 0, 0.898181, 0, 0, 0, 0.375, 0.566474, 0.9160967, 0, 0.2115385, 0.7846154, 0.5, 5.733341, 3.988984, 0.3807987, 0.6931472, 0, 0.1, 0.225, 0.8793104, 0.6931472, 5.924256, 0, 6.052089, 7.257003, 0.275, 0.3523154, 0.5458733, 1.94591, 0.2228809, 0.2993237, 0.5, 0.01183109, 3.89182, 0.275, 0, 0, 0.9324324, 0, 0, 0, 0, 0, 0, 0.2088739, 0, 0, 923186e-8, 2.833213, 0, 0, 0, 0, 0, 0.1666667, 2.197225, 0, 0.08483563, 0.3113497, 0.1012539, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.9995694, 3.367296, 0.6849968, 0.1745893, 0, 0.2, 0.6141758, 0, 0, 0.5, 0, 0, 0.5458733, 0.15, 1.098612, 0.1, 0, 0, 0, 0.1176471, 0.3, 0, 0, 0, 0, 0, 0.7358209, 0, 0, 4.110874, 0, 0, 0.03149606, 0, 0.2955975, 0, 0.5889103, 0.5315315, 0, 0.9, 2.639057, 0, 0, 0, 0, 0.4, 0.4, 0, 0, 4.41884, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.098612, 9.083983, 0, 8.501063, 3.73767, 0.9324324, 0, 7.698029, 0.225, 0, 0.2533333, 0.01219512, 0.5315315, 0, 0, 7.257003, 0, 0.07707246, 0, 0.0346841, 0, 0, 0, 0.4375, 0.5827814, 0, 0, 0, 0, 0, 0, 0.35, 1.94591, 0.375, 3.590021, 2.079442, 0.5471264, 6.55108, 0.566474, 3.637586, 1.94591, 0.075, 1.098612, 0.1666667, 0, 8.2933, 5.733341, 0.6849968, 0, 0.4486312, 3.367296, 6.660575, 0, 2.302585, 0, 3.433987, 0.25, 0, 5.9428, 0.45, 1.94591, 0.25, 0, 0, 0.01111111, 0.3333333, 0.3333333, 0.5827814, 2.331571, 0.1666667, 0.175, 5.459586, 0.72, 0, 0, 0, 4.859812, 0, 0.5948718, 0.6886503, 0.08483563, 0, 0, 0, 0, 0.07347349, 0, 0, 0, 0, 0, 580011e-8, 0.05263158, 0, 0.8896571, 0, 0.6571429, 0.1222076, 6.224558, 0, 0, 0, 0.01565826, 0.941459, 0, 0, 0, 0, 0.04975546, 0.7836897, 3.465736, 0, 0.3309545, 7.470224, 0.8773364, 6.186209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.356709, 3187076e-9, 0.7175612, 2.564949, 0.5546955, 4.41884, 0.5471264, 0.25, 0, 0, 0, 0, 0.4324605, 0.6257396, 0.5, 0, 2.944439, 0.2993237, 0, 0, 0, 0, 0, 0, 0, 0, 0.02871578, 0.25, 0.4651163, 0, 0.1111111, 0.06896552, 0.1578185, 0, 0.1655462, 2.079442, 0, 0.3341523, 0.1, 0.03896104, 4.61512, 2.397895, 0.2002174, 4.912655, 3.135494, 1.098612, 0, 0, 0, 0.1666667, 2.833213, 0.3333333, 0.225, 0, 0, 0.1146875, 2.923849, 0, 0.5315315, 0.6849968, 0, 0.03149606, 0.3230769, 5.236442, 0.275, 0.3807987, 0.5, 3.302175, 0.225, 4.919404, 0, 0, 0, 0.1765268, 0.4055944, 2.833213, 5.768321, 5.924256, 2.560159, 0.5889103, 0, 0, 0, 1.611032, 0.1, 0.06774194, 0, 0.8143564, 0, 0, 0.25, 0, 0.5315315, 0.4, 0.9495798, 0.3, 2.589959, 0, 2.397895, 3.7612, 8.2933, 0.475, 0.5458733, 0.1578185, 0.7987013, 0, 0, 0, 0, 0.01565826, 0, 0, 3.044523, 4.983607, 0, 0.2, 0, 1.098612, 3.555348, 0.1, 0.07347349, 8.501063, 0, 7.257003, 7.095064, 0.9698997, 0.15, 0, 7.553287, 0.03330147, 0, 5.733341, 6.052089, 0, 0.1255986, 0.2, 0, 1.609438, 4.912655, 0.1, 0, 0.5889103, 0.25, 0.3584906, 0, 0, 0.9047619, 0.8143564, 0, 0.1578185, 0, 0, 0, 0, 0, 0, 0.2428695, 1.098612, 0, 0.1856436, 0.5944056, 0, 0, 0, 0.275, 4.356709, 0, 0, 0, 1.098612, 0, 3.89182, 2.792088, 0.275, 0.1666667, 0.4324605, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3187076e-9, 2.564949, 0.2, 0.5546955, 0.1111111, 0, 0.9245283, 0, 0, 0, 0, 0.06896552, 0.1578185, 0.02702703, 0, 0.3333333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.1, 2.331571, 1.609438, 0, 0.09302326, 0.5, 4.859812, 0.3270142, 0.425, 0.976508, 0.03191489, 0.03191489, 3.637586, 0.3807987, 5.609472, 0.4651163, 4.836282, 0, 0.1875, 0.04799343, 4.234107, 0, 0.9521739, 6.133398, 0, 0, 0, 0.6, 0.2978621, 1.609438, 0.01857929, 0, 0, 0, 0, 0, 0, 0, 3111111e-9, 0, 4.770685, 0, 0.06930693, 0, 0, 0, 0.07975792, 2.772589, 0, 0, 0.3807987, 0, 0, 0.6931472, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.3341523, 6.620073, 0.3113497, 0, 1.098612, 5405406e-9, 5.9428, 0, 0.7846154, 7.017506, 0, 5.521461, 0, 0, 0.2, 0.1666667, 0.15, 0.2533333, 0, 0, 0.1234112, 0.3, 0, 0, 0, 0.1765268, 0, 0.3333333, 0.25, 0, 0.1966292, 0, 0, 0.2428695, 0.02836879, 0, 0.1856436, 0.4375, 0.07707246, 0, 0, 0, 0.25, 0, 2.302585, 0, 0, 0.1551724, 0.1109164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.356709, 5396655e-9, 2.079442, 5.686975, 0.5827814, 0.5, 2.683568, 2.223656, 4.983607, 0.9007138, 0, 0.9844254, 0.5278115, 0.72, 0.1264647, 0.9245283, 0.7848276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.277376, 2.564949, 5.17615, 0.03149606, 0, 5.236442, 8.669914, 0.5889103, 0.4180328, 3.302175, 0.075, 0.1666667, 0, 4.356709, 0, 3.465736, 0.4055944, 2.833213, 0.5471264, 0.4324605, 0, 0, 7.257003, 0.1222076, 0, 3.988984, 1.791759, 0.7836897, 0.1, 0, 0, 1.609438, 2.302585, 0.1146875, 0.5077296, 0.9088849, 0, 4.836282, 0, 0.5785877, 0.5, 4.691348, 0.25, 0, 0, 0.03191489, 0, 0, 0, 0.4324605, 0, 4.394449, 0.1012539, 0, 0, 0, 0, 3.555348, 0.6842105, 0, 4.110874, 0.6849968, 3.135494, 0, 0, 0.6849968, 0.4324605, 0, 6.133398, 0, 8.091627, 0.6931472, 5.768321, 580011e-8, 4.836282, 0.6931472, 1.098612, 0.15, 0.4210526, 0.2641791, 5.252274, 0, 0, 7.920083, 0.1264647, 0.225, 0, 0.1913043, 0.25, 2.944439, 0.1655462, 0, 0.04545455, 2.683568, 0, 0, 6.343881, 5.231109, 0.175, 0, 0, 3.367296, 0.2533333, 0.125, 3.637586, 0, 0.01591512, 0.03852465, 0.2517483, 0.3341523, 0.35, 3.178054, 2.302585, 0, 4.859812, 0.03896104, 0, 0, 0, 0, 0, 0, 0.2428571, 0.03149606, 0.2, 0.9995694, 0, 0, 0.735, 0, 0.72, 0.275, 0, 0, 0.525, 5307856e-9, 0.9521739, 0.3230769, 0, 0, 0, 0, 0.425, 0, 3.091043, 4.394449, 0.1234112, 0, 1.94591, 4.983607, 0, 0, 0, 0, 0, 0, 0, 0, 0.6842105, 7.257003, 7.920083, 0.3636364, 0.1765268, 0.1420345, 0.9090909, 0.3333333, 0.15, 8.091627, 0.6141758, 0.09302326, 0, 0.5458733, 2.719441, 6.907755, 0.6849968, 5.78996, 3.044523, 0.225, 0.01111111, 0, 7.251345, 0.3333333, 2.302585, 0.9495798, 0.275, 0, 0, 0, 0, 0, 0, 0.2428695, 3111111e-9, 0, 0.2327044, 0.5944056, 0.06930693, 0, 0, 0, 5.361292, 0, 0, 0, 0.01279318, 0, 1.098612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.110874, 0, 0.25, 1.098612, 0.35, 2.197225, 5.17615, 1.94591, 0.5, 4.691348, 3.061964, 0, 2.560159, 0, 0, 0.1578185, 2.772589, 0, 0, 0, 5.056246, 0, 0, 0, 2.564949, 0.03149606, 0.1666667, 0, 0, 0, 0, 0, 0, 0, 0.02836879, 0.03896104, 2.772589, 0, 0, 0.3333333, 0, 0, 0.03852465, 0, 0, 0, 0, 5.768321, 0, 3.89182, 0, 0, 0, 0, 0, 0.5546955, 0, 0, 0, 0, 0, 0, 7.251345, 4.559038, 0.2, 6.343881, 0.3428572, 0, 0.275, 6.55108, 0, 0, 4.70953, 0.9047619, 0.8010488, 5.733341, 0.25, 0.375, 0.2002174, 0.075, 0.4973886, 0, 0, 0, 0.25, 2.833213, 0.1, 0, 0, 0.25, 0.01219512, 0.7044025, 0.7044025, 0, 0, 0, 0, 0, 6.133398, 0, 0, 0.35, 0.25, 0, 0, 0, 0, 0, 0, 0.7836897, 0.3, 0.1578185, 0, 0.0494359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.60517, 4.153444, 0, 8.711114, 2.639057, 4.61512, 0.9814815, 7.553287, 0.9698997, 0.15, 0.3333333, 0.1493049, 0.2093023, 0.325, 0, 7.257003, 0.175, 0.0700191, 0, 0, 0, 3.637586, 5.356586, 0.15, 0.1655462, 0, 0, 4.919404, 0.5889103, 0, 0, 9.083983, 8.501063, 3.637586, 4.60517, 0.03703704, 0.1234112, 0.2533333, 7.698483, 0, 0, 8.711114, 0.15, 0, 0, 0, 0, 0, 2.079442, 0, 0, 0.38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 2.772589, 0.3333333, 0.3333333, 0.72, 2.302585, 1.098612, 0, 0.260274, 0.5, 0.2, 0, 0, 4.153444, 0, 0, 4.912655, 0, 0.2641791, 0.09302326, 0.3, 2.639057, 0, 0, 0, 0, 0, 0, 3.367296, 0, 0, 0.3702046, 0, 0, 0, 0, 0, 0, 0.3742331, 0.25, 0.1234112, 0, 0, 0, 0, 0.2, 0.25, 0, 0, 0.1666667, 0, 0.1255986, 0.5458733, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.01857929, 0, 0.2, 2.529484, 0.08483563, 0.1666667, 3.637586, 0, 0, 0, 0, 0, 0, 0, 0.1666667, 0, 0, 0, 0, 0, 0, 0, 0, 1.098612, 6.028278, 0, 6.133398, 0.976508, 4.859812, 3111111e-9, 1.791759, 0.1109164, 0, 4.41884, 0.8297873, 0.3270142, 0, 0, 0, 0, 0.5, 6.55108, 0.275, 0.4210526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 580011e-8, 0, 0, 6.907755, 6651744e-9, 0.1234112, 0, 5.609472, 5.361292, 0, 0.3333333, 1.609438, 0.9995694, 5.356586, 0, 0, 1.676732, 0, 0.5948718, 0, 0.8571429, 0.6931472, 5.129899, 0.2, 3.228761, 0.175, 0, 2.883696, 0.02316602, 0.2, 0.1146875, 0.2993237, 3.172406, 0, 0.832981, 1.676732, 0, 0, 0.6842105, 0, 0.1, 0, 5.236442, 0.4375, 7.920083, 0.1109164, 2.302585, 3.332205, 0, 0, 0.1585652, 0, 8.2933, 5.857933, 0.3333333, 0, 0.225, 5.278115, 5.78996, 0.03703704, 0, 0, 0, 0, 0, 0, 4.912655, 0.4651163, 0, 0.2485207, 4.394449, 0.02698599, 3.73767, 7.698029, 0, 0.3702046, 0, 3.061964, 0.3408666, 0, 0, 0, 0.2, 0.3742331, 2.70805, 3.555348, 4.691348, 0.75, 0.1493049, 0, 0, 0, 0, 0, 0, 0, 4.007333, 4.61512, 0.4210526, 0, 7.251345, 7.017506, 0.2, 0, 0.2781682, 0.3333333, 0.275, 4.559038, 0, 0, 4.007333, 0, 0.3523154, 0.5889103, 0, 0, 0.3584906, 0, 3.367296, 3.465736, 0, 0, 0, 0.125, 0.25, 0.4324605, 0, 0.3341523, 5.236442, 0, 0, 0.1111111, 0.06896552, 0.1578185, 0.6141758, 0.1655462, 2.079442, 0, 0.1, 0, 0.03896104, 4.61512, 2.397895, 0.2002174, 5.17615, 2.302585, 0.03191489, 0.04255319, 0.1, 0.5, 4.574711, 2.38506, 0.3333333, 0.3428572, 0, 0, 0.1146875, 2.792088, 0, 0, 0, 0, 0, 0, 0.07142857, 0, 0.2955975, 0, 0, 0.75, 0, 0.4651163, 0.5275567, 0, 0, 0, 0, 0.3333333, 1.098612, 0, 0.09378118, 2.70805, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0.3333333, 8.669914, 2.564949, 0.225, 2.890372, 7.251345, 0.7848276, 0, 0, 0.5889103, 2.302585, 0, 7.698029, 6.478509, 0.01219512, 0.7836897, 0, 0.06774194, 0, 0, 2.302585, 0, 0, 0, 0, 0, 0, 0, 0, 4077529e-10, 4.356709, 5396655e-9, 0.25, 4.912655, 0.5827814, 0.4651163, 0.1666667, 2.223656, 0, 0.4843636, 0, 0.9, 0.425, 0, 0.5275567, 0, 2.564949, 0.5944056, 0, 0, 0, 0, 0, 0, 0, 0, 5.57973, 3.091043, 0.175, 0.03149606, 0.04424779, 3.044523, 3111111e-9, 2.683568, 2.890372, 0, 0.1109164, 0, 0, 0.2, 3.465736, 0, 0, 0.8297873, 0.9995694, 0, 0, 0, 0, 0, 3.89182, 0, 0, 0, 0, 0, 0, 1.494614, 6.55108, 0.7972973, 0.2, 0.5, 0, 0.9814815, 0, 0.35, 0.225, 0, 0, 0.7836897, 0.325, 0.1966292, 0, 2.890372, 0, 0, 7.017506, 6.620073, 0.1651376, 0.425, 0.02584493, 5.204007, 0, 0.7142857, 0.4973886, 0, 0, 0, 0, 0, 0, 0, 0.1111111, 0.06896552, 0.1578185, 7.698029, 0.1655462, 2.890372, 0, 7.257003, 0.525, 0.03896104, 4.61512, 0, 0, 0.4375, 2.302585, 7.095064, 0.4, 0.1666667, 0, 4.912655, 2.38506, 7.412764, 6.028278, 0.28, 0, 0, 0, 0.225, 0, 0, 0, 0.4324605, 0, 0, 0.6141758, 0.8556951, 0.8929385, 0.05, 0.3309545, 0, 0.2422871, 2.529484, 0, 0.05263158, 0, 0, 0.2002174, 0.1222076, 0, 2.484907, 0.0600245, 0.3333333, 0, 0, 4.356709, 5.686975, 0.25, 0, 0, 0, 0, 0, 0.735, 0.6571429, 0, 0, 0, 4.574711, 0.8773364, 0.04975546, 0, 0.125, 5.459586, 0.4973886, 0.7836897, 4.41884, 0.9160967, 0, 0.4973886, 0.03703704, 5.278115, 0, 2.848795, 0.1012539, 0.1666667, 6.907755, 1.386294, 0.275, 0.04799343, 0, 0.275, 0.5889103, 3.38491, 4077529e-10, 0.425, 5396655e-9, 4.356709, 0, 0.5827814, 0.5278115, 0.9245283, 4.912655, 0, 0, 0, 0.9, 0, 1.098612, 0.1420345, 0, 0, 0.2088739, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.425, 1.791759, 5.236442, 2.197225, 0.02702703, 2.772589, 0, 1.960601, 4.219508, 0, 0, 0.03149606, 0.5471264, 0, 0.2533333, 0.5, 3.713572, 4.234107, 0.08333334, 0.1111111, 0.1, 5.924256, 3.853134, 0, 2.529484, 4.025352, 6.028278, 0, 3.258096, 0.4210526, 0.6931472, 0.2517483, 0, 0.8896571, 0.07142857, 0.7829458, 0.3333333, 0, 0, 0.8482024, 0.9090909, 5.056246, 0.8929385, 0, 0, 0, 0, 0, 0.01111111, 0, 4.356709, 0.3309545, 0.1222076, 4.70953, 0.04799343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5.768321, 3.853134, 2.397895, 7.095064, 0, 0, 0, 0.3333333, 4.327618, 0.02584493, 2.995732, 0.2, 0.1146875, 0.35, 5.361292, 0.09624537, 0, 0, 0.0346841, 0.2422871, 0.15, 3.7612, 0.2, 0.125, 0.25, 0.1578185, 0.06774194, 5.356586, 0.2093023, 0, 0, 0, 0.2428695, 0, 0.2, 0.2327044, 0.4375, 0, 0.6931472, 0.7358209, 3.367296, 4.356709, 0, 0, 0, 0.5077296, 0.5472561, 0.1146875, 9.083983, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.1255986, 0.02702703, 923186e-8, 0, 0, 1.609438, 0.05263158, 0.25, 0, 0, 0, 0, 0, 3.178054, 0, 0, 0, 0.38, 4.691348, 0, 0.075, 0, 0, 0, 0, 0, 0, 0, 0, 7.251345, 4.559038, 0.2, 0, 0.3270142, 0.3333333, 0.275, 0.735, 4.70953, 0, 5.521461, 0, 0.6571429, 5.733341, 0, 0, 0.225, 0.260274, 580011e-8, 0, 0, 0, 0.25, 0.125, 1.94591, 0, 0, 0.25, 0.01219512, 0, 0, 0, 0, 0.2428695, 0, 6.028278, 0.2327044, 0.5944056, 0, 0.6931472, 0.5889103, 0, 4.356709, 0, 0, 0, 0.04629841, 0.5472561, 6.028278, 0.2485207, 0.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.03149606, 0, 5.236442, 0.7307692, 0.2781682, 0.25, 3.302175, 0, 0.3309545, 0, 0.1655462, 4.110874, 5.081404, 0.6931472, 2.833213, 6.186209, 0.260274, 1.94591, 0.8460699, 2.302585, 0, 0.4324605, 4.356709, 0.3333333, 0.25, 2.302585, 0.02871578, 0, 0, 0.4371859, 0.1146875],
4078
+ leaves: [-0.23561, 0.023447, -0.13061, 0.14613, 0.12236, -0.21303, -32768e-7, -0.20092, -0.084424, -0.26486, -0.31022, 0, -0.31748, -0.19889, -0.056845, 0, 0.17176, 0.3584, -0.023486, 0.19746, 0.13156, -0.10633, -0.22493, 0.16248, 0.43741, -0.084778, 0.09116, 0.3288, 0.17944, -0.15092, -0.17831, 0.079143, 48886e-7, -0.20068, -0.21915, 55031e-7, 0.11458, -0.17973, -0.21929, 0, -0.2285, -0.038863, -0.27544, 0, -0.28158, -0.14282, -0.048874, 0, 0.24062, 0.048763, -0.071005, 0.21582, -0.1209, -0.25721, 0.049963, -0.25376, 0.2459, 0.089621, -0.23001, 0, 0.35351, 0.1219, 0.17403, -0.12309, -0.080028, -0.23554, -0.23459, 0.027953, 0.074411, -0.19864, -0.18511, 18541e-7, -0.21768, -6757e-6, 0.077287, -0.22157, -0.261, -0.19163, 0.036432, 0, -0.10356, 0.20375, 0.14411, -0.028966, 0.053082, -0.12654, -0.25986, 0, 0.28012, -0.22242, -0.076944, 0.20812, 0.087574, -0.087544, 0.203, -0.19972, -0.21254, 63567e-8, 5394e-6, -0.24324, -0.12629, -0.24969, 0.084259, 0, -0.033203, -0.20835, -0.23734, 0, -0.24275, -0.10501, -0.18429, 0.14892, 0.1766, 0.021734, -0.26587, 0, 0.17567, -0.1707, -0.037455, 0.27335, -0.12374, 0.047843, -98443e-7, 0.17197, -0.11254, 0.058117, -0.23677, 0, -0.055431, 0.097804, -0.18559, -0.052887, -0.23058, 0, 0.11528, -0.13612, -0.13923, 0.080909, -0.22532, 0, -0.23152, -0.15324, 0.051228, 0, -0.067109, -0.22395, 0.050691, -0.13745, 0.13637, -90173e-7, -0.24041, 0, 0.15377, -0.16689, 0.24341, -0.022105, -0.24788, 0, -0.017616, 0, -0.16462, 0.013612, 0.038635, 0.22989, 0.045081, -0.10209, -0.21564, 0, 72906e-7, -0.16289, -0.21373, 0, -0.22081, -0.078086, -0.15316, 0.13243, 0.20276, 0.028648, -0.22413, 0, 0.022891, 0.15134, -0.094822, 0.099655, 71388e-7, 0.14674, 0.014356, -0.12154, -0.19694, 0.15717, -0.099096, 0.12635, 0.057267, -0.14791, -0.059075, -0.17192, -0.22546, 0, -0.032808, 0, -0.22099, 0, -92074e-7, -0.083904, 0.16629, -0.098288, -0.18969, 0, -0.171, -47879e-7, 0.10167, -0.18003, 0.063927, -0.11723, 0.13549, -0.069106, -0.044025, 0.15229, 0.05828, -0.068127, 0.2058, -0.072384, 0.097679, -0.22337, 0.06138, -0.092718, -0.15632, -0.016754, -0.21677, 0, -0.030546, 0, -0.21458, 0, -0.079727, -80882e-7, -0.081047, 0.16639, -0.17949, 0, 0.15047, 0.051409, -0.22976, 0.1185, -0.10147, 0.076186, -0.078185, -0.19178, 0.20854, -0.10599, -0.2048, 0.13967, -0.042093, 0.12159, -0.21578, 0, -0.032261, 0.11931, -0.051799, -0.16103, -0.20943, 0, -0.028452, 0, -0.20929, 0, -0.076386, -62274e-7, 0.10547, -0.11488, -0.16999, 0, -0.15001, -0.021811, 0.025352, -0.12175, 0.13057, 0.025172, 0.074301, -0.057198, 0.12407, -0.027459, -0.047656, -0.21144, 0.20279, 0.12903, -0.13322, 0.14871, -0.018247, -0.13235, 0.14172, -77991e-7, -0.18302, 0.056846, -0.13949, -0.017568, -0.20477, 0, -0.057345, 0, -0.15907, 24572e-8, 0.14063, -0.079145, -0.16216, -0.044827, 0.09244, -61447e-7, -0.03938, 0, -0.21476, 0, 0.084126, -0.058617, -0.21641, 0, 0.15694, -0.15306, 0.18212, -0.013169, 0.053679, -0.092513, -0.14749, 21819e-7, -0.20963, 0, -0.013958, 0, 0.093811, -0.024886, 0.14564, -0.030214, -0.11964, 41722e-7, 0.07505, -0.07905, -0.20442, 0, 0, 0, 0, 0, 0, 0, 0.1758, 0, -0.089306, 0, -0.046911, -0.19303, -0.021063, 0, 0.06359, -0.044415, -0.20234, -0.021942, -0.059815, 0.035376, -0.17578, -39977e-7, 0.17888, 56802e-7, 0.032227, -0.17538, 0.10322, -0.13686, 0.20193, -0.016966, -0.16308, 0, 0, 0, 0.019733, 0.15787, -0.10009, 0, -0.19851, 0, 0, 0, 0, 0, 0, 0, -0.16689, -33277e-7, -0.14714, -0.022562, -0.08232, 0, 0.24257, 0.023297, 0.011179, 0.089414, 0.16925, -0.04224, 0.057977, -0.16024, -0.20261, 0.017276, -0.19734, 0, 0, 0, -0.034978, 0, 0, 0, 0.13841, 0, -0.082451, 0, -0.1816, -0.04037, 0.034321, -0.089539, -0.042515, 0.062484, -0.19902, -0.019479, -0.18087, 0.086361, 0.019014, -0.16028, 0.063493, -0.11741, 0.16351, -22315e-7, -0.072393, 0.039091, -0.13329, 71813e-7, -0.10325, 0.058053, 0.01795, 0.13029, -0.17391, 0, 0, 0, -0.19253, 0, 0, 0, 0, 0, 0, 0, -20847e-8, -0.11977, 0.062216, -0.11356, 0.14928, -0.050463, -0.158, 0.015336, -0.051316, 0.12938, -0.064063, 0.14377, -0.16945, 0.018967, 0.1208, 0, -0.20148, 0, 0, 0, 0, 0, 0, 0, -0.014448, 0, 0, 0, 0, 0, 0, 0, -0.035177, 0.035992, -0.14586, -0.018246, -0.19382, 0, -0.015127, 0, 0.17943, -56409e-7, -0.067703, 0.04488, -0.0701, 0.061599, 0.16, 0.014724, -0.18755, 0, 0, 0, -0.021173, 0, 0, 0, 0.11844, 0, -0.061561, 0, -0.16332, -0.023872, 0.050659, -0.074893, -0.16955, -34366e-7, 0.12213, 59165e-7, 0.14215, -0.041624, 0.056331, -0.12229, -0.19907, 0, 0, 0, 0.030292, 0, -0.077533, 0, -0.18039, 0, 0, 0, 0, 0, 0, 0, 0.018018, -0.090382, 0.17553, 14363e-7, -0.15225, 0, -0.017398, 0, 0.043841, -0.031724, -0.043696, 0.1923, -0.21268, -0.039746, -0.0678, 0.13241, -0.031904, 0.069522, 0.030221, -0.084149, 0.015512, 0.15657, -0.17832, 0, -0.10322, -0.2203, -0.099107, 0.087317, 0.036236, -0.14766, -0.15847, -0.032689, 0.025683, 0, -0.19392, 0, 0.17749, 0, -0.10242, 0, -0.13504, 0.046039, 0.045757, 0.14189, 0.031598, -0.029439, -0.18635, 0.03277, -0.052484, -0.14436, 0.17969, 0, 0.079609, -0.1613, 0.22792, 0.057374, -0.18702, 0, 0, 0, 0, 0, 0, 0, -62027e-7, 0, 0, 0, 0, 0, 0, 0, 0.029274, -0.10804, -0.10166, -0.013495, 0.043026, -0.14524, -68354e-7, 0.15943, -0.065839, 0, 0, 0, 0.04128, 0.21927, 0.028587, 0, -0.16939, 0, 0, 0, 0, 0, 0, 0, -0.034465, 0, 0.020687, 0.11856, -0.12938, 0, 0.015103, 0, -0.13947, 0.042767, 0.098829, -0.047357, -0.14425, -0.041459, -0.12037, 0.015986, 0.097795, -0.072453, -0.083549, 0.079645, -0.18458, 0, -0.010661, 0, -0.18048, 0, 0, 0, 0, 0, 0, 0, -0.012508, 0, 0, 0, 0, 0, 0, 0, -0.13963, 0.015077, -56633e-7, -0.08447, 0.062878, -0.16086, -0.10433, 69148e-7, -0.040194, 0, 0, 0, 0.069782, 0.21114, 0.02415, 0, -0.17492, 0, 0, 0, 0, 0, 0, 0, -0.011535, 0, 0, 0, 0, 0, 0, 0, -0.18509, -0.02891, 0.026986, -0.12263, 0.06225, -56188e-7, -0.14204, 0.039703, -0.046537, 0.029692, -0.17472, 0.070816, -0.17798, -0.059514, -82378e-7, 0.10293, 0.13536, -0.020498, -0.038635, 0, 10336e-7, 0, -0.13372, 0, -47907e-7, 0, 0, 0, -0.17007, 0, 0, 0, 0.010723, -0.17646, 0.070132, -0.10855, -0.046831, 0.083752, 0.069197, -0.030386, -0.027699, 0, 0, 0, 0.059552, 0.18908, 0.026431, 0, -0.17187, 0, 0, 0, -0.033033, 0, 0, 0, -70176e-7, 0, 0, 0, 0, 0, 0, 0, -94916e-7, 0.062978, 0.068851, -0.086152, -0.17573, 0, 0.020377, 0, -0.023508, -0.22803, -0.029807, 0, -0.019627, -0.12365, -12063e-7, 0.17307, 0.04038, -0.079567, -0.12624, 0, -0.1737, 0, 0, 0, -0.11666, 0, 0.027222, 0, 0.020463, 0.14805, -0.032103, 0, -0.17899, 0, -0.090726, 0.01678, -0.12042, 0.02373, -0.02823, 0.13292, 0.012529, -0.10838, -0.013804, -0.15214, 0.022612, 0, 0.17206, 0.036673, -0.16364, -0.04501, -0.030187, 0, -0.078899, 0.041736, 0.089131, 0, -0.033457, -0.14906, 0.093504, 0, -0.065116, 0, 0.13226, 69597e-7, -0.11842, 0.039862, 0.11633, -0.04845, -0.038627, -0.20604, -0.029656, 0.092349, 0.048404, -0.07827, 0.13944, -0.016131, -0.029648, 0.10428, 0.023442, -0.22563, -0.043018, 0, 0, 0, -0.16429, 0, 0, 0, -68783e-7, 0, 0, 0, 0, 0, 0, 0, 0.14964, -0.12357, -0.11181, 0.014126, 0.090086, -0.031282, -89455e-7, 0.31516, 0.06684, 0, -0.090069, 0, -92682e-7, 0, -0.26428, 0, -0.26338, -0.055295, 0.11234, -0.087996, 0.15817, 0.034464, -0.07469, 0, 0.12275, -0.095274, -0.023412, -0.20414, 0.045986, -16579e-7, 0.19152, 60307e-7, -0.052893, 9224e-6, -0.12237, -0.010576, -0.01067, 0.074624, 0.072276, -0.080276, -0.027338, 0, 0, 0, 0.034721, 0, 0.033964, 0.16654, -0.17646, 0, 0, 0, -0.043635, 0, 0, 0, -0.073243, 0, 0, 0, 0.087852, 0, 0, 0, -0.10229, 0.065018, -0.074961, 0.017362, 0.089023, 0, -0.29757, 0.054169, -0.093661, 0.046198, 0.041942, -0.049027, 0.043594, 0, -0.018869, -0.15043, 74506e-8, -0.14663, -0.094872, 0.1193, -0.23405, -0.036313, -58063e-7, 0, 45862e-7, -0.10684, 0.049912, 0, 0.038759, 0, 0.18962, 0, -0.13663, -0.011265, 0.052403, 0, -0.10657, 0.02187, 0.10709, -0.037369, -0.040169, 0.14692, -0.11607, 0.11025, -0.043673, -0.16994, -0.021179, 0.022038, -0.032832, -0.14966, -0.01537, 0, 0.063013, -0.072169, -0.11594, 0.03021, -0.10074, -0.011879, 0.060257, -0.03694, 82852e-7, 0, 0.10109, 0, 87296e-7, -0.032554, 0.061912, -0.14583, 0.16942, -0.035799, -0.10036, 0, -0.25201, 0, 0, 0, -0.06714, 0.070598, -0.21703, -0.020805, -0.15616, 0, 0, 0, 0, 0, 0, 0, -0.067411, 0, 0, 0, 0.077964, 0, 0, 0, 97184e-7, -0.11251, -0.10297, 0.076476, -0.2293, 0, 0.029734, -0.1664, -0.14847, 0, -0.067685, 0.013569, 0.014483, -0.10248, 0.12095, -0.032881, -0.010592, 0, 0, 0, 0, 0, 0, 0, 0.15136, 0, -0.024172, 0.052452, 0.023562, 0, 0, 0, -0.11703, -67568e-7, 0.027969, -0.1303, -0.032499, 0.096898, -0.066292, 23632e-7, 0.016985, 0.20216, -0.045021, 0, -0.094842, 0, -74077e-7, 0, -0.02272, 0, 0, 0, -0.14686, 0, 0, 0, -0.010843, 0, 0, 0, 0, 0, 0, 0, -0.11554, 0.021106, 0.092855, 61127e-7, -0.089733, 0.13877, -0.31614, 0, -0.15266, 0, 0, 0, 95187e-7, 0, 0, 0, -0.036823, -0.12929, 37199e-8, 0, -0.092425, -54843e-7, 0.077607, 0, -0.12118, -6866e-6, 0.079638, 0, 0.11951, 0, -0.063101, 0.042691, 0.013897, -0.029772, -0.055544, -0.16688, -0.024123, -0.16282, 0.083259, -0.16826, -0.11709, 0.14111, -0.04945, 0.12567, -0.22206, 0, 0, 0, 0.075202, 0, 0, 0, -0.19509, 0, -0.01329, 0, 0.066086, -0.056225, 0.14867, -22096e-7, 0.056172, -0.058332, 0.023545, -0.21655, -0.11662, 0.027989, 0.07086, 0, 0.062976, 0, 0, 0, -39226e-7, 0.045231, -0.10971, 0.028016, 0.099821, -0.11154, 0.10035, -80902e-7, 0.083733, -0.057717, -0.037373, 0.1103, 0.18821, -0.13347, -0.14145, 0.038517, -0.20667, 0, -0.012954, 0, -0.097992, -95788e-7, 0.1367, -0.014512, -74928e-7, 0.061214, -0.025965, -0.35652, 0.010248, -0.12233, 0.045179, 0.17395, -0.11337, -0.017159, -0.013082, 0.13763, 0.060315, -0.10206, 47238e-7, 0.096057, 0.027621, 0, 0, 0, -0.022141, 0, 0, 0, 0.029913, 0.1496, 0.017033, 0, 38395e-7, 0, 0, 0, 17018e-7, -0.073631, 0.10472, -0.086849, -0.1612, 0.031844, -0.20719, -0.014377, 0.17109, 20696e-7, -0.04497, 0, -29675e-7, 0, -0.087524, 0, 0.03505, 0, 0, 0, -0.071413, 0, 0, 0, -0.1334, 0, 0, 0, 0, 0, 0, 0, 0.023132, -0.040639, 13964e-7, -0.059039, -0.03272, -0.15992, -0.027861, 0.13672, -93064e-7, 0, 0, 0, -0.12892, 0, 0, 0, 0.026098, 0, 0, 0, -0.021587, 0, 0, 0, 0.017142, 0, 0.14725, 0.034147, 79433e-7, 0, 0, 0, -44645e-7, -0.14211, 0.022738, 0.12232, -0.039126, 0.094491, -0.15503, 0.046449, -0.084334, 0.086456, -0.050584, -0.16035, 0.046691, 0, 0, 0, -0.022616, 0.054251, -0.12761, 0.11536, 0.13399, -4685e-6, -0.081236, 0.074367, 0.051594, -0.062453, -0.017763, 0.032867, -0.076098, 0.078335, -0.033117, 0.15269, -68014e-7, 0.10593, 0.018231, -0.20272, 0.070388, -0.038895, 0.10451, -0.096534, -0.058115, 0, 0, 0, 0.039447, 0, 0.23759, 0, 0.013685, -0.20623, 0.050223, -0.10228, 0.16018, 0, -67171e-7, 0, -0.26708, 0, 0, 0, 0, 0, 0, 0, -0.058168, 0.037662, 0.098829, -0.10525, 0.031284, -0.014658, 0.082819, -0.060853, 0.1563, 0.011533, 0.066928, -0.037838, -0.18387, 0, 0, 0, -0.17228, 0, 0, 0, 0, 0, 0, 0, -0.057021, 0.044363, 0.11007, -0.045433, -0.16052, 0, -64906e-7, 0, -0.14251, 0, -0.0246, 0, 0.019769, 0, 0, 0, 0.076812, -0.058827, 42936e-7, 0.20053, 0.034049, -0.1825, -42978e-7, 0.043507, 0.026149, 0, 0, 0, -0.019686, 0, 0, 0, 0.020124, 0, 0.13645, 0.03404, 69094e-7, 0, 0, 0, -0.087854, -57371e-7, 0.054704, -0.023845, 0.11312, -0.040289, -0.096164, -0.015069, -0.03686, -0.12912, -0.11467, 0.023048, -0.076172, 0.10125, -0.15371, 0.087017, 0.064094, -0.067367, 87943e-7, -0.18935, 0.06857, 0, 0, 0, 0.057758, -0.031592, -0.24321, 0.035847, 0.045729, -0.038507, -0.010069, 0.094229, -0.058471, 0.04788, 0.022197, -0.020475, 10191e-7, -0.25404, -0.10108, 0.05941, 0.051012, -0.1533, 0.10741, 0, 0.084339, -0.11393, 0.22737, -0.085373, -0.15318, -0.048603, 0.046747, 0, 0.14736, 0.014507, -0.053352, 0, -0.23277, 0, 0, 0, 0, 0, 0, 0, -0.012598, 0.057208, -0.091349, 0.023022, 0.011586, 0.11199, 0.019182, -0.12706, 0.026242, 0, -0.01728, 0, 0.1092, 0, 14761e-7, 0, -0.1458, 0, 0, 0, -0.024548, 0, 0, 0, 0.033619, 0, 0, 0, 0, 0, 0, 0, 0.060769, 0, -0.04168, 0, -0.1155, 0, 0, 0, -0.05635, 0.12375, -0.12039, 0.055108, 0.15638, -0.095208, 0.044876, 0.22391, 0.027898, 0, 0, 0, -0.18537, 0, -0.011476, 0, 10771e-7, -0.085038, -0.13102, 0.061915, 0.010993, -0.038246, 0.060992, -0.039904, 88277e-8, 0.11099, -0.17348, 0.049152, 0.034217, -0.17378, 0.04784, 0.16406, -0.092672, -0.023253, -0.016019, 0.03554, 0.055159, -0.054804, 0.045669, -0.051226, 0.086273, -0.054624, -0.092911, 0, -0.022157, 0, -0.17564, 0, -0.092692, 0, -1804e-6, 0, 0.14682, 0, 1217e-6, 0, 43195e-7, -0.060954, 0.10289, -0.04488, -0.1172, 0, 0, 0, -0.064135, 0, -0.027066, 0.11426, -0.13309, -0.011765, 0.053923, 0, -0.13617, 0, 0, 0, -95846e-7, 0, 0, 0, 0.037966, 0, 0, 0, 0, 0, 0, 0, -0.072782, 19586e-8, 0.065306, -0.08246, 0.10742, -0.082033, 0.025722, -0.13675, -0.044876, 0.081243, -0.020144, -0.17855, -0.020185, 0.024922, -0.015335, 0.082642, -0.024638, 0, 0, 0, -0.19208, 0, 0, 0, 0.053235, -0.069716, 0.13402, 0.036234, 0.011639, 0, -0.087599, 0, 25781e-7, 0.098686, -0.065432, 0.12438, -0.19541, 0.04425, 0.086504, -0.074234, -0.13462, 0.078694, 0.11702, -0.073058, 0.09056, -15529e-7, -0.14822, 0.054961, 0.014229, 0, 0.11745, 0, -0.04893, 0, 0, 0, -0.11138, 0, 0.037646, 0, -0.23011, 0, 0, 0, -0.027023, -0.16706, 0.022953, 0, -0.027132, 66989e-7, 0.091168, -0.078126, -0.091205, 0.014818, -37882e-8, 0.081839, 0.027402, 0, -0.032799, -0.18298, -0.010016, 0, 0, 0, 0, 0, 0, 0, 0.019663, 0, 0.1121, 0, -0.038791, 0, 0.086966, -0.012656, 0.051028, -0.086572, -0.03736, 0.13078, 0.21254, 0.010417, -0.034823, 0, 0.014084, 0, -0.16808, 0, -0.080822, 0, 0.14593, 0, -0.028996, 0, 0.063285, 0, -0.17771, 0, -0.01122, 0, -83381e-7, -0.11569, 0.017525, -0.10765, -0.02245, 0.016724, 0.094137, -0.1391, 0.068641, -0.062311, 0.021696, -0.16206, -0.017319, 0.11769, -0.1252, 0.075449, -0.031026, -0.16999, 89412e-7, 0, 44891e-7, -0.067516, 0.095815, 0, 0.040837, -0.041221, -0.10237, 0.032695, -0.10809, -0.01304, -0.082945, 0.16586, 0.014353, 0.12178, -0.033391, 0.038092, -0.13034, 0.016893, 0.072037, -0.036279, 70478e-7, 0.11629, -0.11277, -33893e-9, 0.13587, 98328e-7, -0.11287, 0.043838, -0.060847, 0, 87352e-7, 0.10047, -0.098051, 0.040839, -0.21272, 0, 0.037511, -0.045712, 0.123, 0, 0.084366, -0.031473, -0.13666, 0, -0.12655, 0, 0, 0, 0, 0, 0, 0, -0.064211, 0.011691, -0.014972, -0.14635, 0.010109, -0.059672, 62041e-7, 0.10672, -0.023883, 0, -0.12907, 0, 0.019307, 0, 0, 0, -0.1207, -0.015463, 0.06351, -0.042867, -0.073681, 0.048049, -0.024599, 0.092666, -0.12755, 0, 0.034755, -0.069839, 0.095509, 0, -0.081056, 0, -0.12933, -87413e-7, 0.012868, 0, -0.024262, 0.08939, -0.050111, 0, 87469e-7, -0.026991, -0.035638, 0.1048, -0.041749, 81463e-7, 0.12802, -92768e-7, -82695e-7, 0, 0, 0, 0, 0, 0, 0, 0.10892, 0.013922, -41265e-7, 0, 83668e-7, 0, 0, 0, 0.058892, -0.076451, 0.024721, -0.027744, -0.077197, 0.014084, -0.01787, 0.079272, -0.043127, 0.023074, -66287e-8, 0.14055, -0.038597, 0.13411, -0.098707, 0.065152, 0.038447, -0.10175, -0.16632, -28862e-7, -0.093939, 0.03921, 0.10399, 0, -0.01804, 0, -0.12887, 0, -0.075525, 0, 0.030172, 0.18488, -0.038075, 0.14793, -0.092156, 0, -0.16637, 0.046933, -0.021845, 0.12988, 0.026858, 0, 0, 0, 0.14711, 0, 0, 0, -0.020831, 0, 0.065017, 0, -0.16046, 0, -15394e-7, 0, -0.095489, 81358e-7, 0.011474, -0.092039, 0.018318, -0.058772, -0.08752, -18835e-7, -74007e-7, -0.13859, -43991e-7, 0.037264, 0.036919, 0.12395, -25011e-7, -0.14369, -0.12517, -0.010082, -75648e-7, 0, 0.01777, -0.088467, 0.11354, -0.025452, -94347e-7, 0, 0.068502, 0, -0.046559, 0, 0, 0, 51949e-7, 0, 0, 0, 0.10178, 0, 0, 0, -0.028925, 0.043219, 0.067088, -0.086252, -0.054021, 0.010411, -0.014638, 0.026482, -0.090897, 0.04702, 0.15688, 0.036888, 0.015195, 0, -0.11163, 0, -0.077564, 0, 0.083213, -0.029393, -0.031977, 0, -0.15203, 0, -0.010751, 0, -0.082013, 0, -42429e-7, 0, 0.13797, 0, 0.014728, -0.042233, -0.11558, 90845e-7, -7404e-6, -0.083762, 0.016986, 0.17788, 0.033243, -0.050931, 64581e-7, 0.15697, -0.060633, 0, 0, 0, 0.011266, 0, 0, 0, -0.019896, 0, 0, 0, -0.10036, 0, 0, 0, 0, 0, 0, 0, 0.068942, -0.041067, 0.16084, 0.022912, -0.10507, -0.012065, -0.019251, 0.095677, 0.017085, 0, -0.14537, 0, -0.072424, 0, 0.11794, 0, -0.15807, 0, -0.078506, 0.044617, -0.082513, 0, 0.12083, -0.031406, -0.134, 0, -11686e-7, -0.059066, -90457e-7, 0.14323, 77072e-7, -0.035686, -0.11386, 0, 0, 0, 0, 0, 0, 0, 40124e-7, 0, -0.081835, 0, 0.045325, 0, 0, 0, 0.075585, 0.012067, 19576e-7, -0.13391, -0.1318, 51564e-7, -53664e-7, 0.038303, 0.097674, 0, 0.015099, 0, -0.04527, 0, 0.072404, -0.013285, -0.044525, 0.015425, -78979e-7, -0.098209, -0.014333, 0.089267, -0.089966, 0.045773, 0.056658, -0.09631, -0.11973, 0.054319, -0.065433, 0.060883, 0.12166, 0, -0.052713, 0.010772, -0.14409, 0, 0.045448, 0, -0.041279, 0, 0.025348, 0, -0.083471, 0, -0.023398, 0, 0.10275, 0, 0.013612, 0.099287, -0.11102, 0.039706, -0.028685, 0.061428, -0.11575, 0.018439, -0.12604, 0, 0, 0, 0.036272, -0.092052, -0.031352, 0.073103, 0.030486, -0.023667, 0.048044, 0.1294, 0.049608, -0.032326, -0.19871, 0, -0.085979, 4444e-6, 0.020267, -0.094499, -76792e-8, 0.039979, -0.10038, 0.032002, 0.013407, -0.098613, -0.059474, 0.041004, 0.047522, -0.032072, 0.026178, 0.10754, 0.063095, -0.019133, -0.018855, -0.14983, -0.01822, 0.018971, 0.13636, -0.071734, -0.016905, 0, 0, 0, -0.16396, 0, 0, 0, 0.028277, -0.074484, 0.1087, 73969e-8, -0.075709, 0, 40413e-7, 0, 21871e-7, -0.041341, 0.13722, 49287e-7, 0.056671, -0.088958, -0.043014, -0.18153, 0.11727, 0.011742, 0.024388, -0.08622, -0.16515, 0, -0.02264, 0, -0.10466, 0.018774, 0.049966, 0, 0.10992, -21507e-7, -0.036403, 0, -0.14363, 0, 0, 0, 0.010664, 0, 0, 0, -90518e-7, 0.085894, -0.071778, 34003e-7, 0.16997, 0.010998, -0.046348, 0, 0.020108, 0, -0.13171, 0, -0.041374, 0, 0.099651, 0, -0.031808, 0, 0.075817, 0, 38908e-7, -0.05047, -0.15225, 0, -0.01268, 0.040336, -0.10195, 0.028765, -0.039957, 0.098513, 0.054283, -45809e-7, -0.038714, 0.022956, -0.14743, 0.01803, -0.04678, -0.13838, -0.049028, 0.063874, 0.13524, 0.017221, -0.041853, 0, -0.056841, 0, 0, 0, -93136e-7, 0.096437, 0.061252, 53848e-7, 0.062076, -0.082447, -0.13714, 0.042362, -0.097878, 55276e-7, 0.1106, 83847e-7, 0.14319, -0.038194, 0.024497, -0.13626, -26103e-7, -0.11189, 0.016746, 0, 0.044217, -0.090371, -0.09722, -85953e-8, -62085e-7, 0.061046, -0.040654, 0, 27452e-7, 0, 0.10122, 0, -0.11487, 0, 0, 0, 0, 0, 0, 0, -0.037365, 0, 0, 0, 0.084002, 0, 0, 0, 10589e-7, -0.062693, 0.063548, -0.060634, 0.11474, -0.026823, -0.064678, 0, -0.028063, 0.095617, -0.092126, 0, -0.125, 0, 0, 0, -0.036297, -0.14816, 0.083051, -0.062535, -0.022415, 0, 0.080522, 0, -0.015626, 0, -0.11818, 0, -0.065294, 0, 0.024414, 0.16188, -0.061575, 0, -0.024825, 0.10529, -0.078415, 0.035891, -0.13011, 0, -0.090405, 0, 79793e-7, 0, 0.11606, -0.027934, 0.022427, -0.060072, 20204e-7, -0.099397, 0.039744, -0.041974, -0.12733, 0, 0.050794, -0.054425, 46145e-8, 0.11477, -68312e-7, -0.054964, 0.12721, -0.035087, 0.1341, 0.03404, -0.053982, 0.073716, 0.046027, -0.012968, 0.076601, -0.068069, 56639e-7, -0.11096, -0.035559, 0.15378, -0.10047, -67894e-7, -0.061907, 0.093528, -0.22489, -0.01893, -0.027795, 0.01969, 0.026065, -0.1162, 0.013245, 0.10167, -0.10124, 0.063015, -0.10752, 0.034513, 0.10425, 0, 0.20295, 0.042196, -0.036406, 0, 0.053887, -0.035807, 0.13426, 0.015376, -0.097838, 98482e-7, 0.016337, -45954e-7, -0.037521, 0.031785, 0.016996, 0.13314, -0.057412, 0, 0, 0, 76887e-7, 0, 0, 0, -0.01911, 0, 0, 0, -0.087509, 0, 0, 0, 0, 0, 0, 0, -70105e-7, 0.041433, 0.068467, -0.08355, 0.042291, -0.034208, 0.013814, 0.12966, 3964e-6, 0, -0.14479, 78673e-7, 0.089535, -0.032952, -0.1554, 0.042186, 0.060245, 0, 0, 0, 0, 0, 0, 0, -0.012007, 0.11925, -0.084431, 0, 0.016551, 0, -0.12657, -0.013439, -0.011864, 0.060022, 0.010243, -0.04107, -0.08947, 0, 0, 0, -51752e-7, 0.056231, -0.03771, 0, 35339e-7, 0, 0.092671, 0, -0.10671, 0, 0, 0, 0, 0, 0, 0, -0.030051, 0, 0, 0, 0.071736, 0, 0, 0, 31473e-7, -0.072083, 0.012807, 0.14409, 0.10327, -0.06175, -46157e-7, -0.19152, 0.083344, -0.037406, -0.086446, 0, 0.11693, 0, 0.023197, 0, -0.13106, 42629e-7, 0.10111, -0.034088, 0.024672, 0, 0.14411, 0, -0.17742, 0, 0, 0, 0, 0, 0, 0, -36481e-7, 0.097976, -0.059644, 0.010945, -0.17736, 0, 0.052166, -0.030308, 0.037536, -0.048902, 0.12781, -0.018824, 0.038762, -0.10626, -0.033123, 73543e-7, 0.010478, 0.09011, 0.046406, -0.066241, 0.14083, 0.012084, -0.013579, 0, -0.024051, -0.15048, 0.093206, -0.047767, -0.012898, 0.16289, -0.15402, -94362e-7, 24719e-7, 0.062015, -9113e-6, -0.12535, -0.015601, -0.14511, -0.014026, 0.091893, 65389e-7, 0, 0.097959, 0, -0.16773, 0, 0.055743, 0, -36911e-7, -0.12144, 0.082647, -0.079237, -0.031669, 0, 0.093475, 0, 0.012563, 0, -0.12906, 0, 0.038875, 0.17193, 0.041115, -0.097809, -0.049101, 0.017072, -0.037349, 0.050084, 0.026053, -0.032238, -0.011195, 0.069669, -0.066892, 0.017119, 0.11833, -0.043509, -0.070306, 0.020291, -0.11598, -0.014225, -0.1057, 0, 0, 0, -85173e-7, 0, 0, 0, 0.044826, 0, 0, 0, 0, 0, 0, 0, 0.051261, -0.05756, 0.12748, 0.020223, -0.091474, -0.011746, -0.021651, 0.083333, -0.092935, 0, 0, 0, 0.065673, 0, -0.032527, 0, 0.026538, 0, 0, 0, -0.12219, 0, 0, 0, -0.096123, 0.016753, 49884e-7, -0.090856, 32493e-7, 0.039051, -0.016152, 0.11115, -16681e-7, 0.070326, -0.011068, 0.11573, -0.12686, 0, 0.071647, -0.048114, 0.057974, -0.053051, -0.18256, -40285e-7, -78319e-7, 0.11933, 0.16779, 0.032566, 0.10845, 0, -69227e-7, 0, -0.034497, 0.06832, -0.073056, 0.010276, -0.057565, 0, 0.011249, 0.068987, -0.15754, -0.02366, -78687e-7, 0, -0.027928, 0.03746, -0.011046, -0.14144, 6063e-6, 0.072532, 0.015347, -0.1454, 69539e-7, -0.085862, 0.11657, -0.026427, -0.047607, 0.098571, 0.06469, -0.095536, 0.066227, -19412e-7, -0.026025, 0.11285, -0.07439, 0.063187, 0.13503, 49338e-8, -0.050154, 0, 0.024529, 0.1139, -0.2184, -0.034988, 0.054296, -0.10769, 0.023021, -0.07461, 95677e-7, -0.076644, -0.013989, -0.10659, 0.083938, 0, -47879e-7, 0.097004, 0.01414, -0.092279, 0.010343, 0.15939, -0.025294, 0, -0.039047, 0.027899, -0.041516, 0.12828, -0.022115, 0.09901, 0.031891, -0.093052, 0.045363, -0.088255, 0.097469, -0.016273, 0.10201, -0.066943, -0.075958, 0.040701, -0.037877, 0.046858, -0.017457, -0.12222, -16047e-7, 0.033737, 368e-5, -0.1146, 0.074924, -0.075918, 0.022368, 0.14439, -0.080919, 0, 0, 0, -0.22023, -0.03294, -0.06084, 0.078199, -0.10181, 0.032295, 0.038213, -0.043524, -57997e-7, 0, 0, 0, 0.028167, 0, 0.16664, 0, -0.12004, -0.013787, 97243e-7, 0, -0.014114, 72876e-7, 0.064214, -0.061129, -0.067284, 0.075401, 0.063467, -0.028729, 0.042858, -0.04769, -0.11297, 0, -0.012945, 0, 0.031571, 0, 0.098479, 0, 0, 0, -0.04451, 0, 0, 0, 0.037625, 0, 0, 0, -0.078096, 0.042662, 0.075535, 0, 0.090581, -0.023385, -0.038111, 0, 0.11877, 0, 0, 0, 0.019453, 0, 0, 0, 0.02405, 0, 0, 0, -0.11454, 0, 0, 0, -0.030574, 12378e-7, -0.043249, 0.061374, 0.074681, -0.017251, 97641e-7, -0.11251, 0.026877, -0.037737, -0.046798, -0.16678, -0.036045, 0.030047, 96194e-7, 0.064719, 0.029535, -0.08166, -0.096311, 0.056961, -6353e-6, 0, 0.13762, 0, -50443e-7, 0.08431, 0.017116, 0.14029, 0.098149, -0.014986, 53427e-8, -0.1474, -0.12936, 0, 0, 0, 0.10073, -0.026024, -0.075384, 0, -0.036497, 0.032456, -0.097204, 0, 0.036425, -0.070906, -0.072285, -61076e-8, -0.083872, 0, 0, 0, 0, 0, 0, 0, 0.033468, 0, -0.054226, 0, 0.066526, 0, -56047e-7, 0, 0.081728, 0, 0, 0, 0, 0, 0, 0, 0.028036, -0.037901, -0.025244, 0.051391, 0.012023, 0.14221, -0.053562, 0, 0.10853, 0.011708, -0.067275, 0.05247, 0.14765, 0.016044, 24642e-7, 0, -0.032356, 0, 0.072403, 0, -0.022052, -0.15057, 0.035241, 0, 81425e-7, 0.079268, -0.11247, 0.015622, -0.03752, 39485e-7, 0.11405, -0.07088, 0.019227, 0, -0.090312, 74272e-7, 0.019095, -90648e-8, -0.071071, 0, -0.080112, 0, 0, 0, 0, 0, 0, 0, -0.01033, 0, 0.03032, 0, 0.0927, 0, 0, 0, 0.056884, 0, -0.011741, 0, -0.044238, 0, 0, 0, -49167e-7, -0.084186, 0.080052, -0.022887, 0.1074, -0.011541, -0.071179, 0.041683, 0.023634, 0, -0.12001, 0, -0.03292, 0, 0.073188, 0, 0.035599, 0, 0, 0, -0.014502, 0, -0.12891, 0, 0.066688, -0.027753, -0.046211, 14763e-7, 3725e-6, -0.087824, -0.040941, 0.065301, -0.11843, 0.020655, 94887e-7, -0.015808, 0.099428, 0, -0.05038, 0, -0.046476, -0.20753, -0.067054, 0.061949, -0.076371, 0, 0.10658, -0.045319, -0.023216, 0.040463, -0.05455, 0.075967, 0.13074, -0.021735, 0.1087, -0.028063, -0.037057, 0, 0.020722, 0.10414, -0.026148, -0.18981, -0.11805, 0.044611, 0.013586, -0.04135, -0.18336, -0.030885, 0.028057, -0.041197, -0.11473, 8579e-6, 0.10433, 0, 0, 0, 0, 0, 0, 0, -0.078048, 0.015275, 0.058664, -0.050641, -0.076761, 0.011452, -0.048617, 0.05105, 0.12659, 58411e-7, -0.033245, 0.032304, -0.046681, 0, 0, 0, 90518e-7, -0.057968, 0.084365, -0.032485, 0.073015, -0.083745, -0.059293, 0.0344, 0.024544, -0.13336, 0.026336, -0.088487, -0.063366, 0, 37683e-7, 0.13725, 0.063915, -11878e-7, -0.1234, 0.092455, 0.097509, -0.024547, -0.14816, 0.025725, 82909e-8, 0.12393, 0.012222, -0.13709, 0.02356, 0, 0.15106, 0, 80078e-8, -0.08415, -51807e-7, 0.022182, -0.016149, -0.08785, -0.013216, 0.097938, -0.039217, -0.16418, 14686e-7, 0, 84703e-7, 0, 0.067341, 0, -0.097223, 0.042336, 0.075396, -0.016452, 0.068711, -0.075266, 0.014318, 0.15257, 0.078445, -0.036142, -0.046485, 0.075777, -0.13983, 0.016621, 0.030359, 0, -13904e-7, 0.062646, -0.11038, 0.025236, 0.037315, -0.044186, 0.067745, -0.019436, -75564e-7, -0.069348, -0.017988, 0.13503, -0.064786, 0.062311, 0.032619, -0.093655, -0.066577, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60694e-7, 0.08374, -0.030204, 0.02166, -0.069387, 0.085511, -0.049972, 0.091911, -0.054857, -0.21127, 0.065635, -0.077686, -0.058378, 0.028323, -0.011569, -0.14229, -0.15949, -0.022667, -0.034547, 0.066567, -0.093185, -0.017722, 0.03802, -0.044432, -0.059983, 0, 0.059735, 0, 0.15142, 0, 0.024378, 0, 0.029274, -0.028514, -0.087855, 0, -0.060101, -99398e-8, 0.031324, -0.061277, -0.073847, 0, 0, 0, 0, 0, 0, 0, 29692e-7, -0.016547, 0.042697, 0, 0.09233, 0, 0, 0, -0.039958, 0, 0, 0, 0.031085, 0, 0, 0, 75879e-7, -0.03649, 0.025366, -70925e-7, -0.10259, 0, 76021e-7, 0, -0.1205, -32473e-7, 0.087623, -0.03726, 0.06484, 0, -43988e-7, 0, 0.014698, 0.092447, -0.14334, 0.073741, -0.11843, -26277e-7, -0.054267, 0.012724, -0.021242, 0, 0, 0, -0.13438, 0, 0, 0, 0.01993, 0, -0.088753, -8987e-6, 42327e-7, -0.012898, 0.029834, -0.13108, 43117e-7, 0, 0, 0, -0.073312, 0, 0, 0, -0.027995, 0, 0.076603, 0.010733, -0.037047, 0, 0, 0, 0.071709, 0, 0, 0, 0, 0, 0, 0, 55723e-7, -0.032517, -0.07081, 54897e-7, -0.060529, 0.060508, -0.02562, -0.15117, -0.09165, 0, 0, 0, -15626e-7, 0, 0.03115, 0.13288, -0.049509, 0.067512, 88059e-7, -0.14817, 0.11426, 0.020746, -69245e-7, 0, 0.016984, -0.2156, -0.095263, 0.07485, -0.12414, 0.046094, 0.10663, -0.01294, 0.046531, -0.021249, -0.038091, 0.075778, -19268e-7, -0.062984, 0.074832, -0.016121, -0.031363, 0, -0.018621, 0.061026, 0.070515, 0, 0, 0, -0.094531, 0, 0, 0, -0.01164, 0, 0, 0, 0.045352, 0, 0, 0, 0, 0, 0, 0, 22532e-8, -0.054367, -96745e-7, 0.071514, 0.016327, -0.10466, 0.079813, 0, 0.0419, 0, -0.11622, 0, -0.029137, 0.064427, -11356e-7, 0.12526, -0.022636, 0.055335, 41816e-7, -0.089303, -0.16328, 0, 0.037796, 0, -92388e-7, 0.10268, 0.059209, -0.16494, 0.12371, 0, 0, 0, -42472e-8, 0.088959, -0.01807, 0.091526, 0.025205, -0.067488, 0.088899, -0.019906, -0.080428, 0, 0.073976, -0.064864, -0.010102, 0, -0.12425, 0, 0.053192, 0, -72896e-7, 0, -0.073692, 0, 0, 0, 0.095601, 0, 0, 0, 52792e-7, 0, 0, 0, -37165e-7, 0.024189, -0.013629, -0.13166, 0.064315, -0.013175, -0.027892, 0.080533, -0.043592, 0.10371, -0.090396, 0.012085, -0.059576, 17789e-7, -0.012954, 0.11632, -0.020293, 0, -0.096478, 0, -22258e-7, 0, 0, 0, 0.087081, 0, 0, 0, 0.012164, -0.084984, 0.029828, 0, 12298e-7, -0.094334, 0.067368, -0.037647, 0.028061, 0.13586, 83007e-7, 0, -53086e-7, -0.049861, -0.014786, 0.034914, -0.016577, 0.11328, -0.074623, 0.057475, -0.060874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.072421, -0.067789, -0.14034, 0.048996, 0.095073, 0, -20842e-7, 0, 0.10831, 0, 0, 0, 0.015003, 0, 0, 0, -0.13018, 0, 0.070154, -0.051793, -0.07156, 0.068217, 0.093561, -0.022408, -0.015392, 0.071292, 0.13787, -0.048402, -22329e-7, -0.054159, 0.098085, -0.048759, -0.088504, 0, 0, 0, 0, 0, 0, 0, 0.046487, 0, 0, 0, -0.04283, 0, 0, 0, 0.049892, -0.048272, -0.084313, 0.021002, -0.12778, -0.018955, 0.024201, 0, 0.016427, -0.049224, 0.04356, -0.082732, 51401e-7, -0.029967, 0.041281, -0.02351, -66707e-7, 0.039986, -0.11837, 78793e-7, -0.10802, 0.054786, -0.032356, 0.097517, -25863e-7, 0, -0.15986, -0.014649, -0.020449, 0.071434, 0.029209, -0.12488, -0.034113, 0.014438, -0.13194, -57964e-7, 0.12533, -0.024238, -0.069328, 0, 0.13724, -0.032544, 0.051254, -0.10671, 8457e-6, -0.15378, 0.020007, 0, -94621e-7, 0.069534, -0.011562, 0.039164, -0.017162, 0, 0.098197, 0.014499, 0.032261, -0.051474, 0.11024, -17162e-7, 0.060177, -0.074861, -0.15746, 0, -0.015913, 0, 0, 0, 44952e-7, 0, 0.13828, 0, -0.081701, 0.032823, -0.03152, 0.089107, 0.015357, 0.12929, 37121e-7, 0, 48569e-7, -0.035331, 0.081198, -0.023418, -0.046096, 0.011596, 0.10078, -62143e-7, -0.01174, -0.16655, 0.016809, 0, 0.031727, 0, 0, 0, -0.088292, 0, 0, 0, 0, 0, 0, 0, 34244e-7, 0.046799, 0.017108, -0.16899, -146e-5, -0.11294, -86982e-8, 0.083014, 1379e-6, -0.014092, -0.074625, 0.092358, -0.1252, 0.026724, 0.14448, -12114e-7, -0.01348, 0.051631, -0.096134, 0, 0.027196, 0, 0.14104, 0, 0.018466, -0.07275, 0.12551, 0.038002, -0.074364, 0.06714, -0.12508, 0.021394, -0.013158, -0.2091, -0.090769, 0.063508, 0.043259, -0.11867, 0.10997, 0, -0.061354, 0.054383, 87675e-7, -0.025932, 0.069052, -0.047497, 0.09614, -0.04538, -0.037436, 0.054846, -0.16423, -0.011058, -67032e-7, 0.083432, 0.023966, 0.13873, 0.079415, 0, -0.011765, 0, -0.02855, 0.062349, -0.066807, 67372e-7, -0.028091, -0.14046, 1795e-6, 0, -0.040078, 0, 0.075265, 0, -22216e-8, 0.025852, -0.083628, 47734e-7, -29351e-7, -0.10202, 0.091706, -0.054675, 49582e-8, 0.043259, -0.035803, 0, 0.077701, 0, 56232e-7, 0, -0.082122, 0, 0, 0, 0, 0, 0, 0, 0.040111, 0, 0, 0, 0, 0, 0, 0, -4736e-7, 0.036989, -0.07113, 0.019354, -21085e-8, 0.084813, -0.028817, 0, 0.016399, -0.090104, 0.04557, 0, -0.075399, 0.061857, -0.02894, 0.090185, -0.019948, 0.06452, -0.053624, 0, -0.01932, 0, -0.10565, 0, -0.046083, 0, 0, 0, 56372e-7, 0, 0.095632, 0, 0.072401, -0.056473, -0.095322, 0, -54519e-7, 0.10486, -0.059186, 0.05208, -0.090862, 0, 0, 0, -0.059152, 0, 40407e-7, 0.075818, 0.023541, 0, 0, 0, -0.012171, 0, -0.109, 0, -82365e-7, 0.010551, 0.023798, -0.14501, -0.013234, 0.03534, -0.1121, 0.010917, -0.017687, 0, 0, 0, 0.051828, 0, 0, 0, -0.096246, 0, 0.021185, -0.061406, 0.042289, 0, -0.030129, 0, -0.073371, 0, 0, 0, 0, 0, 0, 0, -0.030231, 0.041888, -0.099148, 0.016334, -84693e-8, -0.031174, -0.029597, 0.042749, 0.057697, -0.038531, -0.045459, 0.084836, 0.01991, -0.089102, 0.098096, -0.068546, -0.024574, 34075e-7, 56476e-7, -0.1519, 0.099905, -0.028271, 0.027696, -0.07069, 0.023926, -0.089018, 0.052613, 0, -0.11073, 0, -17871e-7, 0, 0.034805, 0, 0, 0, 0, 0, 0, 0, -17624e-7, 0.054975, -0.073771, 0.053292, -0.04409, 0.032918, -0.10589, 0, -0.040952, 0.040368, -0.1467, -0.011103, 0.036183, -0.068113, 0.13565, 0.024473, -0.011316, 0.0615, -0.016938, 0, -0.05374, 0, 0.016534, 0, -0.058042, 0.028406, -0.11065, 0, -0.039548, 0, 0.067803, 0, -40078e-7, 0.053614, -0.10499, 0.037209, -0.070159, 0.063901, -0.044992, 0.082937, 0.035033, -0.024661, 0.093549, -0.018313, -0.027553, 0, 0.15641, 0, -0.068142, -8006e-6, 0.046173, -0.087695, 0.084142, -0.029607, -0.072893, 0.029938, 0.097495, 0, 0, 0, -89587e-7, 0, 0, 0, -0.062636, 0.049858, 0.033583, -0.011686, -0.011819, -0.077281, 0.11728, -0.04263, 0.094023, -0.064688, 0.018571, -0.054869, 0.054816, -0.025101, -0.077111, 0.12447, -0.080208, 0.032175, 0.10619, -0.026948, 0.044988, -0.043586, 0.035888, -0.15549, 0.10289, -0.081816, -0.062961, 0.017548, 0.12173, 79593e-7, 0.048087, -0.052038, -48578e-7, 0.07936, -0.028667, 0, -0.084679, 0, -0.055043, 0.056624, -0.058637, 0, 0, 0, 0, 0, 0, 0, 0.017949, 0, 0, 0, -0.010623, 0, -0.10089, 0, -0.024741, 0.09267, -0.037683, 0, 0.017495, -0.08733, -17206e-7, 0.030103, -0.020631, 0.037982, -0.07277, 0.017193, -0.071013, 0.049577, 0.055074, -0.051208, 0.068817, -0.091669, 64682e-7, 0.090505, 0.13803, 0.02049, -53464e-8, 0, -0.059998, 0.066297, -0.018851, -0.11675, 0.096206, -34643e-7, -0.071539, 0.025012, -0.024888, 0.064844, 0.15481, 0.012736, 42901e-7, -0.037584, -0.060621, 0.019117, 24629e-7, -0.030689, -0.091479, -68942e-7, -0.01967, 0.041313, 0.016918, 0.097876, -0.065399, 0.014023, 0.069674, -0.015819, -25726e-7, -0.13065, 0.051227, -0.069298, -0.07594, 0, 0, 0, 0, 0, 0, 0, 0.033386, 0, 0, 0, 0, 0, 0, 0, 0.046566, -0.043066, 0.018075, -0.11143, 0.033705, -0.072396, -0.028093, -0.14962, 0.070676, -0.029298, 0.041516, -0.086733, 0.059211, -0.063577, -0.011734, 0.097562, -0.019105, 0.027536, -0.036594, 0.029791, -0.020464, -0.17061, 0.012298, -0.045872, 0.032919, -0.10686, -0.016498, 0.10019, -0.059879, 84058e-7, 0.077123, 0, 0.050061, -1209e-6, -0.098278, 0.01663, 0.010824, -0.093375, -1494e-6, 0.037135, 72528e-7, -0.062714, 0.078, 0, 0.03689, 0, -0.028829, -0.11571, -0.011079, 0, 0.029034, 0, 0.083556, 0, 0, 0, 0.022749, 0, 0, 0, -0.044617, 0, 0, 0, -37082e-7, 0.098453, -0.067431, 0.01461, 0.10397, 0, -0.017818, 0, 0.029814, -0.10073, -0.041792, 0.075505, -0.047232, 0.033078, -0.042624, 41926e-7, -0.067843, 0, 0, 0, 0, 0, 0, 0, 82708e-8, 0, 0, 0, 0, 0, 0, 0, -15657e-7, 0.017263, -0.028349, 23201e-7, 79103e-7, -0.10576, -0.03311, 0.14053, -0.072866, 0, 0, 0, 42304e-7, 0, 0.02036, 0.11578, 0.017952, -0.063042, 0.018363, 0.096834, -0.050257, 0.073149, -0.11434, 0.021654, 0.025309, -0.14751, -0.068238, 0.0644, 0.052156, -0.074221, 0.10291, 0, -0.020212, 0.035862, -0.089531, 0.014962, -0.083256, 0.010995, -0.013033, 17731e-7, 0.080368, -0.03904, -0.080374, 0, -0.080963, 0, 0, 0, -8666e-6, 0, 0.027735, 0, 0.079129, 0, 0, 0, -0.040607, 0, 0, 0, 0.024221, 0, 0, 0, 25431e-7, 0.024761, 0.027613, -0.054994, -0.044259, 0.023344, -0.074647, 0.058446, 0.0401, -0.058356, -0.1152, 0, 0.019262, -0.11489, -0.063693, 0.072207, -0.010403, 0.042492, 0.075728, -0.063659, -0.047093, 0.031363, 0.05706, -0.089045, -0.011916, 0, 0.082811, 0, -0.015375, -0.14935, -0.092823, 0.038853]
4079
+ };
4080
+ var BLOCK_STACK_MODEL = {
4081
+ kind: "trees",
4082
+ depth: 5,
4083
+ base: -0.422449,
4084
+ features: [57, 57, 57, 60, 61, 62, 57, 48, 65, 64, 3, 51, 6, 50, -1, -1, 31, 6, 54, 51, 48, 59, 63, 52, 62, 40, 61, 40, -1, -1, -1, 57, 57, 57, 62, 62, 62, 57, -1, 63, 63, 48, 59, 58, 50, 61, -1, -1, 28, 51, 54, -1, 57, -1, 52, 54, 48, 50, 30, -1, 2, -1, 57, 57, 57, 62, 62, 61, 57, -1, 63, 64, 41, 58, 6, 30, 25, -1, -1, 54, 49, 65, 54, 59, 54, 7, 54, 3, 59, 52, 51, 60, 49, 60, 57, 57, 61, 58, 62, 57, -1, 28, 54, 63, 41, 2, 50, 40, -1, -1, 63, 32, 63, 24, 50, -1, 30, 40, 30, 52, 52, -1, 60, 48, 57, 57, 57, 62, 64, 62, 57, -1, 63, 62, 48, 59, 6, 30, 53, -1, -1, 54, 49, 65, 54, -1, -1, 7, 30, 3, 63, 62, 45, 40, 61, 61, 57, 57, 62, 64, 57, 57, -1, 63, 59, 60, 3, 58, 50, 40, -1, -1, 28, 49, 63, 52, -1, -1, 58, 63, 30, 15, 60, -1, 61, 48, 61, 61, 57, 62, 51, 57, 25, -1, 32, 62, 65, 3, 43, 57, 51, -1, -1, 60, 60, 52, 53, 64, 53, 8, 63, 32, 63, 65, 40, -1, 1, 57, 61, 57, -1, 56, 62, 57, -1, -1, 59, 54, 54, 59, 65, 40, -1, -1, -1, -1, 65, 65, 51, 47, 52, 47, 45, 8, 31, 62, 62, 48, 60, 62, 57, -1, 54, 57, 57, -1, -1, 65, 63, 51, 7, 25, 40, -1, -1, -1, -1, 65, 31, 59, 32, 62, 65, 63, 65, 40, 46, 61, 48, 60, 62, 57, -1, 54, 60, 31, -1, -1, 65, 51, 63, 15, 39, 53, -1, -1, -1, -1, 65, 56, 28, 48, 41, 49, 30, 43, 65, 50, 65, 61, 57, 62, 57, -1, 32, 58, 57, -1, -1, 60, 64, 54, 8, 31, 40, -1, -1, -1, -1, 62, 63, 40, -1, 56, 54, 58, 54, 43, 53, 61, 50, 57, 62, 57, -1, 32, 59, 57, -1, -1, 60, 64, 54, 6, 65, 40, -1, -1, -1, -1, 42, 63, 61, -1, 63, 59, 25, 63, 53, 62, 61, 50, 57, 62, 57, -1, 32, 58, 31, -1, -1, 60, 64, 30, 8, 40, 53, -1, -1, -1, -1, 63, 45, 61, -1, 38, 40, 56, 65, 48, 23, 65, 61, 62, 62, 57, -1, 40, 57, 40, -1, -1, 51, 40, 59, 63, 61, 42, -1, -1, -1, -1, 58, -1, 28, 59, 40, 61, 62, 30, 54, 41, 53, 62, 61, 7, 57, -1, 54, 56, 40, -1, -1, -1, 64, 65, 15, 61, 42, -1, -1, -1, -1, -1, -1, -1, -1, 65, 54, 58, 45, 12, 41, 53, 62, 62, 62, 57, -1, 40, 45, 40, -1, -1, 51, 56, 61, 11, 61, 31, -1, -1, -1, -1, 41, -1, 65, 40, 52, 15, 1, -1, 54, 41, 63, 53, 61, 60, 57, -1, 54, 63, 40, -1, -1, 7, 59, 59, 32, 2, 50, -1, -1, -1, -1, -1, -1, 51, 49, 65, 52, 6, 58, 54, 65, 41, 41, 62, 62, 62, -1, 48, 63, 2, -1, -1, -1, -1, 65, 2, 25, 7, -1, -1, -1, -1, -1, -1, -1, -1, 12, 63, 44, 48, 40, 49, 62, -1, 60, 59, 57, -1, -1, 59, 40, -1, -1, -1, -1, 40, 45, 57, 48, -1, -1, -1, -1, -1, -1, -1, -1, 65, 28, 12, 11, 54, 41, -1, 54, 60, 59, 63, -1, -1, 61, 2, -1, -1, -1, -1, 65, 65, 30, 60, -1, -1, -1, -1, -1, -1, -1, -1, 32, 64, 31, 40, 44, 51, 56, 6, 60, 59, 59, -1, -1, 12, 53, -1, -1, -1, -1, 63, 41, -1, 31, -1, -1, -1, -1, -1, -1, -1, -1, 40, 50, -1, 41, -1, -1, 60, 2, 62, 24, 63, 57, -1, 33, 2, -1, 64, -1, -1, 25, -1, 30, 61, -1, -1, -1, -1, -1, -1, -1, -1, 49, 31, -1, -1, 44, 51, 62, 6, 60, 59, 57, -1, -1, 40, 40, -1, -1, -1, -1, 65, 54, 41, 24, -1, -1, -1, -1, -1, -1, -1, -1, 65, 54, 53, 51, 42, -1, 41, -1, 62, 59, 63, -1, 40, 65, 2, -1, -1, -1, -1, 51, 40, 30, 65, -1, -1, -1, -1, -1, -1, -1, -1, 32, 63, 31, 49, 44, 51, 56, -1, 60, 59, 58, -1, -1, 12, 54, -1, -1, -1, -1, 33, 41, 25, 40, -1, -1, -1, -1, -1, -1, -1, -1, 40, -1, -1, 41, 6, -1, 27, 61, 60, 65, 45, -1, -1, 58, 1, -1, -1, -1, -1, 24, 31, 13, 30, -1, -1, -1, -1, -1, -1, -1, -1, 54, 65, 52, 52, 3, -1, 42, -1, 57, -1, 63, -1, -1, 7, 25, -1, -1, -1, -1, 50, 48, 65, 56, -1, -1, -1, -1, -1, -1, -1, -1, 65, 52, 59, 40, 32, 59, 9, 65, 62, 59, 65, 7, 38, 47, 65, 8, -1, 45, 41, 50, 24, 65, 6, -1, -1, -1, -1, 51, 31, -1, -1, 63, 59, 40, -1, 42, 40, 40, 42, 57, -1, 12, -1, -1, 33, 58, -1, -1, -1, -1, 52, -1, -1, 41, -1, -1, -1, -1, -1, -1, -1, -1, 52, 65, -1, -1, -1, -1, 1, -1, 61, 52, 42, -1, -1, 25, 15, -1, -1, -1, -1, 63, 56, 65, 57, -1, -1, -1, -1, -1, -1, -1, -1, 26, 6, 50, 48, 10, 65, 47, 50, 59, 32, 40, 40, -1, 63, 31, 65, 49, -1, -1, 31, 15, 1, 65, -1, 48, 50, 31, -1, -1, -1, -1, 8, 52, -1, 50, 54, 65, 38, 52, 57, -1, 7, -1, -1, 2, 48, -1, -1, -1, -1, 63, 40, -1, 52, -1, -1, -1, -1, -1, -1, -1, -1, 65, 41, 13, 65, -1, -1, 65, 40, 59, 32, 12, 40, 64, 33, 41, 41, 49, -1, -1, 52, -1, 41, -1, -1, 42, 40, 31, -1, -1, -1, -1, 52, 52, -1, -1, -1, 61, -1, -1, 57, -1, 65, -1, -1, 65, 6, -1, -1, -1, -1, 65, 40, 54, 42, -1, -1, -1, -1, -1, -1, -1, -1, 25, 27, 54, 52, -1, -1, -1, 61, 59, 32, 12, 63, 52, 42, 51, 65, 50, -1, -1, 40, 50, 65, 43, 64, 47, 1, 40, -1, -1, -1, -1, 62, -1, 65, 48, -1, -1, -1, -1, 21, 48, 39, 15, 50, 65, -1, 48, 4, 52, 2, -1, -1, -1, -1, 52, 50, 7, 65, 56, 41, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, 63, 40, 8, 31, 59, 31, 49, 42, 41, 64, 31, 26, 50, 39, -1, 6, 41, 1, -1, 62, 32, 62, 64, 1, 40, -1, 54, -1, -1, -1, -1, 63, 7, 25, 65, 65, 65, 56, 11, 65, 65, 51, 52, 49, 40, 6, 49, 52, 24, 31, 56, 60, 60, 65, 61, 55, 31, 58, -1, -1, 42, 52, 33, 42, -1, 65, 62, -1, -1, 31, 9, 58, 40, -1, -1, -1, -1, 52, 49, 54, 56, 41, 52, 48, 63, -1, -1, -1, -1, -1, -1, -1, -1, 12, 33, 51, 42, -1, 65, 43, 40, 48, -1, -1, -1, -1, -1, -1, 62, -1, 54, 48, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 60, -1, 7, -1, -1, 2, 48, -1, -1, -1, -1, 7, 40, -1, 52, -1, -1, -1, -1, -1, -1, -1, -1, 63, 1, 52, 50, -1, -1, 52, 40, 50, 48, 31, 63, 52, 63, 62, 16, 56, 62, 41, -1, 59, 62, 1, 42, 53, -1, 42, -1, -1, -1, 51, -1, -1, -1, -1, 44, 52, 57, 61, 30, 38, 41, 65, 61, 54, 50, 24, 21, 59, 58, -1, 59, -1, 61, 40, 62, 42, 65, -1, 54, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 12, 33, 51, 52, -1, 65, 48, 52, 65, -1, -1, -1, -1, -1, 60, 40, 40, -1, 50, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 63, 7, 60, 65, 47, 26, 24, 8, 65, 40, 1, 25, 1, 52, 1, 6, 43, 24, 54, 50, 63, 54, 40, 49, 60, 56, 6, 60, 60, 65, 31, 2, 64, 61, 57, 44, 40, 13, 41, 59, 54, 52, 63, 40, 35, 48, 63, 62, 54, 47, -1, 32, 58, 65, 52, 47, 50, 47, 31, -1, -1, -1, 42, 13, 26, 58, 30, 51, 47, 61, 2, 59, 63, 49, 50, 51, 65, 62, 52, 23, 47, 65, 24, -1, -1, 31, 16, 65, 32, 60, 43, 11, 54, 50, 48, 31, 63, 41, 63, 52, 8, 32, -1, 40, -1, 59, 31, 23, 43, 58, 26, 8, -1, -1, -1, 65, -1, -1, -1, -1, 61, 40, 62, 8, 65, 56, 65, 65, 51, 53, 57, 32, 48, 59, 10, 23, 52, 52, 15, 63, 64, -1, 64, 31, 3, 42, 65, -1, -1, 7, 6, 40, 65, 59, 42, 12, 50, 41, 65, 48, -1, 42, 65, 3, 43, 52, -1, -1, 46, -1, 42, 54, -1, -1, 56, 40, 58, 30, -1, -1, -1, -1, 1, -1, -1, -1, 12, 33, 51, 65, -1, 65, 43, 65, 54, -1, -1, -1, -1, -1, -1, 45, 23, 55, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, 65, 42, 62, 40, 45, 42, 62, 50, 52, -1, -1, -1, 32, -1, 6, 52, 52, 42, 45, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 12, 55, 64, 51, 65, -1, 65, 24, 65, 41, -1, -1, -1, -1, 55, 65, 52, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 63, 62, 43, 48, 24, 56, 40, 40, 8, -1, 63, -1, 60, 40, -1, 45, 62, -1, 31, -1, -1, -1, -1, -1, -1, 42, 57, 15, 45, -1, -1, 52, 52, 65, 42, 6, -1, 3, 62, 42, 59, 23, -1, -1, 39, -1, 64, 11, 64, 57, 63, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 7, 2, 56, 47, 60, 65, 9, 49, 52, 1, 7, 54, -1, 45, -1, 64, 54, 54, 51, 47, 51, 45, 45, -1, -1, -1, -1, 40, 65, -1, -1, 59, 65, 40, 30, 24, 2, 65, 38, 57, 31, 40, 31, -1, 40, -1, 48, 61, 51, 59, 47, 31, 54, 59, -1, 41, -1, -1, -1, 62, -1, -1, 60, -1, 65, -1, -1, 23, 21, -1, -1, -1, -1, 31, -1, 57, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, 60, -1, -1, 49, 42, -1, -1, 40, 43, 52, 1, 43, 65, 65, 10, 51, 65, 54, 40, 54, -1, 1, 54, 40, 31, 2, -1, 61, 24, 24, 1, 6, 65, 39, -1, -1, -1, 58, 65, 65, 65, 55, 59, 52, 51, 65, 61, 55, 42, 60, 51, 61, 58, 65, 31, 48, 31, 50, -1, 49, 63, 63, 31, 51, 62, 52, 51, 31, 60, 52, 65, 52, 65, 30, 62, 31, 63, 15, 51, -1, 61, 48, 9, 62, 8, 1, 62, 41, 40, -1, -1, -1, -1, 60, 65, -1, 26, 41, 62, 41, 42, 45, 50, 62, 53, 15, 48, -1, -1, -1, -1, 47, 54, 43, 15, -1, -1, -1, -1, -1, -1, -1, -1, 63, 65, 61, 60, 56, 40, 40, 61, 59, 52, 54, 40, 51, 25, 61, 2, 65, 40, -1, 63, -1, 65, 24, 54, 40, 63, 63, 51, 48, -1, -1, 40, 40, -1, -1, 40, 26, -1, -1, 65, 65, 49, 55, 55, 50, 40, 65, 61, 53, 2, 24, 11, 40, 52, 51, 31, 15, 31, 39, 8, 63, -1, 61, 32, 40, 59, 7, 63, 39, -1, 63, 40, 8, 31, 62, 31, 44, 42, 41, 48, 24, 26, 50, 50, -1, 2, -1, 44, -1, 16, 50, -1, 63, 1, -1, 41, 57, -1, -1, -1, -1, 65, 57, 6, 6, 63, 43, 47, 41, 40, 65, 58, -1, -1, 61, -1, 62, 62, 6, 3, 42, 50, 46, 30, -1, -1, -1, -1, -1, -1, -1, -1, 12, 33, 30, 57, -1, 52, -1, 47, 23, -1, -1, 65, 43, -1, -1, 65, 65, 63, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 64, 62, 52, 65, 43, 41, 51, 65, 31, 10, 42, 52, 42, 23, 62, 41, 40, 59, 41, 1, 54, 10, 43, 56, 65, 65, 62, 50, -1, -1, -1, 19, 65, -1, 24, 7, -1, -1, -1, -1, 31, 48, -1, -1, -1, -1, -1, -1, -1, -1, 46, 51, -1, 52, -1, -1, -1, -1, -1, -1, -1, -1, 12, 33, 30, 37, -1, 52, -1, 57, 65, -1, -1, 65, 43, -1, -1, 65, 52, -1, -1, -1, -1, -1, -1, 45, -1, -1, -1, -1, -1, -1, -1, 64, 64, 24, 42, 47, 53, 60, 9, 29, 54, 41, 52, 65, 39, 47, 13, 59, 65, 62, 57, 65, 63, 31, 65, 11, 31, 65, 65, 41, -1, -1, 6, 1, 40, 45, 46, 40, 65, 65, 48, 60, -1, 43, 54, 1, 52, 65, 40, 54, 54, -1, -1, -1, -1, 54, 45, 49, -1, -1, -1, 51, 50, 45, 25, 11, 49, 6, 46, 65, 60, 30, 63, 48, 51, 52, -1, -1, 40, 31, 40, 65, 7, 1, 50, 7, 59, 65, 7, -1, -1, -1, -1, -1, 43, 43, 2, 50, 1, 7, 44, 63, 26, 10, 62, 1, 42, 7, 65, 51, 53, 41, 6, 63, 63, -1, 59, 65, 42, 60, -1, 45, -1, -1, -1, 60, 59, 49, 65, 61, 59, -1, 65, 60, 61, 54, 57, 52, -1, -1, 52, 27, 24, 48, -1, 24, -1, 42, -1, -1, 52, 51, -1, -1, -1, -1, 57, 60, 52, 59, 7, 31, 24, 24, 24, 45, -1, 65, 54, 42, 52, 27, 65, 54, 56, 6, -1, -1, -1, 41, 50, 41, 46, 30, 48, 41, 52, 63, 57, 63, 52, 51, 1, 7, 50, 63, 40, 52, 43, 3, 51, 40, 51, 47, 52, 1, 54, 53, 54, 31, -1, -1, 30, -1, 54, 61, 1, 9, 60, 61, 49, 57, 52, 40, -1, 6, 1, 63, 49, -1, 59, -1, -1, 51, 45, 42, 41, -1, 47, 65, 41, -1, -1, 57, 52, -1, -1, -1, -1, 12, 1, 41, 11, 1, -1, 42, 54, 65, 54, 26, -1, -1, 41, 45, 65, 30, -1, 60, -1, -1, 3, 3, -1, -1, -1, -1, -1, -1, -1, -1, 21, 57, 63, 41, 63, -1, 40, 40, 62, 31, 50, -1, -1, -1, -1, 52, 52, 65, 54, 52, 62, 52, 62, -1, -1, -1, -1, -1, -1, -1, -1],
4085
+ thresholds: [-0.3571366, -2.305675, 1.822552, 0.04795042, 0.2888775, 0.4777274, 3.050203, 4.919404, 0.05745253, 5.921578, 0, 0.5546955, 0.01923077, 10.24495, 0, 0, 0.3333333, 0.02316602, 4077529e-10, 0.9844254, 1.783998, 0.3029593, 0.02156334, 6.907755, 0.4310797, 0.075, 0.4741301, 0.075, 0, 0, 0, -0.6342732, -2.573136, 1.293191, 0.02469485, 0.2547487, 0.4310797, 3.050203, 0, 0.3849332, 0.9415143, 4.327618, 0.1943059, 0.2829656, 10.24495, 0.6971402, 0, 0, 0, 0.8793104, 4077529e-10, 0, -1.764177, 0, 3.526361, 0.3807987, 3.013335, 10.24495, 0.5, 0, 0, 0, -0.6342732, -2.870405, 1.56783, 0.02469485, 0.168831, 0.4741301, 2.734421, 0, 0.3849332, 6.452049, 0.5471264, 0.2829656, 0.01219512, 0.5, 0, 0, 0, 0, 0.8571429, 0.07333041, 0, 0.1943059, 0.2781682, 0.5, 0.3807987, 1.098612, 0.3029593, 4.836282, 0, 0.6289944, 0, 0.3867758, -2.573136, 2.107917, 0.02734554, 0.1222605, 0.523972, 3.394045, 0, 0, 4077529e-10, 0.6774194, 0.8773364, 0.5827814, 10.24495, 0.525, 0, 0, 0.3849332, 0.1666667, 0.1653979, 0, 6.759255, 0, 0.1666667, 0.3, 0.5, 8.501063, 3.044523, 0, 0.6289944, 4.327618, -0.9371337, -2.870405, 1.56783, 0.02469485, 6.452049, 0.4310797, 3.050203, 0, 0.3849332, 0.1305989, 1.827123, 0.1943059, 0.01219512, 0, 0, 0, 0, 0, 0.8571429, 0.07333041, 4077529e-10, 0, 0, 0.4166667, 0, 1.098612, 0.1004045, 0.7495036, 2.197225, 0.225, 0.6971402, 0.2888775, -2.870405, 2.107917, 0.02469485, 6.452049, 0.4436583, 3.808074, 0, 0.3849332, 0.1943059, 0.1063413, 1.098612, 0.7306943, 10.24495, 0.525, 0, 0, 0.25, 0.8571429, 0.1360049, 7.257003, 0, 0, 0.2829656, 0.01989664, 0.5, 0, 0.9078827, 0, 0.6971402, 4.327618, 0.2888775, 0.06896514, 2.414095, 0.02469485, 0.9844254, 0.708554, 0, 0, 0, 0.319699, 0.288416, 1.098612, 1.94591, 3.808074, 580011e-8, 0, 0, 0.01315065, 0.1063413, 6.349139, 0, 4.060443, 0, 1.386294, 0.01989664, 0.3333333, 0.01412086, 0.7190987, 0.525, 0, 4.61512, -1.764177, 0.02734554, 2.414095, 0, 0, 0.4310797, 3.808074, 0, 0, 0.08752622, 4077529e-10, 0.6849968, 0.3029593, 0.7190987, 0.525, 0, 0, 0, 0, 0.05745253, 0.1132073, 0.2429577, 0.6, 4.276666, 0.38, 2.302585, 0.6931472, 0.1666667, 0.9522486, 0.523972, 4.327618, 0.1063413, 0.02469485, 2.414095, 0, 4077529e-10, 0.1775001, 3.808074, 0, 0, 0.1423904, 0.1653979, 0.9844254, 0.75, 0, 0.525, 0, 0, 0, 0, 0.1132073, 0.25, 0.08752622, 0.25, 0.2547487, 0.5076258, 0.5579418, 0.623239, 0.075, 0, 0.6971402, 4.327618, 0.1063413, 0.02469485, 2.734421, 0, 4077529e-10, 0.5678395, 0.25, 0, 0, 0.1423904, 0.03852465, 0.6774194, 0, 0, 0, 0, 0, 0, 0, 0.1132073, 0, 0, 4.919404, 0.9245283, 0.01906447, 0.5, 2.397895, 0.4225708, 7.470224, 0.7190987, 0.7527024, -2.870405, 0.02469485, 2.734421, 0, 0, 0.2829656, 3.808074, 0, 0, 0.01315065, 4.828314, 4077529e-10, 0.6931472, 0.2, 0.325, 0, 0, 0, 0, 0.1031566, 0.3849332, 0.275, 0, 0, 0.6849968, 0.8268518, 3187076e-9, 2.890372, 0, 0.6971402, 8.007034, -2.870405, 0.01811626, 2.734421, 0, 0, 0.3029593, 3.808074, 0, 0, 0.01315065, 4.94876, 4077529e-10, 0.01219512, 0.8339582, 0.325, 0, 0, 0, 0, 0.2088739, 0.3849332, 0.4741301, 0, 0.1653979, 0.1349982, 0, 0.1004045, 0, 0.9648098, 0.6971402, 8.007034, -2.870405, 0.01811626, 3.050203, 0, 0, 0.8268518, 0.25, 0, 0, 0.01315065, 4.94876, 0.5, 0, 0.225, 0, 0, 0, 0, 0, 0.04531459, 3.258096, 0.4741301, 0, 0, 0.125, 0, 0.3921823, 2.848795, 0, 0.7190987, 0.6971402, 0.06896514, 0.01811626, 3.394045, 0, 0.1, 0.9928667, 0.225, 0, 0, 0.9521739, 0.35, 0.08752622, 0.02319472, 0.6971402, 0.5859071, 0, 0, 0, 0, 0.3843654, 0, 0, 0.05435247, 0.075, 0.7957155, 0.9206775, 0, 0.6849968, 0.8773364, 0, 0.9648098, 0.02734554, 0.4166667, 3.394045, 0, 9922371e-10, 0, 0.225, 0, 0, 0, 2.833213, 0.4225708, 0, 0.6971402, 0.5859071, 0, 0, 0, 0, 0, 0, 0, 0, 0.3583294, 0.898181, 0.6741498, 4.234107, 0, 0.8773364, 0, 0.9648098, 0.05218401, 0.01811626, 3.394045, 0, 0.1, 4.859812, 0.225, 0, 0, 0.9521739, 0, 0.4741301, 0, 0.6971402, 0.25, 0, 0, 0, 0, 0.2485207, 0, 0.4937787, 0.25, 6.466145, 0, 4.007333, 0, 0.5889103, 0.8773364, 0.5579418, 0, 0.02734554, 5903513e-9, 3.808074, 0, 0, 0.08640844, 0.325, 0, 0, 0.1551724, 0.06987459, 0.1090793, 0.25, 0.05882353, 8.007034, 0, 0, 0, 0, 0, 0, 0, 0.8974359, 0.7652995, 9.083983, 0.01591512, 0.4305397, 0.1012539, 0.7190987, 0.3428572, 0.6415094, 0.02469485, 0.01811626, 0.9206775, 0, 2.19474, 0.5579418, 0.4375, 0, 0, 0, 0, 0.7917553, 0.4375, 0, 0.03149606, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4032821e-9, 0.9047619, 3.38491, 0.075, 5307856e-9, 0.9385887, 0, 5903513e-9, 0.3444971, 3.808074, 0, 0, 0.08752622, 0.325, 0, 0, 0, 0, 0.1, 4.859812, 4.271065, 4.327618, 0, 0, 0, 0, 0, 0, 0, 0, 0.1212097, 0, 0, 0, 0.5889103, 0.8773364, 0, 0.4973886, 5903513e-9, 0.3444971, 0.5579418, 0, 0, 0.9021136, 0.4375, 0, 0, 0, 0, 0.135235, 0.7190987, 0.1666667, 0.1718593, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.484907, 0.1666667, 0.225, 0.9047619, 0.03852465, 0, 0.03191489, 5903513e-9, 0.3444971, 0.9408998, 0, 0, 0, 0, 0, 0, 0, 0, 0.08640844, 0.01279318, 0, 0.25, 0, 0, 0, 0, 0, 0, 0, 0, 0.2, 4.624973, 0, 0.8143564, 0, 0, 0.9574098, 0.2533333, 0.01811626, 0, 0.5579418, -4.433688, 0, 0.1666667, 0.4375, 0, 2.833213, 0, 0, 0, 0, 0.1666667, 0.1829779, 0, 0, 0, 0, 0, 0, 0, 0, 0.04799343, 0.3333333, 0, 0, 0.9047619, 0.03852465, 0.06896514, 0.03191489, 5903513e-9, 0.3029593, 4.271065, 0, 0, 0.25, 0.325, 0, 0, 0, 0, 0.5972933, 0.6849968, 0.8616044, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5651671, 0.08483563, 0, 0.6842105, 0.7175612, 0, 0.6100386, 0, 0.01811626, 0.06987459, 0.5579418, 0, 0.175, 0.135235, 0.4375, 0, 0, 0, 0, 0.7480315, 0.075, 0.1666667, 0.666607, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.02156334, 0, 0.68, 0.9047619, 0.03852465, 0, 0, 5903513e-9, 0.3029593, 0.8608962, 0, 0, 0, 0.5889103, 0, 0, 0, 0, 0, 0.02836879, 0, 0.325, 0, 0, 0, 0, 0, 0, 0, 0, 0.2, 0, 0, 0.8143564, 0.02702703, 0, 0, 0.975294, 5903513e-9, 0.6503634, 4.859812, 0, 0, 0.1533769, 2.944439, 0, 0, 0, 0, 0, 0.2, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.3368467, 8.091627, 7.553287, 0, 0, 0.5859071, 0, -5.875155, 0, 0.06097378, 0, 0, 0.03149606, 0, 0, 0, 0, 0, 5.686975, 1.098612, 0.288416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5076258, 7.553287, 0.5073434, 0.2, 0.1666667, 0.3444971, 0, 0.666607, 0.05218401, 0.04025599, 0.07333041, 0.4166667, 0, 0.4, 0.8675887, 0.6931472, 0, 2.564949, 0.6257669, 4.430817, 0, 0.8163886, 0, 0, 0, 0, 0, 0.9698997, 0.3333333, 0, 0, 5965638e-9, 0.2266646, 0.1, 0, 3111111e-9, 0.275, 0.175, 0.03651913, -5.875155, 0, 0, 0, 0, 0, 0.05888302, 0, 0, 0, 0, 9.083983, 0, 0, 0.7987013, 0, 0, 0, 0, 0, 0, 0, 0, 8.501063, 0.238377, 0, 0, 0, 0, 2.564949, 0, 6141095e-9, 3.367296, 0.5077296, 0, 0, 0, 0, 0, 0, 0, 0, 0.6774194, 0, 0.1726634, 0.9928667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.01219512, 4.356709, 2.560159, 0, 0.4225708, 0.7846154, 7.017506, 0.06987459, 0.25, 0.075, 0.1, 0, 0.5579418, 0.2, 0.1212097, 0.08144234, 0, 0, 0, 0, 0, 0.5972933, 0, 4.153444, 4.997212, 0.5, 0, 0, 0, 0, 1.386294, 5.9428, 0, 7.251345, 0.04629841, 0.4561477, 0, 7.553287, -5.875155, 0, 0.75, 0, 0, 0, 1.098612, 0, 0, 0, 0, 0.1168487, 0.35, 0, 6.55108, 0, 0, 0, 0, 0, 0, 0, 0, 0.5076258, 0.6100386, 0, 0.5076258, 0, 0, 0.4446793, 0.2, 0.06987459, 0.25, 0, 0.1, 4.477337, 0, 0.7987013, 0.28, 0.08144234, 0, 0, 9.083983, 0, 0.0754717, 0, 0, 0.5077296, 0.2, 0.5, 0, 0, 0, 0, 8.501063, 10.0538, 0, 0, 0, 0.8804404, 0, 0, -5.875155, 0, 0.8675887, 0, 0, 0.8163886, 0, 0, 0, 0, 0, 0.7652995, 0.25, 0.4973886, 0.03651913, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.4973886, 5.361292, 0, 0, 0, 0.8572058, 0.06987459, 0.25, 0, 0.1004045, 3.526361, 3111111e-9, 0.03852465, 0.5651671, 6.343881, 0, 0, 0.2, 0, 0.279601, 2.772589, 2.302585, 0.38, 2.70805, 0.1, 0, 0, 0, 0, 0.4777274, 0, 0.7190987, 1.098612, 0, 0, 0, 0, 0, 4.559038, 0, 0, 7.251345, 0.4044122, 0, 1.277376, 0, 5.521461, 0.05882353, 0, 0, 0, 0, 5.693732, 5.356586, 0.01111111, 0.4561477, 0, 0.28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5579418, 0.075, 1.098612, 0, 0.06987459, 0.3333333, 0.1794872, 0.6819527, 0.7672956, 2.079442, 0.25, 0, 7.251345, 0, 0, 0, 0.9245283, 3.091043, 0, 0.2106337, 0, 0.7001467, 4.158883, 3.555348, 0.15, 0, 0.7836897, 0, 0, 0, 0, 0.06097378, 0.03149606, 0, 0.5651671, 0.238377, 0.288416, 0, 0, 0.5972933, 0.1726634, 0.06930693, 4.983607, 0.08144234, 0.3, 0.01591512, 0, 4.276666, 0, 0.1666667, 0, 0.6289944, 0.5678395, 0.288416, 0.8286524, 0, 0, 0.7306943, 0, 0, 0.3341523, 7.698029, 0.1666667, 0.5859071, 0, 0.4446793, 0.852177, 0, 0, 0.3333333, 0, 0.7306943, 0.225, 0, 0, 0, 0, 7.257003, 0.4180328, 0.07347349, 0, 0.4684685, 5.768321, 3.590021, 0.1653979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.03852465, 3111111e-9, 0, 0.279601, 2.772589, 0.2, 0.5278115, 0, 0, 0, 0, 0, 0, 0.1031566, 0, 0.04629841, 1.098612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3075243e-9, 0, 0.75, 0, 0, 0, 1.098612, 0, 0, 0, 0, 0.3333333, 0.15, 0, 6.55108, 0, 0, 0, 0, 0, 0, 0, 0, 0.1168487, 4.61512, 7.095064, 5.924256, 0, 0, 4.644391, 0.2, 7.251345, 4.559038, 0, 0.5579418, 5.521461, 0.4771158, 0.9522486, 0, 0, 0.7495036, 0.28, 0, 0.4685111, 0.5800964, 5.236442, 0.7175612, 0, 0, 0.7175612, 0, 0, 0, 0, 0, 0, 0, 0, 0.2115385, 7.553287, 4.271065, 0.9839365, 0.5, 0, 0.72, 0.07333041, 0.1599989, 0.01440354, 4.276666, 0, 0, 0.04025599, 0.6189346, 0, 0.6474386, 0, 0.1599989, 0.075, 0.319699, 3111111e-9, 0.4044122, 0, 0.2781682, 0, 0, 0, 0, 2.564949, 0, 0, 0, 0, 0, 0, 0, 0.03852465, 9.083983, 0, 0.279601, 2.589959, 8.501063, 0.238377, 0, 0, 0, 0, 0, 0.6289944, 0.15, 0.1, 0, 10.24495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.06097378, 0.09302326, 0.8291906, 0.5651671, 0.07707246, 0, 0, 0, 0.5972933, 0.375, 2.302585, 0, 4.234107, 6.349139, 4.110874, 0.02316602, 3.135494, 0, 0.1012539, 4.276666, 8847693e-9, 0.1935484, 0.2, 0.04799343, 0.6289944, 0, 0.02702703, 0.9078827, 0.9574098, 0.5265958, 0.1666667, 0.2533333, 3.135494, 0.7957155, -0.3571366, 0.7307692, 0.175, 0, 0.9401993, 0.3444971, 0.3807987, 4.912655, 0.3849332, 0.275, 0, 2.848795, 0.06097378, 0.3717366, 0.3309545, 0.4, 0, 0, 0.09596258, 0.298683, 6.55108, 0.38, 3.465736, 0.3230769, 0.3333333, 0, 0, 0, 0.5077296, 0, 0, 0.8268518, 0.25, 0.9521739, 0.4, 0.6971402, 0.75, 0.6474386, 0.02932735, 0.1234112, 4.691348, 0.2429577, 0.4686952, 0.4310797, 6.466145, 0, 0.425, 0.1258911, 0, 0, 0, 0, 0, 0.135235, 0, 0.3202217, 3.637586, 0, 0.2781682, 7.251345, 4.559038, 0, 0.1168487, 0.3270142, 0.4771158, 7.698029, 0, 0.25, 0, 0.075, 0, 0.4685111, 0.25, 0, 4.394449, 0.5114858, 0, 0.6931472, 0, 0, 0, 0.279601, 0, 0, 0, 0, 0.8572058, 0.275, 0.523972, 0, 0.1726634, 0, 0.2053056, 0.1212097, 0.7480315, 0, -0.3571366, 0, 2.923849, 0.1943059, 0, 0, 4.912655, 6.349139, 0, 0.0131972, 1.098612, 0, 1.791759, 0.1666667, 0, 0.1745893, 0.135235, 0, 0, 0, 0.03191489, 0.15, 0.4044122, 0.4685111, 0.5859071, 0, 0, 0.0754717, 0.7300336, 1.098612, 0, 0.5275567, 0.2642521, 0, 0, 2.079442, 0, 0, 0.9, 0, 0.7175612, 0.08483563, 0, 0, 0, 0.175, 0.4753727, 0.5, 0, 0, 0, 0, 2.639057, 0, 0, 0, 0, 0, 0.03852465, 0.5972933, 0, 0.279601, 2.772589, 0.5808709, 0.3807987, 0, 0, 0, 0, 0, 0, 2.564949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.8675887, 0.8163886, 0.0700191, 0.9648098, 0.3, 3.178054, 0.941459, 0.9206775, 7.251345, 9.083983, 0, 0, 0, 0, 0, 0.02316602, 5.768321, 6.466145, 0.2254693, 2.772589, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.302585, 0.03852465, 0.4044122, 0, 0.279601, 0, 0.311186, 0.2012987, 0, 0, 0, 0, 0, 0.298683, 5.9428, 0.7972973, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5579418, 0.984237, 3.526361, 4.919404, 0, 0, 0.275, 0.075, 0, 0, 0.06097378, 0, 0.927255, 0.2, 0, 2.397895, 0.9206775, 0, 0.1666667, 0, 0, 0, 0, 0, 0, 0.0700191, 3.394045, 0, 3.367296, 0, 0, 9.083983, 8.823206, 0.238377, 3111111e-9, 0.03191489, 0, 1.098612, 0.523972, 0.3341523, 0.7388909, 0, 0, 0, 0, 0, 2.302585, 0, 1.098612, 1.56783, 0.1168487, 0, 0, 0, 0, 0, 0, 0, 3.135494, 0, 0, 0, 0.75, 0.2533333, 0, 0.5458733, 0.8835651, 0.4446793, 0, 0.5059524, 5.609472, 2.397895, 0.03149606, 0.3807987, 0, 2.772589, 0, 3.135494, 0.09378118, 0.04975546, 0.2993237, 0.2, 0.4859494, 4.61512, 3.178054, 0, 0, 0, 0, 0.15, 0.3921823, 0, 0, 0.9599924, 0.8163886, 0.25, 0.5, 0, 0.05882353, 0.7917553, 0, -3.537076, 0.3333333, 0.25, 0.25, 0, 0.275, 0, 3.853134, 0.1186681, 0.1578185, 0.6474386, 0.2428571, 0.5, 0.4973886, 0.8218814, 0, 0.6729858, 0, 0, 0, 0.984237, 0, 0, 3075243e-9, 0, 0.05745253, 0, 0, 0, 0, 0, 0, 0, 0, 0.2, 0, -0.6342732, 0.4044122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.2040628, 0, 0, 0.04799343, 0.4095238, 0, 0, 0.35, 1.94591, 6.660575, 4.859812, 2.079442, 0.5076258, 0.279601, 0, 0.02584493, 0.1889052, 0.898181, 0.475, 0.1146875, 0, 1.609438, 0.09378118, 0.1, 0, 0.2533333, 0, 0.5800964, 0, 0, 2.995732, 0.08333334, 0.6503634, 0, 0, 0, 0, 0.8608962, 0.4225708, 0.3583294, 0.4937787, 0, 0.3444971, 4.644391, 0.1578185, 0.3199397, 0.2337021, 0, 0.4878399, 0.3202217, 0.2429577, 0.8572058, 0.5114858, 0.288416, 0.1666667, 2.965995, 0.3333333, 5.17615, 0, 0.0346841, 0.08640844, 0.01072934, 0.1666667, 0.06930693, 0.2106337, 6.028278, 0.0494359, 0, 0.7460366, 7.257003, 0.7300336, 7.553287, 0.5972933, 0, 0.8236248, 0.2, 0.05501111, 0, 0.8793104, 0, 0.4741301, 4.559038, 0, 0.9522486, 0, 2.564949, 0.5800964, 0.3270142, 0.075, 0, 0, 0, 0, 0.8607724, 0.4865274, 0, 0, 0.8301887, 0.4310797, 0.6100386, 3111111e-9, 2.772589, 0, 0.1031566, 0, 0, 1.098612, 0, 0, 0, 0, 0, 0.0600245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6505576e-9, 0.2642521, 0.7957155, 0.6872104, 0, 0.175, 0.125, 0.8572058, 0.8530882, 8.501063, 0.5889103, 0.15, 0.9698997, 0, 0.9839365, 0, 0.7917553, 0.3, 0, 0.1653979, 0, 0.7652995, 0, 0.1765268, 0.1, 0.06876939, 4443248e-9, 0.3636364, 4.001706, 0, 0, 0.275, 0.2, 0, 0, 0.45, 0, 0, 0, 0.4446793, 0.3583294, 0.68, 0, 0, 5.252274, 0.275, 0.3368467, 0.2337021, 0, 0.5827814, 0, 0, 0.25, 7.920083, 0, 0.2, 0, 0.3333333, 0, 0, 0.01610604, 0, 0.4741301, 0.2, 0.275, 0.6474386, 0, 0.03151318, 0, 0, 0.5579418, 0.075, 1.098612, 0, 0.984237, 0.3333333, 0.2115385, 0.6819527, 0.7672956, 4.559038, 0, 0, 7.698483, 8.858511, 0, 0.2533333, 0, 0.9047619, 0, 0, 7.470224, 0, 0.06097378, 3.555348, 0, 0.5944056, 4.271065, 0, 0, 0, 0, 0.8675887, 0.1775001, 0, 0.05882353, 0.02156334, 3.135494, 0.1655462, 0.9245283, 0.2, 0.3478258, 0.5114858, 0, 0, 0.8804404, 0, 0.7001467, 0.7001467, 0.1111111, 1.098612, 0.6257396, 5.081404, 0.9814815, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.107917, 0, 4.770685, 0, 0, 0, 0, 0, 0.4446793, 2.772589, 0, 0, 0.4044122, 0.3583294, 0.2995246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.079442, 0.1305989, 6.349139, 0.2642521, 1.94591, 0.3113497, 0.9698997, 0.2125267, 0.3333333, 0, 0.08259411, 3.218876, 0.4674693, 0, 0.1031566, 0.7514793, 0.1, 0.4280677, 0.7358209, 3.663562, 0.898181, 0, 2.079442, 0, 0.4865274, 0.3199397, 0.2106337, 7.470224, 0, 0, 0, 0, 0.04402662, 0, 0, 0.75, 0, 0, 0, 0, 0.5, 1.098612, 0, 0, 0, 0, 0, 0, 0, 0, 0.9, 0.9324324, 0, 6.55108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.770685, 0, -0.6342732, 0.2492674, 0, 0, 0.4446793, 2.772589, 0, 0, 0.2125267, 9.083983, 0, 0, 0, 0, 0, 0, 2.197225, 0, 0, 0, 0, 0, 0, 0, 2.079442, 1.386294, 0, 0.3341523, 0.3230769, 0, 0.2618343, 0, 0, 0.2978621, 0.5, 4.276666, 0.3199397, 0, 0.38, 0, 0.3444971, 0.1726634, 0.523972, -1.218948, 0.311186, 0.01072934, 0.25, 0.135235, 0, 0, 0.4686952, 0.4937787, 0.5, 0, 0, 0, 4.859812, 0.425, 1.94591, 0.9, 0.375, 0.2237885, 0.4865274, 2.163539, 0.6872104, 0, 0.6931472, 0.7836897, 4.007333, 5.521461, 0.1212097, 0.475, 9922371e-10, 0.2228809, 0, 0, 0, 0, 0.6849968, 2.302585, 0.04799343, 0, 0, 0, 0.1578185, 8.007034, 4.110874, 0, 0, 0.04799343, 0.01591512, 0.9814815, 0.5808709, 0.0811779, 0.25, 0.03420965, 2.357957, 0.4859494, 7.257003, 0, 0, 0.15, 0, 0.15, 0.1726634, 0.05263158, 4.110874, 4.276666, 0, 0.3869769, 0.4225708, 0.05263158, 0, 0, 0, 0, 0, 4.85203, 3.871201, 0.05882353, 5.252274, 4.859812, 0, 0.4375, 0.08640844, 0, 0, 0.319699, 2.944439, 0.8010488, 0.1551724, 0.288416, 0.6842105, 0, 0.4371859, 0.02702703, 0.2470046, 0.01989664, 0, 0.6916528, 0.5461184, 0.735, 0.9078827, 0, 0.6931472, 0, 0, 0, 0.9703127, 0.9408998, 0.08144234, 0.8163886, 0.9230132, 0.6474386, 0, 0.7652995, 0.927255, 0.8804404, 0.09378118, 2.734421, 8.2933, 0, 0, 8.711114, 0, 0, 4.327618, 0, 0, 0, 0.6997636, 0, 0, 7.412764, 580011e-8, 0, 0, 0, 0, 1.293191, 0.8835651, 5.768321, 0.1943059, 0.03149606, 0.5, 0, 0, 0, 3.988984, 0, 0.7300336, 0.1651376, 0.2428695, 6.660575, 0, 0.4937787, 0.04975546, 0, 0.01591512, 0, 0, 0, 0.5785877, 5.356586, 0.28, 0.04643963, 0, 2.331571, 0.2955975, 7.920083, 0.1168487, 2.107917, 0.1653979, 7.553287, 0.02584493, 2.564949, 0.05263158, 5.252274, 8201202e-9, 0.275, 5.278115, 2.564949, 1.098612, 0.8297873, 0.125, 0.6842105, 0.1655462, 9.400051, 1.386294, 0.04629841, 0, 0.2978621, 0.1666667, 0, 0, 0.3333333, 0, 0.1255986, 0.06896514, 5.236442, 0, 0.9703127, 0.9021136, 0.08144234, 2.107917, 3.871201, 0.125, 0, 0.02316602, 4.234107, 4920635e-9, 0.1794872, 0, 0.6474386, 0, 0, 0.9995694, 2.197225, 0.1420345, 0.6886503, 0, 0, 0.8163886, 0.6729858, 0, 0, 3.050203, 8.711114, 0, 0, 0, 0, 0, 0, 0.0754717, 0, 0.6931472, 0, 0.3341523, 0.0542577, 0.3719538, 0.1146875, 0, 0, 0, 0.2327044, 2.639057, 0.1677098, 0, 0, 0.3202217, 0, 0, 0.6931472, 1.098612, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.6342732, 0.0375892, 0.6571429, 0.01412086, 0, 0.175, 0.15, 0.168831, 0.3333333, 4.143135, 0, 0, 0, 0, 7.698029, 6.349139, 0.3478258, 0.2002174, 0, 0.7909349, 4.41884, 0.523972, 0, 0, 0, 0, 0, 0, 0, 0],
4086
+ leaves: [-0.31878, 0, -0.21386, 0.1032, -0.089037, 0.10096, -0.085583, -0.24982, -0.18222, -0.08767, 0.24808, 0.019812, -0.04525, 0.09739, 0.023051, -0.091186, 0.044292, -0.096174, 0.046064, 0.23168, -0.077142, 0.22043, 0.069539, 0.31783, 0.14139, 0.39324, -0.14273, 0, 0.47118, 0, 0, 0, -0.28689, 0, 0, 0, -0.24892, -0.11804, -0.19761, 0.14581, 30592e-7, -0.17347, 0.23968, 0, -0.13943, -0.022438, 0.20109, 0, -0.03742, -0.185, -0.030942, 0.096525, 0.057479, -0.092131, 0.1768, -0.15418, 0.28761, 54349e-7, -0.13046, 0, 0.217, -0.05387, 0.36207, 0, -0.26348, 0, 0, 0, -0.10938, -0.23412, -0.15009, 0.14125, 0.02478, -0.17439, 0.17603, -12222e-7, -0.16946, -0.062622, -0.051299, 0.049975, -0.10266, 0.11684, -77817e-7, 0.11119, 0.11634, -0.16966, 0.03832, 0.19845, 0.1627, 0.2482, -0.17467, 0.16947, 0.085149, 0.30282, -0.17858, 0.21696, -0.24599, 0, 0, 0, -0.20435, -0.061186, 0.14553, -0.12948, -0.065705, 0.20929, -0.1866, -0.061435, -0.035533, -0.18097, 0.22482, 0, 0.062581, -0.080121, -0.18422, 53663e-7, 0.16514, -0.093846, 0.093815, -0.18092, 0.094754, 0.22653, -0.099107, 0, 0.029711, 0.27539, 0.19323, -0.1516, -0.23504, 0, 0, 0, -0.070733, -0.19887, -0.13254, 0.13092, 0.02965, -0.15185, 0.069063, -0.066137, 0.20636, 0, 0.036359, 0, -0.13798, 0.032521, -0.020725, 0.11942, 0.069623, -0.15504, 0.089312, 0.1892, 0.096944, 0.19231, -0.13135, 0.14131, 0.2084, 0.025408, 0.061255, 0.24878, -0.22577, 0, 0, 0, -0.1863, -0.021576, -0.11015, 0.10831, -0.14984, 95591e-7, -0.028693, -0.15562, 0.030327, 0, 0.18693, 0, -0.047796, 0.046741, 0.019708, -0.17314, 0.084792, -0.16877, 0.17469, 0.071447, 0.1241, 0.19422, -0.070848, 0, 0.053655, 0.2394, 0.1489, -0.16053, -0.2184, 0, 0, 0, 0.10223, -0.12888, -0.19218, -70025e-7, -0.083068, -0.17488, 0.055509, -0.06944, 0.059408, 0.27968, -0.16603, 0.052281, 0.016982, 0.16886, 0.022023, -0.14734, 0.059351, -0.15003, 0.046576, 0.13777, 0.1881, 0.12208, 0.2244, 0.030347, -0.17702, 0, -82749e-7, 0.16174, -0.2106, 0, 0, 0, 0, 0, 0, 0, 0.059566, -0.17656, 0.038923, -0.09071, -15376e-7, 0.25299, -0.1101, 0.039362, 0.017342, -0.075443, -0.018361, 0.13649, 0.050524, -0.089454, 0.057659, 0.13835, 0.044795, 0.18141, 0.010322, 0.1659, 64778e-7, 0.21367, 0.13681, -0.1486, -0.20786, 0, 0, 0, 0, 0, 0, 0, -0.012525, 0.26293, -0.15276, 0.018769, -0.17799, -0.09904, 0.074436, -0.17605, -0.084997, 25315e-7, 0.10665, -0.13919, 0.057783, 0.17698, 0.040143, -0.23457, 21528e-7, 0.14463, -0.14011, 0.14053, 0.020322, 0.20465, 0.12803, -0.13533, -0.20366, 0, 0, 0, 0, 0, 0, 0, -0.011659, 0.21856, -0.13993, 0.032537, -0.083678, 0.18514, -0.14706, 0.10396, -89532e-7, -0.12856, 49842e-7, 0.21948, 0.086086, -0.1287, -0.065416, 0.04875, -0.046568, 0.13847, 0.10505, -0.18916, 0.16218, -0.20886, 0.025395, 0.19321, -0.20024, 0, 0, 0, 0, 0, 0, 0, 0.23341, -0.035271, -0.12481, 0.090957, -0.16916, -0.068392, 0.018748, 0, -0.035821, 0.17994, -0.07059, 0.01659, 96452e-7, 0.074111, -0.13471, 0.10429, -0.15561, 0.13238, -43242e-7, 0.14606, 0.013174, 0.1955, 0.13114, -0.083045, -0.19852, 0, 0, 0, 0, 0, 0, 0, -0.050254, 0.22151, -0.11774, 0.056798, -0.16026, -0.043395, 0.030176, 0, 0.01821, 0.19027, -0.091734, -0.019291, 0.016345, -0.11042, 0.029938, 0.11237, 0.039109, 0.12685, -0.10734, 0.13199, 0.011938, 0.18867, 0.12053, -0.071607, -0.19556, 0, 0, 0, 0, 0, 0, 0, -0.04689, 0.19814, -0.11419, 0.036199, -0.15099, -0.039416, 0.027778, 0, 90897e-7, -0.15388, 0.02634, -0.16408, -0.077332, 0.061169, 0.026983, 0.14605, -0.069073, 0.15655, -0.10121, 0.098306, 0.12525, -0.19903, -0.032052, 0.17635, -0.19275, 0, 0, 0, 0, 0, 0, 0, -0.13487, -78661e-7, 0.24791, 0, -0.14641, 0.011359, -0.068595, 0.12632, 0.080484, -0.12021, 78606e-7, -0.076651, -0.035819, 0.11089, 0.07826, -0.053902, -0.068808, 0.062142, 0.1864, 0.034044, -0.073019, 0.13374, -0.19412, 0.051882, -0.18688, 0, 0, 0, 0, 0, 0, 0, 0.12952, 0, 0, 0, -0.025255, 0, -0.13332, 0, -0.029127, -0.16208, 0.045483, -0.17471, 0.011839, 0.085709, -0.022881, 0.095192, -0.070798, 0.063432, 0.18055, 0.031005, -0.062873, 0.12294, -0.16251, 0.045998, -0.18705, 0, 0, 0, 0, 0, 0, 0, -0.014552, -0.10701, 0.19835, 0, -0.15769, -0.042538, -0.090104, 0.12266, 58218e-8, -0.10159, 0.036248, -0.016371, 0.043897, 0.15435, -0.076118, 0, -0.068146, 0.061155, 0.17454, 0.028234, -0.087178, 0.093422, -0.066383, 0.11974, -0.19046, 0, 0, 0, 0, 0, 0, 0, -0.069484, 0, 0.16113, 0, -0.037742, -0.14975, 0.018831, -0.07785, -0.10386, 0.089735, -36422e-7, 0.1541, 0.015404, 0.09292, -0.13876, 0.036152, 49348e-7, 0.16981, -0.072142, 0.075278, -0.093063, 0.12596, 0.040608, -0.18604, -0.18053, 0, 0, 0, 0, 0, 0, 0, 0.030829, 0, 0, 0, -0.091149, 0, 0, 0, -38172e-7, 0.13528, 0.10873, -0.21881, 0.16513, -0.037891, 0.094282, -0.14205, -0.025758, 0.11648, -0.24113, 0.1303, -0.010495, -0.18121, 0.026166, 0, -0.18736, 0, 0, 0, 0, 0, 0, 0, -0.042049, 0, 0, 0, 0, 0, 0, 0, 0.23084, -0.034776, -0.11564, 0.089227, 14196e-7, 0.13943, 0.096535, -0.071237, -0.045889, 0.10821, 0.1697, -0.011255, 0.091511, 0, 0.08187, -0.15145, -0.18469, 0, 0, 0, 0, 0, 0, 0, -0.039368, 0, 0, 0, 0, 0, 0, 0, 0.11634, -0.042627, -5224e-6, -0.081608, -0.076521, 0.091283, 0.070928, -0.10526, 0.16169, -62322e-7, -0.15914, 0.074429, -0.093142, 0.18604, -0.16911, 0.036157, -0.18176, 0, 0, 0, 0, 0, 0, 0, -0.036879, 0, 0, 0, 0, 0, 0, 0, -0.041254, 65793e-7, 0.13597, 0.01078, -0.038195, 0, 0.14741, -23902e-8, -0.12856, 0, 0, 0, 0.096233, -0.037189, 0.14776, -9574e-6, -0.17698, 0, 0, 0, 14974e-7, 0, -0.069735, 0, -0.033346, 0, 0, 0, 0, 0, 0, 0, 0.023197, -0.012282, -0.12026, 0.096717, -0.17937, 0, 0, 0, 0.1488, -79748e-7, -0.1524, 0.067945, -0.073014, 0.16329, -0.14901, 0.03301, -0.17662, 0, 0, 0, 0, 0, 0, 0, -0.032376, 0, 0, 0, 0, 0, 0, 0, -67804e-7, 0.13135, 0.065422, -0.084352, -0.024266, 0.048637, 0.095737, -0.12801, 0.15843, 0.023992, -0.022788, 0, 0.015057, -0.19599, 0.06161, 0, -0.16738, 0, 0, 0, 0, 0, 0, 0, -0.087328, 0, 0, 0, 0.03884, 0, 0, 0, 0.057769, -0.082373, 0.035103, 0.19533, 0.021393, -0.22495, 90638e-7, -0.043117, 0.13735, -39622e-7, -0.14363, 0.060968, -0.10608, 0.1084, -0.1645, 0, -0.16951, 0, 0, 0, 0, 0, 0, 0, -0.028117, 0, 0, 0, 0, 0, 0, 0, -0.021435, 0.01056, -0.17263, 0, -0.019753, 0, 0.13322, 14524e-7, 0.048026, -0.037267, -0.20085, 0, 0.12172, -0.047456, 0.047647, -0.16217, -0.16595, 0, 0, 0, 0, 0, 0, 0, -0.022132, 0, 0, 0, 0, 0, 0, 0, 0.048739, -0.082585, 0.13999, -0.051229, -71629e-7, -0.17621, 27376e-7, 0.074376, -88393e-7, -0.10143, 0.034214, 0, 0.11076, 0.0273, -0.097527, 0, -0.15934, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.037207, 0.025782, -0.12158, 95648e-7, -0.051308, -0.21738, -50697e-7, 0.063456, 0.12071, -0.023277, -0.071724, 0.029418, -0.23141, -0.01848, 0.0964, -0.11606, -0.15657, 0, -0.024559, 0, 86673e-7, 0, 0, 0, -0.11676, 12122e-7, -0.041715, 0.074709, -0.036049, 0, 0.15983, 0, -0.014469, 0.082783, -0.087967, 0.022561, 0.10962, -0.011297, 0.23271, 0, -0.12793, 39687e-7, -0.197, 0.091983, 0.01793, -0.090029, -0.019215, 0.15215, -0.14988, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19636e-7, -0.088794, -0.12343, 0.11977, -0.15647, 0, 0, 0, -3417e-6, 0, 0, 0, 0.020662, 0.14532, 11218e-7, 0, -0.020797, 0, 0, 0, 0, 0, 0, 0, -0.14717, 0, 0, 0, 0, 0, 0, 0, 0.021813, -0.036106, -0.012852, 0.14634, 0.020725, -0.18151, -0.089111, 0.079667, 0.11189, -0.050054, -0.0495, 0.011981, -0.030569, 0.088854, -0.20207, 0.031451, 0.17985, 0, -0.09726, 0.11445, -0.04192, 0.13707, -0.14124, 0.012741, -0.15477, 0, 0, 0, 0, 0, 0, 0, -0.062733, 0.12858, -0.24566, -0.068646, 0.1419, 0, 0.078618, -0.088579, -0.072796, 0.12067, -0.058804, 0.011681, 0.030978, -0.14253, -0.051765, 0.052692, -0.13293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.01667, 0.025776, 0.080178, 52813e-7, -0.037566, 0.07252, 0.12069, -0.059294, -0.23481, 0, 0, 0, -93202e-7, 0.12583, -0.17263, 79894e-8, -0.043584, 0, 0.18834, -53314e-8, -0.061634, 0.10353, -0.13052, 0.011791, -0.15138, 0, 0, 0, -0.02506, 0, 0, 0, 32844e-7, -0.082135, 0.12356, -0.070309, -0.14119, 0, 0, 0, 0.016167, 0, 0.13083, 0.025533, -40782e-7, 0, 0, 0, -0.12086, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2486e-6, -0.049879, 0.12705, -0.19319, -0.2983, 64434e-7, -0.049097, 0.10149, 0.010483, 0, -0.089464, 0, -0.026978, 0, 0.016435, 0.15167, 0.012469, -0.12631, 0.12619, -0.016202, 39847e-7, 0.18765, 0.044292, -0.097042, -0.023166, 0, 0, 0, -0.14499, 0, 0, 0, -0.027742, -0.21044, 0.049073, 0, 0.019086, 0.16431, -0.15111, 22833e-7, -0.065115, 0, 0.072499, 0, 0.1286, 0, 0.024416, 0, -0.10275, 0.050504, 0.025028, -0.012968, -0.061989, 0.012309, 0.014391, 0.11556, -0.10724, 0.016672, -0.042548, 0.17285, -0.095792, 0.09429, -0.16289, 0, -0.15634, 0, 0, 0, -3802e-6, 0, 0, 0, 0.050798, 0, 0, 0, 0, 0, 0, 0, -0.035466, 0.13462, -80576e-7, -0.12781, -0.031953, -0.21175, 89983e-7, 0, 0.10814, -0.073105, -0.021317, -0.13275, 96803e-7, -0.046822, 90479e-7, 0.13648, 0.16757, -0.023139, -0.12912, 0.083669, 0.063632, 0, -0.18048, -0.041198, 0.16056, 0, -41979e-7, 0, -0.062455, 0, 0, 0, -0.016626, -0.064816, -0.10089, 0.088929, 0.19723, -58523e-7, 0.061453, -0.040545, -0.087547, 0.082232, -0.15654, 84322e-7, 0.062902, -0.045914, 0.21256, 0.041883, 0.16271, -0.05326, 0.051288, -0.13793, -0.047191, 0.047581, -0.07067, 0.046794, -0.20163, 0, -0.024462, 0, 0.044388, -0.14135, 0.14349, -0.010779, -0.015012, -0.10164, -802e-5, 0.090082, 0.059939, -0.012717, -73499e-7, 0.095098, -0.1044, -57894e-7, -0.024778, 0.14077, -0.050495, 0.078804, -0.048483, -0.2338, -0.12074, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86442e-7, -0.18453, 0.035221, 0, -0.070439, 0.10129, -0.085599, 89424e-8, -0.13109, 0, 0, 0, 0, 0, 0, 0, -0.068704, 0, 0, 0, 0.065366, 0, 0, 0, 0.11754, 0, 0, 0, 0.026356, 0, 0, 0, -0.10463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -39888e-7, 0.03117, 0.089166, -0.12897, -0.10975, 0.055568, 0.019508, -0.052253, -0.1817, 0, 0, 0, -0.022799, 0.099006, -0.14978, 1331e-6, 19305e-7, -0.025683, -0.046425, 0.13922, -0.058442, 0, 0.15993, -0.022243, -0.076591, 0, 14588e-7, 0, -0.037563, 0, 0.05665, 0.17815, -0.21591, 0, 0, 0, -0.090392, 0, 0.06413, 0, -0.15199, 0.040411, -0.040924, 0.12009, -0.24176, -0.024511, 0.10206, -0.13227, 0.10132, -0.033979, 0.21215, 0.021766, -0.090434, 32753e-7, -0.15063, 0.023887, -0.099811, 0, 0.17106, -0.018465, -0.1656, 0, -12131e-7, 0, 0.07163, 0, 0, 0, -0.021185, -0.20431, 0.040932, 0, -0.071599, 0, 0, 0, -0.030878, 0, 0.16172, 0, -0.021637, 71234e-7, 0.067308, -0.09265, -0.095929, 0, 0.11221, -0.043052, -0.11599, 0, 0, 0, 0, 0, 0, 0, -0.06202, 0, 0, 0, 0.063006, 0, 0, 0, 0.11344, 0, 0, 0, -0.01453, 0, 0.053922, 0, -0.018448, 0.050326, -0.13026, 0.012479, 0.1786, -0.015326, 0.036543, -0.041512, 0.039455, -0.074793, -0.1837, 0.011569, -0.092563, 0.043492, 5745e-6, 0.1005, 0.094171, 0.02522, -0.1476, 0.053489, -0.10464, 0.13951, -0.21577, 0.011098, -0.24379, 75209e-7, 0.029567, -0.089303, 0.058063, -0.11782, -0.074588, 0.12355, 0.023978, 0.098672, -0.10251, 0.044428, -77226e-7, -0.10821, 13148e-7, 0.095462, -0.14125, 0, 0.020748, -0.080522, 0.019748, 0.13311, -0.090006, 36275e-7, -0.11125, 0.015808, -0.096964, 0.12053, -0.059508, 0.087144, 0.099509, -0.054598, -0.039608, -0.18053, 0.071329, 0, -0.012073, 0, 0.080146, 0, -0.019494, 0.035802, -0.073574, 0.025506, 0.020866, 0.10818, -0.097737, 0.018335, -0.016396, 0.11853, 0.070601, -0.049897, 0.019012, 0, -0.11662, 0, -0.069868, 0.014318, -0.074871, 0.096384, 0.12244, -0.099517, 0.13133, -0.088917, -0.12746, 0.029197, 0.20303, -0.032195, -0.089661, 0.10987, -0.030009, -0.19362, 65422e-7, -0.055154, -0.068651, 57858e-8, 0.061897, -0.071067, -0.12961, 0.053763, -0.063009, 0, 0, 0, -0.039017, 0, 0.021404, 0.14126, -0.18415, 0, 0, 0, -0.080929, 0, 0.061823, 0, 0.1225, -0.068711, -0.17039, 0.089541, -0.039238, 0.10799, -0.13652, 0.017893, -0.04963, 0.15226, -60545e-7, -0.12925, -0.16093, 0, 0.10531, -0.055054, 0.032125, -0.11366, 0.087259, -0.027556, -0.033357, 0.20738, -0.10095, 0.060347, -0.17856, 0, 0.0359, 0, -0.12644, 0.035611, 0.10579, -0.03658, -0.044933, 0.049539, -0.10375, 0.028788, -0.03659, 0.016655, -94193e-7, -0.1116, 0.10228, -0.059757, -0.12675, 0.017271, 0.15092, 0, 92177e-7, 0, -0.040398, 0.054139, 0.023495, -0.19998, 0.03108, -0.14859, 16413e-7, -0.063401, -41736e-7, 0, 0, 0, 0, 0, 0, 0, 0.017633, 0.12154, 0.014844, 0, 62872e-7, 0, 0, 0, -0.012991, 0.015632, 0.148, -0.17287, 0.027573, -0.10558, -0.028381, -0.1601, -0.10861, 0, 0, 0, 0, 0, 0, 0, -0.050799, 0, 0, 0, 0.058191, 0, 0, 0, 0.098109, 0, 0, 0, 0.017355, 0, 0, 0, -84396e-7, 0.015511, -0.022006, 0.090502, -0.083425, 0.081995, 0.037485, -0.1868, 63518e-7, -0.20898, 0.066795, 0, 0.086635, 0, 0, 0, -0.10052, 0, 0, 0, 0.029183, 0, 0, 0, 0.13954, 0, 24183e-7, 0, -0.013996, 0, 0, 0, 0.03755, -0.063408, -0.095524, -66204e-8, -0.01011, -0.11417, 0.11893, -0.038519, -0.043845, 0, 0.054809, 0, 0.014584, 0, 0.11024, 0, -0.1286, 0, 0, 0, -0.013809, 0, 0, 0, 0.046643, 0, 0, 0, 0, 0, 0, 0, 0.029664, -0.11144, -38707e-7, 0.036957, -0.020296, 0, 0.015165, 0.13016, -0.20004, 0, 0, 0, -0.014898, 0, 0.085852, 0, -0.052389, 0, 0, 0, 75247e-7, 0.14896, -0.075097, 0.088276, 0.07936, -0.077352, -0.025878, -0.17786, 0.088121, 0, 0, 0, 0.044288, -0.049057, -0.022134, -0.17036, 0.021931, -0.033452, 27312e-7, -0.034044, -0.12375, 0.02196, 0.089596, 0, -0.032824, 0, -0.17654, 0, -0.083957, 0, 0, 0, 0, 0, 0, 0, 21928e-7, 0.13961, -63211e-7, 0, -0.035498, 0, 0, 0, 87513e-7, -0.071363, -0.13341, 79083e-7, -9789e-6, 0.14328, -0.098177, 0.084643, 0.097713, -0.072204, -0.032773, 0.036905, -0.15301, -0.012019, 0.062019, -0.080499, -0.086663, 0, 0.062205, 0, 0.11582, 0, 0, 0, -0.027736, -0.13376, 0.028855, -0.043784, 0.058421, 0, 0, 0, -3833e-7, 0.031007, 0.024274, -0.13301, 0.13596, -0.041948, -0.1096, 0.046452, 0.12662, -0.049254, -0.16126, 0.061984, -0.23536, 74889e-7, -0.045049, 0.063305, 0.028035, 0, 0.13608, 0.023262, -0.046559, 0, 0, 0, -0.16926, 0, 0.067809, -0.082247, 0.096429, 0, 0, 0, -0.084006, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.03839, 0, -0.088326, 21105e-7, 0.17277, 0, 0, 0, 0.041922, -71732e-7, 79168e-7, -0.016058, -0.13714, 0, 0.028529, 0, -0.031387, 0.024855, 0.084249, -0.13553, 98604e-7, -0.19609, 0.09914, -0.11453, -0.049297, 0, 0.1629, 0.013718, 0.022975, -0.021355, -0.059963, 0.046499, 10483e-7, 0.13587, -0.094565, 0.094077, -0.097086, 0.10819, -0.17642, 0.049687, -0.075923, 0, 0, 0, -0.042108, 0, 0.18821, 57007e-7, 0.013693, -0.050797, -0.084963, 0.14106, 0.090782, -0.083822, -0.18338, -0.040639, -0.085108, -0.26172, 0.067755, 0, 0.086039, -0.036826, -0.10901, 0.012851, 0.14848, -0.050912, 95496e-7, -0.18808, 0.066332, -0.095817, -0.067671, 0.15728, 0.01908, 0.092292, -0.042226, 0.078525, 0.012025, -0.12747, -0.045771, 0.072186, 44171e-7, -0.056616, -0.027761, 0.040418, -0.079397, 0.024086, 0.023938, -0.14752, -0.032291, 0.11731, -0.14706, 0, -0.16154, 0, 0, 0, -0.16401, 0, 0.11167, -0.073384, 83214e-7, -0.26138, 0.03664, 0, -0.13406, 0.075173, 0.10732, -0.051645, -0.018098, 0.08159, 0.012014, -0.097678, -26073e-7, 0, 0, 0, -0.13623, 0, 0, 0, 0.053201, 0, 0, 0, -0.028917, 0, 0, 0, 0.096481, -0.030247, -80454e-7, -0.12386, -0.0729, 0.085417, 0.13485, -49854e-7, -0.033804, 0.05768, 0.022797, -0.15992, 0.039011, 54903e-8, -17996e-7, -0.072927, -0.052882, 0.040098, 8722e-6, -0.094152, -99553e-8, 0.034386, 0.074581, -0.103, -0.054192, -0.1867, -0.019201, 0.082774, 0.11276, 0, 0, 0, -0.015622, 0.081396, 0.081931, -0.17916, -0.19171, 0, 0, 0, 0.12595, -0.037572, -0.078861, 0.1052, -0.10291, 0, 0.040601, 0, -0.037273, 0.017012, -0.046905, 0.15692, -0.02941, 0.11382, -0.15523, -0.034254, -0.129, -0.014011, 0.063004, -0.10424, 22214e-8, 0.18625, -0.070594, 0, -30289e-7, 0.085572, 0.023822, -0.093746, -0.019635, 0.058169, -0.21594, -0.011842, -0.059955, 0.067115, -0.0272, 0.16808, -0.16449, -0.025853, 41495e-7, 0, 0.10483, -0.035289, -0.082386, 0, -0.14235, -83287e-7, 0.014714, 0, -30812e-7, 0.052884, 0.09577, -0.026076, -0.17278, 0, -0.013967, 0.081389, 0.13011, -90077e-7, -0.029134, 0, 0.075884, -0.034012, -0.10158, 0.026794, 0.1381, 0, 0.031672, 0, -0.049574, 0, 0, 0, 0.012788, -0.069952, -0.092755, 0.072161, 0.038865, -0.063906, 0.10812, -0.040895, -0.11118, 0.035619, 62968e-7, -0.090447, -0.07104, 0.041187, 0.023093, -0.06366, -0.070612, 0, 0, 0, 0.011894, 0, 0, 0, 0.014733, 0, 0.12602, 0, -29376e-7, 0, 0, 0, -0.019266, 0.058113, 87423e-7, -0.018019, -0.074371, 0.037209, 0.059213, -0.15027, -0.094376, 0, 0, 0, 0, 0, 0, 0, -0.060731, 0, 0.037453, 0, 0.078012, 0, 72858e-7, 0, 0.094867, 0, 0, 0, 0, 0, 0, 0, -0.038517, 0.10626, 59984e-7, 0.27093, -0.087623, 0.057645, 0.13399, -0.053092, 99093e-7, -0.03923, -0.10844, 0.033674, 0.065536, -0.073952, 0.064976, -13644e-7, -0.051146, 0.060127, -0.13571, 54371e-7, 0.13184, -0.041253, -0.040928, 0.049498, -0.1608, -29027e-7, 0.039259, 0, -0.049299, 0, 0.08896, 0, -0.020005, 0, 0, 0, 0.11374, 0, 0, 0, -19855e-7, 0.022288, -52636e-8, -0.13676, -0.1283, 0, 0.025403, -0.082463, -0.081695, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.022278, 0.022731, -63264e-7, 0.070327, -0.09998, 0, 59647e-7, 0, -0.089259, 0, 0, 0, 0, 0, 0, 0, -0.010335, -0.064594, 0.034999, 0, 0.071962, 0, 59737e-7, 0, 0.087249, 0, 0, 0, 0, 0, 0, 0, -98713e-7, 0.065154, -0.07178, 0.068719, 0.033719, -0.016312, -0.093596, 0.10353, 0.15098, 0.037582, -0.068176, 0.065281, 0.028411, -0.090022, -0.02, 0.097608, 0.096275, -0.043733, -0.11081, 0.062366, 0.07787, -0.096504, 0.25379, -0.027689, 0.15274, -0.02326, 0.11649, -0.10328, 0.03204, 0, -0.1041, 0, 0.053508, -0.06176, 0.034901, -0.10102, 0.12959, 0.025727, 0.013432, -0.025025, -0.15642, 0, -0.012913, 0, 0.036708, 0, 0, 0, 92922e-7, -0.11008, 0.039353, -11975e-7, -0.1873, 0.05168, 0.14323, 0, -91294e-7, 0, -0.085983, 0, 0.062435, -0.095586, 0.18119, -0.016888, -0.023405, 0.12695, -0.031822, 0.012227, -0.034832, 83948e-7, -69426e-7, -0.12173, -0.064596, 0.099589, -0.042226, -0.1849, -0.018328, -0.12036, -98686e-7, 0.13638, -0.030563, 0.035158, 0.13902, -0.014779, -0.10195, 0.016682, 0.06353, 0, -0.013256, 0, 0, 0, -0.12189, 0, 0, 0, 93204e-7, -0.032384, 0.099758, -24205e-8, 0.027201, -0.027466, -0.1313, 0.023869, -0.037027, 0.063667, -0.055427, 0.12884, -0.03747, 0, 0.13929, 0.030423, -0.079607, 0.016579, 0.09025, -0.011038, -0.12443, -0.02106, 0.063132, 0, -6998e-6, -0.15043, 0.023482, 0, 0.086269, 0, -0.017606, 0, 11017e-7, -0.058056, 0.1128, -0.10181, 0.048584, -0.059057, -0.15894, -0.019696, 0.037927, 0, -0.10543, 0.010529, 10329e-7, 0, 0.11671, 0.021251, -0.013467, 0, 0.11561, 0, 28383e-7, -0.1409, -0.036411, 0.10079, -0.19653, 0, 0, 0, 0, 0, 0, 0, -0.015822, -0.085147, 0.067554, -0.051877, -0.030254, 0.033135, -0.060647, 755e-5, -0.12698, -0.026913, -0.013847, 0, 0.033159, 0, 0, 0, 20011e-7, -0.089529, 0.11052, -0.039774, -0.06078, 0.074167, -0.22869, -0.012486, 0.076502, -0.082171, 0.069945, -0.062, -0.026703, 0.13525, -0.030485, 0.074094, 0.010066, -0.025533, 0.027049, -0.060656, -0.10503, 0.049859, -0.043438, 0.091805, 0.028386, -0.1374, -0.13168, 0.085657, -0.13418, 0.037796, -0.067383, 0.078579, -0.094719, 0, 0.020552, 0, 0.11307, -0.03556, -0.065418, 0, -0.13795, 0.01813, -0.041248, 0.13839, 0.098539, -0.066899, -0.15574, -18212e-7, -0.010075, 0.030592, 0.037935, -25368e-7, 0.024418, -0.11589, -0.023747, 0.12406, 0.046364, 0, -0.14184, -0.02566, 0.066711, -0.038485, -0.086794, 0.037373, 0.098719, 0, 0, 0, -0.013182, 0.10087, -0.076343, 0.057484, -0.17586, 0, 0, 0, 0, 0, 0, 0, 0.051839, -0.049326, 0.069539, -0.031561, 0.016381, 0, -0.023198, -0.17628, 0.017158, 0, -0.12172, 0, -9651e-6, 0.03746, 0.032993, -0.14898, -68498e-7, 0, 0, 0, 0, 0, 0, 0, 0.015975, 0, 0.09992, 0, 0.041884, 0, -0.036147, 0, -0.056622, 0.047856, 0.021116, -0.063706, 0.038158, -0.063383, 76563e-7, 0.098989, 0.068157, -0.015616, -0.023883, -0.13523, -61924e-7, 0.070755, -0.041158, 23702e-7, 0.029427, 0, 0, 0, 0, 0, 0, 0, -74014e-7, 0, 0, 0, -0.12097, 0, 0, 0]
4087
+ };
4088
+
4089
+ // src/extractors/lib/layout-tables.ts
4090
+ var DATA_MARKERS = /* @__PURE__ */ new Set(["caption", "thead", "tfoot", "th", "col", "colgroup"]);
4091
+ var BLOCK_IN_CELL = /* @__PURE__ */ new Set(["h1", "h2", "h3", "h4", "h5", "h6", "table", "form"]);
4092
+ var TABLE_PARTS = /* @__PURE__ */ new Set(["tbody", "thead", "tfoot", "tr", "td", "th"]);
4093
+ var TABLE_CONTEXT = /* @__PURE__ */ new Set(["table", "tbody", "thead", "tfoot", "tr"]);
4094
+ var shapeOf = (table) => {
4095
+ const shape = { rows: 0, columns: 0, dataMarker: false, blockInCell: false };
4096
+ const visit = (node, inCell) => {
4097
+ for (const child of node.children) {
4098
+ if (!isElement(child)) {
4099
+ continue;
4100
+ }
4101
+ const tag = child.tagName;
4102
+ if (tag === "table") {
4103
+ shape.blockInCell = shape.blockInCell || inCell;
4104
+ continue;
4105
+ }
4106
+ if (DATA_MARKERS.has(tag)) {
4107
+ shape.dataMarker = true;
4108
+ }
4109
+ if (tag === "tr") {
4110
+ shape.rows += 1;
4111
+ const cells = child.children.filter(
4112
+ (cell) => isElement(cell) && (cell.tagName === "td" || cell.tagName === "th")
4113
+ ).length;
4114
+ shape.columns = Math.max(shape.columns, cells);
4115
+ }
4116
+ if (inCell && BLOCK_IN_CELL.has(tag)) {
4117
+ shape.blockInCell = true;
4118
+ }
4119
+ visit(child, inCell || tag === "td" || tag === "th");
4120
+ }
4121
+ };
4122
+ visit(table, false);
4123
+ return shape;
4124
+ };
4125
+ var isLayoutTable = (table) => {
4126
+ const role = stringProperty(table, "role");
4127
+ if (role === "presentation" || role === "none" || stringProperty(table, "datatable") === "0") {
4128
+ return true;
4129
+ }
4130
+ const shape = shapeOf(table);
4131
+ if (shape.blockInCell) {
4132
+ return true;
4133
+ }
4134
+ if (shape.dataMarker) {
4135
+ return false;
4136
+ }
4137
+ if (shape.rows <= 1 || shape.columns <= 1) {
4138
+ return true;
4139
+ }
4140
+ if (shape.rows >= 10 || shape.columns > 4) {
4141
+ return false;
4142
+ }
4143
+ return shape.rows * shape.columns <= 10;
4144
+ };
4145
+ var unwrap = (table) => {
4146
+ const cells = [];
4147
+ const collect2 = (node) => {
4148
+ for (const child of node.children) {
4149
+ if (!isElement(child)) {
4150
+ continue;
4151
+ }
4152
+ if (child.tagName === "td" || child.tagName === "th") {
4153
+ cells.push({ type: "element", tagName: "div", properties: {}, children: child.children });
4154
+ } else if (child.tagName !== "table") {
4155
+ collect2(child);
4156
+ }
4157
+ }
4158
+ };
4159
+ collect2(table);
4160
+ return { type: "element", tagName: "div", properties: {}, children: cells };
4161
+ };
4162
+ var unwrapLayoutTables = (root) => {
4163
+ const visit = (parent) => {
4164
+ const parentTag = isElement(parent) ? parent.tagName : "";
4165
+ for (let index = 0; index < parent.children.length; index++) {
4166
+ const child = parent.children[index];
4167
+ if (!isElement(child)) {
4168
+ continue;
4169
+ }
4170
+ if (TABLE_PARTS.has(child.tagName) && !TABLE_CONTEXT.has(parentTag)) {
4171
+ child.tagName = "div";
4172
+ }
4173
+ visit(child);
4174
+ if (child.tagName === "table" && isLayoutTable(child)) {
4175
+ parent.children[index] = unwrap(child);
4176
+ }
4177
+ }
4178
+ };
4179
+ if ("children" in root) {
4180
+ visit(root);
4181
+ }
4182
+ };
4183
+
2332
4184
  // src/extractors/lib/terminators.ts
2333
4185
  var TERMINATOR_PATTERNS = [
2334
4186
  /^was this (page|article|document) helpful/i,
@@ -2347,27 +4199,27 @@ var TERMINATOR_PATTERNS = [
2347
4199
  ];
2348
4200
  var TAIL_START_FRACTION = 0.8;
2349
4201
  var MAX_TERMINATOR_BLOCK_LENGTH = 500;
2350
- var BLOCK_TAGS = /* @__PURE__ */ new Set(["p", "div", "section", "footer", "aside", "h1", "h2", "h3", "h4", "h5", "h6", "ul", "ol"]);
4202
+ var BLOCK_TAGS3 = /* @__PURE__ */ new Set(["p", "div", "section", "footer", "aside", "h1", "h2", "h3", "h4", "h5", "h6", "ul", "ol"]);
2351
4203
  var isTerminatorBlock = (element3, start, tailStart) => {
2352
- if (!BLOCK_TAGS.has(element3.tagName) || start < tailStart) {
4204
+ if (!BLOCK_TAGS3.has(element3.tagName) || start < tailStart) {
2353
4205
  return false;
2354
4206
  }
2355
- const text6 = textOf(element3).replace(/\s+/g, " ").trim();
4207
+ const text6 = textOf2(element3).replace(/\s+/g, " ").trim();
2356
4208
  if (text6.length === 0 || text6.length > MAX_TERMINATOR_BLOCK_LENGTH) {
2357
4209
  return false;
2358
4210
  }
2359
4211
  return TERMINATOR_PATTERNS.some((pattern) => pattern.test(text6));
2360
4212
  };
2361
- var textOf = (node) => {
4213
+ var textOf2 = (node) => {
2362
4214
  if (node.type === "text") {
2363
4215
  return node.value;
2364
4216
  }
2365
- if (!isParent(node)) {
4217
+ if (!isParent2(node)) {
2366
4218
  return "";
2367
4219
  }
2368
4220
  let text6 = "";
2369
4221
  for (const child of node.children) {
2370
- text6 += textOf(child);
4222
+ text6 += textOf2(child);
2371
4223
  }
2372
4224
  return text6;
2373
4225
  };
@@ -2380,7 +4232,7 @@ var truncateTrailingBoilerplate = (tree) => {
2380
4232
  total += node.value.trim().length;
2381
4233
  return;
2382
4234
  }
2383
- if (isParent(node)) {
4235
+ if (isParent2(node)) {
2384
4236
  for (const child of node.children) {
2385
4237
  measure(child);
2386
4238
  }
@@ -2393,7 +4245,7 @@ var truncateTrailingBoilerplate = (tree) => {
2393
4245
  const tailStart = total * TAIL_START_FRACTION;
2394
4246
  let cutoff = -1;
2395
4247
  const find = (node) => {
2396
- if (cutoff !== -1 || !isParent(node)) {
4248
+ if (cutoff !== -1 || !isParent2(node)) {
2397
4249
  return;
2398
4250
  }
2399
4251
  for (const child of node.children) {
@@ -2433,6 +4285,7 @@ var truncateTrailingBoilerplate = (tree) => {
2433
4285
 
2434
4286
  // src/extractors/presets/takumi.ts
2435
4287
  var MIN_RETAINED_FRACTION = 0.25;
4288
+ var FURNITURE_LINK_DENSITY = 0.5;
2436
4289
  var SEMANTIC_SELECTORS = [
2437
4290
  (element3) => stringProperty(element3, "itemprop")?.includes("articleBody") ?? false,
2438
4291
  (element3) => element3.tagName === "article",
@@ -2470,6 +4323,31 @@ var collectMatching = (tree, matches, into) => {
2470
4323
  }
2471
4324
  }
2472
4325
  };
4326
+ var containsTag = (element3, tagName) => element3.children.some((child) => isElement(child) && (child.tagName === tagName || containsTag(child, tagName)));
4327
+ var removesEveryTitle = (root, doomed) => {
4328
+ if (!doomed.some((element3) => containsTag(element3, "h1"))) {
4329
+ return false;
4330
+ }
4331
+ const doomedSet = new Set(doomed);
4332
+ let survivor = false;
4333
+ const visit = (node) => {
4334
+ if (survivor || !("children" in node)) {
4335
+ return;
4336
+ }
4337
+ for (const child of node.children) {
4338
+ if (!isElement(child) || doomedSet.has(child)) {
4339
+ continue;
4340
+ }
4341
+ if (child.tagName === "h1") {
4342
+ survivor = true;
4343
+ return;
4344
+ }
4345
+ visit(child);
4346
+ }
4347
+ };
4348
+ visit(root);
4349
+ return !survivor;
4350
+ };
2473
4351
  var asRootOf = (nodes) => ({ type: "root", children: nodes });
2474
4352
  var scoredSelection = (tree, collector, lang) => {
2475
4353
  const context = buildScoringContext(tree, collector, lang);
@@ -2496,9 +4374,14 @@ var takumiExtractor = (params) => {
2496
4374
  const shortcut = semanticShortcut(body, collector, minLength);
2497
4375
  const searchRoot = shortcut ?? body;
2498
4376
  const searchText = collector.textLength(searchRoot);
2499
- const doomed = findUnlikelyElements(searchRoot);
2500
- const doomedText = doomed.reduce((sum, element3) => sum + collector.metrics(element3).text, 0);
2501
- if (searchText - doomedText > Math.max(minLength, searchText * MIN_RETAINED_FRACTION)) {
4377
+ let doomed = findUnlikelyElements(searchRoot);
4378
+ const textOf3 = (elements) => elements.reduce((sum, element3) => sum + collector.metrics(element3).text, 0);
4379
+ let acceptable = searchText - textOf3(doomed) > Math.max(minLength, searchText * MIN_RETAINED_FRACTION);
4380
+ if (!acceptable) {
4381
+ doomed = findUnlikelyElements(searchRoot, (element3) => collector.linkDensity(element3) < FURNITURE_LINK_DENSITY);
4382
+ acceptable = doomed.length > 0 && searchText - textOf3(doomed) >= minLength && !removesEveryTitle(searchRoot, doomed);
4383
+ }
4384
+ if (acceptable) {
2502
4385
  const doomedSet = new Set(doomed);
2503
4386
  pruneInPlace(searchRoot, (node) => !(isElement(node) && doomedSet.has(node)));
2504
4387
  collector = new MetricsCollector();
@@ -2521,9 +4404,251 @@ var takumiExtractor = (params) => {
2521
4404
  return cleanContent(chosen, cleanupCollector);
2522
4405
  };
2523
4406
 
4407
+ // src/extractors/lib/takumi-signal.ts
4408
+ var MARK = "dataWebforaiIndex";
4409
+ var cloneElements = (root) => {
4410
+ const copyOf = (node) => "children" in node ? {
4411
+ ...node,
4412
+ ...isElement(node) ? { properties: { ...node.properties } } : {},
4413
+ children: [...node.children]
4414
+ } : node;
4415
+ const copy = copyOf(root);
4416
+ const stack = [copy];
4417
+ while (stack.length > 0) {
4418
+ const parent = stack.pop();
4419
+ if (!("children" in parent)) {
4420
+ continue;
4421
+ }
4422
+ const children = parent.children;
4423
+ for (let index = 0; index < children.length; index++) {
4424
+ if ("children" in children[index]) {
4425
+ children[index] = copyOf(children[index]);
4426
+ stack.push(children[index]);
4427
+ }
4428
+ }
4429
+ }
4430
+ return copy;
4431
+ };
4432
+ var takumiSelection = (root, lang, url) => {
4433
+ const elements = [];
4434
+ walk(root, (node) => {
4435
+ if (isElement(node)) {
4436
+ node.properties[MARK] = elements.length;
4437
+ elements.push(node);
4438
+ }
4439
+ });
4440
+ const copy = cloneElements(root);
4441
+ for (const element3 of elements) {
4442
+ delete element3.properties[MARK];
4443
+ }
4444
+ const kept = /* @__PURE__ */ new Set();
4445
+ walk(takumiExtractor({ hast: copy, lang, url, owned: true }), (node) => {
4446
+ if (isElement(node)) {
4447
+ const index = node.properties[MARK];
4448
+ if (typeof index === "number" && elements[index]) {
4449
+ kept.add(elements[index]);
4450
+ }
4451
+ }
4452
+ });
4453
+ return kept;
4454
+ };
4455
+
4456
+ // src/extractors/presets/kiwame.ts
4457
+ var DEFAULT_THRESHOLD = 0.47;
4458
+ var findBody2 = (hast) => findElement(hast, (element3) => element3.tagName === "body") ?? hast;
4459
+ var completeTables = (kept, blocks) => {
4460
+ const rows = /* @__PURE__ */ new Set();
4461
+ const tables = /* @__PURE__ */ new Set();
4462
+ for (const block of blocks) {
4463
+ if (!kept.has(block.owner)) {
4464
+ continue;
4465
+ }
4466
+ const { row, table } = enclosingTable(block.frame);
4467
+ if (row) {
4468
+ rows.add(row);
4469
+ }
4470
+ if (table) {
4471
+ tables.add(table);
4472
+ }
4473
+ }
4474
+ for (const table of tables) {
4475
+ const first = findElement(table, (element3) => element3.tagName === "tr");
4476
+ if (first) {
4477
+ rows.add(first);
4478
+ }
4479
+ }
4480
+ for (const block of blocks) {
4481
+ const { row } = enclosingTable(block.frame);
4482
+ if (row && rows.has(row)) {
4483
+ kept.add(block.owner);
4484
+ }
4485
+ }
4486
+ };
4487
+ var enclosingTable = (start) => {
4488
+ let row;
4489
+ for (let frame = start; frame; frame = frame.parent) {
4490
+ const tag = frame.element.tagName;
4491
+ if (tag === "tr" && !row) {
4492
+ row = frame.element;
4493
+ } else if (tag === "table") {
4494
+ return { row, table: frame.element };
4495
+ }
4496
+ }
4497
+ return { row };
4498
+ };
4499
+ var HEADING_LOOKAHEAD = 3;
4500
+ var keepSectionHeadings = (kept, blocks) => {
4501
+ let seenKept = false;
4502
+ for (let index = 0; index < blocks.length; index++) {
4503
+ const block = blocks[index];
4504
+ if (kept.has(block.owner)) {
4505
+ seenKept = true;
4506
+ continue;
4507
+ }
4508
+ if (!(seenKept && /^h[1-6]$/.test(block.owner.tagName))) {
4509
+ continue;
4510
+ }
4511
+ for (let next = index + 1; next < Math.min(blocks.length, index + 1 + HEADING_LOOKAHEAD); next++) {
4512
+ if (/^h[1-6]$/.test(blocks[next].owner.tagName)) {
4513
+ break;
4514
+ }
4515
+ if (kept.has(blocks[next].owner)) {
4516
+ kept.add(block.owner);
4517
+ break;
4518
+ }
4519
+ }
4520
+ }
4521
+ };
4522
+ var CODE_IN_CONTENT_THRESHOLD = 0.2;
4523
+ var CODE_CONTEXT = 6;
4524
+ var keepCodeInContent = (kept, blocks, probabilities) => {
4525
+ const keptIndex = blocks.map((block) => kept.has(block.owner));
4526
+ const near = (from, step) => {
4527
+ for (let distance = 1; distance <= CODE_CONTEXT; distance++) {
4528
+ const index = from + step * distance;
4529
+ if (index < 0 || index >= blocks.length) {
4530
+ return false;
4531
+ }
4532
+ if (keptIndex[index]) {
4533
+ return true;
4534
+ }
4535
+ }
4536
+ return false;
4537
+ };
4538
+ for (const block of blocks) {
4539
+ if (block.owner.tagName === "pre" && !keptIndex[block.index] && probabilities[block.index] >= CODE_IN_CONTENT_THRESHOLD && near(block.index, -1) && near(block.index, 1)) {
4540
+ kept.add(block.owner);
4541
+ }
4542
+ }
4543
+ };
4544
+ var listOf = (block) => {
4545
+ if (block.owner.tagName !== "li") {
4546
+ return void 0;
4547
+ }
4548
+ for (let frame = block.frame.parent; frame; frame = frame.parent) {
4549
+ const tag = frame.element.tagName;
4550
+ if (tag === "ul" || tag === "ol") {
4551
+ return frame.element;
4552
+ }
4553
+ }
4554
+ return void 0;
4555
+ };
4556
+ var keepAuthoredLists = (kept, blocks) => {
4557
+ let seenKept = false;
4558
+ for (let index = 0; index < blocks.length - 1; index++) {
4559
+ const block = blocks[index];
4560
+ const introducesList = kept.has(block.owner) && /[::]\s*$/.test(block.text) || seenKept && /^h[1-6]$/.test(block.owner.tagName) && REFERENCE_HEADING.test(block.text.trim());
4561
+ seenKept ||= kept.has(block.owner);
4562
+ const list = listOf(blocks[index + 1]);
4563
+ if (!(introducesList && list)) {
4564
+ continue;
4565
+ }
4566
+ kept.add(block.owner);
4567
+ for (let next = index + 1; next < blocks.length && listOf(blocks[next]) === list; next++) {
4568
+ kept.add(blocks[next].owner);
4569
+ }
4570
+ }
4571
+ };
4572
+ var pruneToBlocks = (element3, kept, ownerKept) => {
4573
+ const isBlock = element3.type === "element" && (BLOCK_TAGS2.has(element3.tagName) || element3.tagName === "pre");
4574
+ const selfKept = isBlock ? kept.has(element3) : ownerKept;
4575
+ if (element3.type === "element" && element3.tagName === "pre") {
4576
+ return selfKept;
4577
+ }
4578
+ let keepChildren = false;
4579
+ const children = [];
4580
+ for (const child of element3.children) {
4581
+ if (child.type === "element") {
4582
+ if (pruneToBlocks(child, kept, selfKept)) {
4583
+ children.push(child);
4584
+ keepChildren = true;
4585
+ }
4586
+ } else if (child.type === "text") {
4587
+ if (selfKept) {
4588
+ children.push(child);
4589
+ }
4590
+ } else {
4591
+ children.push(child);
4592
+ }
4593
+ }
4594
+ element3.children = children;
4595
+ return selfKept || keepChildren;
4596
+ };
4597
+ var createKiwameExtractor = (options = {}) => {
4598
+ const { threshold = DEFAULT_THRESHOLD, model = BLOCK_MODEL, cleanup = true } = options;
4599
+ const stackModel = options.stackModel === void 0 ? BLOCK_STACK_MODEL : options.stackModel;
4600
+ const usable = isUsableModel(model);
4601
+ const stackUsable = stackModel ? isUsableModel(stackModel, STACKED_FEATURE_COUNT) : false;
4602
+ return (params) => {
4603
+ if (!usable) {
4604
+ return takumiExtractor(params);
4605
+ }
4606
+ const { hast, lang, owned } = params;
4607
+ const body = owned ? findBody2(hast) : cloneHast(findBody2(hast));
4608
+ stripNonContent(body);
4609
+ const blocks = segmentBlocks(body);
4610
+ if (blocks.length === 0 || !(isElement(body) || body.type === "root")) {
4611
+ return body;
4612
+ }
4613
+ const collector = new MetricsCollector();
4614
+ const takumiKept = takumiSelection(body, lang, params.url);
4615
+ const features = blockFeatures({ root: body, blocks, collector, lang, takumiKept });
4616
+ let probabilities = scoreBlocks(features, blocks.length, model, FEATURE_COUNT);
4617
+ if (stackModel && stackUsable) {
4618
+ const stacked = stackedFeatures(blocks, features, probabilities);
4619
+ probabilities = scoreBlocks(stacked, blocks.length, stackModel, STACKED_FEATURE_COUNT);
4620
+ }
4621
+ const kept = /* @__PURE__ */ new Set();
4622
+ for (const block of blocks) {
4623
+ if (probabilities[block.index] >= threshold) {
4624
+ kept.add(block.owner);
4625
+ }
4626
+ }
4627
+ if (kept.size === 0) {
4628
+ return takumiExtractor({ hast: body, lang, url: params.url, owned: true });
4629
+ }
4630
+ keepCodeInContent(kept, blocks, probabilities);
4631
+ keepSectionHeadings(kept, blocks);
4632
+ keepAuthoredLists(kept, blocks);
4633
+ completeTables(kept, blocks);
4634
+ pruneToBlocks(body, kept, false);
4635
+ unwrapLayoutTables(body);
4636
+ if (!cleanup) {
4637
+ return body;
4638
+ }
4639
+ walk(body, (node) => {
4640
+ if (isElement(node) && (node.tagName === "form" || node.tagName === "fieldset")) {
4641
+ node.tagName = "div";
4642
+ }
4643
+ });
4644
+ return cleanContent(body, new MetricsCollector());
4645
+ };
4646
+ };
4647
+ var kiwameExtractor = createKiwameExtractor();
4648
+
2524
4649
  // src/extractors/presets/auto.ts
2525
4650
  var createAutoExtractor = (options = {}) => {
2526
- const { adapters } = options;
4651
+ const { adapters, fallback = kiwameExtractor } = options;
2527
4652
  return (params) => {
2528
4653
  if (adapters !== false) {
2529
4654
  const extracted = runAdapters({ hast: params.hast, url: params.url, lang: params.lang }, adapters ?? void 0);
@@ -2531,7 +4656,7 @@ var createAutoExtractor = (options = {}) => {
2531
4656
  return extracted;
2532
4657
  }
2533
4658
  }
2534
- return takumiExtractor(params);
4659
+ return fallback(params);
2535
4660
  };
2536
4661
  };
2537
4662
  var autoExtractor = createAutoExtractor();
@@ -2632,7 +4757,6 @@ var customAHandler = (options) => (state, node) => {
2632
4757
  };
2633
4758
 
2634
4759
  // src/mdast-handlers/custom-code-handler.ts
2635
- import { toText } from "hast-util-to-text";
2636
4760
  import { trimTrailingLines } from "trim-trailing-lines";
2637
4761
 
2638
4762
  // src/utils/detect-code-lang.ts
@@ -2683,17 +4807,157 @@ var detectLanguage = (code) => {
2683
4807
  ).filter(([_, score]) => score > 20).sort((a, b) => b[1] - a[1])[0]?.[0] || "plain";
2684
4808
  };
2685
4809
 
4810
+ // src/utils/pre-text.ts
4811
+ var LINE_BLOCK_TAGS = /* @__PURE__ */ new Set([
4812
+ "address",
4813
+ "article",
4814
+ "aside",
4815
+ "blockquote",
4816
+ "dd",
4817
+ "div",
4818
+ "dl",
4819
+ "dt",
4820
+ "figcaption",
4821
+ "figure",
4822
+ "footer",
4823
+ "form",
4824
+ "h1",
4825
+ "h2",
4826
+ "h3",
4827
+ "h4",
4828
+ "h5",
4829
+ "h6",
4830
+ "header",
4831
+ "hr",
4832
+ "li",
4833
+ "main",
4834
+ "nav",
4835
+ "ol",
4836
+ "p",
4837
+ "pre",
4838
+ "section",
4839
+ "table",
4840
+ "tr",
4841
+ "ul"
4842
+ ]);
4843
+ var INLINE_CONTEXT_TAGS = /* @__PURE__ */ new Set(["span", "a", "b", "i", "em", "strong", "mark", "small", "u", "s", "label"]);
4844
+ var preText = (node) => {
4845
+ let out = "";
4846
+ const ensureLineStart = () => {
4847
+ if (out.length > 0 && out.charCodeAt(out.length - 1) !== 10) {
4848
+ out += "\n";
4849
+ }
4850
+ };
4851
+ const visitChildren = (parent, inline) => {
4852
+ let cells = 0;
4853
+ for (const child of parent.children) {
4854
+ const isCell = child.type === "element" && (child.tagName === "td" || child.tagName === "th");
4855
+ visit(child, isCell ? cells++ : 0, inline);
4856
+ }
4857
+ };
4858
+ const visitElement = (element3, cellIndex, inline) => {
4859
+ const tag = element3.tagName;
4860
+ if (tag === "br") {
4861
+ out += "\n";
4862
+ return;
4863
+ }
4864
+ if (cellIndex > 0) {
4865
+ out += " ";
4866
+ }
4867
+ const block = !inline && LINE_BLOCK_TAGS.has(tag);
4868
+ if (block) {
4869
+ ensureLineStart();
4870
+ }
4871
+ visitChildren(element3, inline || INLINE_CONTEXT_TAGS.has(tag));
4872
+ if (block) {
4873
+ ensureLineStart();
4874
+ }
4875
+ };
4876
+ const visit = (current, cellIndex, inline) => {
4877
+ if (current.type === "text") {
4878
+ out += current.value;
4879
+ } else if (current.type === "element") {
4880
+ visitElement(current, cellIndex, inline);
4881
+ } else if (current.type === "root") {
4882
+ visitChildren(current, inline);
4883
+ }
4884
+ };
4885
+ visit(node, 0, false);
4886
+ return out;
4887
+ };
4888
+
4889
+ // src/mdast-handlers/twoslash.ts
4890
+ var cleanTwoslash = (pre) => {
4891
+ if (!classList(pre).includes("twoslash")) {
4892
+ return void 0;
4893
+ }
4894
+ let language;
4895
+ const clean2 = (element3) => {
4896
+ element3.children = element3.children.flatMap((child) => {
4897
+ if (!isElement(child)) {
4898
+ return [child];
4899
+ }
4900
+ const classes = classList(child);
4901
+ if (classes.includes("language-id")) {
4902
+ language ||= preText(child).trim() || void 0;
4903
+ return [];
4904
+ }
4905
+ if (classes.includes("playground-link") || classes.includes("error-behind")) {
4906
+ return [];
4907
+ }
4908
+ if (classes.includes("error")) {
4909
+ return [errorLine(child)];
4910
+ }
4911
+ clean2(child);
4912
+ return [child];
4913
+ });
4914
+ };
4915
+ clean2(pre);
4916
+ return language && /^[\w+#.-]+$/.test(language) ? language : void 0;
4917
+ };
4918
+ var errorLine = (error) => {
4919
+ let code = "";
4920
+ let message = "";
4921
+ for (const child of error.children) {
4922
+ if (isElement(child) && classList(child).includes("code")) {
4923
+ code = preText(child).trim();
4924
+ } else {
4925
+ message += isElement(child) ? preText(child) : child.type === "text" ? child.value : "";
4926
+ }
4927
+ }
4928
+ const prefix = /^\d+$/.test(code) ? `error TS${code}: ` : "error: ";
4929
+ const lines = `${prefix}${message.trim()}`.split("\n").map((line) => `// ${line}`);
4930
+ return { type: "element", tagName: "div", properties: {}, children: [{ type: "text", value: lines.join("\n") }] };
4931
+ };
4932
+
2686
4933
  // src/mdast-handlers/custom-code-handler.ts
2687
- var LANGUAGE_MATCH_REGEX = [/language-(\w+)/, /highlight-source-(\w+)/, /CodeBlock--language-(\w+)/];
4934
+ var LANGUAGE_MATCH_REGEX = [/^language-(\S+)$/, /^highlight-source-(\S+)$/, /^CodeBlock--language-(\S+)$/];
4935
+ var LANGUAGE_ATTRIBUTES = ["dataLanguage", "dataLang"];
4936
+ var attributeLanguage = (element3) => {
4937
+ for (const name of LANGUAGE_ATTRIBUTES) {
4938
+ const value = element3.properties?.[name];
4939
+ if (typeof value === "string" && /^[\w+#.-]+$/.test(value.trim()) && value.trim() !== "plaintext") {
4940
+ return value.trim();
4941
+ }
4942
+ }
4943
+ return void 0;
4944
+ };
4945
+ var codeLanguage = (...elements) => elements.flatMap(classList).map((className) => LANGUAGE_MATCH_REGEX.map((regex) => className.match(regex)).find(Boolean)?.[1]).find(Boolean) ?? elements.map(attributeLanguage).find(Boolean);
4946
+ var codeMeta = (pre) => {
4947
+ const title = pre.properties?.dataTitle;
4948
+ if (typeof title !== "string") {
4949
+ return null;
4950
+ }
4951
+ const clean2 = title.replace(/["\r\n]+/g, " ").trim();
4952
+ return clean2 ? `title="${clean2}"` : null;
4953
+ };
2688
4954
  var customCodeHandler = (state, node) => {
2689
- const classNames = node.properties?.className || [];
2690
- const codeValue = trimTrailingLines(toText(node)).trim();
2691
- const classLang = classNames.map((className) => {
2692
- const match = LANGUAGE_MATCH_REGEX.map((regex) => className.match(regex)).find((match2) => match2);
2693
- return match?.[1];
2694
- }).find((className) => className);
4955
+ const twoslashLang = cleanTwoslash(node);
4956
+ const code = node.children.find((child) => isElement(child) && child.tagName === "code");
4957
+ const codeValue = trimTrailingLines(preText(node));
4958
+ const classLang = twoslashLang || codeLanguage(...isElement(code) ? [code, node] : [node]);
2695
4959
  const lang = classLang || detectLanguage(codeValue) || null;
2696
- const result = { type: "code", lang, meta: null, value: codeValue };
4960
+ const result = { type: "code", lang, meta: codeMeta(node), value: codeValue };
2697
4961
  state.patch(node, result);
2698
4962
  return result;
2699
4963
  };
@@ -2702,48 +4966,24 @@ var customCodeHandler = (state, node) => {
2702
4966
  import { select as select5 } from "hast-util-select";
2703
4967
  import { defaultHandlers as defaultHandlers2 } from "hast-util-to-mdast";
2704
4968
  import { toString as hastToString2 } from "hast-util-to-string";
2705
- import { toText as toText2 } from "hast-util-to-text";
2706
4969
  import { trimTrailingLines as trimTrailingLines2 } from "trim-trailing-lines";
2707
4970
  var CODE_BLOCK_REGEX = /highlight-source|language-|codegroup|codeblock|code-block/i;
2708
4971
  var CODE_FILENAME_SELECTORS = "[class*='fileName'],[class*='fileName'],[class*='title'],[class*='Title']";
2709
- var LANGUAGE_MATCH_REGEX2 = [/language-(\w+)/, /highlight-source-(\w+)/, /CodeBlock--language-(\w+)/];
2710
- var findRecursive = (array, condition, maxDepth = 3) => {
2711
- if (maxDepth <= 0) {
2712
- return null;
2713
- }
2714
- for (const value of array) {
2715
- const result = condition(value);
2716
- if (Array.isArray(result)) {
2717
- return findRecursive(result, condition, maxDepth - 1);
2718
- }
2719
- if (result) {
2720
- return value;
2721
- }
2722
- }
2723
- return null;
2724
- };
2725
4972
  var customDivHandler = (state, node) => {
2726
- const classNames = Array.isArray(node.properties.className) ? node.properties.className : [];
2727
- const codeBlock = findRecursive(node.children, (child) => {
2728
- if (child.type !== "element") {
2729
- return false;
2730
- }
2731
- if (child.tagName === "pre") {
2732
- return true;
2733
- }
2734
- return child.children.filter((child2) => child2.type === "element");
2735
- });
2736
- if (codeBlock && classNames.some((className) => CODE_BLOCK_REGEX.test(className))) {
2737
- const codeBlockClassNames = codeBlock.type === "element" ? codeBlock.properties.className ?? [] : [];
2738
- const codeValue = trimTrailingLines2(toText2(codeBlock)).trim();
4973
+ const classNames = classList(node);
4974
+ if (!classNames.some((className) => CODE_BLOCK_REGEX.test(className))) {
4975
+ return defaultHandlers2.div(state, node);
4976
+ }
4977
+ const codeBlocks = collectElements(node, (element3) => element3.tagName === "pre");
4978
+ const codeBlock = codeBlocks.length === 1 ? codeBlocks[0] : void 0;
4979
+ if (codeBlock) {
4980
+ const codeValue = trimTrailingLines2(preText(codeBlock));
2739
4981
  const filenameElement = select5(CODE_FILENAME_SELECTORS, node);
2740
4982
  const fileLang = filenameElement ? hastToString2(filenameElement).match(/\.(\w+)$/)?.[1] : null;
2741
- const classLang = [...classNames, ...codeBlockClassNames].map((className) => {
2742
- const match = LANGUAGE_MATCH_REGEX2.map((regex) => className.match(regex)).find((match2) => match2);
2743
- return match?.[1];
2744
- }).find((className) => className);
4983
+ const code = codeBlock.children.find((child) => isElement(child) && child.tagName === "code");
4984
+ const classLang = codeLanguage(...isElement(code) ? [code, codeBlock, node] : [codeBlock, node]);
2745
4985
  const lang = fileLang || classLang || detectLanguage(codeValue) || null;
2746
- const result = { type: "code", lang, meta: null, value: codeValue };
4986
+ const result = { type: "code", lang, meta: codeMeta(codeBlock), value: codeValue };
2747
4987
  state.patch(node, result);
2748
4988
  return result;
2749
4989
  }
@@ -2763,11 +5003,20 @@ var hasNoUsableSource = (node) => {
2763
5003
  }
2764
5004
  return false;
2765
5005
  };
5006
+ var PLACEHOLDER_FILE = /^(?:[\w-]*[-_.])?placeholder[\w-]*\.(?:gif|png|svg|webp|jpe?g)$|^(?:spacer|blank|transparent|pixel)\.(?:gif|png)$/i;
5007
+ var isUndescribedPlaceholder = (node) => {
5008
+ if (stringProperty(node, "alt")?.trim() || stringProperty(node, "title")?.trim()) {
5009
+ return false;
5010
+ }
5011
+ const src = stringProperty(node, "src") ?? "";
5012
+ const file = src.split(/[?#]/)[0].split("/").pop() ?? "";
5013
+ return PLACEHOLDER_FILE.test(file);
5014
+ };
2766
5015
  var customImgHandler = (options) => (state, node) => {
2767
5016
  if (options?.hideImage) {
2768
5017
  return void 0;
2769
5018
  }
2770
- if (hasNoUsableSource(node)) {
5019
+ if (hasNoUsableSource(node) || isUndescribedPlaceholder(node)) {
2771
5020
  return void 0;
2772
5021
  }
2773
5022
  const image = defaultHandlers3.image(state, node);
@@ -2782,7 +5031,175 @@ var customImgHandler = (options) => (state, node) => {
2782
5031
 
2783
5032
  // src/mdast-handlers/custom-table-handler.ts
2784
5033
  import { defaultHandlers as defaultHandlers4 } from "hast-util-to-mdast";
2785
- import { toText as toText3 } from "hast-util-to-text";
5034
+ import { toText } from "hast-util-to-text";
5035
+
5036
+ // src/mdast-handlers/table-cell-flatten.ts
5037
+ var PHRASING_TYPES = /* @__PURE__ */ new Set([
5038
+ "text",
5039
+ "emphasis",
5040
+ "strong",
5041
+ "delete",
5042
+ "inlineCode",
5043
+ "link",
5044
+ "linkReference",
5045
+ "image",
5046
+ "imageReference",
5047
+ "html",
5048
+ "footnoteReference",
5049
+ "inlineMath"
5050
+ ]);
5051
+ var PHRASING_PARENTS = /* @__PURE__ */ new Set(["emphasis", "strong", "delete", "link", "linkReference"]);
5052
+ var lineBreak = () => ({ type: "html", value: "<br>" });
5053
+ var needsFlattening = (nodes) => nodes.some((node) => {
5054
+ if (node.type === "break") {
5055
+ return true;
5056
+ }
5057
+ if (!PHRASING_TYPES.has(node.type)) {
5058
+ return true;
5059
+ }
5060
+ if ((node.type === "text" || node.type === "inlineCode") && node.value.includes("\n")) {
5061
+ return true;
5062
+ }
5063
+ return PHRASING_PARENTS.has(node.type) && "children" in node && needsFlattening(node.children);
5064
+ });
5065
+ var CellBuilder = class _CellBuilder {
5066
+ constructor() {
5067
+ this.out = [];
5068
+ this.#pendingBlock = false;
5069
+ }
5070
+ #pendingBlock;
5071
+ /** Starts a new visual line when the previous block left content on the current one. */
5072
+ block() {
5073
+ const last = this.out.at(-1);
5074
+ if (this.#pendingBlock && last && !(last.type === "html" && last.value === "<br>")) {
5075
+ this.out.push(lineBreak());
5076
+ }
5077
+ this.#pendingBlock = true;
5078
+ }
5079
+ add(nodes) {
5080
+ for (const node of nodes) {
5081
+ this.#addOne(node);
5082
+ }
5083
+ }
5084
+ #addOne(node) {
5085
+ switch (node.type) {
5086
+ case "break":
5087
+ this.out.push(lineBreak());
5088
+ return;
5089
+ case "text":
5090
+ this.out.push({ type: "text", value: node.value.replace(/\s*\n\s*/g, " ") });
5091
+ return;
5092
+ case "inlineCode":
5093
+ this.#codeLines(node.value);
5094
+ return;
5095
+ case "code":
5096
+ this.block();
5097
+ this.#codeLines(node.value);
5098
+ return;
5099
+ case "math":
5100
+ this.block();
5101
+ this.out.push({ type: "inlineMath", value: node.value.replace(/\s*\n\s*/g, " ") });
5102
+ return;
5103
+ case "list":
5104
+ node.children.forEach((item, index) => {
5105
+ this.block();
5106
+ const marker = node.ordered ? `${(node.start ?? 1) + index}. ` : "- ";
5107
+ this.out.push({ type: "text", value: marker });
5108
+ this.#pendingBlock = false;
5109
+ this.add(item.children);
5110
+ });
5111
+ return;
5112
+ case "thematicBreak":
5113
+ return;
5114
+ default:
5115
+ this.#addContainer(node);
5116
+ }
5117
+ }
5118
+ #addContainer(node) {
5119
+ if (PHRASING_PARENTS.has(node.type) && "children" in node) {
5120
+ const inner = new _CellBuilder();
5121
+ inner.add(node.children);
5122
+ this.out.push({ ...node, children: inner.out });
5123
+ return;
5124
+ }
5125
+ if (PHRASING_TYPES.has(node.type)) {
5126
+ this.out.push(node);
5127
+ return;
5128
+ }
5129
+ if ("children" in node) {
5130
+ this.block();
5131
+ this.add(node.children);
5132
+ }
5133
+ }
5134
+ #codeLines(value) {
5135
+ value.split("\n").forEach((line, index) => {
5136
+ if (index > 0) {
5137
+ this.out.push(lineBreak());
5138
+ }
5139
+ if (line.trim().length > 0) {
5140
+ this.out.push({ type: "inlineCode", value: line });
5141
+ }
5142
+ });
5143
+ }
5144
+ };
5145
+ var flattenTableCells = (table) => {
5146
+ for (const row of table.children) {
5147
+ for (const cell of row.children) {
5148
+ if (!needsFlattening(cell.children)) {
5149
+ continue;
5150
+ }
5151
+ const builder = new CellBuilder();
5152
+ builder.add(cell.children);
5153
+ cell.children = builder.out;
5154
+ }
5155
+ }
5156
+ };
5157
+ var hasMultilineCode = (nodes) => nodes.some(
5158
+ (node) => node.type === "code" && node.value.includes("\n") || "children" in node && hasMultilineCode(node.children)
5159
+ );
5160
+ var tableHasCodeSamples = (table) => table.children.some((row) => row.children.some((cell) => hasMultilineCode(cell.children)));
5161
+ var unfoldTable = (table, hasHeader) => {
5162
+ const [first, ...rest] = table.children;
5163
+ const labelled = hasHeader && rest.length > 0;
5164
+ const labels = labelled && first ? first.children.map((cell) => cell.children) : [];
5165
+ const rows = labelled ? rest : table.children;
5166
+ const out = [];
5167
+ rows.forEach((row, rowIndex) => {
5168
+ if (rowIndex > 0) {
5169
+ out.push({ type: "thematicBreak" });
5170
+ }
5171
+ row.children.forEach((cell, cellIndex) => {
5172
+ const label = labels[cellIndex];
5173
+ if (label && label.length > 0) {
5174
+ out.push({ type: "paragraph", children: [{ type: "strong", children: label }] });
5175
+ }
5176
+ out.push(...asBlocks(cell.children));
5177
+ });
5178
+ });
5179
+ return out;
5180
+ };
5181
+ var asBlocks = (nodes) => {
5182
+ const blocks = [];
5183
+ let run = [];
5184
+ const flush = () => {
5185
+ if (run.some((node) => node.type !== "text" || node.value.trim().length > 0)) {
5186
+ blocks.push({ type: "paragraph", children: run });
5187
+ }
5188
+ run = [];
5189
+ };
5190
+ for (const node of nodes) {
5191
+ if (PHRASING_TYPES.has(node.type) || node.type === "break") {
5192
+ run.push(node);
5193
+ } else {
5194
+ flush();
5195
+ blocks.push(node);
5196
+ }
5197
+ }
5198
+ flush();
5199
+ return blocks;
5200
+ };
5201
+
5202
+ // src/mdast-handlers/custom-table-handler.ts
2786
5203
  var MAX_SPAN = 1e3;
2787
5204
  var clampSpans = (node) => {
2788
5205
  walk(node, (candidate) => {
@@ -2797,14 +5214,30 @@ var clampSpans = (node) => {
2797
5214
  }
2798
5215
  });
2799
5216
  };
5217
+ var startsWithHeaderRow = (table) => {
5218
+ const row = findElement(table, (element3) => element3.tagName === "tr");
5219
+ if (!row) {
5220
+ return false;
5221
+ }
5222
+ const cells = row.children.filter(isElement);
5223
+ return cells.length > 0 && cells.every((cell) => cell.tagName === "th");
5224
+ };
2800
5225
  var customTableHandler = (options) => (state, node) => {
2801
5226
  if (options?.asText) {
2802
- const paragraph2 = { type: "paragraph", children: [{ type: "text", value: toText3(node) }] };
5227
+ const paragraph2 = { type: "paragraph", children: [{ type: "text", value: toText(node) }] };
2803
5228
  state.patch(node, paragraph2);
2804
5229
  return paragraph2;
2805
5230
  }
2806
5231
  clampSpans(node);
2807
- return defaultHandlers4.table(state, node);
5232
+ const result = defaultHandlers4.table(state, node);
5233
+ if (!result || Array.isArray(result) || result.type !== "table") {
5234
+ return result;
5235
+ }
5236
+ if (tableHasCodeSamples(result)) {
5237
+ return unfoldTable(result, startsWithHeaderRow(node));
5238
+ }
5239
+ flattenTableCells(result);
5240
+ return result;
2808
5241
  };
2809
5242
 
2810
5243
  // src/mdast-handlers/definition-list-handler.ts
@@ -2837,6 +5270,20 @@ var hoistBoundaryWhitespace = (nodes) => {
2837
5270
  }
2838
5271
  return result;
2839
5272
  };
5273
+ var termsAndDefinitions = (parent) => {
5274
+ const found = [];
5275
+ for (const child of parent.children) {
5276
+ if (child.type !== "element") {
5277
+ continue;
5278
+ }
5279
+ if (child.tagName === "dt" || child.tagName === "dd") {
5280
+ found.push(child);
5281
+ } else if (child.tagName === "div") {
5282
+ found.push(...termsAndDefinitions(child));
5283
+ }
5284
+ }
5285
+ return found;
5286
+ };
2840
5287
  var definitionListHandler = (state, node) => {
2841
5288
  const items = [];
2842
5289
  let current;
@@ -2851,11 +5298,7 @@ var definitionListHandler = (state, node) => {
2851
5298
  items.push({ type: "listItem", spread: false, children: [heading2, ...current.definitions] });
2852
5299
  current = void 0;
2853
5300
  };
2854
- for (const child of node.children) {
2855
- if (child.type !== "element") {
2856
- continue;
2857
- }
2858
- const element3 = child;
5301
+ for (const element3 of termsAndDefinitions(node)) {
2859
5302
  if (element3.tagName === "dt") {
2860
5303
  if (current && current.definitions.length > 0) {
2861
5304
  flush();
@@ -2874,7 +5317,8 @@ var definitionListHandler = (state, node) => {
2874
5317
  }
2875
5318
  flush();
2876
5319
  if (items.length === 0) {
2877
- return void 0;
5320
+ const fallback = state.toFlow(state.all(node));
5321
+ return fallback.length > 0 ? fallback : void 0;
2878
5322
  }
2879
5323
  const result = { type: "list", ordered: false, spread: false, children: items };
2880
5324
  state.patch(node, result);
@@ -2987,14 +5431,16 @@ var katexDuplicates = (node) => {
2987
5431
  if (!(classes.includes("katex") || classes.includes("katex-display"))) {
2988
5432
  return [];
2989
5433
  }
2990
- const hasMathml = node.children.some((child) => isElement(child) && classList(child).includes("katex-mathml"));
5434
+ const hasMathml = node.children.some(
5435
+ (child) => isElement(child) && classList(child).includes("katex-mathml") && hasMathSource(child)
5436
+ );
2991
5437
  if (!hasMathml) {
2992
5438
  return [];
2993
5439
  }
2994
5440
  return node.children.filter((child) => isElement(child) && classList(child).includes("katex-html"));
2995
5441
  };
2996
5442
  var mediawikiDuplicates = (node) => {
2997
- if (!classList(node).includes("mwe-math-element")) {
5443
+ if (!classList(node).includes("mwe-math-element") || !hasMathSource(node)) {
2998
5444
  return [];
2999
5445
  }
3000
5446
  return node.children.filter(
@@ -3005,8 +5451,15 @@ var mathjaxDuplicates = (node) => {
3005
5451
  if (node.tagName !== "mjx-container") {
3006
5452
  return [];
3007
5453
  }
5454
+ const hasMathml = node.children.some(
5455
+ (child) => isElement(child) && child.tagName === "mjx-assistive-mml" && hasMathSource(child)
5456
+ );
5457
+ if (!hasMathml) {
5458
+ return [];
5459
+ }
3008
5460
  return node.children.filter((child) => isElement(child) && child.tagName !== "mjx-assistive-mml");
3009
5461
  };
5462
+ var hasMathSource = (node) => Boolean(findElement(node, (element3) => element3.tagName === "math" && element3.children.length > 0));
3010
5463
  var dedupeRenderedMath = (tree) => {
3011
5464
  const doomed = /* @__PURE__ */ new Set();
3012
5465
  walk(tree, (node) => {
@@ -3068,8 +5521,8 @@ var getLangFromHast = (node) => {
3068
5521
  }
3069
5522
  return void 0;
3070
5523
  };
3071
- var getLangFromStr = (str) => {
3072
- const match = str.match(/lang=["']([^"']+)["']/);
5524
+ var getLangFromStr = (str2) => {
5525
+ const match = str2.match(/lang=["']([^"']+)["']/);
3073
5526
  if (match) {
3074
5527
  return match[1];
3075
5528
  }
@@ -3093,10 +5546,10 @@ var getUrlFromHast = (node) => {
3093
5546
  // src/html-to-mdast.ts
3094
5547
  var htmlToMdast = (htmlOrHast, options) => {
3095
5548
  const { extractors, url: defaultUrl, lang: defaultLang } = options || {};
3096
- const [lang, hast] = typeof htmlOrHast === "string" ? [defaultLang || getLangFromStr(htmlOrHast), fromHtml(htmlOrHast, { fragment: true })] : [defaultLang || getLangFromHast(htmlOrHast), htmlOrHast];
5549
+ const [lang, hast] = typeof htmlOrHast === "string" ? [defaultLang || getLangFromStr(htmlOrHast), parseHtml(htmlOrHast, { fragment: true })] : [defaultLang || getLangFromHast(htmlOrHast), htmlOrHast];
3097
5550
  const isOwned = typeof htmlOrHast === "string" || (options?.owned ?? false);
3098
5551
  const url = defaultUrl || getUrlFromHast(hast);
3099
- const extractedHast = pipeExtractors({ hast, lang, url, owned: isOwned }, extractors);
5552
+ const extractedHast = pipeExtractors({ hast: isOwned ? hast : cloneHast(hast), lang, url, owned: true }, extractors);
3100
5553
  normalizeHast(extractedHast, options?.normalize);
3101
5554
  const mdast = toMdast(extractedHast, {
3102
5555
  handlers: {
@@ -3121,19 +5574,25 @@ import { mathToMarkdown } from "mdast-util-math";
3121
5574
  import { toMarkdown } from "mdast-util-to-markdown";
3122
5575
 
3123
5576
  // src/link-replacer.ts
3124
- var linkReplacer = (markdown, base) => {
3125
- const regex = /(!?\[.*?\]\()([^)\s]+)(\))/g;
3126
- return markdown.replace(regex, (match, pre, url, post) => {
3127
- if (/^(https?:|#)/.test(url)) {
3128
- return match;
3129
- }
3130
- try {
3131
- const absoluteUrl = new URL(url, base).href;
3132
- return `${pre}${absoluteUrl}${post}`;
3133
- } catch {
3134
- return match;
3135
- }
3136
- });
5577
+ var absoluteUrl = (url, base) => {
5578
+ if (/^(?:[a-z][a-z\d+.-]*:|#)/i.test(url)) {
5579
+ return url;
5580
+ }
5581
+ try {
5582
+ return new URL(url, base).href;
5583
+ } catch {
5584
+ return url;
5585
+ }
5586
+ };
5587
+ var linkReplacer = (node, base) => {
5588
+ let result = node;
5589
+ if (node.type === "link" || node.type === "image" || node.type === "definition") {
5590
+ result = { ...node, url: absoluteUrl(node.url, base) };
5591
+ }
5592
+ if ("children" in result) {
5593
+ return { ...result, children: result.children.map((child) => linkReplacer(child, base)) };
5594
+ }
5595
+ return result;
3137
5596
  };
3138
5597
 
3139
5598
  // src/utils/mdast-utils.ts
@@ -3151,11 +5610,8 @@ var DEFAULT_MDAST_TO_MARKDOWN_OPTIONS = {
3151
5610
  };
3152
5611
  var mdastToMarkdown = (mdast, options) => {
3153
5612
  const { baseUrl, ...toMarkdownOptions } = { ...DEFAULT_MDAST_TO_MARKDOWN_OPTIONS, ...options };
3154
- let markdown = toMarkdown(warpRoot(mdast), toMarkdownOptions).replace(/\*\*\*\*/g, "");
3155
- if (baseUrl) {
3156
- markdown = linkReplacer(markdown, baseUrl);
3157
- }
3158
- return markdown;
5613
+ const tree = warpRoot(mdast);
5614
+ return toMarkdown(baseUrl ? linkReplacer(tree, baseUrl) : tree, toMarkdownOptions);
3159
5615
  };
3160
5616
 
3161
5617
  // src/metadata/index.ts
@@ -3251,9 +5707,10 @@ var readName = (value) => {
3251
5707
  };
3252
5708
  var asString = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
3253
5709
  var MAX_TITLE_LENGTH = 160;
3254
- var asTitle = (value) => {
5710
+ var MAX_DOCUMENT_TITLE_LENGTH = 300;
5711
+ var asTitle = (value, maxLength = MAX_TITLE_LENGTH) => {
3255
5712
  const cleaned = clean(value);
3256
- return cleaned && cleaned.length <= MAX_TITLE_LENGTH ? cleaned : void 0;
5713
+ return cleaned && cleaned.length <= maxLength ? cleaned : void 0;
3257
5714
  };
3258
5715
  var clean = (value) => {
3259
5716
  if (value === void 0) {
@@ -3269,7 +5726,7 @@ var documentTitle = (tree) => {
3269
5726
  }
3270
5727
  return title.children.map((child) => child.type === "text" ? child.value : "").join("");
3271
5728
  };
3272
- var firstHeading = (tree) => {
5729
+ var firstHeading2 = (tree) => {
3273
5730
  const heading2 = findElement(tree, (element3) => element3.tagName === "h1");
3274
5731
  if (!heading2) {
3275
5732
  return void 0;
@@ -3319,7 +5776,7 @@ var extractMetadata = (tree) => {
3319
5776
  }
3320
5777
  return void 0;
3321
5778
  };
3322
- const title = asTitle(get("og:title", "twitter:title")) ?? asTitle(asString(article?.headline)) ?? asTitle(asString(article?.name)) ?? asTitle(documentTitle(tree)) ?? asTitle(firstHeading(tree));
5779
+ const title = asTitle(get("og:title", "twitter:title")) ?? asTitle(asString(article?.headline)) ?? asTitle(asString(article?.name)) ?? asTitle(documentTitle(tree), MAX_DOCUMENT_TITLE_LENGTH) ?? asTitle(firstHeading2(tree));
3323
5780
  return {
3324
5781
  title,
3325
5782
  description: clean(get("og:description", "twitter:description", "description")) ?? clean(asString(article?.description)),
@@ -3354,7 +5811,7 @@ ${lines.join("\n")}
3354
5811
  // src/html-to-markdown.ts
3355
5812
  var htmlToMarkdownWithMetadata = (htmlOrHast, options) => {
3356
5813
  const { baseUrl, frontmatter, title, formatting: toMarkdownOptions, ...toMdastOptions } = options || {};
3357
- const hast = typeof htmlOrHast === "string" ? fromHtml2(htmlOrHast, { fragment: true }) : htmlOrHast;
5814
+ const hast = typeof htmlOrHast === "string" ? parseHtml(htmlOrHast, { fragment: true }) : htmlOrHast;
3358
5815
  const isOwned = typeof htmlOrHast === "string";
3359
5816
  const declaredLang = typeof htmlOrHast === "string" ? getLangFromStr(htmlOrHast) : void 0;
3360
5817
  const metadata = extractMetadata(hast);
@@ -3368,10 +5825,54 @@ var htmlToMarkdownWithMetadata = (htmlOrHast, options) => {
3368
5825
  url: toMdastOptions.url ?? metadata.canonicalUrl
3369
5826
  });
3370
5827
  const body = mdastToMarkdown(mdast, { baseUrl, ...toMarkdownOptions });
3371
- const titled = title === false ? body : withTitle(body, metadata.title);
5828
+ const pageUrl = toMdastOptions.url ?? metadata.canonicalUrl;
5829
+ const titled = title === false ? body : withTitle(body, headingTitle(metadata.title, metadata.siteName, pageUrl));
3372
5830
  const markdown = frontmatter ? `${toFrontmatter(metadata)}${titled}` : titled;
3373
5831
  return { markdown, metadata };
3374
5832
  };
5833
+ var TITLE_SEPARATOR = /\s+[-|–—·•:]\s+|\s*[||]\s*/;
5834
+ var SITE_SECTION = /^(docs|documentation|blog|news|wiki|developers?|devblog|help|support|reference)$/;
5835
+ var compact = (value) => value.toLowerCase().replace(/[^\p{L}\p{N}]/gu, "");
5836
+ var siteNames = (siteName, url) => {
5837
+ const names = siteName ? siteName.split(TITLE_SEPARATOR).map(compact) : [];
5838
+ try {
5839
+ const labels = url ? new URL(url).hostname.split(".") : [];
5840
+ const meaningful = labels.slice(0, -1).filter((label) => label !== "www");
5841
+ names.push(...meaningful.map(compact), compact(meaningful.join("")), compact(labels.join("").replace(/^www/, "")));
5842
+ } catch {
5843
+ }
5844
+ return names.filter((name) => name.length >= 3);
5845
+ };
5846
+ var headingTitle = (title, siteName, url) => {
5847
+ if (!title) {
5848
+ return title;
5849
+ }
5850
+ const segments = title.split(TITLE_SEPARATOR);
5851
+ if (segments.length < 2) {
5852
+ return title;
5853
+ }
5854
+ const names = siteNames(siteName, url);
5855
+ if (names.length === 0) {
5856
+ return title;
5857
+ }
5858
+ const isSite = (segment) => {
5859
+ const value = compact(segment);
5860
+ return value.length > 0 && names.some((name) => value === name || value.startsWith(name) && SITE_SECTION.test(value.slice(name.length)));
5861
+ };
5862
+ const last = segments[segments.length - 1];
5863
+ if (isSite(last)) {
5864
+ return stripSegment(title, last, "end");
5865
+ }
5866
+ if (siteName && compact(segments[0]) === compact(siteName)) {
5867
+ return stripSegment(title, segments[0], "start");
5868
+ }
5869
+ return title;
5870
+ };
5871
+ var stripSegment = (title, segment, edge) => {
5872
+ const rest = edge === "end" ? title.slice(0, title.lastIndexOf(segment)) : title.slice(segment.length);
5873
+ const trimmed = rest.replace(edge === "end" ? /[\s\-|–—·•:|]+$/ : /^[\s\-|–—·•:|]+/, "");
5874
+ return trimmed.length > 0 ? trimmed : title;
5875
+ };
3375
5876
  var TITLE_LOOKAHEAD = 400;
3376
5877
  var withTitle = (body, title) => {
3377
5878
  if (!title) {
@@ -3381,17 +5882,118 @@ var withTitle = (body, title) => {
3381
5882
  if (/^#\s+\S/m.test(opening)) {
3382
5883
  return body;
3383
5884
  }
3384
- if (normalizeForCompare(opening).includes(normalizeForCompare(title))) {
5885
+ if (mentionsTitle(opening, title)) {
3385
5886
  return body;
3386
5887
  }
3387
5888
  return `# ${title}
3388
5889
 
3389
5890
  ${body}`;
3390
5891
  };
5892
+ var MIN_EMBEDDED_TITLE_LENGTH = 24;
5893
+ var mentionsTitle = (opening, title) => {
5894
+ const wanted = normalizeForCompare(title);
5895
+ if (wanted.length >= MIN_EMBEDDED_TITLE_LENGTH) {
5896
+ return normalizeForCompare(opening).includes(wanted);
5897
+ }
5898
+ return opening.split("\n").some((line) => normalizeForCompare(line.replace(/[#*_`>]/g, "")) === wanted);
5899
+ };
3391
5900
  var normalizeForCompare = (value) => value.replace(/\s+/g, " ").trim().toLowerCase();
3392
5901
 
5902
+ // src/detect-client-shell.ts
5903
+ var SHELL_SUSPICION_THRESHOLD = 300;
5904
+ var SHELL_EMPTY_THRESHOLD = 50;
5905
+ var BODY_PATTERN = /<body[^>]*>([\s\S]*?)<\/body>/i;
5906
+ var HEAD_PATTERN = /<head[^>]*>[\s\S]*?<\/head>/gi;
5907
+ var NOSCRIPT_PATTERN = /<noscript[^>]*>([\s\S]*?)<\/noscript>/gi;
5908
+ var INVISIBLE_ELEMENT_PATTERN = /<(script|style|template|svg|noscript)[^>]*>[\s\S]*?<\/\1>/gi;
5909
+ var COMMENT_PATTERN = /<!--[\s\S]*?-->/g;
5910
+ var TAG_PATTERN = /<[^>]+>/g;
5911
+ var MOUNT_POINT_PATTERN = /<[a-z][^>]*\sid=["'](?:root|app|__next|___gatsby|__nuxt|q-app|svelte|react-root)["']|<app-root[\s>]|\sdata-reactroot[\s>=]/i;
5912
+ var CHALLENGE_PATTERN = /cf-chl|challenge-platform|cf_chl_opt|just a moment|attention required|checking your browser|_incapsula_|px-captcha|datadome/i;
5913
+ var ENTITIES = {
5914
+ "&nbsp;": " ",
5915
+ "&amp;": "&",
5916
+ "&lt;": "<",
5917
+ "&gt;": ">",
5918
+ "&quot;": '"',
5919
+ "&#39;": "'"
5920
+ };
5921
+ var visibleTextOf = (markup) => markup.replace(COMMENT_PATTERN, " ").replace(INVISIBLE_ELEMENT_PATTERN, " ").replace(TAG_PATTERN, " ").replace(/&(?:nbsp|amp|lt|gt|quot|#39);/g, (entity) => ENTITIES[entity] ?? " ").replace(/\s+/g, " ").trim();
5922
+ var noscriptMentionsJavascript = (html) => {
5923
+ for (const match of html.matchAll(NOSCRIPT_PATTERN)) {
5924
+ if (/javascript/i.test(match[1] ?? "")) {
5925
+ return true;
5926
+ }
5927
+ }
5928
+ return false;
5929
+ };
5930
+ var detectClientShell = (html) => {
5931
+ const body = BODY_PATTERN.exec(html)?.[1] ?? html.replace(HEAD_PATTERN, " ");
5932
+ const visibleTextLength = visibleTextOf(body).length;
5933
+ if (visibleTextLength >= SHELL_SUSPICION_THRESHOLD) {
5934
+ return { isShell: false, visibleTextLength };
5935
+ }
5936
+ if (CHALLENGE_PATTERN.test(html)) {
5937
+ return { isShell: true, reason: "anti-bot-challenge", visibleTextLength };
5938
+ }
5939
+ if (MOUNT_POINT_PATTERN.test(body)) {
5940
+ return { isShell: true, reason: "spa-shell", visibleTextLength };
5941
+ }
5942
+ if (noscriptMentionsJavascript(html)) {
5943
+ return { isShell: true, reason: "noscript-only", visibleTextLength };
5944
+ }
5945
+ if (visibleTextLength < SHELL_EMPTY_THRESHOLD) {
5946
+ return { isShell: true, reason: "empty-body", visibleTextLength };
5947
+ }
5948
+ return { isShell: false, visibleTextLength };
5949
+ };
5950
+
5951
+ // src/extract-meta-refresh.ts
5952
+ var MAX_META_REFRESH_DELAY_SECONDS = 10;
5953
+ var META_TAG_PATTERN = /<meta\b[^>]*>/gi;
5954
+ var HTTP_EQUIV_REFRESH_PATTERN = /\bhttp-equiv\s*=\s*("\s*refresh\s*"|'\s*refresh\s*'|refresh\b)/i;
5955
+ var CONTENT_ATTR_PATTERN = /\bcontent\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/i;
5956
+ var CONTENT_VALUE_PATTERN = /^\s*(\d+(?:\.\d+)?)\s*[;,]\s*url\s*=\s*(?:"([^"]*)"|'([^']*)'|(.+?))\s*$/i;
5957
+ var resolveTarget = (raw, baseUrl) => {
5958
+ try {
5959
+ return baseUrl === void 0 ? new URL(raw) : new URL(raw, baseUrl);
5960
+ } catch {
5961
+ return void 0;
5962
+ }
5963
+ };
5964
+ var extractMetaRefresh = (html, baseUrl) => {
5965
+ for (const [tag] of html.matchAll(META_TAG_PATTERN)) {
5966
+ if (!HTTP_EQUIV_REFRESH_PATTERN.test(tag)) {
5967
+ continue;
5968
+ }
5969
+ const contentMatch = CONTENT_ATTR_PATTERN.exec(tag);
5970
+ const content = contentMatch?.[1] ?? contentMatch?.[2] ?? contentMatch?.[3];
5971
+ if (!content) {
5972
+ continue;
5973
+ }
5974
+ const value = CONTENT_VALUE_PATTERN.exec(content);
5975
+ if (!value) {
5976
+ continue;
5977
+ }
5978
+ const delaySeconds = Number.parseFloat(value[1] ?? "");
5979
+ const raw = (value[2] ?? value[3] ?? value[4] ?? "").trim();
5980
+ if (!raw || delaySeconds > MAX_META_REFRESH_DELAY_SECONDS) {
5981
+ continue;
5982
+ }
5983
+ const target = resolveTarget(raw, baseUrl);
5984
+ if (!target || target.protocol !== "http:" && target.protocol !== "https:") {
5985
+ continue;
5986
+ }
5987
+ if (baseUrl !== void 0 && resolveTarget(baseUrl, void 0)?.href === target.href) {
5988
+ continue;
5989
+ }
5990
+ return { url: target.href, delaySeconds };
5991
+ }
5992
+ return void 0;
5993
+ };
5994
+
3393
5995
  // src/cli/commands/webforai/loadHtml.ts
3394
- import fs5 from "node:fs/promises";
5996
+ import fs8 from "node:fs/promises";
3395
5997
  import { fileURLToPath } from "node:url";
3396
5998
  import boxen from "boxen";
3397
5999
  import pc from "picocolors";
@@ -3399,9 +6001,20 @@ import { chromium as chromium2 } from "playwright-core";
3399
6001
 
3400
6002
  // src/loaders/fetch.ts
3401
6003
  var USER_AGENT = "mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/125.0.0.0 safari/537.36";
6004
+ var MAX_META_REFRESH_HOPS = 3;
3402
6005
  var loadHtml = async (url, userAgent = USER_AGENT) => {
3403
- const response = await fetch(url, { headers: { "User-Agent": userAgent } });
3404
- return response.text();
6006
+ let current = url;
6007
+ let html = "";
6008
+ for (let hop = 0; hop <= MAX_META_REFRESH_HOPS; hop++) {
6009
+ const response = await fetch(current, { headers: { "User-Agent": userAgent } });
6010
+ html = await response.text();
6011
+ const refresh = extractMetaRefresh(html, response.url || current);
6012
+ if (!refresh) {
6013
+ break;
6014
+ }
6015
+ current = refresh.url;
6016
+ }
6017
+ return html;
3405
6018
  };
3406
6019
 
3407
6020
  // src/loaders/playwright.ts
@@ -3419,40 +6032,42 @@ var SUPER_BYPASS_DEVICE = {
3419
6032
  var loadHtml2 = async (url, options) => {
3420
6033
  const { browser, waitUntil, timeout, superBypassMode } = options ?? {};
3421
6034
  const _browser = browser ?? await chromium.launch({ headless: true });
3422
- const context = await _browser.newContext(superBypassMode ? SUPER_BYPASS_DEVICE : devices["Desktop Chrome"]);
3423
- if (superBypassMode) {
3424
- await context.addInitScript(() => {
3425
- Object.defineProperty(navigator, "webdriver", { get: () => void 0 });
3426
- Object.defineProperty(navigator, "languages", { get: () => ["en-US", "en"] });
3427
- Object.defineProperty(navigator, "plugins", { get: () => [1, 2, 3, 4, 5] });
3428
- });
3429
- }
3430
- const page = await context.newPage();
3431
- if (superBypassMode) {
3432
- await page.route("**/*.js", (route) => {
3433
- if (route.request().url().includes("captcha-delivery")) {
3434
- return route.abort();
6035
+ let context;
6036
+ try {
6037
+ context = await _browser.newContext(superBypassMode ? SUPER_BYPASS_DEVICE : devices["Desktop Chrome"]);
6038
+ if (superBypassMode) {
6039
+ await context.addInitScript(() => {
6040
+ Object.defineProperty(navigator, "webdriver", { get: () => void 0 });
6041
+ Object.defineProperty(navigator, "languages", { get: () => ["en-US", "en"] });
6042
+ Object.defineProperty(navigator, "plugins", { get: () => [1, 2, 3, 4, 5] });
6043
+ });
6044
+ }
6045
+ const page = await context.newPage();
6046
+ if (superBypassMode) {
6047
+ await page.route("**/*.js", (route) => {
6048
+ if (route.request().url().includes("captcha-delivery")) {
6049
+ return route.abort();
6050
+ }
6051
+ return route.continue();
6052
+ });
6053
+ }
6054
+ await page.goto(url, { waitUntil: waitUntil ?? "load", timeout });
6055
+ await page.evaluate(() => {
6056
+ const elements = document.querySelectorAll("*");
6057
+ for (const element3 of elements) {
6058
+ const rect = element3.getBoundingClientRect();
6059
+ element3.setAttribute("data-rwidth", rect.width.toString());
6060
+ element3.setAttribute("data-rheight", rect.height.toString());
3435
6061
  }
3436
- return route.continue();
3437
6062
  });
3438
- }
3439
- await page.goto(url, { waitUntil: waitUntil ?? "load", timeout });
3440
- await page.evaluate(() => {
3441
- const elements = document.querySelectorAll("*");
3442
- for (const element3 of elements) {
3443
- const rect = element3.getBoundingClientRect();
3444
- element3.setAttribute("data-rwidth", rect.width.toString());
3445
- element3.setAttribute("data-rheight", rect.height.toString());
6063
+ return await page.content();
6064
+ } finally {
6065
+ if (browser) {
6066
+ await context?.close();
6067
+ } else {
6068
+ await _browser.close();
3446
6069
  }
3447
- });
3448
- const html = await page.content();
3449
- await page.close();
3450
- if (browser) {
3451
- await context.close();
3452
- } else {
3453
- await _browser.close();
3454
6070
  }
3455
- return html;
3456
6071
  };
3457
6072
 
3458
6073
  // src/cli/commands/webforai/loadHtml.ts
@@ -3462,23 +6077,23 @@ var debugLog = (enabled, message) => {
3462
6077
  }
3463
6078
  };
3464
6079
  var checkPlaywrightAvailable = async () => {
3465
- const path4 = chromium2.executablePath();
6080
+ const path6 = chromium2.executablePath();
3466
6081
  try {
3467
- await fs5.access(path4);
6082
+ await fs8.access(path6);
3468
6083
  return true;
3469
6084
  } catch {
3470
6085
  return false;
3471
6086
  }
3472
6087
  };
3473
6088
  var getPlaywrightVersion = async () => {
3474
- const path4 = await import.meta.resolve("playwright-core/package.json");
3475
- const pwPackageJson = await fs5.readFile(fileURLToPath(path4), "utf-8").then((res) => JSON.parse(res.toString())).catch(() => null);
6089
+ const path6 = await import.meta.resolve("playwright-core/package.json");
6090
+ const pwPackageJson = await fs8.readFile(fileURLToPath(path6), "utf-8").then((res) => JSON.parse(res.toString())).catch(() => null);
3476
6091
  return pwPackageJson?.version;
3477
6092
  };
3478
6093
  var loadHtml3 = async (sourcePath, loader, options) => {
3479
6094
  if (loader === "local") {
3480
6095
  debugLog(options.debug, `Loading HTML from local file: ${sourcePath}`);
3481
- const content = await fs5.readFile(sourcePath, "utf-8");
6096
+ const content = await fs8.readFile(sourcePath, "utf-8");
3482
6097
  debugLog(options.debug, `HTML loaded: ${content.slice(0, 100)}`);
3483
6098
  return content;
3484
6099
  }
@@ -3532,6 +6147,8 @@ var extractorOptions = (name) => {
3532
6147
  switch (name) {
3533
6148
  case "takumi":
3534
6149
  return takumiExtractor;
6150
+ case "kiwame":
6151
+ return kiwameExtractor;
3535
6152
  case "minimal":
3536
6153
  return minimalFilter;
3537
6154
  case "none":
@@ -3545,12 +6162,14 @@ var convertViaPlatform = async (run) => {
3545
6162
  if (run.mode !== "default") {
3546
6163
  console.error("[webforai] --mode is applied by local conversion only and is ignored by the platform loader");
3547
6164
  }
3548
- debugLog2(run.debug, `platform scrape: ${run.source} (engine=${run.engine ?? "fetch"})`);
6165
+ debugLog2(run.debug, `platform scrape: ${run.source} (engine=${run.engine ?? "auto"})`);
3549
6166
  const result = await platform.scrape({
3550
6167
  url: run.source,
3551
6168
  engine: run.engine,
3552
6169
  region: run.region,
3553
6170
  screenshot: run.screenshot ? true : void 0,
6171
+ respectRobotsTxt: run.respectRobotsTxt ? true : void 0,
6172
+ // `kiwame` is rejected for the platform loader during option resolution.
3554
6173
  convert: { extractor: run.extractor, frontmatter: run.frontmatter }
3555
6174
  });
3556
6175
  return {
@@ -3562,7 +6181,8 @@ var convertViaPlatform = async (run) => {
3562
6181
  markdown: result.markdown,
3563
6182
  metadata: result.metadata,
3564
6183
  credits: result.credits,
3565
- screenshotUrl: result.screenshotUrl
6184
+ screenshotUrl: result.screenshotUrl,
6185
+ warning: result.warning
3566
6186
  };
3567
6187
  };
3568
6188
  var convertLocally = async (run) => {
@@ -3575,18 +6195,21 @@ var convertLocally = async (run) => {
3575
6195
  extractors: extractorOptions(run.extractor),
3576
6196
  ...run.mode === "ai" ? AI_MODE_OPTIONS : {}
3577
6197
  });
6198
+ const shell = run.loader === "fetch" ? detectClientShell(html) : void 0;
6199
+ const warning = shell?.isShell ? "This page looks like it renders client-side; the fetched HTML has no readable content. Try --engine auto (hosted platform, renders JavaScript) or --loader playwright." : void 0;
3578
6200
  return {
3579
6201
  source: run.source,
3580
6202
  loader: run.loader,
3581
6203
  url: sourceUrl,
3582
6204
  markdown,
3583
- metadata
6205
+ metadata,
6206
+ warning
3584
6207
  };
3585
6208
  };
3586
6209
  var executeRun = (run) => run.loader === "platform" ? convertViaPlatform(run) : convertLocally(run);
3587
6210
  var writeOutputFile = async (outputPath, markdown) => {
3588
- await fs6.mkdir(path3.dirname(path3.resolve(outputPath)), { recursive: true });
3589
- await fs6.writeFile(outputPath, markdown);
6211
+ await fs9.mkdir(path5.dirname(path5.resolve(outputPath)), { recursive: true });
6212
+ await fs9.writeFile(outputPath, markdown);
3590
6213
  };
3591
6214
  var runCommand = async (run) => {
3592
6215
  const envelope = await executeRun(run);
@@ -3604,6 +6227,9 @@ var runCommand = async (run) => {
3604
6227
  process.stdout.write(envelope.markdown.endsWith("\n") ? envelope.markdown : `${envelope.markdown}
3605
6228
  `);
3606
6229
  }
6230
+ if (envelope.warning) {
6231
+ console.error(`[webforai] warning: ${envelope.warning}`);
6232
+ }
3607
6233
  if (envelope.screenshotUrl) {
3608
6234
  console.error(`[webforai] screenshot (expires ~24h): ${envelope.screenshotUrl}`);
3609
6235
  }
@@ -3614,20 +6240,21 @@ var runCommand = async (run) => {
3614
6240
 
3615
6241
  // src/cli/commands/webforai/interactive.ts
3616
6242
  var ENGINE_HINTS = {
6243
+ auto: "Cheapest first, renders when the page needs JavaScript \xB7 1\u20132 credits",
3617
6244
  fetch: "Plain fetch \xB7 1 credit",
3618
- browser: "Browser rendering, screenshots \xB7 5 credits",
3619
- "proxy-fetch": "Rotating-proxy egress \xB7 2 credits",
3620
- "proxy-browser": "Browser rendering behind the proxy \xB7 5 credits"
6245
+ browser: "Browser rendering, screenshots \xB7 2 credits",
6246
+ "proxy-fetch": "Rotating-proxy egress \xB7 2 credits \xB7 paid plan",
6247
+ "proxy-browser": "Browser rendering behind the proxy \xB7 3 credits \xB7 paid plan"
3621
6248
  };
3622
6249
  var promptPlatformOptions = async (flags, env) => {
3623
6250
  const engine = flags.engine ?? await select7({
3624
6251
  message: "Select platform engine:",
3625
- initialValue: "fetch",
3626
- options: ENGINES.map((value) => ({ value, label: value, hint: ENGINE_HINTS[value] }))
6252
+ initialValue: "auto",
6253
+ options: REQUESTED_ENGINES.map((value) => ({ value, label: value, hint: ENGINE_HINTS[value] }))
3627
6254
  });
3628
6255
  assertContinue(engine);
3629
6256
  const region = flags.region ?? await select7({
3630
- message: "Select egress region (proxy engines only):",
6257
+ message: "Select egress region (proxy engines only; jp needs a paid plan):",
3631
6258
  initialValue: "auto",
3632
6259
  options: REGIONS.map((value) => ({ value, label: value }))
3633
6260
  });
@@ -3647,26 +6274,18 @@ var promptPlatformOptions = async (flags, env) => {
3647
6274
  var interactiveCommand = async (initialSource, flags, env = process.env) => {
3648
6275
  intro(pc2.bold(pc2.green(`webforai CLI version ${package_default.version}`)));
3649
6276
  const source = initialSource ?? await inputSourcePath();
3650
- const loader = isUrl(source) ? flags.loader ?? await selectLoader() : "local";
3651
- const run = {
3652
- source,
3653
- loader,
3654
- mode: "default",
3655
- extractor: flags.extractor ?? "auto",
3656
- frontmatter: flags.frontmatter ?? false,
3657
- json: false,
3658
- debug: flags.debug ?? false,
3659
- screenshot: flags.screenshot ?? false
6277
+ const loader = isUrl(source) ? flags.loader ?? (flags.engine !== void 0 || flags.region !== void 0 ? "platform" : await selectLoader()) : "local";
6278
+ const selectedFlags = {
6279
+ ...flags,
6280
+ loader: loader === "local" ? flags.loader : loader
3660
6281
  };
3661
6282
  if (loader === "platform") {
3662
6283
  const platform = await promptPlatformOptions(flags, env);
3663
- run.engine = platform.engine;
3664
- run.region = platform.region;
3665
- run.apiKey = platform.apiKey;
3666
- run.platformUrl = flags.platformUrl;
6284
+ Object.assign(selectedFlags, platform);
3667
6285
  } else {
3668
- run.mode = flags.mode ?? await selectExtractMode();
6286
+ selectedFlags.mode = flags.mode ?? await selectExtractMode();
3669
6287
  }
6288
+ const run = resolveRunOptions(source, selectedFlags, env);
3670
6289
  const outputPath = flags.output ?? await inputOutputPath(source);
3671
6290
  const s = spinner();
3672
6291
  s.start(loader === "platform" ? "Converting via the platform..." : "Loading and converting...");
@@ -3689,73 +6308,6 @@ var interactiveCommand = async (initialSource, flags, env = process.env) => {
3689
6308
  outro(pc2.green(`${pc2.bold("Done!")} Markdown saved to ${outputPath}`));
3690
6309
  };
3691
6310
 
3692
- // src/cli/commands/webforai/options.ts
3693
- import fs7 from "node:fs";
3694
- var UsageError = class extends Error {
3695
- };
3696
- var oneOf = (name, value, allowed) => {
3697
- if (!allowed.includes(value)) {
3698
- throw new UsageError(`invalid --${name} "${value}" (expected: ${allowed.join(" | ")})`);
3699
- }
3700
- return value;
3701
- };
3702
- var impliesPlatform = (flags) => flags.engine !== void 0 || flags.region !== void 0;
3703
- var resolveLoader = (sourceIsUrl, flags) => {
3704
- if (flags.loader) {
3705
- return oneOf("loader", flags.loader, LOADERS);
3706
- }
3707
- if (impliesPlatform(flags)) {
3708
- return "platform";
3709
- }
3710
- return sourceIsUrl ? "fetch" : "local";
3711
- };
3712
- var assertUsableLocalSource = (source, loader, flags) => {
3713
- if (loader !== "local" && flags.loader) {
3714
- throw new UsageError(`--loader ${loader} needs a URL source, but "${source}" is a local path`);
3715
- }
3716
- if (impliesPlatform(flags)) {
3717
- throw new UsageError("--engine/--region need a URL source (the platform cannot read local files)");
3718
- }
3719
- if (!fs7.existsSync(source)) {
3720
- throw new UsageError(`source not found: "${source}" (URLs must start with http:// or https://)`);
3721
- }
3722
- };
3723
- var applyPlatformFields = (resolved, flags, env) => {
3724
- resolved.engine = flags.engine ? oneOf("engine", flags.engine, ENGINES) : void 0;
3725
- resolved.region = flags.region ? oneOf("region", flags.region, REGIONS) : void 0;
3726
- resolved.apiKey = flags.apiKey ?? env[API_KEY_ENV];
3727
- resolved.platformUrl = flags.platformUrl ?? env[PLATFORM_URL_ENV];
3728
- if (!resolved.apiKey) {
3729
- throw new UsageError(
3730
- `the platform loader needs an API key: pass --api-key or set ${API_KEY_ENV} (create one at https://platform.webforai.dev/dashboard)`
3731
- );
3732
- }
3733
- };
3734
- var resolveRunOptions = (source, flags, env = process.env) => {
3735
- const sourceIsUrl = isUrl(source);
3736
- const loader = resolveLoader(sourceIsUrl, flags);
3737
- if (!sourceIsUrl) {
3738
- assertUsableLocalSource(source, loader, flags);
3739
- }
3740
- const resolved = {
3741
- source,
3742
- loader: sourceIsUrl ? loader : "local",
3743
- mode: flags.mode ? oneOf("mode", flags.mode, MODES) : "default",
3744
- extractor: flags.extractor ? oneOf("extractor", flags.extractor, EXTRACTORS) : "auto",
3745
- frontmatter: flags.frontmatter ?? false,
3746
- output: flags.output,
3747
- json: flags.json ?? false,
3748
- debug: flags.debug ?? false,
3749
- screenshot: flags.screenshot ?? false
3750
- };
3751
- if (resolved.loader === "platform") {
3752
- applyPlatformFields(resolved, flags, env);
3753
- } else if (flags.screenshot) {
3754
- throw new UsageError("--screenshot is only available with the platform loader (browser engines)");
3755
- }
3756
- return resolved;
3757
- };
3758
-
3759
6311
  // src/cli/bin.ts
3760
6312
  var HELP_EPILOGUE = `
3761
6313
  Examples:
@@ -3764,7 +6316,9 @@ Examples:
3764
6316
  $ webforai ./page.html --extractor none convert a local file, no extraction
3765
6317
  $ webforai https://example.com --json | jq .markdown
3766
6318
  $ webforai https://spa.example.com -l playwright render JS in local Chromium
3767
- $ webforai https://example.com --engine browser render via the hosted platform
6319
+ $ webforai https://example.com --engine auto hosted platform, renders JS when needed
6320
+ $ webforai crawl https://docs.example.com -o docs --llms-txt crawl a site (platform) + llms.txt
6321
+ $ webforai batch --file urls.txt -o pages many URLs, one .md per page (platform)
3768
6322
  $ webforai -i guided interactive mode
3769
6323
  $ webforai skill --install install the Agent Skill for this CLI
3770
6324
 
@@ -3777,9 +6331,23 @@ Exit codes:
3777
6331
 
3778
6332
  Output contract:
3779
6333
  stdout carries only the Markdown (or the --json envelope); all logs go to stderr.
6334
+
6335
+ Docs:
6336
+ https://webforai.dev/cli this CLI
6337
+ https://webforai.dev/platform the hosted platform (--engine / --region)
6338
+ ${DEFAULT_BASE_URL}/dashboard API keys, usage and billing
3780
6339
  `;
3781
- program.name("webforai").description("Convert web pages and local HTML to clean, LLM-ready Markdown.").version(package_default.version, "-v, --version", "output the current version").addHelpText("after", HELP_EPILOGUE).showSuggestionAfterError();
3782
- program.argument("[source]", "URL or local HTML file to convert").option("-o, --output <path>", "write Markdown to a file instead of stdout").option("-l, --loader <loader>", `how HTML is acquired (${LOADERS.join(" | ")}; local files are automatic)`).option("-m, --mode <mode>", `conversion mode (${MODES.join(" | ")}); ai strips links/tables/images`).option("--extractor <extractor>", `main-content extraction preset (${EXTRACTORS.join(" | ")})`, void 0).option("--frontmatter", "prepend YAML front matter built from the page metadata").option("--json", "print a JSON envelope {source, loader, url, markdown, metadata, ...} to stdout").option("--engine <engine>", "platform engine (fetch | browser | proxy-fetch | proxy-browser); implies -l platform").option("--region <region>", "platform proxy egress region (auto | us | eu | uk | jp | asia); implies -l platform").option("--screenshot", "platform browser engines: also capture a screenshot (expiring URL)").option("--api-key <key>", `platform API key (defaults to $${API_KEY_ENV})`).option("--platform-url <url>", `platform base URL (defaults to $${PLATFORM_URL_ENV} or the hosted instance)`).option("-i, --interactive", "guided prompt flow (the pre-v3 default)").option("-d, --debug", "verbose logs on stderr").action(async (source, flags) => {
6340
+ var DASHBOARD_ERRORS = /* @__PURE__ */ new Set(["invalid_api_key", "payment_required", "spend_cap_reached"]);
6341
+ var activePlatformUrl;
6342
+ var rememberPlatformUrl = (flags) => {
6343
+ activePlatformUrl = flags.platformUrl ?? process.env[PLATFORM_URL_ENV];
6344
+ };
6345
+ program.name("webforai").enablePositionalOptions().exitOverride().description("Convert web pages and local HTML to clean, LLM-ready Markdown.").version(package_default.version, "-v, --version", "output the current version").addHelpText("after", HELP_EPILOGUE).showSuggestionAfterError();
6346
+ program.argument("[source]", "URL or local HTML file to convert").option("-o, --output <path>", "write Markdown to a file instead of stdout").option("-l, --loader <loader>", `how HTML is acquired (${LOADERS.join(" | ")}; local files are automatic)`).option("-m, --mode <mode>", `conversion mode (${MODES.join(" | ")}); ai strips links/tables/images`).option("--extractor <extractor>", `main-content extraction preset (${EXTRACTORS.join(" | ")})`, void 0).option("--frontmatter", "prepend YAML front matter built from the page metadata").option("--json", "print a JSON envelope {source, loader, url, markdown, metadata, ...} to stdout").option(
6347
+ "--engine <engine>",
6348
+ "platform engine (auto | fetch | browser | proxy-fetch | proxy-browser; proxy-* need a paid plan); implies -l platform"
6349
+ ).option("--region <region>", "platform proxy egress region (auto | jp; jp needs a paid plan); implies -l platform").option("--screenshot", "platform browser engines: also capture a screenshot (expiring URL)").option("--respect-robots", "platform loader: honor the target site's robots.txt rules (off by default)").option("--api-key <key>", `platform API key (defaults to $${API_KEY_ENV})`).option("--platform-url <url>", `platform base URL (defaults to $${PLATFORM_URL_ENV} or the hosted instance)`).option("-i, --interactive", "guided prompt flow (the pre-v3 default)").option("-d, --debug", "verbose logs on stderr").action(async (source, flags) => {
6350
+ rememberPlatformUrl(flags);
3783
6351
  if (flags.interactive) {
3784
6352
  await interactiveCommand(source, flags);
3785
6353
  return;
@@ -3789,6 +6357,46 @@ program.argument("[source]", "URL or local HTML file to convert").option("-o, --
3789
6357
  }
3790
6358
  await runCommand(resolveRunOptions(source, flags));
3791
6359
  });
6360
+ var collect = (value, previous = []) => [...previous, value];
6361
+ var addPlatformJobOptions = (command) => command.requiredOption("-o, --output <dir>", "directory for the Markdown files (one per page; created if missing)").option(
6362
+ "--engine <engine>",
6363
+ "platform engine (auto | fetch | browser | proxy-fetch | proxy-browser; proxy-* need a paid plan)"
6364
+ ).option("--region <region>", "proxy egress region (auto | jp); jp runs on the paid proxy tier").option("--extractor <extractor>", `main-content extraction preset (${EXTRACTORS.join(" | ")})`).option("--frontmatter", "prepend YAML front matter built from each page's metadata").option("--json", "print a JSON envelope {jobId, pages[], failures[], ...} to stdout instead of file paths").option("--timeout <seconds>", "stop waiting after this long (the job keeps running); default 1800").option("--api-key <key>", `platform API key (defaults to $${API_KEY_ENV})`).option("--platform-url <url>", `platform base URL (defaults to $${PLATFORM_URL_ENV} or the hosted instance)`).option("-d, --debug", "verbose logs on stderr");
6365
+ var JOB_OUTPUT_HELP = `
6366
+ Output:
6367
+ One .md per converted page under --output, mirroring URL paths (/docs/intro \u2192 docs/intro.md).
6368
+ stdout lists the written files (or the --json envelope); progress and the summary go to stderr.
6369
+ Exit 1 when the job failed or converted no pages; failed pages are listed and never billed.
6370
+ `;
6371
+ addPlatformJobOptions(
6372
+ program.command("crawl").description("crawl a site on the hosted platform and write one Markdown file per page").argument("<url>", "seed URL; only same-origin links are followed")
6373
+ ).option("--max-depth <n>", "link depth from the seed (0-5, default 2)").option("--limit <n>", "maximum pages (1-500, default 50)").option("--include <regex>", "only crawl pathnames matching this regex (repeatable)", collect).option("--exclude <regex>", "skip pathnames matching this regex (repeatable)", collect).option(
6374
+ "--sitemap <mode>",
6375
+ "use the site's sitemaps: skip (default) | include (add their URLs) | only (no link following)"
6376
+ ).option("--respect-robots", "honor robots.txt (the default for crawls)").option("--no-respect-robots", "do not read robots.txt").option("--llms-txt", "also write llms.txt (page index) and llms-full.txt (all pages) per llmstxt.org").addHelpText(
6377
+ "after",
6378
+ `${JOB_OUTPUT_HELP}
6379
+ Examples:
6380
+ $ webforai crawl https://docs.example.com -o docs --limit 100 --include '^/docs' --llms-txt
6381
+ $ webforai crawl https://blog.example.com -o blog --sitemap only --limit 500
6382
+ `
6383
+ ).action(async (url, flags) => {
6384
+ rememberPlatformUrl(flags);
6385
+ await runJobCommand(resolveJobOptions("crawl", [url], flags));
6386
+ });
6387
+ addPlatformJobOptions(
6388
+ program.command("batch").description("convert many URLs on the hosted platform, one Markdown file per page").argument("[urls...]", "URLs to convert (up to 100 per job)")
6389
+ ).option("-f, --file <path>", "read URLs from a file, one per line ('-' for stdin; # comments allowed)").option("--respect-robots", "honor each site's robots.txt (off by default for batches)").addHelpText(
6390
+ "after",
6391
+ `${JOB_OUTPUT_HELP}
6392
+ Examples:
6393
+ $ webforai batch https://a.example/post https://b.example/news -o pages
6394
+ $ cat urls.txt | webforai batch --file - -o pages --json
6395
+ `
6396
+ ).action(async (urls, flags) => {
6397
+ rememberPlatformUrl(flags);
6398
+ await runJobCommand(resolveJobOptions("batch", urls, flags));
6399
+ });
3792
6400
  program.command("skill").description("print the Agent Skill (SKILL.md) for this CLI, or install it via the skills CLI").option("--install", "install through `npx skills add` (interactive agent picker; flags below forward to it)").option("-g, --global", "forward to skills add: install user-level instead of project-level").option("-a, --agent <agents>", "forward to skills add: agents to install to ('*' for all)").option("-y, --yes", "forward to skills add: skip confirmation prompts").option("--copy", "forward to skills add: copy files instead of symlinking").option("--all", "forward to skills add: all skills, all agents, no prompts").option("--dir <path>", "offline fallback: write <path>/webforai/SKILL.md directly, without the skills CLI").addHelpText("after", "\nAlso installable straight from the repository: npx skills add inaridiy/webforai\n").action(async (flags) => {
3793
6401
  await skillCommand(flags);
3794
6402
  });
@@ -3800,8 +6408,19 @@ var fail = (error) => {
3800
6408
  console.error(`error: ${error.message}`);
3801
6409
  process.exit(2);
3802
6410
  }
6411
+ if (error instanceof PlatformApiError) {
6412
+ const retry = error.retryAfter === void 0 ? "" : ` (retryAfter: ${error.retryAfter}s)`;
6413
+ console.error(`error: ${error.code}: ${error.message}${retry}`);
6414
+ if (DASHBOARD_ERRORS.has(error.code) && !error.message.includes("/dashboard")) {
6415
+ console.error(`hint: manage API keys and credits at ${platformDashboardUrl(activePlatformUrl)}`);
6416
+ }
6417
+ process.exit(1);
6418
+ }
6419
+ if (error instanceof JobIncompleteError) {
6420
+ console.error(`error: ${error.message}`);
6421
+ process.exit(1);
6422
+ }
3803
6423
  console.error(error instanceof Error ? `error: ${error.message}` : `error: ${String(error)}`);
3804
6424
  process.exit(1);
3805
6425
  };
3806
- program.exitOverride();
3807
6426
  program.parseAsync().catch(fail);