@pixerate/editor 0.28.0 → 0.29.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 (80) hide show
  1. package/README.md +20 -1
  2. package/dist/HistoryManager-DWSLd6Tf.d.ts +150 -0
  3. package/dist/HistoryManager-DeQQMBCj.d.cts +150 -0
  4. package/dist/agent/index.cjs +20 -427
  5. package/dist/agent/index.cjs.map +1 -1
  6. package/dist/agent/index.d.cts +4 -342
  7. package/dist/agent/index.d.ts +4 -342
  8. package/dist/agent/index.js +14 -421
  9. package/dist/agent/index.js.map +1 -1
  10. package/dist/animation/index.d.cts +3 -73
  11. package/dist/animation/index.d.ts +3 -73
  12. package/dist/{builtins-nMXh9sT3.d.cts → builtins-DxC3aUR2.d.cts} +2 -2
  13. package/dist/{builtins-haN82vjT.d.ts → builtins-NGxNxQfJ.d.ts} +2 -2
  14. package/dist/canvas/index.d.cts +5 -3
  15. package/dist/canvas/index.d.ts +5 -3
  16. package/dist/chunk-36BLROHV.js +438 -0
  17. package/dist/chunk-36BLROHV.js.map +1 -0
  18. package/dist/{chunk-OYEFRO3D.cjs → chunk-6MDQKHRH.cjs} +4 -4
  19. package/dist/{chunk-OYEFRO3D.cjs.map → chunk-6MDQKHRH.cjs.map} +1 -1
  20. package/dist/{chunk-ARRTP33I.js → chunk-D6S5M7HV.js} +2 -2
  21. package/dist/{chunk-ARRTP33I.js.map → chunk-D6S5M7HV.js.map} +1 -1
  22. package/dist/{chunk-MXZJ4PKN.js → chunk-DDADOHJW.js} +8 -8
  23. package/dist/{chunk-CPOKFNBG.cjs → chunk-I6BZB5ZH.cjs} +2 -2
  24. package/dist/{chunk-CPOKFNBG.cjs.map → chunk-I6BZB5ZH.cjs.map} +1 -1
  25. package/dist/chunk-PIIAZV3L.cjs +244 -0
  26. package/dist/chunk-PIIAZV3L.cjs.map +1 -0
  27. package/dist/{chunk-G2I4QJOT.cjs → chunk-QKLRAA4T.cjs} +3 -244
  28. package/dist/chunk-QKLRAA4T.cjs.map +1 -0
  29. package/dist/{chunk-2H7ZHPEJ.js → chunk-QVZZGT4X.js} +1 -242
  30. package/dist/chunk-QVZZGT4X.js.map +1 -0
  31. package/dist/chunk-V7CC7RZ6.cjs +438 -0
  32. package/dist/chunk-V7CC7RZ6.cjs.map +1 -0
  33. package/dist/chunk-YK57D7PW.js +244 -0
  34. package/dist/chunk-YK57D7PW.js.map +1 -0
  35. package/dist/commands/index.cjs +2 -2
  36. package/dist/commands/index.cjs.map +1 -1
  37. package/dist/commands/index.d.cts +2 -2
  38. package/dist/commands/index.d.ts +2 -2
  39. package/dist/commands/index.js +1 -1
  40. package/dist/commands/index.js.map +1 -1
  41. package/dist/easing-B6iAnJHk.d.cts +74 -0
  42. package/dist/easing-B6iAnJHk.d.ts +74 -0
  43. package/dist/extensions/index.cjs +5 -5
  44. package/dist/extensions/index.cjs.map +1 -1
  45. package/dist/extensions/index.js +9 -9
  46. package/dist/generation/index.cjs +2 -2
  47. package/dist/generation/index.cjs.map +1 -1
  48. package/dist/generation/index.js +1 -1
  49. package/dist/generation/index.js.map +1 -1
  50. package/dist/history/index.cjs +4 -2
  51. package/dist/history/index.cjs.map +1 -1
  52. package/dist/history/index.d.cts +3 -149
  53. package/dist/history/index.d.ts +3 -149
  54. package/dist/history/index.js +5 -3
  55. package/dist/image-editor/index.cjs.map +1 -1
  56. package/dist/image-editor/index.js.map +1 -1
  57. package/dist/index.cjs +15 -13
  58. package/dist/index.cjs.map +1 -1
  59. package/dist/index.d.cts +3 -2
  60. package/dist/index.d.ts +3 -2
  61. package/dist/index.js +22 -20
  62. package/dist/index.js.map +1 -1
  63. package/dist/parameters/index.cjs +1283 -0
  64. package/dist/parameters/index.cjs.map +1 -0
  65. package/dist/parameters/index.d.cts +595 -0
  66. package/dist/parameters/index.d.ts +595 -0
  67. package/dist/parameters/index.js +1283 -0
  68. package/dist/parameters/index.js.map +1 -0
  69. package/dist/tools/index.cjs +31 -0
  70. package/dist/tools/index.cjs.map +1 -0
  71. package/dist/tools/index.d.cts +343 -0
  72. package/dist/tools/index.d.ts +343 -0
  73. package/dist/tools/index.js +31 -0
  74. package/dist/tools/index.js.map +1 -0
  75. package/dist/{types-GT5a5YAX.d.cts → types-DsiXGmjo.d.cts} +1 -1
  76. package/dist/{types-GT5a5YAX.d.ts → types-DsiXGmjo.d.ts} +1 -1
  77. package/package.json +11 -1
  78. package/dist/chunk-2H7ZHPEJ.js.map +0 -1
  79. package/dist/chunk-G2I4QJOT.cjs.map +0 -1
  80. /package/dist/{chunk-MXZJ4PKN.js.map → chunk-DDADOHJW.js.map} +0 -0
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/controller.ts","../src/import/controller.ts","../src/import/pdf-layout.ts","../src/import/pdf.ts","../src/import/zip-export.ts"],"sourcesContent":["import { Editor, EditorOptions, Content, Extensions } from \"@tiptap/core\";\nimport { Slice } from \"@tiptap/pm/model\";\nimport { Token, tokenizePrompt } from \"./grammar\";\nimport {\n plainTextToTipTapHtml,\n plainTextToSlice,\n getEditorText,\n markdownToTipTapHtml,\n getEditorMarkdown,\n} from \"./serializers\";\n\nexport interface EditorControllerOptions extends Partial<\n Omit<EditorOptions, \"element\" | \"content\">\n> {\n element?: Element | HTMLElement | null;\n content?: string | Content;\n plainTextMode?: boolean;\n markdownMode?: boolean;\n extensions?: Extensions;\n onPlainTextChange?: (text: string) => void;\n onMarkdownChange?: (markdown: string) => void;\n onTokensChange?: (tokens: Token[]) => void;\n onSelectionChange?: (range: { from: number; to: number } | null) => void;\n}\n\n/**\n * UI-agnostic controller managing the lifecycle, commands, and plain-text/token\n * synchronization of a rich text or prompt editor.\n */\nexport class EditorController {\n public readonly editor: Editor;\n private readonly plainTextMode: boolean;\n private readonly markdownMode: boolean;\n private readonly onPlainTextChange?: (text: string) => void;\n private readonly onMarkdownChange?: (markdown: string) => void;\n private readonly onTokensChange?: (tokens: Token[]) => void;\n private readonly onSelectionChange?: (\n range: { from: number; to: number } | null,\n ) => void;\n private baselineContent: string;\n\n constructor(options: EditorControllerOptions = {}) {\n const {\n element,\n content,\n plainTextMode = false,\n markdownMode = false,\n extensions = [],\n onPlainTextChange,\n onMarkdownChange,\n onTokensChange,\n onSelectionChange,\n ...editorOptions\n } = options;\n\n this.plainTextMode = plainTextMode;\n this.markdownMode = markdownMode;\n this.onPlainTextChange = onPlainTextChange;\n this.onMarkdownChange = onMarkdownChange;\n this.onTokensChange = onTokensChange;\n this.onSelectionChange = onSelectionChange;\n\n const initialContent =\n plainTextMode && typeof content === \"string\"\n ? plainTextToTipTapHtml(content)\n : markdownMode && typeof content === \"string\"\n ? markdownToTipTapHtml(content)\n : content;\n\n this.editor = new Editor({\n element: element || undefined,\n content: initialContent,\n extensions,\n ...editorOptions,\n onUpdate: (props) => {\n editorOptions.onUpdate?.(props);\n this.handleUpdate();\n },\n onSelectionUpdate: (props) => {\n editorOptions.onSelectionUpdate?.(props);\n this.handleSelectionUpdate();\n },\n });\n\n if (plainTextMode) {\n this.enforcePlainTextClipboard();\n }\n\n this.baselineContent = this.getCurrentContentString();\n }\n\n private enforcePlainTextClipboard() {\n // Opt-in rich clipboard / file import must not bypass the plain-text invariant.\n const richClipboard = this.editor.storage?.richClipboard;\n if (richClipboard) richClipboard.plainTextMode = true;\n const fileImport = this.editor.extensionManager?.extensions.find(\n (ext) => ext.name === \"fileImport\",\n );\n if (fileImport) fileImport.options.asPlainText = true;\n\n this.editor.setOptions({\n editorProps: {\n ...this.editor.options.editorProps,\n clipboardTextParser: (\n text: string,\n context: any,\n _plain: boolean,\n view?: any,\n ) => {\n const schema =\n context?.doc?.type?.schema ||\n context?.schema ||\n view?.state?.schema ||\n this.editor.schema;\n\n if (!schema) return Slice.empty;\n\n return plainTextToSlice(text, schema);\n },\n },\n });\n }\n\n private handleUpdate() {\n if (this.plainTextMode || this.onPlainTextChange || this.onTokensChange) {\n const text = this.getPlainText();\n this.onPlainTextChange?.(text);\n\n if (this.onTokensChange) {\n const tokens = tokenizePrompt(text);\n this.onTokensChange(tokens);\n }\n }\n\n if (this.markdownMode || this.onMarkdownChange) {\n const markdown = this.getMarkdown();\n this.onMarkdownChange?.(markdown);\n }\n }\n\n private handleSelectionUpdate() {\n if (this.onSelectionChange) {\n const { from, to } = this.editor.state.selection;\n this.onSelectionChange({ from, to });\n }\n }\n\n public getPlainText(): string {\n return getEditorText(this.editor);\n }\n\n public setPlainText(text: string, emitUpdate = true) {\n const html = plainTextToTipTapHtml(text);\n this.editor.commands.setContent(html, emitUpdate);\n }\n\n public getMarkdown(): string {\n return getEditorMarkdown(this.editor);\n }\n\n public setMarkdown(markdown: string, emitUpdate = true) {\n if (this.editor.storage?.markdown?.parser) {\n this.editor.commands.setContent(markdown, emitUpdate);\n } else {\n const html = markdownToTipTapHtml(markdown);\n this.editor.commands.setContent(html, emitUpdate);\n }\n }\n\n /**\n * Replaces `from`..`to` with literal text: HTML in `text` is not parsed, and\n * newlines split paragraphs.\n */\n private insertPlainText(from: number, to: number, text: string) {\n const { state, view } = this.editor;\n const tr = text.includes(\"\\n\") || text.includes(\"\\r\")\n ? state.tr.replace(from, to, plainTextToSlice(text, state.schema))\n : text\n ? state.tr.insertText(text, from, to)\n : state.tr.delete(from, to);\n view.dispatch(tr.scrollIntoView());\n }\n\n /** Inserts text literally at the selection; HTML in `text` is not parsed. */\n public insertText(text: string) {\n const { from, to } = this.editor.state.selection;\n this.insertPlainText(from, to, text);\n }\n\n /** Inserts text literally at `pos`; HTML in `text` is not parsed. */\n public insertTextAt(pos: number, text: string) {\n this.insertPlainText(pos, pos, text);\n this.editor.commands.focus();\n }\n\n /** Replaces a range with literal text; HTML in `text` is not parsed. */\n public replaceRange(from: number, to: number, text: string) {\n this.insertPlainText(from, to, text);\n this.editor.commands.focus();\n }\n\n public getCurrentContentString(): string {\n if (this.plainTextMode) return this.getPlainText();\n if (this.markdownMode) return this.getMarkdown();\n return this.editor.getHTML();\n }\n\n public isDirty(): boolean {\n return this.getCurrentContentString() !== this.baselineContent;\n }\n\n public setCheckpoint(content?: string): void {\n this.baselineContent =\n content !== undefined ? content : this.getCurrentContentString();\n }\n\n public resetDirty(): void {\n this.setCheckpoint();\n }\n\n public getBaselineContent(): string {\n return this.baselineContent;\n }\n\n public destroy() {\n this.editor.destroy();\n }\n}\n\n/**\n * Creates and initializes an EditorController instance.\n */\nexport function createEditor(\n options: EditorControllerOptions = {},\n): EditorController {\n return new EditorController(options);\n}\n","import { defaultImportRegistry, type DocumentImport } from \"./adapters\";\nimport {\n importFilesIntoEditor,\n type ImportEditorTarget,\n type ImportFilesIntoEditorOptions,\n} from \"./editor\";\nimport type { FileLike, ImportOutcome } from \"./registry\";\nimport type { ImportStructureReport } from \"./pdf-layout\";\n\n/**\n * Opens the browser file picker and resolves with the chosen files (an empty\n * array when the dialog is cancelled). `accept` defaults to every extension\n * and MIME type the default registry can import as a document.\n */\nexport function pickImportFiles(options: { accept?: string; multiple?: boolean } = {}): Promise<File[]> {\n if (typeof document === \"undefined\") return Promise.resolve([]);\n return new Promise((resolve) => {\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = options.accept ?? defaultImportRegistry.accept(\"document\");\n input.multiple = options.multiple ?? true;\n input.style.display = \"none\";\n const finish = (files: File[]) => {\n input.remove();\n resolve(files);\n };\n input.addEventListener(\"change\", () => finish(Array.from(input.files ?? [])), { once: true });\n input.addEventListener(\"cancel\", () => finish([]), { once: true });\n document.body.appendChild(input);\n input.click();\n });\n}\n\nexport interface FileImportState {\n isImporting: boolean;\n /** Last import error (cleared when a new import starts). */\n error: Error | null;\n /** Outcomes of the most recent import. */\n lastOutcomes: ImportOutcome<DocumentImport>[];\n}\n\nexport interface FileImportControllerOptions extends Omit<ImportFilesIntoEditorOptions, \"at\"> {\n /** Allow choosing several files in the picker (default `true`). */\n multiple?: boolean;\n}\n\n/**\n * Framework-agnostic state for a file-import button: tracks `isImporting` /\n * `error`, opens the file picker and inserts the imported content into the\n * editor returned by `getTarget`. React's `useFileImport` and Svelte's\n * `createFileImport` wrap it.\n */\nexport class FileImportController {\n private state: FileImportState = { isImporting: false, error: null, lastOutcomes: [] };\n private readonly listeners = new Set<(state: FileImportState) => void>();\n private pending = 0;\n\n constructor(\n private readonly getTarget: () => ImportEditorTarget | null | undefined,\n private options: FileImportControllerOptions = {},\n ) {}\n\n setOptions(options: FileImportControllerOptions): void {\n this.options = options;\n }\n\n /** `accept` attribute value for document imports. */\n get accept(): string {\n return (this.options.registry ?? defaultImportRegistry).accept(\"document\");\n }\n\n getState = (): FileImportState => this.state;\n\n subscribe = (listener: (state: FileImportState) => void): (() => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n private setState(patch: Partial<FileImportState>) {\n this.state = { ...this.state, ...patch };\n this.listeners.forEach((listener) => listener(this.state));\n }\n\n /** Imports files into the editor at `at` (default: the selection). */\n importFiles = async (\n files: Iterable<FileLike> | ArrayLike<FileLike>,\n at?: number,\n ): Promise<ImportOutcome<DocumentImport>[]> => {\n const target = this.getTarget();\n const list = Array.from(files as ArrayLike<FileLike>);\n if (!target || list.length === 0) return [];\n this.pending++;\n this.setState({ isImporting: true, error: null });\n let error: Error | null = null;\n try {\n const outcomes = await importFilesIntoEditor(target, list, {\n ...this.options,\n at,\n onError: (err, file) => {\n error = err;\n this.options.onError?.(err, file);\n },\n });\n this.pending--;\n this.setState({ isImporting: this.pending > 0, error, lastOutcomes: outcomes });\n return outcomes;\n } catch (err) {\n this.pending--;\n this.setState({ isImporting: this.pending > 0, error: err instanceof Error ? err : new Error(String(err)) });\n return [];\n }\n };\n\n /** Opens the file picker and imports the chosen files at the selection. */\n openFilePicker = async (): Promise<ImportOutcome<DocumentImport>[]> => {\n const files = await pickImportFiles({ accept: this.accept, multiple: this.options.multiple });\n return this.importFiles(files);\n };\n}\n\nexport function createFileImportController(\n getTarget: () => ImportEditorTarget | null | undefined,\n options?: FileImportControllerOptions,\n): FileImportController {\n return new FileImportController(getTarget, options);\n}\n\n/** Totals of the structure reports (`DocumentImport.structure`) of several imports. */\nexport interface ImportStructureSummary {\n /** Imports that carried a report. */\n files: number;\n /** `\"mixed\"` when some files were imported with structure detection and some without. */\n mode: \"structured\" | \"plain\" | \"mixed\";\n headings: number;\n lists: number;\n tables: number;\n paragraphs: number;\n multiColumnPages: number;\n /** Mean of the reports' confidences (0–1). */\n confidence: number;\n}\n\n/**\n * Sums the structure reports of import outcomes, e.g. `lastOutcomes` from a\n * file-import controller. Returns `null` when no outcome has a report (only\n * structure-aware adapters such as PDF produce one).\n */\nexport function summarizeImportStructure(\n outcomes: readonly ImportOutcome<DocumentImport>[],\n): ImportStructureSummary | null {\n const reports = outcomes\n .map((outcome) => outcome.result?.structure)\n .filter((report): report is ImportStructureReport => !!report);\n if (!reports.length) return null;\n const modes = new Set(reports.map((report) => report.mode));\n const sum = (pick: (report: ImportStructureReport) => number) =>\n reports.reduce((total, report) => total + pick(report), 0);\n return {\n files: reports.length,\n mode: modes.size > 1 ? \"mixed\" : reports[0].mode,\n headings: sum((r) => r.counts.headings),\n lists: sum((r) => r.counts.lists),\n tables: sum((r) => r.counts.tables),\n paragraphs: sum((r) => r.counts.paragraphs),\n multiColumnPages: sum((r) => r.multiColumnPages),\n confidence: Math.round((sum((r) => r.confidence) / reports.length) * 100) / 100,\n };\n}\n","/**\n * Layout analysis for PDF import: turns positioned text runs into headings,\n * paragraphs, lists and tables in reading order.\n *\n * Portions ported from pdfcraft/crates/export/src/lib.rs (`body_size`, `level`,\n * `tables`: body size by character count, heading levels relative to it,\n * column grids from aligned cell edges with spanning header and totals rows,\n * the 63-column cap) and pdfcraft/crates/edit/src/text_regions.rs\n * (`group_layout`: joining runs on a baseline, rows into blocks, hyphens at line\n * ends) (MIT OR Apache-2.0, © ArtCraft Team and contributors).\n * See THIRD_PARTY_NOTICES.md.\n *\n * The module is pure: it never touches pdf.js or the DOM, so custom\n * extractors (another PDF library, OCR output) can feed it runs directly.\n *\n * Coordinates are PDF user space: points, `y` grows upwards and is the\n * baseline of the run. Every step sorts or sweeps, so the analysis stays near\n * O(N log N) in the number of runs.\n */\nimport { escapeHtml } from \"../serializers/plain-text\";\n\n/** A positioned piece of text, e.g. a pdf.js text item. */\nexport interface PdfTextRun {\n text: string;\n /** Left edge (points). */\n x: number;\n /** Baseline, y up (points). */\n y: number;\n /** Advance width (points). Estimated from the text length when missing. */\n width?: number;\n /** Font size (points). Falls back to `height`, then 10. */\n fontSize?: number;\n height?: number;\n /** Font name; `Bold` / `Italic` / `Oblique` in it set the style when `bold` / `italic` are absent. */\n fontName?: string;\n bold?: boolean;\n italic?: boolean;\n}\n\n/** A stroked line or thin filled rectangle on a page (table rules). */\nexport interface PdfRuleLine {\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n}\n\nexport interface PdfLayoutPage {\n runs: readonly PdfTextRun[];\n /** Ruling lines, when the extractor can read the page's vector graphics. */\n rules?: readonly PdfRuleLine[];\n}\n\nexport interface PdfLayoutOptions {\n /**\n * A baseline gap larger than this multiple of the typical line pitch starts\n * a new paragraph (default `1.4`).\n */\n paragraphGap?: number;\n /** Remove running headers, footers and page numbers repeated across pages (default `true`). */\n removeHeadersAndFooters?: boolean;\n /** Read multi-column pages column by column (default `true`). */\n detectColumns?: boolean;\n /** Detect headings from font size and weight (default `true`). */\n detectHeadings?: boolean;\n /** Detect bulleted and numbered lists (default `true`). */\n detectLists?: boolean;\n /** Detect tables from ruling lines and aligned columns (default `true`). */\n detectTables?: boolean;\n /** Re-join words hyphenated across line ends (default `true`). */\n dehyphenate?: boolean;\n}\n\nexport interface PdfTableCell {\n text: string;\n colSpan: number;\n rowSpan: number;\n header: boolean;\n}\n\nexport type PdfLayoutBlock =\n | { type: \"heading\"; level: 1 | 2 | 3 | 4 | 5 | 6; text: string; page: number; confidence: number }\n | { type: \"paragraph\"; text: string; page: number }\n | {\n type: \"list\";\n page: number;\n confidence: number;\n /** Items in order; `depth` 0 is the outermost level and grows by at most one per item. */\n items: { text: string; depth: number; ordered: boolean; start?: number }[];\n }\n | {\n type: \"table\";\n page: number;\n confidence: number;\n /** `true` when the grid came from ruling lines. */\n ruled: boolean;\n /** Rows of cells; cells covered by a span are left out. */\n rows: PdfTableCell[][];\n columns: number;\n headerRows: number;\n };\n\n/** One detected structure, for import reports. */\nexport interface ImportStructureItem {\n type: \"heading\" | \"list\" | \"table\" | \"columns\";\n /** 1-based page. */\n page: number;\n /** 0–1. */\n confidence: number;\n /** Short human-readable description, e.g. `H2 \"Results\"` or `3×4 table`. */\n detail: string;\n}\n\n/**\n * What a structure-aware importer recognised. Adapters attach it to\n * `DocumentImport.structure`; `summarizeImportStructure` aggregates it.\n */\nexport interface ImportStructureReport {\n /** `\"plain\"` when structure detection was off (paragraphs only). */\n mode: \"structured\" | \"plain\";\n counts: { headings: number; lists: number; tables: number; paragraphs: number };\n /** Pages read as several columns. */\n multiColumnPages: number;\n /** Mean confidence of the detected structures (1 when nothing was detected). */\n confidence: number;\n items: ImportStructureItem[];\n}\n\nexport interface PdfStructureReport extends ImportStructureReport {\n pages: number;\n removed: { headers: number; footers: number; pageNumbers: number };\n /** Words re-joined across a line-end hyphen. */\n dehyphenated: number;\n}\n\nexport interface PdfLayoutResult {\n blocks: PdfLayoutBlock[];\n report: PdfStructureReport;\n}\n\n// ---------------------------------------------------------------------------\n// Internal shapes\n\ninterface Frag {\n text: string;\n x0: number;\n x1: number;\n /** Baseline. */\n y: number;\n top: number;\n bottom: number;\n size: number;\n bold: boolean;\n italic: boolean;\n words: number;\n /** A ruled table placed in the flow as one atom. */\n table?: PdfLayoutBlock & { type: \"table\" };\n}\n\ntype Segment = { kind: \"flow\"; items: Frag[] } | { kind: \"grid\"; items: Frag[] };\n\n/** Most grid columns a table may have (Word cannot open 64). */\nconst MAX_COLS = 63;\nconst MAX_TABLE_ROWS = 2000;\n/** Rule segments read per page; more are ignored (decorative patterns). */\nconst MAX_RULES = 2000;\nconst MAX_DEPTH = 4;\n\nconst BULLET_GLYPH_RE = /^[•◦▪▫●○■□‣⁃∙·➢►▶✓✔❖]\\s*/;\nconst BULLET_DASH_RE = /^[-–—*]\\s+/;\nconst ORDERED_RE = /^(?:\\((\\d{1,3}|[a-zA-Z]|[ivxlcIVXLC]{1,6})\\)|(\\d{1,3}|[a-zA-Z]|[ivxlcIVXLC]{1,6})[.)])\\s+/;\nconst MARKER_ONLY_RE = /^(?:[•◦▪▫●○■□‣⁃∙·➢►▶✓✔❖]|\\(?(?:\\d{1,3}|[a-zA-Z]|[ivxlcIVXLC]{1,6})[.)])$/;\nconst PAGE_NUMBER_RE = /^(?:page\\s+)?(?:\\d{1,4}|[ivxlcdm]{1,7})(?:\\s*(?:of|\\/)\\s*\\d{1,4})?$/i;\nconst DASHED_PAGE_NUMBER_RE = /^[-–—]\\s*\\d{1,4}\\s*[-–—]$/;\nconst SENTENCE_END_RE = /[.!?:;][\"'”’)\\]]?$/;\n\nconst BOLD_FONT_RE = /bold|black|heavy|semibold|demi/i;\nconst ITALIC_FONT_RE = /italic|oblique/i;\n\nfunction minOf<T>(list: readonly T[], fn: (item: T) => number): number {\n let min = Infinity;\n for (const item of list) min = Math.min(min, fn(item));\n return min;\n}\n\nfunction maxOf<T>(list: readonly T[], fn: (item: T) => number): number {\n let max = -Infinity;\n for (const item of list) max = Math.max(max, fn(item));\n return max;\n}\n\n/** First index in ascending `values` whose value is `>= target`. */\nfunction lowerBound(values: readonly number[], target: number): number {\n let lo = 0;\n let hi = values.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (values[mid] < target) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\nfunction median(values: number[]): number {\n if (!values.length) return 0;\n const sorted = [...values].sort((a, b) => a - b);\n const mid = sorted.length >> 1;\n return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;\n}\n\nconst countWords = (text: string) => {\n let words = 0;\n let inWord = false;\n for (let i = 0; i < text.length; i++) {\n const space = text.charCodeAt(i) <= 32;\n if (!space && !inWord) words++;\n inWord = !space;\n }\n return words;\n};\n\nconst collapse = (text: string) => text.replace(/\\s+/g, \" \").trim();\n\n// ---------------------------------------------------------------------------\n// Runs → fragments (runs on one baseline separated by less than a gutter)\n\nfunction runSize(run: PdfTextRun): number {\n if (run.fontSize && run.fontSize > 0) return run.fontSize;\n if (run.height && run.height > 0) return run.height;\n return 10;\n}\n\n/**\n * Groups a page's runs into fragments: runs on the same baseline whose gap is\n * smaller than about one em. Wider gaps (column gutters, table cells) keep the\n * runs apart; a lone list marker always joins the text after it.\n */\nfunction buildFragments(runs: readonly PdfTextRun[]): Frag[] {\n const items = runs\n .filter((run) => typeof run.text === \"string\" && run.text.trim() !== \"\" && Number.isFinite(run.x) && Number.isFinite(run.y))\n .map((run) => {\n const size = runSize(run);\n const width = run.width !== undefined && run.width >= 0 ? run.width : run.text.length * size * 0.5;\n return {\n text: run.text,\n x0: run.x,\n x1: run.x + width,\n y: run.y,\n size,\n bold: run.bold ?? BOLD_FONT_RE.test(run.fontName ?? \"\"),\n italic: run.italic ?? ITALIC_FONT_RE.test(run.fontName ?? \"\"),\n };\n });\n items.sort((a, b) => b.y - a.y || a.x0 - b.x0);\n\n const frags: Frag[] = [];\n let i = 0;\n while (i < items.length) {\n // One baseline: everything within half the first run's size.\n const anchor = items[i];\n let j = i + 1;\n while (j < items.length && anchor.y - items[j].y <= Math.max(1, Math.min(anchor.size, items[j].size) * 0.5)) j++;\n const row = items.slice(i, j).sort((a, b) => a.x0 - b.x0);\n i = j;\n let current: (Frag & { styleChars: Map<string, number> }) | null = null;\n const finish = () => {\n if (!current) return;\n let best = \"\";\n let bestChars = -1;\n current.styleChars.forEach((chars, key) => {\n if (chars > bestChars) {\n best = key;\n bestChars = chars;\n }\n });\n const [size, bold, italic] = best.split(\"|\");\n current.size = Number(size);\n current.bold = bold === \"1\";\n current.italic = italic === \"1\";\n current.text = collapse(current.text);\n current.words = countWords(current.text);\n current.top = current.y + current.size * 0.8;\n current.bottom = current.y - current.size * 0.2;\n if (current.text) frags.push(current);\n current = null;\n };\n for (const item of row) {\n if (current) {\n const gap = item.x0 - current.x1;\n const em = Math.max(current.size, item.size);\n const markerOnly = MARKER_ONLY_RE.test(collapse(current.text));\n if (gap > em * (markerOnly ? 6 : 1)) finish();\n }\n if (!current) {\n current = {\n text: item.text,\n x0: item.x0,\n x1: item.x1,\n y: item.y,\n top: 0,\n bottom: 0,\n size: item.size,\n bold: item.bold,\n italic: item.italic,\n words: 0,\n styleChars: new Map(),\n };\n } else {\n const gap = item.x0 - current.x1;\n if (gap > Math.max(current.size, item.size) * 0.15 && !/\\s$/.test(current.text) && !/^\\s/.test(item.text)) {\n current.text += \" \";\n }\n current.text += item.text;\n current.x1 = Math.max(current.x1, item.x1);\n }\n const key = `${Math.round(item.size * 2) / 2}|${item.bold ? 1 : 0}|${item.italic ? 1 : 0}`;\n current.styleChars.set(key, (current.styleChars.get(key) ?? 0) + item.text.trim().length);\n }\n finish();\n }\n return frags;\n}\n\n// ---------------------------------------------------------------------------\n// Running headers, footers and page numbers\n\ninterface EdgeRemoval {\n headers: number;\n footers: number;\n pageNumbers: number;\n}\n\n/** Baseline rows of a page's fragments (already sorted top to bottom). */\nfunction baselineRows(frags: Frag[]): Frag[][] {\n const rows: Frag[][] = [];\n for (const frag of frags) {\n const row = rows[rows.length - 1];\n if (row && Math.abs(row[0].y - frag.y) <= Math.max(1, Math.min(row[0].size, frag.size) * 0.5)) row.push(frag);\n else rows.push([frag]);\n }\n return rows;\n}\n\nconst edgeKey = (row: Frag[]) =>\n collapse(row.map((f) => f.text).join(\" \"))\n .toLowerCase()\n .replace(/\\d+/g, \"#\");\n\nfunction removeHeadersAndFooters(pages: Frag[][]): EdgeRemoval {\n const removed: EdgeRemoval = { headers: 0, footers: 0, pageNumbers: 0 };\n const pageRows = pages.map((frags) => baselineRows([...frags].sort((a, b) => b.y - a.y || a.x0 - b.x0)));\n // Candidates: the first and last two rows of each page.\n const counts = new Map<string, Set<number>>();\n const candidates: { page: number; row: Frag[]; edge: \"top\" | \"bottom\"; extreme: boolean; gap: number }[] = [];\n pageRows.forEach((rows, page) => {\n const n = rows.length;\n const picks: [number, \"top\" | \"bottom\"][] = [];\n for (let k = 0; k < Math.min(2, n); k++) picks.push([k, \"top\"]);\n for (let k = Math.max(Math.min(2, n), n - 2); k < n; k++) picks.push([k, \"bottom\"]);\n for (const [index, edge] of picks) {\n const row = rows[index];\n const extreme = edge === \"top\" ? index === 0 : index === n - 1;\n const neighbour = edge === \"top\" ? rows[index + 1] : rows[index - 1];\n const gap = neighbour ? Math.abs(row[0].y - neighbour[0].y) / row[0].size : Infinity;\n candidates.push({ page, row, edge, extreme, gap });\n const key = `${edge}:${edgeKey(row)}`;\n if (!counts.has(key)) counts.set(key, new Set());\n counts.get(key)!.add(page);\n }\n });\n const minPages = Math.max(2, Math.ceil(pages.length * 0.5));\n const drop = new Set<Frag>();\n for (const candidate of candidates) {\n const text = collapse(candidate.row.map((f) => f.text).join(\" \"));\n const isPageNumber = candidate.extreme && (PAGE_NUMBER_RE.test(text) || DASHED_PAGE_NUMBER_RE.test(text));\n const repeated = (counts.get(`${candidate.edge}:${edgeKey(candidate.row)}`)?.size ?? 0) >= minPages;\n let kind: keyof EdgeRemoval | null = null;\n if (isPageNumber && (pages.length > 1 || candidate.gap > 2.5)) kind = \"pageNumbers\";\n else if (repeated && pages.length > 1) kind = candidate.edge === \"top\" ? \"headers\" : \"footers\";\n if (!kind || candidate.row.some((f) => drop.has(f))) continue;\n candidate.row.forEach((f) => drop.add(f));\n removed[kind]++;\n }\n if (drop.size) {\n pages.forEach((frags, index) => {\n pages[index] = frags.filter((f) => !drop.has(f));\n });\n }\n return removed;\n}\n\n// ---------------------------------------------------------------------------\n// Ruled tables\n\ninterface HSeg {\n y: number;\n x0: number;\n x1: number;\n}\ninterface VSeg {\n x: number;\n y0: number;\n y1: number;\n}\n\nfunction splitRules(rules: readonly PdfRuleLine[]): { h: HSeg[]; v: VSeg[] } {\n const h: HSeg[] = [];\n const v: VSeg[] = [];\n for (const rule of rules.slice(0, MAX_RULES)) {\n const { x1, y1, x2, y2 } = rule;\n if (![x1, y1, x2, y2].every(Number.isFinite)) continue;\n const dx = Math.abs(x2 - x1);\n const dy = Math.abs(y2 - y1);\n if (dy <= 1.5 && dx >= 6) h.push({ y: (y1 + y2) / 2, x0: Math.min(x1, x2), x1: Math.max(x1, x2) });\n else if (dx <= 1.5 && dy >= 6) v.push({ x: (x1 + x2) / 2, y0: Math.min(y1, y2), y1: Math.max(y1, y2) });\n }\n return { h, v };\n}\n\n/** Clusters sorted-ascending values within `tol`; returns the cluster means. */\nfunction clusterValues(values: number[], tol: number): number[] {\n const sorted = [...values].sort((a, b) => a - b);\n const out: { sum: number; n: number; last: number }[] = [];\n for (const value of sorted) {\n const cluster = out[out.length - 1];\n if (cluster && value - cluster.last <= tol) {\n cluster.sum += value;\n cluster.n++;\n cluster.last = value;\n } else out.push({ sum: value, n: 1, last: value });\n }\n return out.map((c) => c.sum / c.n);\n}\n\nfunction find(parent: number[], i: number): number {\n while (parent[i] !== i) {\n parent[i] = parent[parent[i]];\n i = parent[i];\n }\n return i;\n}\n\nconst cellText = (frags: Frag[], dehyphenate: boolean, stats: { dehyphenated: number }) => {\n const sorted = [...frags].sort((a, b) => b.y - a.y || a.x0 - b.x0);\n let text = \"\";\n let lastY = Infinity;\n for (const frag of sorted) {\n if (!text) text = frag.text;\n else if (Math.abs(lastY - frag.y) > frag.size * 0.5) text = joinLines(text, frag.text, dehyphenate, stats);\n else text += ` ${frag.text}`;\n lastY = frag.y;\n }\n return collapse(text);\n};\n\nconst NUMERIC_RE = /^[-+−(]?[$€£¥]?\\s?\\d[\\d,.\\s]*%?\\)?$/;\n\n/** Marks a header row: bold over non-bold rows, or labels over numeric data. */\nfunction headerRowCount(rowFrags: Frag[][][]): number {\n if (rowFrags.length < 2) return 0;\n const cells = (row: Frag[][]) => row.filter((cell) => cell.length > 0);\n const first = cells(rowFrags[0]);\n if (!first.length) return 0;\n const rest = rowFrags.slice(1).flatMap(cells);\n const allBold = (list: Frag[][]) => list.length > 0 && list.every((cell) => cell.every((f) => f.bold));\n if (allBold(first) && !allBold(rest)) return 1;\n const numeric = (cell: Frag[]) => NUMERIC_RE.test(collapse(cell.map((f) => f.text).join(\" \")));\n if (first.every((cell) => !numeric(cell))) {\n // A label above a column of numbers.\n const columns = rowFrags[0].length;\n for (let c = 0; c < columns; c++) {\n const body = rowFrags.slice(1).map((row) => row[c]).filter((cell) => cell && cell.length > 0);\n if (rowFrags[0][c].length && body.length >= 2 && body.every(numeric)) return 1;\n }\n }\n const firstSize = maxOf(first.flat(), (f) => f.size);\n const restSize = median(rest.flat().map((f) => f.size));\n if (restSize > 0 && firstSize >= restSize * 1.1) return 1;\n return 0;\n}\n\n/**\n * Tables drawn with ruling lines. Connected horizontal and vertical rules form\n * a grid; stacked horizontal rules alone (booktabs) bound a region whose\n * columns come from aligned gaps. Returns the tables as flow atoms and the\n * fragments they consumed.\n */\nfunction ruledTables(\n frags: Frag[],\n rules: readonly PdfRuleLine[],\n page: number,\n dehyphenate: boolean,\n stats: { dehyphenated: number },\n): { atoms: Frag[]; consumed: Set<Frag> } {\n const consumed = new Set<Frag>();\n const atoms: Frag[] = [];\n const { h, v } = splitRules(rules);\n if (h.length < 2) return { atoms, consumed };\n const n = h.length + v.length;\n const parent = Array.from({ length: n }, (_, i) => i);\n const union = (a: number, b: number) => {\n const ra = find(parent, a);\n const rb = find(parent, b);\n if (ra !== rb) parent[ra] = rb;\n };\n const tol = 2;\n // Horizontal ↔ vertical intersections: sweep verticals sorted by x against horizontals.\n const vOrder = v.map((_, i) => i).sort((a, b) => v[a].x - v[b].x);\n const vxs = vOrder.map((i) => v[i].x);\n h.forEach((seg, hi) => {\n let lo = 0;\n let hiIdx = vxs.length;\n while (lo < hiIdx) {\n const mid = (lo + hiIdx) >> 1;\n if (vxs[mid] < seg.x0 - tol) lo = mid + 1;\n else hiIdx = mid;\n }\n for (let k = lo; k < vxs.length && vxs[k] <= seg.x1 + tol; k++) {\n const vs = v[vOrder[k]];\n if (seg.y >= vs.y0 - tol && seg.y <= vs.y1 + tol) union(hi, h.length + vOrder[k]);\n }\n });\n // Stacked horizontal rules with the same extent (booktabs-style tables).\n const hOrder = h.map((_, i) => i).sort((a, b) => h[a].x0 - h[b].x0 || h[a].x1 - h[b].x1 || h[b].y - h[a].y);\n for (let k = 1; k < hOrder.length; k++) {\n const a = h[hOrder[k - 1]];\n const b = h[hOrder[k]];\n if (Math.abs(a.x0 - b.x0) <= 4 && Math.abs(a.x1 - b.x1) <= 4) union(hOrder[k - 1], hOrder[k]);\n }\n const groups = new Map<number, { h: HSeg[]; v: VSeg[] }>();\n h.forEach((seg, i) => {\n const root = find(parent, i);\n if (!groups.has(root)) groups.set(root, { h: [], v: [] });\n groups.get(root)!.h.push(seg);\n });\n v.forEach((seg, i) => {\n const root = find(parent, h.length + i);\n groups.get(root)?.v.push(seg);\n });\n\n // Fragments sorted by baseline for range lookups.\n const byY = [...frags].sort((a, b) => a.y - b.y);\n const ys = byY.map((f) => f.y);\n const inRange = (y0: number, y1: number) => {\n let lo = 0;\n let hi = ys.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (ys[mid] < y0) lo = mid + 1;\n else hi = mid;\n }\n const out: Frag[] = [];\n for (let k = lo; k < ys.length && ys[k] <= y1; k++) out.push(byY[k]);\n return out;\n };\n\n groups.forEach((group) => {\n const hys = clusterValues(group.h.map((s) => s.y), 1.5).sort((a, b) => b - a);\n if (hys.length < 2) return;\n const x0 = Math.min(...group.h.map((s) => s.x0), ...group.v.map((s) => s.x));\n const x1 = Math.max(...group.h.map((s) => s.x1), ...group.v.map((s) => s.x));\n const top = Math.max(hys[0], ...group.v.map((s) => s.y1));\n const bottom = Math.min(hys[hys.length - 1], ...group.v.map((s) => s.y0));\n const inside = inRange(bottom, top).filter((f) => {\n if (consumed.has(f)) return false;\n const cx = (f.x0 + f.x1) / 2;\n return cx >= x0 - 1 && cx <= x1 + 1;\n });\n if (inside.length < 2) return;\n const vxsGroup = clusterValues(group.v.map((s) => s.x), 1.5);\n let table: (PdfLayoutBlock & { type: \"table\" }) | null = null;\n if (vxsGroup.length >= 3 || (vxsGroup.length >= 2 && hys.length >= 3 && vxsGroup.some((x) => x > x0 + 4 && x < x1 - 4))) {\n table = gridTable(inside, group, hys, vxsGroup, x0, x1, top, bottom, page, dehyphenate, stats);\n }\n if (!table) {\n // Rules bound the table; columns come from aligned gaps (booktabs).\n const result = alignedTable(inside, page, 2, dehyphenate, stats, hys.length >= 3 ? hys[1] : undefined);\n if (result && !result.leftover.length && !result.before.length) table = { ...result.table, ruled: true, confidence: 0.85 };\n }\n if (!table) return;\n inside.forEach((f) => consumed.add(f));\n atoms.push({\n text: \"\",\n x0,\n x1,\n y: bottom,\n top,\n bottom,\n size: median(inside.map((f) => f.size)),\n bold: false,\n italic: false,\n words: 0,\n table,\n });\n });\n return { atoms, consumed };\n}\n\nfunction gridTable(\n inside: Frag[],\n group: { h: HSeg[]; v: VSeg[] },\n hys: number[],\n vxsIn: number[],\n x0: number,\n x1: number,\n top: number,\n bottom: number,\n page: number,\n dehyphenate: boolean,\n stats: { dehyphenated: number },\n): (PdfLayoutBlock & { type: \"table\" }) | null {\n const xs = [...vxsIn];\n if (xs[0] > x0 + 4) xs.unshift(x0);\n if (xs[xs.length - 1] < x1 - 4) xs.push(x1);\n const rowsY = [...hys];\n if (rowsY[0] < top - 4) rowsY.unshift(top);\n if (rowsY[rowsY.length - 1] > bottom + 4) rowsY.push(bottom);\n const cols = xs.length - 1;\n const rows = rowsY.length - 1;\n if (cols < 2 || rows < 1 || cols > MAX_COLS || rows > MAX_TABLE_ROWS) return null;\n const grid: Frag[][][] = Array.from({ length: rows }, () => Array.from({ length: cols }, () => []));\n const ascRows = [...rowsY].reverse();\n for (const frag of inside) {\n const x = frag.x0 + Math.min(2, (frag.x1 - frag.x0) / 2);\n const c = lowerBound(xs, x + 1e-9) - 1;\n const yProbe = frag.y + frag.size * 0.3;\n const r = rows - (lowerBound(ascRows, yProbe + 1e-9) - 1) - 1;\n if (c >= 0 && c < cols && r >= 0 && r < rows) grid[r][c].push(frag);\n }\n const filled = grid.flat().filter((cell) => cell.length).length;\n if (filled < 2 || (rows < 2 && cols < 2)) return null;\n // Rules indexed by the grid edge they lie on, so span checks stay cheap.\n const vAt: VSeg[][] = xs.map(() => []);\n for (const seg of group.v) {\n const k = lowerBound(xs, seg.x - 2);\n if (k < xs.length && Math.abs(xs[k] - seg.x) <= 2) vAt[k].push(seg);\n }\n const hAt: HSeg[][] = rowsY.map(() => []);\n for (const seg of group.h) {\n const k = rows - (lowerBound(ascRows, seg.y - 2));\n if (k >= 0 && k <= rows && Math.abs(rowsY[k] - seg.y) <= 2) hAt[k].push(seg);\n }\n const hasV = (k: number, y: number) => vAt[k].some((s) => y >= s.y0 - 2 && y <= s.y1 + 2);\n const hasH = (k: number, x: number) => hAt[k].some((s) => x >= s.x0 - 2 && x <= s.x1 + 2);\n const covered = grid.map((row) => row.map(() => false));\n const header = headerRowCount(grid);\n const out: PdfTableCell[][] = [];\n for (let r = 0; r < rows; r++) {\n const midY = (rowsY[r] + rowsY[r + 1]) / 2;\n const row: PdfTableCell[] = [];\n for (let c = 0; c < cols; c++) {\n if (covered[r][c]) continue;\n let colSpan = 1;\n while (c + colSpan < cols && !hasV(c + colSpan, midY) && !grid[r][c + colSpan].length && !covered[r][c + colSpan]) colSpan++;\n let rowSpan = 1;\n const midX = (xs[c] + xs[c + colSpan]) / 2;\n while (\n r + rowSpan < rows &&\n !hasH(r + rowSpan, midX) &&\n !covered[r + rowSpan].slice(c, c + colSpan).some(Boolean) &&\n grid[r + rowSpan].slice(c, c + colSpan).every((cell) => !cell.length)\n ) {\n rowSpan++;\n }\n for (let rr = r; rr < r + rowSpan; rr++) for (let cc = c; cc < c + colSpan; cc++) covered[rr][cc] = true;\n row.push({ text: cellText(grid[r][c], dehyphenate, stats), colSpan, rowSpan, header: r < header });\n }\n out.push(row);\n }\n return { type: \"table\", page, confidence: 0.95, ruled: true, rows: out, columns: cols, headerRows: header };\n}\n\n// ---------------------------------------------------------------------------\n// Tables from aligned columns\n\n/**\n * Builds a table from fragments laid out in rows with shared column gaps.\n * Columns are the gaps in the horizontal coverage of rows with several cells;\n * a single-cell row that crosses a column gap becomes a spanning cell. Rows\n * that look like prose at either end are left over for the flow.\n */\nfunction alignedTable(\n frags: Frag[],\n page: number,\n minRows: number,\n dehyphenate: boolean,\n stats: { dehyphenated: number },\n headerRuleY?: number,\n): { table: PdfLayoutBlock & { type: \"table\" }; leftover: Frag[]; before: Frag[] } | null {\n const sorted = [...frags].sort((a, b) => b.y - a.y || a.x0 - b.x0);\n let rows = baselineRows(sorted).map((row) => row.sort((a, b) => a.x0 - b.x0));\n if (rows.length < minRows) return null;\n // Column gaps from rows with at least two cells.\n const multi = rows.filter((row) => row.length >= 2);\n if (multi.length < Math.min(minRows, 2)) return null;\n const spans = multi.flat().map((f) => [f.x0, f.x1] as const).sort((a, b) => a[0] - b[0]);\n const merged: [number, number][] = [];\n for (const [a, b] of spans) {\n const last = merged[merged.length - 1];\n if (last && a <= last[1] + 1) last[1] = Math.max(last[1], b);\n else merged.push([a, b]);\n }\n if (merged.length < 2 || merged.length > MAX_COLS) return null;\n const edges = merged.map((m) => m[0]);\n const cols = merged.length;\n const colOf = (x: number) => {\n let c = 0;\n while (c + 1 < cols && x >= merged[c + 1][0] - 1) c++;\n return c;\n };\n const spanOf = (f: Frag, c: number) => {\n let span = 1;\n while (c + span < cols && f.x1 > merged[c + span][0] + 2) span++;\n return span;\n };\n // Peel prose-like or lone rows from both ends.\n const rowIsCells = (row: Frag[]) => {\n if (row.length >= 2) return true;\n const f = row[0];\n const c = colOf(f.x0);\n return spanOf(f, c) >= 2 && f.words <= 8 && Math.abs(f.x0 - edges[c]) <= Math.max(4, f.size * 0.6);\n };\n const before: Frag[] = [];\n const leftover: Frag[] = [];\n let first = 0;\n let end = rows.length;\n while (first < end && !rowIsCells(rows[first])) first++;\n while (end > first && !rowIsCells(rows[end - 1])) end--;\n rows.slice(0, first).forEach((row) => before.push(...row));\n rows.slice(end).forEach((row) => leftover.push(...row));\n rows = rows.slice(first, end);\n if (rows.length < minRows || rows.length > MAX_TABLE_ROWS) return null;\n // Wrapped cell text: a row with its first column empty and tight spacing continues the row above.\n const grid: Frag[][][] = [];\n const spansGrid: number[][] = [];\n let prevRow: Frag[] | null = null;\n for (const row of rows) {\n const cells: Frag[][] = Array.from({ length: cols }, () => []);\n const spanRow = Array.from({ length: cols }, () => 1);\n for (const f of row) {\n const c = colOf(f.x0);\n cells[c].push(f);\n spanRow[c] = Math.max(spanRow[c], row.length === 1 ? spanOf(f, c) : 1);\n }\n const continuation =\n prevRow !== null &&\n grid.length > 0 &&\n cells[0].length === 0 &&\n grid[grid.length - 1][0].length > 0 &&\n cells.every((cell, c) => !cell.length || grid[grid.length - 1][c].length > 0) &&\n minOf(prevRow, (f) => f.bottom) - maxOf(row, (f) => f.top) < row[0].size * 0.5;\n if (continuation) {\n cells.forEach((cell, c) => grid[grid.length - 1][c].push(...cell));\n } else {\n grid.push(cells);\n spansGrid.push(spanRow);\n }\n prevRow = row;\n }\n if (grid.length < minRows) return null;\n const full = grid.filter((cells) => cells.filter((c) => c.length).length >= 2).length;\n if (full / grid.length < 0.6) return null;\n // Prose check: table cells are short.\n const cellsWithText = grid.flat().filter((c) => c.length);\n const meanWords = cellsWithText.reduce((sum, cell) => sum + cell.reduce((s, f) => s + f.words, 0), 0) / cellsWithText.length;\n if (meanWords > 12) return null;\n\n let header = headerRowCount(grid);\n if (headerRuleY !== undefined) {\n // Rows above the second rule are the header.\n const above = rows.filter((row) => row[0].y > headerRuleY).length;\n if (above > 0 && above < grid.length) header = Math.max(header, Math.min(above, grid.length - 1));\n }\n const out: PdfTableCell[][] = grid.map((cells, r) => {\n const row: PdfTableCell[] = [];\n for (let c = 0; c < cols; ) {\n const span = Math.min(spansGrid[r][c], cols - c);\n row.push({ text: cellText(cells[c], dehyphenate, stats), colSpan: span, rowSpan: 1, header: r < header });\n c += span;\n }\n return row;\n });\n const confidence = Math.min(\n 0.9,\n 0.5 + (grid.length >= 5 ? 0.1 : 0) + (cols >= 3 ? 0.1 : 0) + 0.2 * (full / grid.length) - (cols === 2 ? 0.05 : 0),\n );\n return {\n table: { type: \"table\", page, confidence, ruled: false, rows: out, columns: cols, headerRows: header },\n leftover,\n before,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Reading order: columns and bands\n\n/**\n * Splits a region into reading-order segments. Gutters are vertical strips\n * that no narrow fragment crosses; fragments crossing one (titles, full-width\n * paragraphs) form their own bands. A band whose columns read like prose is\n * read column by column; one that doesn't (short aligned cells) is a grid,\n * which table detection looks at.\n */\nfunction readingOrder(items: Frag[], body: number, detectColumns: boolean, depth: number, columnPages: { count: number }): Segment[] {\n const byTop = [...items].sort((a, b) => b.top - a.top || a.x0 - b.x0);\n if (!detectColumns || items.length < 2 || depth > MAX_DEPTH) return [{ kind: \"flow\", items: byTop }];\n const left = minOf(items, (f) => f.x0);\n const right = maxOf(items, (f) => f.x1);\n const width = right - left;\n const isNarrow = (f: Frag) => f.x1 - f.x0 < width * 0.55;\n const narrow = items.filter(isNarrow);\n const minGutter = Math.max(body * 0.9, 6);\n // Sweep the narrow items' horizontal coverage. A gutter is an interior strip\n // crossed by (almost) no narrow item: a few stray lines crossing a table's\n // column gap must not hide it.\n const allowed = Math.max(1, Math.floor(narrow.length * 0.08));\n const events: [number, number][] = [];\n for (const f of narrow) events.push([f.x0, 1], [f.x1, -1]);\n events.sort((a, b) => a[0] - b[0] || a[1] - b[1]);\n const candidates: [number, number][] = [];\n let depthNow = 0;\n let seenContent = false;\n let start: number | null = null;\n for (const [x, delta] of events) {\n depthNow += delta;\n if (depthNow > allowed) {\n if (start !== null && seenContent && x - start >= minGutter) candidates.push([start, x]);\n start = null;\n seenContent = true;\n } else if (start === null) start = x;\n }\n // Shrink each strip to the items that end or start inside it: only items\n // crossing it entirely are strays.\n const ends = narrow.map((f) => f.x1).sort((a, b) => a - b);\n const starts = narrow.map((f) => f.x0).sort((a, b) => a - b);\n const gutters: [number, number][] = [];\n for (const [a, b] of candidates) {\n const endBelow = lowerBound(ends, b) - 1;\n const left = endBelow >= 0 && ends[endBelow] > a ? ends[endBelow] : a;\n const startAbove = lowerBound(starts, a + 1e-9);\n const right = startAbove < starts.length && starts[startAbove] < b ? starts[startAbove] : b;\n if (right - left < minGutter) continue;\n // Strays must be fewer than the fragments on either side, or the \"gutter\"\n // is just the ragged end of one long line.\n const onLeft = lowerBound(ends, left + 1e-6);\n const onRight = starts.length - lowerBound(starts, right - 1e-6);\n const strays = narrow.length - onLeft - onRight;\n if (strays < Math.min(onLeft, onRight)) gutters.push([left, right]);\n }\n if (!gutters.length) return [{ kind: \"flow\", items: byTop }];\n const gutterEnds = gutters.map((g) => g[1]);\n // The first gutter ending right of x0; the item crosses it if it reaches past its start.\n const crosses = (f: Frag) => {\n const k = lowerBound(gutterEnds, f.x0 + 1 + 1e-9);\n return k < gutters.length && f.x1 > gutters[k][0] + 1 && f.x0 < gutters[k][1] - 1;\n };\n const columnOf = (f: Frag) => lowerBound(gutterEnds, f.x0 + 1 + 1e-9);\n\n // Bands: runs of non-crossing items between crossing ones.\n const bands: { spanning: boolean; items: Frag[] }[] = [];\n for (const f of byTop) {\n const spanning = crosses(f);\n const band = bands[bands.length - 1];\n if (band && band.spanning === spanning) band.items.push(f);\n else bands.push({ spanning, items: [f] });\n }\n const segments: Segment[] = [];\n /** Column segments are sealed so the next band does not merge into the last column. */\n let sealed = false;\n const pushFlow = (list: Frag[]) => {\n if (!list.length) return;\n const last = segments[segments.length - 1];\n if (last && last.kind === \"flow\" && !sealed) last.items.push(...list);\n else segments.push({ kind: \"flow\", items: list });\n sealed = false;\n };\n let multiColumn = false;\n /** A short line crossing the gutters: a spanning header or totals row of a table. */\n const isShortSpan = (f: Frag) => !f.table && isNarrow(f) && f.words <= 8;\n for (const band of bands) {\n const last = segments[segments.length - 1];\n if (band.spanning) {\n const lead = band.items[0];\n if (last && last.kind === \"grid\" && isShortSpan(lead) && minOf(last.items, (f) => f.bottom) - lead.top <= lead.size * 2) {\n last.items.push(lead);\n pushFlow(band.items.slice(1));\n } else pushFlow(band.items);\n continue;\n }\n const columns: Frag[][] = Array.from({ length: gutters.length + 1 }, () => []);\n band.items.forEach((f) => columns[columnOf(f)].push(f));\n const used = columns.filter((c) => c.length);\n if (used.length < 2) {\n pushFlow(band.items);\n continue;\n }\n const prose = used.every((col) => {\n const text = col.filter((f) => !f.table);\n if (text.length < 2) return text.length === 0;\n const colLeft = minOf(text, (f) => f.x0);\n const colRight = maxOf(text, (f) => f.x1);\n const fill = text.reduce((sum, f) => sum + (f.x1 - f.x0), 0) / text.length / Math.max(1, colRight - colLeft);\n const words = text.reduce((sum, f) => sum + f.words, 0) / text.length;\n return fill >= 0.55 && words >= 3;\n });\n const tops = used.map((col) => [minOf(col, (f) => f.bottom), maxOf(col, (f) => f.top)]);\n const overlapping = tops.every(([b, t], i) => i === 0 || Math.min(t, tops[0][1]) - Math.max(b, tops[0][0]) > 0);\n if (prose && overlapping) {\n multiColumn = true;\n for (const col of used) segments.push(...readingOrder(col, body, detectColumns, depth + 1, columnPages));\n sealed = true;\n continue;\n }\n // A grid band. Pull a short spanning line right above it (a header band) into it,\n // which also re-joins grids split by such a line.\n const pulled: Frag[] = [];\n if (last && last.kind === \"flow\" && !sealed) {\n const tail = last.items[last.items.length - 1];\n if (isShortSpan(tail) && tail.bottom - maxOf(band.items, (f) => f.top) <= tail.size * 2) {\n pulled.push(last.items.pop()!);\n if (!last.items.length) segments.pop();\n }\n }\n const prevSegment = segments[segments.length - 1];\n if (prevSegment && prevSegment.kind === \"grid\" && (pulled.length || prevSegment === last)) {\n prevSegment.items.push(...pulled, ...band.items);\n } else segments.push({ kind: \"grid\", items: [...pulled, ...band.items] });\n sealed = false;\n }\n if (multiColumn && depth === 0) columnPages.count++;\n return segments;\n}\n\n// ---------------------------------------------------------------------------\n// Lines → blocks\n\ninterface Line {\n text: string;\n x0: number;\n x1: number;\n y: number;\n top: number;\n size: number;\n bold: boolean;\n page: number;\n table?: PdfLayoutBlock & { type: \"table\" };\n}\n\nfunction flowLines(items: Frag[], page: number): Line[] {\n const lines: Line[] = [];\n const sorted = [...items].sort((a, b) => b.top - a.top || a.x0 - b.x0);\n for (const f of sorted) {\n if (f.table) {\n lines.push({ text: \"\", x0: f.x0, x1: f.x1, y: f.y, top: f.top, size: f.size, bold: false, page, table: f.table });\n continue;\n }\n const last = lines[lines.length - 1];\n if (last && !last.table && Math.abs(last.y - f.y) <= Math.min(last.size, f.size) * 0.5) {\n last.text = `${last.text} ${f.text}`;\n last.x0 = Math.min(last.x0, f.x0);\n last.x1 = Math.max(last.x1, f.x1);\n } else {\n lines.push({ text: f.text, x0: f.x0, x1: f.x1, y: f.y, top: f.top, size: f.size, bold: f.bold, page });\n }\n }\n return lines;\n}\n\nfunction joinLines(prev: string, next: string, dehyphenate: boolean, stats: { dehyphenated: number }): string {\n if (prev.endsWith(\"­\")) {\n stats.dehyphenated++;\n return prev.slice(0, -1) + next;\n }\n if (dehyphenate && /[A-Za-zÀ-ɏ]-$/.test(prev) && /^[a-zß-ɏ]/.test(next)) {\n stats.dehyphenated++;\n return prev.slice(0, -1) + next;\n }\n return `${prev} ${next}`;\n}\n\ntype MarkerKind = \"glyph\" | \"dash\" | \"num\" | \"alpha\" | \"roman\";\n\nfunction listMarker(text: string): { kind: MarkerKind; rest: string; ordered: boolean; value?: number } | null {\n const glyph = BULLET_GLYPH_RE.exec(text);\n if (glyph) return { kind: \"glyph\", rest: text.slice(glyph[0].length), ordered: false };\n const dash = BULLET_DASH_RE.exec(text);\n if (dash) return { kind: \"dash\", rest: text.slice(dash[0].length), ordered: false };\n const ordered = ORDERED_RE.exec(text);\n if (ordered) {\n const token = ordered[1] ?? ordered[2];\n const kind: MarkerKind = /^\\d+$/.test(token) ? \"num\" : /^[ivxlc]{2,}$/i.test(token) || /^i$/i.test(token) ? \"roman\" : \"alpha\";\n return { kind, rest: text.slice(ordered[0].length), ordered: true, value: kind === \"num\" ? Number(token) : undefined };\n }\n return null;\n}\n\ninterface BuildContext {\n body: number;\n boldBody: boolean;\n pitch: (size: number) => number;\n options: Required<PdfLayoutOptions>;\n stats: { dehyphenated: number };\n blocks: PdfLayoutBlock[];\n /** Heading candidates waiting for levels: block plus its style key. */\n headings: { block: PdfLayoutBlock & { type: \"heading\" }; key: number; boldOnly: boolean }[];\n /** The paragraph that may continue in the next segment. */\n open: { block: PdfLayoutBlock & { type: \"paragraph\" }; size: number; lastText: string } | null;\n}\n\nfunction headingStyle(\n line: Line,\n next: Line | undefined,\n segRight: number,\n ctx: BuildContext,\n): { key: number; confidence: number; boldOnly: boolean } | null {\n if (!ctx.options.detectHeadings || line.table) return null;\n const text = line.text;\n const words = countWords(text);\n if (text.length > 200 || words > 25 || !/\\p{L}/u.test(text)) return null;\n // A long sentence in a larger font is a lede paragraph, not a heading.\n if (words > 15 && SENTENCE_END_RE.test(text)) return null;\n const ratio = line.size / ctx.body;\n if (ratio >= 1.15) {\n const confidence = Math.min(0.95, 0.6 + (ratio - 1.15) * 0.8 + (line.bold ? 0.1 : 0));\n return { key: Math.round(line.size * 2) / 2 + (line.bold ? 0.25 : 0), confidence, boldOnly: false };\n }\n // A bold line that fills the column and runs on into more bold text is a bold paragraph.\n const runsOn =\n !!next && !next.table && next.bold && Math.abs(next.size - line.size) < 0.5 && line.x1 >= segRight - 2 * line.size;\n if (line.bold && !ctx.boldBody && !runsOn && ratio >= 0.95 && text.length <= 100 && !/[.,;]$/.test(text)) {\n return { key: Math.round(line.size * 2) / 2 + 0.25, confidence: 0.6, boldOnly: true };\n }\n return null;\n}\n\n/** Turns one flow segment's lines into blocks. */\nfunction buildBlocks(lines: Line[], ctx: BuildContext) {\n const textLines = lines.filter((l) => !l.table);\n const segLeft = textLines.length ? minOf(textLines, (l) => l.x0) : 0;\n const segRight = textLines.length ? maxOf(textLines, (l) => l.x1) : 0;\n // Marker kinds that need company (two items) before they count as a list.\n const kindCounts = new Map<MarkerKind, number>();\n const markers = lines.map((line) => {\n if (!ctx.options.detectLists || line.table) return null;\n const marker = listMarker(line.text);\n if (marker) kindCounts.set(marker.kind, (kindCounts.get(marker.kind) ?? 0) + 1);\n return marker;\n });\n let list: (PdfLayoutBlock & { type: \"list\" }) | null = null;\n let listStack: number[] = [];\n let lastItemLine: Line | null = null;\n let para: { block: PdfLayoutBlock & { type: \"paragraph\" }; lines: Line[] } | null = null;\n let heading: { block: PdfLayoutBlock & { type: \"heading\" }; line: Line; key: number; lines: number } | null = null;\n\n const closeAll = () => {\n if (para) {\n const last = para.lines[para.lines.length - 1];\n const ended = SENTENCE_END_RE.test(last.text) || last.x1 < segRight - 3 * last.size;\n ctx.open = ended ? null : { block: para.block, size: last.size, lastText: para.block.text };\n } else ctx.open = null;\n para = null;\n list = null;\n listStack = [];\n lastItemLine = null;\n heading = null;\n };\n\n lines.forEach((line, index) => {\n const prev = index > 0 ? lines[index - 1] : null;\n if (line.table) {\n closeAll();\n ctx.open = null;\n ctx.blocks.push(line.table);\n return;\n }\n const style = headingStyle(line, lines[index + 1], segRight, ctx);\n if (style) {\n // Consecutive lines in the same heading style form one heading.\n if (\n heading &&\n heading.key === style.key &&\n heading.lines < 3 &&\n prev === heading.line &&\n prev.y - line.y <= line.size * 1.6\n ) {\n heading.block.text = joinLines(heading.block.text, line.text, ctx.options.dehyphenate, ctx.stats);\n heading.line = line;\n heading.lines++;\n return;\n }\n closeAll();\n ctx.open = null;\n const block: PdfLayoutBlock & { type: \"heading\" } = { type: \"heading\", level: 1, text: line.text, page: line.page, confidence: style.confidence };\n ctx.blocks.push(block);\n ctx.headings.push({ block, key: style.key, boldOnly: style.boldOnly });\n heading = { block, line, key: style.key, lines: 1 };\n return;\n }\n heading = null;\n\n const marker = markers[index];\n const validMarker = marker && (marker.kind === \"glyph\" || (kindCounts.get(marker.kind) ?? 0) >= 2) && marker.rest.trim() !== \"\";\n if (validMarker) {\n const gapOk = lastItemLine && lastItemLine.y - line.y <= Math.max(ctx.pitch(line.size) * 2.2, line.size * 2.4);\n if (!list || !gapOk) {\n closeAll();\n ctx.open = null;\n list = { type: \"list\", page: line.page, confidence: 0.6, items: [] };\n ctx.blocks.push(list);\n listStack = [line.x0];\n }\n const tol = line.size * 0.5;\n while (listStack.length > 1 && line.x0 < listStack[listStack.length - 1] - tol) listStack.pop();\n if (line.x0 > listStack[listStack.length - 1] + tol) listStack.push(line.x0);\n else listStack[listStack.length - 1] = Math.min(listStack[listStack.length - 1], line.x0);\n const prevDepth = list.items.length ? list.items[list.items.length - 1].depth : -1;\n const depth = Math.min(listStack.length - 1, prevDepth + 1);\n const item: { text: string; depth: number; ordered: boolean; start?: number } = {\n text: collapse(marker!.rest),\n depth,\n ordered: marker!.ordered,\n };\n if (marker!.value !== undefined) item.start = marker!.value;\n list.items.push(item);\n list.confidence = Math.min(0.95, (marker!.kind === \"glyph\" ? 0.75 : 0.6) + 0.05 * list.items.length);\n lastItemLine = line;\n para = null;\n return;\n }\n if (list && lastItemLine && prev) {\n // Hanging-indent continuation of the last item.\n const markerX = listStack[listStack.length - 1];\n const continues =\n line.x0 > markerX + line.size * 0.3 &&\n line.x0 <= markerX + line.size * 5 &&\n prev.y - line.y <= ctx.pitch(line.size) * ctx.options.paragraphGap;\n if (continues) {\n const item = list.items[list.items.length - 1];\n item.text = joinLines(item.text, line.text, ctx.options.dehyphenate, ctx.stats);\n lastItemLine = line;\n return;\n }\n closeAll();\n }\n\n // Paragraph continuation from the previous segment (next column or page).\n if (!para && ctx.open && index === 0 && /^[a-z]/.test(line.text) && Math.abs(ctx.open.size - line.size) <= line.size * 0.12) {\n ctx.open.block.text = joinLines(ctx.open.block.text, line.text, ctx.options.dehyphenate, ctx.stats);\n para = { block: ctx.open.block, lines: [line] };\n ctx.open = null;\n return;\n }\n if (para && prev && !prev.table) {\n const last = para.lines[para.lines.length - 1];\n const gap = last.y - line.y;\n const sameSize = Math.abs(last.size - line.size) <= last.size * 0.12;\n const closeEnough = gap > 0 && gap <= ctx.pitch(line.size) * ctx.options.paragraphGap;\n const indentEm = line.size * 0.8;\n const indented = line.x0 - segLeft >= indentEm && last.x0 - segLeft < indentEm && line.x0 - segLeft < line.size * 8;\n const shortEnded = last.x1 < segRight - 3 * last.size && SENTENCE_END_RE.test(last.text);\n if (sameSize && closeEnough && !indented && !shortEnded) {\n para.block.text = joinLines(para.block.text, line.text, ctx.options.dehyphenate, ctx.stats);\n para.lines.push(line);\n return;\n }\n }\n closeAll();\n ctx.open = null;\n const block: PdfLayoutBlock & { type: \"paragraph\" } = { type: \"paragraph\", text: line.text, page: line.page };\n ctx.blocks.push(block);\n para = { block, lines: [line] };\n });\n closeAll();\n}\n\n/** Assigns heading levels by rank of style: larger first, bold before regular. */\nfunction assignHeadingLevels(headings: BuildContext[\"headings\"]) {\n const keys = Array.from(new Set(headings.map((h) => h.key))).sort((a, b) => b - a);\n const levelOf = new Map(keys.map((key, i) => [key, Math.min(6, i + 1) as 1 | 2 | 3 | 4 | 5 | 6]));\n headings.forEach((h) => {\n h.block.level = levelOf.get(h.key)!;\n });\n}\n\n// ---------------------------------------------------------------------------\n// Entry point\n\nconst DEFAULTS: Required<PdfLayoutOptions> = {\n paragraphGap: 1.4,\n removeHeadersAndFooters: true,\n detectColumns: true,\n detectHeadings: true,\n detectLists: true,\n detectTables: true,\n dehyphenate: true,\n};\n\n/**\n * Analyses positioned text runs (one entry per page) and returns blocks in\n * reading order plus a report of what was detected.\n */\nexport function analyzePdfLayout(pages: readonly PdfLayoutPage[], options: PdfLayoutOptions = {}): PdfLayoutResult {\n const opts: Required<PdfLayoutOptions> = { ...DEFAULTS };\n (Object.keys(options) as (keyof PdfLayoutOptions)[]).forEach((key) => {\n if (options[key] !== undefined) (opts as any)[key] = options[key];\n });\n const fragPages = pages.map((page) => buildFragments(page.runs ?? []));\n const removed = opts.removeHeadersAndFooters ? removeHeadersAndFooters(fragPages) : { headers: 0, footers: 0, pageNumbers: 0 };\n\n // Body size: the size most characters are set in.\n const bySize = new Map<number, number>();\n let boldChars = 0;\n let totalChars = 0;\n fragPages.flat().forEach((f) => {\n const key = Math.round(f.size * 2) / 2;\n bySize.set(key, (bySize.get(key) ?? 0) + f.text.length);\n });\n let body = 10;\n let bodyChars = -1;\n bySize.forEach((chars, size) => {\n if (chars > bodyChars) {\n body = size;\n bodyChars = chars;\n }\n });\n fragPages.flat().forEach((f) => {\n if (Math.abs(f.size - body) <= body * 0.05) {\n totalChars += f.text.length;\n if (f.bold) boldChars += f.text.length;\n }\n });\n // Typical baseline pitch per size, from consecutive rows on each page.\n const pitches = new Map<number, number[]>();\n fragPages.forEach((frags) => {\n const rows = baselineRows([...frags].sort((a, b) => b.y - a.y || a.x0 - b.x0));\n for (let k = 1; k < rows.length; k++) {\n const a = rows[k - 1][0];\n const b = rows[k][0];\n if (Math.abs(a.size - b.size) > 0.5) continue;\n const d = a.y - b.y;\n if (d > 0 && d < a.size * 3) {\n const key = Math.round(b.size * 2) / 2;\n if (!pitches.has(key)) pitches.set(key, []);\n pitches.get(key)!.push(d);\n }\n }\n });\n const pitchMedians = new Map<number, number>();\n pitches.forEach((values, key) => pitchMedians.set(key, median(values)));\n\n const stats = { dehyphenated: 0 };\n const ctx: BuildContext = {\n body,\n boldBody: totalChars > 0 && boldChars / totalChars > 0.5,\n pitch: (size) => {\n const known = pitchMedians.get(Math.round(size * 2) / 2);\n return known && known >= size * 0.9 ? known : size * 1.2;\n },\n options: opts,\n stats,\n blocks: [],\n headings: [],\n open: null,\n };\n const columnPages = { count: 0 };\n const items: ImportStructureItem[] = [];\n\n fragPages.forEach((frags, pageIndex) => {\n const page = pageIndex + 1;\n let flowFrags = frags;\n const atoms: Frag[] = [];\n if (opts.detectTables && pages[pageIndex].rules?.length) {\n const ruled = ruledTables(frags, pages[pageIndex].rules!, page, opts.dehyphenate, stats);\n flowFrags = frags.filter((f) => !ruled.consumed.has(f));\n atoms.push(...ruled.atoms);\n }\n const before = columnPages.count;\n const segments = readingOrder([...flowFrags, ...atoms], body, opts.detectColumns, 0, columnPages);\n if (columnPages.count > before) items.push({ type: \"columns\", page, confidence: 0.8, detail: \"multi-column layout\" });\n // Rows peeled off a grid (a paragraph's last line, a caption) go back to the neighbouring flow.\n const units: ({ kind: \"flow\"; items: Frag[] } | { kind: \"table\"; table: PdfLayoutBlock & { type: \"table\" } })[] = [];\n let carry: Frag[] = [];\n for (const segment of segments) {\n if (segment.kind === \"grid\" && opts.detectTables) {\n const result = alignedTable(segment.items.filter((f) => !f.table), page, 3, opts.dehyphenate, stats);\n if (result) {\n const last = units[units.length - 1];\n if (result.before.length && last && last.kind === \"flow\") last.items.push(...carry, ...result.before);\n else if (result.before.length || carry.length) units.push({ kind: \"flow\", items: [...carry, ...result.before] });\n units.push({ kind: \"table\", table: result.table });\n carry = [...segment.items.filter((f) => f.table), ...result.leftover];\n continue;\n }\n }\n units.push({ kind: \"flow\", items: [...carry, ...segment.items] });\n carry = [];\n }\n if (carry.length) units.push({ kind: \"flow\", items: carry });\n for (const unit of units) {\n if (unit.kind === \"table\") {\n ctx.open = null;\n ctx.blocks.push(unit.table);\n } else buildBlocks(flowLines(unit.items, page), ctx);\n }\n });\n assignHeadingLevels(ctx.headings);\n\n const counts = { headings: 0, lists: 0, tables: 0, paragraphs: 0 };\n const confidences: number[] = [];\n ctx.blocks.forEach((block) => {\n if (block.type === \"heading\") {\n counts.headings++;\n confidences.push(block.confidence);\n items.push({ type: \"heading\", page: block.page, confidence: block.confidence, detail: `H${block.level} \"${truncate(block.text)}\"` });\n } else if (block.type === \"list\") {\n counts.lists++;\n confidences.push(block.confidence);\n const depth = maxOf(block.items, (i) => i.depth) + 1;\n items.push({\n type: \"list\",\n page: block.page,\n confidence: block.confidence,\n detail: `${block.items[0]?.ordered ? \"numbered\" : \"bulleted\"} list, ${block.items.length} items${depth > 1 ? `, ${depth} levels` : \"\"}`,\n });\n } else if (block.type === \"table\") {\n counts.tables++;\n confidences.push(block.confidence);\n items.push({\n type: \"table\",\n page: block.page,\n confidence: block.confidence,\n detail: `${block.rows.length}×${block.columns} table${block.ruled ? \" (ruled)\" : \"\"}${block.headerRows ? \", header row\" : \"\"}`,\n });\n } else counts.paragraphs++;\n });\n items.sort((a, b) => a.page - b.page);\n return {\n blocks: ctx.blocks,\n report: {\n mode: \"structured\",\n pages: pages.length,\n counts,\n multiColumnPages: columnPages.count,\n confidence: confidences.length ? Math.round((confidences.reduce((a, b) => a + b, 0) / confidences.length) * 100) / 100 : 1,\n items,\n removed,\n dehyphenated: stats.dehyphenated,\n },\n };\n}\n\nconst truncate = (text: string) => (text.length > 60 ? `${text.slice(0, 57)}…` : text);\n\n// ---------------------------------------------------------------------------\n// HTML\n\nfunction listHtml(items: { text: string; depth: number; ordered: boolean; start?: number }[]): string {\n let html = \"\";\n const stack: (\"ul\" | \"ol\")[] = [];\n for (const item of items) {\n const level = item.depth + 1;\n while (stack.length > level) html += `</li></${stack.pop()}>`;\n const tag = item.ordered ? \"ol\" : \"ul\";\n if (stack.length === level) {\n if (stack[stack.length - 1] !== tag) {\n html += `</li></${stack.pop()}>`;\n } else html += \"</li>\";\n }\n while (stack.length < level) {\n const start = item.ordered && item.start !== undefined && item.start !== 1 ? ` start=\"${item.start}\"` : \"\";\n html += `<${tag}${start}>`;\n stack.push(tag);\n }\n html += `<li><p>${escapeHtml(item.text)}</p>`;\n }\n while (stack.length) html += `</li></${stack.pop()}>`;\n return html;\n}\n\n/** Renders layout blocks as editor HTML (`h1`–`h6`, `p`, `ul`/`ol`, `table`). Text is escaped. */\nexport function pdfLayoutBlocksToHtml(blocks: readonly PdfLayoutBlock[]): string {\n let html = \"\";\n for (const block of blocks) {\n if (block.type === \"heading\") html += `<h${block.level}>${escapeHtml(block.text)}</h${block.level}>`;\n else if (block.type === \"paragraph\") html += `<p>${escapeHtml(block.text)}</p>`;\n else if (block.type === \"list\") html += listHtml(block.items);\n else {\n html += \"<table><tbody>\";\n for (const row of block.rows) {\n html += \"<tr>\";\n for (const cell of row) {\n const tag = cell.header ? \"th\" : \"td\";\n const attrs = `${cell.colSpan > 1 ? ` colspan=\"${cell.colSpan}\"` : \"\"}${cell.rowSpan > 1 ? ` rowspan=\"${cell.rowSpan}\"` : \"\"}`;\n html += `<${tag}${attrs}><p>${escapeHtml(cell.text)}</p></${tag}>`;\n }\n html += \"</tr>\";\n }\n html += \"</tbody></table>\";\n }\n }\n return html || \"<p></p>\";\n}\n","import { plainTextToParagraphHtml, sanitizeImportedHtml } from \"../serializers/html\";\nimport { htmlToPlainText } from \"../serializers/plain-text\";\nimport type { DocumentImport } from \"./adapters\";\nimport type { ImportAdapter } from \"./registry\";\nimport {\n analyzePdfLayout,\n pdfLayoutBlocksToHtml,\n type PdfLayoutOptions,\n type PdfLayoutPage,\n type PdfRuleLine,\n type PdfStructureReport,\n type PdfTextRun,\n} from \"./pdf-layout\";\n\n/**\n * PDF import through an injected pdf.js-compatible library. The editor ships\n * no PDF parser; consumers that already bundle `pdfjs-dist` register the\n * adapter themselves:\n *\n * ```ts\n * import * as pdfjs from \"pdfjs-dist\";\n * registerImportAdapter(createPdfImportAdapter(pdfjs));\n * ```\n *\n * By default the text runs (with positions and fonts) and the page's ruling\n * lines go through `analyzePdfLayout`, which recovers reading order across\n * columns, headings, lists and tables, and drops running headers, footers and\n * page numbers. `structure: false` (at creation, or per import through\n * `adapterOptions: { pdf: { structure: false } }`) falls back to plain\n * paragraphs: items grouped into lines by baseline and lines into paragraphs\n * by vertical gaps. Images, links and character styling are not imported.\n */\n\n/** A text item from `page.getTextContent()` (marked-content items have no `str`). */\nexport interface PdfJsTextItem {\n str: string;\n /** `[a, b, c, d, x, y]` transform; `x` / `y` are the baseline origin. */\n transform?: readonly number[];\n width?: number;\n height?: number;\n /** pdf.js sets this when a line break follows the item. */\n hasEOL?: boolean;\n /** Font resource id, e.g. `g_d0_f1` (see `PdfJsTextContent.styles` and `page.commonObjs`). */\n fontName?: string;\n}\n\nexport interface PdfJsTextContent {\n items: ReadonlyArray<PdfJsTextItem | { type: string }>;\n /** Per `fontName`: pdf.js reports the family (sometimes the real font name). */\n styles?: Record<string, { fontFamily?: string } | undefined>;\n}\n\n/** pdf.js operator list (`page.getOperatorList()`). */\nexport interface PdfJsOperatorList {\n fnArray: ArrayLike<number>;\n argsArray: ArrayLike<unknown>;\n}\n\nexport interface PdfJsPage {\n getTextContent(): Promise<PdfJsTextContent>;\n /** Used to read ruling lines (table borders); optional. */\n getOperatorList?(): Promise<PdfJsOperatorList>;\n /** Loaded fonts: `get(fontName)` returns `{ name, bold, black, italic }` once the operator list was read. */\n commonObjs?: { has?(id: string): boolean; get(id: string): unknown };\n cleanup?(): unknown;\n}\n\nexport interface PdfJsDocument {\n numPages: number;\n getPage(pageNumber: number): Promise<PdfJsPage>;\n destroy?(): unknown;\n}\n\n/** The subset of the pdf.js API the adapter uses (`pdfjs-dist` satisfies it). */\nexport interface PdfJsLike {\n getDocument(source: { data: Uint8Array; [option: string]: unknown }): { promise: Promise<PdfJsDocument> };\n /** pdf.js operator codes (`pdfjs.OPS`); the classic values are assumed when missing. */\n OPS?: Record<string, number>;\n}\n\nexport interface PdfTextOptions {\n /**\n * A line gap larger than this multiple of the page's typical line spacing\n * starts a new paragraph (default `1.4`).\n */\n paragraphGap?: number;\n}\n\n/** Options that may also be passed per import as `adapterOptions[adapterId]`. */\nexport interface PdfImportCallOptions extends PdfTextOptions {\n /**\n * Detect headings, lists, tables, columns and running headers (default\n * `true`). `false` imports plain paragraphs, as before structure detection.\n */\n structure?: boolean;\n /** Fine-tuning for `analyzePdfLayout`. */\n layout?: PdfLayoutOptions;\n /** Read the operator list for table rules and font weights (default `true`). */\n rulingLines?: boolean;\n}\n\nexport interface PdfImportOptions extends PdfImportCallOptions {\n /** Adapter id (default `\"pdf\"`). */\n id?: string;\n /** Import at most this many pages (default: all). */\n maxPages?: number;\n /** Extra `getDocument` parameters, e.g. `{ disableFontFace: true }`. */\n documentParams?: Record<string, unknown>;\n}\n\n/** What the PDF adapter returns: a `DocumentImport` with its structure report. */\nexport interface PdfDocumentImport extends DocumentImport {\n structure: PdfStructureReport;\n}\n\ninterface Line {\n text: string;\n y: number;\n height: number;\n /** A blank line (empty `hasEOL` item) follows this one. */\n blankAfter: boolean;\n}\n\nconst isTextItem = (item: PdfJsTextItem | { type: string }): item is PdfJsTextItem =>\n typeof (item as PdfJsTextItem).str === \"string\";\n\nfunction median(values: number[]): number {\n if (!values.length) return 0;\n const sorted = [...values].sort((a, b) => a - b);\n const mid = sorted.length >> 1;\n return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;\n}\n\nfunction groupLines(items: ReadonlyArray<PdfJsTextItem | { type: string }>): Line[] {\n const lines: Line[] = [];\n let current: (Line & { endX?: number }) | null = null;\n let breakNext = false;\n for (const item of items) {\n if (!isTextItem(item)) continue;\n const x = item.transform?.[4] ?? 0;\n const y: number = item.transform?.[5] ?? (current?.y ?? 0);\n const height: number = item.height || Math.abs(item.transform?.[3] ?? 0) || current?.height || 10;\n const tolerance = Math.max(1, height * 0.5);\n if (!item.str) {\n // Empty items mark line ends; two in a row mean a blank line.\n if (item.hasEOL) {\n if (breakNext && current) current.blankAfter = true;\n breakNext = true;\n }\n continue;\n }\n if (!current || breakNext || Math.abs(y - current.y) > tolerance) {\n current = { text: \"\", y, height, blankAfter: false };\n lines.push(current);\n } else if (current.endX !== undefined && x - current.endX > height * 0.15) {\n // A horizontal gap without an explicit space item.\n if (!/\\s$/.test(current.text) && !/^\\s/.test(item.str)) current.text += \" \";\n }\n current.text += item.str;\n current.height = Math.max(current.height, height);\n current.endX = item.width !== undefined ? x + item.width : undefined;\n breakNext = !!item.hasEOL;\n }\n return lines;\n}\n\n/**\n * Groups one page's pdf.js text items into paragraphs. Exposed for custom\n * adapters and tests.\n */\nexport function pdfTextItemsToParagraphs(\n items: ReadonlyArray<PdfJsTextItem | { type: string }>,\n options: PdfTextOptions = {},\n): string[] {\n const lines = groupLines(items).filter((line) => line.text.trim() || line.blankAfter);\n const gaps: number[] = [];\n for (let i = 1; i < lines.length; i++) {\n const gap = lines[i - 1].y - lines[i].y;\n if (gap > 0) gaps.push(gap);\n }\n const typical = median(gaps);\n const factor = options.paragraphGap ?? 1.4;\n\n const paragraphs: string[] = [];\n let current: string[] = [];\n const flush = () => {\n const text = current.join(\" \").replace(/\\s+/g, \" \").trim();\n if (text) paragraphs.push(text);\n current = [];\n };\n lines.forEach((line, i) => {\n if (i > 0) {\n const prev = lines[i - 1];\n const gap = prev.y - line.y;\n const bigGap = typical > 0 ? gap > typical * factor : gap > prev.height * 1.8;\n // A line above the previous one (gap < 0) starts a new column or block.\n if (prev.blankAfter || bigGap || gap < -prev.height * 0.5) flush();\n }\n const text = line.text.trim();\n if (!text) return;\n if (current.length && /\\w-$/.test(current[current.length - 1]) && /^[a-z]/.test(text)) {\n // Re-join words hyphenated across lines.\n current[current.length - 1] = current[current.length - 1].slice(0, -1) + text;\n } else {\n current.push(text);\n }\n });\n flush();\n return paragraphs;\n}\n\n/** Font details pdf.js exposes for a text item's `fontName`. */\nexport interface PdfFontInfo {\n name?: string;\n bold?: boolean;\n italic?: boolean;\n}\n\n/**\n * Converts pdf.js text items to layout runs. `font` resolves a `fontName` to\n * its real name and weight (the adapter reads `page.commonObjs` and\n * `textContent.styles`).\n */\nexport function pdfTextItemsToRuns(\n items: ReadonlyArray<PdfJsTextItem | { type: string }>,\n font?: (fontName: string) => PdfFontInfo | undefined,\n): PdfTextRun[] {\n const runs: PdfTextRun[] = [];\n const cache = new Map<string, PdfFontInfo | undefined>();\n for (const item of items) {\n if (!isTextItem(item) || !item.str.trim()) continue;\n const t = item.transform ?? [];\n const fontSize = Math.hypot(t[2] ?? 0, t[3] ?? 0) || item.height || 10;\n let info: PdfFontInfo | undefined;\n if (item.fontName && font) {\n if (!cache.has(item.fontName)) cache.set(item.fontName, font(item.fontName));\n info = cache.get(item.fontName);\n }\n runs.push({\n text: item.str,\n x: t[4] ?? 0,\n y: t[5] ?? 0,\n width: item.width,\n fontSize,\n fontName: info?.name ?? item.fontName,\n bold: info?.bold,\n italic: info?.italic,\n });\n }\n return runs;\n}\n\n/** pdf.js operator codes (stable since pdf.js 2). */\nconst DEFAULT_OPS: Record<string, number> = {\n save: 10,\n restore: 11,\n transform: 12,\n moveTo: 13,\n lineTo: 14,\n curveTo: 15,\n curveTo2: 16,\n curveTo3: 17,\n closePath: 18,\n rectangle: 19,\n stroke: 20,\n closeStroke: 21,\n fill: 22,\n eoFill: 23,\n fillStroke: 24,\n eoFillStroke: 25,\n closeFillStroke: 26,\n closeEOFillStroke: 27,\n endPath: 28,\n constructPath: 91,\n};\n/** Path codes inside a pdf.js 5 `constructPath` buffer. */\nconst DRAW_OPS = { moveTo: 0, lineTo: 1, curveTo: 2, quadraticCurveTo: 3, closePath: 4 };\nconst MAX_PAGE_RULES = 5000;\n\ntype Matrix = [number, number, number, number, number, number];\nconst IDENTITY: Matrix = [1, 0, 0, 1, 0, 0];\nconst multiply = (m: Matrix, c: Matrix): Matrix => [\n m[0] * c[0] + m[1] * c[2],\n m[0] * c[1] + m[1] * c[3],\n m[2] * c[0] + m[3] * c[2],\n m[2] * c[1] + m[3] * c[3],\n m[4] * c[0] + m[5] * c[2] + c[4],\n m[4] * c[1] + m[5] * c[3] + c[5],\n];\nconst apply = (m: Matrix, x: number, y: number): [number, number] => [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];\n\n/**\n * Reads straight, axis-aligned strokes and thin filled bars (table rules)\n * from a pdf.js operator list, in PDF user space. Understands the classic\n * `constructPath` arguments (`[ops, args, minMax]`) and the pdf.js 5 form\n * (`[paintOp, [pathData], minMax]`); clipping paths and curves are ignored.\n */\nexport function pdfOperatorListToRules(list: PdfJsOperatorList, opsTable?: Record<string, number>): PdfRuleLine[] {\n const OPS = { ...DEFAULT_OPS, ...(opsTable ?? {}) };\n const stroking = new Set([OPS.stroke, OPS.closeStroke, OPS.fillStroke, OPS.eoFillStroke, OPS.closeFillStroke, OPS.closeEOFillStroke]);\n const filling = new Set([OPS.fill, OPS.eoFill, OPS.fillStroke, OPS.eoFillStroke, OPS.closeFillStroke, OPS.closeEOFillStroke]);\n const rules: PdfRuleLine[] = [];\n const stack: Matrix[] = [];\n let ctm: Matrix = IDENTITY;\n /** Path pieces waiting for a paint operator. */\n let lines: [number, number, number, number][] = [];\n let rects: [number, number, number, number][] = [];\n const num = (value: unknown) => (typeof value === \"number\" && Number.isFinite(value) ? value : NaN);\n\n const addLine = (x1: number, y1: number, x2: number, y2: number) => {\n const [a, b] = apply(ctm, x1, y1);\n const [c, d] = apply(ctm, x2, y2);\n lines.push([a, b, c, d]);\n };\n const addRect = (x: number, y: number, w: number, h: number) => {\n const corners = [apply(ctm, x, y), apply(ctm, x + w, y), apply(ctm, x + w, y + h), apply(ctm, x, y + h)];\n const xs = corners.map((p) => p[0]);\n const ys = corners.map((p) => p[1]);\n rects.push([Math.min(...xs), Math.min(...ys), Math.max(...xs), Math.max(...ys)]);\n };\n const paint = (op: number) => {\n const stroke = stroking.has(op);\n const fill = filling.has(op);\n if (stroke) {\n for (const [x1, y1, x2, y2] of lines) rules.push({ x1, y1, x2, y2 });\n for (const [x0, y0, x1, y1] of rects) {\n rules.push({ x1: x0, y1: y0, x2: x1, y2: y0 }, { x1: x0, y1: y1, x2: x1, y2: y1 });\n rules.push({ x1: x0, y1: y0, x2: x0, y2: y1 }, { x1: x1, y1: y0, x2: x1, y2: y1 });\n }\n } else if (fill) {\n // Thin filled bars are drawn rules; larger fills are shading.\n for (const [x0, y0, x1, y1] of rects) {\n if (y1 - y0 <= 2 && x1 - x0 > 2) rules.push({ x1: x0, y1: (y0 + y1) / 2, x2: x1, y2: (y0 + y1) / 2 });\n else if (x1 - x0 <= 2 && y1 - y0 > 2) rules.push({ x1: (x0 + x1) / 2, y1: y0, x2: (x0 + x1) / 2, y2: y1 });\n }\n }\n lines = [];\n rects = [];\n };\n const readPath = (subOps: ArrayLike<unknown>, subArgs: ArrayLike<unknown>) => {\n let k = 0;\n let cx = 0;\n let cy = 0;\n let sx = 0;\n let sy = 0;\n for (let i = 0; i < subOps.length; i++) {\n const op = subOps[i];\n if (op === OPS.moveTo) {\n cx = sx = num(subArgs[k++]);\n cy = sy = num(subArgs[k++]);\n } else if (op === OPS.lineTo) {\n const x = num(subArgs[k++]);\n const y = num(subArgs[k++]);\n addLine(cx, cy, x, y);\n cx = x;\n cy = y;\n } else if (op === OPS.rectangle) {\n addRect(num(subArgs[k++]), num(subArgs[k++]), num(subArgs[k++]), num(subArgs[k++]));\n } else if (op === OPS.curveTo) {\n k += 4;\n cx = num(subArgs[k++]);\n cy = num(subArgs[k++]);\n } else if (op === OPS.curveTo2 || op === OPS.curveTo3) {\n k += 2;\n cx = num(subArgs[k++]);\n cy = num(subArgs[k++]);\n } else if (op === OPS.closePath) {\n if (cx !== sx || cy !== sy) addLine(cx, cy, sx, sy);\n cx = sx;\n cy = sy;\n }\n }\n };\n const readDrawBuffer = (data: ArrayLike<number>) => {\n let cx = 0;\n let cy = 0;\n let sx = 0;\n let sy = 0;\n for (let k = 0; k < data.length; ) {\n const code = data[k++];\n if (code === DRAW_OPS.moveTo) {\n cx = sx = data[k++];\n cy = sy = data[k++];\n } else if (code === DRAW_OPS.lineTo) {\n const x = data[k++];\n const y = data[k++];\n addLine(cx, cy, x, y);\n cx = x;\n cy = y;\n } else if (code === DRAW_OPS.curveTo) {\n k += 4;\n cx = data[k++];\n cy = data[k++];\n } else if (code === DRAW_OPS.quadraticCurveTo) {\n k += 2;\n cx = data[k++];\n cy = data[k++];\n } else if (code === DRAW_OPS.closePath) {\n if (cx !== sx || cy !== sy) addLine(cx, cy, sx, sy);\n cx = sx;\n cy = sy;\n } else break;\n }\n };\n\n for (let i = 0; i < list.fnArray.length && rules.length < MAX_PAGE_RULES; i++) {\n const fn = list.fnArray[i];\n const args = list.argsArray[i] as ArrayLike<unknown> | null | undefined;\n if (fn === OPS.save) stack.push(ctm);\n else if (fn === OPS.restore) ctm = stack.pop() ?? IDENTITY;\n else if (fn === OPS.transform && args && args.length >= 6) {\n const m = Array.from({ length: 6 }, (_, k) => num(args[k])) as Matrix;\n if (m.every(Number.isFinite)) ctm = multiply(m, ctm);\n } else if (fn === OPS.constructPath && args) {\n const first = args[0];\n if (typeof first === \"number\") {\n // pdf.js 5: the paint operator comes with the path.\n const buffers = args[1] as ArrayLike<ArrayLike<number> | null> | undefined;\n const data = buffers?.[0];\n if (data && typeof data.length === \"number\") readDrawBuffer(data);\n paint(first);\n } else if (first && typeof (first as ArrayLike<unknown>).length === \"number\") {\n readPath(first as ArrayLike<unknown>, (args[1] ?? []) as ArrayLike<unknown>);\n }\n } else if (stroking.has(fn) || filling.has(fn)) paint(fn);\n else if (fn === OPS.endPath) {\n lines = [];\n rects = [];\n }\n }\n return rules.filter((rule) => [rule.x1, rule.y1, rule.x2, rule.y2].every(Number.isFinite));\n}\n\nfunction fontResolver(page: PdfJsPage, content: PdfJsTextContent) {\n return (fontName: string): PdfFontInfo | undefined => {\n let info: PdfFontInfo | undefined;\n try {\n if (page.commonObjs && (!page.commonObjs.has || page.commonObjs.has(fontName))) {\n const font = page.commonObjs.get(fontName) as { name?: string; bold?: boolean; black?: boolean; italic?: boolean } | null;\n if (font && typeof font === \"object\") {\n info = {\n name: typeof font.name === \"string\" ? font.name : undefined,\n bold: font.bold || font.black ? true : undefined,\n italic: font.italic ? true : undefined,\n };\n }\n }\n } catch {\n // Not loaded yet: fall back to the family name below.\n }\n const family = content.styles?.[fontName]?.fontFamily;\n if (!info?.name && family) info = { ...info, name: family };\n return info;\n };\n}\n\nfunction plainReport(paragraphs: number, pages: number): PdfStructureReport {\n return {\n mode: \"plain\",\n pages,\n counts: { headings: 0, lists: 0, tables: 0, paragraphs },\n multiColumnPages: 0,\n confidence: 1,\n items: [],\n removed: { headers: 0, footers: 0, pageNumbers: 0 },\n dehyphenated: 0,\n };\n}\n\n/** Creates a PDF `document` adapter backed by an injected pdf.js-compatible library. */\nexport function createPdfImportAdapter(pdfjs: PdfJsLike, options: PdfImportOptions = {}): ImportAdapter<PdfDocumentImport> {\n return {\n id: options.id ?? \"pdf\",\n label: \"PDF\",\n mimeTypes: [\"application/pdf\"],\n extensions: [\".pdf\"],\n target: \"document\",\n async import(_input, context): Promise<PdfDocumentImport> {\n const call = (context.options && typeof context.options === \"object\" ? context.options : {}) as PdfImportCallOptions;\n const opts: PdfImportOptions = { ...options, ...call, layout: { ...options.layout, ...call.layout } };\n const structured = opts.structure !== false;\n // pdf.js may transfer (detach) the buffer it receives, so pass a copy.\n const data = new Uint8Array((await context.readArrayBuffer()).slice(0));\n const doc = await pdfjs.getDocument({ ...opts.documentParams, data }).promise;\n const paragraphs: string[] = [];\n const layoutPages: PdfLayoutPage[] = [];\n let pages = 0;\n try {\n pages = Math.min(doc.numPages, opts.maxPages ?? Infinity);\n for (let n = 1; n <= pages; n++) {\n const page = await doc.getPage(n);\n if (!structured) {\n const content = await page.getTextContent();\n paragraphs.push(...pdfTextItemsToParagraphs(content.items, opts));\n } else {\n let rules: PdfRuleLine[] = [];\n if (opts.rulingLines !== false && typeof page.getOperatorList === \"function\") {\n try {\n rules = pdfOperatorListToRules(await page.getOperatorList(), pdfjs.OPS);\n } catch {\n rules = [];\n }\n }\n const content = await page.getTextContent();\n layoutPages.push({ runs: pdfTextItemsToRuns(content.items, fontResolver(page, content)), rules });\n }\n page.cleanup?.();\n }\n } finally {\n await doc.destroy?.();\n }\n if (!structured) {\n const text = paragraphs.join(\"\\n\");\n return { html: plainTextToParagraphHtml(text), text, structure: plainReport(paragraphs.length, pages) };\n }\n const layout: PdfLayoutOptions = { ...opts.layout };\n if (layout.paragraphGap === undefined && opts.paragraphGap !== undefined) layout.paragraphGap = opts.paragraphGap;\n const { blocks, report } = analyzePdfLayout(layoutPages, layout);\n const html = sanitizeImportedHtml(pdfLayoutBlocksToHtml(blocks));\n return { html, text: htmlToPlainText(html), structure: report };\n },\n };\n}\n","import { escapeHtml } from \"../serializers/plain-text\";\nimport { defaultImportRegistry, type DocumentImport, type DocumentImportAdapter } from \"./adapters\";\nimport { ImportError, type ImportAdapterRegistry } from \"./registry\";\nimport { readZip, type ZipReadOptions } from \"./zip\";\n\n/**\n * Zipped document exports (Notion, Confluence, Obsidian, static-site dumps):\n * a `.zip` of markdown / HTML / text / DOCX files. Each entry is imported\n * with the registry's other `document` adapters and the results are\n * concatenated, with a heading per file.\n *\n * Not registered by default: `.zip` is a generic container, and claiming\n * every dropped archive as a document would steal drops from other handlers\n * (e.g. attachment uploads). Opt in with\n * `registerImportAdapter(zipImportAdapter)`.\n */\n\nexport interface ZipDocumentImport extends DocumentImport {\n /** Imported entries in document order, with the adapter that handled each. */\n files: { name: string; adapterId: string }[];\n /** Entries that were left out, with the reason. */\n skipped: { name: string; reason: string }[];\n}\n\nexport interface ZipImportOptions {\n /** Adapter id (default `\"zip\"`). */\n id?: string;\n /**\n * Registry used for the entries. Defaults to the registry running the\n * import (`context.registry`), then the default registry.\n */\n registry?: ImportAdapterRegistry;\n /** Add a heading with each file's title before its content (default `true`). */\n headings?: boolean;\n /** Heading level for file titles (default `2`). */\n headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;\n /** Import at most this many files (default 500); the rest are reported as skipped. */\n maxFiles?: number;\n /** Archive limits (default: 100 MiB extracted, 5 000 entries). */\n zip?: ZipReadOptions;\n}\n\nconst INDEX_NAMES = /^(index|readme|home|_index|start)$/i;\n\nconst baseName = (path: string) => path.slice(path.lastIndexOf(\"/\") + 1);\nconst stem = (name: string) => name.replace(/\\.[^./]+$/, \"\");\n\n/** File title: the name without extension, path or a trailing Notion-style id. */\nexport function zipEntryTitle(path: string): string {\n const title = stem(baseName(path))\n .replace(/\\s+[0-9a-f]{32}$/i, \"\")\n .replace(/[_]+/g, \" \")\n .trim();\n return title || baseName(path);\n}\n\n/**\n * Orders entries for import: index / README files first (shallowest first),\n * then by path with natural number ordering (`2` before `10`).\n */\nexport function sortZipEntryNames(names: readonly string[]): string[] {\n const isIndex = (name: string) => INDEX_NAMES.test(stem(baseName(name)));\n const depth = (name: string) => name.split(\"/\").length;\n return [...names].sort((a, b) => {\n const ai = isIndex(a);\n const bi = isIndex(b);\n if (ai !== bi) return ai ? -1 : 1;\n if (ai && bi && depth(a) !== depth(b)) return depth(a) - depth(b);\n return a.localeCompare(b, undefined, { numeric: true, sensitivity: \"base\" });\n });\n}\n\nconst isJunk = (name: string) =>\n name.startsWith(\"__MACOSX/\") || name.split(\"/\").some((segment) => segment.startsWith(\".\"));\n\n/** Creates a `document` adapter for zipped exports. */\nexport function createZipImportAdapter(options: ZipImportOptions = {}): DocumentImportAdapter {\n const id = options.id ?? \"zip\";\n return {\n id,\n label: \"Zipped documents\",\n mimeTypes: [\"application/zip\", \"application/x-zip-compressed\"],\n extensions: [\".zip\"],\n target: \"document\",\n async import(_input, context): Promise<ZipDocumentImport> {\n const registry = options.registry ?? context.registry ?? defaultImportRegistry;\n const zip = await readZip(await context.readArrayBuffer(), {\n maxTotalSize: 100 * 1024 * 1024,\n maxEntries: 5_000,\n ...options.zip,\n });\n const maxFiles = options.maxFiles ?? 500;\n const level = options.headingLevel ?? 2;\n const files: ZipDocumentImport[\"files\"] = [];\n const skipped: ZipDocumentImport[\"skipped\"] = [];\n let html = \"\";\n let text = \"\";\n\n const names = zip.entries.filter((entry) => !entry.isDirectory).map((entry) => entry.name);\n for (const name of sortZipEntryNames(names)) {\n if (isJunk(name)) continue;\n const adapter = registry.find({ fileName: name, target: \"document\" });\n if (!adapter) {\n skipped.push({ name, reason: \"unsupported type\" });\n continue;\n }\n if (adapter.id === id || adapter.extensions.some((ext) => ext.toLowerCase() === \".zip\")) {\n skipped.push({ name, reason: \"nested archive\" });\n continue;\n }\n if (files.length >= maxFiles) {\n skipped.push({ name, reason: \"file limit reached\" });\n continue;\n }\n try {\n const outcome = await registry.importFile<DocumentImport>(await zip.read(name), {\n fileName: name,\n adapterId: adapter.id,\n });\n const title = zipEntryTitle(name);\n if (options.headings !== false) {\n html += `<h${level}>${escapeHtml(title)}</h${level}>`;\n text += `${text ? \"\\n\" : \"\"}${title}\\n`;\n } else if (text) {\n text += \"\\n\";\n }\n html += outcome.result.html.trim();\n text += outcome.result.text;\n files.push({ name, adapterId: adapter.id });\n } catch (error) {\n // Archive-wide limits stop the whole import; other failures skip the entry.\n const code = (error as { code?: string })?.code;\n if (code === \"too_large\") throw error;\n skipped.push({ name, reason: error instanceof Error ? error.message : String(error) });\n }\n }\n if (!files.length) {\n throw new ImportError(\"invalid_file\", \"The archive contains no importable documents.\", {\n fileName: context.fileName,\n });\n }\n return { html, text, files, skipped };\n },\n };\n}\n\n/** Zipped-export adapter with default options. Opt in with `registerImportAdapter(zipImportAdapter)`. */\nexport const zipImportAdapter: DocumentImportAdapter = createZipImportAdapter();\n"],"mappings":"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","names":["MAX_TABLE_ROWS","left","right","block","median"]}
1
+ {"version":3,"sources":["../src/controller.ts","../src/import/controller.ts","../src/import/pdf-layout.ts","../src/import/pdf.ts","../src/import/zip-export.ts"],"sourcesContent":["import { Editor, EditorOptions, Content, Extensions } from \"@tiptap/core\";\nimport { Slice } from \"@tiptap/pm/model\";\nimport { Token, tokenizePrompt } from \"./grammar\";\nimport {\n plainTextToTipTapHtml,\n plainTextToSlice,\n getEditorText,\n markdownToTipTapHtml,\n getEditorMarkdown,\n} from \"./serializers\";\n\nexport interface EditorControllerOptions extends Partial<\n Omit<EditorOptions, \"element\" | \"content\">\n> {\n element?: Element | HTMLElement | null;\n content?: string | Content;\n plainTextMode?: boolean;\n markdownMode?: boolean;\n extensions?: Extensions;\n onPlainTextChange?: (text: string) => void;\n onMarkdownChange?: (markdown: string) => void;\n onTokensChange?: (tokens: Token[]) => void;\n onSelectionChange?: (range: { from: number; to: number } | null) => void;\n}\n\n/**\n * UI-agnostic controller managing the lifecycle, commands, and plain-text/token\n * synchronization of a rich text or prompt editor.\n */\nexport class EditorController {\n public readonly editor: Editor;\n private readonly plainTextMode: boolean;\n private readonly markdownMode: boolean;\n private readonly onPlainTextChange?: (text: string) => void;\n private readonly onMarkdownChange?: (markdown: string) => void;\n private readonly onTokensChange?: (tokens: Token[]) => void;\n private readonly onSelectionChange?: (\n range: { from: number; to: number } | null,\n ) => void;\n private baselineContent: string;\n\n constructor(options: EditorControllerOptions = {}) {\n const {\n element,\n content,\n plainTextMode = false,\n markdownMode = false,\n extensions = [],\n onPlainTextChange,\n onMarkdownChange,\n onTokensChange,\n onSelectionChange,\n ...editorOptions\n } = options;\n\n this.plainTextMode = plainTextMode;\n this.markdownMode = markdownMode;\n this.onPlainTextChange = onPlainTextChange;\n this.onMarkdownChange = onMarkdownChange;\n this.onTokensChange = onTokensChange;\n this.onSelectionChange = onSelectionChange;\n\n const initialContent =\n plainTextMode && typeof content === \"string\"\n ? plainTextToTipTapHtml(content)\n : markdownMode && typeof content === \"string\"\n ? markdownToTipTapHtml(content)\n : content;\n\n this.editor = new Editor({\n element: element || undefined,\n content: initialContent,\n extensions,\n ...editorOptions,\n onUpdate: (props) => {\n editorOptions.onUpdate?.(props);\n this.handleUpdate();\n },\n onSelectionUpdate: (props) => {\n editorOptions.onSelectionUpdate?.(props);\n this.handleSelectionUpdate();\n },\n });\n\n if (plainTextMode) {\n this.enforcePlainTextClipboard();\n }\n\n this.baselineContent = this.getCurrentContentString();\n }\n\n private enforcePlainTextClipboard() {\n // Opt-in rich clipboard / file import must not bypass the plain-text invariant.\n const richClipboard = this.editor.storage?.richClipboard;\n if (richClipboard) richClipboard.plainTextMode = true;\n const fileImport = this.editor.extensionManager?.extensions.find(\n (ext) => ext.name === \"fileImport\",\n );\n if (fileImport) fileImport.options.asPlainText = true;\n\n this.editor.setOptions({\n editorProps: {\n ...this.editor.options.editorProps,\n clipboardTextParser: (\n text: string,\n context: any,\n _plain: boolean,\n view?: any,\n ) => {\n const schema =\n context?.doc?.type?.schema ||\n context?.schema ||\n view?.state?.schema ||\n this.editor.schema;\n\n if (!schema) return Slice.empty;\n\n return plainTextToSlice(text, schema);\n },\n },\n });\n }\n\n private handleUpdate() {\n if (this.plainTextMode || this.onPlainTextChange || this.onTokensChange) {\n const text = this.getPlainText();\n this.onPlainTextChange?.(text);\n\n if (this.onTokensChange) {\n const tokens = tokenizePrompt(text);\n this.onTokensChange(tokens);\n }\n }\n\n if (this.markdownMode || this.onMarkdownChange) {\n const markdown = this.getMarkdown();\n this.onMarkdownChange?.(markdown);\n }\n }\n\n private handleSelectionUpdate() {\n if (this.onSelectionChange) {\n const { from, to } = this.editor.state.selection;\n this.onSelectionChange({ from, to });\n }\n }\n\n public getPlainText(): string {\n return getEditorText(this.editor);\n }\n\n public setPlainText(text: string, emitUpdate = true) {\n const html = plainTextToTipTapHtml(text);\n this.editor.commands.setContent(html, emitUpdate);\n }\n\n public getMarkdown(): string {\n return getEditorMarkdown(this.editor);\n }\n\n public setMarkdown(markdown: string, emitUpdate = true) {\n if (this.editor.storage?.markdown?.parser) {\n this.editor.commands.setContent(markdown, emitUpdate);\n } else {\n const html = markdownToTipTapHtml(markdown);\n this.editor.commands.setContent(html, emitUpdate);\n }\n }\n\n /**\n * Replaces `from`..`to` with literal text: HTML in `text` is not parsed, and\n * newlines split paragraphs.\n */\n private insertPlainText(from: number, to: number, text: string) {\n const { state, view } = this.editor;\n const tr = text.includes(\"\\n\") || text.includes(\"\\r\")\n ? state.tr.replace(from, to, plainTextToSlice(text, state.schema))\n : text\n ? state.tr.insertText(text, from, to)\n : state.tr.delete(from, to);\n view.dispatch(tr.scrollIntoView());\n }\n\n /** Inserts text literally at the selection; HTML in `text` is not parsed. */\n public insertText(text: string) {\n const { from, to } = this.editor.state.selection;\n this.insertPlainText(from, to, text);\n }\n\n /** Inserts text literally at `pos`; HTML in `text` is not parsed. */\n public insertTextAt(pos: number, text: string) {\n this.insertPlainText(pos, pos, text);\n this.editor.commands.focus();\n }\n\n /** Replaces a range with literal text; HTML in `text` is not parsed. */\n public replaceRange(from: number, to: number, text: string) {\n this.insertPlainText(from, to, text);\n this.editor.commands.focus();\n }\n\n public getCurrentContentString(): string {\n if (this.plainTextMode) return this.getPlainText();\n if (this.markdownMode) return this.getMarkdown();\n return this.editor.getHTML();\n }\n\n public isDirty(): boolean {\n return this.getCurrentContentString() !== this.baselineContent;\n }\n\n public setCheckpoint(content?: string): void {\n this.baselineContent =\n content !== undefined ? content : this.getCurrentContentString();\n }\n\n public resetDirty(): void {\n this.setCheckpoint();\n }\n\n public getBaselineContent(): string {\n return this.baselineContent;\n }\n\n public destroy() {\n this.editor.destroy();\n }\n}\n\n/**\n * Creates and initializes an EditorController instance.\n */\nexport function createEditor(\n options: EditorControllerOptions = {},\n): EditorController {\n return new EditorController(options);\n}\n","import { defaultImportRegistry, type DocumentImport } from \"./adapters\";\nimport {\n importFilesIntoEditor,\n type ImportEditorTarget,\n type ImportFilesIntoEditorOptions,\n} from \"./editor\";\nimport type { FileLike, ImportOutcome } from \"./registry\";\nimport type { ImportStructureReport } from \"./pdf-layout\";\n\n/**\n * Opens the browser file picker and resolves with the chosen files (an empty\n * array when the dialog is cancelled). `accept` defaults to every extension\n * and MIME type the default registry can import as a document.\n */\nexport function pickImportFiles(options: { accept?: string; multiple?: boolean } = {}): Promise<File[]> {\n if (typeof document === \"undefined\") return Promise.resolve([]);\n return new Promise((resolve) => {\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = options.accept ?? defaultImportRegistry.accept(\"document\");\n input.multiple = options.multiple ?? true;\n input.style.display = \"none\";\n const finish = (files: File[]) => {\n input.remove();\n resolve(files);\n };\n input.addEventListener(\"change\", () => finish(Array.from(input.files ?? [])), { once: true });\n input.addEventListener(\"cancel\", () => finish([]), { once: true });\n document.body.appendChild(input);\n input.click();\n });\n}\n\nexport interface FileImportState {\n isImporting: boolean;\n /** Last import error (cleared when a new import starts). */\n error: Error | null;\n /** Outcomes of the most recent import. */\n lastOutcomes: ImportOutcome<DocumentImport>[];\n}\n\nexport interface FileImportControllerOptions extends Omit<ImportFilesIntoEditorOptions, \"at\"> {\n /** Allow choosing several files in the picker (default `true`). */\n multiple?: boolean;\n}\n\n/**\n * Framework-agnostic state for a file-import button: tracks `isImporting` /\n * `error`, opens the file picker and inserts the imported content into the\n * editor returned by `getTarget`. React's `useFileImport` and Svelte's\n * `createFileImport` wrap it.\n */\nexport class FileImportController {\n private state: FileImportState = { isImporting: false, error: null, lastOutcomes: [] };\n private readonly listeners = new Set<(state: FileImportState) => void>();\n private pending = 0;\n\n constructor(\n private readonly getTarget: () => ImportEditorTarget | null | undefined,\n private options: FileImportControllerOptions = {},\n ) {}\n\n setOptions(options: FileImportControllerOptions): void {\n this.options = options;\n }\n\n /** `accept` attribute value for document imports. */\n get accept(): string {\n return (this.options.registry ?? defaultImportRegistry).accept(\"document\");\n }\n\n getState = (): FileImportState => this.state;\n\n subscribe = (listener: (state: FileImportState) => void): (() => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n private setState(patch: Partial<FileImportState>) {\n this.state = { ...this.state, ...patch };\n this.listeners.forEach((listener) => listener(this.state));\n }\n\n /** Imports files into the editor at `at` (default: the selection). */\n importFiles = async (\n files: Iterable<FileLike> | ArrayLike<FileLike>,\n at?: number,\n ): Promise<ImportOutcome<DocumentImport>[]> => {\n const target = this.getTarget();\n const list = Array.from(files as ArrayLike<FileLike>);\n if (!target || list.length === 0) return [];\n this.pending++;\n this.setState({ isImporting: true, error: null });\n let error: Error | null = null;\n try {\n const outcomes = await importFilesIntoEditor(target, list, {\n ...this.options,\n at,\n onError: (err, file) => {\n error = err;\n this.options.onError?.(err, file);\n },\n });\n this.pending--;\n this.setState({ isImporting: this.pending > 0, error, lastOutcomes: outcomes });\n return outcomes;\n } catch (err) {\n this.pending--;\n this.setState({ isImporting: this.pending > 0, error: err instanceof Error ? err : new Error(String(err)) });\n return [];\n }\n };\n\n /** Opens the file picker and imports the chosen files at the selection. */\n openFilePicker = async (): Promise<ImportOutcome<DocumentImport>[]> => {\n const files = await pickImportFiles({ accept: this.accept, multiple: this.options.multiple });\n return this.importFiles(files);\n };\n}\n\nexport function createFileImportController(\n getTarget: () => ImportEditorTarget | null | undefined,\n options?: FileImportControllerOptions,\n): FileImportController {\n return new FileImportController(getTarget, options);\n}\n\n/** Totals of the structure reports (`DocumentImport.structure`) of several imports. */\nexport interface ImportStructureSummary {\n /** Imports that carried a report. */\n files: number;\n /** `\"mixed\"` when some files were imported with structure detection and some without. */\n mode: \"structured\" | \"plain\" | \"mixed\";\n headings: number;\n lists: number;\n tables: number;\n paragraphs: number;\n multiColumnPages: number;\n /** Mean of the reports' confidences (0–1). */\n confidence: number;\n}\n\n/**\n * Sums the structure reports of import outcomes, e.g. `lastOutcomes` from a\n * file-import controller. Returns `null` when no outcome has a report (only\n * structure-aware adapters such as PDF produce one).\n */\nexport function summarizeImportStructure(\n outcomes: readonly ImportOutcome<DocumentImport>[],\n): ImportStructureSummary | null {\n const reports = outcomes\n .map((outcome) => outcome.result?.structure)\n .filter((report): report is ImportStructureReport => !!report);\n if (!reports.length) return null;\n const modes = new Set(reports.map((report) => report.mode));\n const sum = (pick: (report: ImportStructureReport) => number) =>\n reports.reduce((total, report) => total + pick(report), 0);\n return {\n files: reports.length,\n mode: modes.size > 1 ? \"mixed\" : reports[0].mode,\n headings: sum((r) => r.counts.headings),\n lists: sum((r) => r.counts.lists),\n tables: sum((r) => r.counts.tables),\n paragraphs: sum((r) => r.counts.paragraphs),\n multiColumnPages: sum((r) => r.multiColumnPages),\n confidence: Math.round((sum((r) => r.confidence) / reports.length) * 100) / 100,\n };\n}\n","/**\n * Layout analysis for PDF import: turns positioned text runs into headings,\n * paragraphs, lists and tables in reading order.\n *\n * Portions ported from pdfcraft/crates/export/src/lib.rs (`body_size`, `level`,\n * `tables`: body size by character count, heading levels relative to it,\n * column grids from aligned cell edges with spanning header and totals rows,\n * the 63-column cap) and pdfcraft/crates/edit/src/text_regions.rs\n * (`group_layout`: joining runs on a baseline, rows into blocks, hyphens at line\n * ends) (MIT OR Apache-2.0, © ArtCraft Team and contributors).\n * See THIRD_PARTY_NOTICES.md.\n *\n * The module is pure: it never touches pdf.js or the DOM, so custom\n * extractors (another PDF library, OCR output) can feed it runs directly.\n *\n * Coordinates are PDF user space: points, `y` grows upwards and is the\n * baseline of the run. Every step sorts or sweeps, so the analysis stays near\n * O(N log N) in the number of runs.\n */\nimport { escapeHtml } from \"../serializers/plain-text\";\n\n/** A positioned piece of text, e.g. a pdf.js text item. */\nexport interface PdfTextRun {\n text: string;\n /** Left edge (points). */\n x: number;\n /** Baseline, y up (points). */\n y: number;\n /** Advance width (points). Estimated from the text length when missing. */\n width?: number;\n /** Font size (points). Falls back to `height`, then 10. */\n fontSize?: number;\n height?: number;\n /** Font name; `Bold` / `Italic` / `Oblique` in it set the style when `bold` / `italic` are absent. */\n fontName?: string;\n bold?: boolean;\n italic?: boolean;\n}\n\n/** A stroked line or thin filled rectangle on a page (table rules). */\nexport interface PdfRuleLine {\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n}\n\nexport interface PdfLayoutPage {\n runs: readonly PdfTextRun[];\n /** Ruling lines, when the extractor can read the page's vector graphics. */\n rules?: readonly PdfRuleLine[];\n}\n\nexport interface PdfLayoutOptions {\n /**\n * A baseline gap larger than this multiple of the typical line pitch starts\n * a new paragraph (default `1.4`).\n */\n paragraphGap?: number;\n /** Remove running headers, footers and page numbers repeated across pages (default `true`). */\n removeHeadersAndFooters?: boolean;\n /** Read multi-column pages column by column (default `true`). */\n detectColumns?: boolean;\n /** Detect headings from font size and weight (default `true`). */\n detectHeadings?: boolean;\n /** Detect bulleted and numbered lists (default `true`). */\n detectLists?: boolean;\n /** Detect tables from ruling lines and aligned columns (default `true`). */\n detectTables?: boolean;\n /** Re-join words hyphenated across line ends (default `true`). */\n dehyphenate?: boolean;\n}\n\nexport interface PdfTableCell {\n text: string;\n colSpan: number;\n rowSpan: number;\n header: boolean;\n}\n\nexport type PdfLayoutBlock =\n | { type: \"heading\"; level: 1 | 2 | 3 | 4 | 5 | 6; text: string; page: number; confidence: number }\n | { type: \"paragraph\"; text: string; page: number }\n | {\n type: \"list\";\n page: number;\n confidence: number;\n /** Items in order; `depth` 0 is the outermost level and grows by at most one per item. */\n items: { text: string; depth: number; ordered: boolean; start?: number }[];\n }\n | {\n type: \"table\";\n page: number;\n confidence: number;\n /** `true` when the grid came from ruling lines. */\n ruled: boolean;\n /** Rows of cells; cells covered by a span are left out. */\n rows: PdfTableCell[][];\n columns: number;\n headerRows: number;\n };\n\n/** One detected structure, for import reports. */\nexport interface ImportStructureItem {\n type: \"heading\" | \"list\" | \"table\" | \"columns\";\n /** 1-based page. */\n page: number;\n /** 0–1. */\n confidence: number;\n /** Short human-readable description, e.g. `H2 \"Results\"` or `3×4 table`. */\n detail: string;\n}\n\n/**\n * What a structure-aware importer recognised. Adapters attach it to\n * `DocumentImport.structure`; `summarizeImportStructure` aggregates it.\n */\nexport interface ImportStructureReport {\n /** `\"plain\"` when structure detection was off (paragraphs only). */\n mode: \"structured\" | \"plain\";\n counts: { headings: number; lists: number; tables: number; paragraphs: number };\n /** Pages read as several columns. */\n multiColumnPages: number;\n /** Mean confidence of the detected structures (1 when nothing was detected). */\n confidence: number;\n items: ImportStructureItem[];\n}\n\nexport interface PdfStructureReport extends ImportStructureReport {\n pages: number;\n removed: { headers: number; footers: number; pageNumbers: number };\n /** Words re-joined across a line-end hyphen. */\n dehyphenated: number;\n}\n\nexport interface PdfLayoutResult {\n blocks: PdfLayoutBlock[];\n report: PdfStructureReport;\n}\n\n// ---------------------------------------------------------------------------\n// Internal shapes\n\ninterface Frag {\n text: string;\n x0: number;\n x1: number;\n /** Baseline. */\n y: number;\n top: number;\n bottom: number;\n size: number;\n bold: boolean;\n italic: boolean;\n words: number;\n /** A ruled table placed in the flow as one atom. */\n table?: PdfLayoutBlock & { type: \"table\" };\n}\n\ntype Segment = { kind: \"flow\"; items: Frag[] } | { kind: \"grid\"; items: Frag[] };\n\n/** Most grid columns a table may have (Word cannot open 64). */\nconst MAX_COLS = 63;\nconst MAX_TABLE_ROWS = 2000;\n/** Rule segments read per page; more are ignored (decorative patterns). */\nconst MAX_RULES = 2000;\nconst MAX_DEPTH = 4;\n\nconst BULLET_GLYPH_RE = /^[•◦▪▫●○■□‣⁃∙·➢►▶✓✔❖]\\s*/;\nconst BULLET_DASH_RE = /^[-–—*]\\s+/;\nconst ORDERED_RE = /^(?:\\((\\d{1,3}|[a-zA-Z]|[ivxlcIVXLC]{1,6})\\)|(\\d{1,3}|[a-zA-Z]|[ivxlcIVXLC]{1,6})[.)])\\s+/;\nconst MARKER_ONLY_RE = /^(?:[•◦▪▫●○■□‣⁃∙·➢►▶✓✔❖]|\\(?(?:\\d{1,3}|[a-zA-Z]|[ivxlcIVXLC]{1,6})[.)])$/;\nconst PAGE_NUMBER_RE = /^(?:page\\s+)?(?:\\d{1,4}|[ivxlcdm]{1,7})(?:\\s*(?:of|\\/)\\s*\\d{1,4})?$/i;\nconst DASHED_PAGE_NUMBER_RE = /^[-–—]\\s*\\d{1,4}\\s*[-–—]$/;\nconst SENTENCE_END_RE = /[.!?:;][\"'”’)\\]]?$/;\n\nconst BOLD_FONT_RE = /bold|black|heavy|semibold|demi/i;\nconst ITALIC_FONT_RE = /italic|oblique/i;\n\nfunction minOf<T>(list: readonly T[], fn: (item: T) => number): number {\n let min = Infinity;\n for (const item of list) min = Math.min(min, fn(item));\n return min;\n}\n\nfunction maxOf<T>(list: readonly T[], fn: (item: T) => number): number {\n let max = -Infinity;\n for (const item of list) max = Math.max(max, fn(item));\n return max;\n}\n\n/** First index in ascending `values` whose value is `>= target`. */\nfunction lowerBound(values: readonly number[], target: number): number {\n let lo = 0;\n let hi = values.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (values[mid] < target) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\nfunction median(values: number[]): number {\n if (!values.length) return 0;\n const sorted = [...values].sort((a, b) => a - b);\n const mid = sorted.length >> 1;\n return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;\n}\n\nconst countWords = (text: string) => {\n let words = 0;\n let inWord = false;\n for (let i = 0; i < text.length; i++) {\n const space = text.charCodeAt(i) <= 32;\n if (!space && !inWord) words++;\n inWord = !space;\n }\n return words;\n};\n\nconst collapse = (text: string) => text.replace(/\\s+/g, \" \").trim();\n\n// ---------------------------------------------------------------------------\n// Runs → fragments (runs on one baseline separated by less than a gutter)\n\nfunction runSize(run: PdfTextRun): number {\n if (run.fontSize && run.fontSize > 0) return run.fontSize;\n if (run.height && run.height > 0) return run.height;\n return 10;\n}\n\n/**\n * Groups a page's runs into fragments: runs on the same baseline whose gap is\n * smaller than about one em. Wider gaps (column gutters, table cells) keep the\n * runs apart; a lone list marker always joins the text after it.\n */\nfunction buildFragments(runs: readonly PdfTextRun[]): Frag[] {\n const items = runs\n .filter((run) => typeof run.text === \"string\" && run.text.trim() !== \"\" && Number.isFinite(run.x) && Number.isFinite(run.y))\n .map((run) => {\n const size = runSize(run);\n const width = run.width !== undefined && run.width >= 0 ? run.width : run.text.length * size * 0.5;\n return {\n text: run.text,\n x0: run.x,\n x1: run.x + width,\n y: run.y,\n size,\n bold: run.bold ?? BOLD_FONT_RE.test(run.fontName ?? \"\"),\n italic: run.italic ?? ITALIC_FONT_RE.test(run.fontName ?? \"\"),\n };\n });\n items.sort((a, b) => b.y - a.y || a.x0 - b.x0);\n\n const frags: Frag[] = [];\n let i = 0;\n while (i < items.length) {\n // One baseline: everything within half the first run's size.\n const anchor = items[i];\n let j = i + 1;\n while (j < items.length && anchor.y - items[j].y <= Math.max(1, Math.min(anchor.size, items[j].size) * 0.5)) j++;\n const row = items.slice(i, j).sort((a, b) => a.x0 - b.x0);\n i = j;\n let current: (Frag & { styleChars: Map<string, number> }) | null = null;\n const finish = () => {\n if (!current) return;\n let best = \"\";\n let bestChars = -1;\n current.styleChars.forEach((chars, key) => {\n if (chars > bestChars) {\n best = key;\n bestChars = chars;\n }\n });\n const [size, bold, italic] = best.split(\"|\");\n current.size = Number(size);\n current.bold = bold === \"1\";\n current.italic = italic === \"1\";\n current.text = collapse(current.text);\n current.words = countWords(current.text);\n current.top = current.y + current.size * 0.8;\n current.bottom = current.y - current.size * 0.2;\n if (current.text) frags.push(current);\n current = null;\n };\n for (const item of row) {\n if (current) {\n const gap = item.x0 - current.x1;\n const em = Math.max(current.size, item.size);\n const markerOnly = MARKER_ONLY_RE.test(collapse(current.text));\n if (gap > em * (markerOnly ? 6 : 1)) finish();\n }\n if (!current) {\n current = {\n text: item.text,\n x0: item.x0,\n x1: item.x1,\n y: item.y,\n top: 0,\n bottom: 0,\n size: item.size,\n bold: item.bold,\n italic: item.italic,\n words: 0,\n styleChars: new Map(),\n };\n } else {\n const gap = item.x0 - current.x1;\n if (gap > Math.max(current.size, item.size) * 0.15 && !/\\s$/.test(current.text) && !/^\\s/.test(item.text)) {\n current.text += \" \";\n }\n current.text += item.text;\n current.x1 = Math.max(current.x1, item.x1);\n }\n const key = `${Math.round(item.size * 2) / 2}|${item.bold ? 1 : 0}|${item.italic ? 1 : 0}`;\n current.styleChars.set(key, (current.styleChars.get(key) ?? 0) + item.text.trim().length);\n }\n finish();\n }\n return frags;\n}\n\n// ---------------------------------------------------------------------------\n// Running headers, footers and page numbers\n\ninterface EdgeRemoval {\n headers: number;\n footers: number;\n pageNumbers: number;\n}\n\n/** Baseline rows of a page's fragments (already sorted top to bottom). */\nfunction baselineRows(frags: Frag[]): Frag[][] {\n const rows: Frag[][] = [];\n for (const frag of frags) {\n const row = rows[rows.length - 1];\n if (row && Math.abs(row[0].y - frag.y) <= Math.max(1, Math.min(row[0].size, frag.size) * 0.5)) row.push(frag);\n else rows.push([frag]);\n }\n return rows;\n}\n\nconst edgeKey = (row: Frag[]) =>\n collapse(row.map((f) => f.text).join(\" \"))\n .toLowerCase()\n .replace(/\\d+/g, \"#\");\n\nfunction removeHeadersAndFooters(pages: Frag[][]): EdgeRemoval {\n const removed: EdgeRemoval = { headers: 0, footers: 0, pageNumbers: 0 };\n const pageRows = pages.map((frags) => baselineRows([...frags].sort((a, b) => b.y - a.y || a.x0 - b.x0)));\n // Candidates: the first and last two rows of each page.\n const counts = new Map<string, Set<number>>();\n const candidates: { page: number; row: Frag[]; edge: \"top\" | \"bottom\"; extreme: boolean; gap: number }[] = [];\n pageRows.forEach((rows, page) => {\n const n = rows.length;\n const picks: [number, \"top\" | \"bottom\"][] = [];\n for (let k = 0; k < Math.min(2, n); k++) picks.push([k, \"top\"]);\n for (let k = Math.max(Math.min(2, n), n - 2); k < n; k++) picks.push([k, \"bottom\"]);\n for (const [index, edge] of picks) {\n const row = rows[index];\n const extreme = edge === \"top\" ? index === 0 : index === n - 1;\n const neighbour = edge === \"top\" ? rows[index + 1] : rows[index - 1];\n const gap = neighbour ? Math.abs(row[0].y - neighbour[0].y) / row[0].size : Infinity;\n candidates.push({ page, row, edge, extreme, gap });\n const key = `${edge}:${edgeKey(row)}`;\n if (!counts.has(key)) counts.set(key, new Set());\n counts.get(key)!.add(page);\n }\n });\n const minPages = Math.max(2, Math.ceil(pages.length * 0.5));\n const drop = new Set<Frag>();\n for (const candidate of candidates) {\n const text = collapse(candidate.row.map((f) => f.text).join(\" \"));\n const isPageNumber = candidate.extreme && (PAGE_NUMBER_RE.test(text) || DASHED_PAGE_NUMBER_RE.test(text));\n const repeated = (counts.get(`${candidate.edge}:${edgeKey(candidate.row)}`)?.size ?? 0) >= minPages;\n let kind: keyof EdgeRemoval | null = null;\n if (isPageNumber && (pages.length > 1 || candidate.gap > 2.5)) kind = \"pageNumbers\";\n else if (repeated && pages.length > 1) kind = candidate.edge === \"top\" ? \"headers\" : \"footers\";\n if (!kind || candidate.row.some((f) => drop.has(f))) continue;\n candidate.row.forEach((f) => drop.add(f));\n removed[kind]++;\n }\n if (drop.size) {\n pages.forEach((frags, index) => {\n pages[index] = frags.filter((f) => !drop.has(f));\n });\n }\n return removed;\n}\n\n// ---------------------------------------------------------------------------\n// Ruled tables\n\ninterface HSeg {\n y: number;\n x0: number;\n x1: number;\n}\ninterface VSeg {\n x: number;\n y0: number;\n y1: number;\n}\n\nfunction splitRules(rules: readonly PdfRuleLine[]): { h: HSeg[]; v: VSeg[] } {\n const h: HSeg[] = [];\n const v: VSeg[] = [];\n for (const rule of rules.slice(0, MAX_RULES)) {\n const { x1, y1, x2, y2 } = rule;\n if (![x1, y1, x2, y2].every(Number.isFinite)) continue;\n const dx = Math.abs(x2 - x1);\n const dy = Math.abs(y2 - y1);\n if (dy <= 1.5 && dx >= 6) h.push({ y: (y1 + y2) / 2, x0: Math.min(x1, x2), x1: Math.max(x1, x2) });\n else if (dx <= 1.5 && dy >= 6) v.push({ x: (x1 + x2) / 2, y0: Math.min(y1, y2), y1: Math.max(y1, y2) });\n }\n return { h, v };\n}\n\n/** Clusters sorted-ascending values within `tol`; returns the cluster means. */\nfunction clusterValues(values: number[], tol: number): number[] {\n const sorted = [...values].sort((a, b) => a - b);\n const out: { sum: number; n: number; last: number }[] = [];\n for (const value of sorted) {\n const cluster = out[out.length - 1];\n if (cluster && value - cluster.last <= tol) {\n cluster.sum += value;\n cluster.n++;\n cluster.last = value;\n } else out.push({ sum: value, n: 1, last: value });\n }\n return out.map((c) => c.sum / c.n);\n}\n\nfunction find(parent: number[], i: number): number {\n while (parent[i] !== i) {\n parent[i] = parent[parent[i]];\n i = parent[i];\n }\n return i;\n}\n\nconst cellText = (frags: Frag[], dehyphenate: boolean, stats: { dehyphenated: number }) => {\n const sorted = [...frags].sort((a, b) => b.y - a.y || a.x0 - b.x0);\n let text = \"\";\n let lastY = Infinity;\n for (const frag of sorted) {\n if (!text) text = frag.text;\n else if (Math.abs(lastY - frag.y) > frag.size * 0.5) text = joinLines(text, frag.text, dehyphenate, stats);\n else text += ` ${frag.text}`;\n lastY = frag.y;\n }\n return collapse(text);\n};\n\nconst NUMERIC_RE = /^[-+−(]?[$€£¥]?\\s?\\d[\\d,.\\s]*%?\\)?$/;\n\n/** Marks a header row: bold over non-bold rows, or labels over numeric data. */\nfunction headerRowCount(rowFrags: Frag[][][]): number {\n if (rowFrags.length < 2) return 0;\n const cells = (row: Frag[][]) => row.filter((cell) => cell.length > 0);\n const first = cells(rowFrags[0]);\n if (!first.length) return 0;\n const rest = rowFrags.slice(1).flatMap(cells);\n const allBold = (list: Frag[][]) => list.length > 0 && list.every((cell) => cell.every((f) => f.bold));\n if (allBold(first) && !allBold(rest)) return 1;\n const numeric = (cell: Frag[]) => NUMERIC_RE.test(collapse(cell.map((f) => f.text).join(\" \")));\n if (first.every((cell) => !numeric(cell))) {\n // A label above a column of numbers.\n const columns = rowFrags[0].length;\n for (let c = 0; c < columns; c++) {\n const body = rowFrags.slice(1).map((row) => row[c]).filter((cell) => cell && cell.length > 0);\n if (rowFrags[0][c].length && body.length >= 2 && body.every(numeric)) return 1;\n }\n }\n const firstSize = maxOf(first.flat(), (f) => f.size);\n const restSize = median(rest.flat().map((f) => f.size));\n if (restSize > 0 && firstSize >= restSize * 1.1) return 1;\n return 0;\n}\n\n/**\n * Tables drawn with ruling lines. Connected horizontal and vertical rules form\n * a grid; stacked horizontal rules alone (booktabs) bound a region whose\n * columns come from aligned gaps. Returns the tables as flow atoms and the\n * fragments they consumed.\n */\nfunction ruledTables(\n frags: Frag[],\n rules: readonly PdfRuleLine[],\n page: number,\n dehyphenate: boolean,\n stats: { dehyphenated: number },\n): { atoms: Frag[]; consumed: Set<Frag> } {\n const consumed = new Set<Frag>();\n const atoms: Frag[] = [];\n const { h, v } = splitRules(rules);\n if (h.length < 2) return { atoms, consumed };\n const n = h.length + v.length;\n const parent = Array.from({ length: n }, (_, i) => i);\n const union = (a: number, b: number) => {\n const ra = find(parent, a);\n const rb = find(parent, b);\n if (ra !== rb) parent[ra] = rb;\n };\n const tol = 2;\n // Horizontal ↔ vertical intersections: sweep verticals sorted by x against horizontals.\n const vOrder = v.map((_, i) => i).sort((a, b) => v[a].x - v[b].x);\n const vxs = vOrder.map((i) => v[i].x);\n h.forEach((seg, hi) => {\n let lo = 0;\n let hiIdx = vxs.length;\n while (lo < hiIdx) {\n const mid = (lo + hiIdx) >> 1;\n if (vxs[mid] < seg.x0 - tol) lo = mid + 1;\n else hiIdx = mid;\n }\n for (let k = lo; k < vxs.length && vxs[k] <= seg.x1 + tol; k++) {\n const vs = v[vOrder[k]];\n if (seg.y >= vs.y0 - tol && seg.y <= vs.y1 + tol) union(hi, h.length + vOrder[k]);\n }\n });\n // Stacked horizontal rules with the same extent (booktabs-style tables).\n const hOrder = h.map((_, i) => i).sort((a, b) => h[a].x0 - h[b].x0 || h[a].x1 - h[b].x1 || h[b].y - h[a].y);\n for (let k = 1; k < hOrder.length; k++) {\n const a = h[hOrder[k - 1]];\n const b = h[hOrder[k]];\n if (Math.abs(a.x0 - b.x0) <= 4 && Math.abs(a.x1 - b.x1) <= 4) union(hOrder[k - 1], hOrder[k]);\n }\n const groups = new Map<number, { h: HSeg[]; v: VSeg[] }>();\n h.forEach((seg, i) => {\n const root = find(parent, i);\n if (!groups.has(root)) groups.set(root, { h: [], v: [] });\n groups.get(root)!.h.push(seg);\n });\n v.forEach((seg, i) => {\n const root = find(parent, h.length + i);\n groups.get(root)?.v.push(seg);\n });\n\n // Fragments sorted by baseline for range lookups.\n const byY = [...frags].sort((a, b) => a.y - b.y);\n const ys = byY.map((f) => f.y);\n const inRange = (y0: number, y1: number) => {\n let lo = 0;\n let hi = ys.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (ys[mid] < y0) lo = mid + 1;\n else hi = mid;\n }\n const out: Frag[] = [];\n for (let k = lo; k < ys.length && ys[k] <= y1; k++) out.push(byY[k]);\n return out;\n };\n\n groups.forEach((group) => {\n const hys = clusterValues(group.h.map((s) => s.y), 1.5).sort((a, b) => b - a);\n if (hys.length < 2) return;\n const x0 = Math.min(...group.h.map((s) => s.x0), ...group.v.map((s) => s.x));\n const x1 = Math.max(...group.h.map((s) => s.x1), ...group.v.map((s) => s.x));\n const top = Math.max(hys[0], ...group.v.map((s) => s.y1));\n const bottom = Math.min(hys[hys.length - 1], ...group.v.map((s) => s.y0));\n const inside = inRange(bottom, top).filter((f) => {\n if (consumed.has(f)) return false;\n const cx = (f.x0 + f.x1) / 2;\n return cx >= x0 - 1 && cx <= x1 + 1;\n });\n if (inside.length < 2) return;\n const vxsGroup = clusterValues(group.v.map((s) => s.x), 1.5);\n let table: (PdfLayoutBlock & { type: \"table\" }) | null = null;\n if (vxsGroup.length >= 3 || (vxsGroup.length >= 2 && hys.length >= 3 && vxsGroup.some((x) => x > x0 + 4 && x < x1 - 4))) {\n table = gridTable(inside, group, hys, vxsGroup, x0, x1, top, bottom, page, dehyphenate, stats);\n }\n if (!table) {\n // Rules bound the table; columns come from aligned gaps (booktabs).\n const result = alignedTable(inside, page, 2, dehyphenate, stats, hys.length >= 3 ? hys[1] : undefined);\n if (result && !result.leftover.length && !result.before.length) table = { ...result.table, ruled: true, confidence: 0.85 };\n }\n if (!table) return;\n inside.forEach((f) => consumed.add(f));\n atoms.push({\n text: \"\",\n x0,\n x1,\n y: bottom,\n top,\n bottom,\n size: median(inside.map((f) => f.size)),\n bold: false,\n italic: false,\n words: 0,\n table,\n });\n });\n return { atoms, consumed };\n}\n\nfunction gridTable(\n inside: Frag[],\n group: { h: HSeg[]; v: VSeg[] },\n hys: number[],\n vxsIn: number[],\n x0: number,\n x1: number,\n top: number,\n bottom: number,\n page: number,\n dehyphenate: boolean,\n stats: { dehyphenated: number },\n): (PdfLayoutBlock & { type: \"table\" }) | null {\n const xs = [...vxsIn];\n if (xs[0] > x0 + 4) xs.unshift(x0);\n if (xs[xs.length - 1] < x1 - 4) xs.push(x1);\n const rowsY = [...hys];\n if (rowsY[0] < top - 4) rowsY.unshift(top);\n if (rowsY[rowsY.length - 1] > bottom + 4) rowsY.push(bottom);\n const cols = xs.length - 1;\n const rows = rowsY.length - 1;\n if (cols < 2 || rows < 1 || cols > MAX_COLS || rows > MAX_TABLE_ROWS) return null;\n const grid: Frag[][][] = Array.from({ length: rows }, () => Array.from({ length: cols }, () => []));\n const ascRows = [...rowsY].reverse();\n for (const frag of inside) {\n const x = frag.x0 + Math.min(2, (frag.x1 - frag.x0) / 2);\n const c = lowerBound(xs, x + 1e-9) - 1;\n const yProbe = frag.y + frag.size * 0.3;\n const r = rows - (lowerBound(ascRows, yProbe + 1e-9) - 1) - 1;\n if (c >= 0 && c < cols && r >= 0 && r < rows) grid[r][c].push(frag);\n }\n const filled = grid.flat().filter((cell) => cell.length).length;\n if (filled < 2 || (rows < 2 && cols < 2)) return null;\n // Rules indexed by the grid edge they lie on, so span checks stay cheap.\n const vAt: VSeg[][] = xs.map(() => []);\n for (const seg of group.v) {\n const k = lowerBound(xs, seg.x - 2);\n if (k < xs.length && Math.abs(xs[k] - seg.x) <= 2) vAt[k].push(seg);\n }\n const hAt: HSeg[][] = rowsY.map(() => []);\n for (const seg of group.h) {\n const k = rows - (lowerBound(ascRows, seg.y - 2));\n if (k >= 0 && k <= rows && Math.abs(rowsY[k] - seg.y) <= 2) hAt[k].push(seg);\n }\n const hasV = (k: number, y: number) => vAt[k].some((s) => y >= s.y0 - 2 && y <= s.y1 + 2);\n const hasH = (k: number, x: number) => hAt[k].some((s) => x >= s.x0 - 2 && x <= s.x1 + 2);\n const covered = grid.map((row) => row.map(() => false));\n const header = headerRowCount(grid);\n const out: PdfTableCell[][] = [];\n for (let r = 0; r < rows; r++) {\n const midY = (rowsY[r] + rowsY[r + 1]) / 2;\n const row: PdfTableCell[] = [];\n for (let c = 0; c < cols; c++) {\n if (covered[r][c]) continue;\n let colSpan = 1;\n while (c + colSpan < cols && !hasV(c + colSpan, midY) && !grid[r][c + colSpan].length && !covered[r][c + colSpan]) colSpan++;\n let rowSpan = 1;\n const midX = (xs[c] + xs[c + colSpan]) / 2;\n while (\n r + rowSpan < rows &&\n !hasH(r + rowSpan, midX) &&\n !covered[r + rowSpan].slice(c, c + colSpan).some(Boolean) &&\n grid[r + rowSpan].slice(c, c + colSpan).every((cell) => !cell.length)\n ) {\n rowSpan++;\n }\n for (let rr = r; rr < r + rowSpan; rr++) for (let cc = c; cc < c + colSpan; cc++) covered[rr][cc] = true;\n row.push({ text: cellText(grid[r][c], dehyphenate, stats), colSpan, rowSpan, header: r < header });\n }\n out.push(row);\n }\n return { type: \"table\", page, confidence: 0.95, ruled: true, rows: out, columns: cols, headerRows: header };\n}\n\n// ---------------------------------------------------------------------------\n// Tables from aligned columns\n\n/**\n * Builds a table from fragments laid out in rows with shared column gaps.\n * Columns are the gaps in the horizontal coverage of rows with several cells;\n * a single-cell row that crosses a column gap becomes a spanning cell. Rows\n * that look like prose at either end are left over for the flow.\n */\nfunction alignedTable(\n frags: Frag[],\n page: number,\n minRows: number,\n dehyphenate: boolean,\n stats: { dehyphenated: number },\n headerRuleY?: number,\n): { table: PdfLayoutBlock & { type: \"table\" }; leftover: Frag[]; before: Frag[] } | null {\n const sorted = [...frags].sort((a, b) => b.y - a.y || a.x0 - b.x0);\n let rows = baselineRows(sorted).map((row) => row.sort((a, b) => a.x0 - b.x0));\n if (rows.length < minRows) return null;\n // Column gaps from rows with at least two cells.\n const multi = rows.filter((row) => row.length >= 2);\n if (multi.length < Math.min(minRows, 2)) return null;\n const spans = multi.flat().map((f) => [f.x0, f.x1] as const).sort((a, b) => a[0] - b[0]);\n const merged: [number, number][] = [];\n for (const [a, b] of spans) {\n const last = merged[merged.length - 1];\n if (last && a <= last[1] + 1) last[1] = Math.max(last[1], b);\n else merged.push([a, b]);\n }\n if (merged.length < 2 || merged.length > MAX_COLS) return null;\n const edges = merged.map((m) => m[0]);\n const cols = merged.length;\n const colOf = (x: number) => {\n let c = 0;\n while (c + 1 < cols && x >= merged[c + 1][0] - 1) c++;\n return c;\n };\n const spanOf = (f: Frag, c: number) => {\n let span = 1;\n while (c + span < cols && f.x1 > merged[c + span][0] + 2) span++;\n return span;\n };\n // Peel prose-like or lone rows from both ends.\n const rowIsCells = (row: Frag[]) => {\n if (row.length >= 2) return true;\n const f = row[0];\n const c = colOf(f.x0);\n return spanOf(f, c) >= 2 && f.words <= 8 && Math.abs(f.x0 - edges[c]) <= Math.max(4, f.size * 0.6);\n };\n const before: Frag[] = [];\n const leftover: Frag[] = [];\n let first = 0;\n let end = rows.length;\n while (first < end && !rowIsCells(rows[first])) first++;\n while (end > first && !rowIsCells(rows[end - 1])) end--;\n rows.slice(0, first).forEach((row) => before.push(...row));\n rows.slice(end).forEach((row) => leftover.push(...row));\n rows = rows.slice(first, end);\n if (rows.length < minRows || rows.length > MAX_TABLE_ROWS) return null;\n // Wrapped cell text: a row with its first column empty and tight spacing continues the row above.\n const grid: Frag[][][] = [];\n const spansGrid: number[][] = [];\n let prevRow: Frag[] | null = null;\n for (const row of rows) {\n const cells: Frag[][] = Array.from({ length: cols }, () => []);\n const spanRow = Array.from({ length: cols }, () => 1);\n for (const f of row) {\n const c = colOf(f.x0);\n cells[c].push(f);\n spanRow[c] = Math.max(spanRow[c], row.length === 1 ? spanOf(f, c) : 1);\n }\n const continuation =\n prevRow !== null &&\n grid.length > 0 &&\n cells[0].length === 0 &&\n grid[grid.length - 1][0].length > 0 &&\n cells.every((cell, c) => !cell.length || grid[grid.length - 1][c].length > 0) &&\n minOf(prevRow, (f) => f.bottom) - maxOf(row, (f) => f.top) < row[0].size * 0.5;\n if (continuation) {\n cells.forEach((cell, c) => grid[grid.length - 1][c].push(...cell));\n } else {\n grid.push(cells);\n spansGrid.push(spanRow);\n }\n prevRow = row;\n }\n if (grid.length < minRows) return null;\n const full = grid.filter((cells) => cells.filter((c) => c.length).length >= 2).length;\n if (full / grid.length < 0.6) return null;\n // Prose check: table cells are short.\n const cellsWithText = grid.flat().filter((c) => c.length);\n const meanWords = cellsWithText.reduce((sum, cell) => sum + cell.reduce((s, f) => s + f.words, 0), 0) / cellsWithText.length;\n if (meanWords > 12) return null;\n\n let header = headerRowCount(grid);\n if (headerRuleY !== undefined) {\n // Rows above the second rule are the header.\n const above = rows.filter((row) => row[0].y > headerRuleY).length;\n if (above > 0 && above < grid.length) header = Math.max(header, Math.min(above, grid.length - 1));\n }\n const out: PdfTableCell[][] = grid.map((cells, r) => {\n const row: PdfTableCell[] = [];\n for (let c = 0; c < cols; ) {\n const span = Math.min(spansGrid[r][c], cols - c);\n row.push({ text: cellText(cells[c], dehyphenate, stats), colSpan: span, rowSpan: 1, header: r < header });\n c += span;\n }\n return row;\n });\n const confidence = Math.min(\n 0.9,\n 0.5 + (grid.length >= 5 ? 0.1 : 0) + (cols >= 3 ? 0.1 : 0) + 0.2 * (full / grid.length) - (cols === 2 ? 0.05 : 0),\n );\n return {\n table: { type: \"table\", page, confidence, ruled: false, rows: out, columns: cols, headerRows: header },\n leftover,\n before,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Reading order: columns and bands\n\n/**\n * Splits a region into reading-order segments. Gutters are vertical strips\n * that no narrow fragment crosses; fragments crossing one (titles, full-width\n * paragraphs) form their own bands. A band whose columns read like prose is\n * read column by column; one that doesn't (short aligned cells) is a grid,\n * which table detection looks at.\n */\nfunction readingOrder(items: Frag[], body: number, detectColumns: boolean, depth: number, columnPages: { count: number }): Segment[] {\n const byTop = [...items].sort((a, b) => b.top - a.top || a.x0 - b.x0);\n if (!detectColumns || items.length < 2 || depth > MAX_DEPTH) return [{ kind: \"flow\", items: byTop }];\n const left = minOf(items, (f) => f.x0);\n const right = maxOf(items, (f) => f.x1);\n const width = right - left;\n const isNarrow = (f: Frag) => f.x1 - f.x0 < width * 0.55;\n const narrow = items.filter(isNarrow);\n const minGutter = Math.max(body * 0.9, 6);\n // Sweep the narrow items' horizontal coverage. A gutter is an interior strip\n // crossed by (almost) no narrow item: a few stray lines crossing a table's\n // column gap must not hide it.\n const allowed = Math.max(1, Math.floor(narrow.length * 0.08));\n const events: [number, number][] = [];\n for (const f of narrow) events.push([f.x0, 1], [f.x1, -1]);\n events.sort((a, b) => a[0] - b[0] || a[1] - b[1]);\n const candidates: [number, number][] = [];\n let depthNow = 0;\n let seenContent = false;\n let start: number | null = null;\n for (const [x, delta] of events) {\n depthNow += delta;\n if (depthNow > allowed) {\n if (start !== null && seenContent && x - start >= minGutter) candidates.push([start, x]);\n start = null;\n seenContent = true;\n } else if (start === null) start = x;\n }\n // Shrink each strip to the items that end or start inside it: only items\n // crossing it entirely are strays.\n const ends = narrow.map((f) => f.x1).sort((a, b) => a - b);\n const starts = narrow.map((f) => f.x0).sort((a, b) => a - b);\n const gutters: [number, number][] = [];\n for (const [a, b] of candidates) {\n const endBelow = lowerBound(ends, b) - 1;\n const left = endBelow >= 0 && ends[endBelow] > a ? ends[endBelow] : a;\n const startAbove = lowerBound(starts, a + 1e-9);\n const right = startAbove < starts.length && starts[startAbove] < b ? starts[startAbove] : b;\n if (right - left < minGutter) continue;\n // Strays must be fewer than the fragments on either side, or the \"gutter\"\n // is just the ragged end of one long line.\n const onLeft = lowerBound(ends, left + 1e-6);\n const onRight = starts.length - lowerBound(starts, right - 1e-6);\n const strays = narrow.length - onLeft - onRight;\n if (strays < Math.min(onLeft, onRight)) gutters.push([left, right]);\n }\n if (!gutters.length) return [{ kind: \"flow\", items: byTop }];\n const gutterEnds = gutters.map((g) => g[1]);\n // The first gutter ending right of x0; the item crosses it if it reaches past its start.\n const crosses = (f: Frag) => {\n const k = lowerBound(gutterEnds, f.x0 + 1 + 1e-9);\n return k < gutters.length && f.x1 > gutters[k][0] + 1 && f.x0 < gutters[k][1] - 1;\n };\n const columnOf = (f: Frag) => lowerBound(gutterEnds, f.x0 + 1 + 1e-9);\n\n // Bands: runs of non-crossing items between crossing ones.\n const bands: { spanning: boolean; items: Frag[] }[] = [];\n for (const f of byTop) {\n const spanning = crosses(f);\n const band = bands[bands.length - 1];\n if (band && band.spanning === spanning) band.items.push(f);\n else bands.push({ spanning, items: [f] });\n }\n const segments: Segment[] = [];\n /** Column segments are sealed so the next band does not merge into the last column. */\n let sealed = false;\n const pushFlow = (list: Frag[]) => {\n if (!list.length) return;\n const last = segments[segments.length - 1];\n if (last && last.kind === \"flow\" && !sealed) last.items.push(...list);\n else segments.push({ kind: \"flow\", items: list });\n sealed = false;\n };\n let multiColumn = false;\n /** A short line crossing the gutters: a spanning header or totals row of a table. */\n const isShortSpan = (f: Frag) => !f.table && isNarrow(f) && f.words <= 8;\n for (const band of bands) {\n const last = segments[segments.length - 1];\n if (band.spanning) {\n const lead = band.items[0];\n if (last && last.kind === \"grid\" && isShortSpan(lead) && minOf(last.items, (f) => f.bottom) - lead.top <= lead.size * 2) {\n last.items.push(lead);\n pushFlow(band.items.slice(1));\n } else pushFlow(band.items);\n continue;\n }\n const columns: Frag[][] = Array.from({ length: gutters.length + 1 }, () => []);\n band.items.forEach((f) => columns[columnOf(f)].push(f));\n const used = columns.filter((c) => c.length);\n if (used.length < 2) {\n pushFlow(band.items);\n continue;\n }\n const prose = used.every((col) => {\n const text = col.filter((f) => !f.table);\n if (text.length < 2) return text.length === 0;\n const colLeft = minOf(text, (f) => f.x0);\n const colRight = maxOf(text, (f) => f.x1);\n const fill = text.reduce((sum, f) => sum + (f.x1 - f.x0), 0) / text.length / Math.max(1, colRight - colLeft);\n const words = text.reduce((sum, f) => sum + f.words, 0) / text.length;\n return fill >= 0.55 && words >= 3;\n });\n const tops = used.map((col) => [minOf(col, (f) => f.bottom), maxOf(col, (f) => f.top)]);\n const overlapping = tops.every(([b, t], i) => i === 0 || Math.min(t, tops[0][1]) - Math.max(b, tops[0][0]) > 0);\n if (prose && overlapping) {\n multiColumn = true;\n for (const col of used) segments.push(...readingOrder(col, body, detectColumns, depth + 1, columnPages));\n sealed = true;\n continue;\n }\n // A grid band. Pull a short spanning line right above it (a header band) into it,\n // which also re-joins grids split by such a line.\n const pulled: Frag[] = [];\n if (last && last.kind === \"flow\" && !sealed) {\n const tail = last.items[last.items.length - 1];\n if (isShortSpan(tail) && tail.bottom - maxOf(band.items, (f) => f.top) <= tail.size * 2) {\n pulled.push(last.items.pop()!);\n if (!last.items.length) segments.pop();\n }\n }\n const prevSegment = segments[segments.length - 1];\n if (prevSegment && prevSegment.kind === \"grid\" && (pulled.length || prevSegment === last)) {\n prevSegment.items.push(...pulled, ...band.items);\n } else segments.push({ kind: \"grid\", items: [...pulled, ...band.items] });\n sealed = false;\n }\n if (multiColumn && depth === 0) columnPages.count++;\n return segments;\n}\n\n// ---------------------------------------------------------------------------\n// Lines → blocks\n\ninterface Line {\n text: string;\n x0: number;\n x1: number;\n y: number;\n top: number;\n size: number;\n bold: boolean;\n page: number;\n table?: PdfLayoutBlock & { type: \"table\" };\n}\n\nfunction flowLines(items: Frag[], page: number): Line[] {\n const lines: Line[] = [];\n const sorted = [...items].sort((a, b) => b.top - a.top || a.x0 - b.x0);\n for (const f of sorted) {\n if (f.table) {\n lines.push({ text: \"\", x0: f.x0, x1: f.x1, y: f.y, top: f.top, size: f.size, bold: false, page, table: f.table });\n continue;\n }\n const last = lines[lines.length - 1];\n if (last && !last.table && Math.abs(last.y - f.y) <= Math.min(last.size, f.size) * 0.5) {\n last.text = `${last.text} ${f.text}`;\n last.x0 = Math.min(last.x0, f.x0);\n last.x1 = Math.max(last.x1, f.x1);\n } else {\n lines.push({ text: f.text, x0: f.x0, x1: f.x1, y: f.y, top: f.top, size: f.size, bold: f.bold, page });\n }\n }\n return lines;\n}\n\nfunction joinLines(prev: string, next: string, dehyphenate: boolean, stats: { dehyphenated: number }): string {\n if (prev.endsWith(\"­\")) {\n stats.dehyphenated++;\n return prev.slice(0, -1) + next;\n }\n if (dehyphenate && /[A-Za-zÀ-ɏ]-$/.test(prev) && /^[a-zß-ɏ]/.test(next)) {\n stats.dehyphenated++;\n return prev.slice(0, -1) + next;\n }\n return `${prev} ${next}`;\n}\n\ntype MarkerKind = \"glyph\" | \"dash\" | \"num\" | \"alpha\" | \"roman\";\n\nfunction listMarker(text: string): { kind: MarkerKind; rest: string; ordered: boolean; value?: number } | null {\n const glyph = BULLET_GLYPH_RE.exec(text);\n if (glyph) return { kind: \"glyph\", rest: text.slice(glyph[0].length), ordered: false };\n const dash = BULLET_DASH_RE.exec(text);\n if (dash) return { kind: \"dash\", rest: text.slice(dash[0].length), ordered: false };\n const ordered = ORDERED_RE.exec(text);\n if (ordered) {\n const token = ordered[1] ?? ordered[2];\n const kind: MarkerKind = /^\\d+$/.test(token) ? \"num\" : /^[ivxlc]{2,}$/i.test(token) || /^i$/i.test(token) ? \"roman\" : \"alpha\";\n return { kind, rest: text.slice(ordered[0].length), ordered: true, value: kind === \"num\" ? Number(token) : undefined };\n }\n return null;\n}\n\ninterface BuildContext {\n body: number;\n boldBody: boolean;\n pitch: (size: number) => number;\n options: Required<PdfLayoutOptions>;\n stats: { dehyphenated: number };\n blocks: PdfLayoutBlock[];\n /** Heading candidates waiting for levels: block plus its style key. */\n headings: { block: PdfLayoutBlock & { type: \"heading\" }; key: number; boldOnly: boolean }[];\n /** The paragraph that may continue in the next segment. */\n open: { block: PdfLayoutBlock & { type: \"paragraph\" }; size: number; lastText: string } | null;\n}\n\nfunction headingStyle(\n line: Line,\n next: Line | undefined,\n segRight: number,\n ctx: BuildContext,\n): { key: number; confidence: number; boldOnly: boolean } | null {\n if (!ctx.options.detectHeadings || line.table) return null;\n const text = line.text;\n const words = countWords(text);\n if (text.length > 200 || words > 25 || !/\\p{L}/u.test(text)) return null;\n // A long sentence in a larger font is a lede paragraph, not a heading.\n if (words > 15 && SENTENCE_END_RE.test(text)) return null;\n const ratio = line.size / ctx.body;\n if (ratio >= 1.15) {\n const confidence = Math.min(0.95, 0.6 + (ratio - 1.15) * 0.8 + (line.bold ? 0.1 : 0));\n return { key: Math.round(line.size * 2) / 2 + (line.bold ? 0.25 : 0), confidence, boldOnly: false };\n }\n // A bold line that fills the column and runs on into more bold text is a bold paragraph.\n const runsOn =\n !!next && !next.table && next.bold && Math.abs(next.size - line.size) < 0.5 && line.x1 >= segRight - 2 * line.size;\n if (line.bold && !ctx.boldBody && !runsOn && ratio >= 0.95 && text.length <= 100 && !/[.,;]$/.test(text)) {\n return { key: Math.round(line.size * 2) / 2 + 0.25, confidence: 0.6, boldOnly: true };\n }\n return null;\n}\n\n/** Turns one flow segment's lines into blocks. */\nfunction buildBlocks(lines: Line[], ctx: BuildContext) {\n const textLines = lines.filter((l) => !l.table);\n const segLeft = textLines.length ? minOf(textLines, (l) => l.x0) : 0;\n const segRight = textLines.length ? maxOf(textLines, (l) => l.x1) : 0;\n // Marker kinds that need company (two items) before they count as a list.\n const kindCounts = new Map<MarkerKind, number>();\n const markers = lines.map((line) => {\n if (!ctx.options.detectLists || line.table) return null;\n const marker = listMarker(line.text);\n if (marker) kindCounts.set(marker.kind, (kindCounts.get(marker.kind) ?? 0) + 1);\n return marker;\n });\n let list: (PdfLayoutBlock & { type: \"list\" }) | null = null;\n let listStack: number[] = [];\n let lastItemLine: Line | null = null;\n let para: { block: PdfLayoutBlock & { type: \"paragraph\" }; lines: Line[] } | null = null;\n let heading: { block: PdfLayoutBlock & { type: \"heading\" }; line: Line; key: number; lines: number } | null = null;\n\n const closeAll = () => {\n if (para) {\n const last = para.lines[para.lines.length - 1];\n const ended = SENTENCE_END_RE.test(last.text) || last.x1 < segRight - 3 * last.size;\n ctx.open = ended ? null : { block: para.block, size: last.size, lastText: para.block.text };\n } else ctx.open = null;\n para = null;\n list = null;\n listStack = [];\n lastItemLine = null;\n heading = null;\n };\n\n lines.forEach((line, index) => {\n const prev = index > 0 ? lines[index - 1] : null;\n if (line.table) {\n closeAll();\n ctx.open = null;\n ctx.blocks.push(line.table);\n return;\n }\n const style = headingStyle(line, lines[index + 1], segRight, ctx);\n if (style) {\n // Consecutive lines in the same heading style form one heading.\n if (\n heading &&\n heading.key === style.key &&\n heading.lines < 3 &&\n prev === heading.line &&\n prev.y - line.y <= line.size * 1.6\n ) {\n heading.block.text = joinLines(heading.block.text, line.text, ctx.options.dehyphenate, ctx.stats);\n heading.line = line;\n heading.lines++;\n return;\n }\n closeAll();\n ctx.open = null;\n const block: PdfLayoutBlock & { type: \"heading\" } = { type: \"heading\", level: 1, text: line.text, page: line.page, confidence: style.confidence };\n ctx.blocks.push(block);\n ctx.headings.push({ block, key: style.key, boldOnly: style.boldOnly });\n heading = { block, line, key: style.key, lines: 1 };\n return;\n }\n heading = null;\n\n const marker = markers[index];\n const validMarker = marker && (marker.kind === \"glyph\" || (kindCounts.get(marker.kind) ?? 0) >= 2) && marker.rest.trim() !== \"\";\n if (validMarker) {\n const gapOk = lastItemLine && lastItemLine.y - line.y <= Math.max(ctx.pitch(line.size) * 2.2, line.size * 2.4);\n if (!list || !gapOk) {\n closeAll();\n ctx.open = null;\n list = { type: \"list\", page: line.page, confidence: 0.6, items: [] };\n ctx.blocks.push(list);\n listStack = [line.x0];\n }\n const tol = line.size * 0.5;\n while (listStack.length > 1 && line.x0 < listStack[listStack.length - 1] - tol) listStack.pop();\n if (line.x0 > listStack[listStack.length - 1] + tol) listStack.push(line.x0);\n else listStack[listStack.length - 1] = Math.min(listStack[listStack.length - 1], line.x0);\n const prevDepth = list.items.length ? list.items[list.items.length - 1].depth : -1;\n const depth = Math.min(listStack.length - 1, prevDepth + 1);\n const item: { text: string; depth: number; ordered: boolean; start?: number } = {\n text: collapse(marker!.rest),\n depth,\n ordered: marker!.ordered,\n };\n if (marker!.value !== undefined) item.start = marker!.value;\n list.items.push(item);\n list.confidence = Math.min(0.95, (marker!.kind === \"glyph\" ? 0.75 : 0.6) + 0.05 * list.items.length);\n lastItemLine = line;\n para = null;\n return;\n }\n if (list && lastItemLine && prev) {\n // Hanging-indent continuation of the last item.\n const markerX = listStack[listStack.length - 1];\n const continues =\n line.x0 > markerX + line.size * 0.3 &&\n line.x0 <= markerX + line.size * 5 &&\n prev.y - line.y <= ctx.pitch(line.size) * ctx.options.paragraphGap;\n if (continues) {\n const item = list.items[list.items.length - 1];\n item.text = joinLines(item.text, line.text, ctx.options.dehyphenate, ctx.stats);\n lastItemLine = line;\n return;\n }\n closeAll();\n }\n\n // Paragraph continuation from the previous segment (next column or page).\n if (!para && ctx.open && index === 0 && /^[a-z]/.test(line.text) && Math.abs(ctx.open.size - line.size) <= line.size * 0.12) {\n ctx.open.block.text = joinLines(ctx.open.block.text, line.text, ctx.options.dehyphenate, ctx.stats);\n para = { block: ctx.open.block, lines: [line] };\n ctx.open = null;\n return;\n }\n if (para && prev && !prev.table) {\n const last = para.lines[para.lines.length - 1];\n const gap = last.y - line.y;\n const sameSize = Math.abs(last.size - line.size) <= last.size * 0.12;\n const closeEnough = gap > 0 && gap <= ctx.pitch(line.size) * ctx.options.paragraphGap;\n const indentEm = line.size * 0.8;\n const indented = line.x0 - segLeft >= indentEm && last.x0 - segLeft < indentEm && line.x0 - segLeft < line.size * 8;\n const shortEnded = last.x1 < segRight - 3 * last.size && SENTENCE_END_RE.test(last.text);\n if (sameSize && closeEnough && !indented && !shortEnded) {\n para.block.text = joinLines(para.block.text, line.text, ctx.options.dehyphenate, ctx.stats);\n para.lines.push(line);\n return;\n }\n }\n closeAll();\n ctx.open = null;\n const block: PdfLayoutBlock & { type: \"paragraph\" } = { type: \"paragraph\", text: line.text, page: line.page };\n ctx.blocks.push(block);\n para = { block, lines: [line] };\n });\n closeAll();\n}\n\n/** Assigns heading levels by rank of style: larger first, bold before regular. */\nfunction assignHeadingLevels(headings: BuildContext[\"headings\"]) {\n const keys = Array.from(new Set(headings.map((h) => h.key))).sort((a, b) => b - a);\n const levelOf = new Map(keys.map((key, i) => [key, Math.min(6, i + 1) as 1 | 2 | 3 | 4 | 5 | 6]));\n headings.forEach((h) => {\n h.block.level = levelOf.get(h.key)!;\n });\n}\n\n// ---------------------------------------------------------------------------\n// Entry point\n\nconst DEFAULTS: Required<PdfLayoutOptions> = {\n paragraphGap: 1.4,\n removeHeadersAndFooters: true,\n detectColumns: true,\n detectHeadings: true,\n detectLists: true,\n detectTables: true,\n dehyphenate: true,\n};\n\n/**\n * Analyses positioned text runs (one entry per page) and returns blocks in\n * reading order plus a report of what was detected.\n */\nexport function analyzePdfLayout(pages: readonly PdfLayoutPage[], options: PdfLayoutOptions = {}): PdfLayoutResult {\n const opts: Required<PdfLayoutOptions> = { ...DEFAULTS };\n (Object.keys(options) as (keyof PdfLayoutOptions)[]).forEach((key) => {\n if (options[key] !== undefined) (opts as any)[key] = options[key];\n });\n const fragPages = pages.map((page) => buildFragments(page.runs ?? []));\n const removed = opts.removeHeadersAndFooters ? removeHeadersAndFooters(fragPages) : { headers: 0, footers: 0, pageNumbers: 0 };\n\n // Body size: the size most characters are set in.\n const bySize = new Map<number, number>();\n let boldChars = 0;\n let totalChars = 0;\n fragPages.flat().forEach((f) => {\n const key = Math.round(f.size * 2) / 2;\n bySize.set(key, (bySize.get(key) ?? 0) + f.text.length);\n });\n let body = 10;\n let bodyChars = -1;\n bySize.forEach((chars, size) => {\n if (chars > bodyChars) {\n body = size;\n bodyChars = chars;\n }\n });\n fragPages.flat().forEach((f) => {\n if (Math.abs(f.size - body) <= body * 0.05) {\n totalChars += f.text.length;\n if (f.bold) boldChars += f.text.length;\n }\n });\n // Typical baseline pitch per size, from consecutive rows on each page.\n const pitches = new Map<number, number[]>();\n fragPages.forEach((frags) => {\n const rows = baselineRows([...frags].sort((a, b) => b.y - a.y || a.x0 - b.x0));\n for (let k = 1; k < rows.length; k++) {\n const a = rows[k - 1][0];\n const b = rows[k][0];\n if (Math.abs(a.size - b.size) > 0.5) continue;\n const d = a.y - b.y;\n if (d > 0 && d < a.size * 3) {\n const key = Math.round(b.size * 2) / 2;\n if (!pitches.has(key)) pitches.set(key, []);\n pitches.get(key)!.push(d);\n }\n }\n });\n const pitchMedians = new Map<number, number>();\n pitches.forEach((values, key) => pitchMedians.set(key, median(values)));\n\n const stats = { dehyphenated: 0 };\n const ctx: BuildContext = {\n body,\n boldBody: totalChars > 0 && boldChars / totalChars > 0.5,\n pitch: (size) => {\n const known = pitchMedians.get(Math.round(size * 2) / 2);\n return known && known >= size * 0.9 ? known : size * 1.2;\n },\n options: opts,\n stats,\n blocks: [],\n headings: [],\n open: null,\n };\n const columnPages = { count: 0 };\n const items: ImportStructureItem[] = [];\n\n fragPages.forEach((frags, pageIndex) => {\n const page = pageIndex + 1;\n let flowFrags = frags;\n const atoms: Frag[] = [];\n if (opts.detectTables && pages[pageIndex].rules?.length) {\n const ruled = ruledTables(frags, pages[pageIndex].rules!, page, opts.dehyphenate, stats);\n flowFrags = frags.filter((f) => !ruled.consumed.has(f));\n atoms.push(...ruled.atoms);\n }\n const before = columnPages.count;\n const segments = readingOrder([...flowFrags, ...atoms], body, opts.detectColumns, 0, columnPages);\n if (columnPages.count > before) items.push({ type: \"columns\", page, confidence: 0.8, detail: \"multi-column layout\" });\n // Rows peeled off a grid (a paragraph's last line, a caption) go back to the neighbouring flow.\n const units: ({ kind: \"flow\"; items: Frag[] } | { kind: \"table\"; table: PdfLayoutBlock & { type: \"table\" } })[] = [];\n let carry: Frag[] = [];\n for (const segment of segments) {\n if (segment.kind === \"grid\" && opts.detectTables) {\n const result = alignedTable(segment.items.filter((f) => !f.table), page, 3, opts.dehyphenate, stats);\n if (result) {\n const last = units[units.length - 1];\n if (result.before.length && last && last.kind === \"flow\") last.items.push(...carry, ...result.before);\n else if (result.before.length || carry.length) units.push({ kind: \"flow\", items: [...carry, ...result.before] });\n units.push({ kind: \"table\", table: result.table });\n carry = [...segment.items.filter((f) => f.table), ...result.leftover];\n continue;\n }\n }\n units.push({ kind: \"flow\", items: [...carry, ...segment.items] });\n carry = [];\n }\n if (carry.length) units.push({ kind: \"flow\", items: carry });\n for (const unit of units) {\n if (unit.kind === \"table\") {\n ctx.open = null;\n ctx.blocks.push(unit.table);\n } else buildBlocks(flowLines(unit.items, page), ctx);\n }\n });\n assignHeadingLevels(ctx.headings);\n\n const counts = { headings: 0, lists: 0, tables: 0, paragraphs: 0 };\n const confidences: number[] = [];\n ctx.blocks.forEach((block) => {\n if (block.type === \"heading\") {\n counts.headings++;\n confidences.push(block.confidence);\n items.push({ type: \"heading\", page: block.page, confidence: block.confidence, detail: `H${block.level} \"${truncate(block.text)}\"` });\n } else if (block.type === \"list\") {\n counts.lists++;\n confidences.push(block.confidence);\n const depth = maxOf(block.items, (i) => i.depth) + 1;\n items.push({\n type: \"list\",\n page: block.page,\n confidence: block.confidence,\n detail: `${block.items[0]?.ordered ? \"numbered\" : \"bulleted\"} list, ${block.items.length} items${depth > 1 ? `, ${depth} levels` : \"\"}`,\n });\n } else if (block.type === \"table\") {\n counts.tables++;\n confidences.push(block.confidence);\n items.push({\n type: \"table\",\n page: block.page,\n confidence: block.confidence,\n detail: `${block.rows.length}×${block.columns} table${block.ruled ? \" (ruled)\" : \"\"}${block.headerRows ? \", header row\" : \"\"}`,\n });\n } else counts.paragraphs++;\n });\n items.sort((a, b) => a.page - b.page);\n return {\n blocks: ctx.blocks,\n report: {\n mode: \"structured\",\n pages: pages.length,\n counts,\n multiColumnPages: columnPages.count,\n confidence: confidences.length ? Math.round((confidences.reduce((a, b) => a + b, 0) / confidences.length) * 100) / 100 : 1,\n items,\n removed,\n dehyphenated: stats.dehyphenated,\n },\n };\n}\n\nconst truncate = (text: string) => (text.length > 60 ? `${text.slice(0, 57)}…` : text);\n\n// ---------------------------------------------------------------------------\n// HTML\n\nfunction listHtml(items: { text: string; depth: number; ordered: boolean; start?: number }[]): string {\n let html = \"\";\n const stack: (\"ul\" | \"ol\")[] = [];\n for (const item of items) {\n const level = item.depth + 1;\n while (stack.length > level) html += `</li></${stack.pop()}>`;\n const tag = item.ordered ? \"ol\" : \"ul\";\n if (stack.length === level) {\n if (stack[stack.length - 1] !== tag) {\n html += `</li></${stack.pop()}>`;\n } else html += \"</li>\";\n }\n while (stack.length < level) {\n const start = item.ordered && item.start !== undefined && item.start !== 1 ? ` start=\"${item.start}\"` : \"\";\n html += `<${tag}${start}>`;\n stack.push(tag);\n }\n html += `<li><p>${escapeHtml(item.text)}</p>`;\n }\n while (stack.length) html += `</li></${stack.pop()}>`;\n return html;\n}\n\n/** Renders layout blocks as editor HTML (`h1`–`h6`, `p`, `ul`/`ol`, `table`). Text is escaped. */\nexport function pdfLayoutBlocksToHtml(blocks: readonly PdfLayoutBlock[]): string {\n let html = \"\";\n for (const block of blocks) {\n if (block.type === \"heading\") html += `<h${block.level}>${escapeHtml(block.text)}</h${block.level}>`;\n else if (block.type === \"paragraph\") html += `<p>${escapeHtml(block.text)}</p>`;\n else if (block.type === \"list\") html += listHtml(block.items);\n else {\n html += \"<table><tbody>\";\n for (const row of block.rows) {\n html += \"<tr>\";\n for (const cell of row) {\n const tag = cell.header ? \"th\" : \"td\";\n const attrs = `${cell.colSpan > 1 ? ` colspan=\"${cell.colSpan}\"` : \"\"}${cell.rowSpan > 1 ? ` rowspan=\"${cell.rowSpan}\"` : \"\"}`;\n html += `<${tag}${attrs}><p>${escapeHtml(cell.text)}</p></${tag}>`;\n }\n html += \"</tr>\";\n }\n html += \"</tbody></table>\";\n }\n }\n return html || \"<p></p>\";\n}\n","import { plainTextToParagraphHtml, sanitizeImportedHtml } from \"../serializers/html\";\nimport { htmlToPlainText } from \"../serializers/plain-text\";\nimport type { DocumentImport } from \"./adapters\";\nimport type { ImportAdapter } from \"./registry\";\nimport {\n analyzePdfLayout,\n pdfLayoutBlocksToHtml,\n type PdfLayoutOptions,\n type PdfLayoutPage,\n type PdfRuleLine,\n type PdfStructureReport,\n type PdfTextRun,\n} from \"./pdf-layout\";\n\n/**\n * PDF import through an injected pdf.js-compatible library. The editor ships\n * no PDF parser; consumers that already bundle `pdfjs-dist` register the\n * adapter themselves:\n *\n * ```ts\n * import * as pdfjs from \"pdfjs-dist\";\n * registerImportAdapter(createPdfImportAdapter(pdfjs));\n * ```\n *\n * By default the text runs (with positions and fonts) and the page's ruling\n * lines go through `analyzePdfLayout`, which recovers reading order across\n * columns, headings, lists and tables, and drops running headers, footers and\n * page numbers. `structure: false` (at creation, or per import through\n * `adapterOptions: { pdf: { structure: false } }`) falls back to plain\n * paragraphs: items grouped into lines by baseline and lines into paragraphs\n * by vertical gaps. Images, links and character styling are not imported.\n */\n\n/** A text item from `page.getTextContent()` (marked-content items have no `str`). */\nexport interface PdfJsTextItem {\n str: string;\n /** `[a, b, c, d, x, y]` transform; `x` / `y` are the baseline origin. */\n transform?: readonly number[];\n width?: number;\n height?: number;\n /** pdf.js sets this when a line break follows the item. */\n hasEOL?: boolean;\n /** Font resource id, e.g. `g_d0_f1` (see `PdfJsTextContent.styles` and `page.commonObjs`). */\n fontName?: string;\n}\n\nexport interface PdfJsTextContent {\n items: ReadonlyArray<PdfJsTextItem | { type: string }>;\n /** Per `fontName`: pdf.js reports the family (sometimes the real font name). */\n styles?: Record<string, { fontFamily?: string } | undefined>;\n}\n\n/** pdf.js operator list (`page.getOperatorList()`). */\nexport interface PdfJsOperatorList {\n fnArray: ArrayLike<number>;\n argsArray: ArrayLike<unknown>;\n}\n\nexport interface PdfJsPage {\n getTextContent(): Promise<PdfJsTextContent>;\n /** Used to read ruling lines (table borders); optional. */\n getOperatorList?(): Promise<PdfJsOperatorList>;\n /** Loaded fonts: `get(fontName)` returns `{ name, bold, black, italic }` once the operator list was read. */\n commonObjs?: { has?(id: string): boolean; get(id: string): unknown };\n cleanup?(): unknown;\n}\n\nexport interface PdfJsDocument {\n numPages: number;\n getPage(pageNumber: number): Promise<PdfJsPage>;\n destroy?(): unknown;\n}\n\n/** The subset of the pdf.js API the adapter uses (`pdfjs-dist` satisfies it). */\nexport interface PdfJsLike {\n getDocument(source: { data: Uint8Array; [option: string]: unknown }): { promise: Promise<PdfJsDocument> };\n /** pdf.js operator codes (`pdfjs.OPS`); the classic values are assumed when missing. */\n OPS?: Record<string, number>;\n}\n\nexport interface PdfTextOptions {\n /**\n * A line gap larger than this multiple of the page's typical line spacing\n * starts a new paragraph (default `1.4`).\n */\n paragraphGap?: number;\n}\n\n/** Options that may also be passed per import as `adapterOptions[adapterId]`. */\nexport interface PdfImportCallOptions extends PdfTextOptions {\n /**\n * Detect headings, lists, tables, columns and running headers (default\n * `true`). `false` imports plain paragraphs, as before structure detection.\n */\n structure?: boolean;\n /** Fine-tuning for `analyzePdfLayout`. */\n layout?: PdfLayoutOptions;\n /** Read the operator list for table rules and font weights (default `true`). */\n rulingLines?: boolean;\n}\n\nexport interface PdfImportOptions extends PdfImportCallOptions {\n /** Adapter id (default `\"pdf\"`). */\n id?: string;\n /** Import at most this many pages (default: all). */\n maxPages?: number;\n /** Extra `getDocument` parameters, e.g. `{ disableFontFace: true }`. */\n documentParams?: Record<string, unknown>;\n}\n\n/** What the PDF adapter returns: a `DocumentImport` with its structure report. */\nexport interface PdfDocumentImport extends DocumentImport {\n structure: PdfStructureReport;\n}\n\ninterface Line {\n text: string;\n y: number;\n height: number;\n /** A blank line (empty `hasEOL` item) follows this one. */\n blankAfter: boolean;\n}\n\nconst isTextItem = (item: PdfJsTextItem | { type: string }): item is PdfJsTextItem =>\n typeof (item as PdfJsTextItem).str === \"string\";\n\nfunction median(values: number[]): number {\n if (!values.length) return 0;\n const sorted = [...values].sort((a, b) => a - b);\n const mid = sorted.length >> 1;\n return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;\n}\n\nfunction groupLines(items: ReadonlyArray<PdfJsTextItem | { type: string }>): Line[] {\n const lines: Line[] = [];\n let current: (Line & { endX?: number }) | null = null;\n let breakNext = false;\n for (const item of items) {\n if (!isTextItem(item)) continue;\n const x = item.transform?.[4] ?? 0;\n const y: number = item.transform?.[5] ?? (current?.y ?? 0);\n const height: number = item.height || Math.abs(item.transform?.[3] ?? 0) || current?.height || 10;\n const tolerance = Math.max(1, height * 0.5);\n if (!item.str) {\n // Empty items mark line ends; two in a row mean a blank line.\n if (item.hasEOL) {\n if (breakNext && current) current.blankAfter = true;\n breakNext = true;\n }\n continue;\n }\n if (!current || breakNext || Math.abs(y - current.y) > tolerance) {\n current = { text: \"\", y, height, blankAfter: false };\n lines.push(current);\n } else if (current.endX !== undefined && x - current.endX > height * 0.15) {\n // A horizontal gap without an explicit space item.\n if (!/\\s$/.test(current.text) && !/^\\s/.test(item.str)) current.text += \" \";\n }\n current.text += item.str;\n current.height = Math.max(current.height, height);\n current.endX = item.width !== undefined ? x + item.width : undefined;\n breakNext = !!item.hasEOL;\n }\n return lines;\n}\n\n/**\n * Groups one page's pdf.js text items into paragraphs. Exposed for custom\n * adapters and tests.\n */\nexport function pdfTextItemsToParagraphs(\n items: ReadonlyArray<PdfJsTextItem | { type: string }>,\n options: PdfTextOptions = {},\n): string[] {\n const lines = groupLines(items).filter((line) => line.text.trim() || line.blankAfter);\n const gaps: number[] = [];\n for (let i = 1; i < lines.length; i++) {\n const gap = lines[i - 1].y - lines[i].y;\n if (gap > 0) gaps.push(gap);\n }\n const typical = median(gaps);\n const factor = options.paragraphGap ?? 1.4;\n\n const paragraphs: string[] = [];\n let current: string[] = [];\n const flush = () => {\n const text = current.join(\" \").replace(/\\s+/g, \" \").trim();\n if (text) paragraphs.push(text);\n current = [];\n };\n lines.forEach((line, i) => {\n if (i > 0) {\n const prev = lines[i - 1];\n const gap = prev.y - line.y;\n const bigGap = typical > 0 ? gap > typical * factor : gap > prev.height * 1.8;\n // A line above the previous one (gap < 0) starts a new column or block.\n if (prev.blankAfter || bigGap || gap < -prev.height * 0.5) flush();\n }\n const text = line.text.trim();\n if (!text) return;\n if (current.length && /\\w-$/.test(current[current.length - 1]) && /^[a-z]/.test(text)) {\n // Re-join words hyphenated across lines.\n current[current.length - 1] = current[current.length - 1].slice(0, -1) + text;\n } else {\n current.push(text);\n }\n });\n flush();\n return paragraphs;\n}\n\n/** Font details pdf.js exposes for a text item's `fontName`. */\nexport interface PdfFontInfo {\n name?: string;\n bold?: boolean;\n italic?: boolean;\n}\n\n/**\n * Converts pdf.js text items to layout runs. `font` resolves a `fontName` to\n * its real name and weight (the adapter reads `page.commonObjs` and\n * `textContent.styles`).\n */\nexport function pdfTextItemsToRuns(\n items: ReadonlyArray<PdfJsTextItem | { type: string }>,\n font?: (fontName: string) => PdfFontInfo | undefined,\n): PdfTextRun[] {\n const runs: PdfTextRun[] = [];\n const cache = new Map<string, PdfFontInfo | undefined>();\n for (const item of items) {\n if (!isTextItem(item) || !item.str.trim()) continue;\n const t = item.transform ?? [];\n const fontSize = Math.hypot(t[2] ?? 0, t[3] ?? 0) || item.height || 10;\n let info: PdfFontInfo | undefined;\n if (item.fontName && font) {\n if (!cache.has(item.fontName)) cache.set(item.fontName, font(item.fontName));\n info = cache.get(item.fontName);\n }\n runs.push({\n text: item.str,\n x: t[4] ?? 0,\n y: t[5] ?? 0,\n width: item.width,\n fontSize,\n fontName: info?.name ?? item.fontName,\n bold: info?.bold,\n italic: info?.italic,\n });\n }\n return runs;\n}\n\n/** pdf.js operator codes (stable since pdf.js 2). */\nconst DEFAULT_OPS: Record<string, number> = {\n save: 10,\n restore: 11,\n transform: 12,\n moveTo: 13,\n lineTo: 14,\n curveTo: 15,\n curveTo2: 16,\n curveTo3: 17,\n closePath: 18,\n rectangle: 19,\n stroke: 20,\n closeStroke: 21,\n fill: 22,\n eoFill: 23,\n fillStroke: 24,\n eoFillStroke: 25,\n closeFillStroke: 26,\n closeEOFillStroke: 27,\n endPath: 28,\n constructPath: 91,\n};\n/** Path codes inside a pdf.js 5 `constructPath` buffer. */\nconst DRAW_OPS = { moveTo: 0, lineTo: 1, curveTo: 2, quadraticCurveTo: 3, closePath: 4 };\nconst MAX_PAGE_RULES = 5000;\n\ntype Matrix = [number, number, number, number, number, number];\nconst IDENTITY: Matrix = [1, 0, 0, 1, 0, 0];\nconst multiply = (m: Matrix, c: Matrix): Matrix => [\n m[0] * c[0] + m[1] * c[2],\n m[0] * c[1] + m[1] * c[3],\n m[2] * c[0] + m[3] * c[2],\n m[2] * c[1] + m[3] * c[3],\n m[4] * c[0] + m[5] * c[2] + c[4],\n m[4] * c[1] + m[5] * c[3] + c[5],\n];\nconst apply = (m: Matrix, x: number, y: number): [number, number] => [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];\n\n/**\n * Reads straight, axis-aligned strokes and thin filled bars (table rules)\n * from a pdf.js operator list, in PDF user space. Understands the classic\n * `constructPath` arguments (`[ops, args, minMax]`) and the pdf.js 5 form\n * (`[paintOp, [pathData], minMax]`); clipping paths and curves are ignored.\n */\nexport function pdfOperatorListToRules(list: PdfJsOperatorList, opsTable?: Record<string, number>): PdfRuleLine[] {\n const OPS = { ...DEFAULT_OPS, ...(opsTable ?? {}) };\n const stroking = new Set([OPS.stroke, OPS.closeStroke, OPS.fillStroke, OPS.eoFillStroke, OPS.closeFillStroke, OPS.closeEOFillStroke]);\n const filling = new Set([OPS.fill, OPS.eoFill, OPS.fillStroke, OPS.eoFillStroke, OPS.closeFillStroke, OPS.closeEOFillStroke]);\n const rules: PdfRuleLine[] = [];\n const stack: Matrix[] = [];\n let ctm: Matrix = IDENTITY;\n /** Path pieces waiting for a paint operator. */\n let lines: [number, number, number, number][] = [];\n let rects: [number, number, number, number][] = [];\n const num = (value: unknown) => (typeof value === \"number\" && Number.isFinite(value) ? value : NaN);\n\n const addLine = (x1: number, y1: number, x2: number, y2: number) => {\n const [a, b] = apply(ctm, x1, y1);\n const [c, d] = apply(ctm, x2, y2);\n lines.push([a, b, c, d]);\n };\n const addRect = (x: number, y: number, w: number, h: number) => {\n const corners = [apply(ctm, x, y), apply(ctm, x + w, y), apply(ctm, x + w, y + h), apply(ctm, x, y + h)];\n const xs = corners.map((p) => p[0]);\n const ys = corners.map((p) => p[1]);\n rects.push([Math.min(...xs), Math.min(...ys), Math.max(...xs), Math.max(...ys)]);\n };\n const paint = (op: number) => {\n const stroke = stroking.has(op);\n const fill = filling.has(op);\n if (stroke) {\n for (const [x1, y1, x2, y2] of lines) rules.push({ x1, y1, x2, y2 });\n for (const [x0, y0, x1, y1] of rects) {\n rules.push({ x1: x0, y1: y0, x2: x1, y2: y0 }, { x1: x0, y1: y1, x2: x1, y2: y1 });\n rules.push({ x1: x0, y1: y0, x2: x0, y2: y1 }, { x1: x1, y1: y0, x2: x1, y2: y1 });\n }\n } else if (fill) {\n // Thin filled bars are drawn rules; larger fills are shading.\n for (const [x0, y0, x1, y1] of rects) {\n if (y1 - y0 <= 2 && x1 - x0 > 2) rules.push({ x1: x0, y1: (y0 + y1) / 2, x2: x1, y2: (y0 + y1) / 2 });\n else if (x1 - x0 <= 2 && y1 - y0 > 2) rules.push({ x1: (x0 + x1) / 2, y1: y0, x2: (x0 + x1) / 2, y2: y1 });\n }\n }\n lines = [];\n rects = [];\n };\n const readPath = (subOps: ArrayLike<unknown>, subArgs: ArrayLike<unknown>) => {\n let k = 0;\n let cx = 0;\n let cy = 0;\n let sx = 0;\n let sy = 0;\n for (let i = 0; i < subOps.length; i++) {\n const op = subOps[i];\n if (op === OPS.moveTo) {\n cx = sx = num(subArgs[k++]);\n cy = sy = num(subArgs[k++]);\n } else if (op === OPS.lineTo) {\n const x = num(subArgs[k++]);\n const y = num(subArgs[k++]);\n addLine(cx, cy, x, y);\n cx = x;\n cy = y;\n } else if (op === OPS.rectangle) {\n addRect(num(subArgs[k++]), num(subArgs[k++]), num(subArgs[k++]), num(subArgs[k++]));\n } else if (op === OPS.curveTo) {\n k += 4;\n cx = num(subArgs[k++]);\n cy = num(subArgs[k++]);\n } else if (op === OPS.curveTo2 || op === OPS.curveTo3) {\n k += 2;\n cx = num(subArgs[k++]);\n cy = num(subArgs[k++]);\n } else if (op === OPS.closePath) {\n if (cx !== sx || cy !== sy) addLine(cx, cy, sx, sy);\n cx = sx;\n cy = sy;\n }\n }\n };\n const readDrawBuffer = (data: ArrayLike<number>) => {\n let cx = 0;\n let cy = 0;\n let sx = 0;\n let sy = 0;\n for (let k = 0; k < data.length; ) {\n const code = data[k++];\n if (code === DRAW_OPS.moveTo) {\n cx = sx = data[k++];\n cy = sy = data[k++];\n } else if (code === DRAW_OPS.lineTo) {\n const x = data[k++];\n const y = data[k++];\n addLine(cx, cy, x, y);\n cx = x;\n cy = y;\n } else if (code === DRAW_OPS.curveTo) {\n k += 4;\n cx = data[k++];\n cy = data[k++];\n } else if (code === DRAW_OPS.quadraticCurveTo) {\n k += 2;\n cx = data[k++];\n cy = data[k++];\n } else if (code === DRAW_OPS.closePath) {\n if (cx !== sx || cy !== sy) addLine(cx, cy, sx, sy);\n cx = sx;\n cy = sy;\n } else break;\n }\n };\n\n for (let i = 0; i < list.fnArray.length && rules.length < MAX_PAGE_RULES; i++) {\n const fn = list.fnArray[i];\n const args = list.argsArray[i] as ArrayLike<unknown> | null | undefined;\n if (fn === OPS.save) stack.push(ctm);\n else if (fn === OPS.restore) ctm = stack.pop() ?? IDENTITY;\n else if (fn === OPS.transform && args && args.length >= 6) {\n const m = Array.from({ length: 6 }, (_, k) => num(args[k])) as Matrix;\n if (m.every(Number.isFinite)) ctm = multiply(m, ctm);\n } else if (fn === OPS.constructPath && args) {\n const first = args[0];\n if (typeof first === \"number\") {\n // pdf.js 5: the paint operator comes with the path.\n const buffers = args[1] as ArrayLike<ArrayLike<number> | null> | undefined;\n const data = buffers?.[0];\n if (data && typeof data.length === \"number\") readDrawBuffer(data);\n paint(first);\n } else if (first && typeof (first as ArrayLike<unknown>).length === \"number\") {\n readPath(first as ArrayLike<unknown>, (args[1] ?? []) as ArrayLike<unknown>);\n }\n } else if (stroking.has(fn) || filling.has(fn)) paint(fn);\n else if (fn === OPS.endPath) {\n lines = [];\n rects = [];\n }\n }\n return rules.filter((rule) => [rule.x1, rule.y1, rule.x2, rule.y2].every(Number.isFinite));\n}\n\nfunction fontResolver(page: PdfJsPage, content: PdfJsTextContent) {\n return (fontName: string): PdfFontInfo | undefined => {\n let info: PdfFontInfo | undefined;\n try {\n if (page.commonObjs && (!page.commonObjs.has || page.commonObjs.has(fontName))) {\n const font = page.commonObjs.get(fontName) as { name?: string; bold?: boolean; black?: boolean; italic?: boolean } | null;\n if (font && typeof font === \"object\") {\n info = {\n name: typeof font.name === \"string\" ? font.name : undefined,\n bold: font.bold || font.black ? true : undefined,\n italic: font.italic ? true : undefined,\n };\n }\n }\n } catch {\n // Not loaded yet: fall back to the family name below.\n }\n const family = content.styles?.[fontName]?.fontFamily;\n if (!info?.name && family) info = { ...info, name: family };\n return info;\n };\n}\n\nfunction plainReport(paragraphs: number, pages: number): PdfStructureReport {\n return {\n mode: \"plain\",\n pages,\n counts: { headings: 0, lists: 0, tables: 0, paragraphs },\n multiColumnPages: 0,\n confidence: 1,\n items: [],\n removed: { headers: 0, footers: 0, pageNumbers: 0 },\n dehyphenated: 0,\n };\n}\n\n/** Creates a PDF `document` adapter backed by an injected pdf.js-compatible library. */\nexport function createPdfImportAdapter(pdfjs: PdfJsLike, options: PdfImportOptions = {}): ImportAdapter<PdfDocumentImport> {\n return {\n id: options.id ?? \"pdf\",\n label: \"PDF\",\n mimeTypes: [\"application/pdf\"],\n extensions: [\".pdf\"],\n target: \"document\",\n async import(_input, context): Promise<PdfDocumentImport> {\n const call = (context.options && typeof context.options === \"object\" ? context.options : {}) as PdfImportCallOptions;\n const opts: PdfImportOptions = { ...options, ...call, layout: { ...options.layout, ...call.layout } };\n const structured = opts.structure !== false;\n // pdf.js may transfer (detach) the buffer it receives, so pass a copy.\n const data = new Uint8Array((await context.readArrayBuffer()).slice(0));\n const doc = await pdfjs.getDocument({ ...opts.documentParams, data }).promise;\n const paragraphs: string[] = [];\n const layoutPages: PdfLayoutPage[] = [];\n let pages = 0;\n try {\n pages = Math.min(doc.numPages, opts.maxPages ?? Infinity);\n for (let n = 1; n <= pages; n++) {\n const page = await doc.getPage(n);\n if (!structured) {\n const content = await page.getTextContent();\n paragraphs.push(...pdfTextItemsToParagraphs(content.items, opts));\n } else {\n let rules: PdfRuleLine[] = [];\n if (opts.rulingLines !== false && typeof page.getOperatorList === \"function\") {\n try {\n rules = pdfOperatorListToRules(await page.getOperatorList(), pdfjs.OPS);\n } catch {\n rules = [];\n }\n }\n const content = await page.getTextContent();\n layoutPages.push({ runs: pdfTextItemsToRuns(content.items, fontResolver(page, content)), rules });\n }\n page.cleanup?.();\n }\n } finally {\n await doc.destroy?.();\n }\n if (!structured) {\n const text = paragraphs.join(\"\\n\");\n return { html: plainTextToParagraphHtml(text), text, structure: plainReport(paragraphs.length, pages) };\n }\n const layout: PdfLayoutOptions = { ...opts.layout };\n if (layout.paragraphGap === undefined && opts.paragraphGap !== undefined) layout.paragraphGap = opts.paragraphGap;\n const { blocks, report } = analyzePdfLayout(layoutPages, layout);\n const html = sanitizeImportedHtml(pdfLayoutBlocksToHtml(blocks));\n return { html, text: htmlToPlainText(html), structure: report };\n },\n };\n}\n","import { escapeHtml } from \"../serializers/plain-text\";\nimport { defaultImportRegistry, type DocumentImport, type DocumentImportAdapter } from \"./adapters\";\nimport { ImportError, type ImportAdapterRegistry } from \"./registry\";\nimport { readZip, type ZipReadOptions } from \"./zip\";\n\n/**\n * Zipped document exports (Notion, Confluence, Obsidian, static-site dumps):\n * a `.zip` of markdown / HTML / text / DOCX files. Each entry is imported\n * with the registry's other `document` adapters and the results are\n * concatenated, with a heading per file.\n *\n * Not registered by default: `.zip` is a generic container, and claiming\n * every dropped archive as a document would steal drops from other handlers\n * (e.g. attachment uploads). Opt in with\n * `registerImportAdapter(zipImportAdapter)`.\n */\n\nexport interface ZipDocumentImport extends DocumentImport {\n /** Imported entries in document order, with the adapter that handled each. */\n files: { name: string; adapterId: string }[];\n /** Entries that were left out, with the reason. */\n skipped: { name: string; reason: string }[];\n}\n\nexport interface ZipImportOptions {\n /** Adapter id (default `\"zip\"`). */\n id?: string;\n /**\n * Registry used for the entries. Defaults to the registry running the\n * import (`context.registry`), then the default registry.\n */\n registry?: ImportAdapterRegistry;\n /** Add a heading with each file's title before its content (default `true`). */\n headings?: boolean;\n /** Heading level for file titles (default `2`). */\n headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;\n /** Import at most this many files (default 500); the rest are reported as skipped. */\n maxFiles?: number;\n /** Archive limits (default: 100 MiB extracted, 5 000 entries). */\n zip?: ZipReadOptions;\n}\n\nconst INDEX_NAMES = /^(index|readme|home|_index|start)$/i;\n\nconst baseName = (path: string) => path.slice(path.lastIndexOf(\"/\") + 1);\nconst stem = (name: string) => name.replace(/\\.[^./]+$/, \"\");\n\n/** File title: the name without extension, path or a trailing Notion-style id. */\nexport function zipEntryTitle(path: string): string {\n const title = stem(baseName(path))\n .replace(/\\s+[0-9a-f]{32}$/i, \"\")\n .replace(/[_]+/g, \" \")\n .trim();\n return title || baseName(path);\n}\n\n/**\n * Orders entries for import: index / README files first (shallowest first),\n * then by path with natural number ordering (`2` before `10`).\n */\nexport function sortZipEntryNames(names: readonly string[]): string[] {\n const isIndex = (name: string) => INDEX_NAMES.test(stem(baseName(name)));\n const depth = (name: string) => name.split(\"/\").length;\n return [...names].sort((a, b) => {\n const ai = isIndex(a);\n const bi = isIndex(b);\n if (ai !== bi) return ai ? -1 : 1;\n if (ai && bi && depth(a) !== depth(b)) return depth(a) - depth(b);\n return a.localeCompare(b, undefined, { numeric: true, sensitivity: \"base\" });\n });\n}\n\nconst isJunk = (name: string) =>\n name.startsWith(\"__MACOSX/\") || name.split(\"/\").some((segment) => segment.startsWith(\".\"));\n\n/** Creates a `document` adapter for zipped exports. */\nexport function createZipImportAdapter(options: ZipImportOptions = {}): DocumentImportAdapter {\n const id = options.id ?? \"zip\";\n return {\n id,\n label: \"Zipped documents\",\n mimeTypes: [\"application/zip\", \"application/x-zip-compressed\"],\n extensions: [\".zip\"],\n target: \"document\",\n async import(_input, context): Promise<ZipDocumentImport> {\n const registry = options.registry ?? context.registry ?? defaultImportRegistry;\n const zip = await readZip(await context.readArrayBuffer(), {\n maxTotalSize: 100 * 1024 * 1024,\n maxEntries: 5_000,\n ...options.zip,\n });\n const maxFiles = options.maxFiles ?? 500;\n const level = options.headingLevel ?? 2;\n const files: ZipDocumentImport[\"files\"] = [];\n const skipped: ZipDocumentImport[\"skipped\"] = [];\n let html = \"\";\n let text = \"\";\n\n const names = zip.entries.filter((entry) => !entry.isDirectory).map((entry) => entry.name);\n for (const name of sortZipEntryNames(names)) {\n if (isJunk(name)) continue;\n const adapter = registry.find({ fileName: name, target: \"document\" });\n if (!adapter) {\n skipped.push({ name, reason: \"unsupported type\" });\n continue;\n }\n if (adapter.id === id || adapter.extensions.some((ext) => ext.toLowerCase() === \".zip\")) {\n skipped.push({ name, reason: \"nested archive\" });\n continue;\n }\n if (files.length >= maxFiles) {\n skipped.push({ name, reason: \"file limit reached\" });\n continue;\n }\n try {\n const outcome = await registry.importFile<DocumentImport>(await zip.read(name), {\n fileName: name,\n adapterId: adapter.id,\n });\n const title = zipEntryTitle(name);\n if (options.headings !== false) {\n html += `<h${level}>${escapeHtml(title)}</h${level}>`;\n text += `${text ? \"\\n\" : \"\"}${title}\\n`;\n } else if (text) {\n text += \"\\n\";\n }\n html += outcome.result.html.trim();\n text += outcome.result.text;\n files.push({ name, adapterId: adapter.id });\n } catch (error) {\n // Archive-wide limits stop the whole import; other failures skip the entry.\n const code = (error as { code?: string })?.code;\n if (code === \"too_large\") throw error;\n skipped.push({ name, reason: error instanceof Error ? error.message : String(error) });\n }\n }\n if (!files.length) {\n throw new ImportError(\"invalid_file\", \"The archive contains no importable documents.\", {\n fileName: context.fileName,\n });\n }\n return { html, text, files, skipped };\n },\n };\n}\n\n/** Zipped-export adapter with default options. Opt in with `registerImportAdapter(zipImportAdapter)`. */\nexport const zipImportAdapter: DocumentImportAdapter = createZipImportAdapter();\n"],"mappings":"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","names":["MAX_TABLE_ROWS","left","right","block","median"]}