epochs-pdf 0.1.1 → 0.1.3

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\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,\n 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 filled = 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 const fType = (field as any).type as string | undefined;\n if (fType === \"date\" || fType === \"text\") return;\n onSelectSignatureField?.(field.id);\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?.((field as any).type);\n }\n }}\n title={filled ? \"Signed field\" : \"Signature field\"}\n >\n {(() => {\n const fType = (field as any).type as string | undefined;\n if (fType === \"date\") {\n return (\n <input\n type=\"date\"\n className=\"epochs-pdf-viewer__signature-field-input\"\n value={fieldValues[field.id] ?? \"\"}\n onClick={(ev) => ev.stopPropagation()}\n onChange={(ev) => {\n ev.stopPropagation();\n onFieldValueChange?.(field.id, ev.target.value);\n onFieldValueCommit?.(field.id);\n }}\n style={{ width: \"100%\", height: \"100%\" }}\n />\n );\n }\n if (fType === \"text\") {\n return (\n <input\n type=\"text\"\n className=\"epochs-pdf-viewer__signature-field-input\"\n value={fieldValues[field.id] ?? \"\"}\n placeholder={(field as any).placeholder ?? \"Enter text\"}\n onClick={(ev) => ev.stopPropagation()}\n onChange={(ev) => {\n ev.stopPropagation();\n onFieldValueChange?.(field.id, ev.target.value);\n }}\n onBlur={() => onFieldValueCommit?.(field.id)}\n style={{ width: \"100%\", height: \"100%\" }}\n />\n );\n }\n return !filled ? <span>Sign here</span> : null;\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 /** 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}\n\ntype PadMode = \"draw\" | \"type\";\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;\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\nexport function SignaturePad({\n open,\n onClose,\n onSave,\n fieldType,\n showFieldTypeTabs = false,\n textPlaceholder,\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\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\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 setDateValue(new Date().toISOString().slice(0, 10));\n setTextValue(\"\");\n }, [open, resolvedFieldType]);\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 }, [open, activeFieldType]);\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 =\n typeKind === \"initials\"\n ? 72\n : selectedFont.family === \"Great Vibes\" || selectedFont.family === \"Allura\"\n ? 56\n : selectedFont.family === \"Pacifico\"\n ? 44\n : 48;\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 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 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 if (allPaths.length === 0) return;\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 onSave(dataUrl, w, h);\n } else {\n if (!previewText) return;\n\n const dpr = 3;\n const size =\n typeKind === \"initials\"\n ? 72\n : selectedFont.family === \"Great Vibes\" || selectedFont.family === \"Allura\"\n ? 56\n : selectedFont.family === \"Pacifico\"\n ? 44\n : 48;\n\n const measureCanvas = document.createElement(\"canvas\");\n const measureCtx = measureCanvas.getContext(\"2d\")!;\n measureCtx.font = `${size * dpr}px \"${selectedFont.family}\", cursive`;\n const metrics = measureCtx.measureText(previewText);\n const pad = 12 * dpr;\n const canvasW = Math.ceil(metrics.width) + pad * 2;\n const canvasH = size * dpr + pad * 2;\n\n const outCanvas = document.createElement(\"canvas\");\n outCanvas.width = canvasW;\n outCanvas.height = canvasH;\n const outCtx = outCanvas.getContext(\"2d\")!;\n outCtx.clearRect(0, 0, canvasW, canvasH);\n outCtx.font = `${size * dpr}px \"${selectedFont.family}\", cursive`;\n outCtx.fillStyle = inkColor;\n outCtx.textBaseline = \"middle\";\n outCtx.fillText(previewText, pad, canvasH / 2);\n\n const dataUrl = outCanvas.toDataURL(\"image/png\");\n onSave(dataUrl, canvasW / dpr, canvasH / dpr);\n }\n };\n\n const handleFieldValueSave = () => {\n const text =\n activeFieldType === \"date\" ? dateValue : textValue.trim();\n if (!text) return;\n\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\")!;\n const fontSize = 16;\n ctx.font = `${fontSize}px sans-serif`;\n const metrics = ctx.measureText(text);\n const pad = 8;\n canvas.width = Math.ceil(metrics.width) + pad * 2;\n canvas.height = fontSize + pad * 2;\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.font = `${fontSize}px sans-serif`;\n ctx.fillStyle = \"#111827\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(text, pad, canvas.height / 2);\n\n const dataUrl = canvas.toDataURL(\"image/png\");\n onSave(dataUrl, canvas.width, canvas.height);\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\">Draw your signature below</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 { SignatureAnnotation, SignatureField } from \"./signature\";\nimport { createSignatureId, signatureDisplaySize } from \"./signature\";\nimport { pageSizeFromSurface, viewportRectToPage } from \"./coords\";\nimport type { TextAnnotation } from \"./text\";\nimport {\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 = [],\n textFields = [],\n onSignatureComplete,\n onFieldValueComplete,\n openSignaturePad: externalOpenSignaturePad = false,\n onSignaturePadClose,\n onSubmit,\n submitLabel = \"Submit\",\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 [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 hasFixedSignatureFields = signatureFields.length > 0;\n const hasFixedTextFields = textFields.length > 0;\n const [fieldValues, setFieldValues] = useState<Record<string, string>>({});\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 = enabledToolIds.has(\"signature\");\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 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,\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, texts]);\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 || signatures.length > 0 || texts.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,\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, texts]);\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 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 const nextType = (nextField as any).type as string | undefined;\n if (nextType === \"sign\" || !nextType) {\n window.setTimeout(() => setSignaturePadOpen(true), 350);\n }\n }\n },\n [signatureFields, fieldValues, signatures, scrollToSignatureField],\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 !signatures.some((sig) => sig.fieldId === field.id),\n ) ??\n signatureFields.find(\n (field) => !signatures.some((sig) => sig.fieldId === field.id),\n );\n\n if (!targetField) {\n setSignaturePadOpen(false);\n return;\n }\n\n const signature: SignatureAnnotation = {\n id: createSignatureId(),\n fieldId: targetField.id,\n pageNumber: targetField.pageNumber,\n x: targetField.x,\n y: targetField.y,\n width: targetField.width,\n height: targetField.height,\n imageDataUrl,\n };\n\n setSignatures((prev) => [\n ...prev.filter((sig) => sig.fieldId !== targetField.id),\n signature,\n ]);\n onSignatureComplete?.(targetField.id, signature);\n setPendingSignature(null);\n setMarkupTool(\"none\");\n setSignaturePadOpen(false);\n setEditingSignatureId(null);\n\n const signedFieldIds = new Set(\n signatures\n .filter((sig) => sig.fieldId && sig.fieldId !== targetField.id)\n .map((sig) => sig.fieldId as string),\n );\n signedFieldIds.add(targetField.id);\n\n const currentIndex = signatureFields.findIndex(\n (field) => field.id === targetField.id,\n );\n const nextField =\n signatureFields\n .slice(currentIndex + 1)\n .find((field) => !signedFieldIds.has(field.id)) ??\n signatureFields\n .slice(0, Math.max(0, currentIndex))\n .find((field) => !signedFieldIds.has(field.id));\n\n if (nextField) {\n setSelectedSignatureFieldId(nextField.id);\n setSelectedSignatureId(null);\n scrollToSignatureField(nextField);\n window.setTimeout(() => {\n setSignaturePadOpen(true);\n }, 350);\n } else {\n setSelectedSignatureId(signature.id);\n setSelectedSignatureFieldId(targetField.id);\n }\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 onSignatureComplete?.(undefined, signature);\n setSelectedSignatureId(signature.id);\n setPendingSignature(null);\n setMarkupTool(\"none\");\n setSignaturePadOpen(false);\n setEditingSignatureId(null);\n },\n [\n editingSignatureId,\n hasFixedSignatureFields,\n pageNumber,\n scale,\n scrollToSignatureField,\n selectedSignatureFieldId,\n signatureFields,\n signatures,\n onSignatureComplete,\n ],\n );\n\n const handleAddSignature = useCallback((signature: SignatureAnnotation) => {\n setSignatures((prev) => [...prev, signature]);\n setSelectedSignatureId(signature.id);\n setPendingSignature(null);\n setMarkupTool(\"none\");\n }, []);\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 setSelectedSignatureId(targetId);\n setEditingSignatureId(targetId);\n setSignaturePadOpen(true);\n }, [selectedSignature]);\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 const fieldType = field.type ?? \"sign\";\n if (fieldType === \"date\" || fieldType === \"text\") {\n return Boolean(fieldValues[field.id]?.trim());\n }\n return signatures.some((sig) => sig.fieldId === field.id);\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) ? (\n <SignaturePad\n open={signaturePadOpen}\n onClose={() => {\n setSignaturePadOpen(false);\n setEditingSignatureId(null);\n onSignaturePadClose?.();\n }}\n onSave={handleSignatureSave}\n fieldType={signaturePadFieldType}\n showFieldTypeTabs={!hasFixedSignatureFields}\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={texts}\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 >\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","filled","fType","ev","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","ensureHandwritingFonts","link","loadFaces","font","SignaturePad","open","onClose","onSave","fieldType","showFieldTypeTabs","textPlaceholder","drawingRef","lastPointRef","pathsRef","currentPathRef","resolvedFieldType","activeFieldType","setActiveFieldType","dateValue","setDateValue","textValue","setTextValue","mode","setMode","typedName","setTypedName","typedInitials","setTypedInitials","initialsTouched","setInitialsTouched","typeKind","setTypeKind","inkColor","setInkColor","fontId","setFontId","fontsReady","setFontsReady","selectedFont","previewText","fontPreviewLabel","getPoint","handlePointerDown","pt","handlePointerMove","last","handlePointerUp","clearPad","handleNameChange","deriveInitials","trimAndSave","allPaths","minX","minY","pad","pathData","svg","dpr","measureCtx","metrics","canvasW","canvasH","outCanvas","outCtx","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","onSignatureComplete","onFieldValueComplete","externalOpenSignaturePad","onSignaturePadClose","onSubmit","submitLabel","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","setPendingSignature","setSelectedSignatureId","setSelectedSignatureFieldId","editingSignatureId","setEditingSignatureId","setSelectedTextId","selectedTextFieldId","setSelectedTextFieldId","setEditingTextId","highlightHex","setHighlightHex","underlineHex","setUnderlineHex","setFieldValues","toolbarSides","enabledToolIds","mq","apply","showHighlight","showUnderline","showSignature","showText","showErase","revokeDisplayUrl","useCallback","loadDocument","buffer","blobUrl","scrollToPage","clamped","scrollToSignatureField","focusField","fieldEl","observer","entries","canGoPrev","canGoNext","handlePrev","handleNext","handleRotate","handleZoomOut","handleZoomIn","handleFitWidth","pagePadding","nextScale","run","onMq","handlePrint","iframe","body","wrapper","_b","handleDownload","pdfBytes","toggleMarkupTool","activeMarkupColor","selectedSignature","handleAddAnnotation","annotation","handleRemoveAnnotation","handleClearAnnotations","handleOpenSignaturePad","handleFieldValueChange","handleFieldValueCommit","val","currentIndex","filledIds","k","nextField","nextType","handleSignatureSave","imageDataUrl","targetField","signature","currentPageEl","scrollContainer","visible","visibleTop","visibleBottom","visibleLeft","visibleRight","handleAddSignature","handleUpdateSignature","patch","handleRemoveSignature","removed","handleDuplicateSignature","pageWidth","pageHeight","duplicate","handleEditSignature","targetId","handleAddText","item","handleUpdateText","handleRemoveText","goToSignatureField","direction","from","nextIndex","rootStyle","toolbarCtx","visibleToolIds","ids","currentFieldIndex","filledFieldCount","fieldProgressPercent","renderSide","alignEnd","index","showMarkupSep","_","n","ThumbnailStrip","Document","_props","Page","View","Text","Image","Link","TYPE_MAP","getDisplayName","type","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","fill","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\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,\n 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 filled = 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 const fType = (field as any).type as string | undefined;\n if (fType === \"date\" || fType === \"text\") return;\n onSelectSignatureField?.(field.id);\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?.((field as any).type);\n }\n }}\n title={filled ? \"Signed field\" : \"Signature field\"}\n >\n {(() => {\n const fType = (field as any).type as string | undefined;\n if (fType === \"date\") {\n return (\n <input\n type=\"date\"\n className=\"epochs-pdf-viewer__signature-field-input\"\n value={fieldValues[field.id] ?? \"\"}\n onClick={(ev) => ev.stopPropagation()}\n onChange={(ev) => {\n ev.stopPropagation();\n onFieldValueChange?.(field.id, ev.target.value);\n onFieldValueCommit?.(field.id);\n }}\n style={{ width: \"100%\", height: \"100%\" }}\n />\n );\n }\n if (fType === \"text\") {\n return (\n <input\n type=\"text\"\n className=\"epochs-pdf-viewer__signature-field-input\"\n value={fieldValues[field.id] ?? \"\"}\n placeholder={(field as any).placeholder ?? \"Enter text\"}\n onClick={(ev) => ev.stopPropagation()}\n onChange={(ev) => {\n ev.stopPropagation();\n onFieldValueChange?.(field.id, ev.target.value);\n }}\n onBlur={() => onFieldValueCommit?.(field.id)}\n style={{ width: \"100%\", height: \"100%\" }}\n />\n );\n }\n return !filled ? <span>Sign here</span> : null;\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 /** 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}\n\ntype PadMode = \"draw\" | \"type\";\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;\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\nexport function SignaturePad({\n open,\n onClose,\n onSave,\n fieldType,\n showFieldTypeTabs = false,\n textPlaceholder,\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\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\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 setDateValue(new Date().toISOString().slice(0, 10));\n setTextValue(\"\");\n }, [open, resolvedFieldType]);\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 }, [open, activeFieldType]);\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 =\n typeKind === \"initials\"\n ? 72\n : selectedFont.family === \"Great Vibes\" || selectedFont.family === \"Allura\"\n ? 56\n : selectedFont.family === \"Pacifico\"\n ? 44\n : 48;\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 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 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 if (allPaths.length === 0) return;\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 onSave(dataUrl, w, h);\n } else {\n if (!previewText) return;\n\n const dpr = 3;\n const size =\n typeKind === \"initials\"\n ? 72\n : selectedFont.family === \"Great Vibes\" || selectedFont.family === \"Allura\"\n ? 56\n : selectedFont.family === \"Pacifico\"\n ? 44\n : 48;\n\n const measureCanvas = document.createElement(\"canvas\");\n const measureCtx = measureCanvas.getContext(\"2d\")!;\n measureCtx.font = `${size * dpr}px \"${selectedFont.family}\", cursive`;\n const metrics = measureCtx.measureText(previewText);\n const pad = 12 * dpr;\n const canvasW = Math.ceil(metrics.width) + pad * 2;\n const canvasH = size * dpr + pad * 2;\n\n const outCanvas = document.createElement(\"canvas\");\n outCanvas.width = canvasW;\n outCanvas.height = canvasH;\n const outCtx = outCanvas.getContext(\"2d\")!;\n outCtx.clearRect(0, 0, canvasW, canvasH);\n outCtx.font = `${size * dpr}px \"${selectedFont.family}\", cursive`;\n outCtx.fillStyle = inkColor;\n outCtx.textBaseline = \"middle\";\n outCtx.fillText(previewText, pad, canvasH / 2);\n\n const dataUrl = outCanvas.toDataURL(\"image/png\");\n onSave(dataUrl, canvasW / dpr, canvasH / dpr);\n }\n };\n\n const handleFieldValueSave = () => {\n const text =\n activeFieldType === \"date\" ? dateValue : textValue.trim();\n if (!text) return;\n\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\")!;\n const fontSize = 16;\n ctx.font = `${fontSize}px sans-serif`;\n const metrics = ctx.measureText(text);\n const pad = 8;\n canvas.width = Math.ceil(metrics.width) + pad * 2;\n canvas.height = fontSize + pad * 2;\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.font = `${fontSize}px sans-serif`;\n ctx.fillStyle = \"#111827\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(text, pad, canvas.height / 2);\n\n const dataUrl = canvas.toDataURL(\"image/png\");\n onSave(dataUrl, canvas.width, canvas.height);\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\">Draw your signature below</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 { SignatureAnnotation, SignatureField } from \"./signature\";\nimport { createSignatureId, signatureDisplaySize } from \"./signature\";\nimport { pageSizeFromSurface, viewportRectToPage } from \"./coords\";\nimport type { TextAnnotation } from \"./text\";\nimport {\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 = [],\n textFields = [],\n onSignatureComplete,\n onFieldValueComplete,\n openSignaturePad: externalOpenSignaturePad = false,\n onSignaturePadClose,\n onSubmit,\n submitLabel = \"Submit\",\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 [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 hasFixedSignatureFields = signatureFields.length > 0;\n const hasFixedTextFields = textFields.length > 0;\n const [fieldValues, setFieldValues] = useState<Record<string, string>>({});\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 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,\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, texts]);\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 || signatures.length > 0 || texts.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,\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, texts]);\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 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 const nextType = (nextField as any).type as string | undefined;\n if (nextType === \"sign\" || !nextType) {\n window.setTimeout(() => setSignaturePadOpen(true), 350);\n }\n }\n },\n [signatureFields, fieldValues, signatures, scrollToSignatureField],\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 !signatures.some((sig) => sig.fieldId === field.id),\n ) ??\n signatureFields.find(\n (field) => !signatures.some((sig) => sig.fieldId === field.id),\n );\n\n if (!targetField) {\n setSignaturePadOpen(false);\n return;\n }\n\n const signature: SignatureAnnotation = {\n id: createSignatureId(),\n fieldId: targetField.id,\n pageNumber: targetField.pageNumber,\n x: targetField.x,\n y: targetField.y,\n width: targetField.width,\n height: targetField.height,\n imageDataUrl,\n };\n\n setSignatures((prev) => [\n ...prev.filter((sig) => sig.fieldId !== targetField.id),\n signature,\n ]);\n onSignatureComplete?.(targetField.id, signature);\n setPendingSignature(null);\n setMarkupTool(\"none\");\n setSignaturePadOpen(false);\n setEditingSignatureId(null);\n\n const signedFieldIds = new Set(\n signatures\n .filter((sig) => sig.fieldId && sig.fieldId !== targetField.id)\n .map((sig) => sig.fieldId as string),\n );\n signedFieldIds.add(targetField.id);\n\n const currentIndex = signatureFields.findIndex(\n (field) => field.id === targetField.id,\n );\n const nextField =\n signatureFields\n .slice(currentIndex + 1)\n .find((field) => !signedFieldIds.has(field.id)) ??\n signatureFields\n .slice(0, Math.max(0, currentIndex))\n .find((field) => !signedFieldIds.has(field.id));\n\n if (nextField) {\n setSelectedSignatureFieldId(nextField.id);\n setSelectedSignatureId(null);\n scrollToSignatureField(nextField);\n window.setTimeout(() => {\n setSignaturePadOpen(true);\n }, 350);\n } else {\n setSelectedSignatureId(signature.id);\n setSelectedSignatureFieldId(targetField.id);\n }\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 onSignatureComplete?.(undefined, signature);\n setSelectedSignatureId(signature.id);\n setPendingSignature(null);\n setMarkupTool(\"none\");\n setSignaturePadOpen(false);\n setEditingSignatureId(null);\n },\n [\n editingSignatureId,\n hasFixedSignatureFields,\n pageNumber,\n scale,\n scrollToSignatureField,\n selectedSignatureFieldId,\n signatureFields,\n signatures,\n onSignatureComplete,\n ],\n );\n\n const handleAddSignature = useCallback((signature: SignatureAnnotation) => {\n setSignatures((prev) => [...prev, signature]);\n setSelectedSignatureId(signature.id);\n setPendingSignature(null);\n setMarkupTool(\"none\");\n }, []);\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 setSelectedSignatureId(targetId);\n setEditingSignatureId(targetId);\n setSignaturePadOpen(true);\n }, [selectedSignature]);\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 const fieldType = field.type ?? \"sign\";\n if (fieldType === \"date\" || fieldType === \"text\") {\n return Boolean(fieldValues[field.id]?.trim());\n }\n return signatures.some((sig) => sig.fieldId === field.id);\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 onSignaturePadClose?.();\n }}\n onSave={handleSignatureSave}\n fieldType={signaturePadFieldType}\n showFieldTypeTabs={!hasFixedSignatureFields}\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={texts}\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 >\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","filled","fType","ev","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","ensureHandwritingFonts","link","loadFaces","font","SignaturePad","open","onClose","onSave","fieldType","showFieldTypeTabs","textPlaceholder","drawingRef","lastPointRef","pathsRef","currentPathRef","resolvedFieldType","activeFieldType","setActiveFieldType","dateValue","setDateValue","textValue","setTextValue","mode","setMode","typedName","setTypedName","typedInitials","setTypedInitials","initialsTouched","setInitialsTouched","typeKind","setTypeKind","inkColor","setInkColor","fontId","setFontId","fontsReady","setFontsReady","selectedFont","previewText","fontPreviewLabel","getPoint","handlePointerDown","pt","handlePointerMove","last","handlePointerUp","clearPad","handleNameChange","deriveInitials","trimAndSave","allPaths","minX","minY","pad","pathData","svg","dpr","measureCtx","metrics","canvasW","canvasH","outCanvas","outCtx","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","onSignatureComplete","onFieldValueComplete","externalOpenSignaturePad","onSignaturePadClose","onSubmit","submitLabel","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","setPendingSignature","setSelectedSignatureId","setSelectedSignatureFieldId","editingSignatureId","setEditingSignatureId","setSelectedTextId","selectedTextFieldId","setSelectedTextFieldId","setEditingTextId","highlightHex","setHighlightHex","underlineHex","setUnderlineHex","setFieldValues","toolbarSides","enabledToolIds","mq","apply","showHighlight","showUnderline","showSignature","showText","showErase","revokeDisplayUrl","useCallback","loadDocument","buffer","blobUrl","scrollToPage","clamped","scrollToSignatureField","focusField","fieldEl","observer","entries","canGoPrev","canGoNext","handlePrev","handleNext","handleRotate","handleZoomOut","handleZoomIn","handleFitWidth","pagePadding","nextScale","run","onMq","handlePrint","iframe","body","wrapper","_b","handleDownload","pdfBytes","toggleMarkupTool","activeMarkupColor","selectedSignature","handleAddAnnotation","annotation","handleRemoveAnnotation","handleClearAnnotations","handleOpenSignaturePad","handleFieldValueChange","handleFieldValueCommit","val","currentIndex","filledIds","k","nextField","nextType","handleSignatureSave","imageDataUrl","targetField","signature","currentPageEl","scrollContainer","visible","visibleTop","visibleBottom","visibleLeft","visibleRight","handleAddSignature","handleUpdateSignature","patch","handleRemoveSignature","removed","handleDuplicateSignature","pageWidth","pageHeight","duplicate","handleEditSignature","targetId","handleAddText","item","handleUpdateText","handleRemoveText","goToSignatureField","direction","from","nextIndex","rootStyle","toolbarCtx","visibleToolIds","ids","currentFieldIndex","filledFieldCount","fieldProgressPercent","renderSide","alignEnd","index","showMarkupSep","_","n","ThumbnailStrip","Document","_props","Page","View","Text","Image","Link","TYPE_MAP","getDisplayName","type","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","fill","border","paddingLeft","paddingTop","textX","lineWidth","textY","serializePdf","renderToBytes","tree","laidOut","pdf","toBlob","toUrl","download","renderToBuffer","renderToBlob"],"mappings":"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"}