epochs-pdf 0.1.5 → 0.1.7

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.
@@ -1 +1 @@
1
- {"version":3,"file":"epochs-pdf.cjs","sources":["../src/viewer/markup.ts","../src/viewer/signature.ts","../src/viewer/coords.ts","../src/viewer/text.ts","../src/viewer/icons.tsx","../src/viewer/PageCanvas.tsx","../src/viewer/Thumbnail.tsx","../src/viewer/load.ts","../src/viewer/exportPages.ts","../src/viewer/SignaturePad.tsx","../src/viewer/toolbarTools.ts","../src/viewer/ToolbarButtons.tsx","../src/viewer/PdfViewer.tsx","../src/components.tsx","../src/reconciler.ts","../src/utils.ts","../src/layout.ts","../src/pdf-writer.ts","../src/render.ts"],"sourcesContent":["export type MarkupKind = \"highlight\" | \"underline\" | \"redact\";\n\nexport type MarkupTool = \"none\" | MarkupKind | \"erase\" | \"sign\" | \"text\";\n\n/** Opaque cover used when removing existing PDF text. */\nexport const REDACT_COLOR = \"#ffffff\";\n\nexport interface MarkupRect {\n /** Left edge in page CSS pixels at scale = 1. */\n x: number;\n /** Top edge in page CSS pixels at scale = 1. */\n y: number;\n w: number;\n h: number;\n}\n\nexport interface MarkupAnnotation {\n id: string;\n pageNumber: number;\n kind: MarkupKind;\n color: string;\n rects: MarkupRect[];\n text?: string;\n}\n\nexport interface MarkupColorOption {\n id: string;\n label: string;\n /** Solid hex used by the swatch / color input. */\n hex: string;\n}\n\nexport const HIGHLIGHT_PRESETS: MarkupColorOption[] = [\n { id: \"yellow\", label: \"Yellow\", hex: \"#facc15\" },\n { id: \"green\", label: \"Green\", hex: \"#4ade80\" },\n { id: \"pink\", label: \"Pink\", hex: \"#f472b6\" },\n { id: \"blue\", label: \"Blue\", hex: \"#60a5fa\" },\n { id: \"orange\", label: \"Orange\", hex: \"#fb923c\" },\n { id: \"purple\", label: \"Purple\", hex: \"#c084fc\" },\n];\n\nexport const UNDERLINE_PRESETS: MarkupColorOption[] = [\n { id: \"blue\", label: \"Blue\", hex: \"#2563eb\" },\n { id: \"red\", label: \"Red\", hex: \"#dc2626\" },\n { id: \"green\", label: \"Green\", hex: \"#16a34a\" },\n { id: \"orange\", label: \"Orange\", hex: \"#ea580c\" },\n { id: \"purple\", label: \"Purple\", hex: \"#7c3aed\" },\n { id: \"black\", label: \"Black\", hex: \"#111827\" },\n];\n\nexport const DEFAULT_HIGHLIGHT_HEX = HIGHLIGHT_PRESETS[0].hex;\nexport const DEFAULT_UNDERLINE_HEX = UNDERLINE_PRESETS[0].hex;\n\n/** Legacy defaults kept for callers. */\nexport const HIGHLIGHT_COLOR = hexToMarkupColor(DEFAULT_HIGHLIGHT_HEX, \"highlight\");\nexport const UNDERLINE_COLOR = DEFAULT_UNDERLINE_HEX;\n\nexport function createMarkupId(): string {\n return `m_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nexport function normalizeHex(color: string): string {\n const value = color.trim();\n if (/^#[0-9a-fA-F]{6}$/.test(value)) return value.toLowerCase();\n if (/^#[0-9a-fA-F]{3}$/.test(value)) {\n const r = value[1];\n const g = value[2];\n const b = value[3];\n return `#${r}${r}${g}${g}${b}${b}`.toLowerCase();\n }\n return value;\n}\n\n/** Convert a solid hex into the CSS color used for drawing markup. */\nexport function hexToMarkupColor(hex: string, kind: MarkupKind, alpha = 0.45): string {\n const normalized = normalizeHex(hex);\n if (kind === \"underline\" || kind === \"redact\") return normalized;\n\n const match = /^#([0-9a-f]{6})$/i.exec(normalized);\n if (!match) return `rgba(250, 204, 21, ${alpha})`;\n\n const int = Number.parseInt(match[1], 16);\n const r = (int >> 16) & 255;\n const g = (int >> 8) & 255;\n const b = int & 255;\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n}\n\n/** Best-effort extract of a #rrggbb value from a stored markup color. */\nexport function markupColorToHex(color: string, fallback: string): string {\n const normalized = normalizeHex(color);\n if (/^#[0-9a-f]{6}$/i.test(normalized)) return normalized.toLowerCase();\n\n const rgba = color.match(\n /rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)/i,\n );\n if (!rgba) return normalizeHex(fallback);\n\n const toHex = (n: string) =>\n Math.max(0, Math.min(255, Math.round(Number(n))))\n .toString(16)\n .padStart(2, \"0\");\n\n return `#${toHex(rgba[1])}${toHex(rgba[2])}${toHex(rgba[3])}`;\n}\n\n/** Collect selection client rects relative to a page surface, normalized to scale=1. */\nexport function selectionRectsForPage(\n pageSurface: HTMLElement,\n scale: number,\n): { rects: MarkupRect[]; text: string } | null {\n const selection = window.getSelection();\n if (!selection || selection.isCollapsed || selection.rangeCount === 0) {\n return null;\n }\n\n const range = selection.getRangeAt(0);\n if (!pageSurface.contains(range.commonAncestorContainer)) {\n return null;\n }\n\n const pageBox = pageSurface.getBoundingClientRect();\n const clientRects = Array.from(range.getClientRects()).filter(\n (r) => r.width > 0 && r.height > 0,\n );\n\n if (!clientRects.length) return null;\n\n const safeScale = scale || 1;\n const layoutW = pageSurface.clientWidth || pageBox.width;\n const layoutH = pageSurface.clientHeight || pageBox.height;\n const rects: MarkupRect[] = clientRects.map((r) => ({\n x: pageBox.width > 0 ? ((r.left - pageBox.left) / pageBox.width) * (layoutW / safeScale) : 0,\n y: pageBox.height > 0 ? ((r.top - pageBox.top) / pageBox.height) * (layoutH / safeScale) : 0,\n w: pageBox.width > 0 ? (r.width / pageBox.width) * (layoutW / safeScale) : 0,\n h: pageBox.height > 0 ? (r.height / pageBox.height) * (layoutH / safeScale) : 0,\n }));\n\n return { rects, text: selection.toString() };\n}\n\n/** Pick the top-left anchor for replacement text from selection rects. */\nexport function selectionStartPoint(\n rects: MarkupRect[],\n): { x: number; y: number; fontSize: number } {\n const sorted = [...rects].sort((a, b) => a.y - b.y || a.x - b.x);\n const first = sorted[0] ?? { x: 0, y: 0, w: 0, h: 14 };\n return {\n x: first.x,\n y: first.y,\n fontSize: Math.max(8, Math.round(first.h * 0.9) || 14),\n };\n}\n\n/** Slightly expand rects so redaction fully covers glyph ink. */\nexport function expandRedactRects(\n rects: MarkupRect[],\n padding = 2,\n): MarkupRect[] {\n return rects.map((rect) => ({\n x: Math.max(0, rect.x - padding),\n y: Math.max(0, rect.y - padding),\n w: rect.w + padding * 2,\n h: rect.h + padding * 2,\n }));\n}\n\n/** Draw highlight / underline annotations onto a canvas (rects are stored at scale = 1). */\nexport function drawMarkupOnCanvas(\n ctx: CanvasRenderingContext2D,\n annotations: MarkupAnnotation[],\n scale: number,\n): void {\n for (const ann of annotations) {\n for (const rect of ann.rects) {\n const x = rect.x * scale;\n const y = rect.y * scale;\n const w = rect.w * scale;\n const h = rect.h * scale;\n\n if (ann.kind === \"highlight\") {\n ctx.save();\n ctx.globalCompositeOperation = \"multiply\";\n ctx.fillStyle = ann.color;\n ctx.fillRect(x, y, w, h);\n ctx.restore();\n } else if (ann.kind === \"redact\") {\n ctx.fillStyle = ann.color || REDACT_COLOR;\n ctx.fillRect(x, y, w, h);\n } else {\n const thickness = Math.max(2, scale * 1.5);\n ctx.fillStyle = ann.color;\n ctx.fillRect(x, y + h - thickness, w, thickness);\n }\n }\n }\n}\n\n","export interface SignatureAnnotation {\n id: string;\n pageNumber: number;\n fieldId?: string;\n /** Top-left X in page CSS pixels at scale = 1. */\n x: number;\n /** Top-left Y in page CSS pixels at scale = 1. */\n y: number;\n /** Width at scale = 1. */\n width: number;\n /** Height at scale = 1. */\n height: number;\n /** PNG data URL of the signature ink. */\n imageDataUrl: string;\n}\n\nexport type SignatureFieldType = \"sign\" | \"date\" | \"text\";\n\nexport interface SignatureField {\n id: string;\n pageNumber: number;\n x: number;\n y: number;\n width: number;\n height: number;\n /** Field behavior: \"sign\" (default), \"date\" (date picker), or \"text\" (text input). */\n type?: SignatureFieldType;\n /** Placeholder text for \"text\" type fields. */\n placeholder?: string;\n /**\n * Optional group key. When `applySignatureToSameTag` is enabled on the viewer,\n * one signature fills every field that shares this tag.\n */\n signature_tag?: string;\n /** Filled signature image (data URL) after the user signs this field. */\n signatureDataUrl?: string;\n /** Plain text / date string when `type` is `\"text\"` or `\"date\"`. */\n value?: string;\n}\n\nexport function createSignatureId(): string {\n return `s_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nexport async function drawSignaturesOnCanvas(\n ctx: CanvasRenderingContext2D,\n signatures: SignatureAnnotation[],\n scale: number,\n): Promise<void> {\n for (const sig of signatures) {\n const img = await loadImage(sig.imageDataUrl);\n ctx.drawImage(\n img,\n sig.x * scale,\n sig.y * scale,\n sig.width * scale,\n sig.height * scale,\n );\n }\n}\n\nexport function drawSignatureFieldsOnCanvas(\n ctx: CanvasRenderingContext2D,\n fields: SignatureField[],\n signedFieldIds: Set<string>,\n scale: number,\n): void {\n ctx.save();\n for (const field of fields) {\n const isFilled = signedFieldIds.has(field.id);\n const x = field.x * scale;\n const y = field.y * scale;\n const w = field.width * scale;\n const h = field.height * scale;\n\n ctx.fillStyle = isFilled\n ? \"rgba(29, 78, 216, 0.08)\"\n : \"rgba(29, 78, 216, 0.18)\";\n ctx.strokeStyle = isFilled\n ? \"rgba(29, 78, 216, 0.45)\"\n : \"#1d4ed8\";\n ctx.lineWidth = 1.5;\n ctx.setLineDash(isFilled ? [] : [4, 3]);\n ctx.fillRect(x, y, w, h);\n ctx.strokeRect(x, y, w, h);\n }\n ctx.restore();\n}\n\nfunction loadImage(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = () => reject(new Error(\"Failed to load signature image\"));\n img.src = src;\n });\n}\n\n/** Fit a drawn signature canvas into a target box while keeping aspect ratio. */\nexport function signatureDisplaySize(\n sourceWidth: number,\n sourceHeight: number,\n maxWidth = 180,\n maxHeight = 64,\n): { width: number; height: number } {\n if (sourceWidth <= 0 || sourceHeight <= 0) {\n return { width: maxWidth, height: maxHeight };\n }\n const ratio = Math.min(maxWidth / sourceWidth, maxHeight / sourceHeight);\n return {\n width: Math.max(40, sourceWidth * ratio),\n height: Math.max(20, sourceHeight * ratio),\n };\n}\n","/**\n * Browser zoom changes getBoundingClientRect() but not clientWidth/clientHeight.\n * Convert viewport client coordinates into page CSS pixels at scale = 1.\n */\nexport function clientPointToPage(\n clientX: number,\n clientY: number,\n surface: HTMLElement,\n scale: number,\n): { x: number; y: number } {\n const box = surface.getBoundingClientRect();\n const layoutW = surface.clientWidth || box.width;\n const layoutH = surface.clientHeight || box.height;\n if (box.width <= 0 || box.height <= 0 || scale <= 0) {\n return { x: 0, y: 0 };\n }\n return {\n x: ((clientX - box.left) / box.width) * (layoutW / scale),\n y: ((clientY - box.top) / box.height) * (layoutH / scale),\n };\n}\n\n/** Page size in CSS pixels at scale = 1. */\nexport function pageSizeFromSurface(\n surface: HTMLElement,\n scale: number,\n): { width: number; height: number } {\n return {\n width: surface.clientWidth / scale,\n height: surface.clientHeight / scale,\n };\n}\n\n/**\n * Convert a viewport delta (e.g. drag/resize) into page CSS pixels at scale = 1,\n * compensating for browser zoom.\n */\nexport function clientDeltaToPage(\n deltaX: number,\n deltaY: number,\n surface: HTMLElement,\n scale: number,\n): { dx: number; dy: number } {\n const box = surface.getBoundingClientRect();\n const layoutW = surface.clientWidth || box.width;\n const layoutH = surface.clientHeight || box.height;\n if (box.width <= 0 || box.height <= 0 || scale <= 0) {\n return { dx: 0, dy: 0 };\n }\n return {\n dx: (deltaX / box.width) * (layoutW / scale),\n dy: (deltaY / box.height) * (layoutH / scale),\n };\n}\n\n/** Map a viewport Y (or rect edge) relative to surface into page coords at scale = 1. */\nexport function viewportRectToPage(\n viewport: DOMRect,\n surface: HTMLElement,\n scale: number,\n): { left: number; top: number; right: number; bottom: number } {\n const surfaceRect = surface.getBoundingClientRect();\n const { width: pageW, height: pageH } = pageSizeFromSurface(surface, scale);\n if (surfaceRect.width <= 0 || surfaceRect.height <= 0) {\n return { left: 0, top: 0, right: pageW, bottom: pageH };\n }\n return {\n left: ((viewport.left - surfaceRect.left) / surfaceRect.width) * pageW,\n top: ((viewport.top - surfaceRect.top) / surfaceRect.height) * pageH,\n right: ((viewport.right - surfaceRect.left) / surfaceRect.width) * pageW,\n bottom: ((viewport.bottom - surfaceRect.top) / surfaceRect.height) * pageH,\n };\n}\n","export interface TextField {\n id: string;\n pageNumber: number;\n x: number;\n y: number;\n width: number;\n height: number;\n /** Shown when the field is empty. */\n placeholder?: string;\n /** Font size at scale = 1. Default 14. */\n fontSize?: number;\n /** CSS color. Default #111827. */\n color?: string;\n}\n\nexport interface TextAnnotation {\n id: string;\n pageNumber: number;\n fieldId?: string;\n /** Left edge in page CSS pixels at scale = 1. */\n x: number;\n /** Top edge in page CSS pixels at scale = 1. */\n y: number;\n /** Width at scale = 1. */\n width: number;\n /** Height at scale = 1. */\n height: number;\n value: string;\n fontSize: number;\n color: string;\n}\n\nexport const DEFAULT_TEXT_FONT_SIZE = 14;\nexport const DEFAULT_TEXT_COLOR = \"#111827\";\nexport const MIN_TEXT_WIDTH = 24;\nexport const MIN_TEXT_HEIGHT = 20;\n\nexport function createTextId(): string {\n return `t_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nexport function measureInlineText(\n value: string,\n fontSize: number,\n): { width: number; height: number } {\n if (typeof document === \"undefined\") {\n return {\n width: Math.max(MIN_TEXT_WIDTH, value.length * fontSize * 0.55),\n height: Math.max(MIN_TEXT_HEIGHT, fontSize * 1.25),\n };\n }\n\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n return {\n width: Math.max(MIN_TEXT_WIDTH, value.length * fontSize * 0.55),\n height: Math.max(MIN_TEXT_HEIGHT, fontSize * 1.25),\n };\n }\n\n ctx.font = `${fontSize}px sans-serif`;\n const lines = value.split(\"\\n\");\n const lineHeight = fontSize * 1.25;\n let maxWidth = MIN_TEXT_WIDTH;\n\n for (const line of lines) {\n maxWidth = Math.max(maxWidth, ctx.measureText(line || \" \").width + 4);\n }\n\n return {\n width: maxWidth,\n height: Math.max(MIN_TEXT_HEIGHT, lines.length * lineHeight),\n };\n}\n\n/** Resolve where inline text should start from a click on/near PDF text. */\nexport function resolveInlineTextPoint(\n clientX: number,\n clientY: number,\n surface: HTMLElement,\n textLayer: HTMLElement,\n scale: number,\n): { x: number; y: number; fontSize: number } {\n const surfaceBox = surface.getBoundingClientRect();\n const layoutW = surface.clientWidth || surfaceBox.width;\n const layoutH = surface.clientHeight || surfaceBox.height;\n const toPageX = (client: number) =>\n surfaceBox.width > 0\n ? ((client - surfaceBox.left) / surfaceBox.width) * (layoutW / scale)\n : 0;\n const toPageY = (client: number) =>\n surfaceBox.height > 0\n ? ((client - surfaceBox.top) / surfaceBox.height) * (layoutH / scale)\n : 0;\n const toPageSize = (clientSize: number, axis: \"x\" | \"y\") => {\n const boxSize = axis === \"x\" ? surfaceBox.width : surfaceBox.height;\n const layout = axis === \"x\" ? layoutW : layoutH;\n return boxSize > 0 ? (clientSize / boxSize) * (layout / scale) : 0;\n };\n\n // Default: exact click position (works for gaps between words)\n let x = toPageX(clientX);\n let y = toPageY(clientY);\n let fontSize = DEFAULT_TEXT_FONT_SIZE;\n\n // Prefer a gap between two spans on the same line (e.g. between \"this\" and \"PDF\")\n const gap = findGapBetweenSpans(clientX, clientY, textLayer);\n if (gap) {\n return {\n x: toPageX(gap.x),\n y: toPageY(gap.y),\n fontSize: Math.max(8, Math.round(toPageSize(gap.fontSize, \"y\") * 10) / 10),\n };\n }\n\n const doc = document as Document & {\n caretRangeFromPoint?: (x: number, y: number) => Range | null;\n };\n\n const range = doc.caretRangeFromPoint?.(clientX, clientY);\n if (range && textLayer.contains(range.startContainer)) {\n const rects = range.getClientRects();\n const rect = rects.length > 0 ? rects[0] : range.getBoundingClientRect();\n if (rect.height > 0) {\n // Keep the clicked X (insert point), snap Y/size to the line\n y = toPageY(rect.top);\n fontSize = inferFontSizeFromNode(range.startContainer, scale, surface);\n // If caret snapped to a glyph edge, use that X for cleaner alignment\n const caretX = toPageX(rect.left);\n if (Math.abs(caretX - x) < toPageSize(8, \"x\")) {\n x = caretX;\n }\n return { x, y, fontSize };\n }\n }\n\n const nearest = findNearestSpanOnLine(clientX, clientY, textLayer);\n if (nearest) {\n y = toPageY(nearest.top);\n fontSize = Math.max(8, Math.round(toPageSize(nearest.height, \"y\") * 10) / 10);\n }\n\n return { x, y, fontSize };\n}\n\n/** Find a click that lands in the horizontal gap between two word spans. */\nfunction findGapBetweenSpans(\n clientX: number,\n clientY: number,\n textLayer: HTMLElement,\n): { x: number; y: number; fontSize: number } | null {\n const spans = Array.from(\n textLayer.querySelectorAll(\"span\"),\n ) as HTMLElement[];\n if (spans.length < 2) return null;\n\n type SpanBox = { left: number; right: number; top: number; bottom: number; height: number };\n const boxes: SpanBox[] = [];\n\n for (const span of spans) {\n if (!span.textContent?.trim()) continue;\n const box = span.getBoundingClientRect();\n if (box.width <= 0 || box.height <= 0) continue;\n // Same visual line as the click\n if (clientY < box.top - 4 || clientY > box.bottom + 4) continue;\n boxes.push({\n left: box.left,\n right: box.right,\n top: box.top,\n bottom: box.bottom,\n height: box.height,\n });\n }\n\n boxes.sort((a, b) => a.left - b.left);\n\n for (let i = 0; i < boxes.length - 1; i += 1) {\n const left = boxes[i];\n const right = boxes[i + 1];\n const gapStart = left.right;\n const gapEnd = right.left;\n if (gapEnd - gapStart < 1) continue;\n if (clientX >= gapStart - 2 && clientX <= gapEnd + 2) {\n return {\n x: clientX,\n y: Math.min(left.top, right.top),\n fontSize: Math.min(left.height, right.height),\n };\n }\n }\n\n return null;\n}\n\nfunction findNearestSpanOnLine(\n clientX: number,\n clientY: number,\n textLayer: HTMLElement,\n): { top: number; height: number } | null {\n const spans = Array.from(\n textLayer.querySelectorAll(\"span\"),\n ) as HTMLElement[];\n\n let best: { top: number; height: number; dist: number } | null = null;\n\n for (const span of spans) {\n if (!span.textContent?.trim()) continue;\n const box = span.getBoundingClientRect();\n if (box.width <= 0 || box.height <= 0) continue;\n if (clientY < box.top - 6 || clientY > box.bottom + 6) continue;\n\n const midX = (box.left + box.right) / 2;\n const dist = Math.abs(clientX - midX);\n if (!best || dist < best.dist) {\n best = { top: box.top, height: box.height, dist };\n }\n }\n\n return best ? { top: best.top, height: best.height } : null;\n}\n\nfunction inferFontSizeFromNode(\n node: Node,\n scale: number,\n surface?: HTMLElement,\n): number {\n const element =\n node.nodeType === Node.ELEMENT_NODE\n ? (node as HTMLElement)\n : node.parentElement;\n if (element) return inferFontSizeFromElement(element, scale, surface);\n return DEFAULT_TEXT_FONT_SIZE;\n}\n\nfunction inferFontSizeFromElement(\n element: HTMLElement,\n scale: number,\n surface?: HTMLElement,\n): number {\n const height = element.getBoundingClientRect().height;\n if (height > 0) {\n if (surface) {\n const surfaceBox = surface.getBoundingClientRect();\n const layoutH = surface.clientHeight || surfaceBox.height;\n if (surfaceBox.height > 0) {\n return Math.max(\n 8,\n Math.round(((height / surfaceBox.height) * (layoutH / scale)) * 10) / 10,\n );\n }\n }\n return Math.max(8, Math.round((height / scale) * 10) / 10);\n }\n\n const computed = window.getComputedStyle(element).fontSize;\n const parsed = Number.parseFloat(computed);\n if (Number.isFinite(parsed) && parsed > 0) {\n return Math.max(8, Math.round((parsed / scale) * 10) / 10);\n }\n\n return DEFAULT_TEXT_FONT_SIZE;\n}\n\nexport function findTextFieldAtPoint(\n x: number,\n y: number,\n fields: TextField[],\n pageNumber: number,\n): TextField | null {\n for (const field of fields) {\n if (field.pageNumber !== pageNumber) continue;\n if (\n x >= field.x &&\n x <= field.x + field.width &&\n y >= field.y &&\n y <= field.y + field.height\n ) {\n return field;\n }\n }\n return null;\n}\n\n/** Select the word under a point in the PDF text layer (browser selection). */\nexport function selectWordAtPoint(\n clientX: number,\n clientY: number,\n textLayer: HTMLElement | null,\n): string | null {\n if (!textLayer) return null;\n\n const doc = document as Document & {\n caretRangeFromPoint?: (x: number, y: number) => Range | null;\n };\n const range = doc.caretRangeFromPoint?.(clientX, clientY);\n if (!range || !textLayer.contains(range.startContainer)) return null;\n\n const node = range.startContainer;\n if (node.nodeType !== Node.TEXT_NODE || !node.textContent) return null;\n\n const text = node.textContent;\n let offset = range.startOffset;\n offset = Math.min(Math.max(0, offset), text.length);\n\n const isWordChar = (ch: string) => /[\\p{L}\\p{N}_'-]/u.test(ch);\n let start = offset;\n let end = offset;\n\n while (start > 0 && isWordChar(text[start - 1]!)) start -= 1;\n while (end < text.length && isWordChar(text[end]!)) end += 1;\n\n if (start === end) return null;\n\n const wordRange = document.createRange();\n wordRange.setStart(node, start);\n wordRange.setEnd(node, end);\n\n const selection = window.getSelection();\n selection?.removeAllRanges();\n selection?.addRange(wordRange);\n\n return text.slice(start, end);\n}\n\nexport function drawTextsOnCanvas(\n ctx: CanvasRenderingContext2D,\n texts: TextAnnotation[],\n scale: number,\n): void {\n ctx.save();\n for (const text of texts) {\n if (!text.value.trim()) continue;\n\n const x = text.x * scale;\n const y = text.y * scale;\n const fontSize = Math.max(8, text.fontSize * scale);\n\n ctx.fillStyle = text.color;\n ctx.font = `${fontSize}px sans-serif`;\n ctx.textBaseline = \"top\";\n\n const lineHeight = fontSize * 1.25;\n const lines = text.value.split(\"\\n\");\n let cursorY = y;\n\n for (const line of lines) {\n ctx.fillText(line, x, cursorY);\n cursorY += lineHeight;\n }\n }\n ctx.restore();\n}\n\nexport function drawTextFieldsOnCanvas(\n ctx: CanvasRenderingContext2D,\n fields: TextField[],\n filledFieldIds: Set<string>,\n scale: number,\n): void {\n ctx.save();\n for (const field of fields) {\n const isFilled = filledFieldIds.has(field.id);\n const x = field.x * scale;\n const y = field.y * scale;\n const w = field.width * scale;\n const h = field.height * scale;\n\n ctx.fillStyle = isFilled\n ? \"rgba(5, 150, 105, 0.08)\"\n : \"rgba(5, 150, 105, 0.16)\";\n ctx.strokeStyle = isFilled\n ? \"rgba(5, 150, 105, 0.45)\"\n : \"#059669\";\n ctx.lineWidth = 1.5;\n ctx.setLineDash(isFilled ? [] : [4, 3]);\n ctx.fillRect(x, y, w, h);\n ctx.strokeRect(x, y, w, h);\n }\n ctx.restore();\n}\n","import type { ReactNode } from \"react\";\n\ntype IconProps = {\n size?: number;\n className?: string;\n};\n\nfunction Icon({\n size = 14,\n className,\n children,\n}: IconProps & { children: ReactNode }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden=\"true\"\n >\n {children}\n </svg>\n );\n}\n\nexport function ChevronLeftIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <polyline points=\"15 18 9 12 15 6\" />\n </Icon>\n );\n}\n\nexport function ChevronRightIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <polyline points=\"9 18 15 12 9 6\" />\n </Icon>\n );\n}\n\nexport function DownloadIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" />\n </Icon>\n );\n}\n\nexport function ExternalLinkIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </Icon>\n );\n}\n\nexport function GridIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" />\n <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" />\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" />\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" />\n </Icon>\n );\n}\n\nexport function MinusIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </Icon>\n );\n}\n\nexport function PlusIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </Icon>\n );\n}\n\nexport function PrinterIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <polyline points=\"6 9 6 2 18 2 18 9\" />\n <path d=\"M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2\" />\n <rect x=\"6\" y=\"14\" width=\"12\" height=\"8\" />\n </Icon>\n );\n}\n\nexport function RefreshIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <polyline points=\"23 4 23 10 17 10\" />\n <polyline points=\"1 20 1 14 7 14\" />\n <path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\" />\n </Icon>\n );\n}\n\nexport function RotateIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <polyline points=\"23 4 23 10 17 10\" />\n <path d=\"M20.49 15a9 9 0 1 1-2.12-9.36L23 10\" />\n </Icon>\n );\n}\n\nexport function HighlightIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M12 20h9\" />\n <path d=\"M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z\" />\n </Icon>\n );\n}\n\nexport function UnderlineIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M6 3v7a6 6 0 0 0 12 0V3\" />\n <line x1=\"4\" y1=\"21\" x2=\"20\" y2=\"21\" />\n </Icon>\n );\n}\n\nexport function EraserIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21\" />\n <path d=\"M22 21H7\" />\n <path d=\"m5 11 9 9\" />\n </Icon>\n );\n}\n\nexport function SignatureIcon({ size = 16, className }: IconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 256 256\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n strokeWidth=\"12\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden=\"true\"\n >\n <path d=\"M232,172H57.32c4-7.83,8.18-16.11,12.21-24.56,15.14,3.55,34.13-8.06,56.54-34.59,3.67,12.5,12.53,34.83,29.08,35.15h.35c8.71,0,17.64-6.25,27.16-19.06C187.17,137.14,199.31,148,232,148a4,4,0,0,0,0-8c-42.88,0-44-19.24-44-20a4,4,0,0,0-7.35-2.18C168.74,136.1,160.42,140,155.48,140h-.18c-13-.25-21.29-26.52-23.38-36.61a4,4,0,0,0-7-1.69c-20.94,26.27-39.06,39.55-51.8,38.2C97.31,87.5,105.19,53.16,96.49,37.77,94,33.31,88.7,28,77.91,28,64.09,28,52.54,42.41,47,66.54A122.7,122.7,0,0,0,45.46,113c2.64,15.29,8.39,26.05,16.69,31.35-4.58,9.6-9.3,19-13.84,27.68H24a4,4,0,0,0,0,8H44.1c-12.87,24.17-23.37,41.68-23.53,41.94a4,4,0,0,0,1.37,5.49A3.93,3.93,0,0,0,24,228a4,4,0,0,0,3.43-1.94c.16-.27,11.85-19.75,25.72-46.06H232a4,4,0,0,0,0-8ZM53.34,111.61a114.81,114.81,0,0,1,1.49-43.29C58.4,52.7,66.34,36,77.91,36c7.52,0,10.23,3.26,11.61,5.7C99,58.4,79.92,106,65.6,137,59.76,132.69,55.46,123.83,53.34,111.61Z\" />\n </svg>\n );\n}\n\nexport function PencilIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M12 20h9\" />\n <path d=\"M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z\" />\n </Icon>\n );\n}\n\nexport function TextIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <polyline points=\"4 7 4 4 20 4 20 7\" />\n <line x1=\"9\" y1=\"20\" x2=\"15\" y2=\"20\" />\n <line x1=\"12\" y1=\"4\" x2=\"12\" y2=\"20\" />\n </Icon>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport type { RenderTask } from \"pdfjs-dist\";\nimport { TextLayer } from \"pdfjs-dist\";\nimport type { PdfDoc } from \"./types\";\nimport type { MarkupAnnotation, MarkupTool } from \"./markup\";\nimport { createMarkupId, expandRedactRects, REDACT_COLOR, selectionRectsForPage, selectionStartPoint } from \"./markup\";\nimport type { SignatureAnnotation, SignatureField } from \"./signature\";\nimport { createSignatureId } from \"./signature\";\nimport {\n clientDeltaToPage,\n clientPointToPage,\n pageSizeFromSurface,\n} from \"./coords\";\nimport type { TextAnnotation, TextField } from \"./text\";\nimport {\n createTextId,\n DEFAULT_TEXT_COLOR,\n DEFAULT_TEXT_FONT_SIZE,\n findTextFieldAtPoint,\n measureInlineText,\n resolveInlineTextPoint,\n selectWordAtPoint,\n} from \"./text\";\nimport { PencilIcon } from \"./icons\";\n\ninterface PageCanvasProps {\n pdfDoc: PdfDoc;\n pageNumber: number;\n scale: number;\n rotation: number;\n pageRef?: (el: HTMLDivElement | null) => void;\n onRendered?: (pageNumber: number) => void;\n markupTool?: MarkupTool;\n markupColor?: string;\n annotations?: MarkupAnnotation[];\n onAddAnnotation?: (annotation: MarkupAnnotation) => void;\n onRemoveAnnotation?: (id: string) => void;\n signatures?: SignatureAnnotation[];\n pendingSignature?: { imageDataUrl: string; width: number; height: number } | null;\n onAddSignature?: (signature: SignatureAnnotation) => void;\n onUpdateSignature?: (id: string, patch: Partial<SignatureAnnotation>) => void;\n onRemoveSignature?: (id: string) => void;\n onEditSignature?: (id: string) => void;\n onDuplicateSignature?: (id: string) => void;\n selectedSignatureId?: string | null;\n onSelectSignature?: (id: string | null) => void;\n signatureFields?: SignatureField[];\n selectedSignatureFieldId?: string | null;\n onSelectSignatureField?: (id: string | null) => void;\n hasFixedSignatureFields?: boolean;\n onOpenSignaturePad?: (fieldType?: import(\"./signature\").SignatureFieldType) => void;\n /** Values for date/text fixed fields, keyed by field id. */\n fieldValues?: Record<string, string>;\n onFieldValueChange?: (fieldId: string, value: string) => void;\n onFieldValueCommit?: (fieldId: string) => void;\n pendingFieldValue?: { type: \"date\" | \"text\"; value: string } | null;\n onPlaceFieldValue?: (pageNumber: number, x: number, y: number) => void;\n texts?: TextAnnotation[];\n onAddText?: (text: TextAnnotation) => void;\n onUpdateText?: (id: string, patch: Partial<TextAnnotation>) => void;\n onRemoveText?: (id: string) => void;\n selectedTextId?: string | null;\n onSelectText?: (id: string | null) => void;\n textFields?: TextField[];\n selectedTextFieldId?: string | null;\n onSelectTextField?: (id: string | null) => void;\n hasFixedTextFields?: boolean;\n editingTextId?: string | null;\n onEditingTextIdChange?: (id: string | null) => void;\n}\n\nexport function PageCanvas({\n pdfDoc,\n pageNumber,\n scale,\n rotation,\n pageRef,\n onRendered,\n markupTool = \"none\",\n markupColor,\n annotations = [],\n onAddAnnotation,\n onRemoveAnnotation,\n signatures = [],\n pendingSignature = null,\n onAddSignature,\n onUpdateSignature,\n onRemoveSignature,\n onEditSignature,\n onDuplicateSignature,\n selectedSignatureId = null,\n onSelectSignature,\n signatureFields = [],\n selectedSignatureFieldId = null,\n onSelectSignatureField,\n hasFixedSignatureFields = false,\n onOpenSignaturePad,\n fieldValues = {},\n onFieldValueChange: _onFieldValueChange,\n onFieldValueCommit: _onFieldValueCommit,\n pendingFieldValue = null,\n onPlaceFieldValue,\n texts = [],\n onAddText,\n onUpdateText,\n onRemoveText,\n selectedTextId = null,\n onSelectText,\n textFields = [],\n selectedTextFieldId: _selectedTextFieldId = null,\n onSelectTextField,\n hasFixedTextFields = false,\n editingTextId = null,\n onEditingTextIdChange,\n}: PageCanvasProps) {\n const wrapRef = useRef<HTMLDivElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const textLayerRef = useRef<HTMLDivElement>(null);\n const surfaceRef = useRef<HTMLDivElement>(null);\n const renderTaskRef = useRef<RenderTask | null>(null);\n const textLayerInstanceRef = useRef<TextLayer | null>(null);\n const [dragState, setDragState] = useState<\n | { kind: \"signature\"; id: string; offsetX: number; offsetY: number }\n | { kind: \"resize\"; id: string; startX: number; startY: number; startW: number; startH: number }\n | null\n >(null);\n const inlineEditRef = useRef<HTMLSpanElement>(null);\n const justOpenedEditorRef = useRef(false);\n\n useEffect(() => {\n if (!pdfDoc || !canvasRef.current || !textLayerRef.current || !surfaceRef.current) {\n return;\n }\n\n let cancelled = false;\n const canvas = canvasRef.current;\n const textLayerDiv = textLayerRef.current;\n const surface = surfaceRef.current;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n\n const render = async () => {\n try {\n if (renderTaskRef.current) {\n try {\n renderTaskRef.current.cancel();\n } catch {\n // ignore\n }\n renderTaskRef.current = null;\n }\n if (textLayerInstanceRef.current) {\n try {\n textLayerInstanceRef.current.cancel();\n } catch {\n // ignore\n }\n textLayerInstanceRef.current = null;\n }\n\n const page = await pdfDoc.getPage(pageNumber);\n if (cancelled) return;\n\n const viewport = page.getViewport({ scale, rotation });\n const width = Math.floor(viewport.width);\n const height = Math.floor(viewport.height);\n\n canvas.width = width;\n canvas.height = height;\n surface.style.width = `${width}px`;\n surface.style.height = `${height}px`;\n\n const task = page.render({ canvasContext: ctx, viewport });\n renderTaskRef.current = task;\n await task.promise;\n if (cancelled) return;\n\n textLayerDiv.replaceChildren();\n textLayerDiv.style.setProperty(\"--scale-factor\", String(viewport.scale));\n\n const textContent = await page.getTextContent();\n if (cancelled) return;\n\n const textLayer = new TextLayer({\n textContentSource: textContent,\n container: textLayerDiv,\n viewport,\n });\n textLayerInstanceRef.current = textLayer;\n await textLayer.render();\n if (cancelled) return;\n\n onRendered?.(pageNumber);\n } catch {\n // ignore (often cancellation)\n }\n };\n\n void render();\n\n return () => {\n cancelled = true;\n if (renderTaskRef.current) {\n try {\n renderTaskRef.current.cancel();\n } catch {\n // ignore\n }\n renderTaskRef.current = null;\n }\n if (textLayerInstanceRef.current) {\n try {\n textLayerInstanceRef.current.cancel();\n } catch {\n // ignore\n }\n textLayerInstanceRef.current = null;\n }\n };\n }, [pdfDoc, pageNumber, scale, rotation, onRendered]);\n\n useEffect(() => {\n const surface = surfaceRef.current;\n if (!surface) return;\n\n const applySelectionMarkup = (kind: \"highlight\" | \"underline\" | \"redact\") => {\n if (!onAddAnnotation) return false;\n\n const color =\n kind === \"redact\"\n ? REDACT_COLOR\n : markupColor;\n if (!color) return false;\n\n const captured = selectionRectsForPage(surface, scale);\n if (!captured) return false;\n\n const rects =\n kind === \"redact\"\n ? expandRedactRects(captured.rects)\n : captured.rects;\n\n onAddAnnotation({\n id: createMarkupId(),\n pageNumber,\n kind,\n color,\n rects,\n text: captured.text,\n });\n\n window.getSelection()?.removeAllRanges();\n return true;\n };\n\n const replaceSelectedPdfText = (initialValue: string) => {\n if (!onAddAnnotation || !onAddText) return false;\n\n const captured = selectionRectsForPage(surface, scale);\n if (!captured) return false;\n\n const rects = expandRedactRects(captured.rects);\n onAddAnnotation({\n id: createMarkupId(),\n pageNumber,\n kind: \"redact\",\n color: REDACT_COLOR,\n rects,\n text: captured.text,\n });\n\n const start = selectionStartPoint(captured.rects);\n const size = measureInlineText(initialValue || \" \", start.fontSize);\n const created: TextAnnotation = {\n id: createTextId(),\n pageNumber,\n x: start.x,\n y: start.y,\n width: size.width,\n height: size.height,\n value: initialValue,\n fontSize: start.fontSize,\n color: DEFAULT_TEXT_COLOR,\n };\n\n onAddText(created);\n onSelectText?.(created.id);\n onEditingTextIdChange?.(created.id);\n window.getSelection()?.removeAllRanges();\n justOpenedEditorRef.current = true;\n window.setTimeout(() => {\n justOpenedEditorRef.current = false;\n }, 0);\n return true;\n };\n\n const handleMouseUp = () => {\n if (markupTool === \"highlight\" || markupTool === \"underline\") {\n applySelectionMarkup(markupTool);\n return;\n }\n // Erase tool: select PDF words to cover/remove them\n if (markupTool === \"erase\") {\n applySelectionMarkup(\"redact\");\n return;\n }\n // Text tool: select existing PDF text → open it for editing\n if (markupTool === \"text\") {\n const selection = window.getSelection();\n if (\n selection &&\n !selection.isCollapsed &&\n selection.toString().trim() &&\n selection.anchorNode &&\n surface.contains(selection.anchorNode)\n ) {\n replaceSelectedPdfText(selection.toString());\n }\n }\n };\n\n const handleKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement | null;\n if (\n target?.closest(\"[contenteditable='true']\") ||\n target?.closest(\"[contenteditable='']\") ||\n target?.isContentEditable\n ) {\n return;\n }\n\n const selection = window.getSelection();\n const hasPdfSelection =\n selection != null &&\n !selection.isCollapsed &&\n selection.toString().trim().length > 0 &&\n selection.anchorNode != null &&\n surface.contains(selection.anchorNode);\n\n if (markupTool === \"text\" && hasPdfSelection) {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n replaceSelectedPdfText(selection!.toString());\n return;\n }\n\n if (\n event.key.length === 1 &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey\n ) {\n event.preventDefault();\n replaceSelectedPdfText(event.key);\n return;\n }\n }\n\n if (markupTool !== \"text\" && markupTool !== \"erase\") return;\n if (event.key !== \"Backspace\" && event.key !== \"Delete\") return;\n\n if (!hasPdfSelection) return;\n\n event.preventDefault();\n applySelectionMarkup(\"redact\");\n };\n\n surface.addEventListener(\"mouseup\", handleMouseUp);\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n surface.removeEventListener(\"mouseup\", handleMouseUp);\n window.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [\n markupTool,\n markupColor,\n onAddAnnotation,\n onAddText,\n onEditingTextIdChange,\n onSelectText,\n pageNumber,\n scale,\n ]);\n\n useEffect(() => {\n if (!dragState) return;\n\n let rafId = 0;\n let lastClientX = 0;\n let lastClientY = 0;\n let scrollDir = 0; // -1 up, 1 down, 0 none\n\n const getScrollContainer = (): HTMLElement | null => {\n return (\n wrapRef.current?.closest(\".epochs-pdf-viewer__body\") as HTMLElement | null\n );\n };\n\n const updateResizeAtPoint = (clientX: number, clientY: number) => {\n if (dragState.kind !== \"resize\") return;\n if (!onUpdateSignature || hasFixedSignatureFields) return;\n const sig = signatures.find((s) => s.id === dragState.id);\n if (!sig) return;\n\n const surface = surfaceRef.current;\n const pageSize = surface\n ? pageSizeFromSurface(surface, scale)\n : { width: Infinity, height: Infinity };\n const { dx, dy } = surface\n ? clientDeltaToPage(\n clientX - dragState.startX,\n clientY - dragState.startY,\n surface,\n scale,\n )\n : { dx: 0, dy: 0 };\n\n const maxW = pageSize.width - sig.x;\n const maxH = pageSize.height - sig.y;\n const newW = Math.min(maxW, Math.max(40, dragState.startW + dx));\n const newH = Math.min(maxH, Math.max(20, dragState.startH + dy));\n onUpdateSignature(dragState.id, { width: newW, height: newH });\n };\n\n const updateSignatureAtPoint = (clientX: number, clientY: number) => {\n if (dragState.kind !== \"signature\") return;\n if (!onUpdateSignature || hasFixedSignatureFields) return;\n\n const sig = signatures.find((s) => s.id === dragState.id);\n if (!sig) return;\n\n // Prefer element under cursor; fall back to previous page when over empty gutter\n let pageEl = document\n .elementFromPoint(clientX, clientY)\n ?.closest(\"[data-page-number]\") as HTMLElement | null;\n\n if (!pageEl) {\n const pages = Array.from(\n document.querySelectorAll(\".epochs-pdf-viewer__page[data-page-number]\"),\n ) as HTMLElement[];\n pageEl =\n pages.find((page) => {\n const box = page.getBoundingClientRect();\n return clientY >= box.top && clientY <= box.bottom;\n }) ?? null;\n }\n\n if (!pageEl) {\n pageEl = wrapRef.current;\n }\n if (!pageEl) return;\n\n const surface = pageEl.querySelector(\n \".epochs-pdf-viewer__surface\",\n ) as HTMLDivElement | null;\n if (!surface) return;\n\n const targetPage = Number.parseInt(\n pageEl.getAttribute(\"data-page-number\") || String(sig.pageNumber),\n 10,\n );\n\n const point = clientPointToPage(clientX, clientY, surface, scale);\n const pageSize = pageSizeFromSurface(surface, scale);\n let nextX = point.x - dragState.offsetX;\n let nextY = point.y - dragState.offsetY;\n const maxX = Math.max(0, pageSize.width - sig.width);\n const maxY = Math.max(0, pageSize.height - sig.height);\n nextX = Math.min(Math.max(0, nextX), maxX);\n nextY = Math.min(Math.max(0, nextY), maxY);\n\n onUpdateSignature(dragState.id, {\n pageNumber: targetPage,\n x: nextX,\n y: nextY,\n });\n };\n\n const tickScroll = () => {\n rafId = 0;\n if (!scrollDir) return;\n\n const container = getScrollContainer();\n if (!container) return;\n\n const maxScroll = container.scrollHeight - container.clientHeight;\n if (maxScroll <= 0) return;\n\n const edge = 56;\n const box = container.getBoundingClientRect();\n const distTop = lastClientY - box.top;\n const distBottom = box.bottom - lastClientY;\n\n let speed = 0;\n if (scrollDir < 0 && distTop < edge) {\n speed = -Math.max(6, ((edge - distTop) / edge) * 28);\n } else if (scrollDir > 0 && distBottom < edge) {\n speed = Math.max(6, ((edge - distBottom) / edge) * 28);\n } else {\n scrollDir = 0;\n return;\n }\n\n const prev = container.scrollTop;\n container.scrollTop = Math.min(maxScroll, Math.max(0, prev + speed));\n\n if (container.scrollTop !== prev) {\n updateSignatureAtPoint(lastClientX, lastClientY);\n }\n\n if (\n (speed < 0 && container.scrollTop > 0) ||\n (speed > 0 && container.scrollTop < maxScroll)\n ) {\n rafId = window.requestAnimationFrame(tickScroll);\n } else {\n scrollDir = 0;\n }\n };\n\n const handleMove = (event: PointerEvent) => {\n lastClientX = event.clientX;\n lastClientY = event.clientY;\n\n const container = getScrollContainer();\n if (container) {\n const edge = 56;\n const box = container.getBoundingClientRect();\n const distTop = event.clientY - box.top;\n const distBottom = box.bottom - event.clientY;\n\n if (distTop < edge) {\n scrollDir = -1;\n if (!rafId) rafId = window.requestAnimationFrame(tickScroll);\n } else if (distBottom < edge) {\n scrollDir = 1;\n if (!rafId) rafId = window.requestAnimationFrame(tickScroll);\n } else {\n scrollDir = 0;\n }\n }\n\n if (dragState.kind === \"resize\") {\n updateResizeAtPoint(event.clientX, event.clientY);\n } else {\n updateSignatureAtPoint(event.clientX, event.clientY);\n }\n };\n\n const handleUp = () => {\n scrollDir = 0;\n if (rafId) {\n window.cancelAnimationFrame(rafId);\n rafId = 0;\n }\n setDragState(null);\n };\n\n window.addEventListener(\"pointermove\", handleMove);\n window.addEventListener(\"pointerup\", handleUp);\n window.addEventListener(\"pointercancel\", handleUp);\n return () => {\n scrollDir = 0;\n if (rafId) window.cancelAnimationFrame(rafId);\n window.removeEventListener(\"pointermove\", handleMove);\n window.removeEventListener(\"pointerup\", handleUp);\n window.removeEventListener(\"pointercancel\", handleUp);\n };\n }, [\n dragState,\n hasFixedSignatureFields,\n onUpdateSignature,\n scale,\n signatures,\n ]);\n\n useEffect(() => {\n if (!editingTextId || !inlineEditRef.current) return;\n const el = inlineEditRef.current;\n const current = texts.find((t) => t.id === editingTextId);\n // Uncontrolled while editing — set DOM text once so React won't reset the caret\n el.textContent = current?.value ?? \"\";\n el.focus();\n\n const range = document.createRange();\n range.selectNodeContents(el);\n range.collapse(false);\n const selection = window.getSelection();\n selection?.removeAllRanges();\n selection?.addRange(range);\n // Only re-run when the edit session starts, not on every keystroke\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [editingTextId]);\n\n const setRefs = (el: HTMLDivElement | null) => {\n wrapRef.current = el;\n pageRef?.(el);\n };\n\n const pageAnnotations = annotations.filter((a) => a.pageNumber === pageNumber);\n const pageSignatures = signatures.filter((s) => s.pageNumber === pageNumber);\n const pageSignatureFields = signatureFields.filter((f) => f.pageNumber === pageNumber);\n const pageTexts = texts.filter((t) => t.pageNumber === pageNumber);\n\n const commitInlineText = (text: TextAnnotation, value: string) => {\n const trimmed = value.trim();\n if (!trimmed) {\n onRemoveText?.(text.id);\n onEditingTextIdChange?.(null);\n return;\n }\n\n const size = measureInlineText(trimmed, text.fontSize);\n onUpdateText?.(text.id, {\n value: trimmed,\n width: size.width,\n height: size.height,\n });\n onEditingTextIdChange?.(null);\n };\n\n const beginInlineTextAt = (clientX: number, clientY: number) => {\n if (!onAddText) return;\n\n const surface = surfaceRef.current;\n const textLayer = textLayerRef.current;\n if (!surface || !textLayer) return;\n\n let point = resolveInlineTextPoint(\n clientX,\n clientY,\n surface,\n textLayer,\n scale,\n );\n\n let fieldId: string | undefined;\n let color = DEFAULT_TEXT_COLOR;\n\n if (hasFixedTextFields) {\n const field = findTextFieldAtPoint(\n point.x,\n point.y,\n textFields,\n pageNumber,\n );\n if (!field) return;\n\n const existing = texts.find((t) => t.fieldId === field.id);\n if (existing) {\n onSelectText?.(existing.id);\n onSelectTextField?.(field.id);\n onEditingTextIdChange?.(existing.id);\n return;\n }\n\n fieldId = field.id;\n point = {\n x: field.x,\n y: field.y,\n fontSize: field.fontSize ?? DEFAULT_TEXT_FONT_SIZE,\n };\n color = field.color ?? DEFAULT_TEXT_COLOR;\n onSelectTextField?.(field.id);\n }\n\n const size = measureInlineText(\"\", point.fontSize);\n const created: TextAnnotation = {\n id: createTextId(),\n fieldId,\n pageNumber,\n x: point.x,\n y: point.y,\n width: size.width,\n height: size.height,\n value: \"\",\n fontSize: point.fontSize,\n color,\n };\n\n onAddText(created);\n onSelectText?.(created.id);\n onEditingTextIdChange?.(created.id);\n };\n\n const handleInlineTextClick = (event: React.MouseEvent<HTMLElement>) => {\n if (markupTool !== \"text\") return;\n if ((event.target as HTMLElement).closest(\".epochs-pdf-viewer__inline-text\")) {\n return;\n }\n // Skip the click that follows a select-to-edit mouseup\n if (justOpenedEditorRef.current) {\n justOpenedEditorRef.current = false;\n return;\n }\n\n // Selecting existing PDF words opens the editor on mouseup — don't insert here\n const selection = window.getSelection();\n if (selection && !selection.isCollapsed && selection.toString().trim()) {\n return;\n }\n\n // Double-click: select the word under the cursor and edit it\n if (event.detail >= 2) {\n const word = selectWordAtPoint(event.clientX, event.clientY, textLayerRef.current);\n if (word) {\n // mouseup already ran; open editor from the new word selection\n const surface = surfaceRef.current;\n if (surface && onAddAnnotation && onAddText) {\n const captured = selectionRectsForPage(surface, scale);\n if (captured) {\n onAddAnnotation({\n id: createMarkupId(),\n pageNumber,\n kind: \"redact\",\n color: REDACT_COLOR,\n rects: expandRedactRects(captured.rects),\n text: captured.text,\n });\n const start = selectionStartPoint(captured.rects);\n const size = measureInlineText(captured.text || \" \", start.fontSize);\n const created: TextAnnotation = {\n id: createTextId(),\n pageNumber,\n x: start.x,\n y: start.y,\n width: size.width,\n height: size.height,\n value: captured.text,\n fontSize: start.fontSize,\n color: DEFAULT_TEXT_COLOR,\n };\n onAddText(created);\n onSelectText?.(created.id);\n onEditingTextIdChange?.(created.id);\n window.getSelection()?.removeAllRanges();\n justOpenedEditorRef.current = true;\n }\n }\n return;\n }\n }\n\n event.stopPropagation();\n beginInlineTextAt(event.clientX, event.clientY);\n };\n\n const handleSurfaceClick = (event: React.MouseEvent<HTMLDivElement>) => {\n const target = event.target as HTMLElement;\n if (\n target.closest(\".epochs-pdf-viewer__signature\") ||\n target.closest(\".epochs-pdf-viewer__signature-field\") ||\n target.closest(\".epochs-pdf-viewer__inline-text\")\n ) {\n return;\n }\n\n if (markupTool === \"text\") {\n beginInlineTextAt(event.clientX, event.clientY);\n return;\n }\n\n if (\n !hasFixedSignatureFields &&\n markupTool === \"sign\" &&\n pendingFieldValue &&\n onPlaceFieldValue\n ) {\n const surface = surfaceRef.current;\n if (!surface) return;\n const point = clientPointToPage(event.clientX, event.clientY, surface, scale);\n onPlaceFieldValue(pageNumber, Math.max(0, point.x - 75), Math.max(0, point.y - 12));\n return;\n }\n\n if (\n !hasFixedSignatureFields &&\n markupTool === \"sign\" &&\n pendingSignature &&\n onAddSignature\n ) {\n const surface = surfaceRef.current;\n if (!surface) return;\n const pageSize = pageSizeFromSurface(surface, scale);\n const point = clientPointToPage(event.clientX, event.clientY, surface, scale);\n\n let x = point.x - pendingSignature.width / 2;\n let y = point.y - pendingSignature.height / 2;\n\n const maxX = Math.max(0, pageSize.width - pendingSignature.width);\n const maxY = Math.max(0, pageSize.height - pendingSignature.height);\n x = Math.min(Math.max(0, x), maxX);\n y = Math.min(Math.max(0, y), maxY);\n\n onAddSignature({\n id: createSignatureId(),\n pageNumber,\n x,\n y,\n width: pendingSignature.width,\n height: pendingSignature.height,\n imageDataUrl: pendingSignature.imageDataUrl,\n });\n return;\n }\n };\n\n const renderInlineText = (text: TextAnnotation) => {\n const isEditing = editingTextId === text.id;\n\n if (isEditing) {\n return (\n <span\n key={text.id}\n ref={inlineEditRef}\n contentEditable\n suppressContentEditableWarning\n role=\"textbox\"\n aria-label=\"Edit text\"\n className=\"epochs-pdf-viewer__inline-text epochs-pdf-viewer__inline-text--editing\"\n style={{\n left: text.x * scale,\n top: text.y * scale,\n fontSize: text.fontSize * scale,\n color: text.color,\n minWidth: Math.max(12, text.fontSize * scale * 0.5),\n width: Math.max(text.width * scale, text.fontSize * scale * 0.5),\n }}\n onClick={(e) => e.stopPropagation()}\n onPointerDown={(e) => e.stopPropagation()}\n onInput={(e) => {\n const value = e.currentTarget.textContent ?? \"\";\n const size = measureInlineText(value || \" \", text.fontSize);\n // Update metrics only — do not write value back into the DOM\n onUpdateText?.(text.id, {\n value,\n width: size.width,\n height: size.height,\n });\n }}\n onBlur={(e) => {\n commitInlineText(text, e.currentTarget.textContent ?? \"\");\n }}\n onKeyDown={(e) => {\n // Keep spaces / typing local to this editor\n e.stopPropagation();\n if (e.key === \"Escape\") {\n e.preventDefault();\n (e.currentTarget as HTMLElement).blur();\n }\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n (e.currentTarget as HTMLElement).blur();\n }\n }}\n />\n );\n }\n\n if (!text.value.trim()) return null;\n\n return (\n <span\n key={text.id}\n className={\n selectedTextId === text.id\n ? \"epochs-pdf-viewer__inline-text epochs-pdf-viewer__inline-text--selected\"\n : \"epochs-pdf-viewer__inline-text\"\n }\n style={{\n left: text.x * scale,\n top: text.y * scale,\n fontSize: text.fontSize * scale,\n color: text.color,\n }}\n onClick={(e) => {\n e.stopPropagation();\n if (markupTool === \"erase\") {\n onRemoveText?.(text.id);\n return;\n }\n if (markupTool === \"text\") {\n onSelectText?.(text.id);\n onEditingTextIdChange?.(text.id);\n }\n }}\n >\n {text.value}\n </span>\n );\n };\n\n return (\n <div\n ref={setRefs}\n data-page-number={pageNumber}\n className=\"epochs-pdf-viewer__page\"\n >\n <div\n ref={surfaceRef}\n className={`epochs-pdf-viewer__surface epochs-pdf-viewer__surface--tool-${markupTool}`}\n onClick={handleSurfaceClick}\n >\n <canvas ref={canvasRef} className=\"epochs-pdf-viewer__canvas\" />\n\n <div className=\"epochs-pdf-viewer__markup-layer\" aria-hidden=\"true\">\n {pageAnnotations.map((ann) =>\n ann.kind === \"redact\"\n ? null\n : ann.rects.map((rect, idx) => {\n if (ann.kind === \"highlight\") {\n return (\n <div\n key={`${ann.id}_${idx}`}\n className=\"epochs-pdf-viewer__markup epochs-pdf-viewer__markup--highlight\"\n style={{\n left: rect.x * scale,\n top: rect.y * scale,\n width: rect.w * scale,\n height: rect.h * scale,\n background: ann.color,\n }}\n onClick={(e) => {\n if (markupTool !== \"erase\") return;\n e.stopPropagation();\n onRemoveAnnotation?.(ann.id);\n }}\n />\n );\n }\n\n return (\n <div\n key={`${ann.id}_${idx}`}\n className=\"epochs-pdf-viewer__markup epochs-pdf-viewer__markup--underline\"\n style={{\n left: rect.x * scale,\n top: (rect.y + rect.h) * scale - Math.max(2, scale * 1.5),\n width: rect.w * scale,\n height: Math.max(2, scale * 1.5),\n background: ann.color,\n }}\n onClick={(e) => {\n if (markupTool !== \"erase\") return;\n e.stopPropagation();\n onRemoveAnnotation?.(ann.id);\n }}\n />\n );\n }),\n )}\n </div>\n\n <div className=\"epochs-pdf-viewer__signature-layer\">\n {pageSignatureFields.map((field) => {\n const fType = field.type ?? \"sign\";\n const textValue =\n fieldValues[field.id] ?? field.value ?? \"\";\n const filled =\n fType === \"date\" || fType === \"text\"\n ? Boolean(textValue.trim())\n : pageSignatures.some((sig) => sig.fieldId === field.id);\n return (\n <button\n key={field.id}\n type=\"button\"\n data-signature-field-id={field.id}\n className={\n selectedSignatureFieldId === field.id\n ? \"epochs-pdf-viewer__signature-field epochs-pdf-viewer__signature-field--selected\"\n : filled\n ? \"epochs-pdf-viewer__signature-field epochs-pdf-viewer__signature-field--filled\"\n : \"epochs-pdf-viewer__signature-field\"\n }\n style={{\n left: field.x * scale,\n top: field.y * scale,\n width: field.width * scale,\n height: field.height * scale,\n }}\n onClick={(e) => {\n e.stopPropagation();\n onSelectSignatureField?.(field.id);\n if (fType === \"date\" || fType === \"text\") {\n onSelectSignature?.(null);\n onOpenSignaturePad?.(fType);\n return;\n }\n const existing = pageSignatures.find((sig) => sig.fieldId === field.id);\n onSelectSignature?.(existing?.id ?? null);\n if (existing) {\n onEditSignature?.(existing.id);\n } else {\n onOpenSignaturePad?.(fType);\n }\n }}\n title={\n filled\n ? \"Completed field\"\n : fType === \"date\"\n ? \"Date field\"\n : fType === \"text\"\n ? \"Text field\"\n : \"Signature field\"\n }\n >\n {(() => {\n if (fType === \"date\" || fType === \"text\") {\n if (textValue.trim()) {\n return (\n <span className=\"epochs-pdf-viewer__signature-field-value\">\n {textValue}\n </span>\n );\n }\n if (fType === \"date\") return <span>Date here</span>;\n return <span>{field.placeholder ?? \"Enter text\"}</span>;\n }\n return filled ? null : <span>Sign here</span>;\n })()}\n </button>\n );\n })}\n {pageSignatures.map((sig) => (\n <div\n key={sig.id}\n className={\n selectedSignatureId === sig.id\n ? \"epochs-pdf-viewer__signature epochs-pdf-viewer__signature--selected\"\n : \"epochs-pdf-viewer__signature\"\n }\n style={{\n left: sig.x * scale,\n top: sig.y * scale,\n width: sig.width * scale,\n height: sig.height * scale,\n }}\n onPointerDown={(e) => {\n e.stopPropagation();\n e.preventDefault();\n onSelectSignature?.(sig.id);\n\n if (markupTool === \"erase\" && !hasFixedSignatureFields) {\n onRemoveSignature?.(sig.id);\n return;\n }\n\n if (hasFixedSignatureFields) {\n onSelectSignatureField?.(sig.fieldId ?? null);\n onEditSignature?.(sig.id);\n return;\n }\n\n const surface = surfaceRef.current;\n if (!surface) return;\n const point = clientPointToPage(e.clientX, e.clientY, surface, scale);\n setDragState({\n kind: \"signature\",\n id: sig.id,\n offsetX: point.x - sig.x,\n offsetY: point.y - sig.y,\n });\n }}\n >\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__signature-edit\"\n title=\"Edit signature\"\n aria-label=\"Edit signature\"\n onPointerDown={(e) => {\n e.stopPropagation();\n }}\n onClick={(e) => {\n e.stopPropagation();\n onSelectSignature?.(sig.id);\n onEditSignature?.(sig.id);\n }}\n >\n <PencilIcon size={12} />\n </button>\n {!hasFixedSignatureFields ? (\n <>\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__signature-duplicate\"\n title=\"Duplicate signature\"\n aria-label=\"Duplicate signature\"\n onPointerDown={(e) => {\n e.stopPropagation();\n }}\n onClick={(e) => {\n e.stopPropagation();\n onSelectSignature?.(sig.id);\n onDuplicateSignature?.(sig.id);\n }}\n >\n ⧉\n </button>\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__signature-remove\"\n title=\"Remove signature\"\n aria-label=\"Remove signature\"\n onPointerDown={(e) => {\n e.stopPropagation();\n }}\n onClick={(e) => {\n e.stopPropagation();\n onRemoveSignature?.(sig.id);\n }}\n >\n ×\n </button>\n </>\n ) : null}\n <img src={sig.imageDataUrl} alt=\"Signature\" draggable={false} />\n {!hasFixedSignatureFields ? (\n <div\n className=\"epochs-pdf-viewer__signature-resize\"\n title=\"Resize\"\n onPointerDown={(e) => {\n e.stopPropagation();\n e.preventDefault();\n onSelectSignature?.(sig.id);\n setDragState({\n kind: \"resize\",\n id: sig.id,\n startX: e.clientX,\n startY: e.clientY,\n startW: sig.width,\n startH: sig.height,\n });\n }}\n >\n <svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 1L1 7M7 4L4 7\" stroke=\"white\" strokeWidth=\"1.2\" strokeLinecap=\"round\"/>\n </svg>\n </div>\n ) : null}\n </div>\n ))}\n </div>\n\n <div className=\"epochs-pdf-viewer__text-layer-overlay\">\n {pageTexts.map((text) => renderInlineText(text))}\n </div>\n\n <div\n ref={textLayerRef}\n className=\"textLayer epochs-pdf-viewer__text-layer\"\n onClick={handleInlineTextClick}\n />\n\n <div className=\"epochs-pdf-viewer__redact-layer\" aria-hidden=\"true\">\n {pageAnnotations.map((ann) =>\n ann.kind === \"redact\"\n ? ann.rects.map((rect, idx) => (\n <div\n key={`${ann.id}_${idx}`}\n className=\"epochs-pdf-viewer__markup epochs-pdf-viewer__markup--redact\"\n style={{\n left: rect.x * scale,\n top: rect.y * scale,\n width: rect.w * scale,\n height: rect.h * scale,\n background: ann.color || REDACT_COLOR,\n }}\n onClick={(e) => {\n if (markupTool !== \"erase\") return;\n e.stopPropagation();\n onRemoveAnnotation?.(ann.id);\n }}\n />\n ))\n : null,\n )}\n </div>\n </div>\n </div>\n );\n}\n","import { useEffect, useRef } from \"react\";\nimport type { RenderTask } from \"pdfjs-dist\";\nimport { drawMarkupOnCanvas, type MarkupAnnotation } from \"./markup\";\nimport {\n drawSignatureFieldsOnCanvas,\n drawSignaturesOnCanvas,\n type SignatureAnnotation,\n type SignatureField,\n} from \"./signature\";\nimport {\n drawTextFieldsOnCanvas,\n drawTextsOnCanvas,\n type TextAnnotation,\n type TextField,\n} from \"./text\";\nimport type { PdfDoc } from \"./types\";\n\ninterface ThumbnailProps {\n pdfDoc: PdfDoc;\n pageNumber: number;\n isActive?: boolean;\n rotation: number;\n onSelect: (pageNumber: number) => void;\n width?: number;\n annotations?: MarkupAnnotation[];\n signatures?: SignatureAnnotation[];\n signatureFields?: SignatureField[];\n texts?: TextAnnotation[];\n textFields?: TextField[];\n}\n\nexport function Thumbnail({\n pdfDoc,\n pageNumber,\n isActive,\n rotation,\n onSelect,\n width = 140,\n annotations = [],\n signatures = [],\n signatureFields = [],\n texts = [],\n textFields = [],\n}: ThumbnailProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n useEffect(() => {\n if (!pdfDoc || !canvasRef.current) return;\n\n let cancelled = false;\n const canvas = canvasRef.current;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n let task: RenderTask | null = null;\n\n const render = async () => {\n try {\n const page = await pdfDoc.getPage(pageNumber);\n if (cancelled) return;\n\n const viewportAt1 = page.getViewport({ scale: 1, rotation });\n const scale = width / viewportAt1.width;\n const viewport = page.getViewport({ scale, rotation });\n\n canvas.width = Math.floor(viewport.width);\n canvas.height = Math.floor(viewport.height);\n\n task = page.render({ canvasContext: ctx, viewport });\n await task.promise;\n\n const pageAnnotations = annotations.filter((a) => a.pageNumber === pageNumber);\n if (pageAnnotations.length > 0) {\n drawMarkupOnCanvas(ctx, pageAnnotations, scale);\n }\n\n const pageSignatures = signatures.filter((s) => s.pageNumber === pageNumber);\n const pageSignatureFields = signatureFields.filter(\n (field) => field.pageNumber === pageNumber,\n );\n if (pageSignatureFields.length > 0) {\n drawSignatureFieldsOnCanvas(\n ctx,\n pageSignatureFields,\n new Set(pageSignatures.map((sig) => sig.fieldId).filter(Boolean) as string[]),\n scale,\n );\n }\n if (pageSignatures.length > 0) {\n await drawSignaturesOnCanvas(ctx, pageSignatures, scale);\n }\n\n const pageTexts = texts.filter((t) => t.pageNumber === pageNumber);\n const pageTextFields = textFields.filter(\n (field) => field.pageNumber === pageNumber,\n );\n if (pageTextFields.length > 0) {\n drawTextFieldsOnCanvas(\n ctx,\n pageTextFields,\n new Set(\n pageTexts\n .filter((t) => t.fieldId && t.value.trim())\n .map((t) => t.fieldId as string),\n ),\n scale,\n );\n }\n if (pageTexts.length > 0) {\n drawTextsOnCanvas(ctx, pageTexts, scale);\n }\n } catch {\n // ignore\n }\n };\n\n void render();\n\n return () => {\n cancelled = true;\n if (task) {\n try {\n task.cancel();\n } catch {\n // ignore\n }\n }\n };\n }, [\n annotations,\n pdfDoc,\n pageNumber,\n rotation,\n signatureFields,\n signatures,\n textFields,\n texts,\n width,\n ]);\n\n return (\n <button\n type=\"button\"\n onClick={() => onSelect(pageNumber)}\n className={\n isActive\n ? \"epochs-pdf-viewer__thumb epochs-pdf-viewer__thumb--active\"\n : \"epochs-pdf-viewer__thumb\"\n }\n title={`Page ${pageNumber}`}\n >\n <div className=\"epochs-pdf-viewer__thumb-frame\">\n <canvas ref={canvasRef} />\n </div>\n <span className=\"epochs-pdf-viewer__thumb-label\">{pageNumber}</span>\n </button>\n );\n}\n","import * as pdfjsLib from \"pdfjs-dist\";\n\nconst ABSOLUTE_URL_PATTERN = /^(blob:|https?:|data:)/i;\n\nlet workerConfigured = false;\n\n/** Configure pdf.js worker. Call once, or pass `workerSrc` to `<PdfViewer>`. */\nexport function setPdfWorkerSrc(workerSrc: string): void {\n pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;\n workerConfigured = true;\n}\n\nexport function ensurePdfWorker(workerSrc?: string): void {\n if (workerSrc) {\n setPdfWorkerSrc(workerSrc);\n return;\n }\n if (workerConfigured || pdfjsLib.GlobalWorkerOptions.workerSrc) return;\n\n setPdfWorkerSrc(\n `https://unpkg.com/pdfjs-dist@${pdfjsLib.version}/build/pdf.worker.min.mjs`,\n );\n}\n\nexport function resolvePdfUrl(\n file?: string,\n fileUrl?: string,\n baseUrl = \"\",\n): string {\n const source = fileUrl || file;\n if (!source) return \"\";\n\n if (ABSOLUTE_URL_PATTERN.test(source)) return source;\n\n const path = source.startsWith(\"/\") ? source : `/${source}`;\n if (!baseUrl) return path;\n return `${baseUrl.replace(/\\/$/, \"\")}${path}`;\n}\n\nexport async function urlToPdfArrayBuffer(\n url: string,\n fetchOptions?: RequestInit,\n): Promise<ArrayBuffer> {\n const res = await fetch(url, fetchOptions);\n\n if (!res.ok) {\n throw new Error(`Failed to fetch PDF (${res.status})`);\n }\n\n return res.arrayBuffer();\n}\n\nexport async function sourceToArrayBuffer(\n source: string | ArrayBuffer | Uint8Array | Blob,\n fetchOptions?: RequestInit,\n): Promise<ArrayBuffer> {\n if (typeof source === \"string\") {\n return urlToPdfArrayBuffer(source, fetchOptions);\n }\n if (source instanceof ArrayBuffer) return source.slice(0);\n if (source instanceof Uint8Array) {\n const copy = new Uint8Array(source.byteLength);\n copy.set(source);\n return copy.buffer;\n }\n return source.arrayBuffer();\n}\n\nexport { pdfjsLib };\n","import type { PDFDocumentProxy } from \"pdfjs-dist\";\nimport type { MarkupAnnotation } from \"./markup\";\nimport { drawMarkupOnCanvas } from \"./markup\";\nimport type { SignatureAnnotation } from \"./signature\";\nimport { drawSignaturesOnCanvas } from \"./signature\";\nimport type { TextAnnotation } from \"./text\";\nimport { drawTextsOnCanvas } from \"./text\";\n\nexport interface RenderedPageImage {\n pageNumber: number;\n /** Canvas pixel size */\n width: number;\n height: number;\n /** PDF page size at scale 1 (points) */\n pageWidth: number;\n pageHeight: number;\n dataUrl: string;\n jpegBytes: Uint8Array;\n}\n\n/** Render a page in the *main* document (iframe canvases break pdf.js fonts). */\nexport async function renderPageWithMarkup(\n pdfDoc: PDFDocumentProxy,\n pageNumber: number,\n options: {\n scale: number;\n rotation: number;\n annotations: MarkupAnnotation[];\n signatures?: SignatureAnnotation[];\n texts?: TextAnnotation[];\n mimeType?: \"image/png\" | \"image/jpeg\";\n quality?: number;\n },\n): Promise<RenderedPageImage> {\n const {\n scale,\n rotation,\n annotations,\n signatures = [],\n texts = [],\n mimeType = \"image/jpeg\",\n quality = 0.92,\n } = options;\n\n const page = await pdfDoc.getPage(pageNumber);\n const viewport = page.getViewport({ scale, rotation });\n const baseViewport = page.getViewport({ scale: 1, rotation });\n\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\", { alpha: false });\n if (!ctx) {\n throw new Error(\"Could not create canvas context\");\n }\n\n const width = Math.floor(viewport.width);\n const height = Math.floor(viewport.height);\n canvas.width = width;\n canvas.height = height;\n\n ctx.fillStyle = \"#ffffff\";\n ctx.fillRect(0, 0, width, height);\n\n await page.render({ canvasContext: ctx, viewport }).promise;\n\n const pageMarks = annotations.filter((a) => a.pageNumber === pageNumber);\n if (pageMarks.length > 0) {\n drawMarkupOnCanvas(ctx, pageMarks, scale);\n }\n\n const pageSigs = signatures.filter((s) => s.pageNumber === pageNumber);\n if (pageSigs.length > 0) {\n await drawSignaturesOnCanvas(ctx, pageSigs, scale);\n }\n\n const pageTexts = texts.filter((t) => t.pageNumber === pageNumber);\n if (pageTexts.length > 0) {\n drawTextsOnCanvas(ctx, pageTexts, scale);\n }\n\n const dataUrl = canvas.toDataURL(mimeType, quality);\n const jpegBytes = dataUrlToBytes(dataUrl);\n\n canvas.width = 0;\n canvas.height = 0;\n\n return {\n pageNumber,\n width,\n height,\n pageWidth: baseViewport.width,\n pageHeight: baseViewport.height,\n dataUrl,\n jpegBytes,\n };\n}\n\nexport async function renderAllPagesWithMarkup(\n pdfDoc: PDFDocumentProxy,\n options: {\n scale: number;\n rotation: number;\n annotations: MarkupAnnotation[];\n signatures?: SignatureAnnotation[];\n texts?: TextAnnotation[];\n mimeType?: \"image/png\" | \"image/jpeg\";\n quality?: number;\n },\n): Promise<RenderedPageImage[]> {\n const pages: RenderedPageImage[] = [];\n for (let i = 1; i <= pdfDoc.numPages; i += 1) {\n pages.push(await renderPageWithMarkup(pdfDoc, i, options));\n }\n return pages;\n}\n\nfunction dataUrlToBytes(dataUrl: string): Uint8Array {\n const base64 = dataUrl.split(\",\")[1] ?? \"\";\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i += 1) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\nfunction enc(text: string): Uint8Array {\n return new TextEncoder().encode(text);\n}\n\nfunction concat(...parts: Uint8Array[]): Uint8Array {\n const total = parts.reduce((sum, p) => sum + p.byteLength, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const part of parts) {\n out.set(part, offset);\n offset += part.byteLength;\n }\n return out;\n}\n\n/**\n * Build a multi-page PDF embedding each page as a JPEG (includes baked markup).\n */\nexport function buildPdfFromJpegPages(pages: RenderedPageImage[]): Uint8Array {\n type PdfObject = Uint8Array;\n const objects: PdfObject[] = [];\n\n const add = (bytes: Uint8Array): number => {\n objects.push(bytes);\n return objects.length; // 1-indexed id\n };\n\n const pageIds: number[] = [];\n\n for (const page of pages) {\n const imageStream = concat(\n enc(\n `<< /Type /XObject /Subtype /Image /Width ${page.width} /Height ${page.height} /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length ${page.jpegBytes.byteLength} >>\\nstream\\n`,\n ),\n page.jpegBytes,\n enc(`\\nendstream`),\n );\n const imageId = add(imageStream);\n\n const content = `q\\n${page.pageWidth.toFixed(2)} 0 0 ${page.pageHeight.toFixed(2)} 0 0 cm\\n/Im0 Do\\nQ`;\n const contentId = add(\n enc(`<< /Length ${content.length} >>\\nstream\\n${content}\\nendstream`),\n );\n\n // Parent placeholder replaced after pages object exists\n const pageId = add(\n enc(\n `<< /Type /Page /Parent __PAGES__ 0 R /MediaBox [0 0 ${page.pageWidth.toFixed(2)} ${page.pageHeight.toFixed(2)}] /Contents ${contentId} 0 R /Resources << /XObject << /Im0 ${imageId} 0 R >> >> >>`,\n ),\n );\n pageIds.push(pageId);\n }\n\n const kids = pageIds.map((id) => `${id} 0 R`).join(\" \");\n const pagesId = add(\n enc(`<< /Type /Pages /Kids [${kids}] /Count ${pageIds.length} >>`),\n );\n\n for (const pageId of pageIds) {\n const text = new TextDecoder().decode(objects[pageId - 1]);\n objects[pageId - 1] = enc(\n text.replace(\"/Parent __PAGES__ 0 R\", `/Parent ${pagesId} 0 R`),\n );\n }\n\n const catalogId = add(enc(`<< /Type /Catalog /Pages ${pagesId} 0 R >>`));\n\n const chunks: Uint8Array[] = [enc(\"%PDF-1.4\\n\")];\n const offsets: number[] = [0];\n let offset = chunks[0].byteLength;\n\n for (let i = 0; i < objects.length; i += 1) {\n offsets.push(offset);\n const objHeader = enc(`${i + 1} 0 obj\\n`);\n const objFooter = enc(`\\nendobj\\n`);\n chunks.push(objHeader, objects[i], objFooter);\n offset += objHeader.byteLength + objects[i].byteLength + objFooter.byteLength;\n }\n\n const xrefStart = offset;\n let xref = `xref\\n0 ${objects.length + 1}\\n`;\n xref += \"0000000000 65535 f \\n\";\n for (let i = 1; i <= objects.length; i += 1) {\n xref += `${String(offsets[i]).padStart(10, \"0\")} 00000 n \\n`;\n }\n xref += `trailer\\n<< /Size ${objects.length + 1} /Root ${catalogId} 0 R >>\\n`;\n xref += `startxref\\n${xrefStart}\\n%%EOF`;\n chunks.push(enc(xref));\n\n return concat(...chunks);\n}\n\nexport function triggerBlobDownload(blob: Blob, filename: string): void {\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.download = filename;\n anchor.click();\n URL.revokeObjectURL(url);\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport type { SignatureFieldType } from \"./signature\";\n\ninterface SignaturePadProps {\n open: boolean;\n onClose: () => void;\n onSave: (imageDataUrl: string, width: number, height: number) => void;\n /** Saves plain text for date/text fields (not converted to an image). */\n onSaveFieldValue?: (value: string, fieldType: \"date\" | \"text\") => void;\n /** When set, locks the modal to this field type (from a fixed field). */\n fieldType?: SignatureFieldType;\n /** Show Sign/Date/Text tabs when no fixed field type is provided. */\n showFieldTypeTabs?: boolean;\n /** Placeholder for text-type fields. */\n textPlaceholder?: string;\n /** Prefill when reopening an already-filled date/text field. */\n initialFieldValue?: string;\n /** Last submitted values by field type — used to prefill the modal. */\n rememberedByType?: RememberedFieldFills;\n /** Persist the values the user just submitted for this field type. */\n onRememberFill?: (\n type: SignatureFieldType,\n fill: RememberedSignFill | { value: string },\n ) => void;\n}\n\ntype PadMode = \"draw\" | \"type\";\n\nexport type RememberedSignFill = {\n mode: PadMode;\n imageDataUrl: string;\n width: number;\n height: number;\n typedName?: string;\n typedInitials?: string;\n fontId?: string;\n inkColor?: string;\n typeKind?: \"signature\" | \"initials\";\n};\n\nexport type RememberedFieldFills = {\n sign?: RememberedSignFill;\n date?: { value: string };\n text?: { value: string };\n};\n\nconst HANDWRITING_FONTS = [\n { id: \"dancing-script\", label: \"Dancing Script\", family: \"Dancing Script\" },\n { id: \"great-vibes\", label: \"Great Vibes\", family: \"Great Vibes\" },\n { id: \"pacifico\", label: \"Pacifico\", family: \"Pacifico\" },\n { id: \"satisfy\", label: \"Satisfy\", family: \"Satisfy\" },\n { id: \"allura\", label: \"Allura\", family: \"Allura\" },\n] as const;\n\ntype HandwritingFontId = (typeof HANDWRITING_FONTS)[number][\"id\"];\n\nconst HANDWRITING_FONTS_HREF =\n \"https://fonts.googleapis.com/css2?family=Allura&family=Dancing+Script:wght@500;600&family=Great+Vibes&family=Pacifico&family=Satisfy&display=swap\";\n\nlet handwritingFontsPromise: Promise<void> | null = null;\nconst embeddedFontCssCache = new Map<string, Promise<string>>();\n\nfunction ensureHandwritingFonts(): Promise<void> {\n if (typeof document === \"undefined\") return Promise.resolve();\n if (handwritingFontsPromise) return handwritingFontsPromise;\n\n handwritingFontsPromise = new Promise((resolve) => {\n const existing = document.querySelector(\n `link[data-epochs-signature-fonts=\"true\"]`,\n );\n if (!existing) {\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n link.href = HANDWRITING_FONTS_HREF;\n link.dataset.epochsSignatureFonts = \"true\";\n document.head.appendChild(link);\n }\n\n const loadFaces = () =>\n Promise.all(\n HANDWRITING_FONTS.map((font) =>\n document.fonts.load(`48px \"${font.family}\"`),\n ),\n ).then(() => undefined);\n\n if (document.fonts?.ready) {\n document.fonts.ready.then(loadFaces).then(resolve).catch(() => resolve());\n } else {\n window.setTimeout(() => {\n loadFaces().then(resolve).catch(() => resolve());\n }, 300);\n }\n });\n\n return handwritingFontsPromise;\n}\n\nfunction escapeXml(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\");\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n let binary = \"\";\n const chunk = 0x8000;\n for (let i = 0; i < bytes.length; i += chunk) {\n binary += String.fromCharCode(...bytes.subarray(i, i + chunk));\n }\n return btoa(binary);\n}\n\nfunction typedSignatureFontSize(\n typeKind: \"signature\" | \"initials\",\n family: string,\n): number {\n if (typeKind === \"initials\") return 72;\n if (family === \"Great Vibes\" || family === \"Allura\") return 56;\n if (family === \"Pacifico\") return 44;\n return 48;\n}\n\n/** Embed Google Font face(s) as data URLs so SVG works as <img> / canvas. */\nfunction getEmbeddedFontCss(family: string): Promise<string> {\n const cached = embeddedFontCssCache.get(family);\n if (cached) return cached;\n\n const promise = (async () => {\n const familyParam = family.replace(/ /g, \"+\");\n const cssUrl = `https://fonts.googleapis.com/css2?family=${familyParam}&display=swap`;\n const cssText = await fetch(cssUrl).then((r) => {\n if (!r.ok) throw new Error(`Failed to load font CSS for ${family}`);\n return r.text();\n });\n\n const urls = [\n ...cssText.matchAll(/url\\((['\"]?)([^)'\"]+)\\1\\)/g),\n ].map((match) => match[2]);\n\n const uniqueUrls = [...new Set(urls)];\n const replacements = await Promise.all(\n uniqueUrls.map(async (fontUrl) => {\n const buffer = await fetch(fontUrl).then((r) => {\n if (!r.ok) throw new Error(`Failed to load font file: ${fontUrl}`);\n return r.arrayBuffer();\n });\n const ext = fontUrl.includes(\".woff2\")\n ? \"woff2\"\n : fontUrl.includes(\".woff\")\n ? \"woff\"\n : \"truetype\";\n const mime =\n ext === \"woff2\"\n ? \"font/woff2\"\n : ext === \"woff\"\n ? \"font/woff\"\n : \"font/ttf\";\n const dataUrl = `data:${mime};base64,${bytesToBase64(new Uint8Array(buffer))}`;\n return { fontUrl, dataUrl };\n }),\n );\n\n let embedded = cssText;\n for (const { fontUrl, dataUrl } of replacements) {\n embedded = embedded.split(fontUrl).join(dataUrl);\n }\n return embedded;\n })().catch(() => {\n embeddedFontCssCache.delete(family);\n return \"\";\n });\n\n embeddedFontCssCache.set(family, promise);\n return promise;\n}\n\nexport function SignaturePad({\n open,\n onClose,\n onSave,\n onSaveFieldValue,\n fieldType,\n showFieldTypeTabs = false,\n textPlaceholder,\n initialFieldValue,\n rememberedByType,\n onRememberFill,\n}: SignaturePadProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const drawingRef = useRef(false);\n const lastPointRef = useRef<{ x: number; y: number } | null>(null);\n const pathsRef = useRef<{ x: number; y: number }[][]>([]);\n const currentPathRef = useRef<{ x: number; y: number }[]>([]);\n const reusedSignatureRef = useRef<{\n imageDataUrl: string;\n width: number;\n height: number;\n } | null>(null);\n\n const resolvedFieldType: SignatureFieldType = fieldType ?? \"sign\";\n const [activeFieldType, setActiveFieldType] = useState<SignatureFieldType>(resolvedFieldType);\n const [dateValue, setDateValue] = useState(\"\");\n const [textValue, setTextValue] = useState(\"\");\n\n const [mode, setMode] = useState<PadMode>(\"draw\");\n const [typedName, setTypedName] = useState(\"\");\n const [typedInitials, setTypedInitials] = useState(\"\");\n const [initialsTouched, setInitialsTouched] = useState(false);\n const [typeKind, setTypeKind] = useState<\"signature\" | \"initials\">(\"signature\");\n const [inkColor, setInkColor] = useState(\"#111827\");\n const [fontId, setFontId] = useState<HandwritingFontId>(\"dancing-script\");\n const [fontsReady, setFontsReady] = useState(false);\n const [isSaving, setIsSaving] = useState(false);\n const [hasReusedSignature, setHasReusedSignature] = useState(false);\n\n const selectedFont =\n HANDWRITING_FONTS.find((font) => font.id === fontId) ?? HANDWRITING_FONTS[0];\n\n const previewText =\n typeKind === \"initials\" ? typedInitials.trim() : typedName.trim();\n const fontPreviewLabel =\n previewText || (typeKind === \"initials\" ? \"AB\" : \"Signature\");\n\n useEffect(() => {\n if (!open) return;\n setActiveFieldType(resolvedFieldType);\n\n if (resolvedFieldType === \"date\") {\n setDateValue(\n initialFieldValue ||\n rememberedByType?.date?.value ||\n new Date().toISOString().slice(0, 10),\n );\n return;\n }\n\n if (resolvedFieldType === \"text\") {\n setTextValue(initialFieldValue || rememberedByType?.text?.value || \"\");\n return;\n }\n\n const remembered = rememberedByType?.sign;\n if (!remembered) {\n setMode(\"draw\");\n setTypedName(\"\");\n setTypedInitials(\"\");\n setInitialsTouched(false);\n setTypeKind(\"signature\");\n setInkColor(\"#111827\");\n setFontId(\"dancing-script\");\n reusedSignatureRef.current = null;\n setHasReusedSignature(false);\n return;\n }\n\n setMode(remembered.mode);\n setTypedName(remembered.typedName ?? \"\");\n setTypedInitials(remembered.typedInitials ?? \"\");\n setInitialsTouched(Boolean(remembered.typedInitials));\n setTypeKind(remembered.typeKind ?? \"signature\");\n setInkColor(remembered.inkColor ?? \"#111827\");\n const nextFont = HANDWRITING_FONTS.find((font) => font.id === remembered.fontId);\n if (nextFont) setFontId(nextFont.id);\n if (remembered.mode === \"draw\") {\n reusedSignatureRef.current = {\n imageDataUrl: remembered.imageDataUrl,\n width: remembered.width,\n height: remembered.height,\n };\n setHasReusedSignature(true);\n } else {\n reusedSignatureRef.current = null;\n setHasReusedSignature(false);\n }\n }, [open, resolvedFieldType, rememberedByType, initialFieldValue]);\n\n useEffect(() => {\n if (!open || activeFieldType !== \"sign\") return;\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n\n canvas.width = 560;\n canvas.height = 200;\n ctx.fillStyle = \"#ffffff\";\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n ctx.strokeStyle = inkColor;\n ctx.lineWidth = 2.5;\n lastPointRef.current = null;\n drawingRef.current = false;\n pathsRef.current = [];\n currentPathRef.current = [];\n\n if (mode !== \"draw\") return;\n\n const reused = reusedSignatureRef.current;\n if (!reused?.imageDataUrl) return;\n\n const img = new Image();\n img.onload = () => {\n const scale = Math.min(\n canvas.width / Math.max(1, reused.width),\n canvas.height / Math.max(1, reused.height),\n 1,\n );\n const w = reused.width * scale;\n const h = reused.height * scale;\n ctx.drawImage(img, (canvas.width - w) / 2, (canvas.height - h) / 2, w, h);\n };\n img.src = reused.imageDataUrl;\n }, [open, activeFieldType, mode]);\n\n useEffect(() => {\n if (!open) return;\n let cancelled = false;\n setFontsReady(false);\n ensureHandwritingFonts().then(() => {\n if (!cancelled) setFontsReady(true);\n });\n return () => {\n cancelled = true;\n };\n }, [open]);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext(\"2d\");\n if (!ctx) return;\n ctx.strokeStyle = inkColor;\n ctx.fillStyle = inkColor;\n }, [inkColor]);\n\n useEffect(() => {\n if (!open || mode !== \"type\") return;\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext(\"2d\");\n if (!canvas || !ctx) return;\n\n ctx.fillStyle = \"#ffffff\";\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n\n if (!previewText) return;\n\n const size = typedSignatureFontSize(typeKind, selectedFont.family);\n\n ctx.fillStyle = inkColor;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.font = `${size}px \"${selectedFont.family}\", cursive`;\n ctx.fillText(previewText, canvas.width / 2, canvas.height / 2);\n }, [\n previewText,\n typeKind,\n mode,\n inkColor,\n open,\n selectedFont,\n fontsReady,\n ]);\n\n if (!open) return null;\n\n const getPoint = (event: React.PointerEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current!;\n const rect = canvas.getBoundingClientRect();\n return {\n x: ((event.clientX - rect.left) / rect.width) * canvas.width,\n y: ((event.clientY - rect.top) / rect.height) * canvas.height,\n };\n };\n\n const handlePointerDown = (event: React.PointerEvent<HTMLCanvasElement>) => {\n if (mode !== \"draw\") return;\n if (reusedSignatureRef.current) {\n reusedSignatureRef.current = null;\n setHasReusedSignature(false);\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext(\"2d\");\n if (canvas && ctx) {\n ctx.fillStyle = \"#ffffff\";\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n ctx.strokeStyle = inkColor;\n ctx.lineWidth = 2.5;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n }\n pathsRef.current = [];\n }\n event.currentTarget.setPointerCapture(event.pointerId);\n drawingRef.current = true;\n const pt = getPoint(event);\n lastPointRef.current = pt;\n currentPathRef.current = [pt];\n };\n\n const handlePointerMove = (event: React.PointerEvent<HTMLCanvasElement>) => {\n if (!drawingRef.current || mode !== \"draw\") return;\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext(\"2d\");\n const last = lastPointRef.current;\n if (!ctx || !last) return;\n\n const point = getPoint(event);\n ctx.beginPath();\n ctx.moveTo(last.x, last.y);\n ctx.lineTo(point.x, point.y);\n ctx.stroke();\n lastPointRef.current = point;\n currentPathRef.current.push(point);\n };\n\n const handlePointerUp = () => {\n if (currentPathRef.current.length > 1) {\n pathsRef.current.push([...currentPathRef.current]);\n }\n currentPathRef.current = [];\n drawingRef.current = false;\n lastPointRef.current = null;\n };\n\n const clearPad = () => {\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext(\"2d\");\n if (!canvas || !ctx) return;\n ctx.fillStyle = \"#ffffff\";\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n pathsRef.current = [];\n currentPathRef.current = [];\n reusedSignatureRef.current = null;\n setHasReusedSignature(false);\n setTypedName(\"\");\n setTypedInitials(\"\");\n setInitialsTouched(false);\n };\n\n const handleNameChange = (value: string) => {\n setTypedName(value);\n if (!initialsTouched) {\n setTypedInitials(deriveInitials(value));\n }\n };\n\n const trimAndSave = () => {\n if (mode === \"draw\") {\n const allPaths = pathsRef.current;\n const reused = reusedSignatureRef.current;\n if (allPaths.length === 0) {\n if (!reused) return;\n onRememberFill?.(\"sign\", {\n mode: \"draw\",\n imageDataUrl: reused.imageDataUrl,\n width: reused.width,\n height: reused.height,\n inkColor,\n });\n onSave(reused.imageDataUrl, reused.width, reused.height);\n return;\n }\n\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const path of allPaths) {\n for (const pt of path) {\n if (pt.x < minX) minX = pt.x;\n if (pt.y < minY) minY = pt.y;\n if (pt.x > maxX) maxX = pt.x;\n if (pt.y > maxY) maxY = pt.y;\n }\n }\n\n const pad = 8;\n minX = Math.max(0, minX - pad);\n minY = Math.max(0, minY - pad);\n maxX += pad;\n maxY += pad;\n const w = maxX - minX;\n const h = maxY - minY;\n\n const pathData = allPaths\n .map((path) => {\n const pts = path.map((pt) => ({ x: pt.x - minX, y: pt.y - minY }));\n return \"M\" + pts.map((p) => `${p.x.toFixed(1)},${p.y.toFixed(1)}`).join(\"L\");\n })\n .join(\" \");\n\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${w.toFixed(0)}\" height=\"${h.toFixed(0)}\" viewBox=\"0 0 ${w.toFixed(0)} ${h.toFixed(0)}\"><path d=\"${pathData}\" fill=\"none\" stroke=\"${inkColor}\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`;\n const dataUrl = `data:image/svg+xml;base64,${btoa(svg)}`;\n onRememberFill?.(\"sign\", {\n mode: \"draw\",\n imageDataUrl: dataUrl,\n width: w,\n height: h,\n inkColor,\n });\n onSave(dataUrl, w, h);\n return;\n }\n\n if (!previewText) return;\n\n const size = typedSignatureFontSize(typeKind, selectedFont.family);\n const measureCanvas = document.createElement(\"canvas\");\n const measureCtx = measureCanvas.getContext(\"2d\")!;\n measureCtx.font = `${size}px \"${selectedFont.family}\", cursive`;\n const metrics = measureCtx.measureText(previewText);\n const pad = 12;\n const w = Math.ceil(metrics.width) + pad * 2;\n const h = size + pad * 2;\n const text = previewText;\n const family = selectedFont.family;\n const color = inkColor;\n const rememberSign: RememberedSignFill = {\n mode: \"type\",\n imageDataUrl: \"\",\n width: w,\n height: h,\n typedName,\n typedInitials,\n fontId,\n inkColor: color,\n typeKind,\n };\n\n setIsSaving(true);\n void (async () => {\n try {\n const fontCss = await getEmbeddedFontCss(family);\n const styleBlock = [\n fontCss,\n `text{font-family:'${family}',cursive;font-size:${size}px;fill:${color}}`,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n const svg = [\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${w}\" height=\"${h}\" viewBox=\"0 0 ${w} ${h}\">`,\n `<style type=\"text/css\"><![CDATA[${styleBlock}]]></style>`,\n `<text x=\"${pad}\" y=\"${(h / 2).toFixed(1)}\" dominant-baseline=\"middle\">${escapeXml(text)}</text>`,\n `</svg>`,\n ].join(\"\");\n\n const dataUrl = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;\n onRememberFill?.(\"sign\", { ...rememberSign, imageDataUrl: dataUrl });\n onSave(dataUrl, w, h);\n } finally {\n setIsSaving(false);\n }\n })();\n };\n\n const handleFieldValueSave = () => {\n if (activeFieldType !== \"date\" && activeFieldType !== \"text\") return;\n const text =\n activeFieldType === \"date\" ? dateValue : textValue.trim();\n if (!text) return;\n\n onRememberFill?.(activeFieldType, { value: text });\n onSaveFieldValue?.(text, activeFieldType);\n };\n\n const showSignPad = activeFieldType === \"sign\";\n const modalTitle =\n activeFieldType === \"date\"\n ? \"Pick a date\"\n : activeFieldType === \"text\"\n ? \"Enter text\"\n : \"Create e-signature\";\n\n return (\n <div className=\"epochs-pdf-viewer__modal\" role=\"dialog\" aria-modal=\"true\">\n <div className=\"epochs-pdf-viewer__modal-backdrop\" onClick={onClose} />\n <div className=\"epochs-pdf-viewer__modal-card\">\n <div className=\"epochs-pdf-viewer__modal-header\">\n <h3>{modalTitle}</h3>\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={onClose}\n title=\"Close\"\n >\n ×\n </button>\n </div>\n\n {showFieldTypeTabs && !fieldType ? (\n <div className=\"epochs-pdf-viewer__field-type-tabs\" role=\"tablist\">\n {([\"sign\", \"date\", \"text\"] as const).map((t) => (\n <button\n key={t}\n type=\"button\"\n role=\"tab\"\n aria-selected={activeFieldType === t}\n className={\n activeFieldType === t\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n }\n onClick={() => setActiveFieldType(t)}\n >\n {t === \"sign\" ? \"Sign\" : t === \"date\" ? \"Date\" : \"Text\"}\n </button>\n ))}\n </div>\n ) : null}\n\n {showSignPad ? (\n <>\n <div className=\"epochs-pdf-viewer__sign-modes\">\n <button\n type=\"button\"\n className={\n mode === \"draw\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n }\n onClick={() => {\n setMode(\"draw\");\n clearPad();\n }}\n >\n Draw\n </button>\n <button\n type=\"button\"\n className={\n mode === \"type\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n }\n onClick={() => setMode(\"type\")}\n >\n Type\n </button>\n <label className=\"epochs-pdf-viewer__sign-ink\">\n Ink\n <input\n type=\"color\"\n value={inkColor}\n onChange={(e) => setInkColor(e.target.value)}\n />\n </label>\n </div>\n\n {mode === \"type\" ? (\n <>\n <div\n className=\"epochs-pdf-viewer__sign-fonts\"\n role=\"group\"\n aria-label=\"Handwriting style\"\n >\n {HANDWRITING_FONTS.map((font) => (\n <button\n key={font.id}\n type=\"button\"\n className={\n fontId === font.id\n ? \"epochs-pdf-viewer__sign-font epochs-pdf-viewer__sign-font--active\"\n : \"epochs-pdf-viewer__sign-font\"\n }\n style={{ fontFamily: `\"${font.family}\", cursive` }}\n onClick={() => setFontId(font.id)}\n title={font.label}\n >\n {fontPreviewLabel}\n </button>\n ))}\n </div>\n\n <div className=\"epochs-pdf-viewer__sign-type-fields\">\n <label className=\"epochs-pdf-viewer__sign-type-field\">\n <span>Full name</span>\n <input\n className=\"epochs-pdf-viewer__sign-type-input\"\n type=\"text\"\n value={typedName}\n onChange={(e) => handleNameChange(e.target.value)}\n onFocus={() => setTypeKind(\"signature\")}\n placeholder=\"Type your full name\"\n style={{ fontFamily: `\"${selectedFont.family}\", cursive` }}\n autoFocus\n />\n </label>\n <label className=\"epochs-pdf-viewer__sign-type-field\">\n <span>Initials</span>\n <input\n className=\"epochs-pdf-viewer__sign-type-input\"\n type=\"text\"\n value={typedInitials}\n onChange={(e) => {\n setInitialsTouched(true);\n setTypedInitials(e.target.value.toUpperCase());\n }}\n onFocus={() => setTypeKind(\"initials\")}\n placeholder=\"e.g. JD\"\n maxLength={4}\n style={{ fontFamily: `\"${selectedFont.family}\", cursive` }}\n />\n </label>\n </div>\n\n <div\n className=\"epochs-pdf-viewer__sign-type-kind\"\n role=\"group\"\n aria-label=\"Preview type\"\n >\n <button\n type=\"button\"\n className={\n typeKind === \"signature\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n }\n onClick={() => setTypeKind(\"signature\")}\n >\n Use full name\n </button>\n <button\n type=\"button\"\n className={\n typeKind === \"initials\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n }\n onClick={() => setTypeKind(\"initials\")}\n >\n Use initials\n </button>\n </div>\n </>\n ) : (\n <p className=\"epochs-pdf-viewer__sign-hint\">\n {hasReusedSignature\n ? \"Previous signature loaded — submit to reuse, or draw a new one\"\n : \"Draw your signature below\"}\n </p>\n )}\n\n <canvas\n ref={canvasRef}\n className={\n mode === \"draw\"\n ? \"epochs-pdf-viewer__sign-canvas\"\n : \"epochs-pdf-viewer__sign-canvas epochs-pdf-viewer__sign-canvas--preview\"\n }\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerLeave={handlePointerUp}\n />\n </>\n ) : activeFieldType === \"date\" ? (\n <label className=\"epochs-pdf-viewer__sign-type-field\" style={{ padding: \"1rem\" }}>\n <span>Date</span>\n <input\n className=\"epochs-pdf-viewer__sign-type-input\"\n type=\"date\"\n value={dateValue}\n onChange={(e) => setDateValue(e.target.value)}\n autoFocus\n />\n </label>\n ) : (\n <label className=\"epochs-pdf-viewer__sign-type-field\" style={{ padding: \"1rem\" }}>\n <span>Text</span>\n <input\n className=\"epochs-pdf-viewer__sign-type-input\"\n type=\"text\"\n value={textValue}\n onChange={(e) => setTextValue(e.target.value)}\n placeholder={textPlaceholder ?? \"Enter text\"}\n autoFocus\n />\n </label>\n )}\n\n <div className=\"epochs-pdf-viewer__modal-actions\">\n {showSignPad ? (\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n onClick={clearPad}\n >\n Clear\n </button>\n ) : null}\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n onClick={onClose}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text epochs-pdf-viewer__btn--primary\"\n onClick={showSignPad ? trimAndSave : handleFieldValueSave}\n disabled={\n isSaving ||\n (activeFieldType === \"date\" ? !dateValue\n : activeFieldType === \"text\" ? !textValue.trim()\n : false)\n }\n >\n {isSaving ? \"Saving…\" : showSignPad ? \"Use signature\" : \"Place on page\"}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\nfunction deriveInitials(name: string): string {\n const parts = name\n .trim()\n .split(/\\s+/)\n .filter(Boolean);\n if (parts.length === 0) return \"\";\n if (parts.length === 1) {\n return parts[0].slice(0, 2).toUpperCase();\n }\n return parts\n .slice(0, 3)\n .map((part) => part[0]?.toUpperCase() ?? \"\")\n .join(\"\");\n}\n\n","/** Brand key used to identify toolbar tool components. */\nexport const TOOLBAR_TOOL_ID = \"__epochsToolbarToolId\" as const;\n\nexport type ToolbarToolId =\n | \"thumbnail\"\n | \"navigation\"\n | \"zoom\"\n | \"rotate\"\n | \"reload\"\n | \"print\"\n | \"open\"\n | \"download\"\n | \"highlight\"\n | \"underline\"\n | \"signature\"\n | \"text\"\n | \"erase\"\n | \"clear\";\n\nexport type ToolbarToolComponent = {\n (props?: Record<string, never>): null;\n displayName: string;\n readonly [TOOLBAR_TOOL_ID]: ToolbarToolId;\n};\n\nfunction createToolbarTool(\n id: ToolbarToolId,\n displayName: string,\n): ToolbarToolComponent {\n const Tool = (() => null) as ToolbarToolComponent;\n Tool.displayName = displayName;\n Object.defineProperty(Tool, TOOLBAR_TOOL_ID, {\n value: id,\n enumerable: true,\n });\n return Tool;\n}\n\nexport function getToolbarToolId(\n tool: ToolbarToolComponent,\n): ToolbarToolId {\n return tool[TOOLBAR_TOOL_ID];\n}\n\nexport function isToolbarTool(\n value: unknown,\n): value is ToolbarToolComponent {\n return (\n typeof value === \"function\" &&\n TOOLBAR_TOOL_ID in value &&\n typeof (value as ToolbarToolComponent)[TOOLBAR_TOOL_ID] === \"string\"\n );\n}\n\n/** Toggle thumbnails sidebar. */\nexport const Thumbnail = createToolbarTool(\"thumbnail\", \"Thumbnail\");\n/** Previous / next page and page number. */\nexport const Navigation = createToolbarTool(\"navigation\", \"Navigation\");\n/** Zoom out, zoom %, zoom in, and fit width. */\nexport const Zoom = createToolbarTool(\"zoom\", \"Zoom\");\n/** Rotate pages. */\nexport const Rotate = createToolbarTool(\"rotate\", \"Rotate\");\n/** Reload the PDF. */\nexport const Reload = createToolbarTool(\"reload\", \"Reload\");\n/** Print (includes markup). */\nexport const Print = createToolbarTool(\"print\", \"Print\");\n/** Open PDF in a new tab. */\nexport const Open = createToolbarTool(\"open\", \"Open\");\n/** Download PDF (with markup when present). */\nexport const Download = createToolbarTool(\"download\", \"Download\");\n/** Highlight text markup tool. */\nexport const Highlight = createToolbarTool(\"highlight\", \"Highlight\");\n/** Underline text markup tool. */\nexport const Underline = createToolbarTool(\"underline\", \"Underline\");\n/** E-signature tool. */\nexport const Signature = createToolbarTool(\"signature\", \"Signature\");\n/** Add / edit free text on the page. */\nexport const AddText = createToolbarTool(\"text\", \"AddText\");\n/** Erase markup annotations. */\nexport const Erase = createToolbarTool(\"erase\", \"Erase\");\n/** Clear all markup. */\nexport const Clear = createToolbarTool(\"clear\", \"Clear\");\n\nexport const ALL_TOOLBAR_TOOLS = [\n Thumbnail,\n Navigation,\n Zoom,\n Rotate,\n Highlight,\n Underline,\n Signature,\n AddText,\n Erase,\n Clear,\n Reload,\n Print,\n Open,\n Download,\n] as const;\n\n/** Default left / right toolbar layout. */\nexport const DEFAULT_TOOLBAR_LAYOUT: [\n ToolbarToolComponent[],\n ToolbarToolComponent[],\n] = [\n [Thumbnail, Navigation],\n [\n Zoom,\n Rotate,\n Highlight,\n Underline,\n Signature,\n AddText,\n Erase,\n Clear,\n Reload,\n Print,\n Open,\n Download,\n ],\n];\n","import type { ReactNode } from \"react\";\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n DownloadIcon,\n EraserIcon,\n ExternalLinkIcon,\n GridIcon,\n HighlightIcon,\n MinusIcon,\n PlusIcon,\n PrinterIcon,\n RefreshIcon,\n RotateIcon,\n SignatureIcon,\n TextIcon,\n UnderlineIcon,\n} from \"./icons\";\nimport type { MarkupTool } from \"./markup\";\nimport {\n HIGHLIGHT_PRESETS,\n UNDERLINE_PRESETS,\n normalizeHex,\n} from \"./markup\";\nimport type { ToolbarToolId } from \"./toolbarTools\";\n\nexport type ToolbarRenderContext = {\n status: string;\n showThumbnails: boolean;\n setShowThumbnails: (updater: (v: boolean) => boolean) => void;\n canGoPrev: boolean;\n canGoNext: boolean;\n handlePrev: () => void;\n handleNext: () => void;\n pageNumber: number;\n numPages: number;\n scrollToPage: (page: number) => void;\n scale: number;\n handleZoomOut: () => void;\n handleZoomIn: () => void;\n handleFitWidth: () => void | Promise<void>;\n handleRotate: () => void;\n markupTool: MarkupTool;\n toggleMarkupTool: (tool: Exclude<MarkupTool, \"none\">) => void;\n hasFixedSignatureFields: boolean;\n hasFixedTextFields: boolean;\n pendingSignature: { imageDataUrl: string; width: number; height: number } | null;\n setMarkupTool: (tool: MarkupTool) => void;\n setSignaturePadOpen: (open: boolean) => void;\n annotationsLength: number;\n signaturesLength: number;\n textsLength: number;\n handleClearAnnotations: () => void;\n highlightHex: string;\n underlineHex: string;\n setHighlightHex: (hex: string) => void;\n setUnderlineHex: (hex: string) => void;\n loadDocument: () => void | Promise<void>;\n handlePrint: () => void | Promise<void>;\n isPrinting: boolean;\n pdfDoc: unknown;\n displayUrl: string | null;\n resolvedUrl: string;\n handleDownload: () => void | Promise<void>;\n isDownloading: boolean;\n};\n\nconst MARKUP_TOOLS: ToolbarToolId[] = [\n \"highlight\",\n \"underline\",\n \"signature\",\n \"text\",\n \"erase\",\n \"clear\",\n];\n\nexport function isMarkupToolbarTool(id: ToolbarToolId): boolean {\n return MARKUP_TOOLS.includes(id);\n}\n\nexport function renderToolbarTool(\n id: ToolbarToolId,\n ctx: ToolbarRenderContext,\n options?: { showMarkupSep?: boolean },\n): ReactNode {\n const nodes: ReactNode[] = [];\n\n if (options?.showMarkupSep) {\n nodes.push(\n <span\n key={`${id}-sep`}\n className=\"epochs-pdf-viewer__toolbar-sep\"\n aria-hidden=\"true\"\n />,\n );\n }\n\n switch (id) {\n case \"thumbnail\":\n nodes.push(\n <button\n key=\"thumbnail\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={() => ctx.setShowThumbnails((v) => !v)}\n title={ctx.showThumbnails ? \"Hide thumbnails\" : \"Show thumbnails\"}\n >\n <GridIcon />\n </button>,\n );\n break;\n\n case \"navigation\":\n nodes.push(\n <button\n key=\"nav-prev\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={ctx.handlePrev}\n disabled={!ctx.canGoPrev || ctx.status !== \"ready\"}\n title=\"Previous page\"\n >\n <ChevronLeftIcon />\n </button>,\n <div key=\"nav-page\" className=\"epochs-pdf-viewer__page-input\">\n <input\n type=\"number\"\n value={ctx.pageNumber}\n min={1}\n max={ctx.numPages || 1}\n onChange={(e) => {\n const next = Number.parseInt(e.target.value, 10);\n if (!Number.isFinite(next)) return;\n ctx.scrollToPage(\n Math.max(1, Math.min(ctx.numPages || 1, next)),\n );\n }}\n disabled={ctx.status !== \"ready\"}\n aria-label=\"Page number\"\n />\n <span>/ {ctx.numPages || \"-\"}</span>\n </div>,\n <button\n key=\"nav-next\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={ctx.handleNext}\n disabled={!ctx.canGoNext || ctx.status !== \"ready\"}\n title=\"Next page\"\n >\n <ChevronRightIcon />\n </button>,\n );\n break;\n\n case \"zoom\":\n nodes.push(\n <button\n key=\"zoom-out\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={ctx.handleZoomOut}\n disabled={ctx.status !== \"ready\"}\n title=\"Zoom out\"\n >\n <MinusIcon />\n </button>,\n <span key=\"zoom-label\" className=\"epochs-pdf-viewer__zoom-label\">\n {Math.round(ctx.scale * 100)}%\n </span>,\n <button\n key=\"zoom-in\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={ctx.handleZoomIn}\n disabled={ctx.status !== \"ready\"}\n title=\"Zoom in\"\n >\n <PlusIcon />\n </button>,\n <button\n key=\"zoom-fit\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n onClick={() => void ctx.handleFitWidth()}\n disabled={ctx.status !== \"ready\"}\n title=\"Fit to width\"\n >\n Fit\n </button>,\n );\n break;\n\n case \"rotate\":\n nodes.push(\n <button\n key=\"rotate\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={ctx.handleRotate}\n disabled={ctx.status !== \"ready\"}\n title=\"Rotate\"\n >\n <RotateIcon />\n </button>,\n );\n break;\n\n case \"highlight\":\n nodes.push(\n <button\n key=\"highlight\"\n type=\"button\"\n className={\n ctx.markupTool === \"highlight\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn\"\n }\n onClick={() => ctx.toggleMarkupTool(\"highlight\")}\n disabled={ctx.status !== \"ready\"}\n title=\"Highlight text — select text to highlight\"\n >\n <HighlightIcon />\n </button>,\n );\n break;\n\n case \"underline\":\n nodes.push(\n <button\n key=\"underline\"\n type=\"button\"\n className={\n ctx.markupTool === \"underline\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn\"\n }\n onClick={() => ctx.toggleMarkupTool(\"underline\")}\n disabled={ctx.status !== \"ready\"}\n title=\"Underline text — select text to underline\"\n >\n <UnderlineIcon />\n </button>,\n );\n break;\n\n case \"signature\":\n nodes.push(\n <button\n key=\"signature\"\n type=\"button\"\n className={\n ctx.markupTool === \"sign\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn\"\n }\n onClick={() => {\n if (\n !ctx.hasFixedSignatureFields &&\n ctx.pendingSignature &&\n ctx.markupTool !== \"sign\"\n ) {\n ctx.setMarkupTool(\"sign\");\n return;\n }\n ctx.setSignaturePadOpen(true);\n }}\n disabled={ctx.status !== \"ready\"}\n title={\n ctx.hasFixedSignatureFields\n ? \"Create e-signature for a fixed field\"\n : ctx.pendingSignature\n ? \"Place signature — click on the page, then drag to move\"\n : \"Create e-signature\"\n }\n >\n <SignatureIcon />\n </button>,\n );\n break;\n\n case \"text\":\n nodes.push(\n <button\n key=\"text\"\n type=\"button\"\n className={\n ctx.markupTool === \"text\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn\"\n }\n onClick={() => ctx.toggleMarkupTool(\"text\")}\n disabled={ctx.status !== \"ready\"}\n title={\n ctx.hasFixedTextFields\n ? \"Edit text in predefined areas — click to type\"\n : \"Edit PDF text — select words, then change them\"\n }\n >\n <TextIcon />\n </button>,\n );\n break;\n\n case \"erase\":\n nodes.push(\n <button\n key=\"erase\"\n type=\"button\"\n className={\n ctx.markupTool === \"erase\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn\"\n }\n onClick={() => ctx.toggleMarkupTool(\"erase\")}\n disabled={ctx.status !== \"ready\"}\n title=\"Remove text — select PDF words to cover them, or click added markup\"\n >\n <EraserIcon />\n </button>,\n );\n break;\n\n case \"clear\":\n nodes.push(\n <button\n key=\"clear\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n onClick={ctx.handleClearAnnotations}\n disabled={\n ctx.status !== \"ready\" ||\n (ctx.annotationsLength === 0 &&\n ctx.signaturesLength === 0 &&\n ctx.textsLength === 0)\n }\n title=\"Clear all markup\"\n >\n Clear\n </button>,\n );\n break;\n\n case \"reload\":\n nodes.push(\n <button\n key=\"reload\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={() => void ctx.loadDocument()}\n title=\"Reload\"\n >\n <RefreshIcon />\n </button>,\n );\n break;\n\n case \"print\":\n nodes.push(\n <button\n key=\"print\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={() => void ctx.handlePrint()}\n disabled={ctx.status !== \"ready\" || !ctx.pdfDoc || ctx.isPrinting}\n title={\n ctx.isPrinting\n ? \"Preparing print…\"\n : \"Print (includes highlights & underlines)\"\n }\n >\n <PrinterIcon />\n </button>,\n );\n break;\n\n case \"open\":\n nodes.push(\n <a\n key=\"open\"\n className=\"epochs-pdf-viewer__btn\"\n href={ctx.displayUrl || ctx.resolvedUrl || undefined}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title=\"Open in new tab\"\n >\n <ExternalLinkIcon />\n </a>,\n );\n break;\n\n case \"download\":\n nodes.push(\n <button\n key=\"download\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={() => void ctx.handleDownload()}\n disabled={\n ctx.status !== \"ready\" || !ctx.pdfDoc || ctx.isDownloading\n }\n title={\n ctx.isDownloading\n ? \"Preparing download…\"\n : ctx.annotationsLength > 0 ||\n ctx.signaturesLength > 0 ||\n ctx.textsLength > 0\n ? \"Download PDF with markup\"\n : \"Download PDF\"\n }\n >\n <DownloadIcon />\n </button>,\n );\n break;\n\n default:\n break;\n }\n\n return nodes.length > 0 ? nodes : null;\n}\n\nexport function renderMarkupExtras(\n ctx: ToolbarRenderContext,\n enabledIds: Set<ToolbarToolId>,\n): ReactNode {\n const nodes: ReactNode[] = [];\n\n if (\n ctx.markupTool === \"sign\" &&\n ctx.pendingSignature &&\n !ctx.hasFixedSignatureFields &&\n enabledIds.has(\"signature\")\n ) {\n nodes.push(\n <span key=\"sign-hint\" className=\"epochs-pdf-viewer__markup-hint\">\n Click page to place duplicate/new signature\n </span>,\n );\n }\n\n if (\n ctx.markupTool === \"text\" &&\n enabledIds.has(\"text\")\n ) {\n nodes.push(\n <span key=\"text-hint\" className=\"epochs-pdf-viewer__markup-hint\">\n {ctx.hasFixedTextFields\n ? \"Click in a predefined text area to type\"\n : \"Select text to edit it — e.g. change this PDF to this is PDF\"}\n </span>,\n );\n }\n\n if (\n ctx.markupTool === \"erase\" &&\n enabledIds.has(\"erase\")\n ) {\n nodes.push(\n <span key=\"erase-hint\" className=\"epochs-pdf-viewer__markup-hint\">\n Select PDF words to remove · click added text/markup to erase\n </span>,\n );\n }\n\n if (\n (ctx.markupTool === \"highlight\" && enabledIds.has(\"highlight\")) ||\n (ctx.markupTool === \"underline\" && enabledIds.has(\"underline\"))\n ) {\n const activeMarkupHex =\n ctx.markupTool === \"highlight\" ? ctx.highlightHex : ctx.underlineHex;\n const setActiveMarkupHex =\n ctx.markupTool === \"highlight\" ? ctx.setHighlightHex : ctx.setUnderlineHex;\n const activePresets =\n ctx.markupTool === \"highlight\" ? HIGHLIGHT_PRESETS : UNDERLINE_PRESETS;\n\n nodes.push(\n <div\n key=\"color-picker\"\n className=\"epochs-pdf-viewer__color-picker\"\n role=\"group\"\n aria-label={`${ctx.markupTool} color`}\n >\n {activePresets.map((preset) => (\n <button\n key={preset.id}\n type=\"button\"\n className={\n normalizeHex(activeMarkupHex) === normalizeHex(preset.hex)\n ? \"epochs-pdf-viewer__swatch epochs-pdf-viewer__swatch--active\"\n : \"epochs-pdf-viewer__swatch\"\n }\n style={{ background: preset.hex }}\n title={preset.label}\n aria-label={preset.label}\n aria-pressed={\n normalizeHex(activeMarkupHex) === normalizeHex(preset.hex)\n }\n onClick={() => setActiveMarkupHex(normalizeHex(preset.hex))}\n />\n ))}\n <label\n className=\"epochs-pdf-viewer__custom-color\"\n title=\"Custom color\"\n >\n <span\n className=\"epochs-pdf-viewer__custom-color-chip\"\n style={{ background: activeMarkupHex }}\n />\n <input\n type=\"color\"\n value={normalizeHex(activeMarkupHex)}\n onChange={(e) =>\n setActiveMarkupHex(normalizeHex(e.target.value))\n }\n aria-label=\"Custom color\"\n />\n </label>\n </div>,\n );\n }\n\n return nodes.length > 0 ? nodes : null;\n}\n","import {\n Fragment,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n} from \"react\";\nimport { PageCanvas } from \"./PageCanvas\";\nimport { Thumbnail as ThumbnailStrip } from \"./Thumbnail\";\nimport {\n ensurePdfWorker,\n pdfjsLib,\n resolvePdfUrl,\n sourceToArrayBuffer,\n} from \"./load\";\nimport type { PdfDoc, PdfViewerProps, ToolbarLayout, ViewerStatus } from \"./types\";\nimport type { MarkupAnnotation, MarkupTool } from \"./markup\";\nimport {\n DEFAULT_HIGHLIGHT_HEX,\n DEFAULT_UNDERLINE_HEX,\n hexToMarkupColor,\n} from \"./markup\";\nimport {\n buildPdfFromJpegPages,\n renderAllPagesWithMarkup,\n triggerBlobDownload,\n} from \"./exportPages\";\nimport { SignaturePad } from \"./SignaturePad\";\nimport type { RememberedFieldFills, RememberedSignFill } from \"./SignaturePad\";\nimport type { SignatureAnnotation, SignatureField } from \"./signature\";\nimport { createSignatureId, signatureDisplaySize } from \"./signature\";\nimport { pageSizeFromSurface, viewportRectToPage } from \"./coords\";\nimport type { TextAnnotation } from \"./text\";\nimport {\n createTextId,\n DEFAULT_TEXT_COLOR,\n DEFAULT_TEXT_FONT_SIZE,\n} from \"./text\";\nimport {\n DEFAULT_TOOLBAR_LAYOUT,\n getToolbarToolId,\n isToolbarTool,\n type ToolbarToolComponent,\n type ToolbarToolId,\n} from \"./toolbarTools\";\nimport {\n isMarkupToolbarTool,\n renderMarkupExtras,\n renderToolbarTool,\n type ToolbarRenderContext,\n} from \"./ToolbarButtons\";\nimport \"./PdfViewer.css\";\n\nfunction resolveToolbarLayout(\n enableToolbar: boolean | ToolbarLayout | undefined,\n flags: {\n enableThumbnails?: boolean;\n enableNavigation: boolean;\n enableZoom: boolean;\n enableRotate: boolean;\n enableReload: boolean;\n enablePrint: boolean;\n enableOpen: boolean;\n enableDownload: boolean;\n enableHighlight: boolean;\n enableUnderline: boolean;\n enableSignature: boolean;\n enableText: boolean;\n enableErase: boolean;\n enableClear: boolean;\n },\n): { left: ToolbarToolId[]; right: ToolbarToolId[] } | null {\n if (!enableToolbar) return null;\n\n if (Array.isArray(enableToolbar)) {\n const toIds = (side: ToolbarToolComponent[] | undefined) =>\n (side ?? [])\n .filter(isToolbarTool)\n .map(getToolbarToolId);\n\n return {\n left: toIds(enableToolbar[0]),\n right: toIds(enableToolbar[1]),\n };\n }\n\n const showThumbnailsToggle = flags.enableThumbnails;\n const filterByFlag = (\n tools: readonly ToolbarToolComponent[],\n enabled: Partial<Record<ToolbarToolId, boolean>>,\n ) =>\n tools\n .map(getToolbarToolId)\n .filter((id) => enabled[id] !== false);\n\n const flagMap: Partial<Record<ToolbarToolId, boolean>> = {\n thumbnail: showThumbnailsToggle,\n navigation: flags.enableNavigation,\n zoom: flags.enableZoom,\n rotate: flags.enableRotate,\n reload: flags.enableReload,\n print: flags.enablePrint,\n open: flags.enableOpen,\n download: flags.enableDownload,\n highlight: flags.enableHighlight,\n underline: flags.enableUnderline,\n signature: flags.enableSignature,\n text: flags.enableText,\n erase: flags.enableErase,\n clear: flags.enableClear,\n };\n\n return {\n left: filterByFlag(DEFAULT_TOOLBAR_LAYOUT[0], flagMap),\n right: filterByFlag(DEFAULT_TOOLBAR_LAYOUT[1], flagMap),\n };\n}\n\nexport function PdfViewer({\n file,\n fileUrl,\n baseUrl = \"\",\n fetchOptions,\n height = \"80vh\",\n title = \"PDF document\",\n initialScale = 1,\n withThumbnails = false,\n thumbnailWidth = 140,\n maxThumbnails = 60,\n className,\n workerSrc,\n enableToolbar = false,\n enableThumbnails,\n enableNavigation = true,\n enableZoom = true,\n enableRotate = true,\n enableReload = true,\n enablePrint = true,\n enableOpen = true,\n enableDownload = true,\n enableMarkup = true,\n enableHighlight = true,\n enableUnderline = true,\n enableSignature = true,\n enableText = true,\n enableErase = true,\n enableClear = true,\n signatureFields: signatureFieldsProp = [],\n textFields = [],\n onSignatureComplete,\n onSignatureFieldsChange,\n applySignatureToSameTag = false,\n onFieldValueComplete,\n openSignaturePad: externalOpenSignaturePad = false,\n onSignaturePadClose,\n onSubmit,\n submitLabel = \"Submit\",\n submitLoading = false,\n}: PdfViewerProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const lastBlobUrlRef = useRef<string | null>(null);\n const pageRefsRef = useRef(new Map<number, HTMLDivElement | null>());\n const isProgrammaticScrollRef = useRef(false);\n\n const binarySource = useMemo(() => {\n if (file && typeof file !== \"string\") return file;\n return null;\n }, [file]);\n\n const resolvedUrl = useMemo(() => {\n if (binarySource) return \"\";\n const asString =\n typeof file === \"string\" ? file : undefined;\n return resolvePdfUrl(asString, fileUrl, baseUrl);\n }, [binarySource, file, fileUrl, baseUrl]);\n\n const [status, setStatus] = useState<ViewerStatus>(\"idle\");\n const [pdfDoc, setPdfDoc] = useState<PdfDoc | null>(null);\n const [numPages, setNumPages] = useState(0);\n const [pageNumber, setPageNumber] = useState(1);\n const [scale, setScale] = useState(initialScale);\n const [rotation, setRotation] = useState(0);\n const [displayUrl, setDisplayUrl] = useState<string | null>(null);\n const [showThumbnails, setShowThumbnails] = useState(false);\n const [isPrinting, setIsPrinting] = useState(false);\n const [isDownloading, setIsDownloading] = useState(false);\n const [markupTool, setMarkupTool] = useState<MarkupTool>(\"none\");\n const [annotations, setAnnotations] = useState<MarkupAnnotation[]>([]);\n const [signatures, setSignatures] = useState<SignatureAnnotation[]>([]);\n const [texts, setTexts] = useState<TextAnnotation[]>([]);\n const [signaturePadOpen, setSignaturePadOpen] = useState(false);\n const [signaturePadFieldType, setSignaturePadFieldType] = useState<\n import(\"./signature\").SignatureFieldType | undefined\n >(undefined);\n const [rememberedByType, setRememberedByType] = useState<RememberedFieldFills>({});\n const [pendingSignature, setPendingSignature] = useState<{\n imageDataUrl: string;\n width: number;\n height: number;\n } | null>(null);\n const [selectedSignatureId, setSelectedSignatureId] = useState<string | null>(\n null,\n );\n const [selectedSignatureFieldId, setSelectedSignatureFieldId] = useState<string | null>(\n null,\n );\n const [editingSignatureId, setEditingSignatureId] = useState<string | null>(null);\n const [selectedTextId, setSelectedTextId] = useState<string | null>(null);\n const [selectedTextFieldId, setSelectedTextFieldId] = useState<string | null>(null);\n const [editingTextId, setEditingTextId] = useState<string | null>(null);\n const [highlightHex, setHighlightHex] = useState(DEFAULT_HIGHLIGHT_HEX);\n const [underlineHex, setUnderlineHex] = useState(DEFAULT_UNDERLINE_HEX);\n const hasFixedTextFields = textFields.length > 0;\n const [fieldValues, setFieldValues] = useState<Record<string, string>>({});\n const [signatureFields, setSignatureFields] =\n useState<SignatureField[]>(signatureFieldsProp);\n const signatureFieldsRef = useRef(signatureFields);\n signatureFieldsRef.current = signatureFields;\n\n useEffect(() => {\n signatureFieldsRef.current = signatureFieldsProp;\n setSignatureFields(signatureFieldsProp);\n setFieldValues((prev) => {\n const next = { ...prev };\n for (const field of signatureFieldsProp) {\n const fieldType = field.type ?? \"sign\";\n if (\n (fieldType === \"date\" || fieldType === \"text\") &&\n field.value != null &&\n field.value !== \"\"\n ) {\n next[field.id] = field.value;\n }\n }\n return next;\n });\n }, [signatureFieldsProp]);\n\n const hasFixedSignatureFields = signatureFields.length > 0;\n\n const isSignatureFieldFilled = useCallback(\n (\n field: SignatureField,\n sigs: SignatureAnnotation[],\n values: Record<string, string>,\n ) => {\n const fieldType = field.type ?? \"sign\";\n if (fieldType === \"date\" || fieldType === \"text\") {\n return Boolean((values[field.id] ?? field.value)?.trim());\n }\n return (\n sigs.some((sig) => sig.fieldId === field.id) ||\n Boolean(field.signatureDataUrl)\n );\n },\n [],\n );\n\n const writeFieldValueToFields = useCallback(\n (fieldIds: string[], value: string) => {\n const idSet = new Set(fieldIds);\n const prev = signatureFieldsRef.current;\n const next = prev.map((field) =>\n idSet.has(field.id) ? { ...field, value } : field,\n );\n signatureFieldsRef.current = next;\n setSignatureFields(next);\n onSignatureFieldsChange?.(next);\n\n setFieldValues((prevValues) => {\n const updated = { ...prevValues };\n for (const id of fieldIds) updated[id] = value;\n return updated;\n });\n\n for (const id of fieldIds) {\n onFieldValueComplete?.(id, value);\n }\n },\n [onFieldValueComplete, onSignatureFieldsChange],\n );\n\n const writeSignatureImageToFields = useCallback(\n (\n fieldIds: string | string[] | undefined,\n signature: SignatureAnnotation,\n signaturesByFieldId?: Map<string, SignatureAnnotation>,\n ) => {\n const prev = signatureFieldsRef.current;\n const ids = fieldIds == null ? null : Array.isArray(fieldIds) ? fieldIds : [fieldIds];\n const idSet = ids ? new Set(ids) : null;\n\n const next: SignatureField[] = idSet\n ? prev.map((field) =>\n idSet.has(field.id)\n ? { ...field, signatureDataUrl: signature.imageDataUrl }\n : field,\n )\n : [\n ...prev,\n {\n id: signature.id,\n pageNumber: signature.pageNumber,\n x: signature.x,\n y: signature.y,\n width: signature.width,\n height: signature.height,\n type: \"sign\",\n signatureDataUrl: signature.imageDataUrl,\n },\n ];\n signatureFieldsRef.current = next;\n setSignatureFields(next);\n onSignatureFieldsChange?.(next);\n\n if (!ids || ids.length === 0) {\n onSignatureComplete?.(undefined, signature);\n return;\n }\n for (const id of ids) {\n onSignatureComplete?.(\n id,\n signaturesByFieldId?.get(id) ?? signature,\n );\n }\n },\n [onSignatureComplete, onSignatureFieldsChange],\n );\n\n useEffect(() => {\n if (externalOpenSignaturePad) {\n setSignaturePadOpen(true);\n }\n }, [externalOpenSignaturePad]);\n\n const toolbarSides = useMemo(\n () =>\n resolveToolbarLayout(enableToolbar, {\n enableThumbnails,\n enableNavigation,\n enableZoom,\n enableRotate,\n enableReload,\n enablePrint,\n enableOpen,\n enableDownload,\n enableHighlight,\n enableUnderline,\n enableSignature,\n enableText,\n enableErase,\n enableClear,\n }),\n [\n enableToolbar,\n enableThumbnails,\n enableNavigation,\n enableZoom,\n enableRotate,\n enableReload,\n enablePrint,\n enableOpen,\n enableDownload,\n enableHighlight,\n enableUnderline,\n enableSignature,\n enableText,\n enableErase,\n enableClear,\n ],\n );\n\n const enabledToolIds = useMemo(() => {\n if (!toolbarSides) return new Set<ToolbarToolId>();\n return new Set([...toolbarSides.left, ...toolbarSides.right]);\n }, [toolbarSides]);\n\n useEffect(() => {\n const hasThumbTool = enabledToolIds.has(\"thumbnail\");\n if (!hasThumbTool) {\n setShowThumbnails(false);\n return;\n }\n\n const mq = window.matchMedia(\"(max-width: 720px)\");\n const apply = () => {\n // Mobile: hide thumbnails by default. Desktop: respect withThumbnails.\n setShowThumbnails(mq.matches ? false : withThumbnails);\n };\n apply();\n mq.addEventListener(\"change\", apply);\n return () => mq.removeEventListener(\"change\", apply);\n }, [enabledToolIds, withThumbnails]);\n\n const showHighlight =\n !hasFixedSignatureFields && enabledToolIds.has(\"highlight\");\n const showUnderline =\n !hasFixedSignatureFields && enabledToolIds.has(\"underline\");\n const showSignature =\n enabledToolIds.has(\"signature\") || hasFixedSignatureFields;\n const showText = enabledToolIds.has(\"text\") || hasFixedTextFields;\n const showErase = !hasFixedSignatureFields && enabledToolIds.has(\"erase\");\n\n const revokeDisplayUrl = useCallback(() => {\n if (lastBlobUrlRef.current) {\n URL.revokeObjectURL(lastBlobUrlRef.current);\n lastBlobUrlRef.current = null;\n }\n }, []);\n\n const loadDocument = useCallback(async () => {\n if (!binarySource && !resolvedUrl) return;\n\n ensurePdfWorker(workerSrc);\n setStatus(\"loading\");\n setPdfDoc(null);\n setNumPages(0);\n setPageNumber(1);\n setAnnotations([]);\n setSignatures([]);\n setTexts([]);\n setPendingSignature(null);\n setSelectedSignatureId(null);\n setSelectedSignatureFieldId(null);\n setEditingSignatureId(null);\n setSelectedTextId(null);\n setSelectedTextFieldId(null);\n setEditingTextId(null);\n setMarkupTool(\"none\");\n\n try {\n const buffer = binarySource\n ? await sourceToArrayBuffer(binarySource, fetchOptions)\n : await sourceToArrayBuffer(resolvedUrl, fetchOptions);\n\n const blob = new Blob([buffer], { type: \"application/pdf\" });\n const blobUrl = URL.createObjectURL(blob);\n revokeDisplayUrl();\n lastBlobUrlRef.current = blobUrl;\n setDisplayUrl(blobUrl);\n\n const loadingTask = pdfjsLib.getDocument({\n data: buffer,\n cMapUrl: `https://unpkg.com/pdfjs-dist@${pdfjsLib.version}/cmaps/`,\n cMapPacked: true,\n standardFontDataUrl: `https://unpkg.com/pdfjs-dist@${pdfjsLib.version}/standard_fonts/`,\n });\n const doc = await loadingTask.promise;\n setPdfDoc(doc);\n setNumPages(doc.numPages);\n setStatus(\"ready\");\n } catch {\n setStatus(\"error\");\n }\n }, [\n binarySource,\n resolvedUrl,\n fetchOptions,\n revokeDisplayUrl,\n workerSrc,\n ]);\n\n useEffect(() => {\n if (!binarySource && !resolvedUrl) {\n setStatus(\"idle\");\n setPdfDoc(null);\n setNumPages(0);\n setDisplayUrl(null);\n revokeDisplayUrl();\n return;\n }\n\n void loadDocument();\n\n return () => {\n revokeDisplayUrl();\n };\n }, [binarySource, resolvedUrl, loadDocument, revokeDisplayUrl]);\n\n useEffect(() => {\n if (markupTool === \"highlight\" && !showHighlight) {\n setMarkupTool(\"none\");\n } else if (markupTool === \"underline\" && !showUnderline) {\n setMarkupTool(\"none\");\n } else if (markupTool === \"sign\" && !showSignature) {\n setMarkupTool(\"none\");\n } else if (markupTool === \"text\" && !showText) {\n setMarkupTool(\"none\");\n } else if (markupTool === \"erase\" && !showErase) {\n setMarkupTool(\"none\");\n }\n }, [showHighlight, showUnderline, showSignature, showText, showErase, markupTool]);\n\n const scrollToPage = useCallback(\n (targetPage: number) => {\n const clamped = Math.max(1, Math.min(numPages || 1, targetPage));\n const el = pageRefsRef.current.get(clamped);\n if (!el) {\n setPageNumber(clamped);\n return;\n }\n\n isProgrammaticScrollRef.current = true;\n el.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\n setPageNumber(clamped);\n window.setTimeout(() => {\n isProgrammaticScrollRef.current = false;\n }, 500);\n },\n [numPages],\n );\n\n const scrollToSignatureField = useCallback(\n (field: SignatureField) => {\n const pageEl = pageRefsRef.current.get(field.pageNumber);\n if (pageEl) {\n isProgrammaticScrollRef.current = true;\n setPageNumber(field.pageNumber);\n }\n\n const focusField = () => {\n const fieldEl = containerRef.current?.querySelector(\n `[data-signature-field-id=\"${CSS.escape(field.id)}\"]`,\n ) as HTMLElement | null;\n\n if (fieldEl) {\n fieldEl.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n } else if (pageEl) {\n pageEl.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\n }\n\n window.setTimeout(() => {\n isProgrammaticScrollRef.current = false;\n }, 500);\n };\n\n window.requestAnimationFrame(() => {\n window.setTimeout(focusField, 40);\n });\n },\n [],\n );\n\n useEffect(() => {\n if (status !== \"ready\" || !containerRef.current || !numPages) return;\n\n const container = containerRef.current;\n const observer = new IntersectionObserver(\n (entries) => {\n if (isProgrammaticScrollRef.current) return;\n\n let best: { page: number; ratio: number } | null = null;\n for (const e of entries) {\n if (!e.isIntersecting) continue;\n const page = Number.parseInt(\n (e.target as HTMLElement).dataset.pageNumber || \"0\",\n 10,\n );\n if (!page) continue;\n if (!best || e.intersectionRatio > best.ratio) {\n best = { page, ratio: e.intersectionRatio };\n }\n }\n if (best) setPageNumber(best.page);\n },\n {\n root: container,\n threshold: [0.25, 0.5, 0.75],\n },\n );\n\n for (let p = 1; p <= numPages; p += 1) {\n const el = pageRefsRef.current.get(p);\n if (el) observer.observe(el);\n }\n\n return () => observer.disconnect();\n }, [status, numPages]);\n\n const canGoPrev = pageNumber > 1;\n const canGoNext = numPages ? pageNumber < numPages : false;\n\n const handlePrev = useCallback(() => {\n if (!canGoPrev) return;\n scrollToPage(pageNumber - 1);\n }, [canGoPrev, pageNumber, scrollToPage]);\n\n const handleNext = useCallback(() => {\n if (!canGoNext) return;\n scrollToPage(pageNumber + 1);\n }, [canGoNext, pageNumber, scrollToPage]);\n\n const handleRotate = useCallback(() => {\n setRotation((r) => (r + 90) % 360);\n }, []);\n\n const handleZoomOut = useCallback(() => {\n setScale((s) => Math.max(0.25, Math.round((s - 0.1) * 100) / 100));\n }, []);\n\n const handleZoomIn = useCallback(() => {\n setScale((s) => Math.min(5, Math.round((s + 0.1) * 100) / 100));\n }, []);\n\n const handleFitWidth = useCallback(async () => {\n if (!pdfDoc || !containerRef.current) return;\n try {\n const page = await pdfDoc.getPage(pageNumber);\n const viewportAt1 = page.getViewport({ scale: 1, rotation });\n // Body already excludes the thumbnail rail; subtract page padding only.\n const isMobile = window.matchMedia(\"(max-width: 720px)\").matches;\n const pagePadding = isMobile ? 16 : 24;\n const containerWidth = Math.max(\n 0,\n containerRef.current.clientWidth - pagePadding,\n );\n const nextScale = containerWidth / viewportAt1.width;\n setScale(Math.max(0.25, Math.min(5, Math.round(nextScale * 100) / 100)));\n } catch {\n // ignore\n }\n }, [pdfDoc, pageNumber, rotation]);\n\n // On mobile, auto-fit so fixed-field coordinates/dimensions stay aligned.\n useEffect(() => {\n if (status !== \"ready\" || !pdfDoc) return;\n if (!window.matchMedia(\"(max-width: 720px)\").matches) return;\n\n let cancelled = false;\n const run = () => {\n if (!cancelled) void handleFitWidth();\n };\n run();\n\n const container = containerRef.current;\n const observer =\n typeof ResizeObserver !== \"undefined\" && container\n ? new ResizeObserver(() => run())\n : null;\n observer?.observe(container!);\n\n const mq = window.matchMedia(\"(max-width: 720px)\");\n const onMq = () => {\n if (mq.matches) run();\n };\n mq.addEventListener(\"change\", onMq);\n\n return () => {\n cancelled = true;\n observer?.disconnect();\n mq.removeEventListener(\"change\", onMq);\n };\n }, [status, pdfDoc, showThumbnails, rotation, handleFitWidth]);\n\n const fieldValueTexts = useMemo((): TextAnnotation[] => {\n return signatureFields.flatMap((field) => {\n const fieldType = field.type ?? \"sign\";\n if (fieldType !== \"date\" && fieldType !== \"text\") return [];\n const value = (fieldValues[field.id] ?? field.value ?? \"\").trim();\n if (!value) return [];\n const fontSize = Math.max(\n 10,\n Math.min(DEFAULT_TEXT_FONT_SIZE, field.height * 0.55),\n );\n return [\n {\n id: `fv_${field.id}`,\n pageNumber: field.pageNumber,\n fieldId: field.id,\n x: field.x + 4,\n y: field.y + Math.max(2, (field.height - fontSize) / 2),\n width: Math.max(12, field.width - 8),\n height: Math.max(fontSize * 1.2, field.height - 4),\n value,\n fontSize,\n color: DEFAULT_TEXT_COLOR,\n },\n ];\n });\n }, [signatureFields, fieldValues]);\n\n const textsForExport = useMemo(\n () => [...texts, ...fieldValueTexts],\n [texts, fieldValueTexts],\n );\n\n const handlePrint = useCallback(async () => {\n if (!pdfDoc || status !== \"ready\") return;\n\n setIsPrinting(true);\n try {\n // Render in the main document — pdf.js fonts break on iframe canvases.\n const pages = await renderAllPagesWithMarkup(pdfDoc, {\n scale: 1.5,\n rotation,\n annotations,\n signatures,\n texts: textsForExport,\n mimeType: \"image/png\",\n });\n\n const iframe = document.createElement(\"iframe\");\n iframe.style.position = \"fixed\";\n iframe.style.right = \"0\";\n iframe.style.bottom = \"0\";\n iframe.style.width = \"0\";\n iframe.style.height = \"0\";\n iframe.style.border = \"0\";\n iframe.setAttribute(\"aria-hidden\", \"true\");\n document.body.appendChild(iframe);\n\n const doc = iframe.contentWindow?.document;\n if (!doc) throw new Error(\"print iframe not available\");\n\n doc.open();\n doc.write(`<!doctype html>\n<html>\n <head>\n <meta charset=\"utf-8\" />\n <title>${title.replace(/</g, \"&lt;\")}</title>\n <style>\n html, body { margin: 0; padding: 0; }\n img { width: 100%; display: block; }\n .page { page-break-after: always; }\n .page:last-child { page-break-after: auto; }\n @page { margin: 10mm; }\n </style>\n </head>\n <body></body>\n</html>`);\n doc.close();\n\n const body = doc.body;\n for (const page of pages) {\n const img = doc.createElement(\"img\");\n img.src = page.dataUrl;\n const wrapper = doc.createElement(\"div\");\n wrapper.className = \"page\";\n wrapper.appendChild(img);\n body.appendChild(wrapper);\n }\n\n // Wait for images to decode before printing\n await Promise.all(\n Array.from(body.querySelectorAll(\"img\")).map(\n (img) =>\n img.decode?.().catch(() => undefined) ?? Promise.resolve(),\n ),\n );\n\n setTimeout(() => {\n try {\n iframe.contentWindow?.focus();\n iframe.contentWindow?.print();\n } finally {\n setTimeout(() => {\n try {\n document.body.removeChild(iframe);\n } catch {\n // ignore\n }\n }, 1000);\n }\n }, 50);\n } catch {\n try {\n if (displayUrl) {\n window.open(displayUrl, \"_blank\", \"noopener,noreferrer\");\n } else if (resolvedUrl) {\n window.open(resolvedUrl, \"_blank\", \"noopener,noreferrer\");\n }\n } catch {\n // ignore\n }\n } finally {\n setIsPrinting(false);\n }\n }, [pdfDoc, status, rotation, title, displayUrl, resolvedUrl, annotations, signatures, textsForExport]);\n\n const handleDownload = useCallback(async () => {\n if (!pdfDoc || status !== \"ready\") return;\n\n const filename = `${title.replace(/[^\\w.-]+/g, \"_\") || \"document\"}.pdf`;\n const hasLayers =\n annotations.length > 0 ||\n signatures.length > 0 ||\n textsForExport.length > 0;\n\n // No markup → keep original PDF bytes\n if (!hasLayers && displayUrl) {\n triggerBlobDownload(\n await fetch(displayUrl).then((r) => r.blob()),\n filename,\n );\n return;\n }\n\n setIsDownloading(true);\n try {\n const pages = await renderAllPagesWithMarkup(pdfDoc, {\n scale: 2,\n rotation,\n annotations,\n signatures,\n texts: textsForExport,\n mimeType: \"image/jpeg\",\n quality: 0.92,\n });\n const pdfBytes = buildPdfFromJpegPages(pages);\n const copy = new Uint8Array(pdfBytes.byteLength);\n copy.set(pdfBytes);\n triggerBlobDownload(\n new Blob([copy], { type: \"application/pdf\" }),\n filename,\n );\n } catch {\n if (displayUrl) {\n triggerBlobDownload(\n await fetch(displayUrl).then((r) => r.blob()),\n filename,\n );\n }\n } finally {\n setIsDownloading(false);\n }\n }, [pdfDoc, status, rotation, title, displayUrl, annotations, signatures, textsForExport]);\n\n const toggleMarkupTool = useCallback((tool: MarkupTool) => {\n setMarkupTool((current) => (current === tool ? \"none\" : tool));\n }, []);\n\n const activeMarkupHex =\n markupTool === \"highlight\"\n ? highlightHex\n : markupTool === \"underline\"\n ? underlineHex\n : null;\n\n const activeMarkupColor =\n markupTool === \"highlight\" || markupTool === \"underline\"\n ? hexToMarkupColor(activeMarkupHex!, markupTool)\n : undefined;\n\n const selectedSignature =\n selectedSignatureId != null\n ? signatures.find((sig) => sig.id === selectedSignatureId) ?? null\n : null;\n\n const handleAddAnnotation = useCallback((annotation: MarkupAnnotation) => {\n setAnnotations((prev) => [...prev, annotation]);\n }, []);\n\n const handleRemoveAnnotation = useCallback((id: string) => {\n setAnnotations((prev) => prev.filter((a) => a.id !== id));\n }, []);\n\n const handleClearAnnotations = useCallback(() => {\n setAnnotations([]);\n setSignatures([]);\n setTexts([]);\n setSelectedSignatureId(null);\n setSelectedTextId(null);\n setSelectedTextFieldId(null);\n setEditingTextId(null);\n }, []);\n\n const advanceToNextUnsignedField = useCallback(\n (fromFieldId: string, filledIds: Set<string>) => {\n const currentIndex = signatureFields.findIndex(\n (field) => field.id === fromFieldId,\n );\n const nextField =\n signatureFields\n .slice(currentIndex + 1)\n .find((field) => !filledIds.has(field.id)) ??\n signatureFields\n .slice(0, Math.max(0, currentIndex))\n .find((field) => !filledIds.has(field.id));\n\n if (!nextField) {\n setSignaturePadOpen(false);\n setEditingSignatureId(null);\n return;\n }\n\n setSelectedSignatureFieldId(nextField.id);\n setSelectedSignatureId(null);\n setEditingSignatureId(null);\n setSignaturePadFieldType(nextField.type ?? \"sign\");\n scrollToSignatureField(nextField);\n window.setTimeout(() => {\n setSignaturePadOpen(true);\n }, 350);\n },\n [scrollToSignatureField, signatureFields],\n );\n\n const handleOpenSignaturePad = useCallback(\n (fieldType?: import(\"./signature\").SignatureFieldType) => {\n setSignaturePadFieldType(fieldType);\n setSignaturePadOpen(true);\n },\n [],\n );\n\n const handleFieldValueChange = useCallback((fieldId: string, value: string) => {\n setFieldValues((prev) => ({ ...prev, [fieldId]: value }));\n }, []);\n\n const handleFieldValueCommit = useCallback(\n (fieldId: string) => {\n const val = fieldValues[fieldId];\n if (val) onFieldValueComplete?.(fieldId, val);\n\n const currentIndex = signatureFields.findIndex((f) => f.id === fieldId);\n const filledIds = new Set(\n Object.keys(fieldValues).filter((k) => fieldValues[k]?.trim()),\n );\n filledIds.add(fieldId);\n const nextField =\n signatureFields.slice(currentIndex + 1).find(\n (f) => !filledIds.has(f.id) && !signatures.some((sig) => sig.fieldId === f.id),\n ) ??\n signatureFields.slice(0, Math.max(0, currentIndex)).find(\n (f) => !filledIds.has(f.id) && !signatures.some((sig) => sig.fieldId === f.id),\n );\n if (nextField) {\n setSelectedSignatureFieldId(nextField.id);\n scrollToSignatureField(nextField);\n }\n },\n [signatureFields, fieldValues, signatures, scrollToSignatureField, onFieldValueComplete],\n );\n\n const handleSignatureSave = useCallback(\n (imageDataUrl: string, sourceWidth: number, sourceHeight: number) => {\n const size = signatureDisplaySize(sourceWidth, sourceHeight);\n\n if (editingSignatureId) {\n setSignatures((prev) =>\n prev.map((sig) =>\n sig.id === editingSignatureId\n ? {\n ...sig,\n imageDataUrl,\n width: sig.fieldId ? sig.width : size.width,\n height: sig.fieldId ? sig.height : size.height,\n }\n : sig,\n ),\n );\n setPendingSignature(null);\n setMarkupTool(\"none\");\n setSignaturePadOpen(false);\n setEditingSignatureId(null);\n return;\n }\n\n if (hasFixedSignatureFields) {\n const targetField =\n signatureFields.find(\n (field) =>\n field.id === selectedSignatureFieldId &&\n (field.type ?? \"sign\") === \"sign\" &&\n !signatures.some((sig) => sig.fieldId === field.id),\n ) ??\n signatureFields.find(\n (field) =>\n (field.type ?? \"sign\") === \"sign\" &&\n !signatures.some((sig) => sig.fieldId === field.id),\n );\n\n if (!targetField) {\n setSignaturePadOpen(false);\n return;\n }\n\n const targetFields =\n applySignatureToSameTag && targetField.signature_tag\n ? signatureFields.filter(\n (field) =>\n (field.type ?? \"sign\") === \"sign\" &&\n field.signature_tag === targetField.signature_tag &&\n !signatures.some((sig) => sig.fieldId === field.id),\n )\n : [targetField];\n\n const newSignatures: SignatureAnnotation[] = targetFields.map((field) => ({\n id: createSignatureId(),\n fieldId: field.id,\n pageNumber: field.pageNumber,\n x: field.x,\n y: field.y,\n width: field.width,\n height: field.height,\n imageDataUrl,\n }));\n\n const targetIds = new Set(targetFields.map((field) => field.id));\n setSignatures((prev) => [\n ...prev.filter((sig) => !sig.fieldId || !targetIds.has(sig.fieldId)),\n ...newSignatures,\n ]);\n\n const byFieldId = new Map(\n newSignatures.map((sig) => [sig.fieldId as string, sig]),\n );\n writeSignatureImageToFields(\n targetFields.map((field) => field.id),\n newSignatures[0],\n byFieldId,\n );\n\n setPendingSignature(null);\n setMarkupTool(\"none\");\n setSelectedSignatureId(newSignatures[0]?.id ?? null);\n\n const filledIds = new Set(\n signatureFields\n .filter((field) =>\n isSignatureFieldFilled(\n field,\n [...signatures, ...newSignatures],\n fieldValues,\n ),\n )\n .map((field) => field.id),\n );\n for (const id of targetIds) filledIds.add(id);\n\n advanceToNextUnsignedField(targetField.id, filledIds);\n return;\n }\n\n const currentPageEl = pageRefsRef.current.get(pageNumber);\n const surface = currentPageEl?.querySelector(\n \".epochs-pdf-viewer__surface\",\n ) as HTMLDivElement | null;\n\n let x = 24;\n let y = 24;\n if (surface) {\n const pageSize = pageSizeFromSurface(surface, scale);\n const scrollContainer = surface.closest(\".epochs-pdf-viewer__body\") as HTMLElement | null;\n\n if (scrollContainer) {\n const visible = viewportRectToPage(\n scrollContainer.getBoundingClientRect(),\n surface,\n scale,\n );\n const visibleTop = Math.max(0, visible.top);\n const visibleBottom = Math.min(pageSize.height, visible.bottom);\n const visibleLeft = Math.max(0, visible.left);\n const visibleRight = Math.min(pageSize.width, visible.right);\n x = Math.max(0, (visibleLeft + visibleRight) / 2 - size.width / 2);\n y = Math.max(0, (visibleTop + visibleBottom) / 2 - size.height / 2);\n x = Math.min(x, Math.max(0, pageSize.width - size.width));\n y = Math.min(y, Math.max(0, pageSize.height - size.height));\n } else {\n x = Math.max(0, (pageSize.width - size.width) / 2);\n y = Math.max(0, (pageSize.height - size.height) / 2);\n }\n }\n\n const signature: SignatureAnnotation = {\n id: createSignatureId(),\n pageNumber,\n x,\n y,\n width: size.width,\n height: size.height,\n imageDataUrl,\n };\n\n setSignatures((prev) => [...prev, signature]);\n writeSignatureImageToFields(undefined, signature);\n setSelectedSignatureId(signature.id);\n setPendingSignature(null);\n setMarkupTool(\"none\");\n setSignaturePadOpen(false);\n setEditingSignatureId(null);\n },\n [\n advanceToNextUnsignedField,\n applySignatureToSameTag,\n editingSignatureId,\n fieldValues,\n hasFixedSignatureFields,\n isSignatureFieldFilled,\n pageNumber,\n scale,\n selectedSignatureFieldId,\n signatureFields,\n signatures,\n writeSignatureImageToFields,\n ],\n );\n\n const handleSaveFieldValue = useCallback(\n (value: string, fieldType: \"date\" | \"text\") => {\n if (hasFixedSignatureFields) {\n const targetField =\n signatureFields.find(\n (field) =>\n field.id === selectedSignatureFieldId &&\n (field.type ?? \"sign\") === fieldType,\n ) ??\n signatureFields.find((field) => (field.type ?? \"sign\") === fieldType);\n\n if (!targetField) {\n setSignaturePadOpen(false);\n return;\n }\n\n const targetFields =\n applySignatureToSameTag && targetField.signature_tag\n ? signatureFields.filter(\n (field) =>\n (field.type ?? \"sign\") === fieldType &&\n field.signature_tag === targetField.signature_tag,\n )\n : [targetField];\n\n const targetIds = targetFields.map((field) => field.id);\n writeFieldValueToFields(targetIds, value);\n\n const nextValues = { ...fieldValues };\n for (const id of targetIds) nextValues[id] = value;\n\n const filledIds = new Set(\n signatureFields\n .filter((field) =>\n isSignatureFieldFilled(field, signatures, nextValues),\n )\n .map((field) => field.id),\n );\n\n advanceToNextUnsignedField(targetField.id, filledIds);\n return;\n }\n\n const fontSize = DEFAULT_TEXT_FONT_SIZE;\n const width = Math.max(80, value.length * fontSize * 0.55);\n const height = fontSize * 1.25;\n let x = 24;\n let y = 24;\n\n const currentPageEl = pageRefsRef.current.get(pageNumber);\n const surface = currentPageEl?.querySelector(\n \".epochs-pdf-viewer__surface\",\n ) as HTMLDivElement | null;\n if (surface) {\n const pageSize = pageSizeFromSurface(surface, scale);\n const scrollContainer = surface.closest(\n \".epochs-pdf-viewer__body\",\n ) as HTMLElement | null;\n if (scrollContainer) {\n const visible = viewportRectToPage(\n scrollContainer.getBoundingClientRect(),\n surface,\n scale,\n );\n const visibleTop = Math.max(0, visible.top);\n const visibleBottom = Math.min(pageSize.height, visible.bottom);\n const visibleLeft = Math.max(0, visible.left);\n const visibleRight = Math.min(pageSize.width, visible.right);\n x = Math.max(0, (visibleLeft + visibleRight) / 2 - width / 2);\n y = Math.max(0, (visibleTop + visibleBottom) / 2 - height / 2);\n x = Math.min(x, Math.max(0, pageSize.width - width));\n y = Math.min(y, Math.max(0, pageSize.height - height));\n }\n }\n\n const text: TextAnnotation = {\n id: createTextId(),\n pageNumber,\n x,\n y,\n width,\n height,\n value,\n fontSize,\n color: DEFAULT_TEXT_COLOR,\n };\n setTexts((prev) => [...prev, text]);\n setSelectedTextId(text.id);\n setSignaturePadOpen(false);\n setMarkupTool(\"none\");\n },\n [\n advanceToNextUnsignedField,\n applySignatureToSameTag,\n fieldValues,\n hasFixedSignatureFields,\n isSignatureFieldFilled,\n pageNumber,\n scale,\n selectedSignatureFieldId,\n signatureFields,\n signatures,\n writeFieldValueToFields,\n ],\n );\n\n const handleAddSignature = useCallback((signature: SignatureAnnotation) => {\n setSignatures((prev) => [...prev, signature]);\n writeSignatureImageToFields(undefined, signature);\n setSelectedSignatureId(signature.id);\n setPendingSignature(null);\n setMarkupTool(\"none\");\n }, [writeSignatureImageToFields]);\n\n const handleUpdateSignature = useCallback(\n (id: string, patch: Partial<SignatureAnnotation>) => {\n setSignatures((prev) =>\n prev.map((sig) => (sig.id === id ? { ...sig, ...patch } : sig)),\n );\n },\n [],\n );\n\n const handleRemoveSignature = useCallback((id: string) => {\n const removed = signatures.find((sig) => sig.id === id);\n setSignatures((prev) => prev.filter((sig) => sig.id !== id));\n setSelectedSignatureId((current) => (current === id ? null : current));\n if (removed?.fieldId) {\n setSelectedSignatureFieldId(removed.fieldId);\n }\n }, [signatures]);\n\n const handleDuplicateSignature = useCallback((id?: string) => {\n const target = id\n ? signatures.find((sig) => sig.id === id) ?? null\n : selectedSignature;\n if (!target) return;\n\n const pageEl = pageRefsRef.current.get(target.pageNumber);\n const surface = pageEl?.querySelector(\n \".epochs-pdf-viewer__surface\",\n ) as HTMLDivElement | null;\n\n const offset = 18;\n let x = target.x + offset;\n let y = target.y + offset;\n\n if (surface) {\n const pageWidth = surface.clientWidth / scale;\n const pageHeight = surface.clientHeight / scale;\n x = Math.min(\n Math.max(0, x),\n Math.max(0, pageWidth - target.width),\n );\n y = Math.min(\n Math.max(0, y),\n Math.max(0, pageHeight - target.height),\n );\n }\n\n const duplicate: SignatureAnnotation = {\n ...target,\n id: createSignatureId(),\n x,\n y,\n };\n\n setSignatures((prev) => [...prev, duplicate]);\n setSelectedSignatureId(duplicate.id);\n setPendingSignature(null);\n setMarkupTool(\"none\");\n }, [scale, selectedSignature, signatures]);\n\n const handleEditSignature = useCallback((id?: string) => {\n const targetId = id ?? selectedSignature?.id;\n if (!targetId) return;\n const existing = signatures.find((sig) => sig.id === targetId);\n const field = existing?.fieldId\n ? signatureFields.find((item) => item.id === existing.fieldId)\n : undefined;\n setSignaturePadFieldType(field?.type ?? \"sign\");\n setSelectedSignatureId(targetId);\n setEditingSignatureId(targetId);\n setSignaturePadOpen(true);\n }, [selectedSignature, signatures, signatureFields]);\n\n const handleAddText = useCallback((text: TextAnnotation) => {\n setTexts((prev) => {\n if (text.fieldId) {\n return [...prev.filter((item) => item.fieldId !== text.fieldId), text];\n }\n return [...prev, text];\n });\n setSelectedTextId(text.id);\n if (text.fieldId) setSelectedTextFieldId(text.fieldId);\n }, []);\n\n const handleUpdateText = useCallback(\n (id: string, patch: Partial<TextAnnotation>) => {\n setTexts((prev) =>\n prev.map((text) => (text.id === id ? { ...text, ...patch } : text)),\n );\n },\n [],\n );\n\n const handleRemoveText = useCallback((id: string) => {\n const removed = texts.find((text) => text.id === id);\n setTexts((prev) => prev.filter((text) => text.id !== id));\n setSelectedTextId((current) => (current === id ? null : current));\n setEditingTextId((current) => (current === id ? null : current));\n if (removed?.fieldId) {\n setSelectedTextFieldId(removed.fieldId);\n }\n }, [texts]);\n\n // Sync fixed text field geometry if the prop changes\n useEffect(() => {\n if (!hasFixedTextFields) return;\n setTexts((prev) =>\n prev.map((text) => {\n if (!text.fieldId) return text;\n const field = textFields.find((item) => item.id === text.fieldId);\n if (!field) return text;\n return {\n ...text,\n pageNumber: field.pageNumber,\n x: field.x,\n y: field.y,\n width: field.width,\n height: field.height,\n fontSize: field.fontSize ?? text.fontSize ?? DEFAULT_TEXT_FONT_SIZE,\n color: field.color ?? text.color ?? DEFAULT_TEXT_COLOR,\n };\n }),\n );\n }, [hasFixedTextFields, textFields]);\n\n const goToSignatureField = useCallback(\n (direction: -1 | 1) => {\n if (!signatureFields.length) return;\n const from =\n selectedSignatureFieldId != null\n ? signatureFields.findIndex((f) => f.id === selectedSignatureFieldId)\n : -1;\n const nextIndex = Math.min(\n signatureFields.length - 1,\n Math.max(0, (from < 0 ? 0 : from) + direction),\n );\n const field = signatureFields[nextIndex];\n if (!field) return;\n setSelectedSignatureFieldId(field.id);\n setSelectedSignatureId(\n signatures.find((sig) => sig.fieldId === field.id)?.id ?? null,\n );\n scrollToSignatureField(field);\n },\n [\n scrollToSignatureField,\n selectedSignatureFieldId,\n signatureFields,\n signatures,\n ],\n );\n\n if (!binarySource && !resolvedUrl) {\n return (\n <div\n data-testid=\"pdf-viewer\"\n className={`epochs-pdf-viewer epochs-pdf-viewer--empty ${className ?? \"\"}`.trim()}\n >\n No PDF file provided.\n </div>\n );\n }\n\n const rootStyle: CSSProperties = {\n height,\n };\n\n const toolbarCtx: ToolbarRenderContext = {\n status,\n showThumbnails,\n setShowThumbnails,\n canGoPrev,\n canGoNext,\n handlePrev,\n handleNext,\n pageNumber,\n numPages,\n scrollToPage,\n scale,\n handleZoomOut,\n handleZoomIn,\n handleFitWidth,\n handleRotate,\n markupTool,\n toggleMarkupTool: (tool) => toggleMarkupTool(tool),\n hasFixedSignatureFields,\n hasFixedTextFields,\n pendingSignature,\n setMarkupTool,\n setSignaturePadOpen,\n annotationsLength: annotations.length,\n signaturesLength: signatures.length,\n textsLength: texts.length,\n handleClearAnnotations,\n highlightHex,\n underlineHex,\n setHighlightHex,\n setUnderlineHex,\n loadDocument,\n handlePrint,\n isPrinting,\n pdfDoc,\n displayUrl,\n resolvedUrl,\n handleDownload,\n isDownloading,\n };\n\n const visibleToolIds = (ids: ToolbarToolId[]) =>\n ids.filter((id) => {\n if (\n hasFixedSignatureFields &&\n (id === \"highlight\" || id === \"underline\" || id === \"erase\")\n ) {\n return false;\n }\n return true;\n });\n\n const currentFieldIndex = selectedSignatureFieldId\n ? signatureFields.findIndex((field) => field.id === selectedSignatureFieldId)\n : 0;\n\n const filledFieldCount = signatureFields.filter((field) =>\n isSignatureFieldFilled(field, signatures, fieldValues),\n ).length;\n\n const fieldProgressPercent =\n signatureFields.length > 0\n ? Math.round((filledFieldCount / signatureFields.length) * 100)\n : 0;\n\n const renderSide = (ids: ToolbarToolId[], alignEnd = false) => {\n const visible = visibleToolIds(ids);\n if (visible.length === 0 && !alignEnd) {\n return <div className=\"epochs-pdf-viewer__toolbar-group\" />;\n }\n if (visible.length === 0) {\n return (\n <div className=\"epochs-pdf-viewer__toolbar-group epochs-pdf-viewer__toolbar-group--end\" />\n );\n }\n\n const nodes = visible.map((id, index) => {\n const prev = visible[index - 1];\n const showMarkupSep =\n isMarkupToolbarTool(id) && (!prev || !isMarkupToolbarTool(prev));\n return (\n <Fragment key={id}>\n {renderToolbarTool(id, toolbarCtx, { showMarkupSep })}\n </Fragment>\n );\n });\n\n return (\n <div\n className={\n alignEnd\n ? \"epochs-pdf-viewer__toolbar-group epochs-pdf-viewer__toolbar-group--end\"\n : \"epochs-pdf-viewer__toolbar-group\"\n }\n >\n {nodes}\n {renderMarkupExtras(toolbarCtx, new Set(visible))}\n </div>\n );\n };\n\n return (\n <div\n data-testid=\"pdf-viewer\"\n data-file-url={resolvedUrl || undefined}\n className={`epochs-pdf-viewer ${className ?? \"\"}`.trim()}\n style={rootStyle}\n >\n {toolbarSides ? (\n <div className=\"epochs-pdf-viewer__toolbar\">\n {renderSide(toolbarSides.left)}\n {renderSide(toolbarSides.right, true)}\n </div>\n ) : null}\n\n {(showSignature || externalOpenSignaturePad || hasFixedSignatureFields) ? (\n <SignaturePad\n open={signaturePadOpen}\n onClose={() => {\n setSignaturePadOpen(false);\n setEditingSignatureId(null);\n setSignaturePadFieldType(undefined);\n onSignaturePadClose?.();\n }}\n onSave={handleSignatureSave}\n onSaveFieldValue={handleSaveFieldValue}\n fieldType={signaturePadFieldType}\n showFieldTypeTabs={!hasFixedSignatureFields}\n textPlaceholder={\n signatureFields.find((field) => field.id === selectedSignatureFieldId)\n ?.placeholder\n }\n initialFieldValue={\n selectedSignatureFieldId\n ? fieldValues[selectedSignatureFieldId] ??\n signatureFields.find((field) => field.id === selectedSignatureFieldId)\n ?.value\n : undefined\n }\n rememberedByType={rememberedByType}\n onRememberFill={(type, fill) => {\n setRememberedByType((prev) => {\n if (type === \"sign\") {\n return { ...prev, sign: fill as RememberedSignFill };\n }\n if (type === \"date\") {\n return { ...prev, date: fill as { value: string } };\n }\n return { ...prev, text: fill as { value: string } };\n });\n }}\n />\n ) : null}\n\n <div className=\"epochs-pdf-viewer__content\">\n {showThumbnails ? (\n <div\n className=\"epochs-pdf-viewer__thumbnails\"\n style={{ width: thumbnailWidth + 24 }}\n >\n {status === \"ready\" && pdfDoc ? (\n <>\n {Array.from({\n length: Math.min(numPages || 0, maxThumbnails),\n }).map((_, idx) => {\n const n = idx + 1;\n return (\n <div key={n} className=\"epochs-pdf-viewer__thumb-wrap\">\n <ThumbnailStrip\n pdfDoc={pdfDoc}\n pageNumber={n}\n isActive={n === pageNumber}\n rotation={rotation}\n onSelect={scrollToPage}\n width={thumbnailWidth}\n annotations={annotations}\n signatures={signatures}\n signatureFields={signatureFields}\n texts={textsForExport}\n textFields={textFields}\n />\n </div>\n );\n })}\n {numPages > maxThumbnails ? (\n <div className=\"epochs-pdf-viewer__thumb-more\">\n Showing first {maxThumbnails} pages\n </div>\n ) : null}\n </>\n ) : (\n <div className=\"epochs-pdf-viewer__muted\">Thumbnails</div>\n )}\n </div>\n ) : null}\n\n <div ref={containerRef} className=\"epochs-pdf-viewer__body\">\n {status === \"loading\" ? (\n <div className=\"epochs-pdf-viewer__overlay epochs-pdf-viewer__muted\">\n Loading PDF…\n <span className=\"epochs-pdf-viewer__spinner\" />\n </div>\n ) : null}\n\n {status === \"error\" ? (\n <div className=\"epochs-pdf-viewer__overlay epochs-pdf-viewer__error\">\n Unable to load PDF.\n {resolvedUrl ? (\n <a\n className=\"epochs-pdf-viewer__open-link\"\n href={resolvedUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Open file\n </a>\n ) : null}\n </div>\n ) : null}\n\n {status === \"ready\" && pdfDoc ? (\n <div>\n {Array.from({ length: numPages }).map((_, idx) => {\n const p = idx + 1;\n return (\n <PageCanvas\n key={p}\n pdfDoc={pdfDoc}\n pageNumber={p}\n scale={scale}\n rotation={rotation}\n markupTool={enableMarkup ? markupTool : \"none\"}\n markupColor={activeMarkupColor}\n annotations={annotations}\n onAddAnnotation={handleAddAnnotation}\n onRemoveAnnotation={handleRemoveAnnotation}\n signatures={signatures}\n pendingSignature={pendingSignature}\n onAddSignature={handleAddSignature}\n onUpdateSignature={handleUpdateSignature}\n onRemoveSignature={handleRemoveSignature}\n onEditSignature={handleEditSignature}\n onDuplicateSignature={handleDuplicateSignature}\n selectedSignatureId={selectedSignatureId}\n onSelectSignature={setSelectedSignatureId}\n signatureFields={signatureFields}\n selectedSignatureFieldId={selectedSignatureFieldId}\n onSelectSignatureField={setSelectedSignatureFieldId}\n hasFixedSignatureFields={hasFixedSignatureFields}\n onOpenSignaturePad={handleOpenSignaturePad}\n fieldValues={fieldValues}\n onFieldValueChange={handleFieldValueChange}\n onFieldValueCommit={handleFieldValueCommit}\n texts={texts}\n onAddText={handleAddText}\n onUpdateText={handleUpdateText}\n onRemoveText={handleRemoveText}\n selectedTextId={selectedTextId}\n onSelectText={setSelectedTextId}\n textFields={textFields}\n selectedTextFieldId={selectedTextFieldId}\n onSelectTextField={setSelectedTextFieldId}\n hasFixedTextFields={hasFixedTextFields}\n editingTextId={editingTextId}\n onEditingTextIdChange={setEditingTextId}\n pageRef={(el) => {\n if (el) pageRefsRef.current.set(p, el);\n }}\n />\n );\n })}\n </div>\n ) : null}\n </div>\n </div>\n\n {hasFixedSignatureFields || onSubmit ? (\n <div className=\"epochs-pdf-viewer__footer\" role=\"navigation\" aria-label=\"Viewer actions\">\n {hasFixedSignatureFields ? (\n <>\n <div className=\"epochs-pdf-viewer__footer-nav\">\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n disabled={signatureFields.length <= 1 || currentFieldIndex <= 0}\n onClick={() => goToSignatureField(-1)}\n >\n Prev\n </button>\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n disabled={\n signatureFields.length <= 1 ||\n currentFieldIndex >= signatureFields.length - 1\n }\n onClick={() => goToSignatureField(1)}\n >\n Next\n </button>\n </div>\n <div className=\"epochs-pdf-viewer__footer-center\">\n <span className=\"epochs-pdf-viewer__footer-label\">\n Field {Math.max(1, currentFieldIndex + 1)} of {signatureFields.length}\n </span>\n <div\n className=\"epochs-pdf-viewer__footer-progress\"\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={fieldProgressPercent}\n aria-label=\"Signature progress\"\n >\n <div\n className=\"epochs-pdf-viewer__footer-progress-bar\"\n style={{ width: `${fieldProgressPercent}%` }}\n />\n </div>\n <span className=\"epochs-pdf-viewer__footer-percent\">\n {fieldProgressPercent}%\n </span>\n </div>\n </>\n ) : (\n <div className=\"epochs-pdf-viewer__footer-center\" />\n )}\n {onSubmit ? (\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text epochs-pdf-viewer__btn--primary\"\n onClick={onSubmit}\n disabled={submitLoading}\n aria-busy={submitLoading || undefined}\n >\n {submitLoading ? (\n <span\n className=\"epochs-pdf-viewer__spinner epochs-pdf-viewer__spinner--btn\"\n aria-hidden=\"true\"\n />\n ) : null}\n {submitLabel}\n </button>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\nexport default PdfViewer;\n","import type {\n DocumentProps,\n ImageProps,\n LinkProps,\n PageProps,\n TextProps,\n ViewProps,\n} from \"./types\";\n\n/** Root document container. Must wrap one or more `<Page>` elements. */\nexport function Document(_props: DocumentProps): null {\n return null;\n}\nDocument.displayName = \"Document\";\n\n/** A single PDF page. */\nexport function Page(_props: PageProps): null {\n return null;\n}\nPage.displayName = \"Page\";\n\n/** Flexbox layout container. */\nexport function View(_props: ViewProps): null {\n return null;\n}\nView.displayName = \"View\";\n\n/** Text content. Children are flattened to a string. */\nexport function Text(_props: TextProps): null {\n return null;\n}\nText.displayName = \"Text\";\n\n/** Image placeholder (binary embedding planned). */\nexport function Image(_props: ImageProps): null {\n return null;\n}\nImage.displayName = \"Image\";\n\n/** Linked text. */\nexport function Link(_props: LinkProps): null {\n return null;\n}\nLink.displayName = \"Link\";\n","import { createElement, type ReactElement, type ReactNode } from \"react\";\nimport type { PdfNode, NodeType } from \"./types\";\n\nconst TYPE_MAP: Record<string, NodeType> = {\n Document: \"DOCUMENT\",\n Page: \"PAGE\",\n View: \"VIEW\",\n Text: \"TEXT\",\n Image: \"IMAGE\",\n Link: \"LINK\",\n};\n\nfunction getDisplayName(type: unknown): string | null {\n if (typeof type === \"string\") return type;\n if (typeof type === \"function\") {\n const fn = type as { displayName?: string; name?: string };\n return fn.displayName || fn.name || null;\n }\n return null;\n}\n\nfunction flattenChildren(children: ReactNode): ReactNode[] {\n const result: ReactNode[] = [];\n const visit = (node: ReactNode) => {\n if (node == null || typeof node === \"boolean\") return;\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n result.push(node);\n };\n visit(children);\n return result;\n}\n\nfunction collectText(children: ReactNode): string {\n return flattenChildren(children)\n .map((child) => {\n if (typeof child === \"string\" || typeof child === \"number\") {\n return String(child);\n }\n if (\n child &&\n typeof child === \"object\" &&\n \"props\" in (child as ReactElement)\n ) {\n const el = child as ReactElement<{ children?: ReactNode }>;\n return collectText(el.props.children);\n }\n return \"\";\n })\n .join(\"\");\n}\n\nexport function elementToPdfNode(element: ReactElement): PdfNode {\n const name = getDisplayName(element.type);\n const nodeType = name ? TYPE_MAP[name] : undefined;\n\n if (!nodeType) {\n throw new Error(\n `[epochs-pdf] Unsupported element \"${name ?? \"unknown\"}\". Use Document, Page, View, Text, Image, or Link.`,\n );\n }\n\n const props = { ...(element.props as Record<string, unknown>) };\n const childrenProp = props.children as ReactNode;\n delete props.children;\n\n if (nodeType === \"TEXT\" || nodeType === \"LINK\") {\n return {\n type: nodeType,\n props,\n children: [],\n text: collectText(childrenProp),\n };\n }\n\n const childNodes = flattenChildren(childrenProp)\n .filter(\n (child): child is ReactElement =>\n !!child && typeof child === \"object\" && \"type\" in (child as object),\n )\n .map(elementToPdfNode);\n\n return {\n type: nodeType,\n props,\n children: childNodes,\n };\n}\n\nexport function createPdfElement(\n type: NodeType,\n props: Record<string, unknown> = {},\n ...children: ReactNode[]\n): ReactElement {\n const name = Object.entries(TYPE_MAP).find(([, v]) => v === type)?.[0];\n if (!name) throw new Error(`Unknown node type: ${type}`);\n return createElement(name, props, ...children);\n}\n","import type { PageSize, Style } from \"./types\";\n\nexport const PAGE_SIZES: Record<Exclude<PageSize, [number, number]>, [number, number]> = {\n A4: [595.28, 841.89],\n LETTER: [612, 792],\n LEGAL: [612, 1008],\n};\n\nexport function resolvePageSize(\n size: PageSize = \"A4\",\n orientation: \"portrait\" | \"landscape\" = \"portrait\",\n): [number, number] {\n const [w, h] = Array.isArray(size) ? size : PAGE_SIZES[size];\n return orientation === \"landscape\" ? [h, w] : [w, h];\n}\n\nexport function expandPadding(style: Style = {}) {\n const base = style.padding ?? 0;\n return {\n top: style.paddingTop ?? base,\n right: style.paddingRight ?? base,\n bottom: style.paddingBottom ?? base,\n left: style.paddingLeft ?? base,\n };\n}\n\nexport function expandMargin(style: Style = {}) {\n const base = style.margin ?? 0;\n return {\n top: style.marginTop ?? base,\n right: style.marginRight ?? base,\n bottom: style.marginBottom ?? base,\n left: style.marginLeft ?? base,\n };\n}\n\n/** Parse #RRGGBB / #RGB / rgb() into 0–1 RGB components. */\nexport function parseColor(input?: string): [number, number, number] | null {\n if (!input) return null;\n\n const hex = input.trim();\n if (hex.startsWith(\"#\")) {\n const raw = hex.slice(1);\n if (raw.length === 3) {\n const r = parseInt(raw[0] + raw[0], 16) / 255;\n const g = parseInt(raw[1] + raw[1], 16) / 255;\n const b = parseInt(raw[2] + raw[2], 16) / 255;\n return [r, g, b];\n }\n if (raw.length === 6) {\n const r = parseInt(raw.slice(0, 2), 16) / 255;\n const g = parseInt(raw.slice(2, 4), 16) / 255;\n const b = parseInt(raw.slice(4, 6), 16) / 255;\n return [r, g, b];\n }\n }\n\n const rgb = input.match(\n /rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)/i,\n );\n if (rgb) {\n return [\n Math.min(1, Number(rgb[1]) / 255),\n Math.min(1, Number(rgb[2]) / 255),\n Math.min(1, Number(rgb[3]) / 255),\n ];\n }\n\n return null;\n}\n\nexport function resolveLength(\n value: number | string | undefined,\n parent: number,\n fallback = 0,\n): number {\n if (value == null) return fallback;\n if (typeof value === \"number\") return value;\n if (value.endsWith(\"%\")) {\n const pct = Number.parseFloat(value);\n return Number.isFinite(pct) ? (pct / 100) * parent : fallback;\n }\n const n = Number.parseFloat(value);\n return Number.isFinite(n) ? n : fallback;\n}\n\nexport function isBold(weight?: Style[\"fontWeight\"]): boolean {\n if (weight === \"bold\") return true;\n if (typeof weight === \"number\") return weight >= 600;\n return false;\n}\n","import type { LayoutBox, PdfNode, ResolvedDocument, ResolvedPage, Style } from \"./types\";\nimport {\n expandMargin,\n expandPadding,\n isBold,\n resolveLength,\n resolvePageSize,\n} from \"./utils\";\n\nconst DEFAULT_FONT_SIZE = 12;\nconst DEFAULT_LINE_HEIGHT = 1.4;\nconst AVG_CHAR_WIDTH = 0.5;\n\nfunction measureText(text: string, style: Style, maxWidth: number): { width: number; height: number; lines: string[] } {\n const fontSize = style.fontSize ?? DEFAULT_FONT_SIZE;\n const lineHeight = (style.lineHeight ?? DEFAULT_LINE_HEIGHT) * fontSize;\n const charWidth = fontSize * (isBold(style.fontWeight) ? 0.55 : AVG_CHAR_WIDTH);\n\n if (!text) {\n return { width: 0, height: lineHeight, lines: [\"\"] };\n }\n\n const words = text.split(/\\s+/);\n const lines: string[] = [];\n let current = \"\";\n\n for (const word of words) {\n const candidate = current ? `${current} ${word}` : word;\n if (candidate.length * charWidth <= maxWidth || !current) {\n current = candidate;\n } else {\n lines.push(current);\n current = word;\n }\n }\n if (current) lines.push(current);\n\n const widest = Math.max(...lines.map((l) => l.length * charWidth), 0);\n return {\n width: Math.min(widest, maxWidth),\n height: lines.length * lineHeight,\n lines,\n };\n}\n\nfunction layoutNode(\n node: PdfNode,\n x: number,\n y: number,\n availableWidth: number,\n availableHeight: number,\n): LayoutBox {\n const style = (node.props.style as Style | undefined) ?? {};\n const margin = expandMargin(style);\n const padding = expandPadding(style);\n\n const outerX = x + margin.left;\n const outerY = y + margin.top;\n const contentWidth = Math.max(\n 0,\n resolveLength(style.width, availableWidth, availableWidth) - margin.left - margin.right,\n );\n const innerWidth = Math.max(0, contentWidth - padding.left - padding.right);\n\n if (node.type === \"TEXT\" || node.type === \"LINK\") {\n const measured = measureText(node.text ?? \"\", style, innerWidth);\n const height =\n resolveLength(style.height, availableHeight, measured.height + padding.top + padding.bottom);\n return {\n x: outerX,\n y: outerY,\n width: contentWidth,\n height,\n node,\n children: [],\n style,\n text: node.text,\n };\n }\n\n if (node.type === \"IMAGE\") {\n const width = resolveLength(style.width, availableWidth, Math.min(200, availableWidth));\n const height = resolveLength(style.height, availableHeight, 120);\n return {\n x: outerX,\n y: outerY,\n width: width - margin.left - margin.right,\n height,\n node,\n children: [],\n style,\n };\n }\n\n const direction = style.flexDirection ?? \"column\";\n const gap = style.gap ?? 0;\n const childBoxes: LayoutBox[] = [];\n\n let cursorX = outerX + padding.left;\n let cursorY = outerY + padding.top;\n let usedMain = 0;\n let crossSize = 0;\n\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n const remainingW =\n direction === \"row\"\n ? Math.max(0, innerWidth - usedMain - (i > 0 ? gap : 0))\n : innerWidth;\n const remainingH =\n direction === \"column\"\n ? Math.max(0, availableHeight - (cursorY - y) - margin.bottom)\n : availableHeight;\n\n const box = layoutNode(child, cursorX, cursorY, remainingW, remainingH);\n childBoxes.push(box);\n\n if (direction === \"row\") {\n usedMain += box.width + expandMargin((child.props.style as Style) ?? {}).left\n + expandMargin((child.props.style as Style) ?? {}).right;\n if (i < node.children.length - 1) usedMain += gap;\n cursorX = outerX + padding.left + usedMain;\n crossSize = Math.max(crossSize, box.height);\n } else {\n usedMain += box.height + expandMargin((child.props.style as Style) ?? {}).top\n + expandMargin((child.props.style as Style) ?? {}).bottom;\n if (i < node.children.length - 1) usedMain += gap;\n cursorY = outerY + padding.top + usedMain;\n crossSize = Math.max(crossSize, box.width);\n }\n }\n\n const contentHeight =\n resolveLength(\n style.height,\n availableHeight,\n direction === \"column\"\n ? usedMain + padding.top + padding.bottom\n : crossSize + padding.top + padding.bottom,\n );\n\n const finalWidth =\n direction === \"row\"\n ? resolveLength(style.width, availableWidth, usedMain + padding.left + padding.right)\n : contentWidth;\n\n const justify = style.justifyContent ?? \"flex-start\";\n const align = style.alignItems ?? \"stretch\";\n\n const innerMain =\n direction === \"column\"\n ? contentHeight - padding.top - padding.bottom\n : finalWidth - padding.left - padding.right;\n const childrenMain = usedMain;\n const freeSpace = Math.max(0, innerMain - childrenMain);\n\n let mainOffset = 0;\n let betweenGap = gap;\n if (justify === \"center\") mainOffset = freeSpace / 2;\n if (justify === \"flex-end\") mainOffset = freeSpace;\n if (justify === \"space-between\" && childBoxes.length > 1) {\n betweenGap = gap + freeSpace / (childBoxes.length - 1);\n }\n if (justify === \"space-around\" && childBoxes.length > 0) {\n betweenGap = gap + freeSpace / childBoxes.length;\n mainOffset = betweenGap / 2;\n }\n\n let running = 0;\n for (const box of childBoxes) {\n if (direction === \"column\") {\n box.y = outerY + padding.top + mainOffset + running;\n if (align === \"center\") {\n box.x = outerX + padding.left + Math.max(0, (innerWidth - box.width) / 2);\n } else if (align === \"flex-end\") {\n box.x = outerX + padding.left + Math.max(0, innerWidth - box.width);\n } else if (align === \"stretch\" && box.style.width == null) {\n box.width = innerWidth;\n }\n running += box.height + betweenGap;\n } else {\n box.x = outerX + padding.left + mainOffset + running;\n if (align === \"center\") {\n box.y =\n outerY +\n padding.top +\n Math.max(0, (contentHeight - padding.top - padding.bottom - box.height) / 2);\n } else if (align === \"flex-end\") {\n box.y =\n outerY +\n padding.top +\n Math.max(0, contentHeight - padding.top - padding.bottom - box.height);\n } else if (align === \"stretch\" && box.style.height == null) {\n box.height = contentHeight - padding.top - padding.bottom;\n }\n running += box.width + betweenGap;\n }\n }\n\n return {\n x: outerX,\n y: outerY,\n width: finalWidth,\n height: contentHeight,\n node,\n children: childBoxes,\n style,\n };\n}\n\nexport function layoutDocument(root: PdfNode): ResolvedDocument {\n if (root.type !== \"DOCUMENT\") {\n throw new Error(\"[epochs-pdf] Root element must be <Document>.\");\n }\n\n const pages: ResolvedPage[] = [];\n\n for (const pageNode of root.children) {\n if (pageNode.type !== \"PAGE\") {\n throw new Error(\"[epochs-pdf] Direct children of <Document> must be <Page>.\");\n }\n\n const size = pageNode.props.size as Parameters<typeof resolvePageSize>[0];\n const orientation = (pageNode.props.orientation as \"portrait\" | \"landscape\") ?? \"portrait\";\n const [width, height] = resolvePageSize(size, orientation);\n const style = (pageNode.props.style as Style | undefined) ?? {};\n const padding = expandPadding(style);\n\n const contentRoot: PdfNode = {\n type: \"VIEW\",\n props: {\n style: {\n ...style,\n width,\n height,\n paddingTop: padding.top,\n paddingRight: padding.right,\n paddingBottom: padding.bottom,\n paddingLeft: padding.left,\n },\n },\n children: pageNode.children,\n };\n\n const box = layoutNode(contentRoot, 0, 0, width, height);\n\n pages.push({\n width,\n height,\n boxes: box.children,\n style,\n });\n }\n\n return {\n meta: {\n title: String(root.props.title ?? \"Untitled\"),\n author: String(root.props.author ?? \"\"),\n subject: String(root.props.subject ?? \"\"),\n creator: String(root.props.creator ?? \"epochs-pdf\"),\n },\n pages,\n };\n}\n\nexport { measureText };\n","import type { LayoutBox, ResolvedDocument, Style } from \"./types\";\nimport { isBold, parseColor } from \"./utils\";\nimport { measureText } from \"./layout\";\n\nfunction escapePdfString(value: string): string {\n return value\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\(/g, \"\\\\(\")\n .replace(/\\)/g, \"\\\\)\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\n/g, \"\\\\n\");\n}\n\nclass PdfWriter {\n private objects: (string | null)[] = [null];\n private offsets: number[] = [0];\n\n addObject(content: string): number {\n this.objects.push(content);\n return this.objects.length - 1;\n }\n\n build(doc: ResolvedDocument): Uint8Array {\n const infoId = this.addObject(\n `<< /Title (${escapePdfString(doc.meta.title)}) /Author (${escapePdfString(doc.meta.author)}) /Subject (${escapePdfString(doc.meta.subject)}) /Creator (${escapePdfString(doc.meta.creator)}) /Producer (epochs-pdf) >>`,\n );\n\n const fontRegular = this.addObject(\n \"<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>\",\n );\n const fontBold = this.addObject(\n \"<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica-Bold >>\",\n );\n\n const pageIds: number[] = [];\n\n for (const page of doc.pages) {\n const contentStream = this.renderPageContent(\n page.boxes,\n page.width,\n page.height,\n page.style,\n );\n const contentId = this.addObject(\n `<< /Length ${contentStream.length} >>\\nstream\\n${contentStream}\\nendstream`,\n );\n\n const pageId = this.addObject(\"\"); // placeholder\n pageIds.push(pageId);\n\n this.objects[pageId] =\n `<< /Type /Page /Parent 0 0 R /MediaBox [0 0 ${page.width.toFixed(2)} ${page.height.toFixed(2)}] /Contents ${contentId} 0 R /Resources << /Font << /F1 ${fontRegular} 0 R /F2 ${fontBold} 0 R >> >> >>`;\n }\n\n const kids = pageIds.map((id) => `${id} 0 R`).join(\" \");\n const pagesId = this.addObject(\n `<< /Type /Pages /Kids [${kids}] /Count ${pageIds.length} >>`,\n );\n\n for (const pageId of pageIds) {\n this.objects[pageId] = (this.objects[pageId] as string).replace(\n \"/Parent 0 0 R\",\n `/Parent ${pagesId} 0 R`,\n );\n }\n\n const catalogId = this.addObject(\n `<< /Type /Catalog /Pages ${pagesId} 0 R >>`,\n );\n\n // Serialize\n let body = \"%PDF-1.4\\n\";\n this.offsets = [0];\n\n for (let i = 1; i < this.objects.length; i++) {\n this.offsets[i] = body.length;\n body += `${i} 0 obj\\n${this.objects[i]}\\nendobj\\n`;\n }\n\n const xrefOffset = body.length;\n body += `xref\\n0 ${this.objects.length}\\n`;\n body += \"0000000000 65535 f \\n\";\n for (let i = 1; i < this.objects.length; i++) {\n body += `${String(this.offsets[i]).padStart(10, \"0\")} 00000 n \\n`;\n }\n body += `trailer\\n<< /Size ${this.objects.length} /Root ${catalogId} 0 R /Info ${infoId} 0 R >>\\n`;\n body += `startxref\\n${xrefOffset}\\n%%EOF`;\n\n return new TextEncoder().encode(body);\n }\n\n private renderPageContent(\n boxes: LayoutBox[],\n pageWidth: number,\n pageHeight: number,\n pageStyle: Style,\n ): string {\n const ops: string[] = [];\n\n const pageBg = parseColor(pageStyle.backgroundColor);\n if (pageBg) {\n ops.push(`q`);\n ops.push(\n `${pageBg[0].toFixed(3)} ${pageBg[1].toFixed(3)} ${pageBg[2].toFixed(3)} rg`,\n );\n ops.push(\n `0 0 ${pageWidth.toFixed(2)} ${pageHeight.toFixed(2)} re f`,\n );\n ops.push(`Q`);\n }\n\n const drawBox = (box: LayoutBox) => {\n const { x, y, width, height, style, node, text } = box;\n const pdfY = pageHeight - y - height;\n\n const fill = parseColor(style.backgroundColor);\n if (fill) {\n ops.push(`q`);\n ops.push(`${fill[0].toFixed(3)} ${fill[1].toFixed(3)} ${fill[2].toFixed(3)} rg`);\n ops.push(`${x.toFixed(2)} ${pdfY.toFixed(2)} ${width.toFixed(2)} ${height.toFixed(2)} re f`);\n ops.push(`Q`);\n }\n\n if (style.borderWidth && style.borderWidth > 0) {\n const border = parseColor(style.borderColor) ?? [0, 0, 0];\n ops.push(`q`);\n ops.push(`${style.borderWidth} w`);\n ops.push(`${border[0].toFixed(3)} ${border[1].toFixed(3)} ${border[2].toFixed(3)} RG`);\n ops.push(`${x.toFixed(2)} ${pdfY.toFixed(2)} ${width.toFixed(2)} ${height.toFixed(2)} re S`);\n ops.push(`Q`);\n }\n\n if ((node.type === \"TEXT\" || node.type === \"LINK\") && text != null) {\n const fontSize = style.fontSize ?? 12;\n const color = parseColor(style.color) ?? [0, 0, 0];\n const font = isBold(style.fontWeight) ? \"F2\" : \"F1\";\n const paddingLeft = style.paddingLeft ?? style.padding ?? 0;\n const paddingTop = style.paddingTop ?? style.padding ?? 0;\n const maxWidth = Math.max(0, width - paddingLeft - (style.paddingRight ?? style.padding ?? 0));\n const measured = measureText(text, style, maxWidth || width);\n const lineHeight = (style.lineHeight ?? 1.4) * fontSize;\n\n ops.push(`q`);\n ops.push(`BT`);\n ops.push(`/${font} ${fontSize} Tf`);\n ops.push(`${color[0].toFixed(3)} ${color[1].toFixed(3)} ${color[2].toFixed(3)} rg`);\n\n measured.lines.forEach((line, index) => {\n let textX = x + paddingLeft;\n const lineWidth = line.length * fontSize * (isBold(style.fontWeight) ? 0.55 : 0.5);\n if (style.textAlign === \"center\") {\n textX = x + (width - lineWidth) / 2;\n } else if (style.textAlign === \"right\") {\n textX = x + width - lineWidth - (style.paddingRight ?? style.padding ?? 0);\n }\n const textY = pageHeight - y - paddingTop - fontSize - index * lineHeight;\n ops.push(`1 0 0 1 ${textX.toFixed(2)} ${textY.toFixed(2)} Tm`);\n ops.push(`(${escapePdfString(line)}) Tj`);\n });\n\n ops.push(`ET`);\n ops.push(`Q`);\n }\n\n if (node.type === \"IMAGE\") {\n // Placeholder rectangle for images (no external deps / binary embedding yet)\n ops.push(`q`);\n ops.push(`0.85 0.85 0.85 rg`);\n ops.push(`${x.toFixed(2)} ${pdfY.toFixed(2)} ${width.toFixed(2)} ${height.toFixed(2)} re f`);\n ops.push(`0.6 0.6 0.6 RG 1 w`);\n ops.push(`${x.toFixed(2)} ${pdfY.toFixed(2)} ${width.toFixed(2)} ${height.toFixed(2)} re S`);\n ops.push(\n `BT /F1 10 Tf 0.4 0.4 0.4 rg 1 0 0 1 ${(x + 8).toFixed(2)} ${(pdfY + height / 2 - 4).toFixed(2)} Tm (Image) Tj ET`,\n );\n ops.push(`Q`);\n }\n\n for (const child of box.children) {\n drawBox(child);\n }\n };\n\n for (const box of boxes) {\n drawBox(box);\n }\n\n return ops.join(\"\\n\");\n }\n}\n\nexport function serializePdf(doc: ResolvedDocument): Uint8Array {\n return new PdfWriter().build(doc);\n}\n","import type { ReactElement } from \"react\";\nimport { elementToPdfNode } from \"./reconciler\";\nimport { layoutDocument } from \"./layout\";\nimport { serializePdf } from \"./pdf-writer\";\n\nfunction renderToBytes(element: ReactElement): Uint8Array {\n const tree = elementToPdfNode(element);\n const laidOut = layoutDocument(tree);\n return serializePdf(laidOut);\n}\n\n/** Render a `<Document>` tree to a `Uint8Array` PDF. */\nexport function pdf(element: ReactElement): Uint8Array {\n return renderToBytes(element);\n}\n\n/** Render to a Blob (browser). */\nexport function toBlob(element: ReactElement): Blob {\n const bytes = renderToBytes(element);\n const copy = new Uint8Array(bytes.byteLength);\n copy.set(bytes);\n return new Blob([copy], { type: \"application/pdf\" });\n}\n\n/** Render to an object URL for iframes / previews. */\nexport function toUrl(element: ReactElement): string {\n return URL.createObjectURL(toBlob(element));\n}\n\n/** Trigger a browser download of the generated PDF. */\nexport function download(\n element: ReactElement,\n filename = \"document.pdf\",\n): void {\n const url = toUrl(element);\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.download = filename;\n anchor.click();\n URL.revokeObjectURL(url);\n}\n\n/** Async-friendly API mirroring common PDF libraries. */\nexport async function renderToBuffer(element: ReactElement): Promise<Uint8Array> {\n return renderToBytes(element);\n}\n\nexport async function renderToBlob(element: ReactElement): Promise<Blob> {\n return toBlob(element);\n}\n"],"names":["REDACT_COLOR","HIGHLIGHT_PRESETS","UNDERLINE_PRESETS","DEFAULT_HIGHLIGHT_HEX","DEFAULT_UNDERLINE_HEX","hexToMarkupColor","createMarkupId","normalizeHex","color","value","r","g","b","hex","kind","alpha","normalized","match","int","selectionRectsForPage","pageSurface","scale","selection","range","pageBox","clientRects","safeScale","layoutW","layoutH","selectionStartPoint","rects","first","a","expandRedactRects","padding","rect","drawMarkupOnCanvas","ctx","annotations","ann","x","y","w","h","thickness","createSignatureId","drawSignaturesOnCanvas","signatures","sig","img","loadImage","drawSignatureFieldsOnCanvas","fields","signedFieldIds","field","isFilled","src","resolve","reject","signatureDisplaySize","sourceWidth","sourceHeight","maxWidth","maxHeight","ratio","clientPointToPage","clientX","clientY","surface","box","pageSizeFromSurface","clientDeltaToPage","deltaX","deltaY","viewportRectToPage","viewport","surfaceRect","pageW","pageH","DEFAULT_TEXT_FONT_SIZE","DEFAULT_TEXT_COLOR","MIN_TEXT_WIDTH","MIN_TEXT_HEIGHT","createTextId","measureInlineText","fontSize","lines","lineHeight","line","resolveInlineTextPoint","textLayer","surfaceBox","toPageX","client","toPageY","toPageSize","clientSize","axis","boxSize","layout","gap","findGapBetweenSpans","doc","_a","inferFontSizeFromNode","caretX","nearest","findNearestSpanOnLine","spans","boxes","span","i","left","right","gapStart","gapEnd","best","midX","dist","node","element","inferFontSizeFromElement","height","computed","parsed","findTextFieldAtPoint","pageNumber","selectWordAtPoint","text","offset","isWordChar","ch","start","end","wordRange","drawTextsOnCanvas","texts","cursorY","drawTextFieldsOnCanvas","filledFieldIds","Icon","size","className","children","jsx","ChevronLeftIcon","props","ChevronRightIcon","DownloadIcon","jsxs","ExternalLinkIcon","GridIcon","MinusIcon","PlusIcon","PrinterIcon","RefreshIcon","RotateIcon","HighlightIcon","UnderlineIcon","EraserIcon","SignatureIcon","PencilIcon","TextIcon","PageCanvas","pdfDoc","rotation","pageRef","onRendered","markupTool","markupColor","onAddAnnotation","onRemoveAnnotation","pendingSignature","onAddSignature","onUpdateSignature","onRemoveSignature","onEditSignature","onDuplicateSignature","selectedSignatureId","onSelectSignature","signatureFields","selectedSignatureFieldId","onSelectSignatureField","hasFixedSignatureFields","onOpenSignaturePad","fieldValues","_onFieldValueChange","_onFieldValueCommit","pendingFieldValue","onPlaceFieldValue","onAddText","onUpdateText","onRemoveText","selectedTextId","onSelectText","textFields","_selectedTextFieldId","onSelectTextField","hasFixedTextFields","editingTextId","onEditingTextIdChange","wrapRef","useRef","canvasRef","textLayerRef","surfaceRef","renderTaskRef","textLayerInstanceRef","dragState","setDragState","useState","inlineEditRef","justOpenedEditorRef","useEffect","cancelled","canvas","textLayerDiv","page","width","task","textContent","TextLayer","applySelectionMarkup","captured","replaceSelectedPdfText","initialValue","created","handleMouseUp","handleKeyDown","event","target","hasPdfSelection","rafId","lastClientX","lastClientY","scrollDir","getScrollContainer","updateResizeAtPoint","s","pageSize","dx","dy","maxW","maxH","newW","newH","updateSignatureAtPoint","pageEl","targetPage","point","nextX","nextY","maxX","maxY","tickScroll","container","maxScroll","edge","distTop","distBottom","speed","prev","handleMove","handleUp","el","current","t","setRefs","pageAnnotations","pageSignatures","pageSignatureFields","f","pageTexts","commitInlineText","trimmed","beginInlineTextAt","fieldId","existing","handleInlineTextClick","handleSurfaceClick","renderInlineText","e","idx","fType","textValue","filled","Fragment","Thumbnail","isActive","onSelect","viewportAt1","pageTextFields","ABSOLUTE_URL_PATTERN","workerConfigured","setPdfWorkerSrc","workerSrc","pdfjsLib","ensurePdfWorker","resolvePdfUrl","file","fileUrl","baseUrl","source","path","urlToPdfArrayBuffer","url","fetchOptions","res","sourceToArrayBuffer","copy","renderPageWithMarkup","options","mimeType","quality","baseViewport","pageMarks","pageSigs","dataUrl","jpegBytes","dataUrlToBytes","renderAllPagesWithMarkup","pages","base64","binary","bytes","enc","concat","parts","total","sum","p","out","part","buildPdfFromJpegPages","objects","add","pageIds","imageStream","imageId","content","contentId","pageId","kids","id","pagesId","catalogId","chunks","offsets","objHeader","objFooter","xrefStart","xref","triggerBlobDownload","blob","filename","anchor","HANDWRITING_FONTS","HANDWRITING_FONTS_HREF","handwritingFontsPromise","embeddedFontCssCache","ensureHandwritingFonts","link","loadFaces","font","escapeXml","bytesToBase64","typedSignatureFontSize","typeKind","family","getEmbeddedFontCss","cached","promise","cssUrl","cssText","urls","uniqueUrls","replacements","fontUrl","buffer","ext","embedded","SignaturePad","open","onClose","onSave","onSaveFieldValue","fieldType","showFieldTypeTabs","textPlaceholder","initialFieldValue","rememberedByType","onRememberFill","drawingRef","lastPointRef","pathsRef","currentPathRef","reusedSignatureRef","resolvedFieldType","activeFieldType","setActiveFieldType","dateValue","setDateValue","setTextValue","mode","setMode","typedName","setTypedName","typedInitials","setTypedInitials","initialsTouched","setInitialsTouched","setTypeKind","inkColor","setInkColor","fontId","setFontId","fontsReady","setFontsReady","isSaving","setIsSaving","hasReusedSignature","setHasReusedSignature","selectedFont","previewText","fontPreviewLabel","_b","remembered","nextFont","reused","getPoint","handlePointerDown","pt","handlePointerMove","last","handlePointerUp","clearPad","handleNameChange","deriveInitials","trimAndSave","allPaths","minX","minY","pad","pathData","svg","measureCtx","metrics","rememberSign","styleBlock","handleFieldValueSave","showSignPad","modalTitle","name","TOOLBAR_TOOL_ID","createToolbarTool","displayName","Tool","getToolbarToolId","tool","isToolbarTool","Navigation","Zoom","Rotate","Reload","Print","Open","Download","Highlight","Underline","Signature","AddText","Erase","Clear","ALL_TOOLBAR_TOOLS","DEFAULT_TOOLBAR_LAYOUT","MARKUP_TOOLS","isMarkupToolbarTool","renderToolbarTool","nodes","v","next","renderMarkupExtras","enabledIds","activeMarkupHex","setActiveMarkupHex","activePresets","preset","resolveToolbarLayout","enableToolbar","flags","toIds","side","showThumbnailsToggle","filterByFlag","tools","enabled","flagMap","PdfViewer","title","initialScale","withThumbnails","thumbnailWidth","maxThumbnails","enableThumbnails","enableNavigation","enableZoom","enableRotate","enableReload","enablePrint","enableOpen","enableDownload","enableMarkup","enableHighlight","enableUnderline","enableSignature","enableText","enableErase","enableClear","signatureFieldsProp","onSignatureComplete","onSignatureFieldsChange","applySignatureToSameTag","onFieldValueComplete","externalOpenSignaturePad","onSignaturePadClose","onSubmit","submitLabel","submitLoading","containerRef","lastBlobUrlRef","pageRefsRef","isProgrammaticScrollRef","binarySource","useMemo","resolvedUrl","status","setStatus","setPdfDoc","numPages","setNumPages","setPageNumber","setScale","setRotation","displayUrl","setDisplayUrl","showThumbnails","setShowThumbnails","isPrinting","setIsPrinting","isDownloading","setIsDownloading","setMarkupTool","setAnnotations","setSignatures","setTexts","signaturePadOpen","setSignaturePadOpen","signaturePadFieldType","setSignaturePadFieldType","setRememberedByType","setPendingSignature","setSelectedSignatureId","setSelectedSignatureFieldId","editingSignatureId","setEditingSignatureId","setSelectedTextId","selectedTextFieldId","setSelectedTextFieldId","setEditingTextId","highlightHex","setHighlightHex","underlineHex","setUnderlineHex","setFieldValues","setSignatureFields","signatureFieldsRef","isSignatureFieldFilled","useCallback","sigs","values","writeFieldValueToFields","fieldIds","idSet","prevValues","updated","writeSignatureImageToFields","signature","signaturesByFieldId","ids","toolbarSides","enabledToolIds","mq","apply","showHighlight","showUnderline","showSignature","showText","showErase","revokeDisplayUrl","loadDocument","blobUrl","scrollToPage","clamped","scrollToSignatureField","focusField","fieldEl","observer","entries","canGoPrev","canGoNext","handlePrev","handleNext","handleRotate","handleZoomOut","handleZoomIn","handleFitWidth","pagePadding","nextScale","run","onMq","fieldValueTexts","textsForExport","handlePrint","iframe","body","wrapper","handleDownload","pdfBytes","toggleMarkupTool","activeMarkupColor","selectedSignature","handleAddAnnotation","annotation","handleRemoveAnnotation","handleClearAnnotations","advanceToNextUnsignedField","fromFieldId","filledIds","currentIndex","nextField","handleOpenSignaturePad","handleFieldValueChange","handleFieldValueCommit","val","k","handleSignatureSave","imageDataUrl","targetField","targetFields","newSignatures","targetIds","byFieldId","currentPageEl","scrollContainer","visible","visibleTop","visibleBottom","visibleLeft","visibleRight","handleSaveFieldValue","nextValues","handleAddSignature","handleUpdateSignature","patch","handleRemoveSignature","removed","handleDuplicateSignature","pageWidth","pageHeight","duplicate","handleEditSignature","targetId","item","handleAddText","handleUpdateText","handleRemoveText","goToSignatureField","direction","from","nextIndex","rootStyle","toolbarCtx","visibleToolIds","currentFieldIndex","filledFieldCount","fieldProgressPercent","renderSide","alignEnd","index","showMarkupSep","type","fill","_","n","ThumbnailStrip","Document","_props","Page","View","Text","Image","Link","TYPE_MAP","getDisplayName","fn","flattenChildren","result","visit","collectText","child","elementToPdfNode","nodeType","childrenProp","childNodes","PAGE_SIZES","resolvePageSize","orientation","expandPadding","style","base","expandMargin","parseColor","input","raw","rgb","resolveLength","parent","fallback","pct","isBold","weight","DEFAULT_FONT_SIZE","DEFAULT_LINE_HEIGHT","AVG_CHAR_WIDTH","measureText","charWidth","words","word","candidate","widest","l","layoutNode","availableWidth","availableHeight","margin","outerX","outerY","contentWidth","innerWidth","measured","childBoxes","cursorX","usedMain","crossSize","remainingW","remainingH","contentHeight","finalWidth","justify","align","innerMain","freeSpace","mainOffset","betweenGap","running","layoutDocument","root","pageNode","contentRoot","escapePdfString","PdfWriter","__publicField","infoId","fontRegular","fontBold","contentStream","xrefOffset","pageStyle","ops","pageBg","drawBox","pdfY","border","paddingLeft","paddingTop","textX","lineWidth","textY","serializePdf","renderToBytes","tree","laidOut","pdf","toBlob","toUrl","download","renderToBuffer","renderToBlob"],"mappings":"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"}
1
+ {"version":3,"file":"epochs-pdf.cjs","sources":["../src/viewer/markup.ts","../src/viewer/signature.ts","../src/viewer/coords.ts","../src/viewer/text.ts","../src/viewer/icons.tsx","../src/viewer/PageCanvas.tsx","../src/viewer/Thumbnail.tsx","../src/viewer/load.ts","../src/viewer/exportPages.ts","../src/viewer/SignaturePad.tsx","../src/viewer/toolbarTools.ts","../src/viewer/ToolbarButtons.tsx","../src/viewer/PdfViewer.tsx","../src/components.tsx","../src/reconciler.ts","../src/utils.ts","../src/layout.ts","../src/pdf-writer.ts","../src/render.ts"],"sourcesContent":["export type MarkupKind = \"highlight\" | \"underline\" | \"redact\";\n\nexport type MarkupTool = \"none\" | MarkupKind | \"erase\" | \"sign\" | \"text\";\n\n/** Opaque cover used when removing existing PDF text. */\nexport const REDACT_COLOR = \"#ffffff\";\n\nexport interface MarkupRect {\n /** Left edge in page CSS pixels at scale = 1. */\n x: number;\n /** Top edge in page CSS pixels at scale = 1. */\n y: number;\n w: number;\n h: number;\n}\n\nexport interface MarkupAnnotation {\n id: string;\n pageNumber: number;\n kind: MarkupKind;\n color: string;\n rects: MarkupRect[];\n text?: string;\n}\n\nexport interface MarkupColorOption {\n id: string;\n label: string;\n /** Solid hex used by the swatch / color input. */\n hex: string;\n}\n\nexport const HIGHLIGHT_PRESETS: MarkupColorOption[] = [\n { id: \"yellow\", label: \"Yellow\", hex: \"#facc15\" },\n { id: \"green\", label: \"Green\", hex: \"#4ade80\" },\n { id: \"pink\", label: \"Pink\", hex: \"#f472b6\" },\n { id: \"blue\", label: \"Blue\", hex: \"#60a5fa\" },\n { id: \"orange\", label: \"Orange\", hex: \"#fb923c\" },\n { id: \"purple\", label: \"Purple\", hex: \"#c084fc\" },\n];\n\nexport const UNDERLINE_PRESETS: MarkupColorOption[] = [\n { id: \"blue\", label: \"Blue\", hex: \"#2563eb\" },\n { id: \"red\", label: \"Red\", hex: \"#dc2626\" },\n { id: \"green\", label: \"Green\", hex: \"#16a34a\" },\n { id: \"orange\", label: \"Orange\", hex: \"#ea580c\" },\n { id: \"purple\", label: \"Purple\", hex: \"#7c3aed\" },\n { id: \"black\", label: \"Black\", hex: \"#111827\" },\n];\n\nexport const DEFAULT_HIGHLIGHT_HEX = HIGHLIGHT_PRESETS[0].hex;\nexport const DEFAULT_UNDERLINE_HEX = UNDERLINE_PRESETS[0].hex;\n\n/** Legacy defaults kept for callers. */\nexport const HIGHLIGHT_COLOR = hexToMarkupColor(DEFAULT_HIGHLIGHT_HEX, \"highlight\");\nexport const UNDERLINE_COLOR = DEFAULT_UNDERLINE_HEX;\n\nexport function createMarkupId(): string {\n return `m_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nexport function normalizeHex(color: string): string {\n const value = color.trim();\n if (/^#[0-9a-fA-F]{6}$/.test(value)) return value.toLowerCase();\n if (/^#[0-9a-fA-F]{3}$/.test(value)) {\n const r = value[1];\n const g = value[2];\n const b = value[3];\n return `#${r}${r}${g}${g}${b}${b}`.toLowerCase();\n }\n return value;\n}\n\n/** Convert a solid hex into the CSS color used for drawing markup. */\nexport function hexToMarkupColor(hex: string, kind: MarkupKind, alpha = 0.45): string {\n const normalized = normalizeHex(hex);\n if (kind === \"underline\" || kind === \"redact\") return normalized;\n\n const match = /^#([0-9a-f]{6})$/i.exec(normalized);\n if (!match) return `rgba(250, 204, 21, ${alpha})`;\n\n const int = Number.parseInt(match[1], 16);\n const r = (int >> 16) & 255;\n const g = (int >> 8) & 255;\n const b = int & 255;\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n}\n\n/** Best-effort extract of a #rrggbb value from a stored markup color. */\nexport function markupColorToHex(color: string, fallback: string): string {\n const normalized = normalizeHex(color);\n if (/^#[0-9a-f]{6}$/i.test(normalized)) return normalized.toLowerCase();\n\n const rgba = color.match(\n /rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)/i,\n );\n if (!rgba) return normalizeHex(fallback);\n\n const toHex = (n: string) =>\n Math.max(0, Math.min(255, Math.round(Number(n))))\n .toString(16)\n .padStart(2, \"0\");\n\n return `#${toHex(rgba[1])}${toHex(rgba[2])}${toHex(rgba[3])}`;\n}\n\n/** Collect selection client rects relative to a page surface, normalized to scale=1. */\nexport function selectionRectsForPage(\n pageSurface: HTMLElement,\n scale: number,\n): { rects: MarkupRect[]; text: string } | null {\n const selection = window.getSelection();\n if (!selection || selection.isCollapsed || selection.rangeCount === 0) {\n return null;\n }\n\n const range = selection.getRangeAt(0);\n if (!pageSurface.contains(range.commonAncestorContainer)) {\n return null;\n }\n\n const pageBox = pageSurface.getBoundingClientRect();\n const clientRects = Array.from(range.getClientRects()).filter(\n (r) => r.width > 0 && r.height > 0,\n );\n\n if (!clientRects.length) return null;\n\n const safeScale = scale || 1;\n const layoutW = pageSurface.clientWidth || pageBox.width;\n const layoutH = pageSurface.clientHeight || pageBox.height;\n const rects: MarkupRect[] = clientRects.map((r) => ({\n x: pageBox.width > 0 ? ((r.left - pageBox.left) / pageBox.width) * (layoutW / safeScale) : 0,\n y: pageBox.height > 0 ? ((r.top - pageBox.top) / pageBox.height) * (layoutH / safeScale) : 0,\n w: pageBox.width > 0 ? (r.width / pageBox.width) * (layoutW / safeScale) : 0,\n h: pageBox.height > 0 ? (r.height / pageBox.height) * (layoutH / safeScale) : 0,\n }));\n\n return { rects, text: selection.toString() };\n}\n\n/** Pick the top-left anchor for replacement text from selection rects. */\nexport function selectionStartPoint(\n rects: MarkupRect[],\n): { x: number; y: number; fontSize: number } {\n const sorted = [...rects].sort((a, b) => a.y - b.y || a.x - b.x);\n const first = sorted[0] ?? { x: 0, y: 0, w: 0, h: 14 };\n return {\n x: first.x,\n y: first.y,\n fontSize: Math.max(8, Math.round(first.h * 0.9) || 14),\n };\n}\n\n/** Slightly expand rects so redaction fully covers glyph ink. */\nexport function expandRedactRects(\n rects: MarkupRect[],\n padding = 2,\n): MarkupRect[] {\n return rects.map((rect) => ({\n x: Math.max(0, rect.x - padding),\n y: Math.max(0, rect.y - padding),\n w: rect.w + padding * 2,\n h: rect.h + padding * 2,\n }));\n}\n\n/** Draw highlight / underline annotations onto a canvas (rects are stored at scale = 1). */\nexport function drawMarkupOnCanvas(\n ctx: CanvasRenderingContext2D,\n annotations: MarkupAnnotation[],\n scale: number,\n): void {\n for (const ann of annotations) {\n for (const rect of ann.rects) {\n const x = rect.x * scale;\n const y = rect.y * scale;\n const w = rect.w * scale;\n const h = rect.h * scale;\n\n if (ann.kind === \"highlight\") {\n ctx.save();\n ctx.globalCompositeOperation = \"multiply\";\n ctx.fillStyle = ann.color;\n ctx.fillRect(x, y, w, h);\n ctx.restore();\n } else if (ann.kind === \"redact\") {\n ctx.fillStyle = ann.color || REDACT_COLOR;\n ctx.fillRect(x, y, w, h);\n } else {\n const thickness = Math.max(2, scale * 1.5);\n ctx.fillStyle = ann.color;\n ctx.fillRect(x, y + h - thickness, w, thickness);\n }\n }\n }\n}\n\n","export interface SignatureAnnotation {\n id: string;\n pageNumber: number;\n fieldId?: string;\n /** Top-left X in page CSS pixels at scale = 1. */\n x: number;\n /** Top-left Y in page CSS pixels at scale = 1. */\n y: number;\n /** Width at scale = 1. */\n width: number;\n /** Height at scale = 1. */\n height: number;\n /** PNG data URL of the signature ink. */\n imageDataUrl: string;\n}\n\nexport type SignatureFieldType = \"sign\" | \"date\" | \"text\";\n\nexport interface SignatureField {\n id: string;\n pageNumber: number;\n x: number;\n y: number;\n width: number;\n height: number;\n /** Field behavior: \"sign\" (default), \"date\" (date picker), or \"text\" (text input). */\n type?: SignatureFieldType;\n /** Placeholder text for \"text\" type fields. */\n placeholder?: string;\n /**\n * Optional group key. When `applySignatureToSameTag` is enabled on the viewer,\n * one signature fills every field that shares this tag.\n */\n signature_tag?: string;\n /** Filled signature image (data URL) after the user signs this field. */\n signatureDataUrl?: string;\n /** Plain text / date string when `type` is `\"text\"` or `\"date\"`. */\n value?: string;\n}\n\nexport function createSignatureId(): string {\n return `s_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nexport async function drawSignaturesOnCanvas(\n ctx: CanvasRenderingContext2D,\n signatures: SignatureAnnotation[],\n scale: number,\n): Promise<void> {\n for (const sig of signatures) {\n const img = await loadImage(sig.imageDataUrl);\n ctx.drawImage(\n img,\n sig.x * scale,\n sig.y * scale,\n sig.width * scale,\n sig.height * scale,\n );\n }\n}\n\nexport function drawSignatureFieldsOnCanvas(\n ctx: CanvasRenderingContext2D,\n fields: SignatureField[],\n signedFieldIds: Set<string>,\n scale: number,\n): void {\n ctx.save();\n for (const field of fields) {\n const isFilled = signedFieldIds.has(field.id);\n const x = field.x * scale;\n const y = field.y * scale;\n const w = field.width * scale;\n const h = field.height * scale;\n\n ctx.fillStyle = isFilled\n ? \"rgba(29, 78, 216, 0.08)\"\n : \"rgba(29, 78, 216, 0.18)\";\n ctx.strokeStyle = isFilled\n ? \"rgba(29, 78, 216, 0.45)\"\n : \"#1d4ed8\";\n ctx.lineWidth = 1.5;\n ctx.setLineDash(isFilled ? [] : [4, 3]);\n ctx.fillRect(x, y, w, h);\n ctx.strokeRect(x, y, w, h);\n }\n ctx.restore();\n}\n\nfunction loadImage(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = () => reject(new Error(\"Failed to load signature image\"));\n img.src = src;\n });\n}\n\n/** Fit a drawn signature canvas into a target box while keeping aspect ratio. */\nexport function signatureDisplaySize(\n sourceWidth: number,\n sourceHeight: number,\n maxWidth = 180,\n maxHeight = 64,\n): { width: number; height: number } {\n if (sourceWidth <= 0 || sourceHeight <= 0) {\n return { width: maxWidth, height: maxHeight };\n }\n const ratio = Math.min(maxWidth / sourceWidth, maxHeight / sourceHeight);\n return {\n width: Math.max(40, sourceWidth * ratio),\n height: Math.max(20, sourceHeight * ratio),\n };\n}\n","/**\n * Browser zoom changes getBoundingClientRect() but not clientWidth/clientHeight.\n * Convert viewport client coordinates into page CSS pixels at scale = 1.\n */\nexport function clientPointToPage(\n clientX: number,\n clientY: number,\n surface: HTMLElement,\n scale: number,\n): { x: number; y: number } {\n const box = surface.getBoundingClientRect();\n const layoutW = surface.clientWidth || box.width;\n const layoutH = surface.clientHeight || box.height;\n if (box.width <= 0 || box.height <= 0 || scale <= 0) {\n return { x: 0, y: 0 };\n }\n return {\n x: ((clientX - box.left) / box.width) * (layoutW / scale),\n y: ((clientY - box.top) / box.height) * (layoutH / scale),\n };\n}\n\n/** Page size in CSS pixels at scale = 1. */\nexport function pageSizeFromSurface(\n surface: HTMLElement,\n scale: number,\n): { width: number; height: number } {\n return {\n width: surface.clientWidth / scale,\n height: surface.clientHeight / scale,\n };\n}\n\n/**\n * Convert a viewport delta (e.g. drag/resize) into page CSS pixels at scale = 1,\n * compensating for browser zoom.\n */\nexport function clientDeltaToPage(\n deltaX: number,\n deltaY: number,\n surface: HTMLElement,\n scale: number,\n): { dx: number; dy: number } {\n const box = surface.getBoundingClientRect();\n const layoutW = surface.clientWidth || box.width;\n const layoutH = surface.clientHeight || box.height;\n if (box.width <= 0 || box.height <= 0 || scale <= 0) {\n return { dx: 0, dy: 0 };\n }\n return {\n dx: (deltaX / box.width) * (layoutW / scale),\n dy: (deltaY / box.height) * (layoutH / scale),\n };\n}\n\n/** Map a viewport Y (or rect edge) relative to surface into page coords at scale = 1. */\nexport function viewportRectToPage(\n viewport: DOMRect,\n surface: HTMLElement,\n scale: number,\n): { left: number; top: number; right: number; bottom: number } {\n const surfaceRect = surface.getBoundingClientRect();\n const { width: pageW, height: pageH } = pageSizeFromSurface(surface, scale);\n if (surfaceRect.width <= 0 || surfaceRect.height <= 0) {\n return { left: 0, top: 0, right: pageW, bottom: pageH };\n }\n return {\n left: ((viewport.left - surfaceRect.left) / surfaceRect.width) * pageW,\n top: ((viewport.top - surfaceRect.top) / surfaceRect.height) * pageH,\n right: ((viewport.right - surfaceRect.left) / surfaceRect.width) * pageW,\n bottom: ((viewport.bottom - surfaceRect.top) / surfaceRect.height) * pageH,\n };\n}\n","export interface TextField {\n id: string;\n pageNumber: number;\n x: number;\n y: number;\n width: number;\n height: number;\n /** Shown when the field is empty. */\n placeholder?: string;\n /** Font size at scale = 1. Default 14. */\n fontSize?: number;\n /** CSS color. Default #111827. */\n color?: string;\n}\n\nexport interface TextAnnotation {\n id: string;\n pageNumber: number;\n fieldId?: string;\n /** Left edge in page CSS pixels at scale = 1. */\n x: number;\n /** Top edge in page CSS pixels at scale = 1. */\n y: number;\n /** Width at scale = 1. */\n width: number;\n /** Height at scale = 1. */\n height: number;\n value: string;\n fontSize: number;\n color: string;\n}\n\nexport const DEFAULT_TEXT_FONT_SIZE = 14;\nexport const DEFAULT_TEXT_COLOR = \"#111827\";\nexport const MIN_TEXT_WIDTH = 24;\nexport const MIN_TEXT_HEIGHT = 20;\n\nexport function createTextId(): string {\n return `t_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nexport function measureInlineText(\n value: string,\n fontSize: number,\n): { width: number; height: number } {\n if (typeof document === \"undefined\") {\n return {\n width: Math.max(MIN_TEXT_WIDTH, value.length * fontSize * 0.55),\n height: Math.max(MIN_TEXT_HEIGHT, fontSize * 1.25),\n };\n }\n\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n return {\n width: Math.max(MIN_TEXT_WIDTH, value.length * fontSize * 0.55),\n height: Math.max(MIN_TEXT_HEIGHT, fontSize * 1.25),\n };\n }\n\n ctx.font = `${fontSize}px sans-serif`;\n const lines = value.split(\"\\n\");\n const lineHeight = fontSize * 1.25;\n let maxWidth = MIN_TEXT_WIDTH;\n\n for (const line of lines) {\n maxWidth = Math.max(maxWidth, ctx.measureText(line || \" \").width + 4);\n }\n\n return {\n width: maxWidth,\n height: Math.max(MIN_TEXT_HEIGHT, lines.length * lineHeight),\n };\n}\n\n/** Resolve where inline text should start from a click on/near PDF text. */\nexport function resolveInlineTextPoint(\n clientX: number,\n clientY: number,\n surface: HTMLElement,\n textLayer: HTMLElement,\n scale: number,\n): { x: number; y: number; fontSize: number } {\n const surfaceBox = surface.getBoundingClientRect();\n const layoutW = surface.clientWidth || surfaceBox.width;\n const layoutH = surface.clientHeight || surfaceBox.height;\n const toPageX = (client: number) =>\n surfaceBox.width > 0\n ? ((client - surfaceBox.left) / surfaceBox.width) * (layoutW / scale)\n : 0;\n const toPageY = (client: number) =>\n surfaceBox.height > 0\n ? ((client - surfaceBox.top) / surfaceBox.height) * (layoutH / scale)\n : 0;\n const toPageSize = (clientSize: number, axis: \"x\" | \"y\") => {\n const boxSize = axis === \"x\" ? surfaceBox.width : surfaceBox.height;\n const layout = axis === \"x\" ? layoutW : layoutH;\n return boxSize > 0 ? (clientSize / boxSize) * (layout / scale) : 0;\n };\n\n // Default: exact click position (works for gaps between words)\n let x = toPageX(clientX);\n let y = toPageY(clientY);\n let fontSize = DEFAULT_TEXT_FONT_SIZE;\n\n // Prefer a gap between two spans on the same line (e.g. between \"this\" and \"PDF\")\n const gap = findGapBetweenSpans(clientX, clientY, textLayer);\n if (gap) {\n return {\n x: toPageX(gap.x),\n y: toPageY(gap.y),\n fontSize: Math.max(8, Math.round(toPageSize(gap.fontSize, \"y\") * 10) / 10),\n };\n }\n\n const doc = document as Document & {\n caretRangeFromPoint?: (x: number, y: number) => Range | null;\n };\n\n const range = doc.caretRangeFromPoint?.(clientX, clientY);\n if (range && textLayer.contains(range.startContainer)) {\n const rects = range.getClientRects();\n const rect = rects.length > 0 ? rects[0] : range.getBoundingClientRect();\n if (rect.height > 0) {\n // Keep the clicked X (insert point), snap Y/size to the line\n y = toPageY(rect.top);\n fontSize = inferFontSizeFromNode(range.startContainer, scale, surface);\n // If caret snapped to a glyph edge, use that X for cleaner alignment\n const caretX = toPageX(rect.left);\n if (Math.abs(caretX - x) < toPageSize(8, \"x\")) {\n x = caretX;\n }\n return { x, y, fontSize };\n }\n }\n\n const nearest = findNearestSpanOnLine(clientX, clientY, textLayer);\n if (nearest) {\n y = toPageY(nearest.top);\n fontSize = Math.max(8, Math.round(toPageSize(nearest.height, \"y\") * 10) / 10);\n }\n\n return { x, y, fontSize };\n}\n\n/** Find a click that lands in the horizontal gap between two word spans. */\nfunction findGapBetweenSpans(\n clientX: number,\n clientY: number,\n textLayer: HTMLElement,\n): { x: number; y: number; fontSize: number } | null {\n const spans = Array.from(\n textLayer.querySelectorAll(\"span\"),\n ) as HTMLElement[];\n if (spans.length < 2) return null;\n\n type SpanBox = { left: number; right: number; top: number; bottom: number; height: number };\n const boxes: SpanBox[] = [];\n\n for (const span of spans) {\n if (!span.textContent?.trim()) continue;\n const box = span.getBoundingClientRect();\n if (box.width <= 0 || box.height <= 0) continue;\n // Same visual line as the click\n if (clientY < box.top - 4 || clientY > box.bottom + 4) continue;\n boxes.push({\n left: box.left,\n right: box.right,\n top: box.top,\n bottom: box.bottom,\n height: box.height,\n });\n }\n\n boxes.sort((a, b) => a.left - b.left);\n\n for (let i = 0; i < boxes.length - 1; i += 1) {\n const left = boxes[i];\n const right = boxes[i + 1];\n const gapStart = left.right;\n const gapEnd = right.left;\n if (gapEnd - gapStart < 1) continue;\n if (clientX >= gapStart - 2 && clientX <= gapEnd + 2) {\n return {\n x: clientX,\n y: Math.min(left.top, right.top),\n fontSize: Math.min(left.height, right.height),\n };\n }\n }\n\n return null;\n}\n\nfunction findNearestSpanOnLine(\n clientX: number,\n clientY: number,\n textLayer: HTMLElement,\n): { top: number; height: number } | null {\n const spans = Array.from(\n textLayer.querySelectorAll(\"span\"),\n ) as HTMLElement[];\n\n let best: { top: number; height: number; dist: number } | null = null;\n\n for (const span of spans) {\n if (!span.textContent?.trim()) continue;\n const box = span.getBoundingClientRect();\n if (box.width <= 0 || box.height <= 0) continue;\n if (clientY < box.top - 6 || clientY > box.bottom + 6) continue;\n\n const midX = (box.left + box.right) / 2;\n const dist = Math.abs(clientX - midX);\n if (!best || dist < best.dist) {\n best = { top: box.top, height: box.height, dist };\n }\n }\n\n return best ? { top: best.top, height: best.height } : null;\n}\n\nfunction inferFontSizeFromNode(\n node: Node,\n scale: number,\n surface?: HTMLElement,\n): number {\n const element =\n node.nodeType === Node.ELEMENT_NODE\n ? (node as HTMLElement)\n : node.parentElement;\n if (element) return inferFontSizeFromElement(element, scale, surface);\n return DEFAULT_TEXT_FONT_SIZE;\n}\n\nfunction inferFontSizeFromElement(\n element: HTMLElement,\n scale: number,\n surface?: HTMLElement,\n): number {\n const height = element.getBoundingClientRect().height;\n if (height > 0) {\n if (surface) {\n const surfaceBox = surface.getBoundingClientRect();\n const layoutH = surface.clientHeight || surfaceBox.height;\n if (surfaceBox.height > 0) {\n return Math.max(\n 8,\n Math.round(((height / surfaceBox.height) * (layoutH / scale)) * 10) / 10,\n );\n }\n }\n return Math.max(8, Math.round((height / scale) * 10) / 10);\n }\n\n const computed = window.getComputedStyle(element).fontSize;\n const parsed = Number.parseFloat(computed);\n if (Number.isFinite(parsed) && parsed > 0) {\n return Math.max(8, Math.round((parsed / scale) * 10) / 10);\n }\n\n return DEFAULT_TEXT_FONT_SIZE;\n}\n\nexport function findTextFieldAtPoint(\n x: number,\n y: number,\n fields: TextField[],\n pageNumber: number,\n): TextField | null {\n for (const field of fields) {\n if (field.pageNumber !== pageNumber) continue;\n if (\n x >= field.x &&\n x <= field.x + field.width &&\n y >= field.y &&\n y <= field.y + field.height\n ) {\n return field;\n }\n }\n return null;\n}\n\n/** Select the word under a point in the PDF text layer (browser selection). */\nexport function selectWordAtPoint(\n clientX: number,\n clientY: number,\n textLayer: HTMLElement | null,\n): string | null {\n if (!textLayer) return null;\n\n const doc = document as Document & {\n caretRangeFromPoint?: (x: number, y: number) => Range | null;\n };\n const range = doc.caretRangeFromPoint?.(clientX, clientY);\n if (!range || !textLayer.contains(range.startContainer)) return null;\n\n const node = range.startContainer;\n if (node.nodeType !== Node.TEXT_NODE || !node.textContent) return null;\n\n const text = node.textContent;\n let offset = range.startOffset;\n offset = Math.min(Math.max(0, offset), text.length);\n\n const isWordChar = (ch: string) => /[\\p{L}\\p{N}_'-]/u.test(ch);\n let start = offset;\n let end = offset;\n\n while (start > 0 && isWordChar(text[start - 1]!)) start -= 1;\n while (end < text.length && isWordChar(text[end]!)) end += 1;\n\n if (start === end) return null;\n\n const wordRange = document.createRange();\n wordRange.setStart(node, start);\n wordRange.setEnd(node, end);\n\n const selection = window.getSelection();\n selection?.removeAllRanges();\n selection?.addRange(wordRange);\n\n return text.slice(start, end);\n}\n\nexport function drawTextsOnCanvas(\n ctx: CanvasRenderingContext2D,\n texts: TextAnnotation[],\n scale: number,\n): void {\n ctx.save();\n for (const text of texts) {\n if (!text.value.trim()) continue;\n\n const x = text.x * scale;\n const y = text.y * scale;\n const fontSize = Math.max(8, text.fontSize * scale);\n\n ctx.fillStyle = text.color;\n ctx.font = `${fontSize}px sans-serif`;\n ctx.textBaseline = \"top\";\n\n const lineHeight = fontSize * 1.25;\n const lines = text.value.split(\"\\n\");\n let cursorY = y;\n\n for (const line of lines) {\n ctx.fillText(line, x, cursorY);\n cursorY += lineHeight;\n }\n }\n ctx.restore();\n}\n\nexport function drawTextFieldsOnCanvas(\n ctx: CanvasRenderingContext2D,\n fields: TextField[],\n filledFieldIds: Set<string>,\n scale: number,\n): void {\n ctx.save();\n for (const field of fields) {\n const isFilled = filledFieldIds.has(field.id);\n const x = field.x * scale;\n const y = field.y * scale;\n const w = field.width * scale;\n const h = field.height * scale;\n\n ctx.fillStyle = isFilled\n ? \"rgba(5, 150, 105, 0.08)\"\n : \"rgba(5, 150, 105, 0.16)\";\n ctx.strokeStyle = isFilled\n ? \"rgba(5, 150, 105, 0.45)\"\n : \"#059669\";\n ctx.lineWidth = 1.5;\n ctx.setLineDash(isFilled ? [] : [4, 3]);\n ctx.fillRect(x, y, w, h);\n ctx.strokeRect(x, y, w, h);\n }\n ctx.restore();\n}\n","import type { ReactNode } from \"react\";\n\ntype IconProps = {\n size?: number;\n className?: string;\n};\n\nfunction Icon({\n size = 14,\n className,\n children,\n}: IconProps & { children: ReactNode }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden=\"true\"\n >\n {children}\n </svg>\n );\n}\n\nexport function ChevronLeftIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <polyline points=\"15 18 9 12 15 6\" />\n </Icon>\n );\n}\n\nexport function ChevronRightIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <polyline points=\"9 18 15 12 9 6\" />\n </Icon>\n );\n}\n\nexport function DownloadIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" />\n </Icon>\n );\n}\n\nexport function ExternalLinkIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </Icon>\n );\n}\n\nexport function GridIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" />\n <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" />\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" />\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" />\n </Icon>\n );\n}\n\nexport function MinusIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </Icon>\n );\n}\n\nexport function PlusIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </Icon>\n );\n}\n\nexport function PrinterIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <polyline points=\"6 9 6 2 18 2 18 9\" />\n <path d=\"M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2\" />\n <rect x=\"6\" y=\"14\" width=\"12\" height=\"8\" />\n </Icon>\n );\n}\n\nexport function RefreshIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <polyline points=\"23 4 23 10 17 10\" />\n <polyline points=\"1 20 1 14 7 14\" />\n <path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\" />\n </Icon>\n );\n}\n\nexport function RotateIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <polyline points=\"23 4 23 10 17 10\" />\n <path d=\"M20.49 15a9 9 0 1 1-2.12-9.36L23 10\" />\n </Icon>\n );\n}\n\nexport function HighlightIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M12 20h9\" />\n <path d=\"M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z\" />\n </Icon>\n );\n}\n\nexport function UnderlineIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M6 3v7a6 6 0 0 0 12 0V3\" />\n <line x1=\"4\" y1=\"21\" x2=\"20\" y2=\"21\" />\n </Icon>\n );\n}\n\nexport function EraserIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21\" />\n <path d=\"M22 21H7\" />\n <path d=\"m5 11 9 9\" />\n </Icon>\n );\n}\n\nexport function SignatureIcon({ size = 16, className }: IconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 256 256\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n strokeWidth=\"12\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden=\"true\"\n >\n <path d=\"M232,172H57.32c4-7.83,8.18-16.11,12.21-24.56,15.14,3.55,34.13-8.06,56.54-34.59,3.67,12.5,12.53,34.83,29.08,35.15h.35c8.71,0,17.64-6.25,27.16-19.06C187.17,137.14,199.31,148,232,148a4,4,0,0,0,0-8c-42.88,0-44-19.24-44-20a4,4,0,0,0-7.35-2.18C168.74,136.1,160.42,140,155.48,140h-.18c-13-.25-21.29-26.52-23.38-36.61a4,4,0,0,0-7-1.69c-20.94,26.27-39.06,39.55-51.8,38.2C97.31,87.5,105.19,53.16,96.49,37.77,94,33.31,88.7,28,77.91,28,64.09,28,52.54,42.41,47,66.54A122.7,122.7,0,0,0,45.46,113c2.64,15.29,8.39,26.05,16.69,31.35-4.58,9.6-9.3,19-13.84,27.68H24a4,4,0,0,0,0,8H44.1c-12.87,24.17-23.37,41.68-23.53,41.94a4,4,0,0,0,1.37,5.49A3.93,3.93,0,0,0,24,228a4,4,0,0,0,3.43-1.94c.16-.27,11.85-19.75,25.72-46.06H232a4,4,0,0,0,0-8ZM53.34,111.61a114.81,114.81,0,0,1,1.49-43.29C58.4,52.7,66.34,36,77.91,36c7.52,0,10.23,3.26,11.61,5.7C99,58.4,79.92,106,65.6,137,59.76,132.69,55.46,123.83,53.34,111.61Z\" />\n </svg>\n );\n}\n\nexport function PencilIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M12 20h9\" />\n <path d=\"M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z\" />\n </Icon>\n );\n}\n\nexport function TextIcon(props: IconProps) {\n return (\n <Icon {...props}>\n <polyline points=\"4 7 4 4 20 4 20 7\" />\n <line x1=\"9\" y1=\"20\" x2=\"15\" y2=\"20\" />\n <line x1=\"12\" y1=\"4\" x2=\"12\" y2=\"20\" />\n </Icon>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport type { RenderTask } from \"pdfjs-dist\";\nimport { TextLayer } from \"pdfjs-dist\";\nimport type { PdfDoc } from \"./types\";\nimport type { MarkupAnnotation, MarkupTool } from \"./markup\";\nimport { createMarkupId, expandRedactRects, REDACT_COLOR, selectionRectsForPage, selectionStartPoint } from \"./markup\";\nimport type { SignatureAnnotation, SignatureField } from \"./signature\";\nimport { createSignatureId } from \"./signature\";\nimport {\n clientDeltaToPage,\n clientPointToPage,\n pageSizeFromSurface,\n} from \"./coords\";\nimport type { TextAnnotation, TextField } from \"./text\";\nimport {\n createTextId,\n DEFAULT_TEXT_COLOR,\n DEFAULT_TEXT_FONT_SIZE,\n findTextFieldAtPoint,\n measureInlineText,\n resolveInlineTextPoint,\n selectWordAtPoint,\n} from \"./text\";\nimport { PencilIcon } from \"./icons\";\n\ninterface PageCanvasProps {\n pdfDoc: PdfDoc;\n pageNumber: number;\n scale: number;\n rotation: number;\n pageRef?: (el: HTMLDivElement | null) => void;\n onRendered?: (pageNumber: number) => void;\n markupTool?: MarkupTool;\n markupColor?: string;\n annotations?: MarkupAnnotation[];\n onAddAnnotation?: (annotation: MarkupAnnotation) => void;\n onRemoveAnnotation?: (id: string) => void;\n signatures?: SignatureAnnotation[];\n pendingSignature?: { imageDataUrl: string; width: number; height: number } | null;\n onAddSignature?: (signature: SignatureAnnotation) => void;\n onUpdateSignature?: (id: string, patch: Partial<SignatureAnnotation>) => void;\n onRemoveSignature?: (id: string) => void;\n onEditSignature?: (id: string) => void;\n onDuplicateSignature?: (id: string) => void;\n selectedSignatureId?: string | null;\n onSelectSignature?: (id: string | null) => void;\n signatureFields?: SignatureField[];\n selectedSignatureFieldId?: string | null;\n onSelectSignatureField?: (id: string | null) => void;\n hasFixedSignatureFields?: boolean;\n onOpenSignaturePad?: (fieldType?: import(\"./signature\").SignatureFieldType) => void;\n /** Values for date/text fixed fields, keyed by field id. */\n fieldValues?: Record<string, string>;\n onFieldValueChange?: (fieldId: string, value: string) => void;\n onFieldValueCommit?: (fieldId: string) => void;\n pendingFieldValue?: { type: \"date\" | \"text\"; value: string } | null;\n onPlaceFieldValue?: (pageNumber: number, x: number, y: number) => void;\n texts?: TextAnnotation[];\n onAddText?: (text: TextAnnotation) => void;\n onUpdateText?: (id: string, patch: Partial<TextAnnotation>) => void;\n onRemoveText?: (id: string) => void;\n selectedTextId?: string | null;\n onSelectText?: (id: string | null) => void;\n textFields?: TextField[];\n selectedTextFieldId?: string | null;\n onSelectTextField?: (id: string | null) => void;\n hasFixedTextFields?: boolean;\n editingTextId?: string | null;\n onEditingTextIdChange?: (id: string | null) => void;\n}\n\nexport function PageCanvas({\n pdfDoc,\n pageNumber,\n scale,\n rotation,\n pageRef,\n onRendered,\n markupTool = \"none\",\n markupColor,\n annotations = [],\n onAddAnnotation,\n onRemoveAnnotation,\n signatures = [],\n pendingSignature = null,\n onAddSignature,\n onUpdateSignature,\n onRemoveSignature,\n onEditSignature,\n onDuplicateSignature,\n selectedSignatureId = null,\n onSelectSignature,\n signatureFields = [],\n selectedSignatureFieldId = null,\n onSelectSignatureField,\n hasFixedSignatureFields = false,\n onOpenSignaturePad,\n fieldValues = {},\n onFieldValueChange: _onFieldValueChange,\n onFieldValueCommit: _onFieldValueCommit,\n pendingFieldValue = null,\n onPlaceFieldValue,\n texts = [],\n onAddText,\n onUpdateText,\n onRemoveText,\n selectedTextId = null,\n onSelectText,\n textFields = [],\n selectedTextFieldId: _selectedTextFieldId = null,\n onSelectTextField,\n hasFixedTextFields = false,\n editingTextId = null,\n onEditingTextIdChange,\n}: PageCanvasProps) {\n const wrapRef = useRef<HTMLDivElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const textLayerRef = useRef<HTMLDivElement>(null);\n const surfaceRef = useRef<HTMLDivElement>(null);\n const renderTaskRef = useRef<RenderTask | null>(null);\n const textLayerInstanceRef = useRef<TextLayer | null>(null);\n const [dragState, setDragState] = useState<\n | { kind: \"signature\"; id: string; offsetX: number; offsetY: number }\n | { kind: \"resize\"; id: string; startX: number; startY: number; startW: number; startH: number }\n | null\n >(null);\n const inlineEditRef = useRef<HTMLSpanElement>(null);\n const justOpenedEditorRef = useRef(false);\n\n useEffect(() => {\n if (!pdfDoc || !canvasRef.current || !textLayerRef.current || !surfaceRef.current) {\n return;\n }\n\n let cancelled = false;\n const canvas = canvasRef.current;\n const textLayerDiv = textLayerRef.current;\n const surface = surfaceRef.current;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n\n const render = async () => {\n try {\n if (renderTaskRef.current) {\n try {\n renderTaskRef.current.cancel();\n } catch {\n // ignore\n }\n renderTaskRef.current = null;\n }\n if (textLayerInstanceRef.current) {\n try {\n textLayerInstanceRef.current.cancel();\n } catch {\n // ignore\n }\n textLayerInstanceRef.current = null;\n }\n\n const page = await pdfDoc.getPage(pageNumber);\n if (cancelled) return;\n\n const viewport = page.getViewport({ scale, rotation });\n const width = Math.floor(viewport.width);\n const height = Math.floor(viewport.height);\n\n canvas.width = width;\n canvas.height = height;\n surface.style.width = `${width}px`;\n surface.style.height = `${height}px`;\n\n const task = page.render({ canvasContext: ctx, viewport });\n renderTaskRef.current = task;\n await task.promise;\n if (cancelled) return;\n\n textLayerDiv.replaceChildren();\n textLayerDiv.style.setProperty(\"--scale-factor\", String(viewport.scale));\n\n const textContent = await page.getTextContent();\n if (cancelled) return;\n\n const textLayer = new TextLayer({\n textContentSource: textContent,\n container: textLayerDiv,\n viewport,\n });\n textLayerInstanceRef.current = textLayer;\n await textLayer.render();\n if (cancelled) return;\n\n onRendered?.(pageNumber);\n } catch {\n // ignore (often cancellation)\n }\n };\n\n void render();\n\n return () => {\n cancelled = true;\n if (renderTaskRef.current) {\n try {\n renderTaskRef.current.cancel();\n } catch {\n // ignore\n }\n renderTaskRef.current = null;\n }\n if (textLayerInstanceRef.current) {\n try {\n textLayerInstanceRef.current.cancel();\n } catch {\n // ignore\n }\n textLayerInstanceRef.current = null;\n }\n };\n }, [pdfDoc, pageNumber, scale, rotation, onRendered]);\n\n useEffect(() => {\n const surface = surfaceRef.current;\n if (!surface) return;\n\n const applySelectionMarkup = (kind: \"highlight\" | \"underline\" | \"redact\") => {\n if (!onAddAnnotation) return false;\n\n const color =\n kind === \"redact\"\n ? REDACT_COLOR\n : markupColor;\n if (!color) return false;\n\n const captured = selectionRectsForPage(surface, scale);\n if (!captured) return false;\n\n const rects =\n kind === \"redact\"\n ? expandRedactRects(captured.rects)\n : captured.rects;\n\n onAddAnnotation({\n id: createMarkupId(),\n pageNumber,\n kind,\n color,\n rects,\n text: captured.text,\n });\n\n window.getSelection()?.removeAllRanges();\n return true;\n };\n\n const replaceSelectedPdfText = (initialValue: string) => {\n if (!onAddAnnotation || !onAddText) return false;\n\n const captured = selectionRectsForPage(surface, scale);\n if (!captured) return false;\n\n const rects = expandRedactRects(captured.rects);\n onAddAnnotation({\n id: createMarkupId(),\n pageNumber,\n kind: \"redact\",\n color: REDACT_COLOR,\n rects,\n text: captured.text,\n });\n\n const start = selectionStartPoint(captured.rects);\n const size = measureInlineText(initialValue || \" \", start.fontSize);\n const created: TextAnnotation = {\n id: createTextId(),\n pageNumber,\n x: start.x,\n y: start.y,\n width: size.width,\n height: size.height,\n value: initialValue,\n fontSize: start.fontSize,\n color: DEFAULT_TEXT_COLOR,\n };\n\n onAddText(created);\n onSelectText?.(created.id);\n onEditingTextIdChange?.(created.id);\n window.getSelection()?.removeAllRanges();\n justOpenedEditorRef.current = true;\n window.setTimeout(() => {\n justOpenedEditorRef.current = false;\n }, 0);\n return true;\n };\n\n const handleMouseUp = () => {\n if (markupTool === \"highlight\" || markupTool === \"underline\") {\n applySelectionMarkup(markupTool);\n return;\n }\n // Erase tool: select PDF words to cover/remove them\n if (markupTool === \"erase\") {\n applySelectionMarkup(\"redact\");\n return;\n }\n // Text tool: select existing PDF text → open it for editing\n if (markupTool === \"text\") {\n const selection = window.getSelection();\n if (\n selection &&\n !selection.isCollapsed &&\n selection.toString().trim() &&\n selection.anchorNode &&\n surface.contains(selection.anchorNode)\n ) {\n replaceSelectedPdfText(selection.toString());\n }\n }\n };\n\n const handleKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement | null;\n if (\n target?.closest(\"[contenteditable='true']\") ||\n target?.closest(\"[contenteditable='']\") ||\n target?.isContentEditable\n ) {\n return;\n }\n\n const selection = window.getSelection();\n const hasPdfSelection =\n selection != null &&\n !selection.isCollapsed &&\n selection.toString().trim().length > 0 &&\n selection.anchorNode != null &&\n surface.contains(selection.anchorNode);\n\n if (markupTool === \"text\" && hasPdfSelection) {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n replaceSelectedPdfText(selection!.toString());\n return;\n }\n\n if (\n event.key.length === 1 &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey\n ) {\n event.preventDefault();\n replaceSelectedPdfText(event.key);\n return;\n }\n }\n\n if (markupTool !== \"text\" && markupTool !== \"erase\") return;\n if (event.key !== \"Backspace\" && event.key !== \"Delete\") return;\n\n if (!hasPdfSelection) return;\n\n event.preventDefault();\n applySelectionMarkup(\"redact\");\n };\n\n surface.addEventListener(\"mouseup\", handleMouseUp);\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n surface.removeEventListener(\"mouseup\", handleMouseUp);\n window.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [\n markupTool,\n markupColor,\n onAddAnnotation,\n onAddText,\n onEditingTextIdChange,\n onSelectText,\n pageNumber,\n scale,\n ]);\n\n useEffect(() => {\n if (!dragState) return;\n\n let rafId = 0;\n let lastClientX = 0;\n let lastClientY = 0;\n let scrollDir = 0; // -1 up, 1 down, 0 none\n\n const getScrollContainer = (): HTMLElement | null => {\n return (\n wrapRef.current?.closest(\".epochs-pdf-viewer__body\") as HTMLElement | null\n );\n };\n\n const updateResizeAtPoint = (clientX: number, clientY: number) => {\n if (dragState.kind !== \"resize\") return;\n if (!onUpdateSignature || hasFixedSignatureFields) return;\n const sig = signatures.find((s) => s.id === dragState.id);\n if (!sig) return;\n\n const surface = surfaceRef.current;\n const pageSize = surface\n ? pageSizeFromSurface(surface, scale)\n : { width: Infinity, height: Infinity };\n const { dx, dy } = surface\n ? clientDeltaToPage(\n clientX - dragState.startX,\n clientY - dragState.startY,\n surface,\n scale,\n )\n : { dx: 0, dy: 0 };\n\n const maxW = pageSize.width - sig.x;\n const maxH = pageSize.height - sig.y;\n const newW = Math.min(maxW, Math.max(40, dragState.startW + dx));\n const newH = Math.min(maxH, Math.max(20, dragState.startH + dy));\n onUpdateSignature(dragState.id, { width: newW, height: newH });\n };\n\n const updateSignatureAtPoint = (clientX: number, clientY: number) => {\n if (dragState.kind !== \"signature\") return;\n if (!onUpdateSignature || hasFixedSignatureFields) return;\n\n const sig = signatures.find((s) => s.id === dragState.id);\n if (!sig) return;\n\n // Prefer element under cursor; fall back to previous page when over empty gutter\n let pageEl = document\n .elementFromPoint(clientX, clientY)\n ?.closest(\"[data-page-number]\") as HTMLElement | null;\n\n if (!pageEl) {\n const pages = Array.from(\n document.querySelectorAll(\".epochs-pdf-viewer__page[data-page-number]\"),\n ) as HTMLElement[];\n pageEl =\n pages.find((page) => {\n const box = page.getBoundingClientRect();\n return clientY >= box.top && clientY <= box.bottom;\n }) ?? null;\n }\n\n if (!pageEl) {\n pageEl = wrapRef.current;\n }\n if (!pageEl) return;\n\n const surface = pageEl.querySelector(\n \".epochs-pdf-viewer__surface\",\n ) as HTMLDivElement | null;\n if (!surface) return;\n\n const targetPage = Number.parseInt(\n pageEl.getAttribute(\"data-page-number\") || String(sig.pageNumber),\n 10,\n );\n\n const point = clientPointToPage(clientX, clientY, surface, scale);\n const pageSize = pageSizeFromSurface(surface, scale);\n let nextX = point.x - dragState.offsetX;\n let nextY = point.y - dragState.offsetY;\n const maxX = Math.max(0, pageSize.width - sig.width);\n const maxY = Math.max(0, pageSize.height - sig.height);\n nextX = Math.min(Math.max(0, nextX), maxX);\n nextY = Math.min(Math.max(0, nextY), maxY);\n\n onUpdateSignature(dragState.id, {\n pageNumber: targetPage,\n x: nextX,\n y: nextY,\n });\n };\n\n const tickScroll = () => {\n rafId = 0;\n if (!scrollDir) return;\n\n const container = getScrollContainer();\n if (!container) return;\n\n const maxScroll = container.scrollHeight - container.clientHeight;\n if (maxScroll <= 0) return;\n\n const edge = 56;\n const box = container.getBoundingClientRect();\n const distTop = lastClientY - box.top;\n const distBottom = box.bottom - lastClientY;\n\n let speed = 0;\n if (scrollDir < 0 && distTop < edge) {\n speed = -Math.max(6, ((edge - distTop) / edge) * 28);\n } else if (scrollDir > 0 && distBottom < edge) {\n speed = Math.max(6, ((edge - distBottom) / edge) * 28);\n } else {\n scrollDir = 0;\n return;\n }\n\n const prev = container.scrollTop;\n container.scrollTop = Math.min(maxScroll, Math.max(0, prev + speed));\n\n if (container.scrollTop !== prev) {\n updateSignatureAtPoint(lastClientX, lastClientY);\n }\n\n if (\n (speed < 0 && container.scrollTop > 0) ||\n (speed > 0 && container.scrollTop < maxScroll)\n ) {\n rafId = window.requestAnimationFrame(tickScroll);\n } else {\n scrollDir = 0;\n }\n };\n\n const handleMove = (event: PointerEvent) => {\n lastClientX = event.clientX;\n lastClientY = event.clientY;\n\n const container = getScrollContainer();\n if (container) {\n const edge = 56;\n const box = container.getBoundingClientRect();\n const distTop = event.clientY - box.top;\n const distBottom = box.bottom - event.clientY;\n\n if (distTop < edge) {\n scrollDir = -1;\n if (!rafId) rafId = window.requestAnimationFrame(tickScroll);\n } else if (distBottom < edge) {\n scrollDir = 1;\n if (!rafId) rafId = window.requestAnimationFrame(tickScroll);\n } else {\n scrollDir = 0;\n }\n }\n\n if (dragState.kind === \"resize\") {\n updateResizeAtPoint(event.clientX, event.clientY);\n } else {\n updateSignatureAtPoint(event.clientX, event.clientY);\n }\n };\n\n const handleUp = () => {\n scrollDir = 0;\n if (rafId) {\n window.cancelAnimationFrame(rafId);\n rafId = 0;\n }\n setDragState(null);\n };\n\n window.addEventListener(\"pointermove\", handleMove);\n window.addEventListener(\"pointerup\", handleUp);\n window.addEventListener(\"pointercancel\", handleUp);\n return () => {\n scrollDir = 0;\n if (rafId) window.cancelAnimationFrame(rafId);\n window.removeEventListener(\"pointermove\", handleMove);\n window.removeEventListener(\"pointerup\", handleUp);\n window.removeEventListener(\"pointercancel\", handleUp);\n };\n }, [\n dragState,\n hasFixedSignatureFields,\n onUpdateSignature,\n scale,\n signatures,\n ]);\n\n useEffect(() => {\n if (!editingTextId || !inlineEditRef.current) return;\n const el = inlineEditRef.current;\n const current = texts.find((t) => t.id === editingTextId);\n // Uncontrolled while editing — set DOM text once so React won't reset the caret\n el.textContent = current?.value ?? \"\";\n el.focus();\n\n const range = document.createRange();\n range.selectNodeContents(el);\n range.collapse(false);\n const selection = window.getSelection();\n selection?.removeAllRanges();\n selection?.addRange(range);\n // Only re-run when the edit session starts, not on every keystroke\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [editingTextId]);\n\n const setRefs = (el: HTMLDivElement | null) => {\n wrapRef.current = el;\n pageRef?.(el);\n };\n\n const pageAnnotations = annotations.filter((a) => a.pageNumber === pageNumber);\n const pageSignatures = signatures.filter((s) => s.pageNumber === pageNumber);\n const pageSignatureFields = signatureFields.filter((f) => f.pageNumber === pageNumber);\n const pageTexts = texts.filter((t) => t.pageNumber === pageNumber);\n\n const commitInlineText = (text: TextAnnotation, value: string) => {\n const trimmed = value.trim();\n if (!trimmed) {\n onRemoveText?.(text.id);\n onEditingTextIdChange?.(null);\n return;\n }\n\n const size = measureInlineText(trimmed, text.fontSize);\n onUpdateText?.(text.id, {\n value: trimmed,\n width: size.width,\n height: size.height,\n });\n onEditingTextIdChange?.(null);\n };\n\n const beginInlineTextAt = (clientX: number, clientY: number) => {\n if (!onAddText) return;\n\n const surface = surfaceRef.current;\n const textLayer = textLayerRef.current;\n if (!surface || !textLayer) return;\n\n let point = resolveInlineTextPoint(\n clientX,\n clientY,\n surface,\n textLayer,\n scale,\n );\n\n let fieldId: string | undefined;\n let color = DEFAULT_TEXT_COLOR;\n\n if (hasFixedTextFields) {\n const field = findTextFieldAtPoint(\n point.x,\n point.y,\n textFields,\n pageNumber,\n );\n if (!field) return;\n\n const existing = texts.find((t) => t.fieldId === field.id);\n if (existing) {\n onSelectText?.(existing.id);\n onSelectTextField?.(field.id);\n onEditingTextIdChange?.(existing.id);\n return;\n }\n\n fieldId = field.id;\n point = {\n x: field.x,\n y: field.y,\n fontSize: field.fontSize ?? DEFAULT_TEXT_FONT_SIZE,\n };\n color = field.color ?? DEFAULT_TEXT_COLOR;\n onSelectTextField?.(field.id);\n }\n\n const size = measureInlineText(\"\", point.fontSize);\n const created: TextAnnotation = {\n id: createTextId(),\n fieldId,\n pageNumber,\n x: point.x,\n y: point.y,\n width: size.width,\n height: size.height,\n value: \"\",\n fontSize: point.fontSize,\n color,\n };\n\n onAddText(created);\n onSelectText?.(created.id);\n onEditingTextIdChange?.(created.id);\n };\n\n const handleInlineTextClick = (event: React.MouseEvent<HTMLElement>) => {\n if (markupTool !== \"text\") return;\n if ((event.target as HTMLElement).closest(\".epochs-pdf-viewer__inline-text\")) {\n return;\n }\n // Skip the click that follows a select-to-edit mouseup\n if (justOpenedEditorRef.current) {\n justOpenedEditorRef.current = false;\n return;\n }\n\n // Selecting existing PDF words opens the editor on mouseup — don't insert here\n const selection = window.getSelection();\n if (selection && !selection.isCollapsed && selection.toString().trim()) {\n return;\n }\n\n // Double-click: select the word under the cursor and edit it\n if (event.detail >= 2) {\n const word = selectWordAtPoint(event.clientX, event.clientY, textLayerRef.current);\n if (word) {\n // mouseup already ran; open editor from the new word selection\n const surface = surfaceRef.current;\n if (surface && onAddAnnotation && onAddText) {\n const captured = selectionRectsForPage(surface, scale);\n if (captured) {\n onAddAnnotation({\n id: createMarkupId(),\n pageNumber,\n kind: \"redact\",\n color: REDACT_COLOR,\n rects: expandRedactRects(captured.rects),\n text: captured.text,\n });\n const start = selectionStartPoint(captured.rects);\n const size = measureInlineText(captured.text || \" \", start.fontSize);\n const created: TextAnnotation = {\n id: createTextId(),\n pageNumber,\n x: start.x,\n y: start.y,\n width: size.width,\n height: size.height,\n value: captured.text,\n fontSize: start.fontSize,\n color: DEFAULT_TEXT_COLOR,\n };\n onAddText(created);\n onSelectText?.(created.id);\n onEditingTextIdChange?.(created.id);\n window.getSelection()?.removeAllRanges();\n justOpenedEditorRef.current = true;\n }\n }\n return;\n }\n }\n\n event.stopPropagation();\n beginInlineTextAt(event.clientX, event.clientY);\n };\n\n const handleSurfaceClick = (event: React.MouseEvent<HTMLDivElement>) => {\n const target = event.target as HTMLElement;\n if (\n target.closest(\".epochs-pdf-viewer__signature\") ||\n target.closest(\".epochs-pdf-viewer__signature-field\") ||\n target.closest(\".epochs-pdf-viewer__inline-text\")\n ) {\n return;\n }\n\n if (markupTool === \"text\") {\n beginInlineTextAt(event.clientX, event.clientY);\n return;\n }\n\n if (\n !hasFixedSignatureFields &&\n markupTool === \"sign\" &&\n pendingFieldValue &&\n onPlaceFieldValue\n ) {\n const surface = surfaceRef.current;\n if (!surface) return;\n const point = clientPointToPage(event.clientX, event.clientY, surface, scale);\n onPlaceFieldValue(pageNumber, Math.max(0, point.x - 75), Math.max(0, point.y - 12));\n return;\n }\n\n if (\n !hasFixedSignatureFields &&\n markupTool === \"sign\" &&\n pendingSignature &&\n onAddSignature\n ) {\n const surface = surfaceRef.current;\n if (!surface) return;\n const pageSize = pageSizeFromSurface(surface, scale);\n const point = clientPointToPage(event.clientX, event.clientY, surface, scale);\n\n let x = point.x - pendingSignature.width / 2;\n let y = point.y - pendingSignature.height / 2;\n\n const maxX = Math.max(0, pageSize.width - pendingSignature.width);\n const maxY = Math.max(0, pageSize.height - pendingSignature.height);\n x = Math.min(Math.max(0, x), maxX);\n y = Math.min(Math.max(0, y), maxY);\n\n onAddSignature({\n id: createSignatureId(),\n pageNumber,\n x,\n y,\n width: pendingSignature.width,\n height: pendingSignature.height,\n imageDataUrl: pendingSignature.imageDataUrl,\n });\n return;\n }\n };\n\n const renderInlineText = (text: TextAnnotation) => {\n const isEditing = editingTextId === text.id;\n\n if (isEditing) {\n return (\n <span\n key={text.id}\n ref={inlineEditRef}\n contentEditable\n suppressContentEditableWarning\n role=\"textbox\"\n aria-label=\"Edit text\"\n className=\"epochs-pdf-viewer__inline-text epochs-pdf-viewer__inline-text--editing\"\n style={{\n left: text.x * scale,\n top: text.y * scale,\n fontSize: text.fontSize * scale,\n color: text.color,\n minWidth: Math.max(12, text.fontSize * scale * 0.5),\n width: Math.max(text.width * scale, text.fontSize * scale * 0.5),\n }}\n onClick={(e) => e.stopPropagation()}\n onPointerDown={(e) => e.stopPropagation()}\n onInput={(e) => {\n const value = e.currentTarget.textContent ?? \"\";\n const size = measureInlineText(value || \" \", text.fontSize);\n // Update metrics only — do not write value back into the DOM\n onUpdateText?.(text.id, {\n value,\n width: size.width,\n height: size.height,\n });\n }}\n onBlur={(e) => {\n commitInlineText(text, e.currentTarget.textContent ?? \"\");\n }}\n onKeyDown={(e) => {\n // Keep spaces / typing local to this editor\n e.stopPropagation();\n if (e.key === \"Escape\") {\n e.preventDefault();\n (e.currentTarget as HTMLElement).blur();\n }\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n (e.currentTarget as HTMLElement).blur();\n }\n }}\n />\n );\n }\n\n if (!text.value.trim()) return null;\n\n return (\n <span\n key={text.id}\n className={\n selectedTextId === text.id\n ? \"epochs-pdf-viewer__inline-text epochs-pdf-viewer__inline-text--selected\"\n : \"epochs-pdf-viewer__inline-text\"\n }\n style={{\n left: text.x * scale,\n top: text.y * scale,\n fontSize: text.fontSize * scale,\n color: text.color,\n }}\n onClick={(e) => {\n e.stopPropagation();\n if (markupTool === \"erase\") {\n onRemoveText?.(text.id);\n return;\n }\n if (markupTool === \"text\") {\n onSelectText?.(text.id);\n onEditingTextIdChange?.(text.id);\n }\n }}\n >\n {text.value}\n </span>\n );\n };\n\n return (\n <div\n ref={setRefs}\n data-page-number={pageNumber}\n className=\"epochs-pdf-viewer__page\"\n >\n <div\n ref={surfaceRef}\n className={`epochs-pdf-viewer__surface epochs-pdf-viewer__surface--tool-${markupTool}`}\n onClick={handleSurfaceClick}\n >\n <canvas ref={canvasRef} className=\"epochs-pdf-viewer__canvas\" />\n\n <div className=\"epochs-pdf-viewer__markup-layer\" aria-hidden=\"true\">\n {pageAnnotations.map((ann) =>\n ann.kind === \"redact\"\n ? null\n : ann.rects.map((rect, idx) => {\n if (ann.kind === \"highlight\") {\n return (\n <div\n key={`${ann.id}_${idx}`}\n className=\"epochs-pdf-viewer__markup epochs-pdf-viewer__markup--highlight\"\n style={{\n left: rect.x * scale,\n top: rect.y * scale,\n width: rect.w * scale,\n height: rect.h * scale,\n background: ann.color,\n }}\n onClick={(e) => {\n if (markupTool !== \"erase\") return;\n e.stopPropagation();\n onRemoveAnnotation?.(ann.id);\n }}\n />\n );\n }\n\n return (\n <div\n key={`${ann.id}_${idx}`}\n className=\"epochs-pdf-viewer__markup epochs-pdf-viewer__markup--underline\"\n style={{\n left: rect.x * scale,\n top: (rect.y + rect.h) * scale - Math.max(2, scale * 1.5),\n width: rect.w * scale,\n height: Math.max(2, scale * 1.5),\n background: ann.color,\n }}\n onClick={(e) => {\n if (markupTool !== \"erase\") return;\n e.stopPropagation();\n onRemoveAnnotation?.(ann.id);\n }}\n />\n );\n }),\n )}\n </div>\n\n <div className=\"epochs-pdf-viewer__signature-layer\">\n {pageSignatureFields.map((field) => {\n const fType = field.type ?? \"sign\";\n const textValue =\n fieldValues[field.id] ?? field.value ?? \"\";\n const filled =\n fType === \"date\" || fType === \"text\"\n ? Boolean(textValue.trim())\n : pageSignatures.some((sig) => sig.fieldId === field.id);\n return (\n <button\n key={field.id}\n type=\"button\"\n data-signature-field-id={field.id}\n className={\n selectedSignatureFieldId === field.id\n ? \"epochs-pdf-viewer__signature-field epochs-pdf-viewer__signature-field--selected\"\n : filled\n ? \"epochs-pdf-viewer__signature-field epochs-pdf-viewer__signature-field--filled\"\n : \"epochs-pdf-viewer__signature-field\"\n }\n style={{\n left: field.x * scale,\n top: field.y * scale,\n width: field.width * scale,\n height: field.height * scale,\n }}\n onClick={(e) => {\n e.stopPropagation();\n onSelectSignatureField?.(field.id);\n if (fType === \"date\" || fType === \"text\") {\n onSelectSignature?.(null);\n onOpenSignaturePad?.(fType);\n return;\n }\n const existing = pageSignatures.find((sig) => sig.fieldId === field.id);\n onSelectSignature?.(existing?.id ?? null);\n if (existing) {\n onEditSignature?.(existing.id);\n } else {\n onOpenSignaturePad?.(fType);\n }\n }}\n title={\n filled\n ? \"Completed field\"\n : fType === \"date\"\n ? \"Date field\"\n : fType === \"text\"\n ? \"Text field\"\n : \"Signature field\"\n }\n >\n {(() => {\n if (fType === \"date\" || fType === \"text\") {\n if (textValue.trim()) {\n return (\n <span className=\"epochs-pdf-viewer__signature-field-value\">\n {textValue}\n </span>\n );\n }\n if (fType === \"date\") return <span>Date here</span>;\n return <span>{field.placeholder ?? \"Enter text\"}</span>;\n }\n return filled ? null : <span>Sign here</span>;\n })()}\n </button>\n );\n })}\n {pageSignatures.map((sig) => (\n <div\n key={sig.id}\n className={\n selectedSignatureId === sig.id\n ? \"epochs-pdf-viewer__signature epochs-pdf-viewer__signature--selected\"\n : \"epochs-pdf-viewer__signature\"\n }\n style={{\n left: sig.x * scale,\n top: sig.y * scale,\n width: sig.width * scale,\n height: sig.height * scale,\n }}\n onPointerDown={(e) => {\n e.stopPropagation();\n e.preventDefault();\n onSelectSignature?.(sig.id);\n\n if (markupTool === \"erase\" && !hasFixedSignatureFields) {\n onRemoveSignature?.(sig.id);\n return;\n }\n\n if (hasFixedSignatureFields) {\n onSelectSignatureField?.(sig.fieldId ?? null);\n onEditSignature?.(sig.id);\n return;\n }\n\n const surface = surfaceRef.current;\n if (!surface) return;\n const point = clientPointToPage(e.clientX, e.clientY, surface, scale);\n setDragState({\n kind: \"signature\",\n id: sig.id,\n offsetX: point.x - sig.x,\n offsetY: point.y - sig.y,\n });\n }}\n >\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__signature-edit\"\n title=\"Edit signature\"\n aria-label=\"Edit signature\"\n onPointerDown={(e) => {\n e.stopPropagation();\n }}\n onClick={(e) => {\n e.stopPropagation();\n onSelectSignature?.(sig.id);\n onEditSignature?.(sig.id);\n }}\n >\n <PencilIcon size={12} />\n </button>\n {!hasFixedSignatureFields ? (\n <>\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__signature-duplicate\"\n title=\"Duplicate signature\"\n aria-label=\"Duplicate signature\"\n onPointerDown={(e) => {\n e.stopPropagation();\n }}\n onClick={(e) => {\n e.stopPropagation();\n onSelectSignature?.(sig.id);\n onDuplicateSignature?.(sig.id);\n }}\n >\n ⧉\n </button>\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__signature-remove\"\n title=\"Remove signature\"\n aria-label=\"Remove signature\"\n onPointerDown={(e) => {\n e.stopPropagation();\n }}\n onClick={(e) => {\n e.stopPropagation();\n onRemoveSignature?.(sig.id);\n }}\n >\n ×\n </button>\n </>\n ) : null}\n <img src={sig.imageDataUrl} alt=\"Signature\" draggable={false} />\n {!hasFixedSignatureFields ? (\n <div\n className=\"epochs-pdf-viewer__signature-resize\"\n title=\"Resize\"\n onPointerDown={(e) => {\n e.stopPropagation();\n e.preventDefault();\n onSelectSignature?.(sig.id);\n setDragState({\n kind: \"resize\",\n id: sig.id,\n startX: e.clientX,\n startY: e.clientY,\n startW: sig.width,\n startH: sig.height,\n });\n }}\n >\n <svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 1L1 7M7 4L4 7\" stroke=\"white\" strokeWidth=\"1.2\" strokeLinecap=\"round\"/>\n </svg>\n </div>\n ) : null}\n </div>\n ))}\n </div>\n\n <div className=\"epochs-pdf-viewer__text-layer-overlay\">\n {pageTexts.map((text) => renderInlineText(text))}\n </div>\n\n <div\n ref={textLayerRef}\n className=\"textLayer epochs-pdf-viewer__text-layer\"\n onClick={handleInlineTextClick}\n />\n\n <div className=\"epochs-pdf-viewer__redact-layer\" aria-hidden=\"true\">\n {pageAnnotations.map((ann) =>\n ann.kind === \"redact\"\n ? ann.rects.map((rect, idx) => (\n <div\n key={`${ann.id}_${idx}`}\n className=\"epochs-pdf-viewer__markup epochs-pdf-viewer__markup--redact\"\n style={{\n left: rect.x * scale,\n top: rect.y * scale,\n width: rect.w * scale,\n height: rect.h * scale,\n background: ann.color || REDACT_COLOR,\n }}\n onClick={(e) => {\n if (markupTool !== \"erase\") return;\n e.stopPropagation();\n onRemoveAnnotation?.(ann.id);\n }}\n />\n ))\n : null,\n )}\n </div>\n </div>\n </div>\n );\n}\n","import { useEffect, useRef } from \"react\";\nimport type { RenderTask } from \"pdfjs-dist\";\nimport { drawMarkupOnCanvas, type MarkupAnnotation } from \"./markup\";\nimport {\n drawSignatureFieldsOnCanvas,\n drawSignaturesOnCanvas,\n type SignatureAnnotation,\n type SignatureField,\n} from \"./signature\";\nimport {\n drawTextFieldsOnCanvas,\n drawTextsOnCanvas,\n type TextAnnotation,\n type TextField,\n} from \"./text\";\nimport type { PdfDoc } from \"./types\";\n\ninterface ThumbnailProps {\n pdfDoc: PdfDoc;\n pageNumber: number;\n isActive?: boolean;\n rotation: number;\n onSelect: (pageNumber: number) => void;\n width?: number;\n annotations?: MarkupAnnotation[];\n signatures?: SignatureAnnotation[];\n signatureFields?: SignatureField[];\n texts?: TextAnnotation[];\n textFields?: TextField[];\n}\n\nexport function Thumbnail({\n pdfDoc,\n pageNumber,\n isActive,\n rotation,\n onSelect,\n width = 140,\n annotations = [],\n signatures = [],\n signatureFields = [],\n texts = [],\n textFields = [],\n}: ThumbnailProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n useEffect(() => {\n if (!pdfDoc || !canvasRef.current) return;\n\n let cancelled = false;\n const canvas = canvasRef.current;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n let task: RenderTask | null = null;\n\n const render = async () => {\n try {\n const page = await pdfDoc.getPage(pageNumber);\n if (cancelled) return;\n\n const viewportAt1 = page.getViewport({ scale: 1, rotation });\n const scale = width / viewportAt1.width;\n const viewport = page.getViewport({ scale, rotation });\n\n canvas.width = Math.floor(viewport.width);\n canvas.height = Math.floor(viewport.height);\n\n task = page.render({ canvasContext: ctx, viewport });\n await task.promise;\n\n const pageAnnotations = annotations.filter((a) => a.pageNumber === pageNumber);\n if (pageAnnotations.length > 0) {\n drawMarkupOnCanvas(ctx, pageAnnotations, scale);\n }\n\n const pageSignatures = signatures.filter((s) => s.pageNumber === pageNumber);\n const pageSignatureFields = signatureFields.filter(\n (field) => field.pageNumber === pageNumber,\n );\n if (pageSignatureFields.length > 0) {\n drawSignatureFieldsOnCanvas(\n ctx,\n pageSignatureFields,\n new Set(pageSignatures.map((sig) => sig.fieldId).filter(Boolean) as string[]),\n scale,\n );\n }\n if (pageSignatures.length > 0) {\n await drawSignaturesOnCanvas(ctx, pageSignatures, scale);\n }\n\n const pageTexts = texts.filter((t) => t.pageNumber === pageNumber);\n const pageTextFields = textFields.filter(\n (field) => field.pageNumber === pageNumber,\n );\n if (pageTextFields.length > 0) {\n drawTextFieldsOnCanvas(\n ctx,\n pageTextFields,\n new Set(\n pageTexts\n .filter((t) => t.fieldId && t.value.trim())\n .map((t) => t.fieldId as string),\n ),\n scale,\n );\n }\n if (pageTexts.length > 0) {\n drawTextsOnCanvas(ctx, pageTexts, scale);\n }\n } catch {\n // ignore\n }\n };\n\n void render();\n\n return () => {\n cancelled = true;\n if (task) {\n try {\n task.cancel();\n } catch {\n // ignore\n }\n }\n };\n }, [\n annotations,\n pdfDoc,\n pageNumber,\n rotation,\n signatureFields,\n signatures,\n textFields,\n texts,\n width,\n ]);\n\n return (\n <button\n type=\"button\"\n onClick={() => onSelect(pageNumber)}\n className={\n isActive\n ? \"epochs-pdf-viewer__thumb epochs-pdf-viewer__thumb--active\"\n : \"epochs-pdf-viewer__thumb\"\n }\n title={`Page ${pageNumber}`}\n >\n <div className=\"epochs-pdf-viewer__thumb-frame\">\n <canvas ref={canvasRef} />\n </div>\n <span className=\"epochs-pdf-viewer__thumb-label\">{pageNumber}</span>\n </button>\n );\n}\n","import * as pdfjsLib from \"pdfjs-dist\";\n\nconst ABSOLUTE_URL_PATTERN = /^(blob:|https?:|data:)/i;\n\nlet workerConfigured = false;\n\n/** Configure pdf.js worker. Call once, or pass `workerSrc` to `<PdfViewer>`. */\nexport function setPdfWorkerSrc(workerSrc: string): void {\n pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;\n workerConfigured = true;\n}\n\nexport function ensurePdfWorker(workerSrc?: string): void {\n if (workerSrc) {\n setPdfWorkerSrc(workerSrc);\n return;\n }\n if (workerConfigured || pdfjsLib.GlobalWorkerOptions.workerSrc) return;\n\n setPdfWorkerSrc(\n `https://unpkg.com/pdfjs-dist@${pdfjsLib.version}/build/pdf.worker.min.mjs`,\n );\n}\n\nexport function resolvePdfUrl(\n file?: string,\n fileUrl?: string,\n baseUrl = \"\",\n): string {\n const source = fileUrl || file;\n if (!source) return \"\";\n\n if (ABSOLUTE_URL_PATTERN.test(source)) return source;\n\n const path = source.startsWith(\"/\") ? source : `/${source}`;\n if (!baseUrl) return path;\n return `${baseUrl.replace(/\\/$/, \"\")}${path}`;\n}\n\nexport async function urlToPdfArrayBuffer(\n url: string,\n fetchOptions?: RequestInit,\n): Promise<ArrayBuffer> {\n const res = await fetch(url, fetchOptions);\n\n if (!res.ok) {\n throw new Error(`Failed to fetch PDF (${res.status})`);\n }\n\n return res.arrayBuffer();\n}\n\nexport async function sourceToArrayBuffer(\n source: string | ArrayBuffer | Uint8Array | Blob,\n fetchOptions?: RequestInit,\n): Promise<ArrayBuffer> {\n if (typeof source === \"string\") {\n return urlToPdfArrayBuffer(source, fetchOptions);\n }\n if (source instanceof ArrayBuffer) return source.slice(0);\n if (source instanceof Uint8Array) {\n const copy = new Uint8Array(source.byteLength);\n copy.set(source);\n return copy.buffer;\n }\n return source.arrayBuffer();\n}\n\nexport { pdfjsLib };\n","import type { PDFDocumentProxy } from \"pdfjs-dist\";\nimport type { MarkupAnnotation } from \"./markup\";\nimport { drawMarkupOnCanvas } from \"./markup\";\nimport type { SignatureAnnotation } from \"./signature\";\nimport { drawSignaturesOnCanvas } from \"./signature\";\nimport type { TextAnnotation } from \"./text\";\nimport { drawTextsOnCanvas } from \"./text\";\n\nexport interface RenderedPageImage {\n pageNumber: number;\n /** Canvas pixel size */\n width: number;\n height: number;\n /** PDF page size at scale 1 (points) */\n pageWidth: number;\n pageHeight: number;\n dataUrl: string;\n jpegBytes: Uint8Array;\n}\n\n/** Render a page in the *main* document (iframe canvases break pdf.js fonts). */\nexport async function renderPageWithMarkup(\n pdfDoc: PDFDocumentProxy,\n pageNumber: number,\n options: {\n scale: number;\n rotation: number;\n annotations: MarkupAnnotation[];\n signatures?: SignatureAnnotation[];\n texts?: TextAnnotation[];\n mimeType?: \"image/png\" | \"image/jpeg\";\n quality?: number;\n },\n): Promise<RenderedPageImage> {\n const {\n scale,\n rotation,\n annotations,\n signatures = [],\n texts = [],\n mimeType = \"image/jpeg\",\n quality = 0.92,\n } = options;\n\n const page = await pdfDoc.getPage(pageNumber);\n const viewport = page.getViewport({ scale, rotation });\n const baseViewport = page.getViewport({ scale: 1, rotation });\n\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\", { alpha: false });\n if (!ctx) {\n throw new Error(\"Could not create canvas context\");\n }\n\n const width = Math.floor(viewport.width);\n const height = Math.floor(viewport.height);\n canvas.width = width;\n canvas.height = height;\n\n ctx.fillStyle = \"#ffffff\";\n ctx.fillRect(0, 0, width, height);\n\n await page.render({ canvasContext: ctx, viewport }).promise;\n\n const pageMarks = annotations.filter((a) => a.pageNumber === pageNumber);\n if (pageMarks.length > 0) {\n drawMarkupOnCanvas(ctx, pageMarks, scale);\n }\n\n const pageSigs = signatures.filter((s) => s.pageNumber === pageNumber);\n if (pageSigs.length > 0) {\n await drawSignaturesOnCanvas(ctx, pageSigs, scale);\n }\n\n const pageTexts = texts.filter((t) => t.pageNumber === pageNumber);\n if (pageTexts.length > 0) {\n drawTextsOnCanvas(ctx, pageTexts, scale);\n }\n\n const dataUrl = canvas.toDataURL(mimeType, quality);\n const jpegBytes = dataUrlToBytes(dataUrl);\n\n canvas.width = 0;\n canvas.height = 0;\n\n return {\n pageNumber,\n width,\n height,\n pageWidth: baseViewport.width,\n pageHeight: baseViewport.height,\n dataUrl,\n jpegBytes,\n };\n}\n\nexport async function renderAllPagesWithMarkup(\n pdfDoc: PDFDocumentProxy,\n options: {\n scale: number;\n rotation: number;\n annotations: MarkupAnnotation[];\n signatures?: SignatureAnnotation[];\n texts?: TextAnnotation[];\n mimeType?: \"image/png\" | \"image/jpeg\";\n quality?: number;\n },\n): Promise<RenderedPageImage[]> {\n const pages: RenderedPageImage[] = [];\n for (let i = 1; i <= pdfDoc.numPages; i += 1) {\n pages.push(await renderPageWithMarkup(pdfDoc, i, options));\n }\n return pages;\n}\n\nfunction dataUrlToBytes(dataUrl: string): Uint8Array {\n const base64 = dataUrl.split(\",\")[1] ?? \"\";\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i += 1) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\nfunction enc(text: string): Uint8Array {\n return new TextEncoder().encode(text);\n}\n\nfunction concat(...parts: Uint8Array[]): Uint8Array {\n const total = parts.reduce((sum, p) => sum + p.byteLength, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const part of parts) {\n out.set(part, offset);\n offset += part.byteLength;\n }\n return out;\n}\n\n/**\n * Build a multi-page PDF embedding each page as a JPEG (includes baked markup).\n */\nexport function buildPdfFromJpegPages(pages: RenderedPageImage[]): Uint8Array {\n type PdfObject = Uint8Array;\n const objects: PdfObject[] = [];\n\n const add = (bytes: Uint8Array): number => {\n objects.push(bytes);\n return objects.length; // 1-indexed id\n };\n\n const pageIds: number[] = [];\n\n for (const page of pages) {\n const imageStream = concat(\n enc(\n `<< /Type /XObject /Subtype /Image /Width ${page.width} /Height ${page.height} /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length ${page.jpegBytes.byteLength} >>\\nstream\\n`,\n ),\n page.jpegBytes,\n enc(`\\nendstream`),\n );\n const imageId = add(imageStream);\n\n const content = `q\\n${page.pageWidth.toFixed(2)} 0 0 ${page.pageHeight.toFixed(2)} 0 0 cm\\n/Im0 Do\\nQ`;\n const contentId = add(\n enc(`<< /Length ${content.length} >>\\nstream\\n${content}\\nendstream`),\n );\n\n // Parent placeholder replaced after pages object exists\n const pageId = add(\n enc(\n `<< /Type /Page /Parent __PAGES__ 0 R /MediaBox [0 0 ${page.pageWidth.toFixed(2)} ${page.pageHeight.toFixed(2)}] /Contents ${contentId} 0 R /Resources << /XObject << /Im0 ${imageId} 0 R >> >> >>`,\n ),\n );\n pageIds.push(pageId);\n }\n\n const kids = pageIds.map((id) => `${id} 0 R`).join(\" \");\n const pagesId = add(\n enc(`<< /Type /Pages /Kids [${kids}] /Count ${pageIds.length} >>`),\n );\n\n for (const pageId of pageIds) {\n const text = new TextDecoder().decode(objects[pageId - 1]);\n objects[pageId - 1] = enc(\n text.replace(\"/Parent __PAGES__ 0 R\", `/Parent ${pagesId} 0 R`),\n );\n }\n\n const catalogId = add(enc(`<< /Type /Catalog /Pages ${pagesId} 0 R >>`));\n\n const chunks: Uint8Array[] = [enc(\"%PDF-1.4\\n\")];\n const offsets: number[] = [0];\n let offset = chunks[0].byteLength;\n\n for (let i = 0; i < objects.length; i += 1) {\n offsets.push(offset);\n const objHeader = enc(`${i + 1} 0 obj\\n`);\n const objFooter = enc(`\\nendobj\\n`);\n chunks.push(objHeader, objects[i], objFooter);\n offset += objHeader.byteLength + objects[i].byteLength + objFooter.byteLength;\n }\n\n const xrefStart = offset;\n let xref = `xref\\n0 ${objects.length + 1}\\n`;\n xref += \"0000000000 65535 f \\n\";\n for (let i = 1; i <= objects.length; i += 1) {\n xref += `${String(offsets[i]).padStart(10, \"0\")} 00000 n \\n`;\n }\n xref += `trailer\\n<< /Size ${objects.length + 1} /Root ${catalogId} 0 R >>\\n`;\n xref += `startxref\\n${xrefStart}\\n%%EOF`;\n chunks.push(enc(xref));\n\n return concat(...chunks);\n}\n\nexport function triggerBlobDownload(blob: Blob, filename: string): void {\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.download = filename;\n anchor.click();\n URL.revokeObjectURL(url);\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport type { SignatureFieldType } from \"./signature\";\n\ninterface SignaturePadProps {\n open: boolean;\n onClose: () => void;\n onSave: (imageDataUrl: string, width: number, height: number) => void;\n /** Saves plain text for date/text fields (not converted to an image). */\n onSaveFieldValue?: (value: string, fieldType: \"date\" | \"text\") => void;\n /** When set, locks the modal to this field type (from a fixed field). */\n fieldType?: SignatureFieldType;\n /** Show Sign/Date/Text tabs when no fixed field type is provided. */\n showFieldTypeTabs?: boolean;\n /** Placeholder for text-type fields. */\n textPlaceholder?: string;\n /** Prefill when reopening an already-filled date/text field. */\n initialFieldValue?: string;\n /** Fixed signature field box size — typed/draw output is fit to this. */\n targetSize?: { width: number; height: number };\n /** Last submitted values by field type — used to prefill the modal. */\n rememberedByType?: RememberedFieldFills;\n /** Persist the values the user just submitted for this field type. */\n onRememberFill?: (\n type: SignatureFieldType,\n fill: RememberedSignFill | { value: string },\n ) => void;\n}\n\ntype PadMode = \"draw\" | \"type\";\n\nexport type RememberedSignFill = {\n mode: PadMode;\n imageDataUrl: string;\n width: number;\n height: number;\n typedName?: string;\n typedInitials?: string;\n fontId?: string;\n inkColor?: string;\n typeKind?: \"signature\" | \"initials\";\n};\n\nexport type RememberedFieldFills = {\n sign?: RememberedSignFill;\n date?: { value: string };\n text?: { value: string };\n};\n\nconst SVG_SAFE_FONTS = [\n { id: \"cursive\", label: \"Cursive\", family: \"cursive\" },\n { id: \"serif\", label: \"Serif\", family: \"serif\" },\n { id: \"sans\", label: \"Sans\", family: \"sans-serif\" },\n { id: \"mono\", label: \"Mono\", family: \"monospace\" },\n { id: \"fantasy\", label: \"Fantasy\", family: \"fantasy\" },\n] as const;\n\ntype SvgSafeFontId = (typeof SVG_SAFE_FONTS)[number][\"id\"];\n\nfunction escapeXml(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\");\n}\n\nfunction svgToBase64DataUrl(svg: string): string {\n const bytes = new TextEncoder().encode(svg);\n let binary = \"\";\n const chunk = 0x8000;\n for (let i = 0; i < bytes.length; i += chunk) {\n binary += String.fromCharCode(...bytes.subarray(i, i + chunk));\n }\n return `data:image/svg+xml;base64,${btoa(binary)}`;\n}\n\nfunction typedSignatureFontSize(typeKind: \"signature\" | \"initials\"): number {\n return typeKind === \"initials\" ? 64 : 48;\n}\n\nexport function SignaturePad({\n open,\n onClose,\n onSave,\n onSaveFieldValue,\n fieldType,\n showFieldTypeTabs = false,\n textPlaceholder,\n initialFieldValue,\n targetSize,\n rememberedByType,\n onRememberFill,\n}: SignaturePadProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const drawingRef = useRef(false);\n const lastPointRef = useRef<{ x: number; y: number } | null>(null);\n const pathsRef = useRef<{ x: number; y: number }[][]>([]);\n const currentPathRef = useRef<{ x: number; y: number }[]>([]);\n const reusedSignatureRef = useRef<{\n imageDataUrl: string;\n width: number;\n height: number;\n } | null>(null);\n\n const resolvedFieldType: SignatureFieldType = fieldType ?? \"sign\";\n const [activeFieldType, setActiveFieldType] = useState<SignatureFieldType>(resolvedFieldType);\n const [dateValue, setDateValue] = useState(\"\");\n const [textValue, setTextValue] = useState(\"\");\n\n const [mode, setMode] = useState<PadMode>(\"draw\");\n const [typedName, setTypedName] = useState(\"\");\n const [typedInitials, setTypedInitials] = useState(\"\");\n const [initialsTouched, setInitialsTouched] = useState(false);\n const [typeKind, setTypeKind] = useState<\"signature\" | \"initials\">(\"signature\");\n const [inkColor, setInkColor] = useState(\"#111827\");\n const [fontId, setFontId] = useState<SvgSafeFontId>(\"cursive\");\n const [hasReusedSignature, setHasReusedSignature] = useState(false);\n\n const selectedFont =\n SVG_SAFE_FONTS.find((font) => font.id === fontId) ?? SVG_SAFE_FONTS[0];\n\n const previewText =\n typeKind === \"initials\" ? typedInitials.trim() : typedName.trim();\n const fontPreviewLabel =\n previewText || (typeKind === \"initials\" ? \"AB\" : \"Signature\");\n\n useEffect(() => {\n if (!open) return;\n setActiveFieldType(resolvedFieldType);\n\n if (resolvedFieldType === \"date\") {\n setDateValue(\n initialFieldValue ||\n rememberedByType?.date?.value ||\n new Date().toISOString().slice(0, 10),\n );\n return;\n }\n\n if (resolvedFieldType === \"text\") {\n setTextValue(initialFieldValue || rememberedByType?.text?.value || \"\");\n return;\n }\n\n const remembered = rememberedByType?.sign;\n if (!remembered) {\n setMode(\"draw\");\n setTypedName(\"\");\n setTypedInitials(\"\");\n setInitialsTouched(false);\n setTypeKind(\"signature\");\n setInkColor(\"#111827\");\n setFontId(\"cursive\");\n reusedSignatureRef.current = null;\n setHasReusedSignature(false);\n return;\n }\n\n setMode(remembered.mode);\n setTypedName(remembered.typedName ?? \"\");\n setTypedInitials(remembered.typedInitials ?? \"\");\n setInitialsTouched(Boolean(remembered.typedInitials));\n setTypeKind(remembered.typeKind ?? \"signature\");\n setInkColor(remembered.inkColor ?? \"#111827\");\n const nextFont = SVG_SAFE_FONTS.find((font) => font.id === remembered.fontId);\n if (nextFont) setFontId(nextFont.id);\n if (remembered.mode === \"draw\") {\n reusedSignatureRef.current = {\n imageDataUrl: remembered.imageDataUrl,\n width: remembered.width,\n height: remembered.height,\n };\n setHasReusedSignature(true);\n } else {\n reusedSignatureRef.current = null;\n setHasReusedSignature(false);\n }\n }, [open, resolvedFieldType, rememberedByType, initialFieldValue]);\n\n useEffect(() => {\n if (!open || activeFieldType !== \"sign\") return;\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n\n canvas.width = 560;\n canvas.height = 200;\n ctx.fillStyle = \"#ffffff\";\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n ctx.strokeStyle = inkColor;\n ctx.lineWidth = 2.5;\n lastPointRef.current = null;\n drawingRef.current = false;\n pathsRef.current = [];\n currentPathRef.current = [];\n\n if (mode !== \"draw\") return;\n\n const reused = reusedSignatureRef.current;\n if (!reused?.imageDataUrl) return;\n\n const img = new Image();\n img.onload = () => {\n const scale = Math.min(\n canvas.width / Math.max(1, reused.width),\n canvas.height / Math.max(1, reused.height),\n 1,\n );\n const w = reused.width * scale;\n const h = reused.height * scale;\n ctx.drawImage(img, (canvas.width - w) / 2, (canvas.height - h) / 2, w, h);\n };\n img.src = reused.imageDataUrl;\n }, [open, activeFieldType, mode]);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext(\"2d\");\n if (!ctx) return;\n ctx.strokeStyle = inkColor;\n ctx.fillStyle = inkColor;\n }, [inkColor]);\n\n useEffect(() => {\n if (!open || mode !== \"type\") return;\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext(\"2d\");\n if (!canvas || !ctx) return;\n\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n if (!previewText) return;\n\n const size = typedSignatureFontSize(typeKind);\n\n ctx.fillStyle = inkColor;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.font = `${size}px ${selectedFont.family}`;\n ctx.fillText(previewText, canvas.width / 2, canvas.height / 2);\n }, [\n previewText,\n typeKind,\n mode,\n inkColor,\n open,\n selectedFont,\n ]);\n\n if (!open) return null;\n\n const getPoint = (event: React.PointerEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current!;\n const rect = canvas.getBoundingClientRect();\n return {\n x: ((event.clientX - rect.left) / rect.width) * canvas.width,\n y: ((event.clientY - rect.top) / rect.height) * canvas.height,\n };\n };\n\n const handlePointerDown = (event: React.PointerEvent<HTMLCanvasElement>) => {\n if (mode !== \"draw\") return;\n if (reusedSignatureRef.current) {\n reusedSignatureRef.current = null;\n setHasReusedSignature(false);\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext(\"2d\");\n if (canvas && ctx) {\n ctx.fillStyle = \"#ffffff\";\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n ctx.strokeStyle = inkColor;\n ctx.lineWidth = 2.5;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n }\n pathsRef.current = [];\n }\n event.currentTarget.setPointerCapture(event.pointerId);\n drawingRef.current = true;\n const pt = getPoint(event);\n lastPointRef.current = pt;\n currentPathRef.current = [pt];\n };\n\n const handlePointerMove = (event: React.PointerEvent<HTMLCanvasElement>) => {\n if (!drawingRef.current || mode !== \"draw\") return;\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext(\"2d\");\n const last = lastPointRef.current;\n if (!ctx || !last) return;\n\n const point = getPoint(event);\n ctx.beginPath();\n ctx.moveTo(last.x, last.y);\n ctx.lineTo(point.x, point.y);\n ctx.stroke();\n lastPointRef.current = point;\n currentPathRef.current.push(point);\n };\n\n const handlePointerUp = () => {\n if (currentPathRef.current.length > 1) {\n pathsRef.current.push([...currentPathRef.current]);\n }\n currentPathRef.current = [];\n drawingRef.current = false;\n lastPointRef.current = null;\n };\n\n const clearPad = () => {\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext(\"2d\");\n if (!canvas || !ctx) return;\n ctx.fillStyle = \"#ffffff\";\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n pathsRef.current = [];\n currentPathRef.current = [];\n reusedSignatureRef.current = null;\n setHasReusedSignature(false);\n setTypedName(\"\");\n setTypedInitials(\"\");\n setInitialsTouched(false);\n };\n\n const handleNameChange = (value: string) => {\n setTypedName(value);\n if (!initialsTouched) {\n setTypedInitials(deriveInitials(value));\n }\n };\n\n const trimAndSave = () => {\n if (mode === \"draw\") {\n const allPaths = pathsRef.current;\n const reused = reusedSignatureRef.current;\n if (allPaths.length === 0) {\n if (!reused) return;\n onRememberFill?.(\"sign\", {\n mode: \"draw\",\n imageDataUrl: reused.imageDataUrl,\n width: reused.width,\n height: reused.height,\n inkColor,\n });\n onSave(reused.imageDataUrl, reused.width, reused.height);\n return;\n }\n\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const path of allPaths) {\n for (const pt of path) {\n if (pt.x < minX) minX = pt.x;\n if (pt.y < minY) minY = pt.y;\n if (pt.x > maxX) maxX = pt.x;\n if (pt.y > maxY) maxY = pt.y;\n }\n }\n\n const pad = 8;\n minX = Math.max(0, minX - pad);\n minY = Math.max(0, minY - pad);\n maxX += pad;\n maxY += pad;\n const w = maxX - minX;\n const h = maxY - minY;\n\n const pathData = allPaths\n .map((path) => {\n const pts = path.map((pt) => ({ x: pt.x - minX, y: pt.y - minY }));\n return \"M\" + pts.map((p) => `${p.x.toFixed(1)},${p.y.toFixed(1)}`).join(\"L\");\n })\n .join(\" \");\n\n const boxW = Math.max(1, targetSize?.width ?? w);\n const boxH = Math.max(1, targetSize?.height ?? h);\n const scale = Math.min(boxW / w, boxH / h);\n const drawnW = w * scale;\n const drawnH = h * scale;\n const ox = (boxW - drawnW) / 2;\n const oy = (boxH - drawnH) / 2;\n\n const svg =\n `<?xml version=\"1.0\" encoding=\"UTF-8\"?>` +\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"100%\" height=\"100%\" viewBox=\"0 0 ${boxW} ${boxH}\">` +\n `<g transform=\"translate(${ox.toFixed(2)} ${oy.toFixed(2)}) scale(${scale.toFixed(4)})\">` +\n `<path d=\"${pathData}\" fill=\"none\" stroke=\"${inkColor}\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>` +\n `</g></svg>`;\n const dataUrl = `data:image/svg+xml;base64,${btoa(svg)}`;\n onRememberFill?.(\"sign\", {\n mode: \"draw\",\n imageDataUrl: dataUrl,\n width: boxW,\n height: boxH,\n inkColor,\n });\n onSave(dataUrl, boxW, boxH);\n return;\n }\n\n if (!previewText) return;\n\n const baseSize = typedSignatureFontSize(typeKind);\n const measureCanvas = document.createElement(\"canvas\");\n const measureCtx = measureCanvas.getContext(\"2d\")!;\n measureCtx.font = `${baseSize}px ${selectedFont.family}`;\n const baseMetrics = measureCtx.measureText(previewText);\n const basePad = 8;\n const naturalW = Math.ceil(baseMetrics.width) + basePad * 2;\n const naturalH = baseSize + basePad * 2;\n\n const boxW = Math.max(1, targetSize?.width ?? naturalW);\n const boxH = Math.max(1, targetSize?.height ?? naturalH);\n const fit = Math.min(boxW / naturalW, boxH / naturalH);\n const fontSize = Math.max(8, baseSize * fit);\n\n // Transparent SVG text — centered in the sign block.\n const cx = (boxW / 2).toFixed(1);\n const cy = (boxH / 2).toFixed(1);\n const svg =\n `<?xml version=\"1.0\" encoding=\"UTF-8\"?>` +\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"100%\" height=\"100%\" viewBox=\"0 0 ${boxW} ${boxH}\">` +\n `<text x=\"${cx}\" y=\"${cy}\" ` +\n `text-anchor=\"middle\" dominant-baseline=\"central\" alignment-baseline=\"middle\" ` +\n `font-family=\"${selectedFont.family}\" font-size=\"${fontSize.toFixed(1)}\" ` +\n `fill=\"${inkColor}\">${escapeXml(previewText)}</text>` +\n `</svg>`;\n const dataUrl = svgToBase64DataUrl(svg);\n\n onRememberFill?.(\"sign\", {\n mode: \"type\",\n imageDataUrl: dataUrl,\n width: boxW,\n height: boxH,\n typedName,\n typedInitials,\n fontId,\n inkColor,\n typeKind,\n });\n onSave(dataUrl, boxW, boxH);\n };\n\n const handleFieldValueSave = () => {\n if (activeFieldType !== \"date\" && activeFieldType !== \"text\") return;\n const text =\n activeFieldType === \"date\" ? dateValue : textValue.trim();\n if (!text) return;\n\n onRememberFill?.(activeFieldType, { value: text });\n onSaveFieldValue?.(text, activeFieldType);\n };\n\n const showSignPad = activeFieldType === \"sign\";\n const modalTitle =\n activeFieldType === \"date\"\n ? \"Pick a date\"\n : activeFieldType === \"text\"\n ? \"Enter text\"\n : \"Create e-signature\";\n\n return (\n <div className=\"epochs-pdf-viewer__modal\" role=\"dialog\" aria-modal=\"true\">\n <div className=\"epochs-pdf-viewer__modal-backdrop\" onClick={onClose} />\n <div className=\"epochs-pdf-viewer__modal-card\">\n <div className=\"epochs-pdf-viewer__modal-header\">\n <h3>{modalTitle}</h3>\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={onClose}\n title=\"Close\"\n >\n ×\n </button>\n </div>\n\n {showFieldTypeTabs && !fieldType ? (\n <div className=\"epochs-pdf-viewer__field-type-tabs\" role=\"tablist\">\n {([\"sign\", \"date\", \"text\"] as const).map((t) => (\n <button\n key={t}\n type=\"button\"\n role=\"tab\"\n aria-selected={activeFieldType === t}\n className={\n activeFieldType === t\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n }\n onClick={() => setActiveFieldType(t)}\n >\n {t === \"sign\" ? \"Sign\" : t === \"date\" ? \"Date\" : \"Text\"}\n </button>\n ))}\n </div>\n ) : null}\n\n {showSignPad ? (\n <>\n <div className=\"epochs-pdf-viewer__sign-modes\">\n <button\n type=\"button\"\n className={\n mode === \"draw\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n }\n onClick={() => {\n setMode(\"draw\");\n clearPad();\n }}\n >\n Draw\n </button>\n <button\n type=\"button\"\n className={\n mode === \"type\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n }\n onClick={() => setMode(\"type\")}\n >\n Type\n </button>\n <label className=\"epochs-pdf-viewer__sign-ink\">\n Ink\n <input\n type=\"color\"\n value={inkColor}\n onChange={(e) => setInkColor(e.target.value)}\n />\n </label>\n </div>\n\n {mode === \"type\" ? (\n <>\n <div\n className=\"epochs-pdf-viewer__sign-fonts\"\n role=\"group\"\n aria-label=\"Handwriting style\"\n >\n {SVG_SAFE_FONTS.map((font) => (\n <button\n key={font.id}\n type=\"button\"\n className={\n fontId === font.id\n ? \"epochs-pdf-viewer__sign-font epochs-pdf-viewer__sign-font--active\"\n : \"epochs-pdf-viewer__sign-font\"\n }\n style={{ fontFamily: font.family }}\n onClick={() => setFontId(font.id)}\n title={font.label}\n >\n {fontPreviewLabel}\n </button>\n ))}\n </div>\n\n <div className=\"epochs-pdf-viewer__sign-type-fields\">\n <label className=\"epochs-pdf-viewer__sign-type-field\">\n <span>Full name</span>\n <input\n className=\"epochs-pdf-viewer__sign-type-input\"\n type=\"text\"\n value={typedName}\n onChange={(e) => handleNameChange(e.target.value)}\n onFocus={() => setTypeKind(\"signature\")}\n placeholder=\"Type your full name\"\n style={{ fontFamily: selectedFont.family }}\n autoFocus\n />\n </label>\n <label className=\"epochs-pdf-viewer__sign-type-field\">\n <span>Initials</span>\n <input\n className=\"epochs-pdf-viewer__sign-type-input\"\n type=\"text\"\n value={typedInitials}\n onChange={(e) => {\n setInitialsTouched(true);\n setTypedInitials(e.target.value.toUpperCase());\n }}\n onFocus={() => setTypeKind(\"initials\")}\n placeholder=\"e.g. JD\"\n maxLength={4}\n style={{ fontFamily: selectedFont.family }}\n />\n </label>\n </div>\n\n <div\n className=\"epochs-pdf-viewer__sign-type-kind\"\n role=\"group\"\n aria-label=\"Preview type\"\n >\n <button\n type=\"button\"\n className={\n typeKind === \"signature\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n }\n onClick={() => setTypeKind(\"signature\")}\n >\n Use full name\n </button>\n <button\n type=\"button\"\n className={\n typeKind === \"initials\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n }\n onClick={() => setTypeKind(\"initials\")}\n >\n Use initials\n </button>\n </div>\n </>\n ) : (\n <p className=\"epochs-pdf-viewer__sign-hint\">\n {hasReusedSignature\n ? \"Previous signature loaded — submit to reuse, or draw a new one\"\n : \"Draw your signature below\"}\n </p>\n )}\n\n <canvas\n ref={canvasRef}\n className={\n mode === \"draw\"\n ? \"epochs-pdf-viewer__sign-canvas\"\n : \"epochs-pdf-viewer__sign-canvas epochs-pdf-viewer__sign-canvas--preview\"\n }\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerLeave={handlePointerUp}\n />\n </>\n ) : activeFieldType === \"date\" ? (\n <label className=\"epochs-pdf-viewer__sign-type-field\" style={{ padding: \"1rem\" }}>\n <span>Date</span>\n <input\n className=\"epochs-pdf-viewer__sign-type-input\"\n type=\"date\"\n value={dateValue}\n onChange={(e) => setDateValue(e.target.value)}\n autoFocus\n />\n </label>\n ) : (\n <label className=\"epochs-pdf-viewer__sign-type-field\" style={{ padding: \"1rem\" }}>\n <span>Text</span>\n <input\n className=\"epochs-pdf-viewer__sign-type-input\"\n type=\"text\"\n value={textValue}\n onChange={(e) => setTextValue(e.target.value)}\n placeholder={textPlaceholder ?? \"Enter text\"}\n autoFocus\n />\n </label>\n )}\n\n <div className=\"epochs-pdf-viewer__modal-actions\">\n {showSignPad ? (\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n onClick={clearPad}\n >\n Clear\n </button>\n ) : null}\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n onClick={onClose}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text epochs-pdf-viewer__btn--primary\"\n onClick={showSignPad ? trimAndSave : handleFieldValueSave}\n disabled={\n activeFieldType === \"date\" ? !dateValue\n : activeFieldType === \"text\" ? !textValue.trim()\n : false\n }\n >\n {showSignPad ? \"Use signature\" : \"Place on page\"}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\nfunction deriveInitials(name: string): string {\n const parts = name\n .trim()\n .split(/\\s+/)\n .filter(Boolean);\n if (parts.length === 0) return \"\";\n if (parts.length === 1) {\n return parts[0].slice(0, 2).toUpperCase();\n }\n return parts\n .slice(0, 3)\n .map((part) => part[0]?.toUpperCase() ?? \"\")\n .join(\"\");\n}\n\n","/** Brand key used to identify toolbar tool components. */\nexport const TOOLBAR_TOOL_ID = \"__epochsToolbarToolId\" as const;\n\nexport type ToolbarToolId =\n | \"thumbnail\"\n | \"navigation\"\n | \"zoom\"\n | \"rotate\"\n | \"reload\"\n | \"print\"\n | \"open\"\n | \"download\"\n | \"highlight\"\n | \"underline\"\n | \"signature\"\n | \"text\"\n | \"erase\"\n | \"clear\";\n\nexport type ToolbarToolComponent = {\n (props?: Record<string, never>): null;\n displayName: string;\n readonly [TOOLBAR_TOOL_ID]: ToolbarToolId;\n};\n\nfunction createToolbarTool(\n id: ToolbarToolId,\n displayName: string,\n): ToolbarToolComponent {\n const Tool = (() => null) as ToolbarToolComponent;\n Tool.displayName = displayName;\n Object.defineProperty(Tool, TOOLBAR_TOOL_ID, {\n value: id,\n enumerable: true,\n });\n return Tool;\n}\n\nexport function getToolbarToolId(\n tool: ToolbarToolComponent,\n): ToolbarToolId {\n return tool[TOOLBAR_TOOL_ID];\n}\n\nexport function isToolbarTool(\n value: unknown,\n): value is ToolbarToolComponent {\n return (\n typeof value === \"function\" &&\n TOOLBAR_TOOL_ID in value &&\n typeof (value as ToolbarToolComponent)[TOOLBAR_TOOL_ID] === \"string\"\n );\n}\n\n/** Toggle thumbnails sidebar. */\nexport const Thumbnail = createToolbarTool(\"thumbnail\", \"Thumbnail\");\n/** Previous / next page and page number. */\nexport const Navigation = createToolbarTool(\"navigation\", \"Navigation\");\n/** Zoom out, zoom %, zoom in, and fit width. */\nexport const Zoom = createToolbarTool(\"zoom\", \"Zoom\");\n/** Rotate pages. */\nexport const Rotate = createToolbarTool(\"rotate\", \"Rotate\");\n/** Reload the PDF. */\nexport const Reload = createToolbarTool(\"reload\", \"Reload\");\n/** Print (includes markup). */\nexport const Print = createToolbarTool(\"print\", \"Print\");\n/** Open PDF in a new tab. */\nexport const Open = createToolbarTool(\"open\", \"Open\");\n/** Download PDF (with markup when present). */\nexport const Download = createToolbarTool(\"download\", \"Download\");\n/** Highlight text markup tool. */\nexport const Highlight = createToolbarTool(\"highlight\", \"Highlight\");\n/** Underline text markup tool. */\nexport const Underline = createToolbarTool(\"underline\", \"Underline\");\n/** E-signature tool. */\nexport const Signature = createToolbarTool(\"signature\", \"Signature\");\n/** Add / edit free text on the page. */\nexport const AddText = createToolbarTool(\"text\", \"AddText\");\n/** Erase markup annotations. */\nexport const Erase = createToolbarTool(\"erase\", \"Erase\");\n/** Clear all markup. */\nexport const Clear = createToolbarTool(\"clear\", \"Clear\");\n\nexport const ALL_TOOLBAR_TOOLS = [\n Thumbnail,\n Navigation,\n Zoom,\n Rotate,\n Highlight,\n Underline,\n Signature,\n AddText,\n Erase,\n Clear,\n Reload,\n Print,\n Open,\n Download,\n] as const;\n\n/** Default left / right toolbar layout. */\nexport const DEFAULT_TOOLBAR_LAYOUT: [\n ToolbarToolComponent[],\n ToolbarToolComponent[],\n] = [\n [Thumbnail, Navigation],\n [\n Zoom,\n Rotate,\n Highlight,\n Underline,\n Signature,\n AddText,\n Erase,\n Clear,\n Reload,\n Print,\n Open,\n Download,\n ],\n];\n","import type { ReactNode } from \"react\";\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n DownloadIcon,\n EraserIcon,\n ExternalLinkIcon,\n GridIcon,\n HighlightIcon,\n MinusIcon,\n PlusIcon,\n PrinterIcon,\n RefreshIcon,\n RotateIcon,\n SignatureIcon,\n TextIcon,\n UnderlineIcon,\n} from \"./icons\";\nimport type { MarkupTool } from \"./markup\";\nimport {\n HIGHLIGHT_PRESETS,\n UNDERLINE_PRESETS,\n normalizeHex,\n} from \"./markup\";\nimport type { ToolbarToolId } from \"./toolbarTools\";\n\nexport type ToolbarRenderContext = {\n status: string;\n showThumbnails: boolean;\n setShowThumbnails: (updater: (v: boolean) => boolean) => void;\n canGoPrev: boolean;\n canGoNext: boolean;\n handlePrev: () => void;\n handleNext: () => void;\n pageNumber: number;\n numPages: number;\n scrollToPage: (page: number) => void;\n scale: number;\n handleZoomOut: () => void;\n handleZoomIn: () => void;\n handleFitWidth: () => void | Promise<void>;\n handleRotate: () => void;\n markupTool: MarkupTool;\n toggleMarkupTool: (tool: Exclude<MarkupTool, \"none\">) => void;\n hasFixedSignatureFields: boolean;\n hasFixedTextFields: boolean;\n pendingSignature: { imageDataUrl: string; width: number; height: number } | null;\n setMarkupTool: (tool: MarkupTool) => void;\n setSignaturePadOpen: (open: boolean) => void;\n annotationsLength: number;\n signaturesLength: number;\n textsLength: number;\n handleClearAnnotations: () => void;\n highlightHex: string;\n underlineHex: string;\n setHighlightHex: (hex: string) => void;\n setUnderlineHex: (hex: string) => void;\n loadDocument: () => void | Promise<void>;\n handlePrint: () => void | Promise<void>;\n isPrinting: boolean;\n pdfDoc: unknown;\n displayUrl: string | null;\n resolvedUrl: string;\n handleDownload: () => void | Promise<void>;\n isDownloading: boolean;\n};\n\nconst MARKUP_TOOLS: ToolbarToolId[] = [\n \"highlight\",\n \"underline\",\n \"signature\",\n \"text\",\n \"erase\",\n \"clear\",\n];\n\nexport function isMarkupToolbarTool(id: ToolbarToolId): boolean {\n return MARKUP_TOOLS.includes(id);\n}\n\nexport function renderToolbarTool(\n id: ToolbarToolId,\n ctx: ToolbarRenderContext,\n options?: { showMarkupSep?: boolean },\n): ReactNode {\n const nodes: ReactNode[] = [];\n\n if (options?.showMarkupSep) {\n nodes.push(\n <span\n key={`${id}-sep`}\n className=\"epochs-pdf-viewer__toolbar-sep\"\n aria-hidden=\"true\"\n />,\n );\n }\n\n switch (id) {\n case \"thumbnail\":\n nodes.push(\n <button\n key=\"thumbnail\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={() => ctx.setShowThumbnails((v) => !v)}\n title={ctx.showThumbnails ? \"Hide thumbnails\" : \"Show thumbnails\"}\n >\n <GridIcon />\n </button>,\n );\n break;\n\n case \"navigation\":\n nodes.push(\n <button\n key=\"nav-prev\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={ctx.handlePrev}\n disabled={!ctx.canGoPrev || ctx.status !== \"ready\"}\n title=\"Previous page\"\n >\n <ChevronLeftIcon />\n </button>,\n <div key=\"nav-page\" className=\"epochs-pdf-viewer__page-input\">\n <input\n type=\"number\"\n value={ctx.pageNumber}\n min={1}\n max={ctx.numPages || 1}\n onChange={(e) => {\n const next = Number.parseInt(e.target.value, 10);\n if (!Number.isFinite(next)) return;\n ctx.scrollToPage(\n Math.max(1, Math.min(ctx.numPages || 1, next)),\n );\n }}\n disabled={ctx.status !== \"ready\"}\n aria-label=\"Page number\"\n />\n <span>/ {ctx.numPages || \"-\"}</span>\n </div>,\n <button\n key=\"nav-next\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={ctx.handleNext}\n disabled={!ctx.canGoNext || ctx.status !== \"ready\"}\n title=\"Next page\"\n >\n <ChevronRightIcon />\n </button>,\n );\n break;\n\n case \"zoom\":\n nodes.push(\n <button\n key=\"zoom-out\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={ctx.handleZoomOut}\n disabled={ctx.status !== \"ready\"}\n title=\"Zoom out\"\n >\n <MinusIcon />\n </button>,\n <span key=\"zoom-label\" className=\"epochs-pdf-viewer__zoom-label\">\n {Math.round(ctx.scale * 100)}%\n </span>,\n <button\n key=\"zoom-in\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={ctx.handleZoomIn}\n disabled={ctx.status !== \"ready\"}\n title=\"Zoom in\"\n >\n <PlusIcon />\n </button>,\n <button\n key=\"zoom-fit\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n onClick={() => void ctx.handleFitWidth()}\n disabled={ctx.status !== \"ready\"}\n title=\"Fit to width\"\n >\n Fit\n </button>,\n );\n break;\n\n case \"rotate\":\n nodes.push(\n <button\n key=\"rotate\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={ctx.handleRotate}\n disabled={ctx.status !== \"ready\"}\n title=\"Rotate\"\n >\n <RotateIcon />\n </button>,\n );\n break;\n\n case \"highlight\":\n nodes.push(\n <button\n key=\"highlight\"\n type=\"button\"\n className={\n ctx.markupTool === \"highlight\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn\"\n }\n onClick={() => ctx.toggleMarkupTool(\"highlight\")}\n disabled={ctx.status !== \"ready\"}\n title=\"Highlight text — select text to highlight\"\n >\n <HighlightIcon />\n </button>,\n );\n break;\n\n case \"underline\":\n nodes.push(\n <button\n key=\"underline\"\n type=\"button\"\n className={\n ctx.markupTool === \"underline\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn\"\n }\n onClick={() => ctx.toggleMarkupTool(\"underline\")}\n disabled={ctx.status !== \"ready\"}\n title=\"Underline text — select text to underline\"\n >\n <UnderlineIcon />\n </button>,\n );\n break;\n\n case \"signature\":\n nodes.push(\n <button\n key=\"signature\"\n type=\"button\"\n className={\n ctx.markupTool === \"sign\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn\"\n }\n onClick={() => {\n if (\n !ctx.hasFixedSignatureFields &&\n ctx.pendingSignature &&\n ctx.markupTool !== \"sign\"\n ) {\n ctx.setMarkupTool(\"sign\");\n return;\n }\n ctx.setSignaturePadOpen(true);\n }}\n disabled={ctx.status !== \"ready\"}\n title={\n ctx.hasFixedSignatureFields\n ? \"Create e-signature for a fixed field\"\n : ctx.pendingSignature\n ? \"Place signature — click on the page, then drag to move\"\n : \"Create e-signature\"\n }\n >\n <SignatureIcon />\n </button>,\n );\n break;\n\n case \"text\":\n nodes.push(\n <button\n key=\"text\"\n type=\"button\"\n className={\n ctx.markupTool === \"text\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn\"\n }\n onClick={() => ctx.toggleMarkupTool(\"text\")}\n disabled={ctx.status !== \"ready\"}\n title={\n ctx.hasFixedTextFields\n ? \"Edit text in predefined areas — click to type\"\n : \"Edit PDF text — select words, then change them\"\n }\n >\n <TextIcon />\n </button>,\n );\n break;\n\n case \"erase\":\n nodes.push(\n <button\n key=\"erase\"\n type=\"button\"\n className={\n ctx.markupTool === \"erase\"\n ? \"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--active\"\n : \"epochs-pdf-viewer__btn\"\n }\n onClick={() => ctx.toggleMarkupTool(\"erase\")}\n disabled={ctx.status !== \"ready\"}\n title=\"Remove text — select PDF words to cover them, or click added markup\"\n >\n <EraserIcon />\n </button>,\n );\n break;\n\n case \"clear\":\n nodes.push(\n <button\n key=\"clear\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n onClick={ctx.handleClearAnnotations}\n disabled={\n ctx.status !== \"ready\" ||\n (ctx.annotationsLength === 0 &&\n ctx.signaturesLength === 0 &&\n ctx.textsLength === 0)\n }\n title=\"Clear all markup\"\n >\n Clear\n </button>,\n );\n break;\n\n case \"reload\":\n nodes.push(\n <button\n key=\"reload\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={() => void ctx.loadDocument()}\n title=\"Reload\"\n >\n <RefreshIcon />\n </button>,\n );\n break;\n\n case \"print\":\n nodes.push(\n <button\n key=\"print\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={() => void ctx.handlePrint()}\n disabled={ctx.status !== \"ready\" || !ctx.pdfDoc || ctx.isPrinting}\n title={\n ctx.isPrinting\n ? \"Preparing print…\"\n : \"Print (includes highlights & underlines)\"\n }\n >\n <PrinterIcon />\n </button>,\n );\n break;\n\n case \"open\":\n nodes.push(\n <a\n key=\"open\"\n className=\"epochs-pdf-viewer__btn\"\n href={ctx.displayUrl || ctx.resolvedUrl || undefined}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title=\"Open in new tab\"\n >\n <ExternalLinkIcon />\n </a>,\n );\n break;\n\n case \"download\":\n nodes.push(\n <button\n key=\"download\"\n type=\"button\"\n className=\"epochs-pdf-viewer__btn\"\n onClick={() => void ctx.handleDownload()}\n disabled={\n ctx.status !== \"ready\" || !ctx.pdfDoc || ctx.isDownloading\n }\n title={\n ctx.isDownloading\n ? \"Preparing download…\"\n : ctx.annotationsLength > 0 ||\n ctx.signaturesLength > 0 ||\n ctx.textsLength > 0\n ? \"Download PDF with markup\"\n : \"Download PDF\"\n }\n >\n <DownloadIcon />\n </button>,\n );\n break;\n\n default:\n break;\n }\n\n return nodes.length > 0 ? nodes : null;\n}\n\nexport function renderMarkupExtras(\n ctx: ToolbarRenderContext,\n enabledIds: Set<ToolbarToolId>,\n): ReactNode {\n const nodes: ReactNode[] = [];\n\n if (\n ctx.markupTool === \"sign\" &&\n ctx.pendingSignature &&\n !ctx.hasFixedSignatureFields &&\n enabledIds.has(\"signature\")\n ) {\n nodes.push(\n <span key=\"sign-hint\" className=\"epochs-pdf-viewer__markup-hint\">\n Click page to place duplicate/new signature\n </span>,\n );\n }\n\n if (\n ctx.markupTool === \"text\" &&\n enabledIds.has(\"text\")\n ) {\n nodes.push(\n <span key=\"text-hint\" className=\"epochs-pdf-viewer__markup-hint\">\n {ctx.hasFixedTextFields\n ? \"Click in a predefined text area to type\"\n : \"Select text to edit it — e.g. change this PDF to this is PDF\"}\n </span>,\n );\n }\n\n if (\n ctx.markupTool === \"erase\" &&\n enabledIds.has(\"erase\")\n ) {\n nodes.push(\n <span key=\"erase-hint\" className=\"epochs-pdf-viewer__markup-hint\">\n Select PDF words to remove · click added text/markup to erase\n </span>,\n );\n }\n\n if (\n (ctx.markupTool === \"highlight\" && enabledIds.has(\"highlight\")) ||\n (ctx.markupTool === \"underline\" && enabledIds.has(\"underline\"))\n ) {\n const activeMarkupHex =\n ctx.markupTool === \"highlight\" ? ctx.highlightHex : ctx.underlineHex;\n const setActiveMarkupHex =\n ctx.markupTool === \"highlight\" ? ctx.setHighlightHex : ctx.setUnderlineHex;\n const activePresets =\n ctx.markupTool === \"highlight\" ? HIGHLIGHT_PRESETS : UNDERLINE_PRESETS;\n\n nodes.push(\n <div\n key=\"color-picker\"\n className=\"epochs-pdf-viewer__color-picker\"\n role=\"group\"\n aria-label={`${ctx.markupTool} color`}\n >\n {activePresets.map((preset) => (\n <button\n key={preset.id}\n type=\"button\"\n className={\n normalizeHex(activeMarkupHex) === normalizeHex(preset.hex)\n ? \"epochs-pdf-viewer__swatch epochs-pdf-viewer__swatch--active\"\n : \"epochs-pdf-viewer__swatch\"\n }\n style={{ background: preset.hex }}\n title={preset.label}\n aria-label={preset.label}\n aria-pressed={\n normalizeHex(activeMarkupHex) === normalizeHex(preset.hex)\n }\n onClick={() => setActiveMarkupHex(normalizeHex(preset.hex))}\n />\n ))}\n <label\n className=\"epochs-pdf-viewer__custom-color\"\n title=\"Custom color\"\n >\n <span\n className=\"epochs-pdf-viewer__custom-color-chip\"\n style={{ background: activeMarkupHex }}\n />\n <input\n type=\"color\"\n value={normalizeHex(activeMarkupHex)}\n onChange={(e) =>\n setActiveMarkupHex(normalizeHex(e.target.value))\n }\n aria-label=\"Custom color\"\n />\n </label>\n </div>,\n );\n }\n\n return nodes.length > 0 ? nodes : null;\n}\n","import {\n Fragment,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n} from \"react\";\nimport { PageCanvas } from \"./PageCanvas\";\nimport { Thumbnail as ThumbnailStrip } from \"./Thumbnail\";\nimport {\n ensurePdfWorker,\n pdfjsLib,\n resolvePdfUrl,\n sourceToArrayBuffer,\n} from \"./load\";\nimport type { PdfDoc, PdfViewerProps, ToolbarLayout, ViewerStatus } from \"./types\";\nimport type { MarkupAnnotation, MarkupTool } from \"./markup\";\nimport {\n DEFAULT_HIGHLIGHT_HEX,\n DEFAULT_UNDERLINE_HEX,\n hexToMarkupColor,\n} from \"./markup\";\nimport {\n buildPdfFromJpegPages,\n renderAllPagesWithMarkup,\n triggerBlobDownload,\n} from \"./exportPages\";\nimport { SignaturePad } from \"./SignaturePad\";\nimport type { RememberedFieldFills, RememberedSignFill } from \"./SignaturePad\";\nimport type { SignatureAnnotation, SignatureField } from \"./signature\";\nimport { createSignatureId, signatureDisplaySize } from \"./signature\";\nimport { pageSizeFromSurface, viewportRectToPage } from \"./coords\";\nimport type { TextAnnotation } from \"./text\";\nimport {\n createTextId,\n DEFAULT_TEXT_COLOR,\n DEFAULT_TEXT_FONT_SIZE,\n} from \"./text\";\nimport {\n DEFAULT_TOOLBAR_LAYOUT,\n getToolbarToolId,\n isToolbarTool,\n type ToolbarToolComponent,\n type ToolbarToolId,\n} from \"./toolbarTools\";\nimport {\n isMarkupToolbarTool,\n renderMarkupExtras,\n renderToolbarTool,\n type ToolbarRenderContext,\n} from \"./ToolbarButtons\";\nimport \"./PdfViewer.css\";\n\nfunction resolveToolbarLayout(\n enableToolbar: boolean | ToolbarLayout | undefined,\n flags: {\n enableThumbnails?: boolean;\n enableNavigation: boolean;\n enableZoom: boolean;\n enableRotate: boolean;\n enableReload: boolean;\n enablePrint: boolean;\n enableOpen: boolean;\n enableDownload: boolean;\n enableHighlight: boolean;\n enableUnderline: boolean;\n enableSignature: boolean;\n enableText: boolean;\n enableErase: boolean;\n enableClear: boolean;\n },\n): { left: ToolbarToolId[]; right: ToolbarToolId[] } | null {\n if (!enableToolbar) return null;\n\n if (Array.isArray(enableToolbar)) {\n const toIds = (side: ToolbarToolComponent[] | undefined) =>\n (side ?? [])\n .filter(isToolbarTool)\n .map(getToolbarToolId);\n\n return {\n left: toIds(enableToolbar[0]),\n right: toIds(enableToolbar[1]),\n };\n }\n\n const showThumbnailsToggle = flags.enableThumbnails;\n const filterByFlag = (\n tools: readonly ToolbarToolComponent[],\n enabled: Partial<Record<ToolbarToolId, boolean>>,\n ) =>\n tools\n .map(getToolbarToolId)\n .filter((id) => enabled[id] !== false);\n\n const flagMap: Partial<Record<ToolbarToolId, boolean>> = {\n thumbnail: showThumbnailsToggle,\n navigation: flags.enableNavigation,\n zoom: flags.enableZoom,\n rotate: flags.enableRotate,\n reload: flags.enableReload,\n print: flags.enablePrint,\n open: flags.enableOpen,\n download: flags.enableDownload,\n highlight: flags.enableHighlight,\n underline: flags.enableUnderline,\n signature: flags.enableSignature,\n text: flags.enableText,\n erase: flags.enableErase,\n clear: flags.enableClear,\n };\n\n return {\n left: filterByFlag(DEFAULT_TOOLBAR_LAYOUT[0], flagMap),\n right: filterByFlag(DEFAULT_TOOLBAR_LAYOUT[1], flagMap),\n };\n}\n\nexport function PdfViewer({\n file,\n fileUrl,\n baseUrl = \"\",\n fetchOptions,\n height = \"80vh\",\n title = \"PDF document\",\n initialScale = 1,\n withThumbnails = false,\n thumbnailWidth = 140,\n maxThumbnails = 60,\n className,\n workerSrc,\n enableToolbar = false,\n enableThumbnails,\n enableNavigation = true,\n enableZoom = true,\n enableRotate = true,\n enableReload = true,\n enablePrint = true,\n enableOpen = true,\n enableDownload = true,\n enableMarkup = true,\n enableHighlight = true,\n enableUnderline = true,\n enableSignature = true,\n enableText = true,\n enableErase = true,\n enableClear = true,\n signatureFields: signatureFieldsProp = [],\n textFields = [],\n onSignatureComplete,\n onSignatureFieldsChange,\n applySignatureToSameTag = false,\n onFieldValueComplete,\n openSignaturePad: externalOpenSignaturePad = false,\n onSignaturePadClose,\n onSubmit,\n submitLabel = \"Submit\",\n submitLoading = false,\n}: PdfViewerProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const lastBlobUrlRef = useRef<string | null>(null);\n const pageRefsRef = useRef(new Map<number, HTMLDivElement | null>());\n const isProgrammaticScrollRef = useRef(false);\n\n const binarySource = useMemo(() => {\n if (file && typeof file !== \"string\") return file;\n return null;\n }, [file]);\n\n const resolvedUrl = useMemo(() => {\n if (binarySource) return \"\";\n const asString =\n typeof file === \"string\" ? file : undefined;\n return resolvePdfUrl(asString, fileUrl, baseUrl);\n }, [binarySource, file, fileUrl, baseUrl]);\n\n const [status, setStatus] = useState<ViewerStatus>(\"idle\");\n const [pdfDoc, setPdfDoc] = useState<PdfDoc | null>(null);\n const [numPages, setNumPages] = useState(0);\n const [pageNumber, setPageNumber] = useState(1);\n const [scale, setScale] = useState(initialScale);\n const [rotation, setRotation] = useState(0);\n const [displayUrl, setDisplayUrl] = useState<string | null>(null);\n const [showThumbnails, setShowThumbnails] = useState(false);\n const [isPrinting, setIsPrinting] = useState(false);\n const [isDownloading, setIsDownloading] = useState(false);\n const [markupTool, setMarkupTool] = useState<MarkupTool>(\"none\");\n const [annotations, setAnnotations] = useState<MarkupAnnotation[]>([]);\n const [signatures, setSignatures] = useState<SignatureAnnotation[]>([]);\n const [texts, setTexts] = useState<TextAnnotation[]>([]);\n const [signaturePadOpen, setSignaturePadOpen] = useState(false);\n const [signaturePadFieldType, setSignaturePadFieldType] = useState<\n import(\"./signature\").SignatureFieldType | undefined\n >(undefined);\n const [rememberedByType, setRememberedByType] = useState<RememberedFieldFills>({});\n const [pendingSignature, setPendingSignature] = useState<{\n imageDataUrl: string;\n width: number;\n height: number;\n } | null>(null);\n const [selectedSignatureId, setSelectedSignatureId] = useState<string | null>(\n null,\n );\n const [selectedSignatureFieldId, setSelectedSignatureFieldId] = useState<string | null>(\n null,\n );\n const [editingSignatureId, setEditingSignatureId] = useState<string | null>(null);\n const [selectedTextId, setSelectedTextId] = useState<string | null>(null);\n const [selectedTextFieldId, setSelectedTextFieldId] = useState<string | null>(null);\n const [editingTextId, setEditingTextId] = useState<string | null>(null);\n const [highlightHex, setHighlightHex] = useState(DEFAULT_HIGHLIGHT_HEX);\n const [underlineHex, setUnderlineHex] = useState(DEFAULT_UNDERLINE_HEX);\n const hasFixedTextFields = textFields.length > 0;\n const [fieldValues, setFieldValues] = useState<Record<string, string>>({});\n const [signatureFields, setSignatureFields] =\n useState<SignatureField[]>(signatureFieldsProp);\n const signatureFieldsRef = useRef(signatureFields);\n signatureFieldsRef.current = signatureFields;\n\n useEffect(() => {\n signatureFieldsRef.current = signatureFieldsProp;\n setSignatureFields(signatureFieldsProp);\n setFieldValues((prev) => {\n const next = { ...prev };\n for (const field of signatureFieldsProp) {\n const fieldType = field.type ?? \"sign\";\n if (\n (fieldType === \"date\" || fieldType === \"text\") &&\n field.value != null &&\n field.value !== \"\"\n ) {\n next[field.id] = field.value;\n }\n }\n return next;\n });\n }, [signatureFieldsProp]);\n\n const hasFixedSignatureFields = signatureFields.length > 0;\n\n const isSignatureFieldFilled = useCallback(\n (\n field: SignatureField,\n sigs: SignatureAnnotation[],\n values: Record<string, string>,\n ) => {\n const fieldType = field.type ?? \"sign\";\n if (fieldType === \"date\" || fieldType === \"text\") {\n return Boolean((values[field.id] ?? field.value)?.trim());\n }\n return (\n sigs.some((sig) => sig.fieldId === field.id) ||\n Boolean(field.signatureDataUrl)\n );\n },\n [],\n );\n\n const writeFieldValueToFields = useCallback(\n (fieldIds: string[], value: string) => {\n const idSet = new Set(fieldIds);\n const prev = signatureFieldsRef.current;\n const next = prev.map((field) =>\n idSet.has(field.id) ? { ...field, value } : field,\n );\n signatureFieldsRef.current = next;\n setSignatureFields(next);\n onSignatureFieldsChange?.(next);\n\n setFieldValues((prevValues) => {\n const updated = { ...prevValues };\n for (const id of fieldIds) updated[id] = value;\n return updated;\n });\n\n for (const id of fieldIds) {\n onFieldValueComplete?.(id, value);\n }\n },\n [onFieldValueComplete, onSignatureFieldsChange],\n );\n\n const writeSignatureImageToFields = useCallback(\n (\n fieldIds: string | string[] | undefined,\n signature: SignatureAnnotation,\n signaturesByFieldId?: Map<string, SignatureAnnotation>,\n ) => {\n const prev = signatureFieldsRef.current;\n const ids = fieldIds == null ? null : Array.isArray(fieldIds) ? fieldIds : [fieldIds];\n const idSet = ids ? new Set(ids) : null;\n\n const next: SignatureField[] = idSet\n ? prev.map((field) =>\n idSet.has(field.id)\n ? { ...field, signatureDataUrl: signature.imageDataUrl }\n : field,\n )\n : [\n ...prev,\n {\n id: signature.id,\n pageNumber: signature.pageNumber,\n x: signature.x,\n y: signature.y,\n width: signature.width,\n height: signature.height,\n type: \"sign\",\n signatureDataUrl: signature.imageDataUrl,\n },\n ];\n signatureFieldsRef.current = next;\n setSignatureFields(next);\n onSignatureFieldsChange?.(next);\n\n if (!ids || ids.length === 0) {\n onSignatureComplete?.(undefined, signature);\n return;\n }\n for (const id of ids) {\n onSignatureComplete?.(\n id,\n signaturesByFieldId?.get(id) ?? signature,\n );\n }\n },\n [onSignatureComplete, onSignatureFieldsChange],\n );\n\n useEffect(() => {\n if (externalOpenSignaturePad) {\n setSignaturePadOpen(true);\n }\n }, [externalOpenSignaturePad]);\n\n const toolbarSides = useMemo(\n () =>\n resolveToolbarLayout(enableToolbar, {\n enableThumbnails,\n enableNavigation,\n enableZoom,\n enableRotate,\n enableReload,\n enablePrint,\n enableOpen,\n enableDownload,\n enableHighlight,\n enableUnderline,\n enableSignature,\n enableText,\n enableErase,\n enableClear,\n }),\n [\n enableToolbar,\n enableThumbnails,\n enableNavigation,\n enableZoom,\n enableRotate,\n enableReload,\n enablePrint,\n enableOpen,\n enableDownload,\n enableHighlight,\n enableUnderline,\n enableSignature,\n enableText,\n enableErase,\n enableClear,\n ],\n );\n\n const enabledToolIds = useMemo(() => {\n if (!toolbarSides) return new Set<ToolbarToolId>();\n return new Set([...toolbarSides.left, ...toolbarSides.right]);\n }, [toolbarSides]);\n\n useEffect(() => {\n const hasThumbTool = enabledToolIds.has(\"thumbnail\");\n if (!hasThumbTool) {\n setShowThumbnails(false);\n return;\n }\n\n const mq = window.matchMedia(\"(max-width: 720px)\");\n const apply = () => {\n // Mobile: hide thumbnails by default. Desktop: respect withThumbnails.\n setShowThumbnails(mq.matches ? false : withThumbnails);\n };\n apply();\n mq.addEventListener(\"change\", apply);\n return () => mq.removeEventListener(\"change\", apply);\n }, [enabledToolIds, withThumbnails]);\n\n const showHighlight =\n !hasFixedSignatureFields && enabledToolIds.has(\"highlight\");\n const showUnderline =\n !hasFixedSignatureFields && enabledToolIds.has(\"underline\");\n const showSignature =\n enabledToolIds.has(\"signature\") || hasFixedSignatureFields;\n const showText = enabledToolIds.has(\"text\") || hasFixedTextFields;\n const showErase = !hasFixedSignatureFields && enabledToolIds.has(\"erase\");\n\n const revokeDisplayUrl = useCallback(() => {\n if (lastBlobUrlRef.current) {\n URL.revokeObjectURL(lastBlobUrlRef.current);\n lastBlobUrlRef.current = null;\n }\n }, []);\n\n const loadDocument = useCallback(async () => {\n if (!binarySource && !resolvedUrl) return;\n\n ensurePdfWorker(workerSrc);\n setStatus(\"loading\");\n setPdfDoc(null);\n setNumPages(0);\n setPageNumber(1);\n setAnnotations([]);\n setSignatures([]);\n setTexts([]);\n setPendingSignature(null);\n setSelectedSignatureId(null);\n setSelectedSignatureFieldId(null);\n setEditingSignatureId(null);\n setSelectedTextId(null);\n setSelectedTextFieldId(null);\n setEditingTextId(null);\n setMarkupTool(\"none\");\n\n try {\n const buffer = binarySource\n ? await sourceToArrayBuffer(binarySource, fetchOptions)\n : await sourceToArrayBuffer(resolvedUrl, fetchOptions);\n\n const blob = new Blob([buffer], { type: \"application/pdf\" });\n const blobUrl = URL.createObjectURL(blob);\n revokeDisplayUrl();\n lastBlobUrlRef.current = blobUrl;\n setDisplayUrl(blobUrl);\n\n const loadingTask = pdfjsLib.getDocument({\n data: buffer,\n cMapUrl: `https://unpkg.com/pdfjs-dist@${pdfjsLib.version}/cmaps/`,\n cMapPacked: true,\n standardFontDataUrl: `https://unpkg.com/pdfjs-dist@${pdfjsLib.version}/standard_fonts/`,\n });\n const doc = await loadingTask.promise;\n setPdfDoc(doc);\n setNumPages(doc.numPages);\n setStatus(\"ready\");\n } catch {\n setStatus(\"error\");\n }\n }, [\n binarySource,\n resolvedUrl,\n fetchOptions,\n revokeDisplayUrl,\n workerSrc,\n ]);\n\n useEffect(() => {\n if (!binarySource && !resolvedUrl) {\n setStatus(\"idle\");\n setPdfDoc(null);\n setNumPages(0);\n setDisplayUrl(null);\n revokeDisplayUrl();\n return;\n }\n\n void loadDocument();\n\n return () => {\n revokeDisplayUrl();\n };\n }, [binarySource, resolvedUrl, loadDocument, revokeDisplayUrl]);\n\n useEffect(() => {\n if (markupTool === \"highlight\" && !showHighlight) {\n setMarkupTool(\"none\");\n } else if (markupTool === \"underline\" && !showUnderline) {\n setMarkupTool(\"none\");\n } else if (markupTool === \"sign\" && !showSignature) {\n setMarkupTool(\"none\");\n } else if (markupTool === \"text\" && !showText) {\n setMarkupTool(\"none\");\n } else if (markupTool === \"erase\" && !showErase) {\n setMarkupTool(\"none\");\n }\n }, [showHighlight, showUnderline, showSignature, showText, showErase, markupTool]);\n\n const scrollToPage = useCallback(\n (targetPage: number) => {\n const clamped = Math.max(1, Math.min(numPages || 1, targetPage));\n const el = pageRefsRef.current.get(clamped);\n if (!el) {\n setPageNumber(clamped);\n return;\n }\n\n isProgrammaticScrollRef.current = true;\n el.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\n setPageNumber(clamped);\n window.setTimeout(() => {\n isProgrammaticScrollRef.current = false;\n }, 500);\n },\n [numPages],\n );\n\n const scrollToSignatureField = useCallback(\n (field: SignatureField) => {\n const pageEl = pageRefsRef.current.get(field.pageNumber);\n if (pageEl) {\n isProgrammaticScrollRef.current = true;\n setPageNumber(field.pageNumber);\n }\n\n const focusField = () => {\n const fieldEl = containerRef.current?.querySelector(\n `[data-signature-field-id=\"${CSS.escape(field.id)}\"]`,\n ) as HTMLElement | null;\n\n if (fieldEl) {\n fieldEl.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n } else if (pageEl) {\n pageEl.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\n }\n\n window.setTimeout(() => {\n isProgrammaticScrollRef.current = false;\n }, 500);\n };\n\n window.requestAnimationFrame(() => {\n window.setTimeout(focusField, 40);\n });\n },\n [],\n );\n\n useEffect(() => {\n if (status !== \"ready\" || !containerRef.current || !numPages) return;\n\n const container = containerRef.current;\n const observer = new IntersectionObserver(\n (entries) => {\n if (isProgrammaticScrollRef.current) return;\n\n let best: { page: number; ratio: number } | null = null;\n for (const e of entries) {\n if (!e.isIntersecting) continue;\n const page = Number.parseInt(\n (e.target as HTMLElement).dataset.pageNumber || \"0\",\n 10,\n );\n if (!page) continue;\n if (!best || e.intersectionRatio > best.ratio) {\n best = { page, ratio: e.intersectionRatio };\n }\n }\n if (best) setPageNumber(best.page);\n },\n {\n root: container,\n threshold: [0.25, 0.5, 0.75],\n },\n );\n\n for (let p = 1; p <= numPages; p += 1) {\n const el = pageRefsRef.current.get(p);\n if (el) observer.observe(el);\n }\n\n return () => observer.disconnect();\n }, [status, numPages]);\n\n const canGoPrev = pageNumber > 1;\n const canGoNext = numPages ? pageNumber < numPages : false;\n\n const handlePrev = useCallback(() => {\n if (!canGoPrev) return;\n scrollToPage(pageNumber - 1);\n }, [canGoPrev, pageNumber, scrollToPage]);\n\n const handleNext = useCallback(() => {\n if (!canGoNext) return;\n scrollToPage(pageNumber + 1);\n }, [canGoNext, pageNumber, scrollToPage]);\n\n const handleRotate = useCallback(() => {\n setRotation((r) => (r + 90) % 360);\n }, []);\n\n const handleZoomOut = useCallback(() => {\n setScale((s) => Math.max(0.25, Math.round((s - 0.1) * 100) / 100));\n }, []);\n\n const handleZoomIn = useCallback(() => {\n setScale((s) => Math.min(5, Math.round((s + 0.1) * 100) / 100));\n }, []);\n\n const handleFitWidth = useCallback(async () => {\n if (!pdfDoc || !containerRef.current) return;\n try {\n const page = await pdfDoc.getPage(pageNumber);\n const viewportAt1 = page.getViewport({ scale: 1, rotation });\n // Body already excludes the thumbnail rail; subtract page padding only.\n const isMobile = window.matchMedia(\"(max-width: 720px)\").matches;\n const pagePadding = isMobile ? 16 : 24;\n const containerWidth = Math.max(\n 0,\n containerRef.current.clientWidth - pagePadding,\n );\n const nextScale = containerWidth / viewportAt1.width;\n setScale(Math.max(0.25, Math.min(5, Math.round(nextScale * 100) / 100)));\n } catch {\n // ignore\n }\n }, [pdfDoc, pageNumber, rotation]);\n\n // On mobile, auto-fit so fixed-field coordinates/dimensions stay aligned.\n useEffect(() => {\n if (status !== \"ready\" || !pdfDoc) return;\n if (!window.matchMedia(\"(max-width: 720px)\").matches) return;\n\n let cancelled = false;\n const run = () => {\n if (!cancelled) void handleFitWidth();\n };\n run();\n\n const container = containerRef.current;\n const observer =\n typeof ResizeObserver !== \"undefined\" && container\n ? new ResizeObserver(() => run())\n : null;\n observer?.observe(container!);\n\n const mq = window.matchMedia(\"(max-width: 720px)\");\n const onMq = () => {\n if (mq.matches) run();\n };\n mq.addEventListener(\"change\", onMq);\n\n return () => {\n cancelled = true;\n observer?.disconnect();\n mq.removeEventListener(\"change\", onMq);\n };\n }, [status, pdfDoc, showThumbnails, rotation, handleFitWidth]);\n\n const fieldValueTexts = useMemo((): TextAnnotation[] => {\n return signatureFields.flatMap((field) => {\n const fieldType = field.type ?? \"sign\";\n if (fieldType !== \"date\" && fieldType !== \"text\") return [];\n const value = (fieldValues[field.id] ?? field.value ?? \"\").trim();\n if (!value) return [];\n const fontSize = Math.max(\n 10,\n Math.min(DEFAULT_TEXT_FONT_SIZE, field.height * 0.55),\n );\n return [\n {\n id: `fv_${field.id}`,\n pageNumber: field.pageNumber,\n fieldId: field.id,\n x: field.x + 4,\n y: field.y + Math.max(2, (field.height - fontSize) / 2),\n width: Math.max(12, field.width - 8),\n height: Math.max(fontSize * 1.2, field.height - 4),\n value,\n fontSize,\n color: DEFAULT_TEXT_COLOR,\n },\n ];\n });\n }, [signatureFields, fieldValues]);\n\n const textsForExport = useMemo(\n () => [...texts, ...fieldValueTexts],\n [texts, fieldValueTexts],\n );\n\n const handlePrint = useCallback(async () => {\n if (!pdfDoc || status !== \"ready\") return;\n\n setIsPrinting(true);\n try {\n // Render in the main document — pdf.js fonts break on iframe canvases.\n const pages = await renderAllPagesWithMarkup(pdfDoc, {\n scale: 1.5,\n rotation,\n annotations,\n signatures,\n texts: textsForExport,\n mimeType: \"image/png\",\n });\n\n const iframe = document.createElement(\"iframe\");\n iframe.style.position = \"fixed\";\n iframe.style.right = \"0\";\n iframe.style.bottom = \"0\";\n iframe.style.width = \"0\";\n iframe.style.height = \"0\";\n iframe.style.border = \"0\";\n iframe.setAttribute(\"aria-hidden\", \"true\");\n document.body.appendChild(iframe);\n\n const doc = iframe.contentWindow?.document;\n if (!doc) throw new Error(\"print iframe not available\");\n\n doc.open();\n doc.write(`<!doctype html>\n<html>\n <head>\n <meta charset=\"utf-8\" />\n <title>${title.replace(/</g, \"&lt;\")}</title>\n <style>\n html, body { margin: 0; padding: 0; }\n img { width: 100%; display: block; }\n .page { page-break-after: always; }\n .page:last-child { page-break-after: auto; }\n @page { margin: 10mm; }\n </style>\n </head>\n <body></body>\n</html>`);\n doc.close();\n\n const body = doc.body;\n for (const page of pages) {\n const img = doc.createElement(\"img\");\n img.src = page.dataUrl;\n const wrapper = doc.createElement(\"div\");\n wrapper.className = \"page\";\n wrapper.appendChild(img);\n body.appendChild(wrapper);\n }\n\n // Wait for images to decode before printing\n await Promise.all(\n Array.from(body.querySelectorAll(\"img\")).map(\n (img) =>\n img.decode?.().catch(() => undefined) ?? Promise.resolve(),\n ),\n );\n\n setTimeout(() => {\n try {\n iframe.contentWindow?.focus();\n iframe.contentWindow?.print();\n } finally {\n setTimeout(() => {\n try {\n document.body.removeChild(iframe);\n } catch {\n // ignore\n }\n }, 1000);\n }\n }, 50);\n } catch {\n try {\n if (displayUrl) {\n window.open(displayUrl, \"_blank\", \"noopener,noreferrer\");\n } else if (resolvedUrl) {\n window.open(resolvedUrl, \"_blank\", \"noopener,noreferrer\");\n }\n } catch {\n // ignore\n }\n } finally {\n setIsPrinting(false);\n }\n }, [pdfDoc, status, rotation, title, displayUrl, resolvedUrl, annotations, signatures, textsForExport]);\n\n const handleDownload = useCallback(async () => {\n if (!pdfDoc || status !== \"ready\") return;\n\n const filename = `${title.replace(/[^\\w.-]+/g, \"_\") || \"document\"}.pdf`;\n const hasLayers =\n annotations.length > 0 ||\n signatures.length > 0 ||\n textsForExport.length > 0;\n\n // No markup → keep original PDF bytes\n if (!hasLayers && displayUrl) {\n triggerBlobDownload(\n await fetch(displayUrl).then((r) => r.blob()),\n filename,\n );\n return;\n }\n\n setIsDownloading(true);\n try {\n const pages = await renderAllPagesWithMarkup(pdfDoc, {\n scale: 2,\n rotation,\n annotations,\n signatures,\n texts: textsForExport,\n mimeType: \"image/jpeg\",\n quality: 0.92,\n });\n const pdfBytes = buildPdfFromJpegPages(pages);\n const copy = new Uint8Array(pdfBytes.byteLength);\n copy.set(pdfBytes);\n triggerBlobDownload(\n new Blob([copy], { type: \"application/pdf\" }),\n filename,\n );\n } catch {\n if (displayUrl) {\n triggerBlobDownload(\n await fetch(displayUrl).then((r) => r.blob()),\n filename,\n );\n }\n } finally {\n setIsDownloading(false);\n }\n }, [pdfDoc, status, rotation, title, displayUrl, annotations, signatures, textsForExport]);\n\n const toggleMarkupTool = useCallback((tool: MarkupTool) => {\n setMarkupTool((current) => (current === tool ? \"none\" : tool));\n }, []);\n\n const activeMarkupHex =\n markupTool === \"highlight\"\n ? highlightHex\n : markupTool === \"underline\"\n ? underlineHex\n : null;\n\n const activeMarkupColor =\n markupTool === \"highlight\" || markupTool === \"underline\"\n ? hexToMarkupColor(activeMarkupHex!, markupTool)\n : undefined;\n\n const selectedSignature =\n selectedSignatureId != null\n ? signatures.find((sig) => sig.id === selectedSignatureId) ?? null\n : null;\n\n const handleAddAnnotation = useCallback((annotation: MarkupAnnotation) => {\n setAnnotations((prev) => [...prev, annotation]);\n }, []);\n\n const handleRemoveAnnotation = useCallback((id: string) => {\n setAnnotations((prev) => prev.filter((a) => a.id !== id));\n }, []);\n\n const handleClearAnnotations = useCallback(() => {\n setAnnotations([]);\n setSignatures([]);\n setTexts([]);\n setSelectedSignatureId(null);\n setSelectedTextId(null);\n setSelectedTextFieldId(null);\n setEditingTextId(null);\n }, []);\n\n const advanceToNextUnsignedField = useCallback(\n (fromFieldId: string, filledIds: Set<string>) => {\n const currentIndex = signatureFields.findIndex(\n (field) => field.id === fromFieldId,\n );\n const nextField =\n signatureFields\n .slice(currentIndex + 1)\n .find((field) => !filledIds.has(field.id)) ??\n signatureFields\n .slice(0, Math.max(0, currentIndex))\n .find((field) => !filledIds.has(field.id));\n\n if (!nextField) {\n setSignaturePadOpen(false);\n setEditingSignatureId(null);\n return;\n }\n\n setSelectedSignatureFieldId(nextField.id);\n setSelectedSignatureId(null);\n setEditingSignatureId(null);\n setSignaturePadFieldType(nextField.type ?? \"sign\");\n scrollToSignatureField(nextField);\n window.setTimeout(() => {\n setSignaturePadOpen(true);\n }, 350);\n },\n [scrollToSignatureField, signatureFields],\n );\n\n const handleOpenSignaturePad = useCallback(\n (fieldType?: import(\"./signature\").SignatureFieldType) => {\n setSignaturePadFieldType(fieldType);\n setSignaturePadOpen(true);\n },\n [],\n );\n\n const handleFieldValueChange = useCallback((fieldId: string, value: string) => {\n setFieldValues((prev) => ({ ...prev, [fieldId]: value }));\n }, []);\n\n const handleFieldValueCommit = useCallback(\n (fieldId: string) => {\n const val = fieldValues[fieldId];\n if (val) onFieldValueComplete?.(fieldId, val);\n\n const currentIndex = signatureFields.findIndex((f) => f.id === fieldId);\n const filledIds = new Set(\n Object.keys(fieldValues).filter((k) => fieldValues[k]?.trim()),\n );\n filledIds.add(fieldId);\n const nextField =\n signatureFields.slice(currentIndex + 1).find(\n (f) => !filledIds.has(f.id) && !signatures.some((sig) => sig.fieldId === f.id),\n ) ??\n signatureFields.slice(0, Math.max(0, currentIndex)).find(\n (f) => !filledIds.has(f.id) && !signatures.some((sig) => sig.fieldId === f.id),\n );\n if (nextField) {\n setSelectedSignatureFieldId(nextField.id);\n scrollToSignatureField(nextField);\n }\n },\n [signatureFields, fieldValues, signatures, scrollToSignatureField, onFieldValueComplete],\n );\n\n const handleSignatureSave = useCallback(\n (imageDataUrl: string, sourceWidth: number, sourceHeight: number) => {\n const size = signatureDisplaySize(sourceWidth, sourceHeight);\n\n if (editingSignatureId) {\n setSignatures((prev) =>\n prev.map((sig) =>\n sig.id === editingSignatureId\n ? {\n ...sig,\n imageDataUrl,\n width: sig.fieldId ? sig.width : size.width,\n height: sig.fieldId ? sig.height : size.height,\n }\n : sig,\n ),\n );\n setPendingSignature(null);\n setMarkupTool(\"none\");\n setSignaturePadOpen(false);\n setEditingSignatureId(null);\n return;\n }\n\n if (hasFixedSignatureFields) {\n const targetField =\n signatureFields.find(\n (field) =>\n field.id === selectedSignatureFieldId &&\n (field.type ?? \"sign\") === \"sign\" &&\n !signatures.some((sig) => sig.fieldId === field.id),\n ) ??\n signatureFields.find(\n (field) =>\n (field.type ?? \"sign\") === \"sign\" &&\n !signatures.some((sig) => sig.fieldId === field.id),\n );\n\n if (!targetField) {\n setSignaturePadOpen(false);\n return;\n }\n\n const targetFields =\n applySignatureToSameTag && targetField.signature_tag\n ? signatureFields.filter(\n (field) =>\n (field.type ?? \"sign\") === \"sign\" &&\n field.signature_tag === targetField.signature_tag &&\n !signatures.some((sig) => sig.fieldId === field.id),\n )\n : [targetField];\n\n const newSignatures: SignatureAnnotation[] = targetFields.map((field) => ({\n id: createSignatureId(),\n fieldId: field.id,\n pageNumber: field.pageNumber,\n x: field.x,\n y: field.y,\n width: field.width,\n height: field.height,\n imageDataUrl,\n }));\n\n const targetIds = new Set(targetFields.map((field) => field.id));\n setSignatures((prev) => [\n ...prev.filter((sig) => !sig.fieldId || !targetIds.has(sig.fieldId)),\n ...newSignatures,\n ]);\n\n const byFieldId = new Map(\n newSignatures.map((sig) => [sig.fieldId as string, sig]),\n );\n writeSignatureImageToFields(\n targetFields.map((field) => field.id),\n newSignatures[0],\n byFieldId,\n );\n\n setPendingSignature(null);\n setMarkupTool(\"none\");\n setSelectedSignatureId(newSignatures[0]?.id ?? null);\n\n const filledIds = new Set(\n signatureFields\n .filter((field) =>\n isSignatureFieldFilled(\n field,\n [...signatures, ...newSignatures],\n fieldValues,\n ),\n )\n .map((field) => field.id),\n );\n for (const id of targetIds) filledIds.add(id);\n\n advanceToNextUnsignedField(targetField.id, filledIds);\n return;\n }\n\n const currentPageEl = pageRefsRef.current.get(pageNumber);\n const surface = currentPageEl?.querySelector(\n \".epochs-pdf-viewer__surface\",\n ) as HTMLDivElement | null;\n\n let x = 24;\n let y = 24;\n if (surface) {\n const pageSize = pageSizeFromSurface(surface, scale);\n const scrollContainer = surface.closest(\".epochs-pdf-viewer__body\") as HTMLElement | null;\n\n if (scrollContainer) {\n const visible = viewportRectToPage(\n scrollContainer.getBoundingClientRect(),\n surface,\n scale,\n );\n const visibleTop = Math.max(0, visible.top);\n const visibleBottom = Math.min(pageSize.height, visible.bottom);\n const visibleLeft = Math.max(0, visible.left);\n const visibleRight = Math.min(pageSize.width, visible.right);\n x = Math.max(0, (visibleLeft + visibleRight) / 2 - size.width / 2);\n y = Math.max(0, (visibleTop + visibleBottom) / 2 - size.height / 2);\n x = Math.min(x, Math.max(0, pageSize.width - size.width));\n y = Math.min(y, Math.max(0, pageSize.height - size.height));\n } else {\n x = Math.max(0, (pageSize.width - size.width) / 2);\n y = Math.max(0, (pageSize.height - size.height) / 2);\n }\n }\n\n const signature: SignatureAnnotation = {\n id: createSignatureId(),\n pageNumber,\n x,\n y,\n width: size.width,\n height: size.height,\n imageDataUrl,\n };\n\n setSignatures((prev) => [...prev, signature]);\n writeSignatureImageToFields(undefined, signature);\n setSelectedSignatureId(signature.id);\n setPendingSignature(null);\n setMarkupTool(\"none\");\n setSignaturePadOpen(false);\n setEditingSignatureId(null);\n },\n [\n advanceToNextUnsignedField,\n applySignatureToSameTag,\n editingSignatureId,\n fieldValues,\n hasFixedSignatureFields,\n isSignatureFieldFilled,\n pageNumber,\n scale,\n selectedSignatureFieldId,\n signatureFields,\n signatures,\n writeSignatureImageToFields,\n ],\n );\n\n const handleSaveFieldValue = useCallback(\n (value: string, fieldType: \"date\" | \"text\") => {\n if (hasFixedSignatureFields) {\n const targetField =\n signatureFields.find(\n (field) =>\n field.id === selectedSignatureFieldId &&\n (field.type ?? \"sign\") === fieldType,\n ) ??\n signatureFields.find((field) => (field.type ?? \"sign\") === fieldType);\n\n if (!targetField) {\n setSignaturePadOpen(false);\n return;\n }\n\n const targetFields =\n applySignatureToSameTag && targetField.signature_tag\n ? signatureFields.filter(\n (field) =>\n (field.type ?? \"sign\") === fieldType &&\n field.signature_tag === targetField.signature_tag,\n )\n : [targetField];\n\n const targetIds = targetFields.map((field) => field.id);\n writeFieldValueToFields(targetIds, value);\n\n const nextValues = { ...fieldValues };\n for (const id of targetIds) nextValues[id] = value;\n\n const filledIds = new Set(\n signatureFields\n .filter((field) =>\n isSignatureFieldFilled(field, signatures, nextValues),\n )\n .map((field) => field.id),\n );\n\n advanceToNextUnsignedField(targetField.id, filledIds);\n return;\n }\n\n const fontSize = DEFAULT_TEXT_FONT_SIZE;\n const width = Math.max(80, value.length * fontSize * 0.55);\n const height = fontSize * 1.25;\n let x = 24;\n let y = 24;\n\n const currentPageEl = pageRefsRef.current.get(pageNumber);\n const surface = currentPageEl?.querySelector(\n \".epochs-pdf-viewer__surface\",\n ) as HTMLDivElement | null;\n if (surface) {\n const pageSize = pageSizeFromSurface(surface, scale);\n const scrollContainer = surface.closest(\n \".epochs-pdf-viewer__body\",\n ) as HTMLElement | null;\n if (scrollContainer) {\n const visible = viewportRectToPage(\n scrollContainer.getBoundingClientRect(),\n surface,\n scale,\n );\n const visibleTop = Math.max(0, visible.top);\n const visibleBottom = Math.min(pageSize.height, visible.bottom);\n const visibleLeft = Math.max(0, visible.left);\n const visibleRight = Math.min(pageSize.width, visible.right);\n x = Math.max(0, (visibleLeft + visibleRight) / 2 - width / 2);\n y = Math.max(0, (visibleTop + visibleBottom) / 2 - height / 2);\n x = Math.min(x, Math.max(0, pageSize.width - width));\n y = Math.min(y, Math.max(0, pageSize.height - height));\n }\n }\n\n const text: TextAnnotation = {\n id: createTextId(),\n pageNumber,\n x,\n y,\n width,\n height,\n value,\n fontSize,\n color: DEFAULT_TEXT_COLOR,\n };\n setTexts((prev) => [...prev, text]);\n setSelectedTextId(text.id);\n setSignaturePadOpen(false);\n setMarkupTool(\"none\");\n },\n [\n advanceToNextUnsignedField,\n applySignatureToSameTag,\n fieldValues,\n hasFixedSignatureFields,\n isSignatureFieldFilled,\n pageNumber,\n scale,\n selectedSignatureFieldId,\n signatureFields,\n signatures,\n writeFieldValueToFields,\n ],\n );\n\n const handleAddSignature = useCallback((signature: SignatureAnnotation) => {\n setSignatures((prev) => [...prev, signature]);\n writeSignatureImageToFields(undefined, signature);\n setSelectedSignatureId(signature.id);\n setPendingSignature(null);\n setMarkupTool(\"none\");\n }, [writeSignatureImageToFields]);\n\n const handleUpdateSignature = useCallback(\n (id: string, patch: Partial<SignatureAnnotation>) => {\n setSignatures((prev) =>\n prev.map((sig) => (sig.id === id ? { ...sig, ...patch } : sig)),\n );\n },\n [],\n );\n\n const handleRemoveSignature = useCallback((id: string) => {\n const removed = signatures.find((sig) => sig.id === id);\n setSignatures((prev) => prev.filter((sig) => sig.id !== id));\n setSelectedSignatureId((current) => (current === id ? null : current));\n if (removed?.fieldId) {\n setSelectedSignatureFieldId(removed.fieldId);\n }\n }, [signatures]);\n\n const handleDuplicateSignature = useCallback((id?: string) => {\n const target = id\n ? signatures.find((sig) => sig.id === id) ?? null\n : selectedSignature;\n if (!target) return;\n\n const pageEl = pageRefsRef.current.get(target.pageNumber);\n const surface = pageEl?.querySelector(\n \".epochs-pdf-viewer__surface\",\n ) as HTMLDivElement | null;\n\n const offset = 18;\n let x = target.x + offset;\n let y = target.y + offset;\n\n if (surface) {\n const pageWidth = surface.clientWidth / scale;\n const pageHeight = surface.clientHeight / scale;\n x = Math.min(\n Math.max(0, x),\n Math.max(0, pageWidth - target.width),\n );\n y = Math.min(\n Math.max(0, y),\n Math.max(0, pageHeight - target.height),\n );\n }\n\n const duplicate: SignatureAnnotation = {\n ...target,\n id: createSignatureId(),\n x,\n y,\n };\n\n setSignatures((prev) => [...prev, duplicate]);\n setSelectedSignatureId(duplicate.id);\n setPendingSignature(null);\n setMarkupTool(\"none\");\n }, [scale, selectedSignature, signatures]);\n\n const handleEditSignature = useCallback((id?: string) => {\n const targetId = id ?? selectedSignature?.id;\n if (!targetId) return;\n const existing = signatures.find((sig) => sig.id === targetId);\n const field = existing?.fieldId\n ? signatureFields.find((item) => item.id === existing.fieldId)\n : undefined;\n setSignaturePadFieldType(field?.type ?? \"sign\");\n setSelectedSignatureId(targetId);\n setEditingSignatureId(targetId);\n setSignaturePadOpen(true);\n }, [selectedSignature, signatures, signatureFields]);\n\n const handleAddText = useCallback((text: TextAnnotation) => {\n setTexts((prev) => {\n if (text.fieldId) {\n return [...prev.filter((item) => item.fieldId !== text.fieldId), text];\n }\n return [...prev, text];\n });\n setSelectedTextId(text.id);\n if (text.fieldId) setSelectedTextFieldId(text.fieldId);\n }, []);\n\n const handleUpdateText = useCallback(\n (id: string, patch: Partial<TextAnnotation>) => {\n setTexts((prev) =>\n prev.map((text) => (text.id === id ? { ...text, ...patch } : text)),\n );\n },\n [],\n );\n\n const handleRemoveText = useCallback((id: string) => {\n const removed = texts.find((text) => text.id === id);\n setTexts((prev) => prev.filter((text) => text.id !== id));\n setSelectedTextId((current) => (current === id ? null : current));\n setEditingTextId((current) => (current === id ? null : current));\n if (removed?.fieldId) {\n setSelectedTextFieldId(removed.fieldId);\n }\n }, [texts]);\n\n // Sync fixed text field geometry if the prop changes\n useEffect(() => {\n if (!hasFixedTextFields) return;\n setTexts((prev) =>\n prev.map((text) => {\n if (!text.fieldId) return text;\n const field = textFields.find((item) => item.id === text.fieldId);\n if (!field) return text;\n return {\n ...text,\n pageNumber: field.pageNumber,\n x: field.x,\n y: field.y,\n width: field.width,\n height: field.height,\n fontSize: field.fontSize ?? text.fontSize ?? DEFAULT_TEXT_FONT_SIZE,\n color: field.color ?? text.color ?? DEFAULT_TEXT_COLOR,\n };\n }),\n );\n }, [hasFixedTextFields, textFields]);\n\n const goToSignatureField = useCallback(\n (direction: -1 | 1) => {\n if (!signatureFields.length) return;\n const from =\n selectedSignatureFieldId != null\n ? signatureFields.findIndex((f) => f.id === selectedSignatureFieldId)\n : -1;\n const nextIndex = Math.min(\n signatureFields.length - 1,\n Math.max(0, (from < 0 ? 0 : from) + direction),\n );\n const field = signatureFields[nextIndex];\n if (!field) return;\n setSelectedSignatureFieldId(field.id);\n setSelectedSignatureId(\n signatures.find((sig) => sig.fieldId === field.id)?.id ?? null,\n );\n scrollToSignatureField(field);\n },\n [\n scrollToSignatureField,\n selectedSignatureFieldId,\n signatureFields,\n signatures,\n ],\n );\n\n if (!binarySource && !resolvedUrl) {\n return (\n <div\n data-testid=\"pdf-viewer\"\n className={`epochs-pdf-viewer epochs-pdf-viewer--empty ${className ?? \"\"}`.trim()}\n >\n No PDF file provided.\n </div>\n );\n }\n\n const rootStyle: CSSProperties = {\n height,\n };\n\n const toolbarCtx: ToolbarRenderContext = {\n status,\n showThumbnails,\n setShowThumbnails,\n canGoPrev,\n canGoNext,\n handlePrev,\n handleNext,\n pageNumber,\n numPages,\n scrollToPage,\n scale,\n handleZoomOut,\n handleZoomIn,\n handleFitWidth,\n handleRotate,\n markupTool,\n toggleMarkupTool: (tool) => toggleMarkupTool(tool),\n hasFixedSignatureFields,\n hasFixedTextFields,\n pendingSignature,\n setMarkupTool,\n setSignaturePadOpen,\n annotationsLength: annotations.length,\n signaturesLength: signatures.length,\n textsLength: texts.length,\n handleClearAnnotations,\n highlightHex,\n underlineHex,\n setHighlightHex,\n setUnderlineHex,\n loadDocument,\n handlePrint,\n isPrinting,\n pdfDoc,\n displayUrl,\n resolvedUrl,\n handleDownload,\n isDownloading,\n };\n\n const visibleToolIds = (ids: ToolbarToolId[]) =>\n ids.filter((id) => {\n if (\n hasFixedSignatureFields &&\n (id === \"highlight\" || id === \"underline\" || id === \"erase\")\n ) {\n return false;\n }\n return true;\n });\n\n const currentFieldIndex = selectedSignatureFieldId\n ? signatureFields.findIndex((field) => field.id === selectedSignatureFieldId)\n : 0;\n\n const filledFieldCount = signatureFields.filter((field) =>\n isSignatureFieldFilled(field, signatures, fieldValues),\n ).length;\n\n const fieldProgressPercent =\n signatureFields.length > 0\n ? Math.round((filledFieldCount / signatureFields.length) * 100)\n : 0;\n\n const renderSide = (ids: ToolbarToolId[], alignEnd = false) => {\n const visible = visibleToolIds(ids);\n if (visible.length === 0 && !alignEnd) {\n return <div className=\"epochs-pdf-viewer__toolbar-group\" />;\n }\n if (visible.length === 0) {\n return (\n <div className=\"epochs-pdf-viewer__toolbar-group epochs-pdf-viewer__toolbar-group--end\" />\n );\n }\n\n const nodes = visible.map((id, index) => {\n const prev = visible[index - 1];\n const showMarkupSep =\n isMarkupToolbarTool(id) && (!prev || !isMarkupToolbarTool(prev));\n return (\n <Fragment key={id}>\n {renderToolbarTool(id, toolbarCtx, { showMarkupSep })}\n </Fragment>\n );\n });\n\n return (\n <div\n className={\n alignEnd\n ? \"epochs-pdf-viewer__toolbar-group epochs-pdf-viewer__toolbar-group--end\"\n : \"epochs-pdf-viewer__toolbar-group\"\n }\n >\n {nodes}\n {renderMarkupExtras(toolbarCtx, new Set(visible))}\n </div>\n );\n };\n\n return (\n <div\n data-testid=\"pdf-viewer\"\n data-file-url={resolvedUrl || undefined}\n className={`epochs-pdf-viewer ${className ?? \"\"}`.trim()}\n style={rootStyle}\n >\n {toolbarSides ? (\n <div className=\"epochs-pdf-viewer__toolbar\">\n {renderSide(toolbarSides.left)}\n {renderSide(toolbarSides.right, true)}\n </div>\n ) : null}\n\n {(showSignature || externalOpenSignaturePad || hasFixedSignatureFields) ? (\n <SignaturePad\n open={signaturePadOpen}\n onClose={() => {\n setSignaturePadOpen(false);\n setEditingSignatureId(null);\n setSignaturePadFieldType(undefined);\n onSignaturePadClose?.();\n }}\n onSave={handleSignatureSave}\n onSaveFieldValue={handleSaveFieldValue}\n fieldType={signaturePadFieldType}\n showFieldTypeTabs={!hasFixedSignatureFields}\n textPlaceholder={\n signatureFields.find((field) => field.id === selectedSignatureFieldId)\n ?.placeholder\n }\n initialFieldValue={\n selectedSignatureFieldId\n ? fieldValues[selectedSignatureFieldId] ??\n signatureFields.find((field) => field.id === selectedSignatureFieldId)\n ?.value\n : undefined\n }\n targetSize={(() => {\n const field = signatureFields.find(\n (item) => item.id === selectedSignatureFieldId,\n );\n if (!field || (field.type ?? \"sign\") !== \"sign\") return undefined;\n return { width: field.width, height: field.height };\n })()}\n rememberedByType={rememberedByType}\n onRememberFill={(type, fill) => {\n setRememberedByType((prev) => {\n if (type === \"sign\") {\n return { ...prev, sign: fill as RememberedSignFill };\n }\n if (type === \"date\") {\n return { ...prev, date: fill as { value: string } };\n }\n return { ...prev, text: fill as { value: string } };\n });\n }}\n />\n ) : null}\n\n <div className=\"epochs-pdf-viewer__content\">\n {showThumbnails ? (\n <div\n className=\"epochs-pdf-viewer__thumbnails\"\n style={{ width: thumbnailWidth + 24 }}\n >\n {status === \"ready\" && pdfDoc ? (\n <>\n {Array.from({\n length: Math.min(numPages || 0, maxThumbnails),\n }).map((_, idx) => {\n const n = idx + 1;\n return (\n <div key={n} className=\"epochs-pdf-viewer__thumb-wrap\">\n <ThumbnailStrip\n pdfDoc={pdfDoc}\n pageNumber={n}\n isActive={n === pageNumber}\n rotation={rotation}\n onSelect={scrollToPage}\n width={thumbnailWidth}\n annotations={annotations}\n signatures={signatures}\n signatureFields={signatureFields}\n texts={textsForExport}\n textFields={textFields}\n />\n </div>\n );\n })}\n {numPages > maxThumbnails ? (\n <div className=\"epochs-pdf-viewer__thumb-more\">\n Showing first {maxThumbnails} pages\n </div>\n ) : null}\n </>\n ) : (\n <div className=\"epochs-pdf-viewer__muted\">Thumbnails</div>\n )}\n </div>\n ) : null}\n\n <div ref={containerRef} className=\"epochs-pdf-viewer__body\">\n {status === \"loading\" ? (\n <div className=\"epochs-pdf-viewer__overlay epochs-pdf-viewer__muted\">\n Loading PDF…\n <span className=\"epochs-pdf-viewer__spinner\" />\n </div>\n ) : null}\n\n {status === \"error\" ? (\n <div className=\"epochs-pdf-viewer__overlay epochs-pdf-viewer__error\">\n Unable to load PDF.\n {resolvedUrl ? (\n <a\n className=\"epochs-pdf-viewer__open-link\"\n href={resolvedUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Open file\n </a>\n ) : null}\n </div>\n ) : null}\n\n {status === \"ready\" && pdfDoc ? (\n <div>\n {Array.from({ length: numPages }).map((_, idx) => {\n const p = idx + 1;\n return (\n <PageCanvas\n key={p}\n pdfDoc={pdfDoc}\n pageNumber={p}\n scale={scale}\n rotation={rotation}\n markupTool={enableMarkup ? markupTool : \"none\"}\n markupColor={activeMarkupColor}\n annotations={annotations}\n onAddAnnotation={handleAddAnnotation}\n onRemoveAnnotation={handleRemoveAnnotation}\n signatures={signatures}\n pendingSignature={pendingSignature}\n onAddSignature={handleAddSignature}\n onUpdateSignature={handleUpdateSignature}\n onRemoveSignature={handleRemoveSignature}\n onEditSignature={handleEditSignature}\n onDuplicateSignature={handleDuplicateSignature}\n selectedSignatureId={selectedSignatureId}\n onSelectSignature={setSelectedSignatureId}\n signatureFields={signatureFields}\n selectedSignatureFieldId={selectedSignatureFieldId}\n onSelectSignatureField={setSelectedSignatureFieldId}\n hasFixedSignatureFields={hasFixedSignatureFields}\n onOpenSignaturePad={handleOpenSignaturePad}\n fieldValues={fieldValues}\n onFieldValueChange={handleFieldValueChange}\n onFieldValueCommit={handleFieldValueCommit}\n texts={texts}\n onAddText={handleAddText}\n onUpdateText={handleUpdateText}\n onRemoveText={handleRemoveText}\n selectedTextId={selectedTextId}\n onSelectText={setSelectedTextId}\n textFields={textFields}\n selectedTextFieldId={selectedTextFieldId}\n onSelectTextField={setSelectedTextFieldId}\n hasFixedTextFields={hasFixedTextFields}\n editingTextId={editingTextId}\n onEditingTextIdChange={setEditingTextId}\n pageRef={(el) => {\n if (el) pageRefsRef.current.set(p, el);\n }}\n />\n );\n })}\n </div>\n ) : null}\n </div>\n </div>\n\n {hasFixedSignatureFields || onSubmit ? (\n <div className=\"epochs-pdf-viewer__footer\" role=\"navigation\" aria-label=\"Viewer actions\">\n {hasFixedSignatureFields ? (\n <>\n <div className=\"epochs-pdf-viewer__footer-nav\">\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n disabled={signatureFields.length <= 1 || currentFieldIndex <= 0}\n onClick={() => goToSignatureField(-1)}\n >\n Prev\n </button>\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text\"\n disabled={\n signatureFields.length <= 1 ||\n currentFieldIndex >= signatureFields.length - 1\n }\n onClick={() => goToSignatureField(1)}\n >\n Next\n </button>\n </div>\n <div className=\"epochs-pdf-viewer__footer-center\">\n <span className=\"epochs-pdf-viewer__footer-label\">\n Field {Math.max(1, currentFieldIndex + 1)} of {signatureFields.length}\n </span>\n <div\n className=\"epochs-pdf-viewer__footer-progress\"\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={fieldProgressPercent}\n aria-label=\"Signature progress\"\n >\n <div\n className=\"epochs-pdf-viewer__footer-progress-bar\"\n style={{ width: `${fieldProgressPercent}%` }}\n />\n </div>\n <span className=\"epochs-pdf-viewer__footer-percent\">\n {fieldProgressPercent}%\n </span>\n </div>\n </>\n ) : (\n <div className=\"epochs-pdf-viewer__footer-center\" />\n )}\n {onSubmit ? (\n <button\n type=\"button\"\n className=\"epochs-pdf-viewer__btn epochs-pdf-viewer__btn--text epochs-pdf-viewer__btn--primary\"\n onClick={onSubmit}\n disabled={submitLoading}\n aria-busy={submitLoading || undefined}\n >\n {submitLoading ? (\n <span\n className=\"epochs-pdf-viewer__spinner epochs-pdf-viewer__spinner--btn\"\n aria-hidden=\"true\"\n />\n ) : null}\n {submitLabel}\n </button>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\nexport default PdfViewer;\n","import type {\n DocumentProps,\n ImageProps,\n LinkProps,\n PageProps,\n TextProps,\n ViewProps,\n} from \"./types\";\n\n/** Root document container. Must wrap one or more `<Page>` elements. */\nexport function Document(_props: DocumentProps): null {\n return null;\n}\nDocument.displayName = \"Document\";\n\n/** A single PDF page. */\nexport function Page(_props: PageProps): null {\n return null;\n}\nPage.displayName = \"Page\";\n\n/** Flexbox layout container. */\nexport function View(_props: ViewProps): null {\n return null;\n}\nView.displayName = \"View\";\n\n/** Text content. Children are flattened to a string. */\nexport function Text(_props: TextProps): null {\n return null;\n}\nText.displayName = \"Text\";\n\n/** Image placeholder (binary embedding planned). */\nexport function Image(_props: ImageProps): null {\n return null;\n}\nImage.displayName = \"Image\";\n\n/** Linked text. */\nexport function Link(_props: LinkProps): null {\n return null;\n}\nLink.displayName = \"Link\";\n","import { createElement, type ReactElement, type ReactNode } from \"react\";\nimport type { PdfNode, NodeType } from \"./types\";\n\nconst TYPE_MAP: Record<string, NodeType> = {\n Document: \"DOCUMENT\",\n Page: \"PAGE\",\n View: \"VIEW\",\n Text: \"TEXT\",\n Image: \"IMAGE\",\n Link: \"LINK\",\n};\n\nfunction getDisplayName(type: unknown): string | null {\n if (typeof type === \"string\") return type;\n if (typeof type === \"function\") {\n const fn = type as { displayName?: string; name?: string };\n return fn.displayName || fn.name || null;\n }\n return null;\n}\n\nfunction flattenChildren(children: ReactNode): ReactNode[] {\n const result: ReactNode[] = [];\n const visit = (node: ReactNode) => {\n if (node == null || typeof node === \"boolean\") return;\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n result.push(node);\n };\n visit(children);\n return result;\n}\n\nfunction collectText(children: ReactNode): string {\n return flattenChildren(children)\n .map((child) => {\n if (typeof child === \"string\" || typeof child === \"number\") {\n return String(child);\n }\n if (\n child &&\n typeof child === \"object\" &&\n \"props\" in (child as ReactElement)\n ) {\n const el = child as ReactElement<{ children?: ReactNode }>;\n return collectText(el.props.children);\n }\n return \"\";\n })\n .join(\"\");\n}\n\nexport function elementToPdfNode(element: ReactElement): PdfNode {\n const name = getDisplayName(element.type);\n const nodeType = name ? TYPE_MAP[name] : undefined;\n\n if (!nodeType) {\n throw new Error(\n `[epochs-pdf] Unsupported element \"${name ?? \"unknown\"}\". Use Document, Page, View, Text, Image, or Link.`,\n );\n }\n\n const props = { ...(element.props as Record<string, unknown>) };\n const childrenProp = props.children as ReactNode;\n delete props.children;\n\n if (nodeType === \"TEXT\" || nodeType === \"LINK\") {\n return {\n type: nodeType,\n props,\n children: [],\n text: collectText(childrenProp),\n };\n }\n\n const childNodes = flattenChildren(childrenProp)\n .filter(\n (child): child is ReactElement =>\n !!child && typeof child === \"object\" && \"type\" in (child as object),\n )\n .map(elementToPdfNode);\n\n return {\n type: nodeType,\n props,\n children: childNodes,\n };\n}\n\nexport function createPdfElement(\n type: NodeType,\n props: Record<string, unknown> = {},\n ...children: ReactNode[]\n): ReactElement {\n const name = Object.entries(TYPE_MAP).find(([, v]) => v === type)?.[0];\n if (!name) throw new Error(`Unknown node type: ${type}`);\n return createElement(name, props, ...children);\n}\n","import type { PageSize, Style } from \"./types\";\n\nexport const PAGE_SIZES: Record<Exclude<PageSize, [number, number]>, [number, number]> = {\n A4: [595.28, 841.89],\n LETTER: [612, 792],\n LEGAL: [612, 1008],\n};\n\nexport function resolvePageSize(\n size: PageSize = \"A4\",\n orientation: \"portrait\" | \"landscape\" = \"portrait\",\n): [number, number] {\n const [w, h] = Array.isArray(size) ? size : PAGE_SIZES[size];\n return orientation === \"landscape\" ? [h, w] : [w, h];\n}\n\nexport function expandPadding(style: Style = {}) {\n const base = style.padding ?? 0;\n return {\n top: style.paddingTop ?? base,\n right: style.paddingRight ?? base,\n bottom: style.paddingBottom ?? base,\n left: style.paddingLeft ?? base,\n };\n}\n\nexport function expandMargin(style: Style = {}) {\n const base = style.margin ?? 0;\n return {\n top: style.marginTop ?? base,\n right: style.marginRight ?? base,\n bottom: style.marginBottom ?? base,\n left: style.marginLeft ?? base,\n };\n}\n\n/** Parse #RRGGBB / #RGB / rgb() into 0–1 RGB components. */\nexport function parseColor(input?: string): [number, number, number] | null {\n if (!input) return null;\n\n const hex = input.trim();\n if (hex.startsWith(\"#\")) {\n const raw = hex.slice(1);\n if (raw.length === 3) {\n const r = parseInt(raw[0] + raw[0], 16) / 255;\n const g = parseInt(raw[1] + raw[1], 16) / 255;\n const b = parseInt(raw[2] + raw[2], 16) / 255;\n return [r, g, b];\n }\n if (raw.length === 6) {\n const r = parseInt(raw.slice(0, 2), 16) / 255;\n const g = parseInt(raw.slice(2, 4), 16) / 255;\n const b = parseInt(raw.slice(4, 6), 16) / 255;\n return [r, g, b];\n }\n }\n\n const rgb = input.match(\n /rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)/i,\n );\n if (rgb) {\n return [\n Math.min(1, Number(rgb[1]) / 255),\n Math.min(1, Number(rgb[2]) / 255),\n Math.min(1, Number(rgb[3]) / 255),\n ];\n }\n\n return null;\n}\n\nexport function resolveLength(\n value: number | string | undefined,\n parent: number,\n fallback = 0,\n): number {\n if (value == null) return fallback;\n if (typeof value === \"number\") return value;\n if (value.endsWith(\"%\")) {\n const pct = Number.parseFloat(value);\n return Number.isFinite(pct) ? (pct / 100) * parent : fallback;\n }\n const n = Number.parseFloat(value);\n return Number.isFinite(n) ? n : fallback;\n}\n\nexport function isBold(weight?: Style[\"fontWeight\"]): boolean {\n if (weight === \"bold\") return true;\n if (typeof weight === \"number\") return weight >= 600;\n return false;\n}\n","import type { LayoutBox, PdfNode, ResolvedDocument, ResolvedPage, Style } from \"./types\";\nimport {\n expandMargin,\n expandPadding,\n isBold,\n resolveLength,\n resolvePageSize,\n} from \"./utils\";\n\nconst DEFAULT_FONT_SIZE = 12;\nconst DEFAULT_LINE_HEIGHT = 1.4;\nconst AVG_CHAR_WIDTH = 0.5;\n\nfunction measureText(text: string, style: Style, maxWidth: number): { width: number; height: number; lines: string[] } {\n const fontSize = style.fontSize ?? DEFAULT_FONT_SIZE;\n const lineHeight = (style.lineHeight ?? DEFAULT_LINE_HEIGHT) * fontSize;\n const charWidth = fontSize * (isBold(style.fontWeight) ? 0.55 : AVG_CHAR_WIDTH);\n\n if (!text) {\n return { width: 0, height: lineHeight, lines: [\"\"] };\n }\n\n const words = text.split(/\\s+/);\n const lines: string[] = [];\n let current = \"\";\n\n for (const word of words) {\n const candidate = current ? `${current} ${word}` : word;\n if (candidate.length * charWidth <= maxWidth || !current) {\n current = candidate;\n } else {\n lines.push(current);\n current = word;\n }\n }\n if (current) lines.push(current);\n\n const widest = Math.max(...lines.map((l) => l.length * charWidth), 0);\n return {\n width: Math.min(widest, maxWidth),\n height: lines.length * lineHeight,\n lines,\n };\n}\n\nfunction layoutNode(\n node: PdfNode,\n x: number,\n y: number,\n availableWidth: number,\n availableHeight: number,\n): LayoutBox {\n const style = (node.props.style as Style | undefined) ?? {};\n const margin = expandMargin(style);\n const padding = expandPadding(style);\n\n const outerX = x + margin.left;\n const outerY = y + margin.top;\n const contentWidth = Math.max(\n 0,\n resolveLength(style.width, availableWidth, availableWidth) - margin.left - margin.right,\n );\n const innerWidth = Math.max(0, contentWidth - padding.left - padding.right);\n\n if (node.type === \"TEXT\" || node.type === \"LINK\") {\n const measured = measureText(node.text ?? \"\", style, innerWidth);\n const height =\n resolveLength(style.height, availableHeight, measured.height + padding.top + padding.bottom);\n return {\n x: outerX,\n y: outerY,\n width: contentWidth,\n height,\n node,\n children: [],\n style,\n text: node.text,\n };\n }\n\n if (node.type === \"IMAGE\") {\n const width = resolveLength(style.width, availableWidth, Math.min(200, availableWidth));\n const height = resolveLength(style.height, availableHeight, 120);\n return {\n x: outerX,\n y: outerY,\n width: width - margin.left - margin.right,\n height,\n node,\n children: [],\n style,\n };\n }\n\n const direction = style.flexDirection ?? \"column\";\n const gap = style.gap ?? 0;\n const childBoxes: LayoutBox[] = [];\n\n let cursorX = outerX + padding.left;\n let cursorY = outerY + padding.top;\n let usedMain = 0;\n let crossSize = 0;\n\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n const remainingW =\n direction === \"row\"\n ? Math.max(0, innerWidth - usedMain - (i > 0 ? gap : 0))\n : innerWidth;\n const remainingH =\n direction === \"column\"\n ? Math.max(0, availableHeight - (cursorY - y) - margin.bottom)\n : availableHeight;\n\n const box = layoutNode(child, cursorX, cursorY, remainingW, remainingH);\n childBoxes.push(box);\n\n if (direction === \"row\") {\n usedMain += box.width + expandMargin((child.props.style as Style) ?? {}).left\n + expandMargin((child.props.style as Style) ?? {}).right;\n if (i < node.children.length - 1) usedMain += gap;\n cursorX = outerX + padding.left + usedMain;\n crossSize = Math.max(crossSize, box.height);\n } else {\n usedMain += box.height + expandMargin((child.props.style as Style) ?? {}).top\n + expandMargin((child.props.style as Style) ?? {}).bottom;\n if (i < node.children.length - 1) usedMain += gap;\n cursorY = outerY + padding.top + usedMain;\n crossSize = Math.max(crossSize, box.width);\n }\n }\n\n const contentHeight =\n resolveLength(\n style.height,\n availableHeight,\n direction === \"column\"\n ? usedMain + padding.top + padding.bottom\n : crossSize + padding.top + padding.bottom,\n );\n\n const finalWidth =\n direction === \"row\"\n ? resolveLength(style.width, availableWidth, usedMain + padding.left + padding.right)\n : contentWidth;\n\n const justify = style.justifyContent ?? \"flex-start\";\n const align = style.alignItems ?? \"stretch\";\n\n const innerMain =\n direction === \"column\"\n ? contentHeight - padding.top - padding.bottom\n : finalWidth - padding.left - padding.right;\n const childrenMain = usedMain;\n const freeSpace = Math.max(0, innerMain - childrenMain);\n\n let mainOffset = 0;\n let betweenGap = gap;\n if (justify === \"center\") mainOffset = freeSpace / 2;\n if (justify === \"flex-end\") mainOffset = freeSpace;\n if (justify === \"space-between\" && childBoxes.length > 1) {\n betweenGap = gap + freeSpace / (childBoxes.length - 1);\n }\n if (justify === \"space-around\" && childBoxes.length > 0) {\n betweenGap = gap + freeSpace / childBoxes.length;\n mainOffset = betweenGap / 2;\n }\n\n let running = 0;\n for (const box of childBoxes) {\n if (direction === \"column\") {\n box.y = outerY + padding.top + mainOffset + running;\n if (align === \"center\") {\n box.x = outerX + padding.left + Math.max(0, (innerWidth - box.width) / 2);\n } else if (align === \"flex-end\") {\n box.x = outerX + padding.left + Math.max(0, innerWidth - box.width);\n } else if (align === \"stretch\" && box.style.width == null) {\n box.width = innerWidth;\n }\n running += box.height + betweenGap;\n } else {\n box.x = outerX + padding.left + mainOffset + running;\n if (align === \"center\") {\n box.y =\n outerY +\n padding.top +\n Math.max(0, (contentHeight - padding.top - padding.bottom - box.height) / 2);\n } else if (align === \"flex-end\") {\n box.y =\n outerY +\n padding.top +\n Math.max(0, contentHeight - padding.top - padding.bottom - box.height);\n } else if (align === \"stretch\" && box.style.height == null) {\n box.height = contentHeight - padding.top - padding.bottom;\n }\n running += box.width + betweenGap;\n }\n }\n\n return {\n x: outerX,\n y: outerY,\n width: finalWidth,\n height: contentHeight,\n node,\n children: childBoxes,\n style,\n };\n}\n\nexport function layoutDocument(root: PdfNode): ResolvedDocument {\n if (root.type !== \"DOCUMENT\") {\n throw new Error(\"[epochs-pdf] Root element must be <Document>.\");\n }\n\n const pages: ResolvedPage[] = [];\n\n for (const pageNode of root.children) {\n if (pageNode.type !== \"PAGE\") {\n throw new Error(\"[epochs-pdf] Direct children of <Document> must be <Page>.\");\n }\n\n const size = pageNode.props.size as Parameters<typeof resolvePageSize>[0];\n const orientation = (pageNode.props.orientation as \"portrait\" | \"landscape\") ?? \"portrait\";\n const [width, height] = resolvePageSize(size, orientation);\n const style = (pageNode.props.style as Style | undefined) ?? {};\n const padding = expandPadding(style);\n\n const contentRoot: PdfNode = {\n type: \"VIEW\",\n props: {\n style: {\n ...style,\n width,\n height,\n paddingTop: padding.top,\n paddingRight: padding.right,\n paddingBottom: padding.bottom,\n paddingLeft: padding.left,\n },\n },\n children: pageNode.children,\n };\n\n const box = layoutNode(contentRoot, 0, 0, width, height);\n\n pages.push({\n width,\n height,\n boxes: box.children,\n style,\n });\n }\n\n return {\n meta: {\n title: String(root.props.title ?? \"Untitled\"),\n author: String(root.props.author ?? \"\"),\n subject: String(root.props.subject ?? \"\"),\n creator: String(root.props.creator ?? \"epochs-pdf\"),\n },\n pages,\n };\n}\n\nexport { measureText };\n","import type { LayoutBox, ResolvedDocument, Style } from \"./types\";\nimport { isBold, parseColor } from \"./utils\";\nimport { measureText } from \"./layout\";\n\nfunction escapePdfString(value: string): string {\n return value\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\(/g, \"\\\\(\")\n .replace(/\\)/g, \"\\\\)\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\n/g, \"\\\\n\");\n}\n\nclass PdfWriter {\n private objects: (string | null)[] = [null];\n private offsets: number[] = [0];\n\n addObject(content: string): number {\n this.objects.push(content);\n return this.objects.length - 1;\n }\n\n build(doc: ResolvedDocument): Uint8Array {\n const infoId = this.addObject(\n `<< /Title (${escapePdfString(doc.meta.title)}) /Author (${escapePdfString(doc.meta.author)}) /Subject (${escapePdfString(doc.meta.subject)}) /Creator (${escapePdfString(doc.meta.creator)}) /Producer (epochs-pdf) >>`,\n );\n\n const fontRegular = this.addObject(\n \"<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>\",\n );\n const fontBold = this.addObject(\n \"<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica-Bold >>\",\n );\n\n const pageIds: number[] = [];\n\n for (const page of doc.pages) {\n const contentStream = this.renderPageContent(\n page.boxes,\n page.width,\n page.height,\n page.style,\n );\n const contentId = this.addObject(\n `<< /Length ${contentStream.length} >>\\nstream\\n${contentStream}\\nendstream`,\n );\n\n const pageId = this.addObject(\"\"); // placeholder\n pageIds.push(pageId);\n\n this.objects[pageId] =\n `<< /Type /Page /Parent 0 0 R /MediaBox [0 0 ${page.width.toFixed(2)} ${page.height.toFixed(2)}] /Contents ${contentId} 0 R /Resources << /Font << /F1 ${fontRegular} 0 R /F2 ${fontBold} 0 R >> >> >>`;\n }\n\n const kids = pageIds.map((id) => `${id} 0 R`).join(\" \");\n const pagesId = this.addObject(\n `<< /Type /Pages /Kids [${kids}] /Count ${pageIds.length} >>`,\n );\n\n for (const pageId of pageIds) {\n this.objects[pageId] = (this.objects[pageId] as string).replace(\n \"/Parent 0 0 R\",\n `/Parent ${pagesId} 0 R`,\n );\n }\n\n const catalogId = this.addObject(\n `<< /Type /Catalog /Pages ${pagesId} 0 R >>`,\n );\n\n // Serialize\n let body = \"%PDF-1.4\\n\";\n this.offsets = [0];\n\n for (let i = 1; i < this.objects.length; i++) {\n this.offsets[i] = body.length;\n body += `${i} 0 obj\\n${this.objects[i]}\\nendobj\\n`;\n }\n\n const xrefOffset = body.length;\n body += `xref\\n0 ${this.objects.length}\\n`;\n body += \"0000000000 65535 f \\n\";\n for (let i = 1; i < this.objects.length; i++) {\n body += `${String(this.offsets[i]).padStart(10, \"0\")} 00000 n \\n`;\n }\n body += `trailer\\n<< /Size ${this.objects.length} /Root ${catalogId} 0 R /Info ${infoId} 0 R >>\\n`;\n body += `startxref\\n${xrefOffset}\\n%%EOF`;\n\n return new TextEncoder().encode(body);\n }\n\n private renderPageContent(\n boxes: LayoutBox[],\n pageWidth: number,\n pageHeight: number,\n pageStyle: Style,\n ): string {\n const ops: string[] = [];\n\n const pageBg = parseColor(pageStyle.backgroundColor);\n if (pageBg) {\n ops.push(`q`);\n ops.push(\n `${pageBg[0].toFixed(3)} ${pageBg[1].toFixed(3)} ${pageBg[2].toFixed(3)} rg`,\n );\n ops.push(\n `0 0 ${pageWidth.toFixed(2)} ${pageHeight.toFixed(2)} re f`,\n );\n ops.push(`Q`);\n }\n\n const drawBox = (box: LayoutBox) => {\n const { x, y, width, height, style, node, text } = box;\n const pdfY = pageHeight - y - height;\n\n const fill = parseColor(style.backgroundColor);\n if (fill) {\n ops.push(`q`);\n ops.push(`${fill[0].toFixed(3)} ${fill[1].toFixed(3)} ${fill[2].toFixed(3)} rg`);\n ops.push(`${x.toFixed(2)} ${pdfY.toFixed(2)} ${width.toFixed(2)} ${height.toFixed(2)} re f`);\n ops.push(`Q`);\n }\n\n if (style.borderWidth && style.borderWidth > 0) {\n const border = parseColor(style.borderColor) ?? [0, 0, 0];\n ops.push(`q`);\n ops.push(`${style.borderWidth} w`);\n ops.push(`${border[0].toFixed(3)} ${border[1].toFixed(3)} ${border[2].toFixed(3)} RG`);\n ops.push(`${x.toFixed(2)} ${pdfY.toFixed(2)} ${width.toFixed(2)} ${height.toFixed(2)} re S`);\n ops.push(`Q`);\n }\n\n if ((node.type === \"TEXT\" || node.type === \"LINK\") && text != null) {\n const fontSize = style.fontSize ?? 12;\n const color = parseColor(style.color) ?? [0, 0, 0];\n const font = isBold(style.fontWeight) ? \"F2\" : \"F1\";\n const paddingLeft = style.paddingLeft ?? style.padding ?? 0;\n const paddingTop = style.paddingTop ?? style.padding ?? 0;\n const maxWidth = Math.max(0, width - paddingLeft - (style.paddingRight ?? style.padding ?? 0));\n const measured = measureText(text, style, maxWidth || width);\n const lineHeight = (style.lineHeight ?? 1.4) * fontSize;\n\n ops.push(`q`);\n ops.push(`BT`);\n ops.push(`/${font} ${fontSize} Tf`);\n ops.push(`${color[0].toFixed(3)} ${color[1].toFixed(3)} ${color[2].toFixed(3)} rg`);\n\n measured.lines.forEach((line, index) => {\n let textX = x + paddingLeft;\n const lineWidth = line.length * fontSize * (isBold(style.fontWeight) ? 0.55 : 0.5);\n if (style.textAlign === \"center\") {\n textX = x + (width - lineWidth) / 2;\n } else if (style.textAlign === \"right\") {\n textX = x + width - lineWidth - (style.paddingRight ?? style.padding ?? 0);\n }\n const textY = pageHeight - y - paddingTop - fontSize - index * lineHeight;\n ops.push(`1 0 0 1 ${textX.toFixed(2)} ${textY.toFixed(2)} Tm`);\n ops.push(`(${escapePdfString(line)}) Tj`);\n });\n\n ops.push(`ET`);\n ops.push(`Q`);\n }\n\n if (node.type === \"IMAGE\") {\n // Placeholder rectangle for images (no external deps / binary embedding yet)\n ops.push(`q`);\n ops.push(`0.85 0.85 0.85 rg`);\n ops.push(`${x.toFixed(2)} ${pdfY.toFixed(2)} ${width.toFixed(2)} ${height.toFixed(2)} re f`);\n ops.push(`0.6 0.6 0.6 RG 1 w`);\n ops.push(`${x.toFixed(2)} ${pdfY.toFixed(2)} ${width.toFixed(2)} ${height.toFixed(2)} re S`);\n ops.push(\n `BT /F1 10 Tf 0.4 0.4 0.4 rg 1 0 0 1 ${(x + 8).toFixed(2)} ${(pdfY + height / 2 - 4).toFixed(2)} Tm (Image) Tj ET`,\n );\n ops.push(`Q`);\n }\n\n for (const child of box.children) {\n drawBox(child);\n }\n };\n\n for (const box of boxes) {\n drawBox(box);\n }\n\n return ops.join(\"\\n\");\n }\n}\n\nexport function serializePdf(doc: ResolvedDocument): Uint8Array {\n return new PdfWriter().build(doc);\n}\n","import type { ReactElement } from \"react\";\nimport { elementToPdfNode } from \"./reconciler\";\nimport { layoutDocument } from \"./layout\";\nimport { serializePdf } from \"./pdf-writer\";\n\nfunction renderToBytes(element: ReactElement): Uint8Array {\n const tree = elementToPdfNode(element);\n const laidOut = layoutDocument(tree);\n return serializePdf(laidOut);\n}\n\n/** Render a `<Document>` tree to a `Uint8Array` PDF. */\nexport function pdf(element: ReactElement): Uint8Array {\n return renderToBytes(element);\n}\n\n/** Render to a Blob (browser). */\nexport function toBlob(element: ReactElement): Blob {\n const bytes = renderToBytes(element);\n const copy = new Uint8Array(bytes.byteLength);\n copy.set(bytes);\n return new Blob([copy], { type: \"application/pdf\" });\n}\n\n/** Render to an object URL for iframes / previews. */\nexport function toUrl(element: ReactElement): string {\n return URL.createObjectURL(toBlob(element));\n}\n\n/** Trigger a browser download of the generated PDF. */\nexport function download(\n element: ReactElement,\n filename = \"document.pdf\",\n): void {\n const url = toUrl(element);\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.download = filename;\n anchor.click();\n URL.revokeObjectURL(url);\n}\n\n/** Async-friendly API mirroring common PDF libraries. */\nexport async function renderToBuffer(element: ReactElement): Promise<Uint8Array> {\n return renderToBytes(element);\n}\n\nexport async function renderToBlob(element: ReactElement): Promise<Blob> {\n return toBlob(element);\n}\n"],"names":["REDACT_COLOR","HIGHLIGHT_PRESETS","UNDERLINE_PRESETS","DEFAULT_HIGHLIGHT_HEX","DEFAULT_UNDERLINE_HEX","hexToMarkupColor","createMarkupId","normalizeHex","color","value","r","g","b","hex","kind","alpha","normalized","match","int","selectionRectsForPage","pageSurface","scale","selection","range","pageBox","clientRects","safeScale","layoutW","layoutH","selectionStartPoint","rects","first","a","expandRedactRects","padding","rect","drawMarkupOnCanvas","ctx","annotations","ann","x","y","w","h","thickness","createSignatureId","drawSignaturesOnCanvas","signatures","sig","img","loadImage","drawSignatureFieldsOnCanvas","fields","signedFieldIds","field","isFilled","src","resolve","reject","signatureDisplaySize","sourceWidth","sourceHeight","maxWidth","maxHeight","ratio","clientPointToPage","clientX","clientY","surface","box","pageSizeFromSurface","clientDeltaToPage","deltaX","deltaY","viewportRectToPage","viewport","surfaceRect","pageW","pageH","DEFAULT_TEXT_FONT_SIZE","DEFAULT_TEXT_COLOR","MIN_TEXT_WIDTH","MIN_TEXT_HEIGHT","createTextId","measureInlineText","fontSize","lines","lineHeight","line","resolveInlineTextPoint","textLayer","surfaceBox","toPageX","client","toPageY","toPageSize","clientSize","axis","boxSize","layout","gap","findGapBetweenSpans","doc","_a","inferFontSizeFromNode","caretX","nearest","findNearestSpanOnLine","spans","boxes","span","i","left","right","gapStart","gapEnd","best","midX","dist","node","element","inferFontSizeFromElement","height","computed","parsed","findTextFieldAtPoint","pageNumber","selectWordAtPoint","text","offset","isWordChar","ch","start","end","wordRange","drawTextsOnCanvas","texts","cursorY","drawTextFieldsOnCanvas","filledFieldIds","Icon","size","className","children","jsx","ChevronLeftIcon","props","ChevronRightIcon","DownloadIcon","jsxs","ExternalLinkIcon","GridIcon","MinusIcon","PlusIcon","PrinterIcon","RefreshIcon","RotateIcon","HighlightIcon","UnderlineIcon","EraserIcon","SignatureIcon","PencilIcon","TextIcon","PageCanvas","pdfDoc","rotation","pageRef","onRendered","markupTool","markupColor","onAddAnnotation","onRemoveAnnotation","pendingSignature","onAddSignature","onUpdateSignature","onRemoveSignature","onEditSignature","onDuplicateSignature","selectedSignatureId","onSelectSignature","signatureFields","selectedSignatureFieldId","onSelectSignatureField","hasFixedSignatureFields","onOpenSignaturePad","fieldValues","_onFieldValueChange","_onFieldValueCommit","pendingFieldValue","onPlaceFieldValue","onAddText","onUpdateText","onRemoveText","selectedTextId","onSelectText","textFields","_selectedTextFieldId","onSelectTextField","hasFixedTextFields","editingTextId","onEditingTextIdChange","wrapRef","useRef","canvasRef","textLayerRef","surfaceRef","renderTaskRef","textLayerInstanceRef","dragState","setDragState","useState","inlineEditRef","justOpenedEditorRef","useEffect","cancelled","canvas","textLayerDiv","page","width","task","textContent","TextLayer","applySelectionMarkup","captured","replaceSelectedPdfText","initialValue","created","handleMouseUp","handleKeyDown","event","target","hasPdfSelection","rafId","lastClientX","lastClientY","scrollDir","getScrollContainer","updateResizeAtPoint","s","pageSize","dx","dy","maxW","maxH","newW","newH","updateSignatureAtPoint","pageEl","targetPage","point","nextX","nextY","maxX","maxY","tickScroll","container","maxScroll","edge","distTop","distBottom","speed","prev","handleMove","handleUp","el","current","t","setRefs","pageAnnotations","pageSignatures","pageSignatureFields","f","pageTexts","commitInlineText","trimmed","beginInlineTextAt","fieldId","existing","handleInlineTextClick","handleSurfaceClick","renderInlineText","e","idx","fType","textValue","filled","Fragment","Thumbnail","isActive","onSelect","viewportAt1","pageTextFields","ABSOLUTE_URL_PATTERN","workerConfigured","setPdfWorkerSrc","workerSrc","pdfjsLib","ensurePdfWorker","resolvePdfUrl","file","fileUrl","baseUrl","source","path","urlToPdfArrayBuffer","url","fetchOptions","res","sourceToArrayBuffer","copy","renderPageWithMarkup","options","mimeType","quality","baseViewport","pageMarks","pageSigs","dataUrl","jpegBytes","dataUrlToBytes","renderAllPagesWithMarkup","pages","base64","binary","bytes","enc","concat","parts","total","sum","p","out","part","buildPdfFromJpegPages","objects","add","pageIds","imageStream","imageId","content","contentId","pageId","kids","id","pagesId","catalogId","chunks","offsets","objHeader","objFooter","xrefStart","xref","triggerBlobDownload","blob","filename","anchor","SVG_SAFE_FONTS","escapeXml","svgToBase64DataUrl","svg","chunk","typedSignatureFontSize","typeKind","SignaturePad","open","onClose","onSave","onSaveFieldValue","fieldType","showFieldTypeTabs","textPlaceholder","initialFieldValue","targetSize","rememberedByType","onRememberFill","drawingRef","lastPointRef","pathsRef","currentPathRef","reusedSignatureRef","resolvedFieldType","activeFieldType","setActiveFieldType","dateValue","setDateValue","setTextValue","mode","setMode","typedName","setTypedName","typedInitials","setTypedInitials","initialsTouched","setInitialsTouched","setTypeKind","inkColor","setInkColor","fontId","setFontId","hasReusedSignature","setHasReusedSignature","selectedFont","font","previewText","fontPreviewLabel","_b","remembered","nextFont","reused","getPoint","handlePointerDown","pt","handlePointerMove","last","handlePointerUp","clearPad","handleNameChange","deriveInitials","trimAndSave","allPaths","minX","minY","pad","pathData","boxW","boxH","drawnW","drawnH","ox","oy","baseSize","measureCtx","baseMetrics","basePad","naturalW","naturalH","fit","cx","cy","handleFieldValueSave","showSignPad","modalTitle","name","TOOLBAR_TOOL_ID","createToolbarTool","displayName","Tool","getToolbarToolId","tool","isToolbarTool","Navigation","Zoom","Rotate","Reload","Print","Open","Download","Highlight","Underline","Signature","AddText","Erase","Clear","ALL_TOOLBAR_TOOLS","DEFAULT_TOOLBAR_LAYOUT","MARKUP_TOOLS","isMarkupToolbarTool","renderToolbarTool","nodes","v","next","renderMarkupExtras","enabledIds","activeMarkupHex","setActiveMarkupHex","activePresets","preset","resolveToolbarLayout","enableToolbar","flags","toIds","side","showThumbnailsToggle","filterByFlag","tools","enabled","flagMap","PdfViewer","title","initialScale","withThumbnails","thumbnailWidth","maxThumbnails","enableThumbnails","enableNavigation","enableZoom","enableRotate","enableReload","enablePrint","enableOpen","enableDownload","enableMarkup","enableHighlight","enableUnderline","enableSignature","enableText","enableErase","enableClear","signatureFieldsProp","onSignatureComplete","onSignatureFieldsChange","applySignatureToSameTag","onFieldValueComplete","externalOpenSignaturePad","onSignaturePadClose","onSubmit","submitLabel","submitLoading","containerRef","lastBlobUrlRef","pageRefsRef","isProgrammaticScrollRef","binarySource","useMemo","resolvedUrl","status","setStatus","setPdfDoc","numPages","setNumPages","setPageNumber","setScale","setRotation","displayUrl","setDisplayUrl","showThumbnails","setShowThumbnails","isPrinting","setIsPrinting","isDownloading","setIsDownloading","setMarkupTool","setAnnotations","setSignatures","setTexts","signaturePadOpen","setSignaturePadOpen","signaturePadFieldType","setSignaturePadFieldType","setRememberedByType","setPendingSignature","setSelectedSignatureId","setSelectedSignatureFieldId","editingSignatureId","setEditingSignatureId","setSelectedTextId","selectedTextFieldId","setSelectedTextFieldId","setEditingTextId","highlightHex","setHighlightHex","underlineHex","setUnderlineHex","setFieldValues","setSignatureFields","signatureFieldsRef","isSignatureFieldFilled","useCallback","sigs","values","writeFieldValueToFields","fieldIds","idSet","prevValues","updated","writeSignatureImageToFields","signature","signaturesByFieldId","ids","toolbarSides","enabledToolIds","mq","apply","showHighlight","showUnderline","showSignature","showText","showErase","revokeDisplayUrl","loadDocument","buffer","blobUrl","scrollToPage","clamped","scrollToSignatureField","focusField","fieldEl","observer","entries","canGoPrev","canGoNext","handlePrev","handleNext","handleRotate","handleZoomOut","handleZoomIn","handleFitWidth","pagePadding","nextScale","run","onMq","fieldValueTexts","textsForExport","handlePrint","iframe","body","wrapper","handleDownload","pdfBytes","toggleMarkupTool","activeMarkupColor","selectedSignature","handleAddAnnotation","annotation","handleRemoveAnnotation","handleClearAnnotations","advanceToNextUnsignedField","fromFieldId","filledIds","currentIndex","nextField","handleOpenSignaturePad","handleFieldValueChange","handleFieldValueCommit","val","k","handleSignatureSave","imageDataUrl","targetField","targetFields","newSignatures","targetIds","byFieldId","currentPageEl","scrollContainer","visible","visibleTop","visibleBottom","visibleLeft","visibleRight","handleSaveFieldValue","nextValues","handleAddSignature","handleUpdateSignature","patch","handleRemoveSignature","removed","handleDuplicateSignature","pageWidth","pageHeight","duplicate","handleEditSignature","targetId","item","handleAddText","handleUpdateText","handleRemoveText","goToSignatureField","direction","from","nextIndex","rootStyle","toolbarCtx","visibleToolIds","currentFieldIndex","filledFieldCount","fieldProgressPercent","renderSide","alignEnd","index","showMarkupSep","type","fill","_","n","ThumbnailStrip","Document","_props","Page","View","Text","Image","Link","TYPE_MAP","getDisplayName","fn","flattenChildren","result","visit","collectText","child","elementToPdfNode","nodeType","childrenProp","childNodes","PAGE_SIZES","resolvePageSize","orientation","expandPadding","style","base","expandMargin","parseColor","input","raw","rgb","resolveLength","parent","fallback","pct","isBold","weight","DEFAULT_FONT_SIZE","DEFAULT_LINE_HEIGHT","AVG_CHAR_WIDTH","measureText","charWidth","words","word","candidate","widest","l","layoutNode","availableWidth","availableHeight","margin","outerX","outerY","contentWidth","innerWidth","measured","childBoxes","cursorX","usedMain","crossSize","remainingW","remainingH","contentHeight","finalWidth","justify","align","innerMain","freeSpace","mainOffset","betweenGap","running","layoutDocument","root","pageNode","contentRoot","escapePdfString","PdfWriter","__publicField","infoId","fontRegular","fontBold","contentStream","xrefOffset","pageStyle","ops","pageBg","drawBox","pdfY","border","paddingLeft","paddingTop","textX","lineWidth","textY","serializePdf","renderToBytes","tree","laidOut","pdf","toBlob","toUrl","download","renderToBuffer","renderToBlob"],"mappings":"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"}