efficient-shell 4.127.0 → 4.131.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +926 -5
- package/dist/{Browser-F5TKMP4K.js → Browser-PSEMJFZE.js} +13 -10
- package/dist/Browser-PSEMJFZE.js.map +1 -0
- package/dist/{Calculator-T3XG7S73.js → Calculator-ZXJPXG7F.js} +12 -9
- package/dist/Calculator-ZXJPXG7F.js.map +1 -0
- package/dist/ConfirmDialog-MTC7QMUJ.js +4 -0
- package/dist/{ConfirmDialog-LJXMB45A.js.map → ConfirmDialog-MTC7QMUJ.js.map} +1 -1
- package/dist/{CurrencyConverter-CASQMKLO.js → CurrencyConverter-WSJ2BBSX.js} +12 -9
- package/dist/CurrencyConverter-WSJ2BBSX.js.map +1 -0
- package/dist/{Documents-YX67YTZS.js → Documents-PGMZR2MA.js} +14 -11
- package/dist/Documents-PGMZR2MA.js.map +1 -0
- package/dist/{Files-QB63GO6J.js → Files-2LKCJGYW.js} +17 -14
- package/dist/Files-2LKCJGYW.js.map +1 -0
- package/dist/{Notepad-3SUD5XUE.js → Notepad-KW6WVABH.js} +15 -12
- package/dist/Notepad-KW6WVABH.js.map +1 -0
- package/dist/PdfViewer-M2YGZIYX.js +5 -0
- package/dist/{PdfViewer-LSP3YNFC.js.map → PdfViewer-M2YGZIYX.js.map} +1 -1
- package/dist/{PomodoroTimer-4EHD2QC4.js → PomodoroTimer-DG3LI5CX.js} +14 -11
- package/dist/PomodoroTimer-DG3LI5CX.js.map +1 -0
- package/dist/{Preview-4ZHR4SKP.js → Preview-E7EJJNXN.js} +16 -13
- package/dist/Preview-E7EJJNXN.js.map +1 -0
- package/dist/{Sidebar-J76PV4QF.js → Sidebar-BPU7RCZP.js} +5 -4
- package/dist/Sidebar-BPU7RCZP.js.map +1 -0
- package/dist/{Spreadsheet-G3SC7XJ5.js → Spreadsheet-IDUODRZU.js} +14 -11
- package/dist/Spreadsheet-IDUODRZU.js.map +1 -0
- package/dist/{Stock-TLT4VN2R.js → Stock-YMPOMUAW.js} +12 -9
- package/dist/Stock-YMPOMUAW.js.map +1 -0
- package/dist/{Weather-FRKX3DAK.js → Weather-NZO3CWLH.js} +12 -9
- package/dist/Weather-NZO3CWLH.js.map +1 -0
- package/dist/{WorldClock-GKCITO3M.js → WorldClock-HUC6D3AD.js} +12 -9
- package/dist/WorldClock-HUC6D3AD.js.map +1 -0
- package/dist/apps/index.js +26 -22
- package/dist/apps/index.js.map +1 -1
- package/dist/brand.css +1 -1
- package/dist/{chunk-XUCIYMN7.js → chunk-2GZQ352J.js} +4 -4
- package/dist/{chunk-XUCIYMN7.js.map → chunk-2GZQ352J.js.map} +1 -1
- package/dist/chunk-7IN7YZAL.js +547 -0
- package/dist/chunk-7IN7YZAL.js.map +1 -0
- package/dist/{chunk-YNGPTOL6.js → chunk-7MA5XBWD.js} +3 -3
- package/dist/{chunk-YNGPTOL6.js.map → chunk-7MA5XBWD.js.map} +1 -1
- package/dist/{chunk-WK7FV7VV.js → chunk-BJ34QOR3.js} +827 -625
- package/dist/chunk-BJ34QOR3.js.map +1 -0
- package/dist/{chunk-HNH7FOYB.js → chunk-CGXMWHQW.js} +7 -6
- package/dist/chunk-CGXMWHQW.js.map +1 -0
- package/dist/{chunk-N3CG5HG5.js → chunk-CLGNTGC5.js} +12 -11
- package/dist/chunk-CLGNTGC5.js.map +1 -0
- package/dist/chunk-D276EMXS.js +57 -0
- package/dist/chunk-D276EMXS.js.map +1 -0
- package/dist/{chunk-7KIOEKHS.js → chunk-E3TWIN7Z.js} +21 -135
- package/dist/chunk-E3TWIN7Z.js.map +1 -0
- package/dist/{chunk-2VM2FRZJ.js → chunk-EENVXIVU.js} +47 -67
- package/dist/chunk-EENVXIVU.js.map +1 -0
- package/dist/{chunk-YG45DAUT.js → chunk-FONEQRBH.js} +17 -11
- package/dist/chunk-FONEQRBH.js.map +1 -0
- package/dist/chunk-IPXN646P.js +14 -0
- package/dist/chunk-IPXN646P.js.map +1 -0
- package/dist/chunk-IRWSRJ4K.js +48 -0
- package/dist/chunk-IRWSRJ4K.js.map +1 -0
- package/dist/{chunk-JFQGPY7W.js → chunk-KWEX4ZAF.js} +20 -17
- package/dist/chunk-KWEX4ZAF.js.map +1 -0
- package/dist/{chunk-OKEFO6TI.js → chunk-LQTVTOSY.js} +10 -10
- package/dist/chunk-LQTVTOSY.js.map +1 -0
- package/dist/{chunk-G4KA3SAX.js → chunk-MQPX6ERJ.js} +4 -4
- package/dist/{chunk-G4KA3SAX.js.map → chunk-MQPX6ERJ.js.map} +1 -1
- package/dist/{chunk-FQB24B42.js → chunk-SEWF4O3H.js} +3 -3
- package/dist/{chunk-FQB24B42.js.map → chunk-SEWF4O3H.js.map} +1 -1
- package/dist/{chunk-AXWC3332.js → chunk-TFXJRHJV.js} +3 -3
- package/dist/{chunk-AXWC3332.js.map → chunk-TFXJRHJV.js.map} +1 -1
- package/dist/{chunk-G3HQLQYZ.js → chunk-TQURTLK2.js} +59 -34
- package/dist/chunk-TQURTLK2.js.map +1 -0
- package/dist/{chunk-6XQHH7D2.js → chunk-TRCWINHF.js} +5 -5
- package/dist/{chunk-6XQHH7D2.js.map → chunk-TRCWINHF.js.map} +1 -1
- package/dist/chunk-UHPWZ2F4.js +7 -0
- package/dist/{chunk-CJZXR7MG.js.map → chunk-UHPWZ2F4.js.map} +1 -1
- package/dist/{chunk-NPJCMM6V.js → chunk-VWZIGZFF.js} +4 -4
- package/dist/{chunk-NPJCMM6V.js.map → chunk-VWZIGZFF.js.map} +1 -1
- package/dist/{chunk-HYZ5QMVO.js → chunk-XH3ELPQZ.js} +22 -19
- package/dist/chunk-XH3ELPQZ.js.map +1 -0
- package/dist/{chunk-PPUZJFCI.js → chunk-ZKHD4J73.js} +8 -7
- package/dist/chunk-ZKHD4J73.js.map +1 -0
- package/dist/file-intake/index.js +3 -1
- package/dist/file-intake/index.js.map +1 -1
- package/dist/{index-dQia6NpB.d.ts → index-COwksV6G.d.ts} +699 -199
- package/dist/index.d.ts +2 -2
- package/dist/index.js +37 -32
- package/dist/index.js.map +1 -1
- package/dist/map/index.js +5 -3
- package/dist/map/index.js.map +1 -1
- package/dist/markdown/index.js +4 -3
- package/dist/markdown/index.js.map +1 -1
- package/dist/page-tabs/index.js +12 -8
- package/dist/page-tabs/index.js.map +1 -1
- package/dist/shell.css +17 -17
- package/dist/themes.css +15 -0
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +17 -13
- package/dist/ui/index.js.map +1 -1
- package/dist/ui.css +673 -283
- package/package.json +1 -1
- package/dist/Browser-F5TKMP4K.js.map +0 -1
- package/dist/Calculator-T3XG7S73.js.map +0 -1
- package/dist/ConfirmDialog-LJXMB45A.js +0 -3
- package/dist/CurrencyConverter-CASQMKLO.js.map +0 -1
- package/dist/Documents-YX67YTZS.js.map +0 -1
- package/dist/Files-QB63GO6J.js.map +0 -1
- package/dist/Notepad-3SUD5XUE.js.map +0 -1
- package/dist/PdfViewer-LSP3YNFC.js +0 -4
- package/dist/PomodoroTimer-4EHD2QC4.js.map +0 -1
- package/dist/Preview-4ZHR4SKP.js.map +0 -1
- package/dist/Sidebar-J76PV4QF.js.map +0 -1
- package/dist/Spreadsheet-G3SC7XJ5.js.map +0 -1
- package/dist/Stock-TLT4VN2R.js.map +0 -1
- package/dist/Weather-FRKX3DAK.js.map +0 -1
- package/dist/WorldClock-GKCITO3M.js.map +0 -1
- package/dist/chunk-2VM2FRZJ.js.map +0 -1
- package/dist/chunk-3CUSBZWG.js +0 -59
- package/dist/chunk-3CUSBZWG.js.map +0 -1
- package/dist/chunk-7KIOEKHS.js.map +0 -1
- package/dist/chunk-CJZXR7MG.js +0 -7
- package/dist/chunk-G3HQLQYZ.js.map +0 -1
- package/dist/chunk-HNH7FOYB.js.map +0 -1
- package/dist/chunk-HYZ5QMVO.js.map +0 -1
- package/dist/chunk-JFQGPY7W.js.map +0 -1
- package/dist/chunk-N3CG5HG5.js.map +0 -1
- package/dist/chunk-OKEFO6TI.js.map +0 -1
- package/dist/chunk-PPUZJFCI.js.map +0 -1
- package/dist/chunk-WK7FV7VV.js.map +0 -1
- package/dist/chunk-YG45DAUT.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shell/EditableGrid.tsx"],"names":[],"mappings":"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","file":"chunk-KWEX4ZAF.js","sourcesContent":["import { useState, useRef, useCallback, useEffect, useMemo } from 'react';\nimport type { HTMLAttributes } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useBrowserLayoutEffect } from './hydration';\nimport { escapeHtml } from '../utils/escapeHtml';\nimport { useShellStrings } from './strings';\n\nexport interface GridColumn {\n key: string;\n title: string;\n width?: number;\n readOnly?: boolean;\n align?: 'left' | 'right' | 'center';\n}\n\nexport type CellStyle = {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n fontSize?: 'sm' | 'base' | 'lg' | 'xl';\n};\n\nexport interface EditableGridProps {\n columns: GridColumn[];\n data: string[][];\n onChange: (data: string[][]) => void;\n onColumnsChange?: (columns: GridColumn[]) => void;\n /** Fixed row count — disables add/delete rows */\n fixedRows?: boolean;\n minRows?: number;\n maxHeight?: string;\n /** Per-cell text styling, keyed by `${row}:${col}`. */\n cellStyles?: Record<string, CellStyle>;\n /** Notifies the parent when the focused/edited cell changes. */\n onFocusChange?: (pos: { row: number; col: number } | null) => void;\n /** Notifies the parent when the selection rectangle changes. */\n onSelectionChange?: (sel: { anchor: { row: number; col: number }; end: { row: number; col: number } } | null) => void;\n}\n\ninterface CellPos { row: number; col: number }\n\nfunction rangeContains(anchor: CellPos, end: CellPos, row: number, col: number): boolean {\n const r1 = Math.min(anchor.row, end.row), r2 = Math.max(anchor.row, end.row);\n const c1 = Math.min(anchor.col, end.col), c2 = Math.max(anchor.col, end.col);\n return row >= r1 && row <= r2 && col >= c1 && col <= c2;\n}\n\n/**\n * `rows` with one blank row under it when the last row has content, so there is\n * always a line left to click into.\n *\n * Typing has had this since the beginning — `ensureRows` grows the grid as the\n * cursor nears the bottom. Paste never did: 16 lines into a 15-line grid landed\n * as exactly 16 rows, and the operator with a second batch to paste had nowhere\n * to put it. Returns a new array rather than pushing into the caller's, so the\n * paste handlers' selection maths still sees the pasted block's own length.\n */\nexport function withSpareRow(rows: string[][], colCount: number): string[][] {\n const last = rows[rows.length - 1];\n if (last && !last.some(cell => cell.trim())) return rows;\n return [...rows, Array(colCount).fill('')];\n}\n\n/**\n * A cell's editable node, whose text is written into the DOM only when the\n * text itself changes.\n *\n * The node is `contentEditable`, so while a cell is being typed into the DOM\n * holds keys the grid has not committed yet (they commit on blur). React 19\n * decides whether to rewrite `dangerouslySetInnerHTML` by comparing the prop\n * OBJECT, not its `__html` (React 18 compared the string), so a fresh\n * `{ __html }` on every render made any re-render of the grid wipe those keys\n * and put the caret back at the start: typing 100 into a production-progress\n * cell saved 001 once the form's debounced check re-rendered it. Holding the\n * object steady per value restores the React 18 behaviour on both versions.\n */\nfunction CellText({ text, ...props }: Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'dangerouslySetInnerHTML'> & { text: string }) {\n // Escaped, NOT raw: a cell can hold text this grid never authored — a CSV\n // export of storefront form answers is typed by anonymous visitors. Every\n // read path takes `textContent`, so nothing here wants markup, and escaping\n // round-trips through `textContent` unchanged.\n const html = useMemo(() => ({ __html: escapeHtml(text) }), [text]);\n return <div {...props} dangerouslySetInnerHTML={html} />;\n}\n\n/**\n * Lightweight editable grid with spreadsheet-like features:\n * - Click + drag to select a range of cells\n * - Ctrl+C / Cmd+C to copy selection as tab-delimited text\n * - Multi-cell paste from spreadsheets (Ctrl+V)\n * - Tab/Enter/Arrow keyboard navigation\n */\nexport default function EditableGrid({ columns, data, onChange, onColumnsChange, fixedRows = false, minRows = 15, maxHeight = '260px', cellStyles, onFocusChange, onSelectionChange }: EditableGridProps) {\n const tableRef = useRef<HTMLTableElement>(null);\n const strings = useShellStrings().grid;\n const [focus, setFocus] = useState<CellPos | null>(null);\n useEffect(() => { onFocusChange?.(focus); }, [focus, onFocusChange]);\n\n // Column resize state\n const [colWidths, setColWidths] = useState<Record<number, number>>({});\n const resizing = useRef<{ col: number; startX: number; startW: number } | null>(null);\n\n // Row resize state\n const [rowHeights, setRowHeights] = useState<Record<number, number>>({});\n const rowResizing = useRef<{ row: number; startY: number; startH: number } | null>(null);\n\n // Drag reorder state\n const [dragRow, setDragRow] = useState<number | null>(null);\n const [dragOverRow, setDragOverRow] = useState<number | null>(null);\n const [dragCol, setDragCol] = useState<number | null>(null);\n const [dragOverCol, setDragOverCol] = useState<number | null>(null);\n const [editingCell, setEditingCell] = useState<CellPos | null>(null);\n\n // A printable key on a cell that is not being edited commits that key and\n // opens the cell for editing; the caret then has to move past it before the\n // NEXT key lands. A layout effect runs in the same commit, ahead of the next\n // key event. A requestAnimationFrame (the old way) waited for a frame, so a\n // quick second key went in before the first — and never, in a hidden tab.\n const caretToEnd = useRef<CellPos | null>(null);\n useBrowserLayoutEffect(() => {\n const pos = caretToEnd.current;\n if (!pos || pos.row !== editingCell?.row || pos.col !== editingCell?.col) return;\n caretToEnd.current = null;\n const el = tableRef.current?.querySelector<HTMLElement>(`[data-row=\"${pos.row}\"][data-col=\"${pos.col}\"]`);\n if (!el) return;\n el.focus();\n const range = document.createRange();\n range.selectNodeContents(el);\n range.collapse(false);\n const sel = window.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(range);\n }, [editingCell]);\n\n // Range selection state\n const [selAnchor, setSelAnchor] = useState<CellPos | null>(null);\n const [selEnd, setSelEnd] = useState<CellPos | null>(null);\n useEffect(() => {\n onSelectionChange?.(selAnchor && selEnd ? { anchor: selAnchor, end: selEnd } : null);\n }, [selAnchor, selEnd, onSelectionChange]);\n const dragging = useRef(false);\n\n // Fill handle state\n const [fillTarget, setFillTarget] = useState<CellPos | null>(null);\n const filling = useRef(false);\n const selRefForFill = useRef<{ a: CellPos | null; e: CellPos | null }>({ a: null, e: null });\n selRefForFill.current = { a: selAnchor, e: selEnd };\n\n const hasRange = selAnchor && selEnd && (selAnchor.row !== selEnd.row || selAnchor.col !== selEnd.col);\n\n // Ensure minimum rows\n const rows = [...data];\n if (!fixedRows) {\n while (rows.length < minRows) rows.push(Array(columns.length).fill(''));\n }\n\n const updateCell = useCallback((row: number, col: number, value: string) => {\n const next = rows.map(r => [...r]);\n while (next.length <= row) next.push(Array(columns.length).fill(''));\n while (next[row].length < columns.length) next[row].push('');\n next[row][col] = value;\n onChange(next);\n }, [rows, columns.length, onChange]);\n\n // Mouse drag selection\n const handleMouseDown = useCallback((e: React.MouseEvent, row: number, col: number) => {\n if (e.button !== 0) return;\n // Commit the currently focused cell's value before moving\n const active = document.activeElement as HTMLElement;\n if (active?.dataset?.row && active?.dataset?.col) {\n const ar = parseInt(active.dataset.row);\n const ac = parseInt(active.dataset.col);\n const val = active.textContent || '';\n if (val !== (rows[ar]?.[ac] || '')) {\n const next = rows.map(r => [...r]);\n if (next[ar]) { next[ar][ac] = val; onChange(next); }\n }\n }\n dragging.current = true;\n if (e.shiftKey && selAnchor) {\n // Shift+click: extend selection from anchor to clicked cell\n setSelEnd({ row, col });\n } else {\n setSelAnchor({ row, col });\n setSelEnd({ row, col });\n }\n }, [rows, onChange, selAnchor]);\n\n const handleMouseEnter = useCallback((row: number, col: number) => {\n if (dragging.current) {\n setSelEnd({ row, col });\n }\n }, []);\n\n useEffect(() => {\n const handleMouseUp = () => { dragging.current = false; };\n window.addEventListener('mouseup', handleMouseUp);\n return () => window.removeEventListener('mouseup', handleMouseUp);\n }, []);\n\n // Copy selection with Ctrl+C / Cmd+C\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (!(e.ctrlKey || e.metaKey) || e.key !== 'c') return;\n if (!selAnchor || !selEnd) return;\n // Don't intercept if user has text selected within a cell\n const nativeSel = window.getSelection();\n if (nativeSel && nativeSel.toString().length > 0 && !hasRange) return;\n\n const r1 = Math.min(selAnchor.row, selEnd.row), r2 = Math.max(selAnchor.row, selEnd.row);\n const c1 = Math.min(selAnchor.col, selEnd.col), c2 = Math.max(selAnchor.col, selEnd.col);\n\n const text = [];\n for (let r = r1; r <= r2; r++) {\n const rowCells = [];\n for (let c = c1; c <= c2; c++) {\n rowCells.push(rows[r]?.[c] || '');\n }\n text.push(rowCells.join('\\t'));\n }\n const tsv = text.join('\\n');\n if (tsv) {\n e.preventDefault();\n navigator.clipboard.writeText(tsv);\n }\n };\n window.addEventListener('keydown', handler);\n return () => window.removeEventListener('keydown', handler);\n }, [selAnchor, selEnd, rows, hasRange]);\n\n // Global paste — works even when cell is selected but not editing\n useEffect(() => {\n const handler = (e: ClipboardEvent) => {\n if (!focus) return;\n // Don't intercept if already in an editable element\n const active = document.activeElement as HTMLElement;\n if (active?.isContentEditable) return;\n // Only intercept if focus is inside our grid\n if (!tableRef.current?.contains(active)) return;\n\n const text = e.clipboardData?.getData('text/plain');\n if (!text) return;\n\n e.preventDefault();\n const pastedRows = text.split('\\n').filter(l => l).map(line => line.split('\\t'));\n const next = rows.map(r => [...r]);\n\n for (let r = 0; r < pastedRows.length; r++) {\n const targetRow = focus.row + r;\n while (next.length <= targetRow) next.push(Array(columns.length).fill(''));\n while (next[targetRow].length < columns.length) next[targetRow].push('');\n for (let c = 0; c < pastedRows[r].length; c++) {\n const targetCol = focus.col + c;\n if (targetCol >= columns.length) break;\n if (columns[targetCol].readOnly) continue;\n next[targetRow][targetCol] = pastedRows[r][c].trim();\n }\n }\n onChange(fixedRows ? next : withSpareRow(next, columns.length));\n\n // Select the pasted range\n setSelAnchor({ row: focus.row, col: focus.col });\n setSelEnd({ row: Math.min(focus.row + pastedRows.length - 1, next.length - 1), col: Math.min(focus.col + (pastedRows[0]?.length || 1) - 1, columns.length - 1) });\n };\n window.addEventListener('paste', handler);\n return () => window.removeEventListener('paste', handler);\n }, [focus, rows, columns, onChange, fixedRows]);\n\n // Handle paste — supports multi-cell paste from spreadsheets (when in edit mode)\n const handlePaste = useCallback((e: React.ClipboardEvent, startRow: number, startCol: number) => {\n const text = e.clipboardData.getData('text/plain');\n if (!text) return;\n\n const pastedRows = text.split('\\n').map(line => line.split('\\t'));\n if (pastedRows.length <= 1 && pastedRows[0]?.length <= 1) return;\n\n e.preventDefault();\n const next = rows.map(r => [...r]);\n\n for (let r = 0; r < pastedRows.length; r++) {\n const targetRow = startRow + r;\n while (next.length <= targetRow) next.push(Array(columns.length).fill(''));\n while (next[targetRow].length < columns.length) next[targetRow].push('');\n for (let c = 0; c < pastedRows[r].length; c++) {\n const targetCol = startCol + c;\n if (targetCol >= columns.length) break;\n if (columns[targetCol].readOnly) continue;\n next[targetRow][targetCol] = pastedRows[r][c].trim();\n }\n }\n\n onChange(fixedRows ? next : withSpareRow(next, columns.length));\n }, [rows, columns, onChange, fixedRows]);\n\n // Handle keyboard navigation\n const handleKeyDown = useCallback((e: React.KeyboardEvent, row: number, col: number) => {\n let nextRow = row;\n let nextCol = col;\n\n if (e.key === 'Tab') {\n e.preventDefault();\n nextCol = e.shiftKey ? col - 1 : col + 1;\n if (nextCol >= columns.length) { nextCol = 0; nextRow = row + 1; }\n if (nextCol < 0) { nextCol = columns.length - 1; nextRow = row - 1; }\n } else if (e.key === 'Enter') {\n e.preventDefault();\n nextRow = e.shiftKey ? row - 1 : row + 1;\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n nextRow = row + 1;\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n nextRow = row - 1;\n } else if (e.key === 'ArrowLeft') {\n e.preventDefault();\n nextCol = col - 1;\n } else if (e.key === 'ArrowRight') {\n e.preventDefault();\n nextCol = col + 1;\n } else if (e.key === 'Delete' || e.key === 'Backspace') {\n const target = e.target as HTMLElement;\n // While editing, only intercept when the whole cell text is selected.\n if (target.isContentEditable) {\n if (target.textContent && window.getSelection()?.toString() === target.textContent) {\n e.preventDefault();\n updateCell(row, col, '');\n }\n return;\n }\n // Not editing — clear the selection range (or just this cell).\n e.preventDefault();\n if (selAnchor && selEnd) {\n const r1 = Math.min(selAnchor.row, selEnd.row), r2 = Math.max(selAnchor.row, selEnd.row);\n const c1 = Math.min(selAnchor.col, selEnd.col), c2 = Math.max(selAnchor.col, selEnd.col);\n const next = rows.map(r => [...r]);\n for (let r = r1; r <= r2; r++) for (let c = c1; c <= c2; c++) {\n if (next[r] && !columns[c]?.readOnly) next[r][c] = '';\n }\n onChange(next);\n } else {\n updateCell(row, col, '');\n }\n return;\n } else {\n return;\n }\n\n // Skip read-only columns\n while (nextCol >= 0 && nextCol < columns.length && columns[nextCol].readOnly) {\n nextCol += e.key === 'Tab' && e.shiftKey ? -1 : 1;\n }\n\n if (nextRow >= 0 && nextRow < rows.length && nextCol >= 0 && nextCol < columns.length) {\n const cell = tableRef.current?.querySelector(`[data-row=\"${nextRow}\"][data-col=\"${nextCol}\"]`) as HTMLElement;\n if (cell) {\n cell.focus({ preventScroll: true });\n cell.scrollIntoView({ block: 'nearest', inline: 'nearest' });\n setFocus({ row: nextRow, col: nextCol });\n setEditingCell(null);\n setSelAnchor({ row: nextRow, col: nextCol });\n setSelEnd({ row: nextRow, col: nextCol });\n }\n }\n }, [columns, rows, rows.length, updateCell, selAnchor, selEnd, onChange]);\n\n // Add rows when typing in the last row\n const ensureRows = useCallback((row: number) => {\n if (fixedRows) return;\n if (row >= rows.length - 2) {\n const next = rows.map(r => [...r]);\n for (let i = 0; i < 5; i++) next.push(Array(columns.length).fill(''));\n onChange(next);\n }\n }, [fixedRows, rows, columns.length, onChange]);\n\n // Context menu\n const [ctxMenu, setCtxMenu] = useState<{ x: number; y: number; items: { label: string; onClick: () => void }[] } | null>(null);\n\n // Close context menu on click outside\n useEffect(() => {\n if (!ctxMenu) return;\n const handler = () => setCtxMenu(null);\n window.addEventListener('pointerdown', handler);\n return () => window.removeEventListener('pointerdown', handler);\n }, [ctxMenu]);\n\n const insertRow = useCallback((at: number) => {\n const next = rows.map(r => [...r]);\n next.splice(at, 0, Array(columns.length).fill(''));\n onChange(next);\n }, [rows, columns.length, onChange]);\n\n const deleteRow = useCallback((at: number) => {\n if (rows.length <= 1) return;\n const next = rows.filter((_, i) => i !== at);\n onChange(next);\n }, [rows, onChange]);\n\n const insertCol = useCallback((at: number) => {\n const next = rows.map(r => { const nr = [...r]; nr.splice(at, 0, ''); return nr; });\n onChange(next);\n }, [rows, onChange]);\n\n const deleteCol = useCallback((at: number) => {\n if (columns.length <= 1) return;\n const next = rows.map(r => { const nr = [...r]; nr.splice(at, 1); return nr; });\n onChange(next);\n }, [rows, columns.length, onChange]);\n\n const handleRowCtx = useCallback((e: React.MouseEvent, ri: number) => {\n e.preventDefault();\n if (fixedRows) return;\n setCtxMenu({ x: e.clientX, y: e.clientY, items: [\n { label: strings.insertRowAbove, onClick: () => { insertRow(ri); setCtxMenu(null); } },\n { label: strings.insertRowBelow, onClick: () => { insertRow(ri + 1); setCtxMenu(null); } },\n { label: strings.deleteRow(ri + 1), onClick: () => { deleteRow(ri); setCtxMenu(null); } },\n ]});\n }, [fixedRows, insertRow, deleteRow, strings]);\n\n const handleColCtx = useCallback((e: React.MouseEvent, ci: number) => {\n e.preventDefault();\n if (fixedRows) return;\n setCtxMenu({ x: e.clientX, y: e.clientY, items: [\n { label: strings.insertColumnLeft, onClick: () => { insertCol(ci); setCtxMenu(null); } },\n { label: strings.insertColumnRight, onClick: () => { insertCol(ci + 1); setCtxMenu(null); } },\n { label: strings.deleteColumn(String(columns[ci]?.title || ci + 1)), onClick: () => { deleteCol(ci); setCtxMenu(null); } },\n ]});\n }, [fixedRows, columns, insertCol, deleteCol, strings]);\n\n // Column resize\n const getColWidth = (ci: number) => colWidths[ci] ?? columns[ci]?.width ?? 150;\n\n useEffect(() => {\n const handleMouseMove = (e: MouseEvent) => {\n if (!resizing.current) return;\n const diff = e.clientX - resizing.current.startX;\n const newW = Math.max(40, resizing.current.startW + diff);\n setColWidths(prev => ({ ...prev, [resizing.current!.col]: newW }));\n };\n const handleMouseUp = () => {\n if (resizing.current && onColumnsChange) {\n const updated = columns.map((c, i) => ({ ...c, width: colWidths[i] ?? c.width }));\n updated[resizing.current.col] = { ...updated[resizing.current.col], width: colWidths[resizing.current.col] ?? columns[resizing.current.col].width };\n onColumnsChange(updated);\n }\n resizing.current = null;\n document.body.style.cursor = '';\n };\n window.addEventListener('mousemove', handleMouseMove);\n window.addEventListener('mouseup', handleMouseUp);\n return () => { window.removeEventListener('mousemove', handleMouseMove); window.removeEventListener('mouseup', handleMouseUp); };\n }, [columns, colWidths, onColumnsChange]);\n\n const startColResize = (e: React.MouseEvent, ci: number) => {\n e.preventDefault();\n e.stopPropagation();\n resizing.current = { col: ci, startX: e.clientX, startW: getColWidth(ci) };\n document.body.style.cursor = 'col-resize';\n };\n\n // Row resize\n const getRowHeight = (ri: number) => rowHeights[ri] ?? 28;\n useEffect(() => {\n const handleMove = (e: MouseEvent) => {\n if (!rowResizing.current) return;\n const diff = e.clientY - rowResizing.current.startY;\n const newH = Math.max(20, rowResizing.current.startH + diff);\n setRowHeights(prev => ({ ...prev, [rowResizing.current!.row]: newH }));\n };\n const handleUp = () => { rowResizing.current = null; document.body.style.cursor = ''; };\n window.addEventListener('mousemove', handleMove);\n window.addEventListener('mouseup', handleUp);\n return () => { window.removeEventListener('mousemove', handleMove); window.removeEventListener('mouseup', handleUp); };\n }, []);\n const startRowResize = (e: React.MouseEvent, ri: number) => {\n e.preventDefault();\n e.stopPropagation();\n rowResizing.current = { row: ri, startY: e.clientY, startH: getRowHeight(ri) };\n document.body.style.cursor = 'row-resize';\n };\n\n // Auto-fit column to the widest cell content (data + header).\n const autoFitColumn = useCallback((ci: number) => {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n ctx.font = '12px ui-monospace, SFMono-Regular, Menlo, monospace';\n let maxW = 0;\n for (const row of rows) {\n const plain = String(row[ci] ?? '').replace(/<[^>]*>/g, '');\n const w = ctx.measureText(plain).width;\n if (w > maxW) maxW = w;\n }\n const headerW = ctx.measureText(columns[ci]?.title ?? '').width;\n if (headerW > maxW) maxW = headerW;\n const finalW = Math.max(40, Math.ceil(maxW + 24));\n setColWidths(prev => ({ ...prev, [ci]: finalW }));\n if (onColumnsChange) {\n const updated = columns.map((c, i) => ({ ...c, width: i === ci ? finalW : (colWidths[i] ?? c.width) }));\n onColumnsChange(updated);\n }\n }, [rows, columns, colWidths, onColumnsChange]);\n\n // Auto-fit row — reset to the default height (cells use whitespace-nowrap so\n // a single row line is the natural fit).\n const autoFitRow = useCallback((ri: number) => {\n setRowHeights(prev => { const next = { ...prev }; delete next[ri]; return next; });\n }, []);\n\n // Fill handle — drag the small square at the bottom-right of the selection\n // to copy / extrapolate values into adjacent cells.\n const applyFill = useCallback((target: CellPos) => {\n const { a: sa, e: se } = selRefForFill.current;\n if (!sa || !se) return;\n const r1 = Math.min(sa.row, se.row);\n const r2 = Math.max(sa.row, se.row);\n const c1 = Math.min(sa.col, se.col);\n const c2 = Math.max(sa.col, se.col);\n\n let nr1 = r1, nr2 = r2, nc1 = c1, nc2 = c2;\n if (target.row > r2) nr2 = target.row;\n else if (target.row < r1) nr1 = target.row;\n if (target.col > c2) nc2 = target.col;\n else if (target.col < c1) nc1 = target.col;\n\n const selH = r2 - r1 + 1;\n const selW = c2 - c1 + 1;\n const next = rows.map(r => [...r]);\n while (next.length <= nr2) next.push(Array(columns.length).fill(''));\n for (const row of next) while (row.length <= nc2) row.push('');\n\n // Detect a 1-d numeric arithmetic sequence so vertical/horizontal drags\n // continue the series instead of repeating the pattern.\n function asSeries(values: string[]): { step: number } | null {\n const nums = values.map(v => parseFloat(v));\n if (nums.length < 2 || nums.some(n => Number.isNaN(n))) return null;\n const step = nums[1] - nums[0];\n for (let i = 2; i < nums.length; i++) {\n if (Math.abs((nums[i] - nums[i - 1]) - step) > 1e-9) return null;\n }\n return { step };\n }\n\n for (let r = nr1; r <= nr2; r++) {\n for (let c = nc1; c <= nc2; c++) {\n if (r >= r1 && r <= r2 && c >= c1 && c <= c2) continue; // inside original\n let value: string;\n if (selW === 1 && nc1 === c1 && nc2 === c2) {\n // Vertical fill (same column as selection).\n const colVals = Array.from({ length: selH }, (_, i) => next[r1 + i]?.[c] ?? '');\n const series = asSeries(colVals);\n if (series) {\n const last = parseFloat(next[r2]?.[c] ?? '0');\n const first = parseFloat(next[r1]?.[c] ?? '0');\n const offset = r > r2 ? r - r2 : -(r1 - r);\n value = String((r > r2 ? last : first) + series.step * offset);\n } else {\n const dr = ((r - r1) % selH + selH) % selH;\n value = next[r1 + dr]?.[c] ?? '';\n }\n } else if (selH === 1 && nr1 === r1 && nr2 === r2) {\n // Horizontal fill (same row as selection).\n const rowVals = Array.from({ length: selW }, (_, i) => next[r]?.[c1 + i] ?? '');\n const series = asSeries(rowVals);\n if (series) {\n const last = parseFloat(next[r]?.[c2] ?? '0');\n const first = parseFloat(next[r]?.[c1] ?? '0');\n const offset = c > c2 ? c - c2 : -(c1 - c);\n value = String((c > c2 ? last : first) + series.step * offset);\n } else {\n const dc = ((c - c1) % selW + selW) % selW;\n value = next[r]?.[c1 + dc] ?? '';\n }\n } else {\n // 2-d fill — tile the selection rectangle.\n const dr = ((r - r1) % selH + selH) % selH;\n const dc = ((c - c1) % selW + selW) % selW;\n value = next[r1 + dr]?.[c1 + dc] ?? '';\n }\n next[r][c] = value;\n }\n }\n\n onChange(next);\n setSelAnchor({ row: nr1, col: nc1 });\n setSelEnd({ row: nr2, col: nc2 });\n }, [rows, columns.length, onChange]);\n\n useEffect(() => {\n const handleMove = (e: MouseEvent) => {\n if (!filling.current) return;\n const el = document.elementFromPoint(e.clientX, e.clientY);\n const inner = (el as HTMLElement)?.closest?.('[data-row][data-col]') as HTMLElement | null;\n if (!inner) return;\n const r = parseInt(inner.dataset.row!);\n const c = parseInt(inner.dataset.col!);\n setFillTarget({ row: r, col: c });\n };\n const handleUp = () => {\n if (filling.current && fillTarget) applyFill(fillTarget);\n filling.current = false;\n setFillTarget(null);\n document.body.style.cursor = '';\n };\n window.addEventListener('mousemove', handleMove);\n window.addEventListener('mouseup', handleUp);\n return () => {\n window.removeEventListener('mousemove', handleMove);\n window.removeEventListener('mouseup', handleUp);\n };\n }, [fillTarget, applyFill]);\n\n const startFill = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n filling.current = true;\n document.body.style.cursor = 'crosshair';\n };\n\n // Row drag reorder\n const handleRowDragStart = (ri: number) => setDragRow(ri);\n const handleRowDragOver = (e: React.DragEvent, ri: number) => { e.preventDefault(); setDragOverRow(ri); };\n const handleRowDrop = (ri: number) => {\n if (dragRow === null || dragRow === ri) { setDragRow(null); setDragOverRow(null); return; }\n const next = rows.map(r => [...r]);\n const [moved] = next.splice(dragRow, 1);\n next.splice(ri, 0, moved);\n onChange(next);\n setDragRow(null);\n setDragOverRow(null);\n };\n\n // Column drag reorder\n const handleColDragStart = (ci: number) => setDragCol(ci);\n const handleColDragOver = (e: React.DragEvent, ci: number) => { e.preventDefault(); setDragOverCol(ci); };\n const handleColDrop = (ci: number) => {\n if (dragCol === null || dragCol === ci) { setDragCol(null); setDragOverCol(null); return; }\n const next = rows.map(r => {\n const nr = [...r];\n const [moved] = nr.splice(dragCol, 1);\n nr.splice(ci, 0, moved);\n return nr;\n });\n onChange(next);\n if (onColumnsChange) {\n const newCols = [...columns];\n const [moved] = newCols.splice(dragCol, 1);\n newCols.splice(ci, 0, moved);\n onColumnsChange(newCols);\n }\n setDragCol(null);\n setDragOverCol(null);\n };\n\n // Virtual scrolling — only render visible rows + buffer\n const ROW_HEIGHT = 28;\n const BUFFER = 20;\n const containerRef = useRef<HTMLDivElement>(null);\n const [scrollTop, setScrollTop] = useState(0);\n const [containerHeight, setContainerHeight] = useState(800);\n\n // Measure actual container height\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n const measure = () => setContainerHeight(el.clientHeight || 800);\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(el);\n return () => observer.disconnect();\n }, []);\n\n // Only virtualize if there are many rows (>100), otherwise render all\n const useVirtualization = rows.length > 100;\n const visibleStart = useVirtualization ? Math.max(0, Math.floor(scrollTop / ROW_HEIGHT) - BUFFER) : 0;\n const visibleEnd = useVirtualization ? Math.min(rows.length, Math.ceil((scrollTop + containerHeight) / ROW_HEIGHT) + BUFFER) : rows.length;\n const visibleRows = useMemo(() => rows.slice(visibleStart, visibleEnd), [rows, visibleStart, visibleEnd]);\n const topPad = visibleStart * ROW_HEIGHT;\n const bottomPad = (rows.length - visibleEnd) * ROW_HEIGHT;\n\n const thCls = 'px-2 py-1.5 text-left text-xs font-medium text-gray-500 uppercase bg-gray-100 border-b border-r border-gray-200 select-none';\n const tdCls = 'px-0 py-0 border-b border-r border-gray-200 text-sm';\n\n return (\n <div ref={containerRef} className=\"border border-gray-300 rounded overflow-scroll grid-scroll\"\n style={{ maxHeight, height: maxHeight }}\n onScroll={(e) => setScrollTop((e.target as HTMLElement).scrollTop)}>\n <table ref={tableRef} className=\"border-collapse select-none\" style={{ tableLayout: 'fixed', minWidth: 36 + columns.reduce((s, c) => s + (getColWidth(columns.indexOf(c))), 0) }}>\n <colgroup>\n <col style={{ width: 36 }} />\n {columns.map((c, ci) => <col key={c.key} style={{ width: getColWidth(ci) }} />)}\n </colgroup>\n <thead className=\"sticky top-0 z-10\">\n <tr>\n <th className={thCls + ' text-center w-9 cursor-pointer hover:bg-gray-200'}\n onClick={() => { setSelAnchor({ row: 0, col: 0 }); setSelEnd({ row: rows.length - 1, col: columns.length - 1 }); }}\n title={strings.selectAll}>#</th>\n {columns.map((c, ci) => {\n const colSelected = selAnchor && selEnd && Math.min(selAnchor.col, selEnd.col) <= ci && ci <= Math.max(selAnchor.col, selEnd.col)\n && Math.min(selAnchor.row, selEnd.row) === 0 && Math.max(selAnchor.row, selEnd.row) === rows.length - 1;\n return (\n <th key={c.key} className={`${thCls} cursor-pointer hover:bg-gray-200 relative${colSelected ? ' !bg-blue-200' : ''}${dragOverCol === ci ? ' !bg-blue-100' : ''}`}\n style={{ width: getColWidth(ci) }}\n draggable\n onDragStart={() => handleColDragStart(ci)}\n onDragOver={(e) => handleColDragOver(e, ci)}\n onDrop={() => handleColDrop(ci)}\n onDragEnd={() => { setDragCol(null); setDragOverCol(null); }}\n onClick={(e) => {\n if (e.shiftKey && selAnchor) {\n setSelEnd({ row: rows.length - 1, col: ci });\n } else {\n setSelAnchor({ row: 0, col: ci }); setSelEnd({ row: rows.length - 1, col: ci });\n }\n }}\n onContextMenu={(e) => handleColCtx(e, ci)}>\n {c.title}\n {/* Resize handle — thin edge, wider hover target */}\n <div className=\"absolute -right-1 top-0 bottom-0 w-2 cursor-col-resize z-20\"\n onMouseDown={(e) => startColResize(e, ci)}\n onDoubleClick={(e) => { e.stopPropagation(); autoFitColumn(ci); }}\n title={strings.resize}\n />\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {topPad > 0 && <tr style={{ height: topPad }} />}\n {visibleRows.map((row, vi) => {\n const ri = visibleStart + vi;\n const rowSelected = selAnchor && selEnd && Math.min(selAnchor.row, selEnd.row) <= ri && ri <= Math.max(selAnchor.row, selEnd.row)\n && Math.min(selAnchor.col, selEnd.col) === 0 && Math.max(selAnchor.col, selEnd.col) === columns.length - 1;\n return (\n <tr key={ri} style={{ height: getRowHeight(ri) }}>\n <td className={`relative px-1 py-1 text-center text-[10px] text-gray-400 border-b border-r border-gray-200 bg-gray-50 select-none cursor-pointer hover:bg-gray-200${rowSelected ? ' !bg-blue-200 !text-gray-700' : ''}${dragOverRow === ri ? ' !bg-blue-100' : ''}`}\n draggable\n onDragStart={() => handleRowDragStart(ri)}\n onDragOver={(e) => handleRowDragOver(e, ri)}\n onDrop={() => handleRowDrop(ri)}\n onDragEnd={() => { setDragRow(null); setDragOverRow(null); }}\n onClick={(e) => {\n if (e.shiftKey && selAnchor) {\n setSelEnd({ row: ri, col: columns.length - 1 });\n } else {\n setSelAnchor({ row: ri, col: 0 }); setSelEnd({ row: ri, col: columns.length - 1 });\n }\n }}\n onContextMenu={(e) => handleRowCtx(e, ri)}>\n {ri + 1}\n {/* Row resize handle — slim bar at the bottom of the row header */}\n <div className=\"absolute -bottom-1 left-0 right-0 h-2 cursor-row-resize z-20\"\n onMouseDown={(e) => startRowResize(e, ri)}\n onDoubleClick={(e) => { e.stopPropagation(); autoFitRow(ri); }}\n title={strings.resize}\n />\n </td>\n {columns.map((col, ci) => {\n const inRange = selAnchor && selEnd && rangeContains(selAnchor, selEnd, ri, ci);\n const isEditing = editingCell?.row === ri && editingCell?.col === ci && !col.readOnly;\n const isFocused = focus?.row === ri && focus?.col === ci;\n const cellStyle = cellStyles?.[`${ri}:${ci}`];\n const selR2 = selAnchor && selEnd ? Math.max(selAnchor.row, selEnd.row) : -1;\n const selC2 = selAnchor && selEnd ? Math.max(selAnchor.col, selEnd.col) : -1;\n const isFillCorner = selAnchor && selEnd && ri === selR2 && ci === selC2;\n const inFillPreview = filling.current && fillTarget && selAnchor && selEnd && (() => {\n const r1 = Math.min(selAnchor.row, selEnd.row), r2 = Math.max(selAnchor.row, selEnd.row);\n const c1 = Math.min(selAnchor.col, selEnd.col), c2 = Math.max(selAnchor.col, selEnd.col);\n let nr1 = r1, nr2 = r2, nc1 = c1, nc2 = c2;\n if (fillTarget.row > r2) nr2 = fillTarget.row; else if (fillTarget.row < r1) nr1 = fillTarget.row;\n if (fillTarget.col > c2) nc2 = fillTarget.col; else if (fillTarget.col < c1) nc1 = fillTarget.col;\n return ri >= nr1 && ri <= nr2 && ci >= nc1 && ci <= nc2 && !(ri >= r1 && ri <= r2 && ci >= c1 && ci <= c2);\n })();\n const fontSizeCls = cellStyle?.fontSize === 'sm' ? 'text-[11px]'\n : cellStyle?.fontSize === 'lg' ? 'text-sm'\n : cellStyle?.fontSize === 'xl' ? 'text-base'\n : 'text-xs';\n const styleCls = `${cellStyle?.bold ? ' font-bold' : ''}${cellStyle?.italic ? ' italic' : ''}${cellStyle?.underline ? ' underline' : ''}`;\n return (\n <td key={ci}\n className={`relative ${tdCls}${col.readOnly ? ' bg-gray-50 text-gray-500 cursor-default' : ' cursor-cell'}${inRange ? ' !bg-blue-100' : ''}${isFocused && !inRange ? ' ring-2 ring-inset ring-blue-400' : ''}${inFillPreview ? ' !bg-blue-50 ring-1 ring-inset ring-blue-300' : ''}`}\n onMouseDown={(e) => {\n // td-level handler so clicks anywhere in the cell (incl. borders) select.\n if (e.target === e.currentTarget) {\n handleMouseDown(e, ri, ci);\n const inner = e.currentTarget.querySelector<HTMLElement>('[data-row][data-col]');\n inner?.focus();\n }\n }}\n onMouseEnter={() => handleMouseEnter(ri, ci)}\n onClick={(e) => {\n if (e.target === e.currentTarget) {\n const inner = e.currentTarget.querySelector<HTMLElement>('[data-row][data-col]');\n inner?.focus();\n }\n }}\n onDoubleClick={(e) => {\n if (e.target === e.currentTarget && !col.readOnly) setEditingCell({ row: ri, col: ci });\n }}>\n <CellText\n contentEditable={isEditing}\n suppressContentEditableWarning\n tabIndex={0}\n data-row={ri}\n data-col={ci}\n className={`w-full h-full px-2 py-1 rosh-focus-ring whitespace-nowrap overflow-hidden ${\n col.align === 'right' ? 'text-right' : col.align === 'center' ? 'text-center' : ''\n } ${col.readOnly ? 'cursor-default' : 'cursor-cell'} font-mono ${fontSizeCls}${styleCls}`}\n onMouseDown={(e) => handleMouseDown(e, ri, ci)}\n onMouseEnter={() => handleMouseEnter(ri, ci)}\n onDoubleClick={() => { if (!col.readOnly) setEditingCell({ row: ri, col: ci }); }}\n onFocus={() => {\n setFocus({ row: ri, col: ci });\n if (!dragging.current) {\n setSelAnchor({ row: ri, col: ci });\n setSelEnd({ row: ri, col: ci });\n }\n }}\n onBlur={(e) => {\n const val = e.currentTarget.textContent || '';\n if (val !== (row[ci] || '')) updateCell(ri, ci, val);\n setEditingCell(null);\n }}\n onInput={() => ensureRows(ri)}\n onPaste={(e) => handlePaste(e, ri, ci)}\n onKeyDown={(e) => {\n // Start editing on any printable key — clear cell and type\n if (!isEditing && !col.readOnly && e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {\n e.preventDefault();\n updateCell(ri, ci, e.key);\n caretToEnd.current = { row: ri, col: ci };\n setEditingCell({ row: ri, col: ci });\n return;\n }\n handleKeyDown(e, ri, ci);\n }}\n text={row[ci] || ''}\n />\n {isFillCorner && (\n <div\n onMouseDown={startFill}\n title={strings.fill}\n className=\"absolute -bottom-[3px] -right-[3px] w-[7px] h-[7px] bg-blue-500 border border-white cursor-crosshair z-30 hover:bg-blue-600\"\n />\n )}\n </td>\n );\n })}\n </tr>\n );\n })}\n {bottomPad > 0 && <tr style={{ height: bottomPad }} />}\n </tbody>\n </table>\n\n {/* Context menu — portalled to body to avoid overflow clipping */}\n {ctxMenu && createPortal(\n <>\n <div className=\"fixed inset-0 z-[200]\" onPointerDown={() => setCtxMenu(null)} />\n <div className=\"fixed z-[201] bg-white rounded-lg shadow-lg border border-gray-200 py-1 min-w-[160px]\"\n style={{ left: ctxMenu.x, top: ctxMenu.y }}>\n {ctxMenu.items.map((item, i) => (\n <button key={i} onPointerDown={e => { e.stopPropagation(); item.onClick(); }}\n className=\"w-full text-left px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100\">\n {item.label}\n </button>\n ))}\n </div>\n </>,\n document.body\n )}\n </div>\n );\n}\n"]}
|
|
@@ -2,13 +2,13 @@ import { forwardRef, useId } from 'react';
|
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
// src/forms/Button.tsx
|
|
5
|
-
var BUTTON_BASE = "inline-flex items-center justify-center rounded-md font-medium transition-colors focus
|
|
5
|
+
var BUTTON_BASE = "inline-flex items-center justify-center rounded-md font-medium transition-colors rosh-focus-ring focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-60";
|
|
6
6
|
var BUTTON_VARIANTS = {
|
|
7
|
-
primary: "bg-blue-600 text-white shadow-sm hover:bg-blue-700 focus:ring-
|
|
8
|
-
secondary: "border border-gray-300 bg-white text-gray-700 shadow-sm hover:bg-gray-50 focus:ring-
|
|
9
|
-
ghost: "text-gray-700 hover:bg-gray-100 focus:ring-
|
|
10
|
-
"ghost-danger": "text-red-600 hover:bg-red-50 focus:ring-
|
|
11
|
-
danger: "bg-red-600 text-white shadow-sm hover:bg-red-700 focus:ring-
|
|
7
|
+
primary: "bg-blue-600 text-white shadow-sm hover:bg-blue-700 focus-visible:ring-[color:var(--rosh-focus-ring-strong)]",
|
|
8
|
+
secondary: "border border-gray-300 bg-white text-gray-700 shadow-sm hover:bg-gray-50 focus-visible:ring-[color:var(--rosh-focus-ring)]",
|
|
9
|
+
ghost: "text-gray-700 hover:bg-gray-100 focus-visible:ring-[color:var(--rosh-focus-ring)]",
|
|
10
|
+
"ghost-danger": "text-red-600 hover:bg-red-50 focus-visible:ring-[color:var(--rosh-focus-ring-invalid)]",
|
|
11
|
+
danger: "bg-red-600 text-white shadow-sm hover:bg-red-700 focus-visible:ring-[color:var(--rosh-focus-ring-invalid-strong)]",
|
|
12
12
|
/**
|
|
13
13
|
* A button that reads as a link: no box, no padding, underlined on hover.
|
|
14
14
|
* For an action that belongs in running text or beside a field — "Forgot
|
|
@@ -19,7 +19,7 @@ var BUTTON_VARIANTS = {
|
|
|
19
19
|
* can be middle-clicked and read off the status bar; this is for actions
|
|
20
20
|
* that merely look quiet.
|
|
21
21
|
*/
|
|
22
|
-
link: "text-blue-600 underline-offset-4 hover:underline focus:ring-
|
|
22
|
+
link: "text-blue-600 underline-offset-4 hover:underline focus-visible:ring-[color:var(--rosh-focus-ring)]"
|
|
23
23
|
};
|
|
24
24
|
var SIZES = {
|
|
25
25
|
sm: "gap-1 px-2.5 py-1 text-xs",
|
|
@@ -42,7 +42,7 @@ var SIZES = {
|
|
|
42
42
|
"touch-xl": "gap-3 h-20 px-8 text-2xl"
|
|
43
43
|
// 80px — keypad keys, tender
|
|
44
44
|
};
|
|
45
|
-
var LINK_BASE = "inline-flex items-center font-medium transition-colors focus
|
|
45
|
+
var LINK_BASE = "inline-flex items-center font-medium transition-colors rosh-focus-ring focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-60";
|
|
46
46
|
var LINK_SIZES = {
|
|
47
47
|
sm: "gap-1 text-xs",
|
|
48
48
|
md: "gap-1.5 text-sm",
|
|
@@ -113,5 +113,5 @@ var Button = forwardRef(function Button2({
|
|
|
113
113
|
var Button_default = Button;
|
|
114
114
|
|
|
115
115
|
export { BUTTON_BASE, BUTTON_VARIANTS, Button_default };
|
|
116
|
-
//# sourceMappingURL=chunk-
|
|
117
|
-
//# sourceMappingURL=chunk-
|
|
116
|
+
//# sourceMappingURL=chunk-LQTVTOSY.js.map
|
|
117
|
+
//# sourceMappingURL=chunk-LQTVTOSY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/forms/Button.tsx"],"names":["Button"],"mappings":"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","file":"chunk-LQTVTOSY.js","sourcesContent":["/**\n * Button — the kit's standard button. `primary` uses `bg-blue-600`, which the\n * theme system remaps to the active accent (and to a readable tone in dark\n * mode), so a primary button always follows the user's chosen accent.\n *\n * Controlled by the consumer like any native button (spread `onClick`, `type`,\n * `form`, …); the component only adds the look, a `loading` spinner state, and\n * optional icon slots.\n */\nimport { forwardRef, useId, type ButtonHTMLAttributes, type ReactNode } from 'react';\n\n/**\n * `ghost-danger` is a destructive action sitting in a row of ordinary ones —\n * Clear, Discard, Remove — where solid `danger` would be wrong. Two solid\n * shouting buttons on one screen means neither is read, so the destructive one\n * borrows `ghost`'s weight and keeps only the colour. The colour is the point:\n * it lets someone tell what the button costs WITHOUT reading it, which under\n * time pressure is what actually happens.\n */\nexport type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'ghost-danger' | 'danger' | 'link';\n/**\n * `sm`/`md`/`lg` are the desktop scale. The `touch-*` rungs are for a finger on\n * glass — a till, a warehouse tablet — and are a SEPARATE ladder on purpose:\n * a till's idea of \"medium\" is 56px, and naming it `md` would have made the\n * same word mean two sizes depending on which app you were reading.\n *\n * Nothing picks a touch size automatically. An app that wants them asks for\n * them, so a desktop portal cannot grow finger-sized buttons by accident.\n */\nexport type ButtonSize = 'sm' | 'md' | 'lg' | 'touch-sm' | 'touch' | 'touch-lg' | 'touch-xl';\n\nexport interface ButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'className'> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n /** Show a spinner and disable the button while an action is in flight. */\n loading?: boolean;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n /** Stretch to the full width of the container. */\n block?: boolean;\n className?: string;\n /**\n * Why this button is disabled, rendered as text BESIDE it — never as a\n * `title` tooltip. A tooltip needs a hover, a touchscreen has no hover, and a\n * cashier facing a dead button with no explanation calls a manager.\n *\n * Only rendered while the button is actually disabled (or loading); ignored\n * otherwise, so it is safe to pass unconditionally. Note it changes the\n * rendered shape: the button gains a wrapper element, which matters to a\n * parent `flex gap-*` row or a `:first-child` selector.\n */\n disabledReason?: ReactNode;\n}\n\n/**\n * Shared with `IconButton`, which composes its own class string rather than\n * passing a square size through this component's `className` — two competing\n * padding utilities in one attribute resolve by compiled-stylesheet order, not\n * by the order they were written (the reasoning in forms/styles.ts applies\n * here identically).\n *\n * Package-internal on purpose: exported from the module so IconButton can share\n * it, deliberately absent from `src/ui/kit.ts` so it is not public API. A\n * consumer restyling a button is a consumer the theme system cannot reach.\n */\nexport const BUTTON_BASE =\n 'inline-flex items-center justify-center rounded-md font-medium transition-colors ' +\n 'rosh-focus-ring focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-60';\n\nexport const BUTTON_VARIANTS: Record<ButtonVariant, string> = {\n primary: 'bg-blue-600 text-white shadow-sm hover:bg-blue-700 focus-visible:ring-[color:var(--rosh-focus-ring-strong)]',\n secondary: 'border border-gray-300 bg-white text-gray-700 shadow-sm hover:bg-gray-50 focus-visible:ring-[color:var(--rosh-focus-ring)]',\n ghost: 'text-gray-700 hover:bg-gray-100 focus-visible:ring-[color:var(--rosh-focus-ring)]',\n 'ghost-danger': 'text-red-600 hover:bg-red-50 focus-visible:ring-[color:var(--rosh-focus-ring-invalid)]',\n danger: 'bg-red-600 text-white shadow-sm hover:bg-red-700 focus-visible:ring-[color:var(--rosh-focus-ring-invalid-strong)]',\n /**\n * A button that reads as a link: no box, no padding, underlined on hover.\n * For an action that belongs in running text or beside a field — \"Forgot\n * your password?\", \"Use a different address\" — where a boxed button would\n * claim more of the page than the action deserves.\n *\n * It is still a <button>. Anything that NAVIGATES should be an anchor, so it\n * can be middle-clicked and read off the status bar; this is for actions\n * that merely look quiet.\n */\n link: 'text-blue-600 underline-offset-4 hover:underline focus-visible:ring-[color:var(--rosh-focus-ring)]',\n};\n\n// A Record keyed by the union, not a ternary chain: adding a member without a\n// size here is then a compile error rather than a silent fall-through to the\n// default branch. `sm`/`md` are byte-for-byte what they have always been, and\n// `tests/touchPrimitives.test.tsx` pins them against a captured literal.\n//\n// Every rung is also asserted to be the same height as the IconButton rung of\n// the same name (`tests/buttonLinkAndLarge.test.tsx`) — pinning the two sides\n// separately is how `lg` first shipped 4px short of its square twin.\n//\n// The touch rungs carry an explicit `h-*` where the desktop pair uses `py-*`.\n// That is deliberate: a hit target has to be a guaranteed height, not a height\n// implied by the current font size. They are separate map entries and never\n// concatenated with each other, so no two competing utilities land in one class\n// attribute.\nconst SIZES: Record<ButtonSize, string> = {\n sm: 'gap-1 px-2.5 py-1 text-xs',\n md: 'gap-1.5 px-3 py-1.5 text-sm',\n // `py-2.5`, not `py-2`: this rung has to come out 40px to match IconButton's\n // `h-10`, which is the promise IconButton's docblock makes for every rung.\n // `py-2` gives 36px (20px line box + 8px twice) and puts a 4px step between a\n // Button and an IconButton sitting in the same row.\n lg: 'gap-2 px-4 py-2.5 text-sm',\n // 44px is the WCAG 2.5.5 floor, and a floor is not a comfortable size. Use it\n // ONLY for chrome that sits outside the task — switching screens, ending a\n // shift — and never on the path someone is actually working through. It\n // exists so a dense toolbar has something legitimate to reach for instead of\n // borrowing the desktop `sm`, which is half this height.\n 'touch-sm': 'gap-1.5 h-11 px-4 text-base',\n 'touch': 'gap-2 h-14 px-5 text-base', // 56px — the comfortable default\n 'touch-lg': 'gap-2 h-16 px-6 text-lg', // 64px — primary action on a page\n 'touch-xl': 'gap-3 h-20 px-8 text-2xl', // 80px — keypad keys, tender\n};\n\n// Everything BUTTON_BASE has except the box: no rounding (there is nothing to\n// round) and no `justify-center` (a link sits in a line of text, it does not\n// centre itself in a shape).\nconst LINK_BASE =\n 'inline-flex items-center font-medium transition-colors ' +\n 'rosh-focus-ring focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-60';\n\n// Only the gap and the text size survive from each rung — the padding is what\n// the link variant exists to shed.\nconst LINK_SIZES: Record<ButtonSize, string> = {\n sm: 'gap-1 text-xs',\n md: 'gap-1.5 text-sm',\n lg: 'gap-2 text-sm',\n 'touch-sm': 'gap-1.5 text-base',\n 'touch': 'gap-2 text-base',\n 'touch-lg': 'gap-2 text-lg',\n 'touch-xl': 'gap-3 text-2xl',\n};\n\nfunction Spinner() {\n return (\n <svg className=\"h-3.5 w-3.5 animate-spin\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z\" />\n </svg>\n );\n}\n\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n { variant = 'primary', size = 'md', loading = false, leftIcon, rightIcon, block = false,\n disabled, type = 'button', children, className = '', disabledReason, ...rest },\n ref,\n) {\n // useId, not a module counter: a counter assigns different ids on the server\n // and the client and breaks hydration. Called unconditionally — it is a hook.\n const generatedId = useId();\n const isDisabled = disabled || loading;\n const showReason = isDisabled && disabledReason != null && disabledReason !== '';\n const reasonId = showReason ? generatedId : undefined;\n\n const button = (\n <button\n ref={ref}\n type={type}\n disabled={isDisabled}\n aria-busy={loading || undefined}\n aria-describedby={reasonId}\n className={[\n // `link` takes the base WITHOUT the box: no rounding, no padding from\n // the size table. It cannot cancel those by overriding — two padding\n // utilities in one class attribute resolve by compiled-stylesheet\n // order, not by the order they were written — so it never receives\n // them, and keeps only the size's gap and text size.\n variant === 'link' ? LINK_BASE : BUTTON_BASE,\n BUTTON_VARIANTS[variant],\n variant === 'link' ? LINK_SIZES[size] : SIZES[size],\n block ? 'w-full' : '',\n className,\n ].filter(Boolean).join(' ')}\n {...rest}\n >\n {loading ? <Spinner /> : leftIcon}\n {children}\n {!loading && rightIcon}\n </button>\n );\n\n // No reason to show ⇒ the bare <button>, byte-identical to every release\n // before this prop existed. Only the disabled-with-a-reason case wraps.\n if (!showReason) return button;\n\n return (\n <span className={block ? 'flex w-full flex-col gap-1' : 'inline-flex flex-col items-start gap-1'}>\n {button}\n <span id={reasonId} className=\"text-xs text-red-600\">{disabledReason}</span>\n </span>\n );\n});\n\nexport default Button;\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Modal } from './chunk-
|
|
2
|
-
import { keepsNativeMenu } from './chunk-
|
|
1
|
+
import { Modal } from './chunk-ZKHD4J73.js';
|
|
2
|
+
import { keepsNativeMenu } from './chunk-E3TWIN7Z.js';
|
|
3
3
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
5
|
var DEFAULT_APPEARANCE = { activeOpacity: 70, inactiveOpacity: 50, activeBlur: 0, inactiveBlur: 0 };
|
|
@@ -149,5 +149,5 @@ function WidgetSettingsModal({ open, onClose, title, appearance, onAppearanceCha
|
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
export { WidgetSettingsModal, loadAppearance };
|
|
152
|
-
//# sourceMappingURL=chunk-
|
|
153
|
-
//# sourceMappingURL=chunk-
|
|
152
|
+
//# sourceMappingURL=chunk-MQPX6ERJ.js.map
|
|
153
|
+
//# sourceMappingURL=chunk-MQPX6ERJ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shell/WidgetSettingsModal.tsx"],"names":[],"mappings":"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","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/shell/WidgetSettingsModal.tsx"],"names":[],"mappings":"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","file":"chunk-MQPX6ERJ.js","sourcesContent":["import Modal from './Modal';\nimport { keepsNativeMenu } from './contextMenuTarget';\n\nexport interface WidgetAppearance {\n activeOpacity: number;\n inactiveOpacity: number;\n activeBlur: number;\n inactiveBlur: number;\n}\n\nexport const DEFAULT_APPEARANCE: WidgetAppearance = { activeOpacity: 70, inactiveOpacity: 50, activeBlur: 0, inactiveBlur: 0 };\n\nexport function loadAppearance(key: string): WidgetAppearance {\n try {\n const saved = JSON.parse(localStorage.getItem(key) || '');\n // Migrate old single `blur` field to activeBlur/inactiveBlur\n if (saved.blur != null && saved.activeBlur == null) {\n saved.activeBlur = saved.blur;\n saved.inactiveBlur = saved.blur;\n delete saved.blur;\n }\n return { ...DEFAULT_APPEARANCE, ...saved };\n }\n catch { return DEFAULT_APPEARANCE; }\n}\n\n/** Reusable settings modal for widgets — renders appearance sliders + optional extra content above */\nexport default function WidgetSettingsModal({ open, onClose, title, appearance, onAppearanceChange, onSave, children }: {\n open: boolean;\n onClose: () => void;\n title: string;\n appearance: WidgetAppearance;\n onAppearanceChange: (a: WidgetAppearance) => void;\n onSave: () => void;\n children?: React.ReactNode;\n}) {\n if (!open) return null;\n\n const inp = 'w-full h-1.5 rounded-full appearance-none bg-gray-200 cursor-pointer accent-blue-500';\n const lbl = 'flex items-center justify-between text-xs text-gray-500';\n\n // stopPropagation keeps a right-click inside the settings dialog from\n // reaching the widget underneath and opening the widget's own menu. It also\n // stops the event before the shell's global contextmenu listener can see it,\n // so without preventDefault the browser's native menu would show here. A\n // text field in `children` still keeps that menu, as it does everywhere else\n // in the shell — spellcheck and Paste are the browser's.\n return (\n <div\n onPointerDown={e => e.stopPropagation()}\n onContextMenu={e => {\n e.stopPropagation();\n if (!keepsNativeMenu(e.target)) e.preventDefault();\n }}\n >\n <Modal open={open} onClose={onClose} title={title} size=\"sm\">\n <div className=\"space-y-4\">\n {children}\n\n {/* Appearance */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-3\">Appearance</h3>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <div className=\"text-xs font-medium text-gray-600 mb-2\">Active</div>\n <div className=\"space-y-2\">\n <div>\n <div className={lbl}><span>Opacity</span><span>{appearance.activeOpacity}%</span></div>\n <input type=\"range\" min={20} max={100} value={appearance.activeOpacity}\n onChange={e => onAppearanceChange({ ...appearance, activeOpacity: +e.target.value })} className={inp} />\n </div>\n <div>\n <div className={lbl}><span>Blur</span><span>{appearance.activeBlur}px</span></div>\n <input type=\"range\" min={0} max={20} value={appearance.activeBlur}\n onChange={e => onAppearanceChange({ ...appearance, activeBlur: +e.target.value })} className={inp} />\n </div>\n </div>\n </div>\n <div>\n <div className=\"text-xs font-medium text-gray-600 mb-2\">Inactive</div>\n <div className=\"space-y-2\">\n <div>\n <div className={lbl}><span>Opacity</span><span>{appearance.inactiveOpacity}%</span></div>\n <input type=\"range\" min={20} max={100} value={appearance.inactiveOpacity}\n onChange={e => onAppearanceChange({ ...appearance, inactiveOpacity: +e.target.value })} className={inp} />\n </div>\n <div>\n <div className={lbl}><span>Blur</span><span>{appearance.inactiveBlur}px</span></div>\n <input type=\"range\" min={0} max={20} value={appearance.inactiveBlur}\n onChange={e => onAppearanceChange({ ...appearance, inactiveBlur: +e.target.value })} className={inp} />\n </div>\n </div>\n </div>\n </div>\n </div>\n\n {/* Actions */}\n <div className=\"flex gap-2 pt-2\">\n <button onClick={onSave}\n className=\"flex-1 text-sm font-medium py-2 rounded-lg bg-blue-600 text-white hover:bg-blue-700 transition\">Save</button>\n <button onClick={onClose}\n className=\"flex-1 text-sm font-medium py-2 rounded-lg border border-gray-300 text-gray-600 hover:bg-gray-50 transition\">Cancel</button>\n </div>\n </div>\n </Modal>\n </div>\n );\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { toast_default } from './chunk-
|
|
1
|
+
import { toast_default } from './chunk-EENVXIVU.js';
|
|
2
2
|
import { createContext, useContext, useRef, useState, useEffect } from 'react';
|
|
3
3
|
import * as pdfjsLib from 'pdfjs-dist';
|
|
4
4
|
import { createPortal } from 'react-dom';
|
|
@@ -412,5 +412,5 @@ function PdfViewer({ url, filename, fit = "width", onDownload, onEmail }) {
|
|
|
412
412
|
}
|
|
413
413
|
|
|
414
414
|
export { PanelActions, PdfViewer, ToolbarSlotContext, fitScale };
|
|
415
|
-
//# sourceMappingURL=chunk-
|
|
416
|
-
//# sourceMappingURL=chunk-
|
|
415
|
+
//# sourceMappingURL=chunk-SEWF4O3H.js.map
|
|
416
|
+
//# sourceMappingURL=chunk-SEWF4O3H.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/apps/_wasmBytes.ts","../src/apps/_panelActions.tsx","../src/apps/PdfViewer.tsx"],"names":["jsx"],"mappings":"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","file":"chunk-FQB24B42.js","sourcesContent":["/**\n * Is what came back over the wire actually a WebAssembly module?\n *\n * `Preview`'s wasm factory used to accept any `res.ok` response. That is not\n * enough on a single-page app: an SPA host answers a path its router does not\n * recognise with its own index.html under HTTP 200, so a build that failed to\n * emit a decoder returns a PAGE rather than a 404 (confirmed against the live\n * console on 2026-08-30 — both `/assets/jbig2.wasm` and a made-up asset path\n * answered 200 with `content-type: text/html`). pdf.js then instantiates the\n * page inside a `try` that only warns before dropping to its JS fallback, which\n * is the same quiet degrading the factory was added to remove — except now\n * nothing in the console points at the emit as the cause.\n *\n * This module is deliberately free of React and of pdfjs-dist so it can be\n * driven directly from a spec. Importing `Preview.tsx` in a Node test is not\n * possible: pdfjs builds a `new DOMMatrix()` at module scope and throws.\n */\n\n/** Every WebAssembly module opens with the four bytes `\\0asm`. Anything else —\n * an HTML fallback page, most often — is not one. */\nexport function hasWasmPreamble(bytes: Uint8Array): boolean {\n return (\n bytes.length >= 4 &&\n bytes[0] === 0x00 &&\n bytes[1] === 0x61 &&\n bytes[2] === 0x73 &&\n bytes[3] === 0x6d\n );\n}\n\n/** A short, safe description of what arrived instead, for the error message.\n * The opening bytes of an HTML page name the problem far better than a length\n * does, so they are worth quoting; the cap keeps a stray binary out of the\n * console. */\nexport function describeNonWasm(bytes: Uint8Array): string {\n if (bytes.length === 0) return 'an empty response';\n const head = Array.from(bytes.subarray(0, 24))\n .map(b => (b >= 0x20 && b < 0x7f ? String.fromCharCode(b) : '.'))\n .join('');\n return `${bytes.length} bytes starting \"${head}\"`;\n}\n\n/** The message a developer reads when the emit went missing. It has to name the\n * emit, because the symptom they are looking at is a preview that renders\n * everything except the scanned page, with a silent console. */\nexport function wasmBytesError(href: string, filename: string, bytes: Uint8Array): Error {\n return new Error(\n `The response for ${href} is not a WebAssembly module (got ` +\n `${describeNonWasm(bytes)}). The bundler did not emit \"${filename}\" as ` +\n `an asset, and the host answered with a fallback page instead of a 404. ` +\n `Serve pdfjs-dist/wasm/ yourself and point ` +\n `window.__REACT_OS_SHELL_PDF_WASM__ at it.`,\n );\n}\n","/**\n * Where a format panel's toolbar buttons go.\n *\n * Inside the Preview window there is one toolbar row — Open, the filename,\n * then a slot at its right end — and each panel (PDF, DXF, 3D, image) portals\n * its own page nav / zoom / layer / download buttons into that slot rather\n * than stacking a second row under it. `ToolbarSlotContext` carries the slot\n * element down.\n *\n * Outside Preview there is no slot, and there is no outer toolbar to merge\n * with either: an embedded `PdfViewer` is the whole widget. So the fallback\n * renders the buttons in place as the panel's own toolbar. It used to return\n * `null`, which was right while every panel lived in a window and wrong the\n * moment one did not — an embedded viewer with no page nav and no zoom.\n */\nimport { createContext, useContext } from 'react';\nimport { createPortal } from 'react-dom';\n\nexport const ToolbarSlotContext = createContext<HTMLElement | null>(null);\n\nexport function PanelActions({ children }: { children: React.ReactNode }) {\n const slot = useContext(ToolbarSlotContext);\n if (slot) return createPortal(children, slot);\n return (\n <div className=\"flex shrink-0 items-center gap-1 border-b border-gray-200 bg-gray-50 px-3 py-2 text-xs\">\n {children}\n </div>\n );\n}\n","/**\n * PdfViewer — the pdf.js reader, on its own so it can be embedded.\n *\n * It was the Preview window's private `PdfPanel` until a consumer needed a PDF\n * inside a dialog rather than in a window of its own. The two consumers that\n * needed one had each reached for `<iframe src={blobUrl}>`, which hands the\n * page to the BROWSER's built-in plugin: its own toolbar, a ~250px thumbnail\n * rail, and its own idea of the zoom — roughly a third of an already small\n * pane spent on chrome nobody asked for, and a portrait page cropped at the\n * fold. Nothing about that is themeable or testable, and it is not this\n * package's viewer.\n *\n * Import it lazily (`react-os-shell/apps` exports it wrapped in `lazy`, like\n * the other document apps) and render it inside a `<Suspense>`: the static\n * `pdfjs-dist` import below must not reach a host's startup bundle. Give it a\n * parent with a resolved height — it fills its container and scrolls inside.\n */\nimport { useState, useEffect, useRef } from 'react';\nimport * as pdfjsLib from 'pdfjs-dist';\nimport toast from '../shell/toast';\nimport { hasWasmPreamble, wasmBytesError } from './_wasmBytes';\nimport { PanelActions } from './_panelActions';\n\n// Default the worker to the matching unpkg build (mirrors the consumer's\n// installed npm version exactly). Consumers can override by setting\n// pdfjsLib.GlobalWorkerOptions.workerSrc themselves before this module loads.\nif (typeof window !== 'undefined' && !pdfjsLib.GlobalWorkerOptions.workerSrc) {\n pdfjsLib.GlobalWorkerOptions.workerSrc =\n `https://unpkg.com/pdfjs-dist@${pdfjsLib.version}/build/pdf.worker.min.mjs`;\n}\n\n// pdf.js does not ship its JBIG2 and JPEG 2000 decoders as JavaScript any\n// more: both are WebAssembly modules it loads at decode time, and it will only\n// load them from a location the caller supplies. With neither `wasmUrl` nor a\n// `BinaryDataFactory` configured — this package's state until now — the\n// decoder asks for one, pdf.js's own base factory throws \"Ensure that the\n// `wasmUrl` API parameter is provided\", and the worker swallows that as a\n// `warn()`. The page still renders; the scanned or JPEG-2000 image on it is\n// just missing. Nothing reaches the user, which is why it went unnoticed.\n//\n// The fix follows the mechanism the admin portal already uses for the pdf\n// WORKER (`import ... from 'pdfjs-dist/build/pdf.worker.min.mjs?url'`, which\n// Vite emits as /assets/pdf.worker.min-<hash>.mjs): let the CONSUMER'S bundler\n// emit the file and hand pdf.js the URL it produced. `new URL(spec,\n// import.meta.url)` is the bundler-neutral spelling of that — Vite resolves\n// the bare specifier and emits the binary as its own hashed asset (verified on\n// Vite 5 and 7), and a bundler that does not understand the form leaves it\n// alone and lands back on today's warn-and-degrade rather than on an error.\n//\n// The specifier points at the CONSUMER'S installed `pdfjs-dist`, not at a copy\n// vendored into this package. That is deliberate: these binaries are built\n// alongside the worker that instantiates them, and a vendored copy would pin\n// them to THIS package's devDependency instead of to the peer they actually\n// run against.\nconst PDF_WASM_MODULES: Record<string, string> = {\n 'jbig2.wasm': new URL('pdfjs-dist/wasm/jbig2.wasm', import.meta.url).href,\n 'openjpeg.wasm': new URL('pdfjs-dist/wasm/openjpeg.wasm', import.meta.url).href,\n};\n\n/** pdf.js instantiates this itself (it is passed to `getDocument` as a class,\n * not an instance) and calls `fetch` once per binary it needs.\n *\n * Only the `wasmUrl` kind is served. cMap and standard-font data are the other\n * two kinds pdf.js can ask for, and this package has never configured a URL\n * for either — so those keep the exact message pdf.js's own base factory\n * raises for an unconfigured URL, and behave as they always have. */\nclass BundledPdfWasmFactory {\n async fetch({ kind, filename }: { kind: string; filename: string }): Promise<Uint8Array> {\n if (kind !== 'wasmUrl') {\n throw new Error(`Ensure that the \\`${kind}\\` API parameter is provided.`);\n }\n const href = PDF_WASM_MODULES[filename];\n if (!href) {\n throw new Error(`No bundled pdf.js wasm module for \"${filename}\".`);\n }\n const res = await fetch(href);\n if (!res.ok) {\n throw new Error(`Unable to load wasm data at: ${href}`);\n }\n // A 200 is not proof the bundler emitted the binary — see _wasmBytes.ts.\n const bytes = new Uint8Array(await res.arrayBuffer());\n if (!hasWasmPreamble(bytes)) {\n throw wasmBytesError(href, filename, bytes);\n }\n return bytes;\n }\n}\n\n/** The `getDocument` parameters that give pdf.js somewhere to load its wasm\n * decoders from.\n *\n * A consumer that serves the whole `pdfjs-dist/wasm/` directory itself (copied\n * into `public/`, say, or on an air-gapped host) points us at it with\n * `window.__REACT_OS_SHELL_PDF_WASM__` — same escape hatch as\n * `__REACT_OS_SHELL_O3DV_LIBS__` below. pdf.js requires a trailing slash on\n * that value and throws \"Invalid factory url\" without one, so add it here\n * rather than making every consumer remember. Everyone else gets the\n * bundler-emitted modules and configures nothing. */\nfunction pdfWasmParams(): { wasmUrl?: string; BinaryDataFactory?: object } {\n const dir = typeof window !== 'undefined'\n ? (window as unknown as { __REACT_OS_SHELL_PDF_WASM__?: unknown }).__REACT_OS_SHELL_PDF_WASM__\n : undefined;\n if (typeof dir === 'string' && dir) {\n return { wasmUrl: dir.endsWith('/') ? dir : `${dir}/` };\n }\n return { BinaryDataFactory: BundledPdfWasmFactory };\n}\n\nexport interface PdfViewerProps {\n /** Object URL or remote URL of the PDF. */\n url: string;\n /** Display name — also the filename the built-in Download uses. */\n filename: string;\n /**\n * What the auto-fit scale tracks until the reader picks a manual zoom.\n *\n * `'width'` fills the container's width and lets a tall page scroll — right\n * for a viewer that owns a whole window, and what the Preview app uses.\n * `'page'` fits the WHOLE page, which is what an embedded preview pane\n * wants: someone checking a document before sending it needs to see that it\n * is the right document, and a page cropped at the fold reads as broken.\n */\n fit?: 'width' | 'page';\n /** Replaces the built-in \"save `url` as `filename`\" download. */\n onDownload?: () => void;\n /** An Email button joins the toolbar only when this is supplied. */\n onEmail?: () => void;\n}\n\nconst ZOOM_PRESETS = [50, 75, 100, 125, 150, 200, 300, 400];\n\n/** The `p-4` gutter the page sits in, on both axes. */\nconst PAGE_GUTTER = 40;\nconst MIN_SCALE = 0.3;\nconst MAX_SCALE = 4;\n\n/**\n * The scale auto-fit lands on.\n *\n * @internal Exported for the spec. The effect that calls it needs a rendered\n * document and a laid-out container to reach, and the wrong answer here does\n * not throw — it crops the page at the fold, which reads as a broken preview\n * rather than as a bug in a formula.\n */\nexport function fitScale(\n fit: 'width' | 'page',\n container: { width: number; height: number },\n page: { width: number; height: number },\n): number {\n const byWidth = (container.width - PAGE_GUTTER) / page.width;\n // Fitting the PAGE means neither axis may overflow, so take whichever\n // constraint binds first. Width alone is what crops a portrait page in a\n // pane wider than it is tall.\n const wanted = fit === 'page'\n ? Math.min(byWidth, (container.height - PAGE_GUTTER) / page.height)\n : byWidth;\n return Math.min(Math.max(wanted, MIN_SCALE), MAX_SCALE);\n}\n\n// Trimmed copy of pdf.js's text-layer rules (pdf_viewer.css), under our own\n// class name so a consumer that loads the full viewer CSS doesn't\n// double-apply. The layer is a sheet of transparent spans positioned over\n// the canvas glyphs — that's what makes the rendered page selectable. Span\n// positions are % of page size; font-size derives from\n// --total-scale-factor, which the render effect sets to the viewport scale.\n// The .endOfContent sentinel plus the .selecting toggle keep a\n// drag-selection alive between lines and past the last line (same trick as\n// pdf.js's own TextLayerBuilder).\nconst TEXT_LAYER_CSS = `\n.preview-pdf-textlayer {\n position: absolute;\n inset: 0;\n overflow: clip;\n line-height: 1;\n text-align: initial;\n text-size-adjust: none;\n forced-color-adjust: none;\n transform-origin: 0 0;\n caret-color: CanvasText;\n --min-font-size: 1;\n --text-scale-factor: calc(var(--total-scale-factor, 1) * var(--min-font-size));\n --min-font-size-inv: calc(1 / var(--min-font-size));\n}\n.preview-pdf-textlayer :is(span, br) {\n color: transparent;\n position: absolute;\n white-space: pre;\n cursor: text;\n transform-origin: 0% 0%;\n}\n.preview-pdf-textlayer > :not(.markedContent),\n.preview-pdf-textlayer .markedContent span:not(.markedContent) {\n z-index: 1;\n --font-height: 0;\n font-size: calc(var(--text-scale-factor) * var(--font-height));\n --scale-x: 1;\n --rotate: 0deg;\n transform: rotate(var(--rotate)) scaleX(var(--scale-x)) scale(var(--min-font-size-inv));\n}\n.preview-pdf-textlayer .markedContent {\n display: contents;\n}\n.preview-pdf-textlayer span[role=\"img\"] {\n user-select: none;\n cursor: default;\n}\n.preview-pdf-textlayer ::selection {\n background: rgba(0, 80, 255, 0.25);\n}\n.preview-pdf-textlayer br::selection {\n background: transparent;\n}\n.preview-pdf-textlayer .endOfContent {\n display: block;\n position: absolute;\n inset: 100% 0 0;\n z-index: 0;\n cursor: default;\n user-select: none;\n}\n.preview-pdf-textlayer.selecting .endOfContent {\n top: 0;\n}\n`;\n\nexport default function PdfViewer({ url, filename, fit = 'width', onDownload, onEmail }: PdfViewerProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const textLayerRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const [pdf, setPdf] = useState<pdfjsLib.PDFDocumentProxy | null>(null);\n const [page, setPage] = useState(1);\n const [totalPages, setTotalPages] = useState(0);\n const [scale, setScale] = useState(1);\n // Fit mode is the default — scale stays auto-tracking the container width\n // until the user picks a manual zoom (− / + / dropdown). Re-armed by the\n // Fit toolbar button.\n const [fitMode, setFitMode] = useState(true);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n // A new document starts at its first page. The page number belongs to the\n // document being read, not to the viewer, and it used to survive a change\n // of `url`: sitting on page 3 and being handed a one-page document asked\n // pdf.js for a page that does not exist, and the canvas went blank with\n // nothing thrown. The Preview window never saw it because it keys its\n // panels by url, but an embedder that re-renders one viewer with a new\n // document — a preview pane next to the options that regenerate it — is\n // exactly the shape this component was extracted for.\n //\n // Reset before the fetch, not in its `.then`: the manual page controls are\n // live while a document loads, and a reset that landed afterwards would\n // undo a page the reader had already picked.\n //\n // Zoom is deliberately NOT reset. It is the reader's own preference for\n // how large they want text, and it holds across documents the way it does\n // in every reader; only the page is a fact about the file.\n setPage(1);\n // Parameter-object form, not the bare string: pdfjs-dist 6.x removed the\n // string overload (\"expected either `data`, `range`, or `url` parameter\"),\n // so a consumer on 6.x had every preview die on this line. The object form\n // works on 5.x too. tests/pdfjsContract.test.ts fails if it reverts.\n pdfjsLib.getDocument({ url, ...pdfWasmParams() }).promise.then(doc => {\n if (cancelled) return;\n setPdf(doc);\n setTotalPages(doc.numPages);\n setLoading(false);\n }).catch(() => {\n if (!cancelled) { toast.error('Failed to load PDF'); setLoading(false); }\n });\n return () => { cancelled = true; };\n }, [url]);\n\n // Auto-fit: re-compute scale from the container whenever fit mode is on, the\n // document changes, the page changes, or the container resizes. Window\n // resize and Modal drag-resize both trigger ResizeObserver. Manual zoom\n // turns this off until the user clicks Fit again.\n useEffect(() => {\n if (!pdf || !fitMode || !containerRef.current) return;\n const recompute = () => {\n const el = containerRef.current;\n if (!el) return;\n pdf.getPage(page).then(p => {\n if (!containerRef.current) return;\n const viewport = p.getViewport({ scale: 1 });\n const next = fitScale(\n fit,\n { width: el.clientWidth, height: el.clientHeight },\n { width: viewport.width, height: viewport.height },\n );\n setScale(prev => (Math.abs(prev - next) < 0.005 ? prev : next));\n });\n };\n recompute();\n const ro = new ResizeObserver(recompute);\n ro.observe(containerRef.current);\n return () => ro.disconnect();\n }, [pdf, page, fitMode, fit]);\n\n useEffect(() => {\n if (!pdf || !canvasRef.current) return;\n let cancelled = false;\n let task: { cancel: () => void; promise: Promise<void> } | null = null;\n let textLayer: pdfjsLib.TextLayer | null = null;\n pdf.getPage(page).then(p => {\n if (cancelled || !canvasRef.current) return;\n const viewport = p.getViewport({ scale });\n const canvas = canvasRef.current;\n canvas.width = viewport.width;\n canvas.height = viewport.height;\n // Lock the displayed (CSS) size to the viewport. pdf.js stamps inline\n // style.width/height on render and inline values stick across re-renders\n // even when canvas.width shrinks — without this, zoom changes only\n // affect resolution, not visible size.\n canvas.style.width = `${viewport.width}px`;\n canvas.style.height = `${viewport.height}px`;\n const ctx = canvas.getContext('2d')!;\n task = p.render({ canvas, canvasContext: ctx, viewport });\n task.promise.catch(() => {});\n // Selectable text layer — transparent spans over the canvas glyphs.\n // Rebuilt per page/zoom render; pdf.js reads --total-scale-factor for\n // span font-size and the container's own width/height.\n const textEl = textLayerRef.current;\n if (textEl) {\n textEl.replaceChildren();\n textEl.style.setProperty('--total-scale-factor', String(viewport.scale));\n textLayer = new pdfjsLib.TextLayer({\n textContentSource: p.streamTextContent(),\n container: textEl,\n viewport,\n });\n textLayer.render().then(() => {\n if (cancelled) return;\n const end = document.createElement('div');\n end.className = 'endOfContent';\n textEl.append(end);\n }).catch(() => {});\n }\n });\n return () => {\n cancelled = true;\n task?.cancel();\n textLayer?.cancel();\n };\n }, [pdf, page, scale]);\n\n // End a selection drag wherever the pointer is released — the .selecting\n // class is added on pointerdown in the layer itself (see JSX below).\n useEffect(() => {\n const up = () => textLayerRef.current?.classList.remove('selecting');\n window.addEventListener('pointerup', up);\n return () => window.removeEventListener('pointerup', up);\n }, []);\n\n const handlePrint = () => {\n if (!pdf) return;\n const win = window.open('', '_blank');\n if (!win) { toast.error('Allow popups to print'); return; }\n const promises: Promise<string>[] = [];\n for (let i = 1; i <= totalPages; i++) {\n promises.push(pdf.getPage(i).then(p => {\n const vp = p.getViewport({ scale: 2 });\n const c = document.createElement('canvas');\n c.width = vp.width; c.height = vp.height;\n return p.render({ canvas: c, canvasContext: c.getContext('2d')!, viewport: vp }).promise.then(() => c.toDataURL());\n }));\n }\n Promise.all(promises).then(images => {\n win.document.write(`<html><head><title>${filename}</title><style>@media print{body{margin:0}img{width:100%;page-break-after:always}}</style></head><body>`);\n win.document.write(images.map(src => `<img src=\"${src}\"/>`).join(''));\n win.document.write('</body></html>');\n win.document.close();\n setTimeout(() => { win.print(); win.close(); }, 300);\n });\n };\n\n const handleDefaultDownload = () => {\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n a.click();\n };\n\n // Re-arm fit mode. The auto-fit effect picks the new scale on its next\n // tick once `fitMode` flips to true.\n const reFit = () => setFitMode(true);\n const fitLabel = fit === 'page' ? 'Fit page' : 'Fit width';\n\n // Wheel and keyboard page navigation. Only takes the wheel event when\n // the container is at the top/bottom edge — otherwise normal scroll\n // moves through a tall page first, matching native PDF readers.\n const onWheelPage = (e: React.WheelEvent<HTMLDivElement>) => {\n if (!pdf) return;\n if (e.ctrlKey || e.metaKey) return; // browser-zoom shortcut, leave alone\n const el = containerRef.current;\n if (!el) return;\n const atTop = el.scrollTop <= 0;\n const atBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - 1;\n if (e.deltaY > 0 && atBottom && page < totalPages) {\n e.preventDefault();\n setPage(p => Math.min(totalPages, p + 1));\n // Land at the top of the next page so wheel-down keeps reading\n // forward. requestAnimationFrame so the canvas has a tick to\n // resize before we scroll.\n requestAnimationFrame(() => { if (containerRef.current) containerRef.current.scrollTop = 0; });\n } else if (e.deltaY < 0 && atTop && page > 1) {\n e.preventDefault();\n setPage(p => Math.max(1, p - 1));\n requestAnimationFrame(() => {\n if (containerRef.current) containerRef.current.scrollTop = containerRef.current.scrollHeight;\n });\n }\n };\n const onKeyPage = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (!pdf) return;\n // Ignore keyboard nav when an input/textarea has focus.\n const tag = (document.activeElement?.tagName || '').toLowerCase();\n if (tag === 'input' || tag === 'textarea' || (document.activeElement as HTMLElement)?.isContentEditable) return;\n if (e.key === 'PageDown' || e.key === 'ArrowRight') {\n if (page < totalPages) { e.preventDefault(); setPage(p => Math.min(totalPages, p + 1)); }\n } else if (e.key === 'PageUp' || e.key === 'ArrowLeft') {\n if (page > 1) { e.preventDefault(); setPage(p => Math.max(1, p - 1)); }\n } else if (e.key === 'Home') {\n e.preventDefault(); setPage(1);\n } else if (e.key === 'End') {\n e.preventDefault(); setPage(totalPages);\n }\n };\n\n const btn = 'px-2 py-1 rounded hover:bg-gray-200 transition-colors text-gray-600 flex items-center gap-1';\n\n return (\n <div className=\"flex flex-col h-full\">\n <PanelActions>\n <button aria-label=\"Previous page\" onClick={() => setPage(p => Math.max(1, p - 1))} disabled={page <= 1} className=\"px-1 py-1 rounded hover:bg-gray-200 disabled:opacity-30 text-gray-600\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15.75 19.5L8.25 12l7.5-7.5\" /></svg>\n </button>\n <span className=\"text-gray-600 font-medium tabular-nums\">{page} / {totalPages}</span>\n <button aria-label=\"Next page\" onClick={() => setPage(p => Math.min(totalPages, p + 1))} disabled={page >= totalPages} className=\"px-1 py-1 rounded hover:bg-gray-200 disabled:opacity-30 text-gray-600\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M8.25 4.5l7.5 7.5-7.5 7.5\" /></svg>\n </button>\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <button\n onClick={() => { setFitMode(false); setScale(s => Math.max(0.3, Math.round((s - 0.25) * 100) / 100)); }}\n className={btn}\n >−</button>\n <select\n value={fitMode ? 'fit' : (ZOOM_PRESETS.includes(Math.round(scale * 100)) ? Math.round(scale * 100) : 'custom')}\n onChange={e => {\n const v = e.target.value;\n if (v === 'fit') { setFitMode(true); return; }\n if (v !== 'custom') { setFitMode(false); setScale(Number(v) / 100); }\n }}\n className=\"bg-transparent hover:bg-gray-200 rounded px-1 py-1 text-gray-600 tabular-nums cursor-pointer focus:outline-none focus:ring-1 focus:ring-blue-400\"\n title=\"Zoom\"\n >\n <option value=\"fit\">{fitLabel}</option>\n {!fitMode && !ZOOM_PRESETS.includes(Math.round(scale * 100)) && (\n <option value=\"custom\">{Math.round(scale * 100)}%</option>\n )}\n {ZOOM_PRESETS.map(p => <option key={p} value={p}>{p}%</option>)}\n </select>\n <button\n onClick={() => { setFitMode(false); setScale(s => Math.min(4, Math.round((s + 0.25) * 100) / 100)); }}\n className={btn}\n >+</button>\n <button\n onClick={reFit}\n className={btn + (fitMode ? ' bg-gray-200 text-gray-900' : '')}\n title={`${fitLabel} — auto-tracks the container size until you zoom manually`}\n >Fit</button>\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <button onClick={handlePrint} className={btn}>\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6.72 13.829c-.24.03-.48.062-.72.096m.72-.096a42.415 42.415 0 0110.56 0m-10.56 0L6.34 18m10.94-4.171c.24.03.48.062.72.096m-.72-.096L17.66 18m0 0l.229 2.523a1.125 1.125 0 01-1.12 1.227H7.231c-.662 0-1.18-.568-1.12-1.227L6.34 18m11.318 0h1.091A2.25 2.25 0 0021 15.75V9.456c0-1.081-.768-2.015-1.837-2.175a48.055 48.055 0 00-1.913-.247M6.34 18H5.25A2.25 2.25 0 013 15.75V9.456c0-1.081.768-2.015 1.837-2.175a48.041 48.041 0 011.913-.247m10.5 0a48.536 48.536 0 00-10.5 0m10.5 0V3.375c0-.621-.504-1.125-1.125-1.125h-8.25c-.621 0-1.125.504-1.125 1.125v3.659M18 10.5h.008v.008H18V10.5zm-3 0h.008v.008H15V10.5z\" /></svg>\n Print\n </button>\n <button onClick={onDownload ?? handleDefaultDownload} className={btn}>\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3\" /></svg>\n Download\n </button>\n {onEmail && (\n <button onClick={onEmail} className={btn}>\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75\" /></svg>\n Email\n </button>\n )}\n </PanelActions>\n\n <div\n ref={containerRef}\n className=\"flex-1 overflow-auto bg-gray-100 outline-none\"\n // tabIndex makes the scroll container itself focusable so PageUp /\n // PageDown / Arrow keys are captured even when no inner element\n // has focus (e.g. right after the panel mounts). Wheel handler\n // page-flips when the user reaches the top/bottom of a long page.\n tabIndex={0}\n onWheel={onWheelPage}\n onKeyDown={onKeyPage}\n >\n {loading ? (\n <div className=\"flex items-center justify-center h-full text-gray-400 text-sm\">Loading PDF...</div>\n ) : (\n <div className=\"min-h-full flex items-center justify-center p-4\">\n <style>{TEXT_LAYER_CSS}</style>\n <div className=\"relative shadow-lg rounded\">\n <canvas ref={canvasRef} className=\"block rounded\" />\n <div\n ref={textLayerRef}\n className=\"preview-pdf-textlayer\"\n onPointerDown={e => e.currentTarget.classList.add('selecting')}\n />\n </div>\n </div>\n )}\n </div>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/apps/_wasmBytes.ts","../src/apps/_panelActions.tsx","../src/apps/PdfViewer.tsx"],"names":["jsx"],"mappings":";;;;;;;AAoBO,SAAS,gBAAgB,KAAA,EAA4B;AAC1D,EAAA,OACE,MAAM,MAAA,IAAU,CAAA,IAChB,KAAA,CAAM,CAAC,MAAM,CAAA,IACb,KAAA,CAAM,CAAC,CAAA,KAAM,MACb,KAAA,CAAM,CAAC,MAAM,GAAA,IACb,KAAA,CAAM,CAAC,CAAA,KAAM,GAAA;AAEjB;AAMO,SAAS,gBAAgB,KAAA,EAA2B;AACzD,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,mBAAA;AAC/B,EAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA,EAAG,EAAE,CAAC,CAAA,CAC1C,GAAA,CAAI,CAAA,CAAA,KAAM,KAAK,EAAA,IAAQ,CAAA,GAAI,MAAO,MAAA,CAAO,YAAA,CAAa,CAAC,CAAA,GAAI,GAAI,CAAA,CAC/D,IAAA,CAAK,EAAE,CAAA;AACV,EAAA,OAAO,CAAA,EAAG,KAAA,CAAM,MAAM,CAAA,iBAAA,EAAoB,IAAI,CAAA,CAAA,CAAA;AAChD;AAKO,SAAS,cAAA,CAAe,IAAA,EAAc,QAAA,EAAkB,KAAA,EAA0B;AACvF,EAAA,OAAO,IAAI,KAAA;AAAA,IACT,oBAAoB,IAAI,CAAA,kCAAA,EACnB,gBAAgB,KAAK,CAAC,gCAAgC,QAAQ,CAAA,+JAAA;AAAA,GAIrE;AACF;ACnCO,IAAM,kBAAA,GAAqB,cAAkC,IAAI;AAEjE,SAAS,YAAA,CAAa,EAAE,QAAA,EAAS,EAAkC;AACxE,EAAA,MAAM,IAAA,GAAO,WAAW,kBAAkB,CAAA;AAC1C,EAAA,IAAI,IAAA,EAAM,OAAO,YAAA,CAAa,QAAA,EAAU,IAAI,CAAA;AAC5C,EAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wFAAA,EACZ,QAAA,EACH,CAAA;AAEJ;ACFA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,CAAU,6BAAoB,SAAA,EAAW;AAC5E,EAAS,QAAA,CAAA,mBAAA,CAAoB,SAAA,GAC3B,CAAA,6BAAA,EAAyC,QAAA,CAAA,OAAO,CAAA,yBAAA,CAAA;AACpD;AAyBA,IAAM,gBAAA,GAA2C;AAAA,EAC/C,cAAc,IAAI,GAAA,CAAI,4BAAA,EAA8B,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA,CAAE,IAAA;AAAA,EACrE,iBAAiB,IAAI,GAAA,CAAI,+BAAA,EAAiC,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA,CAAE;AAC7E,CAAA;AASA,IAAM,wBAAN,MAA4B;AAAA,EAC1B,MAAM,KAAA,CAAM,EAAE,IAAA,EAAM,UAAS,EAA4D;AACvF,IAAA,IAAI,SAAS,SAAA,EAAW;AACtB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kBAAA,EAAqB,IAAI,CAAA,6BAAA,CAA+B,CAAA;AAAA,IAC1E;AACA,IAAA,MAAM,IAAA,GAAO,iBAAiB,QAAQ,CAAA;AACtC,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mCAAA,EAAsC,QAAQ,CAAA,EAAA,CAAI,CAAA;AAAA,IACpE;AACA,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,IAAI,CAAA;AAC5B,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,6BAAA,EAAgC,IAAI,CAAA,CAAE,CAAA;AAAA,IACxD;AAEA,IAAA,MAAM,QAAQ,IAAI,UAAA,CAAW,MAAM,GAAA,CAAI,aAAa,CAAA;AACpD,IAAA,IAAI,CAAC,eAAA,CAAgB,KAAK,CAAA,EAAG;AAC3B,MAAA,MAAM,cAAA,CAAe,IAAA,EAAM,QAAA,EAAU,KAAK,CAAA;AAAA,IAC5C;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AACF,CAAA;AAYA,SAAS,aAAA,GAAkE;AACzE,EAAA,MAAM,GAAA,GAAM,OAAO,MAAA,KAAW,WAAA,GACzB,OAAgE,2BAAA,GACjE,MAAA;AACJ,EAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,IAAY,GAAA,EAAK;AAClC,IAAA,OAAO,EAAE,SAAS,GAAA,CAAI,QAAA,CAAS,GAAG,CAAA,GAAI,GAAA,GAAM,CAAA,EAAG,GAAG,CAAA,CAAA,CAAA,EAAI;AAAA,EACxD;AACA,EAAA,OAAO,EAAE,mBAAmB,qBAAA,EAAsB;AACpD;AAuBA,IAAM,YAAA,GAAe,CAAC,EAAA,EAAI,EAAA,EAAI,KAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA;AAG1D,IAAM,WAAA,GAAc,EAAA;AACpB,IAAM,SAAA,GAAY,GAAA;AAClB,IAAM,SAAA,GAAY,CAAA;AAUX,SAAS,QAAA,CACd,GAAA,EACA,SAAA,EACA,IAAA,EACQ;AACR,EAAA,MAAM,OAAA,GAAA,CAAW,SAAA,CAAU,KAAA,GAAQ,WAAA,IAAe,IAAA,CAAK,KAAA;AAIvD,EAAA,MAAM,MAAA,GAAS,GAAA,KAAQ,MAAA,GACnB,IAAA,CAAK,GAAA,CAAI,OAAA,EAAA,CAAU,SAAA,CAAU,MAAA,GAAS,WAAA,IAAe,IAAA,CAAK,MAAM,CAAA,GAChE,OAAA;AACJ,EAAA,OAAO,KAAK,GAAA,CAAI,IAAA,CAAK,IAAI,MAAA,EAAQ,SAAS,GAAG,SAAS,CAAA;AACxD;AAWA,IAAM,cAAA,GAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAyDR,SAAR,SAAA,CAA2B,EAAE,GAAA,EAAK,QAAA,EAAU,MAAM,OAAA,EAAS,UAAA,EAAY,SAAQ,EAAmB;AACvG,EAAA,MAAM,SAAA,GAAY,OAA0B,IAAI,CAAA;AAChD,EAAA,MAAM,YAAA,GAAe,OAAuB,IAAI,CAAA;AAChD,EAAA,MAAM,YAAA,GAAe,OAAuB,IAAI,CAAA;AAChD,EAAA,MAAM,CAAC,GAAA,EAAK,MAAM,CAAA,GAAI,SAA2C,IAAI,CAAA;AACrE,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,CAAC,CAAA;AAClC,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAS,CAAC,CAAA;AAC9C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,CAAC,CAAA;AAIpC,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,IAAI,CAAA;AAC3C,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,IAAI,CAAA;AAE3C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,UAAA,CAAW,IAAI,CAAA;AAiBf,IAAA,OAAA,CAAQ,CAAC,CAAA;AAKT,IAAS,QAAA,CAAA,WAAA,CAAY,EAAE,GAAA,EAAK,GAAG,aAAA,IAAiB,CAAA,CAAE,OAAA,CAAQ,IAAA,CAAK,CAAA,GAAA,KAAO;AACpE,MAAA,IAAI,SAAA,EAAW;AACf,MAAA,MAAA,CAAO,GAAG,CAAA;AACV,MAAA,aAAA,CAAc,IAAI,QAAQ,CAAA;AAC1B,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IAClB,CAAC,CAAA,CAAE,KAAA,CAAM,MAAM;AACb,MAAA,IAAI,CAAC,SAAA,EAAW;AAAE,QAAA,aAAA,CAAM,MAAM,oBAAoB,CAAA;AAAG,QAAA,UAAA,CAAW,KAAK,CAAA;AAAA,MAAG;AAAA,IAC1E,CAAC,CAAA;AACD,IAAA,OAAO,MAAM;AAAE,MAAA,SAAA,GAAY,IAAA;AAAA,IAAM,CAAA;AAAA,EACnC,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAMR,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,GAAA,IAAO,CAAC,OAAA,IAAW,CAAC,aAAa,OAAA,EAAS;AAC/C,IAAA,MAAM,YAAY,MAAM;AACtB,MAAA,MAAM,KAAK,YAAA,CAAa,OAAA;AACxB,MAAA,IAAI,CAAC,EAAA,EAAI;AACT,MAAA,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,KAAK;AAC1B,QAAA,IAAI,CAAC,aAAa,OAAA,EAAS;AAC3B,QAAA,MAAM,WAAW,CAAA,CAAE,WAAA,CAAY,EAAE,KAAA,EAAO,GAAG,CAAA;AAC3C,QAAA,MAAM,IAAA,GAAO,QAAA;AAAA,UACX,GAAA;AAAA,UACA,EAAE,KAAA,EAAO,EAAA,CAAG,WAAA,EAAa,MAAA,EAAQ,GAAG,YAAA,EAAa;AAAA,UACjD,EAAE,KAAA,EAAO,QAAA,CAAS,KAAA,EAAO,MAAA,EAAQ,SAAS,MAAA;AAAO,SACnD;AACA,QAAA,QAAA,CAAS,CAAA,IAAA,KAAS,KAAK,GAAA,CAAI,IAAA,GAAO,IAAI,CAAA,GAAI,IAAA,GAAQ,OAAO,IAAK,CAAA;AAAA,MAChE,CAAC,CAAA;AAAA,IACH,CAAA;AACA,IAAA,SAAA,EAAU;AACV,IAAA,MAAM,EAAA,GAAK,IAAI,cAAA,CAAe,SAAS,CAAA;AACvC,IAAA,EAAA,CAAG,OAAA,CAAQ,aAAa,OAAO,CAAA;AAC/B,IAAA,OAAO,MAAM,GAAG,UAAA,EAAW;AAAA,EAC7B,GAAG,CAAC,GAAA,EAAK,IAAA,EAAM,OAAA,EAAS,GAAG,CAAC,CAAA;AAE5B,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,GAAA,IAAO,CAAC,SAAA,CAAU,OAAA,EAAS;AAChC,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,IAAI,IAAA,GAA8D,IAAA;AAClE,IAAA,IAAI,SAAA,GAAuC,IAAA;AAC3C,IAAA,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,KAAK;AAC1B,MAAA,IAAI,SAAA,IAAa,CAAC,SAAA,CAAU,OAAA,EAAS;AACrC,MAAA,MAAM,QAAA,GAAW,CAAA,CAAE,WAAA,CAAY,EAAE,OAAO,CAAA;AACxC,MAAA,MAAM,SAAS,SAAA,CAAU,OAAA;AACzB,MAAA,MAAA,CAAO,QAAQ,QAAA,CAAS,KAAA;AACxB,MAAA,MAAA,CAAO,SAAS,QAAA,CAAS,MAAA;AAKzB,MAAA,MAAA,CAAO,KAAA,CAAM,KAAA,GAAQ,CAAA,EAAG,QAAA,CAAS,KAAK,CAAA,EAAA,CAAA;AACtC,MAAA,MAAA,CAAO,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,QAAA,CAAS,MAAM,CAAA,EAAA,CAAA;AACxC,MAAA,MAAM,GAAA,GAAM,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AAClC,MAAA,IAAA,GAAO,EAAE,MAAA,CAAO,EAAE,QAAQ,aAAA,EAAe,GAAA,EAAK,UAAU,CAAA;AACxD,MAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,MAAM;AAAA,MAAC,CAAC,CAAA;AAI3B,MAAA,MAAM,SAAS,YAAA,CAAa,OAAA;AAC5B,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,MAAA,CAAO,eAAA,EAAgB;AACvB,QAAA,MAAA,CAAO,MAAM,WAAA,CAAY,sBAAA,EAAwB,MAAA,CAAO,QAAA,CAAS,KAAK,CAAC,CAAA;AACvE,QAAA,SAAA,GAAY,IAAa,QAAA,CAAA,SAAA,CAAU;AAAA,UACjC,iBAAA,EAAmB,EAAE,iBAAA,EAAkB;AAAA,UACvC,SAAA,EAAW,MAAA;AAAA,UACX;AAAA,SACD,CAAA;AACD,QAAA,SAAA,CAAU,MAAA,EAAO,CAAE,IAAA,CAAK,MAAM;AAC5B,UAAA,IAAI,SAAA,EAAW;AACf,UAAA,MAAM,GAAA,GAAM,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AACxC,UAAA,GAAA,CAAI,SAAA,GAAY,cAAA;AAChB,UAAA,MAAA,CAAO,OAAO,GAAG,CAAA;AAAA,QACnB,CAAC,CAAA,CAAE,KAAA,CAAM,MAAM;AAAA,QAAC,CAAC,CAAA;AAAA,MACnB;AAAA,IACF,CAAC,CAAA;AACD,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AACZ,MAAA,IAAA,EAAM,MAAA,EAAO;AACb,MAAA,SAAA,EAAW,MAAA,EAAO;AAAA,IACpB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,GAAA,EAAK,IAAA,EAAM,KAAK,CAAC,CAAA;AAIrB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,KAAK,MAAM,YAAA,CAAa,OAAA,EAAS,SAAA,CAAU,OAAO,WAAW,CAAA;AACnE,IAAA,MAAA,CAAO,gBAAA,CAAiB,aAAa,EAAE,CAAA;AACvC,IAAA,OAAO,MAAM,MAAA,CAAO,mBAAA,CAAoB,WAAA,EAAa,EAAE,CAAA;AAAA,EACzD,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,cAAc,MAAM;AACxB,IAAA,IAAI,CAAC,GAAA,EAAK;AACV,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,IAAA,CAAK,EAAA,EAAI,QAAQ,CAAA;AACpC,IAAA,IAAI,CAAC,GAAA,EAAK;AAAE,MAAA,aAAA,CAAM,MAAM,uBAAuB,CAAA;AAAG,MAAA;AAAA,IAAQ;AAC1D,IAAA,MAAM,WAA8B,EAAC;AACrC,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,UAAA,EAAY,CAAA,EAAA,EAAK;AACpC,MAAA,QAAA,CAAS,KAAK,GAAA,CAAI,OAAA,CAAQ,CAAC,CAAA,CAAE,KAAK,CAAA,CAAA,KAAK;AACrC,QAAA,MAAM,KAAK,CAAA,CAAE,WAAA,CAAY,EAAE,KAAA,EAAO,GAAG,CAAA;AACrC,QAAA,MAAM,CAAA,GAAI,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AACzC,QAAA,CAAA,CAAE,QAAQ,EAAA,CAAG,KAAA;AAAO,QAAA,CAAA,CAAE,SAAS,EAAA,CAAG,MAAA;AAClC,QAAA,OAAO,EAAE,MAAA,CAAO,EAAE,QAAQ,CAAA,EAAG,aAAA,EAAe,EAAE,UAAA,CAAW,IAAI,GAAI,QAAA,EAAU,EAAA,EAAI,CAAA,CAAE,OAAA,CAAQ,KAAK,MAAM,CAAA,CAAE,WAAW,CAAA;AAAA,MACnH,CAAC,CAAC,CAAA;AAAA,IACJ;AACA,IAAA,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA,CAAE,IAAA,CAAK,CAAA,MAAA,KAAU;AACnC,MAAA,GAAA,CAAI,QAAA,CAAS,KAAA,CAAM,CAAA,mBAAA,EAAsB,QAAQ,CAAA,uGAAA,CAAyG,CAAA;AAC1J,MAAA,GAAA,CAAI,QAAA,CAAS,KAAA,CAAM,MAAA,CAAO,GAAA,CAAI,CAAA,GAAA,KAAO,CAAA,UAAA,EAAa,GAAG,CAAA,GAAA,CAAK,CAAA,CAAE,IAAA,CAAK,EAAE,CAAC,CAAA;AACpE,MAAA,GAAA,CAAI,QAAA,CAAS,MAAM,gBAAgB,CAAA;AACnC,MAAA,GAAA,CAAI,SAAS,KAAA,EAAM;AACnB,MAAA,UAAA,CAAW,MAAM;AAAE,QAAA,GAAA,CAAI,KAAA,EAAM;AAAG,QAAA,GAAA,CAAI,KAAA,EAAM;AAAA,MAAG,GAAG,GAAG,CAAA;AAAA,IACrD,CAAC,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,wBAAwB,MAAM;AAClC,IAAA,MAAM,CAAA,GAAI,QAAA,CAAS,aAAA,CAAc,GAAG,CAAA;AACpC,IAAA,CAAA,CAAE,IAAA,GAAO,GAAA;AACT,IAAA,CAAA,CAAE,QAAA,GAAW,QAAA;AACb,IAAA,CAAA,CAAE,KAAA,EAAM;AAAA,EACV,CAAA;AAIA,EAAA,MAAM,KAAA,GAAQ,MAAM,UAAA,CAAW,IAAI,CAAA;AACnC,EAAA,MAAM,QAAA,GAAW,GAAA,KAAQ,MAAA,GAAS,UAAA,GAAa,WAAA;AAK/C,EAAA,MAAM,WAAA,GAAc,CAAC,CAAA,KAAwC;AAC3D,IAAA,IAAI,CAAC,GAAA,EAAK;AACV,IAAA,IAAI,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,OAAA,EAAS;AAC5B,IAAA,MAAM,KAAK,YAAA,CAAa,OAAA;AACxB,IAAA,IAAI,CAAC,EAAA,EAAI;AACT,IAAA,MAAM,KAAA,GAAQ,GAAG,SAAA,IAAa,CAAA;AAC9B,IAAA,MAAM,WAAW,EAAA,CAAG,SAAA,GAAY,EAAA,CAAG,YAAA,IAAgB,GAAG,YAAA,GAAe,CAAA;AACrE,IAAA,IAAI,CAAA,CAAE,MAAA,GAAS,CAAA,IAAK,QAAA,IAAY,OAAO,UAAA,EAAY;AACjD,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,OAAA,CAAQ,OAAK,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,CAAA,GAAI,CAAC,CAAC,CAAA;AAIxC,MAAA,qBAAA,CAAsB,MAAM;AAAE,QAAA,IAAI,YAAA,CAAa,OAAA,EAAS,YAAA,CAAa,OAAA,CAAQ,SAAA,GAAY,CAAA;AAAA,MAAG,CAAC,CAAA;AAAA,IAC/F,WAAW,CAAA,CAAE,MAAA,GAAS,CAAA,IAAK,KAAA,IAAS,OAAO,CAAA,EAAG;AAC5C,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,OAAA,CAAQ,OAAK,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,CAAA,GAAI,CAAC,CAAC,CAAA;AAC/B,MAAA,qBAAA,CAAsB,MAAM;AAC1B,QAAA,IAAI,aAAa,OAAA,EAAS,YAAA,CAAa,OAAA,CAAQ,SAAA,GAAY,aAAa,OAAA,CAAQ,YAAA;AAAA,MAClF,CAAC,CAAA;AAAA,IACH;AAAA,EACF,CAAA;AACA,EAAA,MAAM,SAAA,GAAY,CAAC,CAAA,KAA2C;AAC5D,IAAA,IAAI,CAAC,GAAA,EAAK;AAEV,IAAA,MAAM,GAAA,GAAA,CAAO,QAAA,CAAS,aAAA,EAAe,OAAA,IAAW,IAAI,WAAA,EAAY;AAChE,IAAA,IAAI,QAAQ,OAAA,IAAW,GAAA,KAAQ,UAAA,IAAe,QAAA,CAAS,eAA+B,iBAAA,EAAmB;AACzG,IAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,UAAA,IAAc,CAAA,CAAE,QAAQ,YAAA,EAAc;AAClD,MAAA,IAAI,OAAO,UAAA,EAAY;AAAE,QAAA,CAAA,CAAE,cAAA,EAAe;AAAG,QAAA,OAAA,CAAQ,OAAK,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,CAAA,GAAI,CAAC,CAAC,CAAA;AAAA,MAAG;AAAA,IAC1F,WAAW,CAAA,CAAE,GAAA,KAAQ,QAAA,IAAY,CAAA,CAAE,QAAQ,WAAA,EAAa;AACtD,MAAA,IAAI,OAAO,CAAA,EAAG;AAAE,QAAA,CAAA,CAAE,cAAA,EAAe;AAAG,QAAA,OAAA,CAAQ,OAAK,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,CAAA,GAAI,CAAC,CAAC,CAAA;AAAA,MAAG;AAAA,IACxE,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,MAAA,EAAQ;AAC3B,MAAA,CAAA,CAAE,cAAA,EAAe;AAAG,MAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC/B,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,KAAA,EAAO;AAC1B,MAAA,CAAA,CAAE,cAAA,EAAe;AAAG,MAAA,OAAA,CAAQ,UAAU,CAAA;AAAA,IACxC;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,GAAA,GAAM,6FAAA;AAEZ,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sBAAA,EACb,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,YAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAAA,IAAC,QAAA,EAAA,EAAO,YAAA,EAAW,iBAAgB,OAAA,EAAS,MAAM,QAAQ,CAAA,CAAA,KAAK,IAAA,CAAK,IAAI,CAAA,EAAG,CAAA,GAAI,CAAC,CAAC,CAAA,EAAG,UAAU,IAAA,IAAQ,CAAA,EAAG,WAAU,uEAAA,EACjH,QAAA,kBAAAA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAc,IAAA,EAAK,MAAA,EAAO,SAAQ,WAAA,EAAY,MAAA,EAAO,gBAAe,WAAA,EAAa,CAAA,EAAG,0BAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,eAAc,OAAA,EAAQ,cAAA,EAAe,SAAQ,CAAA,EAAE,6BAAA,EAA8B,GAAE,CAAA,EAC1L,CAAA;AAAA,sBACA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,wCAAA,EAA0C,QAAA,EAAA;AAAA,QAAA,IAAA;AAAA,QAAK,KAAA;AAAA,QAAI;AAAA,OAAA,EAAW,CAAA;AAAA,sBAC9EA,IAAC,QAAA,EAAA,EAAO,YAAA,EAAW,aAAY,OAAA,EAAS,MAAM,QAAQ,CAAA,CAAA,KAAK,IAAA,CAAK,IAAI,UAAA,EAAY,CAAA,GAAI,CAAC,CAAC,CAAA,EAAG,UAAU,IAAA,IAAQ,UAAA,EAAY,WAAU,uEAAA,EAC/H,QAAA,kBAAAA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAc,IAAA,EAAK,MAAA,EAAO,SAAQ,WAAA,EAAY,MAAA,EAAO,gBAAe,WAAA,EAAa,CAAA,EAAG,0BAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,eAAc,OAAA,EAAQ,cAAA,EAAe,SAAQ,CAAA,EAAE,2BAAA,EAA4B,GAAE,CAAA,EACxL,CAAA;AAAA,sBACAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EAA4B,CAAA;AAAA,sBAC3CA,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,SAAS,MAAM;AAAE,YAAA,UAAA,CAAW,KAAK,CAAA;AAAG,YAAA,QAAA,CAAS,CAAA,CAAA,KAAK,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,IAAA,CAAK,KAAA,CAAA,CAAO,CAAA,GAAI,IAAA,IAAQ,GAAG,CAAA,GAAI,GAAG,CAAC,CAAA;AAAA,UAAG,CAAA;AAAA,UACtG,SAAA,EAAW,GAAA;AAAA,UACZ,QAAA,EAAA;AAAA;AAAA,OAAC;AAAA,sBACF,IAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAO,OAAA,GAAU,KAAA,GAAS,YAAA,CAAa,SAAS,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,GAAG,CAAC,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,GAAG,CAAA,GAAI,QAAA;AAAA,UACrG,UAAU,CAAA,CAAA,KAAK;AACb,YAAA,MAAM,CAAA,GAAI,EAAE,MAAA,CAAO,KAAA;AACnB,YAAA,IAAI,MAAM,KAAA,EAAO;AAAE,cAAA,UAAA,CAAW,IAAI,CAAA;AAAG,cAAA;AAAA,YAAQ;AAC7C,YAAA,IAAI,MAAM,QAAA,EAAU;AAAE,cAAA,UAAA,CAAW,KAAK,CAAA;AAAG,cAAA,QAAA,CAAS,MAAA,CAAO,CAAC,CAAA,GAAI,GAAG,CAAA;AAAA,YAAG;AAAA,UACtE,CAAA;AAAA,UACA,SAAA,EAAU,kJAAA;AAAA,UACV,KAAA,EAAM,MAAA;AAAA,UAEN,QAAA,EAAA;AAAA,4BAAAA,GAAAA,CAAC,QAAA,EAAA,EAAO,KAAA,EAAM,KAAA,EAAO,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,YAC7B,CAAC,OAAA,IAAW,CAAC,YAAA,CAAa,SAAS,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,GAAG,CAAC,CAAA,oBACzD,IAAA,CAAC,QAAA,EAAA,EAAO,OAAM,QAAA,EAAU,QAAA,EAAA;AAAA,cAAA,IAAA,CAAK,KAAA,CAAM,QAAQ,GAAG,CAAA;AAAA,cAAE;AAAA,aAAA,EAAC,CAAA;AAAA,YAElD,aAAa,GAAA,CAAI,CAAA,CAAA,qBAAK,IAAA,CAAC,QAAA,EAAA,EAAe,OAAO,CAAA,EAAI,QAAA,EAAA;AAAA,cAAA,CAAA;AAAA,cAAE;AAAA,aAAA,EAAA,EAAhB,CAAiB,CAAS;AAAA;AAAA;AAAA,OAChE;AAAA,sBACAA,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,SAAS,MAAM;AAAE,YAAA,UAAA,CAAW,KAAK,CAAA;AAAG,YAAA,QAAA,CAAS,CAAA,CAAA,KAAK,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,KAAA,CAAA,CAAO,CAAA,GAAI,IAAA,IAAQ,GAAG,CAAA,GAAI,GAAG,CAAC,CAAA;AAAA,UAAG,CAAA;AAAA,UACpG,SAAA,EAAW,GAAA;AAAA,UACZ,QAAA,EAAA;AAAA;AAAA,OAAC;AAAA,sBACFA,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAS,KAAA;AAAA,UACT,SAAA,EAAW,GAAA,IAAO,OAAA,GAAU,4BAAA,GAA+B,EAAA,CAAA;AAAA,UAC3D,KAAA,EAAO,GAAG,QAAQ,CAAA,8DAAA,CAAA;AAAA,UACnB,QAAA,EAAA;AAAA;AAAA,OAAG;AAAA,sBACJA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EAA4B,CAAA;AAAA,sBAC3C,IAAA,CAAC,QAAA,EAAA,EAAO,OAAA,EAAS,WAAA,EAAa,WAAW,GAAA,EACvC,QAAA,EAAA;AAAA,wBAAAA,GAAAA,CAAC,SAAI,SAAA,EAAU,aAAA,EAAc,MAAK,MAAA,EAAO,OAAA,EAAQ,aAAY,MAAA,EAAO,cAAA,EAAe,aAAa,GAAA,EAAK,QAAA,kBAAAA,IAAC,MAAA,EAAA,EAAK,aAAA,EAAc,SAAQ,cAAA,EAAe,OAAA,EAAQ,CAAA,EAAE,0lBAAA,EAA2lB,CAAA,EAAE,CAAA;AAAA,QAAM;AAAA,OAAA,EAE/vB,CAAA;AAAA,2BACC,QAAA,EAAA,EAAO,OAAA,EAAS,UAAA,IAAc,qBAAA,EAAuB,WAAW,GAAA,EAC/D,QAAA,EAAA;AAAA,wBAAAA,GAAAA,CAAC,SAAI,SAAA,EAAU,aAAA,EAAc,MAAK,MAAA,EAAO,OAAA,EAAQ,aAAY,MAAA,EAAO,cAAA,EAAe,aAAa,GAAA,EAAK,QAAA,kBAAAA,IAAC,MAAA,EAAA,EAAK,aAAA,EAAc,SAAQ,cAAA,EAAe,OAAA,EAAQ,CAAA,EAAE,0GAAA,EAA2G,CAAA,EAAE,CAAA;AAAA,QAAM;AAAA,OAAA,EAE/Q,CAAA;AAAA,MACC,2BACC,IAAA,CAAC,QAAA,EAAA,EAAO,OAAA,EAAS,OAAA,EAAS,WAAW,GAAA,EACnC,QAAA,EAAA;AAAA,wBAAAA,GAAAA,CAAC,SAAI,SAAA,EAAU,aAAA,EAAc,MAAK,MAAA,EAAO,OAAA,EAAQ,aAAY,MAAA,EAAO,cAAA,EAAe,aAAa,GAAA,EAAK,QAAA,kBAAAA,IAAC,MAAA,EAAA,EAAK,aAAA,EAAc,SAAQ,cAAA,EAAe,OAAA,EAAQ,CAAA,EAAE,wPAAA,EAAyP,CAAA,EAAE,CAAA;AAAA,QAAM;AAAA,OAAA,EAE7Z;AAAA,KAAA,EAEJ,CAAA;AAAA,oBAEAA,GAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,YAAA;AAAA,QACL,SAAA,EAAU,+CAAA;AAAA,QAKV,QAAA,EAAU,CAAA;AAAA,QACV,OAAA,EAAS,WAAA;AAAA,QACT,SAAA,EAAW,SAAA;AAAA,QAEV,QAAA,EAAA,OAAA,mBACCA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+DAAA,EAAgE,QAAA,EAAA,gBAAA,EAAc,CAAA,mBAE7F,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iDAAA,EACb,QAAA,EAAA;AAAA,0BAAAA,GAAAA,CAAC,WAAO,QAAA,EAAA,cAAA,EAAe,CAAA;AAAA,0BACvB,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4BAAA,EACb,QAAA,EAAA;AAAA,4BAAAA,GAAAA,CAAC,QAAA,EAAA,EAAO,GAAA,EAAK,SAAA,EAAW,WAAU,eAAA,EAAgB,CAAA;AAAA,4BAClDA,GAAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBACC,GAAA,EAAK,YAAA;AAAA,gBACL,SAAA,EAAU,uBAAA;AAAA,gBACV,eAAe,CAAA,CAAA,KAAK,CAAA,CAAE,aAAA,CAAc,SAAA,CAAU,IAAI,WAAW;AAAA;AAAA;AAC/D,WAAA,EACF;AAAA,SAAA,EACF;AAAA;AAAA;AAEJ,GAAA,EACF,CAAA;AAEJ","file":"chunk-SEWF4O3H.js","sourcesContent":["/**\n * Is what came back over the wire actually a WebAssembly module?\n *\n * `Preview`'s wasm factory used to accept any `res.ok` response. That is not\n * enough on a single-page app: an SPA host answers a path its router does not\n * recognise with its own index.html under HTTP 200, so a build that failed to\n * emit a decoder returns a PAGE rather than a 404 (confirmed against the live\n * console on 2026-08-30 — both `/assets/jbig2.wasm` and a made-up asset path\n * answered 200 with `content-type: text/html`). pdf.js then instantiates the\n * page inside a `try` that only warns before dropping to its JS fallback, which\n * is the same quiet degrading the factory was added to remove — except now\n * nothing in the console points at the emit as the cause.\n *\n * This module is deliberately free of React and of pdfjs-dist so it can be\n * driven directly from a spec. Importing `Preview.tsx` in a Node test is not\n * possible: pdfjs builds a `new DOMMatrix()` at module scope and throws.\n */\n\n/** Every WebAssembly module opens with the four bytes `\\0asm`. Anything else —\n * an HTML fallback page, most often — is not one. */\nexport function hasWasmPreamble(bytes: Uint8Array): boolean {\n return (\n bytes.length >= 4 &&\n bytes[0] === 0x00 &&\n bytes[1] === 0x61 &&\n bytes[2] === 0x73 &&\n bytes[3] === 0x6d\n );\n}\n\n/** A short, safe description of what arrived instead, for the error message.\n * The opening bytes of an HTML page name the problem far better than a length\n * does, so they are worth quoting; the cap keeps a stray binary out of the\n * console. */\nexport function describeNonWasm(bytes: Uint8Array): string {\n if (bytes.length === 0) return 'an empty response';\n const head = Array.from(bytes.subarray(0, 24))\n .map(b => (b >= 0x20 && b < 0x7f ? String.fromCharCode(b) : '.'))\n .join('');\n return `${bytes.length} bytes starting \"${head}\"`;\n}\n\n/** The message a developer reads when the emit went missing. It has to name the\n * emit, because the symptom they are looking at is a preview that renders\n * everything except the scanned page, with a silent console. */\nexport function wasmBytesError(href: string, filename: string, bytes: Uint8Array): Error {\n return new Error(\n `The response for ${href} is not a WebAssembly module (got ` +\n `${describeNonWasm(bytes)}). The bundler did not emit \"${filename}\" as ` +\n `an asset, and the host answered with a fallback page instead of a 404. ` +\n `Serve pdfjs-dist/wasm/ yourself and point ` +\n `window.__REACT_OS_SHELL_PDF_WASM__ at it.`,\n );\n}\n","/**\n * Where a format panel's toolbar buttons go.\n *\n * Inside the Preview window there is one toolbar row — Open, the filename,\n * then a slot at its right end — and each panel (PDF, DXF, 3D, image) portals\n * its own page nav / zoom / layer / download buttons into that slot rather\n * than stacking a second row under it. `ToolbarSlotContext` carries the slot\n * element down.\n *\n * Outside Preview there is no slot, and there is no outer toolbar to merge\n * with either: an embedded `PdfViewer` is the whole widget. So the fallback\n * renders the buttons in place as the panel's own toolbar. It used to return\n * `null`, which was right while every panel lived in a window and wrong the\n * moment one did not — an embedded viewer with no page nav and no zoom.\n */\nimport { createContext, useContext } from 'react';\nimport { createPortal } from 'react-dom';\n\nexport const ToolbarSlotContext = createContext<HTMLElement | null>(null);\n\nexport function PanelActions({ children }: { children: React.ReactNode }) {\n const slot = useContext(ToolbarSlotContext);\n if (slot) return createPortal(children, slot);\n return (\n <div className=\"flex shrink-0 items-center gap-1 border-b border-gray-200 bg-gray-50 px-3 py-2 text-xs\">\n {children}\n </div>\n );\n}\n","/**\n * PdfViewer — the pdf.js reader, on its own so it can be embedded.\n *\n * It was the Preview window's private `PdfPanel` until a consumer needed a PDF\n * inside a dialog rather than in a window of its own. The two consumers that\n * needed one had each reached for `<iframe src={blobUrl}>`, which hands the\n * page to the BROWSER's built-in plugin: its own toolbar, a ~250px thumbnail\n * rail, and its own idea of the zoom — roughly a third of an already small\n * pane spent on chrome nobody asked for, and a portrait page cropped at the\n * fold. Nothing about that is themeable or testable, and it is not this\n * package's viewer.\n *\n * Import it lazily (`react-os-shell/apps` exports it wrapped in `lazy`, like\n * the other document apps) and render it inside a `<Suspense>`: the static\n * `pdfjs-dist` import below must not reach a host's startup bundle. Give it a\n * parent with a resolved height — it fills its container and scrolls inside.\n */\nimport { useState, useEffect, useRef } from 'react';\nimport * as pdfjsLib from 'pdfjs-dist';\nimport toast from '../shell/toast';\nimport { hasWasmPreamble, wasmBytesError } from './_wasmBytes';\nimport { PanelActions } from './_panelActions';\n\n// Default the worker to the matching unpkg build (mirrors the consumer's\n// installed npm version exactly). Consumers can override by setting\n// pdfjsLib.GlobalWorkerOptions.workerSrc themselves before this module loads.\nif (typeof window !== 'undefined' && !pdfjsLib.GlobalWorkerOptions.workerSrc) {\n pdfjsLib.GlobalWorkerOptions.workerSrc =\n `https://unpkg.com/pdfjs-dist@${pdfjsLib.version}/build/pdf.worker.min.mjs`;\n}\n\n// pdf.js does not ship its JBIG2 and JPEG 2000 decoders as JavaScript any\n// more: both are WebAssembly modules it loads at decode time, and it will only\n// load them from a location the caller supplies. With neither `wasmUrl` nor a\n// `BinaryDataFactory` configured — this package's state until now — the\n// decoder asks for one, pdf.js's own base factory throws \"Ensure that the\n// `wasmUrl` API parameter is provided\", and the worker swallows that as a\n// `warn()`. The page still renders; the scanned or JPEG-2000 image on it is\n// just missing. Nothing reaches the user, which is why it went unnoticed.\n//\n// The fix follows the mechanism the admin portal already uses for the pdf\n// WORKER (`import ... from 'pdfjs-dist/build/pdf.worker.min.mjs?url'`, which\n// Vite emits as /assets/pdf.worker.min-<hash>.mjs): let the CONSUMER'S bundler\n// emit the file and hand pdf.js the URL it produced. `new URL(spec,\n// import.meta.url)` is the bundler-neutral spelling of that — Vite resolves\n// the bare specifier and emits the binary as its own hashed asset (verified on\n// Vite 5 and 7), and a bundler that does not understand the form leaves it\n// alone and lands back on today's warn-and-degrade rather than on an error.\n//\n// The specifier points at the CONSUMER'S installed `pdfjs-dist`, not at a copy\n// vendored into this package. That is deliberate: these binaries are built\n// alongside the worker that instantiates them, and a vendored copy would pin\n// them to THIS package's devDependency instead of to the peer they actually\n// run against.\nconst PDF_WASM_MODULES: Record<string, string> = {\n 'jbig2.wasm': new URL('pdfjs-dist/wasm/jbig2.wasm', import.meta.url).href,\n 'openjpeg.wasm': new URL('pdfjs-dist/wasm/openjpeg.wasm', import.meta.url).href,\n};\n\n/** pdf.js instantiates this itself (it is passed to `getDocument` as a class,\n * not an instance) and calls `fetch` once per binary it needs.\n *\n * Only the `wasmUrl` kind is served. cMap and standard-font data are the other\n * two kinds pdf.js can ask for, and this package has never configured a URL\n * for either — so those keep the exact message pdf.js's own base factory\n * raises for an unconfigured URL, and behave as they always have. */\nclass BundledPdfWasmFactory {\n async fetch({ kind, filename }: { kind: string; filename: string }): Promise<Uint8Array> {\n if (kind !== 'wasmUrl') {\n throw new Error(`Ensure that the \\`${kind}\\` API parameter is provided.`);\n }\n const href = PDF_WASM_MODULES[filename];\n if (!href) {\n throw new Error(`No bundled pdf.js wasm module for \"${filename}\".`);\n }\n const res = await fetch(href);\n if (!res.ok) {\n throw new Error(`Unable to load wasm data at: ${href}`);\n }\n // A 200 is not proof the bundler emitted the binary — see _wasmBytes.ts.\n const bytes = new Uint8Array(await res.arrayBuffer());\n if (!hasWasmPreamble(bytes)) {\n throw wasmBytesError(href, filename, bytes);\n }\n return bytes;\n }\n}\n\n/** The `getDocument` parameters that give pdf.js somewhere to load its wasm\n * decoders from.\n *\n * A consumer that serves the whole `pdfjs-dist/wasm/` directory itself (copied\n * into `public/`, say, or on an air-gapped host) points us at it with\n * `window.__REACT_OS_SHELL_PDF_WASM__` — same escape hatch as\n * `__REACT_OS_SHELL_O3DV_LIBS__` below. pdf.js requires a trailing slash on\n * that value and throws \"Invalid factory url\" without one, so add it here\n * rather than making every consumer remember. Everyone else gets the\n * bundler-emitted modules and configures nothing. */\nfunction pdfWasmParams(): { wasmUrl?: string; BinaryDataFactory?: object } {\n const dir = typeof window !== 'undefined'\n ? (window as unknown as { __REACT_OS_SHELL_PDF_WASM__?: unknown }).__REACT_OS_SHELL_PDF_WASM__\n : undefined;\n if (typeof dir === 'string' && dir) {\n return { wasmUrl: dir.endsWith('/') ? dir : `${dir}/` };\n }\n return { BinaryDataFactory: BundledPdfWasmFactory };\n}\n\nexport interface PdfViewerProps {\n /** Object URL or remote URL of the PDF. */\n url: string;\n /** Display name — also the filename the built-in Download uses. */\n filename: string;\n /**\n * What the auto-fit scale tracks until the reader picks a manual zoom.\n *\n * `'width'` fills the container's width and lets a tall page scroll — right\n * for a viewer that owns a whole window, and what the Preview app uses.\n * `'page'` fits the WHOLE page, which is what an embedded preview pane\n * wants: someone checking a document before sending it needs to see that it\n * is the right document, and a page cropped at the fold reads as broken.\n */\n fit?: 'width' | 'page';\n /** Replaces the built-in \"save `url` as `filename`\" download. */\n onDownload?: () => void;\n /** An Email button joins the toolbar only when this is supplied. */\n onEmail?: () => void;\n}\n\nconst ZOOM_PRESETS = [50, 75, 100, 125, 150, 200, 300, 400];\n\n/** The `p-4` gutter the page sits in, on both axes. */\nconst PAGE_GUTTER = 40;\nconst MIN_SCALE = 0.3;\nconst MAX_SCALE = 4;\n\n/**\n * The scale auto-fit lands on.\n *\n * @internal Exported for the spec. The effect that calls it needs a rendered\n * document and a laid-out container to reach, and the wrong answer here does\n * not throw — it crops the page at the fold, which reads as a broken preview\n * rather than as a bug in a formula.\n */\nexport function fitScale(\n fit: 'width' | 'page',\n container: { width: number; height: number },\n page: { width: number; height: number },\n): number {\n const byWidth = (container.width - PAGE_GUTTER) / page.width;\n // Fitting the PAGE means neither axis may overflow, so take whichever\n // constraint binds first. Width alone is what crops a portrait page in a\n // pane wider than it is tall.\n const wanted = fit === 'page'\n ? Math.min(byWidth, (container.height - PAGE_GUTTER) / page.height)\n : byWidth;\n return Math.min(Math.max(wanted, MIN_SCALE), MAX_SCALE);\n}\n\n// Trimmed copy of pdf.js's text-layer rules (pdf_viewer.css), under our own\n// class name so a consumer that loads the full viewer CSS doesn't\n// double-apply. The layer is a sheet of transparent spans positioned over\n// the canvas glyphs — that's what makes the rendered page selectable. Span\n// positions are % of page size; font-size derives from\n// --total-scale-factor, which the render effect sets to the viewport scale.\n// The .endOfContent sentinel plus the .selecting toggle keep a\n// drag-selection alive between lines and past the last line (same trick as\n// pdf.js's own TextLayerBuilder).\nconst TEXT_LAYER_CSS = `\n.preview-pdf-textlayer {\n position: absolute;\n inset: 0;\n overflow: clip;\n line-height: 1;\n text-align: initial;\n text-size-adjust: none;\n forced-color-adjust: none;\n transform-origin: 0 0;\n caret-color: CanvasText;\n --min-font-size: 1;\n --text-scale-factor: calc(var(--total-scale-factor, 1) * var(--min-font-size));\n --min-font-size-inv: calc(1 / var(--min-font-size));\n}\n.preview-pdf-textlayer :is(span, br) {\n color: transparent;\n position: absolute;\n white-space: pre;\n cursor: text;\n transform-origin: 0% 0%;\n}\n.preview-pdf-textlayer > :not(.markedContent),\n.preview-pdf-textlayer .markedContent span:not(.markedContent) {\n z-index: 1;\n --font-height: 0;\n font-size: calc(var(--text-scale-factor) * var(--font-height));\n --scale-x: 1;\n --rotate: 0deg;\n transform: rotate(var(--rotate)) scaleX(var(--scale-x)) scale(var(--min-font-size-inv));\n}\n.preview-pdf-textlayer .markedContent {\n display: contents;\n}\n.preview-pdf-textlayer span[role=\"img\"] {\n user-select: none;\n cursor: default;\n}\n.preview-pdf-textlayer ::selection {\n background: rgba(0, 80, 255, 0.25);\n}\n.preview-pdf-textlayer br::selection {\n background: transparent;\n}\n.preview-pdf-textlayer .endOfContent {\n display: block;\n position: absolute;\n inset: 100% 0 0;\n z-index: 0;\n cursor: default;\n user-select: none;\n}\n.preview-pdf-textlayer.selecting .endOfContent {\n top: 0;\n}\n`;\n\nexport default function PdfViewer({ url, filename, fit = 'width', onDownload, onEmail }: PdfViewerProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const textLayerRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const [pdf, setPdf] = useState<pdfjsLib.PDFDocumentProxy | null>(null);\n const [page, setPage] = useState(1);\n const [totalPages, setTotalPages] = useState(0);\n const [scale, setScale] = useState(1);\n // Fit mode is the default — scale stays auto-tracking the container width\n // until the user picks a manual zoom (− / + / dropdown). Re-armed by the\n // Fit toolbar button.\n const [fitMode, setFitMode] = useState(true);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n // A new document starts at its first page. The page number belongs to the\n // document being read, not to the viewer, and it used to survive a change\n // of `url`: sitting on page 3 and being handed a one-page document asked\n // pdf.js for a page that does not exist, and the canvas went blank with\n // nothing thrown. The Preview window never saw it because it keys its\n // panels by url, but an embedder that re-renders one viewer with a new\n // document — a preview pane next to the options that regenerate it — is\n // exactly the shape this component was extracted for.\n //\n // Reset before the fetch, not in its `.then`: the manual page controls are\n // live while a document loads, and a reset that landed afterwards would\n // undo a page the reader had already picked.\n //\n // Zoom is deliberately NOT reset. It is the reader's own preference for\n // how large they want text, and it holds across documents the way it does\n // in every reader; only the page is a fact about the file.\n setPage(1);\n // Parameter-object form, not the bare string: pdfjs-dist 6.x removed the\n // string overload (\"expected either `data`, `range`, or `url` parameter\"),\n // so a consumer on 6.x had every preview die on this line. The object form\n // works on 5.x too. tests/pdfjsContract.test.ts fails if it reverts.\n pdfjsLib.getDocument({ url, ...pdfWasmParams() }).promise.then(doc => {\n if (cancelled) return;\n setPdf(doc);\n setTotalPages(doc.numPages);\n setLoading(false);\n }).catch(() => {\n if (!cancelled) { toast.error('Failed to load PDF'); setLoading(false); }\n });\n return () => { cancelled = true; };\n }, [url]);\n\n // Auto-fit: re-compute scale from the container whenever fit mode is on, the\n // document changes, the page changes, or the container resizes. Window\n // resize and Modal drag-resize both trigger ResizeObserver. Manual zoom\n // turns this off until the user clicks Fit again.\n useEffect(() => {\n if (!pdf || !fitMode || !containerRef.current) return;\n const recompute = () => {\n const el = containerRef.current;\n if (!el) return;\n pdf.getPage(page).then(p => {\n if (!containerRef.current) return;\n const viewport = p.getViewport({ scale: 1 });\n const next = fitScale(\n fit,\n { width: el.clientWidth, height: el.clientHeight },\n { width: viewport.width, height: viewport.height },\n );\n setScale(prev => (Math.abs(prev - next) < 0.005 ? prev : next));\n });\n };\n recompute();\n const ro = new ResizeObserver(recompute);\n ro.observe(containerRef.current);\n return () => ro.disconnect();\n }, [pdf, page, fitMode, fit]);\n\n useEffect(() => {\n if (!pdf || !canvasRef.current) return;\n let cancelled = false;\n let task: { cancel: () => void; promise: Promise<void> } | null = null;\n let textLayer: pdfjsLib.TextLayer | null = null;\n pdf.getPage(page).then(p => {\n if (cancelled || !canvasRef.current) return;\n const viewport = p.getViewport({ scale });\n const canvas = canvasRef.current;\n canvas.width = viewport.width;\n canvas.height = viewport.height;\n // Lock the displayed (CSS) size to the viewport. pdf.js stamps inline\n // style.width/height on render and inline values stick across re-renders\n // even when canvas.width shrinks — without this, zoom changes only\n // affect resolution, not visible size.\n canvas.style.width = `${viewport.width}px`;\n canvas.style.height = `${viewport.height}px`;\n const ctx = canvas.getContext('2d')!;\n task = p.render({ canvas, canvasContext: ctx, viewport });\n task.promise.catch(() => {});\n // Selectable text layer — transparent spans over the canvas glyphs.\n // Rebuilt per page/zoom render; pdf.js reads --total-scale-factor for\n // span font-size and the container's own width/height.\n const textEl = textLayerRef.current;\n if (textEl) {\n textEl.replaceChildren();\n textEl.style.setProperty('--total-scale-factor', String(viewport.scale));\n textLayer = new pdfjsLib.TextLayer({\n textContentSource: p.streamTextContent(),\n container: textEl,\n viewport,\n });\n textLayer.render().then(() => {\n if (cancelled) return;\n const end = document.createElement('div');\n end.className = 'endOfContent';\n textEl.append(end);\n }).catch(() => {});\n }\n });\n return () => {\n cancelled = true;\n task?.cancel();\n textLayer?.cancel();\n };\n }, [pdf, page, scale]);\n\n // End a selection drag wherever the pointer is released — the .selecting\n // class is added on pointerdown in the layer itself (see JSX below).\n useEffect(() => {\n const up = () => textLayerRef.current?.classList.remove('selecting');\n window.addEventListener('pointerup', up);\n return () => window.removeEventListener('pointerup', up);\n }, []);\n\n const handlePrint = () => {\n if (!pdf) return;\n const win = window.open('', '_blank');\n if (!win) { toast.error('Allow popups to print'); return; }\n const promises: Promise<string>[] = [];\n for (let i = 1; i <= totalPages; i++) {\n promises.push(pdf.getPage(i).then(p => {\n const vp = p.getViewport({ scale: 2 });\n const c = document.createElement('canvas');\n c.width = vp.width; c.height = vp.height;\n return p.render({ canvas: c, canvasContext: c.getContext('2d')!, viewport: vp }).promise.then(() => c.toDataURL());\n }));\n }\n Promise.all(promises).then(images => {\n win.document.write(`<html><head><title>${filename}</title><style>@media print{body{margin:0}img{width:100%;page-break-after:always}}</style></head><body>`);\n win.document.write(images.map(src => `<img src=\"${src}\"/>`).join(''));\n win.document.write('</body></html>');\n win.document.close();\n setTimeout(() => { win.print(); win.close(); }, 300);\n });\n };\n\n const handleDefaultDownload = () => {\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n a.click();\n };\n\n // Re-arm fit mode. The auto-fit effect picks the new scale on its next\n // tick once `fitMode` flips to true.\n const reFit = () => setFitMode(true);\n const fitLabel = fit === 'page' ? 'Fit page' : 'Fit width';\n\n // Wheel and keyboard page navigation. Only takes the wheel event when\n // the container is at the top/bottom edge — otherwise normal scroll\n // moves through a tall page first, matching native PDF readers.\n const onWheelPage = (e: React.WheelEvent<HTMLDivElement>) => {\n if (!pdf) return;\n if (e.ctrlKey || e.metaKey) return; // browser-zoom shortcut, leave alone\n const el = containerRef.current;\n if (!el) return;\n const atTop = el.scrollTop <= 0;\n const atBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - 1;\n if (e.deltaY > 0 && atBottom && page < totalPages) {\n e.preventDefault();\n setPage(p => Math.min(totalPages, p + 1));\n // Land at the top of the next page so wheel-down keeps reading\n // forward. requestAnimationFrame so the canvas has a tick to\n // resize before we scroll.\n requestAnimationFrame(() => { if (containerRef.current) containerRef.current.scrollTop = 0; });\n } else if (e.deltaY < 0 && atTop && page > 1) {\n e.preventDefault();\n setPage(p => Math.max(1, p - 1));\n requestAnimationFrame(() => {\n if (containerRef.current) containerRef.current.scrollTop = containerRef.current.scrollHeight;\n });\n }\n };\n const onKeyPage = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (!pdf) return;\n // Ignore keyboard nav when an input/textarea has focus.\n const tag = (document.activeElement?.tagName || '').toLowerCase();\n if (tag === 'input' || tag === 'textarea' || (document.activeElement as HTMLElement)?.isContentEditable) return;\n if (e.key === 'PageDown' || e.key === 'ArrowRight') {\n if (page < totalPages) { e.preventDefault(); setPage(p => Math.min(totalPages, p + 1)); }\n } else if (e.key === 'PageUp' || e.key === 'ArrowLeft') {\n if (page > 1) { e.preventDefault(); setPage(p => Math.max(1, p - 1)); }\n } else if (e.key === 'Home') {\n e.preventDefault(); setPage(1);\n } else if (e.key === 'End') {\n e.preventDefault(); setPage(totalPages);\n }\n };\n\n const btn = 'px-2 py-1 rounded hover:bg-gray-200 transition-colors text-gray-600 flex items-center gap-1';\n\n return (\n <div className=\"flex flex-col h-full\">\n <PanelActions>\n <button aria-label=\"Previous page\" onClick={() => setPage(p => Math.max(1, p - 1))} disabled={page <= 1} className=\"px-1 py-1 rounded hover:bg-gray-200 disabled:opacity-30 text-gray-600\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15.75 19.5L8.25 12l7.5-7.5\" /></svg>\n </button>\n <span className=\"text-gray-600 font-medium tabular-nums\">{page} / {totalPages}</span>\n <button aria-label=\"Next page\" onClick={() => setPage(p => Math.min(totalPages, p + 1))} disabled={page >= totalPages} className=\"px-1 py-1 rounded hover:bg-gray-200 disabled:opacity-30 text-gray-600\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M8.25 4.5l7.5 7.5-7.5 7.5\" /></svg>\n </button>\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <button\n onClick={() => { setFitMode(false); setScale(s => Math.max(0.3, Math.round((s - 0.25) * 100) / 100)); }}\n className={btn}\n >−</button>\n <select\n value={fitMode ? 'fit' : (ZOOM_PRESETS.includes(Math.round(scale * 100)) ? Math.round(scale * 100) : 'custom')}\n onChange={e => {\n const v = e.target.value;\n if (v === 'fit') { setFitMode(true); return; }\n if (v !== 'custom') { setFitMode(false); setScale(Number(v) / 100); }\n }}\n className=\"bg-transparent hover:bg-gray-200 rounded px-1 py-1 text-gray-600 tabular-nums cursor-pointer focus:outline-none focus:ring-1 focus:ring-blue-400\"\n title=\"Zoom\"\n >\n <option value=\"fit\">{fitLabel}</option>\n {!fitMode && !ZOOM_PRESETS.includes(Math.round(scale * 100)) && (\n <option value=\"custom\">{Math.round(scale * 100)}%</option>\n )}\n {ZOOM_PRESETS.map(p => <option key={p} value={p}>{p}%</option>)}\n </select>\n <button\n onClick={() => { setFitMode(false); setScale(s => Math.min(4, Math.round((s + 0.25) * 100) / 100)); }}\n className={btn}\n >+</button>\n <button\n onClick={reFit}\n className={btn + (fitMode ? ' bg-gray-200 text-gray-900' : '')}\n title={`${fitLabel} — auto-tracks the container size until you zoom manually`}\n >Fit</button>\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <button onClick={handlePrint} className={btn}>\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6.72 13.829c-.24.03-.48.062-.72.096m.72-.096a42.415 42.415 0 0110.56 0m-10.56 0L6.34 18m10.94-4.171c.24.03.48.062.72.096m-.72-.096L17.66 18m0 0l.229 2.523a1.125 1.125 0 01-1.12 1.227H7.231c-.662 0-1.18-.568-1.12-1.227L6.34 18m11.318 0h1.091A2.25 2.25 0 0021 15.75V9.456c0-1.081-.768-2.015-1.837-2.175a48.055 48.055 0 00-1.913-.247M6.34 18H5.25A2.25 2.25 0 013 15.75V9.456c0-1.081.768-2.015 1.837-2.175a48.041 48.041 0 011.913-.247m10.5 0a48.536 48.536 0 00-10.5 0m10.5 0V3.375c0-.621-.504-1.125-1.125-1.125h-8.25c-.621 0-1.125.504-1.125 1.125v3.659M18 10.5h.008v.008H18V10.5zm-3 0h.008v.008H15V10.5z\" /></svg>\n Print\n </button>\n <button onClick={onDownload ?? handleDefaultDownload} className={btn}>\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3\" /></svg>\n Download\n </button>\n {onEmail && (\n <button onClick={onEmail} className={btn}>\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75\" /></svg>\n Email\n </button>\n )}\n </PanelActions>\n\n <div\n ref={containerRef}\n className=\"flex-1 overflow-auto bg-gray-100 outline-none\"\n // tabIndex makes the scroll container itself focusable so PageUp /\n // PageDown / Arrow keys are captured even when no inner element\n // has focus (e.g. right after the panel mounts). Wheel handler\n // page-flips when the user reaches the top/bottom of a long page.\n tabIndex={0}\n onWheel={onWheelPage}\n onKeyDown={onKeyPage}\n >\n {loading ? (\n <div className=\"flex items-center justify-center h-full text-gray-400 text-sm\">Loading PDF...</div>\n ) : (\n <div className=\"min-h-full flex items-center justify-center p-4\">\n <style>{TEXT_LAYER_CSS}</style>\n <div className=\"relative shadow-lg rounded\">\n <canvas ref={canvasRef} className=\"block rounded\" />\n <div\n ref={textLayerRef}\n className=\"preview-pdf-textlayer\"\n onPointerDown={e => e.currentTarget.classList.add('selecting')}\n />\n </div>\n </div>\n )}\n </div>\n </div>\n );\n}\n"]}
|