@zerohive/hive-viewer 0.1.0 → 0.2.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/dist/index.js CHANGED
@@ -310,9 +310,15 @@ function PdfRenderer(props) {
310
310
  }
311
311
 
312
312
  // src/editors/RichTextEditor.tsx
313
- import { forwardRef, useEffect as useEffect2, useImperativeHandle, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
313
+ import {
314
+ forwardRef,
315
+ useEffect as useEffect2,
316
+ useImperativeHandle,
317
+ useMemo as useMemo2,
318
+ useRef as useRef2,
319
+ useState as useState2
320
+ } from "react";
314
321
  import mammoth from "mammoth";
315
- import htmlToDocx from "html-to-docx";
316
322
  import MarkdownIt from "markdown-it";
317
323
  import html2canvas from "html2canvas";
318
324
 
@@ -330,7 +336,10 @@ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
330
336
  var PAGE_H = 1122;
331
337
  var RichTextEditor = forwardRef((props, ref) => {
332
338
  const readOnly = props.mode === "view";
333
- const md = useMemo2(() => new MarkdownIt({ html: false, linkify: true, breaks: true }), []);
339
+ const md = useMemo2(
340
+ () => new MarkdownIt({ html: false, linkify: true, breaks: true }),
341
+ []
342
+ );
334
343
  const scrollerRef = useRef2(null);
335
344
  const editorRef = useRef2(null);
336
345
  const captureRef = useRef2(null);
@@ -344,7 +353,9 @@ var RichTextEditor = forwardRef((props, ref) => {
344
353
  }
345
354
  if (!props.arrayBuffer) return;
346
355
  if (props.fileType === "docx") {
347
- const res = await mammoth.convertToHtml({ arrayBuffer: props.arrayBuffer });
356
+ const res = await mammoth.convertToHtml({
357
+ arrayBuffer: props.arrayBuffer
358
+ });
348
359
  if (!cancelled) setHtml(sanitizeHtml(res.value || "<p><br/></p>"));
349
360
  } else {
350
361
  const text = new TextDecoder().decode(props.arrayBuffer);
@@ -389,7 +400,11 @@ var RichTextEditor = forwardRef((props, ref) => {
389
400
  scroller.scrollTop = index * PAGE_H;
390
401
  await new Promise((r) => requestAnimationFrame(() => r(null)));
391
402
  try {
392
- const canvas = await html2canvas(capture, { backgroundColor: null, scale: 0.25, useCORS: true });
403
+ const canvas = await html2canvas(capture, {
404
+ backgroundColor: null,
405
+ scale: 0.25,
406
+ useCORS: true
407
+ });
393
408
  return canvas.toDataURL("image/png");
394
409
  } catch {
395
410
  return void 0;
@@ -402,25 +417,69 @@ var RichTextEditor = forwardRef((props, ref) => {
402
417
  const stitched = `<!doctype html><html><head><meta charset="utf-8" /></head><body>${inner}</body></html>`;
403
418
  if (exportPdf) {
404
419
  const b642 = btoa(unescape(encodeURIComponent(stitched)));
405
- props.onSave(b642, { fileName: replaceExt(props.fileName, "html"), fileType: "txt", exportedAsPdf: true, annotations: { signaturePlacements: props.signaturePlacements } });
420
+ props.onSave(b642, {
421
+ fileName: replaceExt(props.fileName, "html"),
422
+ fileType: "txt",
423
+ exportedAsPdf: true,
424
+ annotations: { signaturePlacements: props.signaturePlacements }
425
+ });
406
426
  return;
407
427
  }
408
428
  if (props.fileType === "docx") {
409
- const blob = await htmlToDocx(stitched);
410
- const ab = await blob.arrayBuffer();
411
- props.onSave(arrayBufferToBase64(ab), { fileName: replaceExt(props.fileName, "docx"), fileType: "docx", annotations: { signaturePlacements: props.signaturePlacements } });
429
+ try {
430
+ const htmlToDocx = (await import("html-to-docx")).default;
431
+ const blob = await htmlToDocx(stitched);
432
+ const ab = await blob.arrayBuffer();
433
+ props.onSave(arrayBufferToBase64(ab), {
434
+ fileName: replaceExt(props.fileName, "docx"),
435
+ fileType: "docx",
436
+ annotations: { signaturePlacements: props.signaturePlacements }
437
+ });
438
+ } catch (err) {
439
+ alert(
440
+ "DOCX export is not supported in this environment. Please use this feature in a Node.js/server context."
441
+ );
442
+ }
412
443
  return;
413
444
  }
414
445
  const text = editorRef.current?.innerText ?? "";
415
446
  const b64 = btoa(unescape(encodeURIComponent(text)));
416
- props.onSave(b64, { fileName: replaceExt(props.fileName, props.fileType), fileType: props.fileType, annotations: { signaturePlacements: props.signaturePlacements } });
447
+ props.onSave(b64, {
448
+ fileName: replaceExt(props.fileName, props.fileType),
449
+ fileType: props.fileType,
450
+ annotations: { signaturePlacements: props.signaturePlacements }
451
+ });
417
452
  }
418
453
  useImperativeHandle(ref, () => ({ save, requestThumbnail }));
419
454
  return /* @__PURE__ */ jsxs5("div", { className: "hv-doc", children: [
420
455
  /* @__PURE__ */ jsxs5("div", { className: "hv-ribbon", role: "toolbar", children: [
421
- /* @__PURE__ */ jsx5("button", { className: "hv-btn", onClick: () => exec("bold"), disabled: readOnly, children: "B" }),
422
- /* @__PURE__ */ jsx5("button", { className: "hv-btn", onClick: () => exec("italic"), disabled: readOnly, children: "I" }),
423
- /* @__PURE__ */ jsx5("button", { className: "hv-btn", onClick: () => exec("underline"), disabled: readOnly, children: "U" }),
456
+ /* @__PURE__ */ jsx5(
457
+ "button",
458
+ {
459
+ className: "hv-btn",
460
+ onClick: () => exec("bold"),
461
+ disabled: readOnly,
462
+ children: "B"
463
+ }
464
+ ),
465
+ /* @__PURE__ */ jsx5(
466
+ "button",
467
+ {
468
+ className: "hv-btn",
469
+ onClick: () => exec("italic"),
470
+ disabled: readOnly,
471
+ children: "I"
472
+ }
473
+ ),
474
+ /* @__PURE__ */ jsx5(
475
+ "button",
476
+ {
477
+ className: "hv-btn",
478
+ onClick: () => exec("underline"),
479
+ disabled: readOnly,
480
+ children: "U"
481
+ }
482
+ ),
424
483
  props.armedSignatureUrl ? /* @__PURE__ */ jsx5("div", { className: "hv-hint", children: "Click to place signature" }) : null
425
484
  ] }),
426
485
  /* @__PURE__ */ jsx5("div", { className: "hv-scroll", ref: scrollerRef, onClick, children: /* @__PURE__ */ jsxs5("div", { className: "hv-pageStage", ref: captureRef, children: [
@@ -438,7 +497,14 @@ var RichTextEditor = forwardRef((props, ref) => {
438
497
  ),
439
498
  props.headerFooterEnabled && props.footerComponent ? /* @__PURE__ */ jsx5("div", { className: "hv-letterhead hv-letterhead--footer", children: props.footerComponent }) : null,
440
499
  props.mode === "create" && props.signatures.length ? /* @__PURE__ */ jsx5("div", { className: "hv-signatures-inline", children: props.signatures.map((s, i) => /* @__PURE__ */ jsxs5("div", { className: "hv-sign-inline", children: [
441
- /* @__PURE__ */ jsx5("img", { src: s.signatureImageUrl, alt: "", className: "hv-sign-img" }),
500
+ /* @__PURE__ */ jsx5(
501
+ "img",
502
+ {
503
+ src: s.signatureImageUrl,
504
+ alt: "",
505
+ className: "hv-sign-img"
506
+ }
507
+ ),
442
508
  /* @__PURE__ */ jsxs5("div", { children: [
443
509
  /* @__PURE__ */ jsx5("div", { className: "hv-sign-name", children: s.signedBy }),
444
510
  /* @__PURE__ */ jsx5("div", { className: "hv-sign-date", children: new Date(s.dateSigned).toLocaleString() })
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/DocumentViewer.tsx","../src/utils/locale.ts","../src/utils/fileSource.ts","../src/components/Toolbar.tsx","../src/components/ThumbnailsSidebar.tsx","../src/components/SignaturePanel.tsx","../src/renderers/PdfRenderer.tsx","../src/editors/RichTextEditor.tsx","../src/utils/sanitize.ts","../src/editors/SpreadsheetEditor.tsx","../src/renderers/ImageRenderer.tsx","../src/renderers/PptxRenderer.tsx"],"sourcesContent":["'use client';\n\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport type { DocumentMode, DocumentViewerProps, PageLayout, Signature, SupportedFileType } from '../types';\nimport { defaultLocale } from '../utils/locale';\nimport { resolveSource } from '../utils/fileSource';\nimport { Toolbar } from './Toolbar';\nimport { ThumbnailsSidebar, type Thumbnail } from './ThumbnailsSidebar';\nimport { SignaturePanel } from './SignaturePanel';\nimport { PdfRenderer } from '../renderers/PdfRenderer';\nimport { RichTextEditor, type RichTextEditorHandle } from '../editors/RichTextEditor';\nimport { SpreadsheetEditor, type SpreadsheetEditorHandle } from '../editors/SpreadsheetEditor';\nimport { ImageRenderer } from '../renderers/ImageRenderer';\nimport { PptxRenderer } from '../renderers/PptxRenderer';\n\ntype SigPlacement = { page: number; x: number; y: number; w: number; h: number; signatureImageUrl: string };\n\ntype EditorHandle = (RichTextEditorHandle | SpreadsheetEditorHandle) & { save: (exportPdf?: boolean) => Promise<void> };\n\nexport function DocumentViewer(props: DocumentViewerProps) {\n const mode: DocumentMode = props.mode ?? 'view';\n const theme = props.theme ?? 'light';\n const locale = useMemo(() => ({ ...defaultLocale, ...(props.locale ?? {}) }), [props.locale]);\n\n const [layout, setLayout] = useState<PageLayout>(props.defaultLayout ?? 'single');\n const [showThumbnails, setShowThumbnails] = useState(true);\n const [showSignatures, setShowSignatures] = useState(true);\n const [headerFooterEnabled, setHeaderFooterEnabled] = useState(true);\n\n const allowSigning = props.allowSigning ?? false;\n const [signingBusy, setSigningBusy] = useState(false);\n\n const [resolved, setResolved] = useState<{ fileType: SupportedFileType; fileName: string; url?: string; arrayBuffer?: ArrayBuffer } | null>(null);\n const [error, setError] = useState<string>('');\n const [pageCount, setPageCount] = useState(1);\n const [currentPage, setCurrentPage] = useState(1);\n const [thumbs, setThumbs] = useState<(string | undefined)[]>([]);\n\n const [localSignatures, setLocalSignatures] = useState<Signature[]>(props.signatures ?? []);\n useEffect(() => setLocalSignatures(props.signatures ?? []), [props.signatures]);\n\n const [sigPlacements, setSigPlacements] = useState<SigPlacement[]>([]);\n const [armedSignatureUrl, setArmedSignatureUrl] = useState<string | null>(null);\n\n const editorRef = useRef<EditorHandle | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n (async () => {\n setError('');\n setResolved(null);\n setThumbs([]);\n setPageCount(1);\n setCurrentPage(1);\n setSigPlacements([]);\n setArmedSignatureUrl(null);\n\n if (mode === 'create') {\n const ft = (props.fileType ?? 'docx') as SupportedFileType;\n setResolved({ fileType: ft, fileName: props.fileName ?? `Untitled.${ft}` });\n return;\n }\n\n try {\n const res = await resolveSource({\n fileUrl: props.fileUrl,\n base64: props.base64,\n blob: props.blob,\n fileName: props.fileName,\n fileType: props.fileType\n });\n if (cancelled) return;\n setResolved({ fileType: res.fileType, fileName: res.fileName, url: res.url, arrayBuffer: res.arrayBuffer });\n } catch (e) {\n if (cancelled) return;\n setError(e instanceof Error ? e.message : String(e));\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [mode, props.fileUrl, props.base64, props.blob, props.fileName, props.fileType]);\n\n const thumbnails: Thumbnail[] = useMemo(() => {\n const n = Math.max(1, pageCount);\n return Array.from({ length: n }, (_, i) => ({\n id: `p-${i + 1}`,\n label: `${locale['thumbnails.page'] ?? 'Page'} ${i + 1}`,\n dataUrl: thumbs[i]\n }));\n }, [pageCount, thumbs, locale]);\n\n async function handleSignRequest() {\n if (!allowSigning || signingBusy || !props.onSignRequest) return;\n setSigningBusy(true);\n try {\n const sig = await props.onSignRequest();\n setLocalSignatures((prev: Signature[]) => [...prev, sig]);\n setArmedSignatureUrl(sig.signatureImageUrl);\n } finally {\n setSigningBusy(false);\n }\n }\n\n function placeSignature(p: { page: number; x: number; y: number; w: number; h: number }) {\n if (!armedSignatureUrl) return;\n setSigPlacements((prev: SigPlacement[]) => [...prev, { ...p, signatureImageUrl: armedSignatureUrl }]);\n setArmedSignatureUrl(null);\n }\n\n async function handleSave(exportPdf?: boolean) {\n if (editorRef.current) {\n await editorRef.current.save(!!exportPdf);\n return;\n }\n if (!resolved?.arrayBuffer) return;\n const b64 = arrayBufferToBase64(resolved.arrayBuffer);\n props.onSave?.(b64, { fileName: resolved.fileName, fileType: resolved.fileType, annotations: { sigPlacements } });\n }\n\n const canSave = mode === 'edit' || mode === 'create';\n const canExportPdf = (mode === 'edit' || mode === 'create') && (resolved?.fileType === 'docx' || resolved?.fileType === 'md' || resolved?.fileType === 'txt' || resolved?.fileType === 'xlsx');\n\n return (\n <div className={`hv-root`} data-hv-theme={theme}>\n <Toolbar\n locale={locale}\n mode={mode}\n fileType={resolved?.fileType}\n layout={layout}\n onChangeLayout={setLayout}\n showThumbnails={showThumbnails}\n onToggleThumbnails={() => setShowThumbnails((v: boolean) => !v)}\n showSignatures={showSignatures}\n onToggleSignatures={() => setShowSignatures((v: boolean) => !v)}\n onSign={() => void handleSignRequest()}\n allowSigning={allowSigning}\n signingDisabled={signingBusy || !props.onSignRequest}\n canSave={canSave}\n onSave={() => void handleSave(false)}\n canExportPdf={canExportPdf}\n onExportPdf={() => void handleSave(true)}\n headerFooterEnabled={headerFooterEnabled}\n showHeaderFooterToggle={(props.enableHeaderFooterToggle ?? true) && mode === 'create'}\n onToggleHeaderFooter={() => setHeaderFooterEnabled((v: boolean) => !v)}\n />\n\n {error ? (\n <div className=\"hv-error\" role=\"alert\">\n <div className=\"hv-error-title\">{locale['error.title'] ?? 'Error'}</div>\n <div className=\"hv-error-body\">{error}</div>\n </div>\n ) : null}\n\n {!resolved && !error ? <div className=\"hv-loading\" aria-busy=\"true\">{locale['loading'] ?? 'Loading…'}</div> : null}\n\n {resolved ? (\n <div className=\"hv-shell\">\n {mode !== 'create' ? (\n <ThumbnailsSidebar\n locale={locale}\n thumbnails={thumbnails}\n currentPage={currentPage}\n collapsed={!showThumbnails}\n onToggle={() => setShowThumbnails((v: boolean) => !v)}\n onSelectPage={setCurrentPage}\n />\n ) : null}\n\n <main className=\"hv-main\">\n {resolved.fileType === 'pdf' ? (\n <PdfRenderer\n url={resolved.url}\n arrayBuffer={resolved.arrayBuffer}\n layout={layout}\n currentPage={currentPage}\n onCurrentPageChange={setCurrentPage}\n onPageCount={(n) => {\n setPageCount(n);\n setThumbs((prev) => (prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i])));\n }}\n onThumbs={(t) => setThumbs(t)}\n signatureStamp={armedSignatureUrl ? { imageUrl: armedSignatureUrl, armed: true, onPlaced: placeSignature } : undefined}\n />\n ) : null}\n\n {resolved.fileType === 'docx' || resolved.fileType === 'md' || resolved.fileType === 'txt' ? (\n <RichTextEditor\n ref={editorRef as any}\n mode={mode}\n fileType={resolved.fileType}\n fileName={resolved.fileName}\n arrayBuffer={resolved.arrayBuffer}\n headerComponent={props.headerComponent}\n footerComponent={props.footerComponent}\n headerFooterEnabled={headerFooterEnabled}\n locale={locale}\n signatures={localSignatures}\n signaturePlacements={sigPlacements}\n onPageCount={(n) => { setPageCount(n); setThumbs((prev) => (prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i]))); }}\n onSave={(b64, meta) => props.onSave?.(b64, meta)}\n armedSignatureUrl={armedSignatureUrl}\n onPlaceSignature={placeSignature}\n />\n ) : null}\n\n {resolved.fileType === 'xlsx' ? (\n <SpreadsheetEditor\n ref={editorRef as any}\n mode={mode}\n fileName={resolved.fileName}\n arrayBuffer={resolved.arrayBuffer}\n locale={locale}\n onSave={(b64, meta) => props.onSave?.(b64, meta)}\n />\n ) : null}\n\n {resolved.fileType === 'pptx' ? (\n <PptxRenderer\n arrayBuffer={resolved.arrayBuffer}\n layout={layout}\n currentPage={currentPage}\n onCurrentPageChange={setCurrentPage}\n onSlideCount={(n) => {\n setPageCount(n);\n setThumbs((prev) => (prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i])));\n }}\n onThumbs={(t) => setThumbs(t)}\n />\n ) : null}\n\n {resolved.fileType === 'png' || resolved.fileType === 'jpg' || resolved.fileType === 'svg' ? (\n <ImageRenderer arrayBuffer={resolved.arrayBuffer} fileType={resolved.fileType} fileName={resolved.fileName} />\n ) : null}\n </main>\n\n {mode !== 'create' && localSignatures.length ? (\n <SignaturePanel\n locale={locale}\n signatures={localSignatures}\n collapsed={!showSignatures}\n onToggle={() => setShowSignatures((v: boolean) => !v)}\n />\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction arrayBufferToBase64(ab: ArrayBuffer): string {\n const bytes = new Uint8Array(ab);\n let binary = '';\n const chunk = 0x8000;\n for (let i = 0; i < bytes.length; i += chunk) {\n binary += String.fromCharCode(...bytes.subarray(i, i + chunk));\n }\n return btoa(binary);\n}\n","export const defaultLocale: Record<string, string> = {\n 'loading': 'Loading…',\n 'error.title': 'Error',\n 'toolbar.layout.single': 'Single page',\n 'toolbar.layout.two': 'Side-by-side',\n 'toolbar.thumbs': 'Thumbnails',\n 'toolbar.signatures': 'Signatures',\n 'toolbar.sign': 'Sign Document',\n 'toolbar.save': 'Save',\n 'toolbar.exportPdf': 'Export as PDF',\n 'thumbnails.title': 'Thumbnails',\n 'thumbnails.page': 'Page',\n 'signatures.title': 'Signatures',\n 'signatures.empty': 'No signatures',\n 'signatures.placeHint': 'Click on the document to place the signature.',\n 'a11y.viewer': 'Document viewer',\n 'a11y.ribbon': 'Ribbon',\n 'a11y.editor': 'Document editor'\n};\n","import type { SupportedFileType } from '../types';\n\nexport function guessFileType(name?: string, explicit?: SupportedFileType): SupportedFileType {\n if (explicit) return explicit;\n const ext = (name?.split('.').pop() || '').toLowerCase();\n const allowed: SupportedFileType[] = ['pdf','md','docx','xlsx','pptx','txt','png','jpg','svg'];\n return (allowed as string[]).includes(ext) ? (ext as SupportedFileType) : 'txt';\n}\n\nexport function arrayBufferToBase64(buf: ArrayBuffer): string {\n const bytes = new Uint8Array(buf);\n let binary = '';\n const chunk = 0x8000;\n for (let i = 0; i < bytes.length; i += chunk) {\n binary += String.fromCharCode(...bytes.subarray(i, i + chunk));\n }\n return btoa(binary);\n}\n\nexport async function base64ToArrayBuffer(b64: string): Promise<ArrayBuffer> {\n const bin = atob(b64);\n const len = bin.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) bytes[i] = bin.charCodeAt(i);\n return bytes.buffer;\n}\n\nexport async function resolveSource(args: {\n fileUrl?: string;\n base64?: string;\n blob?: Blob;\n fileName?: string;\n fileType?: SupportedFileType;\n onProgress?: (loaded: number, total?: number) => void;\n}): Promise<{ fileType: SupportedFileType; fileName: string; arrayBuffer: ArrayBuffer; url?: string }>{\n const fileType = guessFileType(args.fileName, args.fileType);\n const fileName = args.fileName ?? `document.${fileType}`;\n\n if (args.blob) {\n const ab = await args.blob.arrayBuffer();\n const url = URL.createObjectURL(args.blob);\n return { fileType, fileName, arrayBuffer: ab, url };\n }\n\n if (args.base64) {\n const ab = await base64ToArrayBuffer(args.base64);\n return { fileType, fileName, arrayBuffer: ab };\n }\n\n if (!args.fileUrl) throw new Error('No file source provided. Use fileUrl, blob, or base64.');\n\n const res = await fetch(args.fileUrl);\n if (!res.ok) throw new Error(`Failed to fetch file (${res.status})`);\n\n const total = Number(res.headers.get('content-length') || '') || undefined;\n if (!res.body) {\n const ab = await res.arrayBuffer();\n args.onProgress?.(ab.byteLength, total);\n return { fileType, fileName, arrayBuffer: ab, url: args.fileUrl };\n }\n\n const reader = res.body.getReader();\n const chunks: Uint8Array[] = [];\n let loaded = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n if (value) {\n chunks.push(value);\n loaded += value.length;\n args.onProgress?.(loaded, total);\n }\n }\n const out = new Uint8Array(loaded);\n let offset = 0;\n for (const c of chunks) { out.set(c, offset); offset += c.length; }\n return { fileType, fileName, arrayBuffer: out.buffer, url: args.fileUrl };\n}\n","'use client';\n\nimport React from 'react';\nimport type { DocumentMode, PageLayout, SupportedFileType } from '../types';\n\nexport function Toolbar(props: {\n locale: Record<string, string>;\n mode: DocumentMode;\n fileType?: SupportedFileType;\n layout: PageLayout;\n onChangeLayout: (l: PageLayout) => void;\n showThumbnails: boolean;\n onToggleThumbnails: () => void;\n showSignatures: boolean;\n onToggleSignatures: () => void;\n allowSigning: boolean;\n signingDisabled: boolean;\n onSign: () => void;\n canSave: boolean;\n onSave: () => void;\n canExportPdf: boolean;\n onExportPdf: () => void;\n showHeaderFooterToggle: boolean;\n headerFooterEnabled: boolean;\n onToggleHeaderFooter: () => void;\n}) {\n const t = (k: string, fallback: string) => props.locale[k] ?? fallback;\n\n return (\n <div className=\"hv-toolbar\" role=\"toolbar\" aria-label={t('a11y.toolbar', 'Document toolbar')}>\n <div className=\"hv-toolbar__left\">\n <button type=\"button\" className=\"hv-btn\" onClick={props.onToggleThumbnails} aria-pressed={props.showThumbnails}>\n {t('toolbar.thumbs', 'Thumbnails')}\n </button>\n {props.mode !== 'create' && (\n <button type=\"button\" className=\"hv-btn\" onClick={props.onToggleSignatures} aria-pressed={props.showSignatures}>\n {t('toolbar.signatures', 'Signatures')}\n </button>\n )}\n <span className=\"hv-sep\" />\n <button type=\"button\" className={props.layout === 'single' ? 'hv-btn hv-btn--active' : 'hv-btn'} onClick={() => props.onChangeLayout('single')}>\n {t('toolbar.layout.single', 'Single')}\n </button>\n <button type=\"button\" className={props.layout === 'side-by-side' ? 'hv-btn hv-btn--active' : 'hv-btn'} onClick={() => props.onChangeLayout('side-by-side')}>\n {t('toolbar.layout.two', 'Two')}\n </button>\n </div>\n\n <div className=\"hv-toolbar__right\">\n {props.showHeaderFooterToggle && (\n <label className=\"hv-toggle\">\n <input type=\"checkbox\" checked={props.headerFooterEnabled} onChange={props.onToggleHeaderFooter} />\n <span>{t('toolbar.letterhead', 'Letterhead')}</span>\n </label>\n )}\n\n {props.allowSigning && (\n <button type=\"button\" className=\"hv-btn hv-btn--primary\" onClick={props.onSign} disabled={props.signingDisabled}>\n {t('toolbar.sign', 'Sign Document')}\n </button>\n )}\n\n {props.canExportPdf && (\n <button type=\"button\" className=\"hv-btn\" onClick={props.onExportPdf}>\n {t('toolbar.exportPdf', 'Export as PDF')}\n </button>\n )}\n {props.canSave && (\n <button type=\"button\" className=\"hv-btn hv-btn--primary\" onClick={props.onSave}>\n {t('toolbar.save', 'Save')}\n </button>\n )}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport React from 'react';\n\nexport type Thumbnail = {\n id: string;\n label: string;\n dataUrl?: string;\n};\n\nexport function ThumbnailsSidebar(props: {\n locale: Record<string, string>;\n thumbnails: Thumbnail[];\n currentPage: number;\n collapsed: boolean;\n onToggle: () => void;\n onSelectPage: (p: number) => void;\n}) {\n const t = props.locale['thumbnails.title'] ?? 'Thumbnails';\n return (\n <aside className={props.collapsed ? 'hv-thumbs hv-thumbs--collapsed' : 'hv-thumbs'} aria-label={t}>\n <div className=\"hv-thumbs__header\">\n <button type=\"button\" className=\"hv-icon\" onClick={props.onToggle} aria-label={props.collapsed ? (props.locale['thumbnails.open'] ?? 'Open thumbnails') : (props.locale['thumbnails.close'] ?? 'Close thumbnails')}\n >{props.collapsed ? '▸' : '▾'}</button>\n {!props.collapsed ? <div className=\"hv-thumbs__title\">{t}</div> : null}\n </div>\n {!props.collapsed ? (\n <div className=\"hv-thumbs__list\" role=\"list\">\n {props.thumbnails.map((th, idx) => {\n const p = idx + 1;\n const active = p === props.currentPage;\n return (\n <button\n key={th.id}\n type=\"button\"\n role=\"listitem\"\n className={active ? 'hv-thumb hv-thumb--active' : 'hv-thumb'}\n onClick={() => props.onSelectPage(p)}\n aria-current={active ? 'page' : undefined}\n >\n <div className=\"hv-thumb__img\" aria-hidden>\n {th.dataUrl ? <img src={th.dataUrl} alt=\"\" /> : <div className=\"hv-thumb__placeholder\" />}\n </div>\n <div className=\"hv-thumb__label\">{th.label}</div>\n </button>\n );\n })}\n </div>\n ) : null}\n </aside>\n );\n}\n","'use client';\n\nimport React from 'react';\nimport type { Signature } from '../types';\n\nexport function SignaturePanel(props: {\n locale: Record<string, string>;\n signatures: Signature[];\n collapsed: boolean;\n onToggle: () => void;\n}) {\n const title = props.locale['signatures.title'] ?? 'Signatures';\n return (\n <aside className={props.collapsed ? 'hv-side hv-side--collapsed' : 'hv-side'} aria-label={title}>\n <div className=\"hv-sidebar-header\">\n <button type=\"button\" className=\"hv-icon\" onClick={props.onToggle} aria-label={props.locale['toolbar.signatures'] ?? 'Signatures'}>\n ✍\n </button>\n <div className=\"hv-sidebar-title\">{title}</div>\n </div>\n <div className=\"hv-sidebar-body\">\n {props.signatures.map((s, idx) => (\n <div key={`${s.signedBy}-${s.dateSigned}-${idx}`} className=\"hv-signature-card\">\n <img src={s.signatureImageUrl} alt={`Signature by ${s.signedBy}`} className=\"hv-signature-img\" />\n <div className=\"hv-signature-meta\">\n <div className=\"hv-signature-name\">{s.signedBy}</div>\n <div className=\"hv-signature-date\">{new Date(s.dateSigned).toLocaleString()}</div>\n {s.comment ? <div className=\"hv-signature-comment\">{s.comment}</div> : null}\n </div>\n </div>\n ))}\n </div>\n </aside>\n );\n}\n","'use client';\n\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { GlobalWorkerOptions, getDocument, type PDFDocumentProxy } from 'pdfjs-dist';\nimport type { PageLayout } from '../types';\n\nexport function PdfRenderer(props: {\n url?: string;\n arrayBuffer?: ArrayBuffer;\n layout: PageLayout;\n currentPage: number;\n onCurrentPageChange: (p: number) => void;\n onPageCount: (n: number) => void;\n onThumbs: (thumbs: (string | undefined)[]) => void;\n signatureStamp?: {\n imageUrl: string;\n armed: boolean;\n onPlaced: (placement: { page: number; x: number; y: number; w: number; h: number }) => void;\n };\n}) {\n const { url, arrayBuffer } = props;\n const [doc, setDoc] = useState<PDFDocumentProxy | null>(null);\n const [pageCount, setPageCount] = useState(0);\n const [rendered, setRendered] = useState<Map<number, HTMLCanvasElement>>(new Map());\n const [thumbs, setThumbs] = useState<(string | undefined)[]>([]);\n const [size, setSize] = useState({ w: 840, h: 1188 });\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n try {\n GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.min.mjs', import.meta.url).toString();\n } catch {}\n }, []);\n\n useEffect(() => {\n let cancel = false;\n (async () => {\n setDoc(null);\n setRendered(new Map());\n setThumbs([]);\n if (!url && !arrayBuffer) return;\n const task = getDocument(url ? { url, rangeChunkSize: 512 * 1024 } : { data: arrayBuffer! });\n const pdf = await task.promise;\n if (cancel) return;\n setDoc(pdf);\n setPageCount(pdf.numPages);\n props.onPageCount(pdf.numPages);\n setThumbs(Array.from({ length: pdf.numPages }));\n const p1 = await pdf.getPage(1);\n const base = p1.getViewport({ scale: 1 });\n const w = Math.min(980, Math.max(640, base.width));\n const s = w / base.width;\n const vp = p1.getViewport({ scale: s });\n setSize({ w: Math.round(vp.width), h: Math.round(vp.height) });\n })().catch(() => {\n // ignore; caller shows error\n });\n return () => { cancel = true; };\n }, [url, arrayBuffer]);\n\n useEffect(() => {\n props.onThumbs(thumbs);\n }, [thumbs]);\n\n const pagesToShow = useMemo(() => {\n if (props.layout === 'side-by-side') {\n const left = props.currentPage;\n const right = Math.min(pageCount || left + 1, left + 1);\n return [left, right];\n }\n return [props.currentPage];\n }, [props.currentPage, props.layout, pageCount]);\n\n useEffect(() => {\n if (!doc) return;\n let cancel = false;\n (async () => {\n for (const p of pagesToShow) {\n if (rendered.has(p)) continue;\n const page = await doc.getPage(p);\n if (cancel) return;\n const base = page.getViewport({ scale: 1 });\n const vp = page.getViewport({ scale: size.w / base.width });\n const canvas = document.createElement('canvas');\n canvas.width = Math.round(vp.width);\n canvas.height = Math.round(vp.height);\n const ctx = canvas.getContext('2d', { alpha: false });\n if (!ctx) continue;\n await page.render({ canvasContext: ctx, viewport: vp }).promise;\n if (cancel) return;\n setRendered(prev => {\n const next = new Map(prev);\n next.set(p, canvas);\n return next;\n });\n try {\n const tw = 140;\n const th = Math.round(tw * (canvas.height / canvas.width));\n const t = document.createElement('canvas');\n t.width = tw; t.height = th;\n const tctx = t.getContext('2d');\n if (tctx) {\n tctx.drawImage(canvas, 0, 0, tw, th);\n const url = t.toDataURL('image/jpeg', 0.75);\n setThumbs(prev => {\n const next = prev.slice();\n next[p - 1] = url;\n return next;\n });\n }\n } catch {}\n }\n })();\n return () => { cancel = true; };\n }, [doc, pagesToShow, size.w, rendered]);\n\n function onWheel(e: React.WheelEvent) {\n if (!pageCount) return;\n if (Math.abs(e.deltaY) < 10) return;\n const dir = e.deltaY > 0 ? 1 : -1;\n const step = props.layout === 'side-by-side' ? 2 : 1;\n const next = Math.max(1, Math.min(pageCount, props.currentPage + dir * step));\n props.onCurrentPageChange(next);\n }\n\n function clickPlace(e: React.MouseEvent, page: number) {\n const stamp = props.signatureStamp;\n if (!stamp?.armed) return;\n const rect = (e.currentTarget as HTMLDivElement).getBoundingClientRect();\n const x = (e.clientX - rect.left) / rect.width;\n const y = (e.clientY - rect.top) / rect.height;\n stamp.onPlaced({ page, x, y, w: 0.22, h: 0.08 });\n }\n\n return (\n <div className=\"hv-doc\" ref={containerRef} onWheel={onWheel}>\n {!doc ? <div className=\"hv-loading\">Loading PDF…</div> : null}\n {doc ? (\n <div className={props.layout === 'side-by-side' ? 'hv-pages hv-pages--two' : 'hv-pages'}>\n {pagesToShow.map(p => {\n const c = rendered.get(p);\n return (\n <div key={p} className=\"hv-page\" style={{ width: size.w, height: size.h }} onClick={(e) => clickPlace(e, p)}>\n {c ? (\n <canvas\n className=\"hv-canvas\"\n width={c.width}\n height={c.height}\n ref={(node) => {\n if (!node) return;\n const ctx = node.getContext('2d');\n if (ctx) ctx.drawImage(c, 0, 0);\n }}\n />\n ) : <div className=\"hv-loading\">Rendering…</div>}\n </div>\n );\n })}\n </div>\n ) : null}\n </div>\n );\n}\n","'use client';\n\nimport React, { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';\nimport mammoth from 'mammoth';\nimport htmlToDocx from 'html-to-docx';\nimport MarkdownIt from 'markdown-it';\nimport html2canvas from 'html2canvas';\nimport { sanitizeHtml } from '../utils/sanitize';\nimport { arrayBufferToBase64 } from '../utils/fileSource';\nimport type { DocumentMode, Signature, SupportedFileType } from '../types';\n\nconst PAGE_H = 1122; // virtual A4\n\nexport type RichTextEditorHandle = {\n save: (exportPdf?: boolean) => Promise<void>;\n requestThumbnail: (index: number) => Promise<string | undefined>;\n};\n\nexport const RichTextEditor = forwardRef<RichTextEditorHandle, {\n mode: DocumentMode;\n fileType: 'docx' | 'md' | 'txt';\n fileName: string;\n arrayBuffer?: ArrayBuffer;\n locale: Record<string, string>;\n headerComponent?: React.ReactNode;\n footerComponent?: React.ReactNode;\n headerFooterEnabled: boolean;\n signatures: Signature[];\n signaturePlacements: { page: number; x: number; y: number; w: number; h: number; signatureImageUrl: string }[];\n armedSignatureUrl: string | null;\n onPlaceSignature: (p: { page: number; x: number; y: number; w: number; h: number }) => void;\n onSave: (b64: string, meta: { fileName: string; fileType: SupportedFileType; exportedAsPdf?: boolean; annotations?: unknown }) => void;\n onPageCount: (n: number) => void;\n}>((props, ref) => {\n const readOnly = props.mode === 'view';\n const md = useMemo(() => new MarkdownIt({ html: false, linkify: true, breaks: true }), []);\n const scrollerRef = useRef<HTMLDivElement | null>(null);\n const editorRef = useRef<HTMLDivElement | null>(null);\n const captureRef = useRef<HTMLDivElement | null>(null);\n\n const [html, setHtml] = useState('<p><br/></p>');\n\n useEffect(() => {\n let cancelled = false;\n (async () => {\n if (props.mode === 'create') {\n setHtml('<p><br/></p>');\n return;\n }\n if (!props.arrayBuffer) return;\n if (props.fileType === 'docx') {\n const res = await mammoth.convertToHtml({ arrayBuffer: props.arrayBuffer });\n if (!cancelled) setHtml(sanitizeHtml(res.value || '<p><br/></p>'));\n } else {\n const text = new TextDecoder().decode(props.arrayBuffer);\n if (props.fileType === 'md') setHtml(sanitizeHtml(md.render(text)));\n else setHtml(`<pre>${escapeHtml(text)}</pre>`);\n }\n })();\n return () => { cancelled = true; };\n }, [props.arrayBuffer, props.fileType, props.mode, md]);\n\n useEffect(() => {\n const el = scrollerRef.current;\n if (!el) return;\n const recompute = () => props.onPageCount(Math.max(1, Math.ceil(el.scrollHeight / PAGE_H)));\n recompute();\n const ro = new ResizeObserver(recompute);\n ro.observe(el);\n return () => ro.disconnect();\n }, [html, props.headerFooterEnabled]);\n\n function exec(cmd: string) {\n if (readOnly) return;\n document.execCommand(cmd);\n }\n\n function onClick(e: React.MouseEvent<HTMLDivElement>) {\n if (!props.armedSignatureUrl) return;\n const scroller = scrollerRef.current;\n if (!scroller) return;\n const rect = (e.currentTarget as HTMLDivElement).getBoundingClientRect();\n const absY = scroller.scrollTop + (e.clientY - rect.top);\n const page = Math.max(1, Math.floor(absY / PAGE_H) + 1);\n const pageTop = (page - 1) * PAGE_H;\n const x = (e.clientX - rect.left) / rect.width;\n const y = (absY - pageTop) / PAGE_H;\n props.onPlaceSignature({ page, x, y, w: 0.25, h: 0.1 });\n }\n\n async function requestThumbnail(index: number): Promise<string | undefined> {\n const scroller = scrollerRef.current;\n const capture = captureRef.current;\n if (!scroller || !capture) return undefined;\n const old = scroller.scrollTop;\n scroller.scrollTop = index * PAGE_H;\n await new Promise((r) => requestAnimationFrame(() => r(null)));\n try {\n const canvas = await html2canvas(capture, { backgroundColor: null, scale: 0.25, useCORS: true });\n return canvas.toDataURL('image/png');\n } catch {\n return undefined;\n } finally {\n scroller.scrollTop = old;\n }\n }\n\n async function save(exportPdf?: boolean) {\n const inner = editorRef.current?.innerHTML ?? html;\n const stitched = `<!doctype html><html><head><meta charset=\"utf-8\" /></head><body>${inner}</body></html>`;\n\n if (exportPdf) {\n // client-side: return print-ready HTML as base64\n const b64 = btoa(unescape(encodeURIComponent(stitched)));\n props.onSave(b64, { fileName: replaceExt(props.fileName, 'html'), fileType: 'txt', exportedAsPdf: true, annotations: { signaturePlacements: props.signaturePlacements } });\n return;\n }\n\n if (props.fileType === 'docx') {\n const blob = await htmlToDocx(stitched);\n const ab = await blob.arrayBuffer();\n props.onSave(arrayBufferToBase64(ab), { fileName: replaceExt(props.fileName, 'docx'), fileType: 'docx', annotations: { signaturePlacements: props.signaturePlacements } });\n return;\n }\n\n const text = editorRef.current?.innerText ?? '';\n const b64 = btoa(unescape(encodeURIComponent(text)));\n props.onSave(b64, { fileName: replaceExt(props.fileName, props.fileType), fileType: props.fileType, annotations: { signaturePlacements: props.signaturePlacements } });\n }\n\n useImperativeHandle(ref, () => ({ save, requestThumbnail }));\n\n return (\n <div className=\"hv-doc\">\n <div className=\"hv-ribbon\" role=\"toolbar\">\n <button className=\"hv-btn\" onClick={() => exec('bold')} disabled={readOnly}>B</button>\n <button className=\"hv-btn\" onClick={() => exec('italic')} disabled={readOnly}>I</button>\n <button className=\"hv-btn\" onClick={() => exec('underline')} disabled={readOnly}>U</button>\n {props.armedSignatureUrl ? <div className=\"hv-hint\">Click to place signature</div> : null}\n </div>\n\n <div className=\"hv-scroll\" ref={scrollerRef} onClick={onClick}>\n <div className=\"hv-pageStage\" ref={captureRef}>\n {props.headerFooterEnabled && props.headerComponent ? <div className=\"hv-letterhead\">{props.headerComponent}</div> : null}\n\n <div\n ref={editorRef}\n className={readOnly ? 'hv-editor hv-editor--ro' : 'hv-editor'}\n contentEditable={!readOnly}\n suppressContentEditableWarning\n onInput={() => setHtml(editorRef.current?.innerHTML ?? '')}\n dangerouslySetInnerHTML={{ __html: html }}\n />\n\n {props.headerFooterEnabled && props.footerComponent ? <div className=\"hv-letterhead hv-letterhead--footer\">{props.footerComponent}</div> : null}\n\n {props.mode === 'create' && props.signatures.length ? (\n <div className=\"hv-signatures-inline\">\n {props.signatures.map((s, i) => (\n <div key={i} className=\"hv-sign-inline\">\n <img src={s.signatureImageUrl} alt=\"\" className=\"hv-sign-img\" />\n <div>\n <div className=\"hv-sign-name\">{s.signedBy}</div>\n <div className=\"hv-sign-date\">{new Date(s.dateSigned).toLocaleString()}</div>\n </div>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n </div>\n </div>\n );\n});\n\nfunction replaceExt(name: string, ext: string) {\n const base = name.includes('.') ? name.slice(0, name.lastIndexOf('.')) : name;\n return `${base}.${ext}`;\n}\n\nfunction escapeHtml(s: string) {\n return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');\n}\n","import DOMPurify from 'dompurify';\n\nexport function sanitizeHtml(html: string): string {\n // DOMPurify is safe to call in the browser. For SSR, callers should only run after mount.\n return DOMPurify.sanitize(html, {\n USE_PROFILES: { html: true },\n ADD_ATTR: ['target', 'rel']\n });\n}\n","'use client';\n\nimport React, { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from 'react';\nimport * as XLSX from 'xlsx';\nimport { arrayBufferToBase64 } from '../utils/fileSource';\nimport type { DocumentMode, SupportedFileType } from '../types';\n\nexport type SpreadsheetEditorHandle = {\n save: (exportPdf?: boolean) => Promise<void>;\n requestThumbnails: (index: number) => Promise<void>;\n};\n\nexport const SpreadsheetEditor = forwardRef<SpreadsheetEditorHandle, {\n mode: DocumentMode;\n fileName: string;\n arrayBuffer?: ArrayBuffer;\n locale: Record<string, string>;\n onSave: (base64: string, meta: { fileName: string; fileType: SupportedFileType; exportedAsPdf?: boolean }) => void;\n}>(function SpreadsheetEditor(props, ref) {\n const readonly = props.mode === 'view';\n const [grid, setGrid] = useState<string[][]>(() => Array.from({ length: 30 }, () => Array.from({ length: 12 }, () => '')));\n\n useEffect(() => {\n if (!props.arrayBuffer) return;\n try {\n const wb = XLSX.read(props.arrayBuffer, { type: 'array' });\n const name = wb.SheetNames[0];\n const ws = wb.Sheets[name];\n const aoa = XLSX.utils.sheet_to_json(ws, { header: 1, raw: true }) as any[][];\n const rows = Math.max(30, aoa.length);\n const cols = Math.max(12, Math.max(...aoa.map(r => (r?.length ?? 0)), 0));\n const next = Array.from({ length: rows }, (_, r) => Array.from({ length: cols }, (_, c) => {\n const v = aoa[r]?.[c];\n return v == null ? '' : String(v);\n }));\n setGrid(next);\n } catch {\n // ignore\n }\n }, [props.arrayBuffer]);\n\n async function save(exportPdf?: boolean) {\n const ws = XLSX.utils.aoa_to_sheet(grid);\n const wb = XLSX.utils.book_new();\n XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');\n const out = XLSX.write(wb, { type: 'array', bookType: 'xlsx' }) as ArrayBuffer;\n const b64 = arrayBufferToBase64(out);\n props.onSave(b64, { fileName: ensureExt(props.fileName, 'xlsx'), fileType: 'xlsx', exportedAsPdf: !!exportPdf });\n }\n\n useImperativeHandle(ref, () => ({\n save,\n requestThumbnails: async () => undefined\n }));\n\n const cols = useMemo(() => Array.from({ length: grid[0]?.length ?? 0 }, (_, i) => String.fromCharCode(65 + (i % 26))), [grid]);\n\n return (\n <div className=\"hv-sheet\">\n <div className=\"hv-sheetbar\">\n <div className=\"hv-sheetbar-title\">{props.fileName}</div>\n {!readonly ? <button className=\"hv-btn\" type=\"button\" onClick={() => void save(false)}>{props.locale['toolbar.save'] ?? 'Save'}</button> : null}\n </div>\n <div className=\"hv-sheetgrid\" role=\"table\" aria-label=\"Spreadsheet\">\n <div className=\"hv-sheetrow hv-sheetrow--header\" role=\"row\">\n <div className=\"hv-sheetcell hv-sheetcell--corner\" role=\"columnheader\" />\n {cols.map((c, i) => <div key={i} className=\"hv-sheetcell hv-sheetcell--header\" role=\"columnheader\">{c}</div>)}\n </div>\n {grid.map((row, r) => (\n <div key={r} className=\"hv-sheetrow\" role=\"row\">\n <div className=\"hv-sheetcell hv-sheetcell--header\" role=\"rowheader\">{r + 1}</div>\n {row.map((val, c) => (\n <div\n key={c}\n className=\"hv-sheetcell\"\n role=\"cell\"\n contentEditable={!readonly}\n suppressContentEditableWarning\n onInput={(e) => {\n const text = (e.currentTarget.textContent ?? '');\n setGrid((prev) => {\n const next = prev.map(rr => rr.slice());\n next[r][c] = text;\n return next;\n });\n }}\n >{val}</div>\n ))}\n </div>\n ))}\n </div>\n </div>\n );\n});\n\nfunction ensureExt(name: string, ext: string) {\n const base = name.includes('.') ? name.slice(0, name.lastIndexOf('.')) : name;\n return `${base}.${ext}`;\n}\n","'use client';\n\nimport React, { useEffect, useMemo, useState } from 'react';\nimport type { SupportedFileType } from '../types';\n\nexport function ImageRenderer({ arrayBuffer, fileType, fileName }: { arrayBuffer?: ArrayBuffer; fileType: SupportedFileType; fileName: string }) {\n const [zoom, setZoom] = useState(1);\n const url = useMemo(() => {\n if (!arrayBuffer) return undefined;\n const mime = fileType === 'svg' ? 'image/svg+xml' : fileType === 'png' ? 'image/png' : 'image/jpeg';\n return URL.createObjectURL(new Blob([arrayBuffer], { type: mime }));\n }, [arrayBuffer, fileType]);\n\n useEffect(() => {\n return () => { if (url) URL.revokeObjectURL(url); };\n }, [url]);\n\n return (\n <div className=\"hv-doc\">\n <div className=\"hv-mini-toolbar\">\n <div className=\"hv-title\">{fileName}</div>\n <div className=\"hv-spacer\" />\n <button type=\"button\" className=\"hv-btn\" onClick={() => setZoom((z) => Math.max(0.25, z - 0.25))}>-</button>\n <div className=\"hv-zoom\">{Math.round(zoom * 100)}%</div>\n <button type=\"button\" className=\"hv-btn\" onClick={() => setZoom((z) => Math.min(4, z + 0.25))}>+</button>\n </div>\n <div className=\"hv-center\">\n {url ? <img src={url} alt={fileName} style={{ transform: `scale(${zoom})` }} className=\"hv-image\" /> : <div className=\"hv-loading\">Loading…</div>}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport React, { useEffect, useMemo, useState } from 'react';\nimport JSZip from 'jszip';\nimport type { PageLayout } from '../types';\n\ntype Slide = { index: number; text: string };\n\nfunction decodeXml(s: string): string {\n return s\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\");\n}\n\nfunction extractText(xml: string) {\n return [...xml.matchAll(/<a:t>(.*?)<\\/a:t>/g)].map(m => decodeXml(m[1] || '')).join(' ').trim();\n}\n\nexport function PptxRenderer(props: {\n arrayBuffer?: ArrayBuffer;\n layout: PageLayout;\n currentPage: number;\n onCurrentPageChange: (p: number) => void;\n onSlideCount: (n: number) => void;\n onThumbs: (thumbs: (string|undefined)[]) => void;\n}) {\n const [slides, setSlides] = useState<Slide[]>([]);\n const [thumbs, setThumbs] = useState<(string | undefined)[]>([]);\n\n useEffect(() => {\n let cancelled = false;\n (async () => {\n setSlides([]); setThumbs([]);\n if (!props.arrayBuffer) { props.onSlideCount(1); setSlides([{index:1,text:'No content'}]); return; }\n const zip = await JSZip.loadAsync(props.arrayBuffer);\n const files = Object.keys(zip.files).filter(p => /^ppt\\/slides\\/slide\\d+\\.xml$/.test(p)).sort((a,b)=>{\n const na = Number(a.match(/slide(\\d+)\\.xml/)?.[1]||0);\n const nb = Number(b.match(/slide(\\d+)\\.xml/)?.[1]||0);\n return na-nb;\n });\n const out: Slide[] = [];\n for (let i=0;i<files.length;i++) {\n const xml = await zip.file(files[i])!.async('string');\n out.push({ index:i+1, text: extractText(xml) });\n }\n if (cancelled) return;\n const count = Math.max(1,out.length);\n props.onSlideCount(count);\n setSlides(out.length?out:[{index:1,text:'(empty)'}]);\n setThumbs(Array.from({length:count}, (_,i)=>`data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgThumb(i+1))}`));\n })().catch(()=>{\n props.onSlideCount(1);\n setSlides([{index:1,text:'Unable to render this .pptx in-browser.'}]);\n setThumbs([undefined]);\n });\n return ()=>{cancelled=true;};\n }, [props.arrayBuffer]);\n\n useEffect(()=>{ props.onThumbs(thumbs); }, [thumbs]);\n\n const pagesToShow = useMemo(()=>{\n if (props.layout==='side-by-side') return [props.currentPage, Math.min(slides.length||props.currentPage+1, props.currentPage+1)];\n return [props.currentPage];\n }, [props.currentPage, props.layout, slides.length]);\n\n return (\n <div className=\"hv-doc\">\n <div className={props.layout==='side-by-side' ? 'hv-pages hv-pages--two' : 'hv-pages'}>\n {pagesToShow.map(p=>{\n const s = slides[p-1];\n return (\n <div key={p} className=\"hv-slide\" tabIndex={0} onFocus={()=>props.onCurrentPageChange(p)}>\n <div className=\"hv-slide-title\">Slide {p}</div>\n <div className=\"hv-slide-text\">{s?.text || ''}</div>\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nfunction svgThumb(n: number) {\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"180\" height=\"100\"><rect width=\"100%\" height=\"100%\" rx=\"12\" fill=\"#111827\"/><text x=\"50%\" y=\"54%\" font-size=\"18\" fill=\"#e5e7eb\" text-anchor=\"middle\">${n}</text></svg>`;\n}\n"],"mappings":"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","names":["useEffect","useMemo","useRef","useState","jsx","jsxs","jsx","jsxs","jsx","jsxs","url","useEffect","useMemo","useRef","useState","jsx","jsxs","useMemo","useRef","useState","useEffect","b64","forwardRef","useEffect","useImperativeHandle","useMemo","useState","jsx","jsxs","forwardRef","SpreadsheetEditor","useState","useEffect","cols","_","useImperativeHandle","useMemo","useEffect","useMemo","useState","jsx","jsxs","useEffect","useMemo","useState","jsx","jsxs","jsx","jsxs","useMemo","useState","useEffect","useRef","arrayBufferToBase64"]}
1
+ {"version":3,"sources":["../src/components/DocumentViewer.tsx","../src/utils/locale.ts","../src/utils/fileSource.ts","../src/components/Toolbar.tsx","../src/components/ThumbnailsSidebar.tsx","../src/components/SignaturePanel.tsx","../src/renderers/PdfRenderer.tsx","../src/editors/RichTextEditor.tsx","../src/utils/sanitize.ts","../src/editors/SpreadsheetEditor.tsx","../src/renderers/ImageRenderer.tsx","../src/renderers/PptxRenderer.tsx"],"sourcesContent":["'use client';\n\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport type { DocumentMode, DocumentViewerProps, PageLayout, Signature, SupportedFileType } from '../types';\nimport { defaultLocale } from '../utils/locale';\nimport { resolveSource } from '../utils/fileSource';\nimport { Toolbar } from './Toolbar';\nimport { ThumbnailsSidebar, type Thumbnail } from './ThumbnailsSidebar';\nimport { SignaturePanel } from './SignaturePanel';\nimport { PdfRenderer } from '../renderers/PdfRenderer';\nimport { RichTextEditor, type RichTextEditorHandle } from '../editors/RichTextEditor';\nimport { SpreadsheetEditor, type SpreadsheetEditorHandle } from '../editors/SpreadsheetEditor';\nimport { ImageRenderer } from '../renderers/ImageRenderer';\nimport { PptxRenderer } from '../renderers/PptxRenderer';\n\ntype SigPlacement = { page: number; x: number; y: number; w: number; h: number; signatureImageUrl: string };\n\ntype EditorHandle = (RichTextEditorHandle | SpreadsheetEditorHandle) & { save: (exportPdf?: boolean) => Promise<void> };\n\nexport function DocumentViewer(props: DocumentViewerProps) {\n const mode: DocumentMode = props.mode ?? 'view';\n const theme = props.theme ?? 'light';\n const locale = useMemo(() => ({ ...defaultLocale, ...(props.locale ?? {}) }), [props.locale]);\n\n const [layout, setLayout] = useState<PageLayout>(props.defaultLayout ?? 'single');\n const [showThumbnails, setShowThumbnails] = useState(true);\n const [showSignatures, setShowSignatures] = useState(true);\n const [headerFooterEnabled, setHeaderFooterEnabled] = useState(true);\n\n const allowSigning = props.allowSigning ?? false;\n const [signingBusy, setSigningBusy] = useState(false);\n\n const [resolved, setResolved] = useState<{ fileType: SupportedFileType; fileName: string; url?: string; arrayBuffer?: ArrayBuffer } | null>(null);\n const [error, setError] = useState<string>('');\n const [pageCount, setPageCount] = useState(1);\n const [currentPage, setCurrentPage] = useState(1);\n const [thumbs, setThumbs] = useState<(string | undefined)[]>([]);\n\n const [localSignatures, setLocalSignatures] = useState<Signature[]>(props.signatures ?? []);\n useEffect(() => setLocalSignatures(props.signatures ?? []), [props.signatures]);\n\n const [sigPlacements, setSigPlacements] = useState<SigPlacement[]>([]);\n const [armedSignatureUrl, setArmedSignatureUrl] = useState<string | null>(null);\n\n const editorRef = useRef<EditorHandle | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n (async () => {\n setError('');\n setResolved(null);\n setThumbs([]);\n setPageCount(1);\n setCurrentPage(1);\n setSigPlacements([]);\n setArmedSignatureUrl(null);\n\n if (mode === 'create') {\n const ft = (props.fileType ?? 'docx') as SupportedFileType;\n setResolved({ fileType: ft, fileName: props.fileName ?? `Untitled.${ft}` });\n return;\n }\n\n try {\n const res = await resolveSource({\n fileUrl: props.fileUrl,\n base64: props.base64,\n blob: props.blob,\n fileName: props.fileName,\n fileType: props.fileType\n });\n if (cancelled) return;\n setResolved({ fileType: res.fileType, fileName: res.fileName, url: res.url, arrayBuffer: res.arrayBuffer });\n } catch (e) {\n if (cancelled) return;\n setError(e instanceof Error ? e.message : String(e));\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [mode, props.fileUrl, props.base64, props.blob, props.fileName, props.fileType]);\n\n const thumbnails: Thumbnail[] = useMemo(() => {\n const n = Math.max(1, pageCount);\n return Array.from({ length: n }, (_, i) => ({\n id: `p-${i + 1}`,\n label: `${locale['thumbnails.page'] ?? 'Page'} ${i + 1}`,\n dataUrl: thumbs[i]\n }));\n }, [pageCount, thumbs, locale]);\n\n async function handleSignRequest() {\n if (!allowSigning || signingBusy || !props.onSignRequest) return;\n setSigningBusy(true);\n try {\n const sig = await props.onSignRequest();\n setLocalSignatures((prev: Signature[]) => [...prev, sig]);\n setArmedSignatureUrl(sig.signatureImageUrl);\n } finally {\n setSigningBusy(false);\n }\n }\n\n function placeSignature(p: { page: number; x: number; y: number; w: number; h: number }) {\n if (!armedSignatureUrl) return;\n setSigPlacements((prev: SigPlacement[]) => [...prev, { ...p, signatureImageUrl: armedSignatureUrl }]);\n setArmedSignatureUrl(null);\n }\n\n async function handleSave(exportPdf?: boolean) {\n if (editorRef.current) {\n await editorRef.current.save(!!exportPdf);\n return;\n }\n if (!resolved?.arrayBuffer) return;\n const b64 = arrayBufferToBase64(resolved.arrayBuffer);\n props.onSave?.(b64, { fileName: resolved.fileName, fileType: resolved.fileType, annotations: { sigPlacements } });\n }\n\n const canSave = mode === 'edit' || mode === 'create';\n const canExportPdf = (mode === 'edit' || mode === 'create') && (resolved?.fileType === 'docx' || resolved?.fileType === 'md' || resolved?.fileType === 'txt' || resolved?.fileType === 'xlsx');\n\n return (\n <div className={`hv-root`} data-hv-theme={theme}>\n <Toolbar\n locale={locale}\n mode={mode}\n fileType={resolved?.fileType}\n layout={layout}\n onChangeLayout={setLayout}\n showThumbnails={showThumbnails}\n onToggleThumbnails={() => setShowThumbnails((v: boolean) => !v)}\n showSignatures={showSignatures}\n onToggleSignatures={() => setShowSignatures((v: boolean) => !v)}\n onSign={() => void handleSignRequest()}\n allowSigning={allowSigning}\n signingDisabled={signingBusy || !props.onSignRequest}\n canSave={canSave}\n onSave={() => void handleSave(false)}\n canExportPdf={canExportPdf}\n onExportPdf={() => void handleSave(true)}\n headerFooterEnabled={headerFooterEnabled}\n showHeaderFooterToggle={(props.enableHeaderFooterToggle ?? true) && mode === 'create'}\n onToggleHeaderFooter={() => setHeaderFooterEnabled((v: boolean) => !v)}\n />\n\n {error ? (\n <div className=\"hv-error\" role=\"alert\">\n <div className=\"hv-error-title\">{locale['error.title'] ?? 'Error'}</div>\n <div className=\"hv-error-body\">{error}</div>\n </div>\n ) : null}\n\n {!resolved && !error ? <div className=\"hv-loading\" aria-busy=\"true\">{locale['loading'] ?? 'Loading…'}</div> : null}\n\n {resolved ? (\n <div className=\"hv-shell\">\n {mode !== 'create' ? (\n <ThumbnailsSidebar\n locale={locale}\n thumbnails={thumbnails}\n currentPage={currentPage}\n collapsed={!showThumbnails}\n onToggle={() => setShowThumbnails((v: boolean) => !v)}\n onSelectPage={setCurrentPage}\n />\n ) : null}\n\n <main className=\"hv-main\">\n {resolved.fileType === 'pdf' ? (\n <PdfRenderer\n url={resolved.url}\n arrayBuffer={resolved.arrayBuffer}\n layout={layout}\n currentPage={currentPage}\n onCurrentPageChange={setCurrentPage}\n onPageCount={(n) => {\n setPageCount(n);\n setThumbs((prev) => (prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i])));\n }}\n onThumbs={(t) => setThumbs(t)}\n signatureStamp={armedSignatureUrl ? { imageUrl: armedSignatureUrl, armed: true, onPlaced: placeSignature } : undefined}\n />\n ) : null}\n\n {resolved.fileType === 'docx' || resolved.fileType === 'md' || resolved.fileType === 'txt' ? (\n <RichTextEditor\n ref={editorRef as any}\n mode={mode}\n fileType={resolved.fileType}\n fileName={resolved.fileName}\n arrayBuffer={resolved.arrayBuffer}\n headerComponent={props.headerComponent}\n footerComponent={props.footerComponent}\n headerFooterEnabled={headerFooterEnabled}\n locale={locale}\n signatures={localSignatures}\n signaturePlacements={sigPlacements}\n onPageCount={(n) => { setPageCount(n); setThumbs((prev) => (prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i]))); }}\n onSave={(b64, meta) => props.onSave?.(b64, meta)}\n armedSignatureUrl={armedSignatureUrl}\n onPlaceSignature={placeSignature}\n />\n ) : null}\n\n {resolved.fileType === 'xlsx' ? (\n <SpreadsheetEditor\n ref={editorRef as any}\n mode={mode}\n fileName={resolved.fileName}\n arrayBuffer={resolved.arrayBuffer}\n locale={locale}\n onSave={(b64, meta) => props.onSave?.(b64, meta)}\n />\n ) : null}\n\n {resolved.fileType === 'pptx' ? (\n <PptxRenderer\n arrayBuffer={resolved.arrayBuffer}\n layout={layout}\n currentPage={currentPage}\n onCurrentPageChange={setCurrentPage}\n onSlideCount={(n) => {\n setPageCount(n);\n setThumbs((prev) => (prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i])));\n }}\n onThumbs={(t) => setThumbs(t)}\n />\n ) : null}\n\n {resolved.fileType === 'png' || resolved.fileType === 'jpg' || resolved.fileType === 'svg' ? (\n <ImageRenderer arrayBuffer={resolved.arrayBuffer} fileType={resolved.fileType} fileName={resolved.fileName} />\n ) : null}\n </main>\n\n {mode !== 'create' && localSignatures.length ? (\n <SignaturePanel\n locale={locale}\n signatures={localSignatures}\n collapsed={!showSignatures}\n onToggle={() => setShowSignatures((v: boolean) => !v)}\n />\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction arrayBufferToBase64(ab: ArrayBuffer): string {\n const bytes = new Uint8Array(ab);\n let binary = '';\n const chunk = 0x8000;\n for (let i = 0; i < bytes.length; i += chunk) {\n binary += String.fromCharCode(...bytes.subarray(i, i + chunk));\n }\n return btoa(binary);\n}\n","export const defaultLocale: Record<string, string> = {\n 'loading': 'Loading…',\n 'error.title': 'Error',\n 'toolbar.layout.single': 'Single page',\n 'toolbar.layout.two': 'Side-by-side',\n 'toolbar.thumbs': 'Thumbnails',\n 'toolbar.signatures': 'Signatures',\n 'toolbar.sign': 'Sign Document',\n 'toolbar.save': 'Save',\n 'toolbar.exportPdf': 'Export as PDF',\n 'thumbnails.title': 'Thumbnails',\n 'thumbnails.page': 'Page',\n 'signatures.title': 'Signatures',\n 'signatures.empty': 'No signatures',\n 'signatures.placeHint': 'Click on the document to place the signature.',\n 'a11y.viewer': 'Document viewer',\n 'a11y.ribbon': 'Ribbon',\n 'a11y.editor': 'Document editor'\n};\n","import type { SupportedFileType } from '../types';\n\nexport function guessFileType(name?: string, explicit?: SupportedFileType): SupportedFileType {\n if (explicit) return explicit;\n const ext = (name?.split('.').pop() || '').toLowerCase();\n const allowed: SupportedFileType[] = ['pdf','md','docx','xlsx','pptx','txt','png','jpg','svg'];\n return (allowed as string[]).includes(ext) ? (ext as SupportedFileType) : 'txt';\n}\n\nexport function arrayBufferToBase64(buf: ArrayBuffer): string {\n const bytes = new Uint8Array(buf);\n let binary = '';\n const chunk = 0x8000;\n for (let i = 0; i < bytes.length; i += chunk) {\n binary += String.fromCharCode(...bytes.subarray(i, i + chunk));\n }\n return btoa(binary);\n}\n\nexport async function base64ToArrayBuffer(b64: string): Promise<ArrayBuffer> {\n const bin = atob(b64);\n const len = bin.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) bytes[i] = bin.charCodeAt(i);\n return bytes.buffer;\n}\n\nexport async function resolveSource(args: {\n fileUrl?: string;\n base64?: string;\n blob?: Blob;\n fileName?: string;\n fileType?: SupportedFileType;\n onProgress?: (loaded: number, total?: number) => void;\n}): Promise<{ fileType: SupportedFileType; fileName: string; arrayBuffer: ArrayBuffer; url?: string }>{\n const fileType = guessFileType(args.fileName, args.fileType);\n const fileName = args.fileName ?? `document.${fileType}`;\n\n if (args.blob) {\n const ab = await args.blob.arrayBuffer();\n const url = URL.createObjectURL(args.blob);\n return { fileType, fileName, arrayBuffer: ab, url };\n }\n\n if (args.base64) {\n const ab = await base64ToArrayBuffer(args.base64);\n return { fileType, fileName, arrayBuffer: ab };\n }\n\n if (!args.fileUrl) throw new Error('No file source provided. Use fileUrl, blob, or base64.');\n\n const res = await fetch(args.fileUrl);\n if (!res.ok) throw new Error(`Failed to fetch file (${res.status})`);\n\n const total = Number(res.headers.get('content-length') || '') || undefined;\n if (!res.body) {\n const ab = await res.arrayBuffer();\n args.onProgress?.(ab.byteLength, total);\n return { fileType, fileName, arrayBuffer: ab, url: args.fileUrl };\n }\n\n const reader = res.body.getReader();\n const chunks: Uint8Array[] = [];\n let loaded = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n if (value) {\n chunks.push(value);\n loaded += value.length;\n args.onProgress?.(loaded, total);\n }\n }\n const out = new Uint8Array(loaded);\n let offset = 0;\n for (const c of chunks) { out.set(c, offset); offset += c.length; }\n return { fileType, fileName, arrayBuffer: out.buffer, url: args.fileUrl };\n}\n","'use client';\n\nimport React from 'react';\nimport type { DocumentMode, PageLayout, SupportedFileType } from '../types';\n\nexport function Toolbar(props: {\n locale: Record<string, string>;\n mode: DocumentMode;\n fileType?: SupportedFileType;\n layout: PageLayout;\n onChangeLayout: (l: PageLayout) => void;\n showThumbnails: boolean;\n onToggleThumbnails: () => void;\n showSignatures: boolean;\n onToggleSignatures: () => void;\n allowSigning: boolean;\n signingDisabled: boolean;\n onSign: () => void;\n canSave: boolean;\n onSave: () => void;\n canExportPdf: boolean;\n onExportPdf: () => void;\n showHeaderFooterToggle: boolean;\n headerFooterEnabled: boolean;\n onToggleHeaderFooter: () => void;\n}) {\n const t = (k: string, fallback: string) => props.locale[k] ?? fallback;\n\n return (\n <div className=\"hv-toolbar\" role=\"toolbar\" aria-label={t('a11y.toolbar', 'Document toolbar')}>\n <div className=\"hv-toolbar__left\">\n <button type=\"button\" className=\"hv-btn\" onClick={props.onToggleThumbnails} aria-pressed={props.showThumbnails}>\n {t('toolbar.thumbs', 'Thumbnails')}\n </button>\n {props.mode !== 'create' && (\n <button type=\"button\" className=\"hv-btn\" onClick={props.onToggleSignatures} aria-pressed={props.showSignatures}>\n {t('toolbar.signatures', 'Signatures')}\n </button>\n )}\n <span className=\"hv-sep\" />\n <button type=\"button\" className={props.layout === 'single' ? 'hv-btn hv-btn--active' : 'hv-btn'} onClick={() => props.onChangeLayout('single')}>\n {t('toolbar.layout.single', 'Single')}\n </button>\n <button type=\"button\" className={props.layout === 'side-by-side' ? 'hv-btn hv-btn--active' : 'hv-btn'} onClick={() => props.onChangeLayout('side-by-side')}>\n {t('toolbar.layout.two', 'Two')}\n </button>\n </div>\n\n <div className=\"hv-toolbar__right\">\n {props.showHeaderFooterToggle && (\n <label className=\"hv-toggle\">\n <input type=\"checkbox\" checked={props.headerFooterEnabled} onChange={props.onToggleHeaderFooter} />\n <span>{t('toolbar.letterhead', 'Letterhead')}</span>\n </label>\n )}\n\n {props.allowSigning && (\n <button type=\"button\" className=\"hv-btn hv-btn--primary\" onClick={props.onSign} disabled={props.signingDisabled}>\n {t('toolbar.sign', 'Sign Document')}\n </button>\n )}\n\n {props.canExportPdf && (\n <button type=\"button\" className=\"hv-btn\" onClick={props.onExportPdf}>\n {t('toolbar.exportPdf', 'Export as PDF')}\n </button>\n )}\n {props.canSave && (\n <button type=\"button\" className=\"hv-btn hv-btn--primary\" onClick={props.onSave}>\n {t('toolbar.save', 'Save')}\n </button>\n )}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport React from 'react';\n\nexport type Thumbnail = {\n id: string;\n label: string;\n dataUrl?: string;\n};\n\nexport function ThumbnailsSidebar(props: {\n locale: Record<string, string>;\n thumbnails: Thumbnail[];\n currentPage: number;\n collapsed: boolean;\n onToggle: () => void;\n onSelectPage: (p: number) => void;\n}) {\n const t = props.locale['thumbnails.title'] ?? 'Thumbnails';\n return (\n <aside className={props.collapsed ? 'hv-thumbs hv-thumbs--collapsed' : 'hv-thumbs'} aria-label={t}>\n <div className=\"hv-thumbs__header\">\n <button type=\"button\" className=\"hv-icon\" onClick={props.onToggle} aria-label={props.collapsed ? (props.locale['thumbnails.open'] ?? 'Open thumbnails') : (props.locale['thumbnails.close'] ?? 'Close thumbnails')}\n >{props.collapsed ? '▸' : '▾'}</button>\n {!props.collapsed ? <div className=\"hv-thumbs__title\">{t}</div> : null}\n </div>\n {!props.collapsed ? (\n <div className=\"hv-thumbs__list\" role=\"list\">\n {props.thumbnails.map((th, idx) => {\n const p = idx + 1;\n const active = p === props.currentPage;\n return (\n <button\n key={th.id}\n type=\"button\"\n role=\"listitem\"\n className={active ? 'hv-thumb hv-thumb--active' : 'hv-thumb'}\n onClick={() => props.onSelectPage(p)}\n aria-current={active ? 'page' : undefined}\n >\n <div className=\"hv-thumb__img\" aria-hidden>\n {th.dataUrl ? <img src={th.dataUrl} alt=\"\" /> : <div className=\"hv-thumb__placeholder\" />}\n </div>\n <div className=\"hv-thumb__label\">{th.label}</div>\n </button>\n );\n })}\n </div>\n ) : null}\n </aside>\n );\n}\n","'use client';\n\nimport React from 'react';\nimport type { Signature } from '../types';\n\nexport function SignaturePanel(props: {\n locale: Record<string, string>;\n signatures: Signature[];\n collapsed: boolean;\n onToggle: () => void;\n}) {\n const title = props.locale['signatures.title'] ?? 'Signatures';\n return (\n <aside className={props.collapsed ? 'hv-side hv-side--collapsed' : 'hv-side'} aria-label={title}>\n <div className=\"hv-sidebar-header\">\n <button type=\"button\" className=\"hv-icon\" onClick={props.onToggle} aria-label={props.locale['toolbar.signatures'] ?? 'Signatures'}>\n ✍\n </button>\n <div className=\"hv-sidebar-title\">{title}</div>\n </div>\n <div className=\"hv-sidebar-body\">\n {props.signatures.map((s, idx) => (\n <div key={`${s.signedBy}-${s.dateSigned}-${idx}`} className=\"hv-signature-card\">\n <img src={s.signatureImageUrl} alt={`Signature by ${s.signedBy}`} className=\"hv-signature-img\" />\n <div className=\"hv-signature-meta\">\n <div className=\"hv-signature-name\">{s.signedBy}</div>\n <div className=\"hv-signature-date\">{new Date(s.dateSigned).toLocaleString()}</div>\n {s.comment ? <div className=\"hv-signature-comment\">{s.comment}</div> : null}\n </div>\n </div>\n ))}\n </div>\n </aside>\n );\n}\n","'use client';\n\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { GlobalWorkerOptions, getDocument, type PDFDocumentProxy } from 'pdfjs-dist';\nimport type { PageLayout } from '../types';\n\nexport function PdfRenderer(props: {\n url?: string;\n arrayBuffer?: ArrayBuffer;\n layout: PageLayout;\n currentPage: number;\n onCurrentPageChange: (p: number) => void;\n onPageCount: (n: number) => void;\n onThumbs: (thumbs: (string | undefined)[]) => void;\n signatureStamp?: {\n imageUrl: string;\n armed: boolean;\n onPlaced: (placement: { page: number; x: number; y: number; w: number; h: number }) => void;\n };\n}) {\n const { url, arrayBuffer } = props;\n const [doc, setDoc] = useState<PDFDocumentProxy | null>(null);\n const [pageCount, setPageCount] = useState(0);\n const [rendered, setRendered] = useState<Map<number, HTMLCanvasElement>>(new Map());\n const [thumbs, setThumbs] = useState<(string | undefined)[]>([]);\n const [size, setSize] = useState({ w: 840, h: 1188 });\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n try {\n GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.min.mjs', import.meta.url).toString();\n } catch {}\n }, []);\n\n useEffect(() => {\n let cancel = false;\n (async () => {\n setDoc(null);\n setRendered(new Map());\n setThumbs([]);\n if (!url && !arrayBuffer) return;\n const task = getDocument(url ? { url, rangeChunkSize: 512 * 1024 } : { data: arrayBuffer! });\n const pdf = await task.promise;\n if (cancel) return;\n setDoc(pdf);\n setPageCount(pdf.numPages);\n props.onPageCount(pdf.numPages);\n setThumbs(Array.from({ length: pdf.numPages }));\n const p1 = await pdf.getPage(1);\n const base = p1.getViewport({ scale: 1 });\n const w = Math.min(980, Math.max(640, base.width));\n const s = w / base.width;\n const vp = p1.getViewport({ scale: s });\n setSize({ w: Math.round(vp.width), h: Math.round(vp.height) });\n })().catch(() => {\n // ignore; caller shows error\n });\n return () => { cancel = true; };\n }, [url, arrayBuffer]);\n\n useEffect(() => {\n props.onThumbs(thumbs);\n }, [thumbs]);\n\n const pagesToShow = useMemo(() => {\n if (props.layout === 'side-by-side') {\n const left = props.currentPage;\n const right = Math.min(pageCount || left + 1, left + 1);\n return [left, right];\n }\n return [props.currentPage];\n }, [props.currentPage, props.layout, pageCount]);\n\n useEffect(() => {\n if (!doc) return;\n let cancel = false;\n (async () => {\n for (const p of pagesToShow) {\n if (rendered.has(p)) continue;\n const page = await doc.getPage(p);\n if (cancel) return;\n const base = page.getViewport({ scale: 1 });\n const vp = page.getViewport({ scale: size.w / base.width });\n const canvas = document.createElement('canvas');\n canvas.width = Math.round(vp.width);\n canvas.height = Math.round(vp.height);\n const ctx = canvas.getContext('2d', { alpha: false });\n if (!ctx) continue;\n await page.render({ canvasContext: ctx, viewport: vp }).promise;\n if (cancel) return;\n setRendered(prev => {\n const next = new Map(prev);\n next.set(p, canvas);\n return next;\n });\n try {\n const tw = 140;\n const th = Math.round(tw * (canvas.height / canvas.width));\n const t = document.createElement('canvas');\n t.width = tw; t.height = th;\n const tctx = t.getContext('2d');\n if (tctx) {\n tctx.drawImage(canvas, 0, 0, tw, th);\n const url = t.toDataURL('image/jpeg', 0.75);\n setThumbs(prev => {\n const next = prev.slice();\n next[p - 1] = url;\n return next;\n });\n }\n } catch {}\n }\n })();\n return () => { cancel = true; };\n }, [doc, pagesToShow, size.w, rendered]);\n\n function onWheel(e: React.WheelEvent) {\n if (!pageCount) return;\n if (Math.abs(e.deltaY) < 10) return;\n const dir = e.deltaY > 0 ? 1 : -1;\n const step = props.layout === 'side-by-side' ? 2 : 1;\n const next = Math.max(1, Math.min(pageCount, props.currentPage + dir * step));\n props.onCurrentPageChange(next);\n }\n\n function clickPlace(e: React.MouseEvent, page: number) {\n const stamp = props.signatureStamp;\n if (!stamp?.armed) return;\n const rect = (e.currentTarget as HTMLDivElement).getBoundingClientRect();\n const x = (e.clientX - rect.left) / rect.width;\n const y = (e.clientY - rect.top) / rect.height;\n stamp.onPlaced({ page, x, y, w: 0.22, h: 0.08 });\n }\n\n return (\n <div className=\"hv-doc\" ref={containerRef} onWheel={onWheel}>\n {!doc ? <div className=\"hv-loading\">Loading PDF…</div> : null}\n {doc ? (\n <div className={props.layout === 'side-by-side' ? 'hv-pages hv-pages--two' : 'hv-pages'}>\n {pagesToShow.map(p => {\n const c = rendered.get(p);\n return (\n <div key={p} className=\"hv-page\" style={{ width: size.w, height: size.h }} onClick={(e) => clickPlace(e, p)}>\n {c ? (\n <canvas\n className=\"hv-canvas\"\n width={c.width}\n height={c.height}\n ref={(node) => {\n if (!node) return;\n const ctx = node.getContext('2d');\n if (ctx) ctx.drawImage(c, 0, 0);\n }}\n />\n ) : <div className=\"hv-loading\">Rendering…</div>}\n </div>\n );\n })}\n </div>\n ) : null}\n </div>\n );\n}\n","\"use client\";\n\nimport React, {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport mammoth from \"mammoth\";\n// Do not statically import html-to-docx; use dynamic import for browser compatibility\nimport MarkdownIt from \"markdown-it\";\nimport html2canvas from \"html2canvas\";\nimport { sanitizeHtml } from \"../utils/sanitize\";\nimport { arrayBufferToBase64 } from \"../utils/fileSource\";\nimport type { DocumentMode, Signature, SupportedFileType } from \"../types\";\n\nconst PAGE_H = 1122; // virtual A4\n\nexport type RichTextEditorHandle = {\n save: (exportPdf?: boolean) => Promise<void>;\n requestThumbnail: (index: number) => Promise<string | undefined>;\n};\n\nexport const RichTextEditor = forwardRef<\n RichTextEditorHandle,\n {\n mode: DocumentMode;\n fileType: \"docx\" | \"md\" | \"txt\";\n fileName: string;\n arrayBuffer?: ArrayBuffer;\n locale: Record<string, string>;\n headerComponent?: React.ReactNode;\n footerComponent?: React.ReactNode;\n headerFooterEnabled: boolean;\n signatures: Signature[];\n signaturePlacements: {\n page: number;\n x: number;\n y: number;\n w: number;\n h: number;\n signatureImageUrl: string;\n }[];\n armedSignatureUrl: string | null;\n onPlaceSignature: (p: {\n page: number;\n x: number;\n y: number;\n w: number;\n h: number;\n }) => void;\n onSave: (\n b64: string,\n meta: {\n fileName: string;\n fileType: SupportedFileType;\n exportedAsPdf?: boolean;\n annotations?: unknown;\n },\n ) => void;\n onPageCount: (n: number) => void;\n }\n>((props, ref) => {\n const readOnly = props.mode === \"view\";\n const md = useMemo(\n () => new MarkdownIt({ html: false, linkify: true, breaks: true }),\n [],\n );\n const scrollerRef = useRef<HTMLDivElement | null>(null);\n const editorRef = useRef<HTMLDivElement | null>(null);\n const captureRef = useRef<HTMLDivElement | null>(null);\n\n const [html, setHtml] = useState(\"<p><br/></p>\");\n\n useEffect(() => {\n let cancelled = false;\n (async () => {\n if (props.mode === \"create\") {\n setHtml(\"<p><br/></p>\");\n return;\n }\n if (!props.arrayBuffer) return;\n if (props.fileType === \"docx\") {\n const res = await mammoth.convertToHtml({\n arrayBuffer: props.arrayBuffer,\n });\n if (!cancelled) setHtml(sanitizeHtml(res.value || \"<p><br/></p>\"));\n } else {\n const text = new TextDecoder().decode(props.arrayBuffer);\n if (props.fileType === \"md\") setHtml(sanitizeHtml(md.render(text)));\n else setHtml(`<pre>${escapeHtml(text)}</pre>`);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [props.arrayBuffer, props.fileType, props.mode, md]);\n\n useEffect(() => {\n const el = scrollerRef.current;\n if (!el) return;\n const recompute = () =>\n props.onPageCount(Math.max(1, Math.ceil(el.scrollHeight / PAGE_H)));\n recompute();\n const ro = new ResizeObserver(recompute);\n ro.observe(el);\n return () => ro.disconnect();\n }, [html, props.headerFooterEnabled]);\n\n function exec(cmd: string) {\n if (readOnly) return;\n document.execCommand(cmd);\n }\n\n function onClick(e: React.MouseEvent<HTMLDivElement>) {\n if (!props.armedSignatureUrl) return;\n const scroller = scrollerRef.current;\n if (!scroller) return;\n const rect = (e.currentTarget as HTMLDivElement).getBoundingClientRect();\n const absY = scroller.scrollTop + (e.clientY - rect.top);\n const page = Math.max(1, Math.floor(absY / PAGE_H) + 1);\n const pageTop = (page - 1) * PAGE_H;\n const x = (e.clientX - rect.left) / rect.width;\n const y = (absY - pageTop) / PAGE_H;\n props.onPlaceSignature({ page, x, y, w: 0.25, h: 0.1 });\n }\n\n async function requestThumbnail(index: number): Promise<string | undefined> {\n const scroller = scrollerRef.current;\n const capture = captureRef.current;\n if (!scroller || !capture) return undefined;\n const old = scroller.scrollTop;\n scroller.scrollTop = index * PAGE_H;\n await new Promise((r) => requestAnimationFrame(() => r(null)));\n try {\n const canvas = await html2canvas(capture, {\n backgroundColor: null,\n scale: 0.25,\n useCORS: true,\n });\n return canvas.toDataURL(\"image/png\");\n } catch {\n return undefined;\n } finally {\n scroller.scrollTop = old;\n }\n }\n\n async function save(exportPdf?: boolean) {\n const inner = editorRef.current?.innerHTML ?? html;\n const stitched = `<!doctype html><html><head><meta charset=\"utf-8\" /></head><body>${inner}</body></html>`;\n\n if (exportPdf) {\n // client-side: return print-ready HTML as base64\n const b64 = btoa(unescape(encodeURIComponent(stitched)));\n props.onSave(b64, {\n fileName: replaceExt(props.fileName, \"html\"),\n fileType: \"txt\",\n exportedAsPdf: true,\n annotations: { signaturePlacements: props.signaturePlacements },\n });\n return;\n }\n\n if (props.fileType === \"docx\") {\n // Only attempt to import html-to-docx at runtime\n try {\n // @ts-ignore\n const htmlToDocx = (await import(\"html-to-docx\")).default;\n const blob = await htmlToDocx(stitched);\n const ab = await blob.arrayBuffer();\n props.onSave(arrayBufferToBase64(ab), {\n fileName: replaceExt(props.fileName, \"docx\"),\n fileType: \"docx\",\n annotations: { signaturePlacements: props.signaturePlacements },\n });\n } catch (err) {\n // Show a user-friendly error if running in the browser or import fails\n alert(\n \"DOCX export is not supported in this environment. Please use this feature in a Node.js/server context.\",\n );\n }\n return;\n }\n\n const text = editorRef.current?.innerText ?? \"\";\n const b64 = btoa(unescape(encodeURIComponent(text)));\n props.onSave(b64, {\n fileName: replaceExt(props.fileName, props.fileType),\n fileType: props.fileType,\n annotations: { signaturePlacements: props.signaturePlacements },\n });\n }\n\n useImperativeHandle(ref, () => ({ save, requestThumbnail }));\n\n return (\n <div className=\"hv-doc\">\n <div className=\"hv-ribbon\" role=\"toolbar\">\n <button\n className=\"hv-btn\"\n onClick={() => exec(\"bold\")}\n disabled={readOnly}\n >\n B\n </button>\n <button\n className=\"hv-btn\"\n onClick={() => exec(\"italic\")}\n disabled={readOnly}\n >\n I\n </button>\n <button\n className=\"hv-btn\"\n onClick={() => exec(\"underline\")}\n disabled={readOnly}\n >\n U\n </button>\n {props.armedSignatureUrl ? (\n <div className=\"hv-hint\">Click to place signature</div>\n ) : null}\n </div>\n\n <div className=\"hv-scroll\" ref={scrollerRef} onClick={onClick}>\n <div className=\"hv-pageStage\" ref={captureRef}>\n {props.headerFooterEnabled && props.headerComponent ? (\n <div className=\"hv-letterhead\">{props.headerComponent}</div>\n ) : null}\n\n <div\n ref={editorRef}\n className={readOnly ? \"hv-editor hv-editor--ro\" : \"hv-editor\"}\n contentEditable={!readOnly}\n suppressContentEditableWarning\n onInput={() => setHtml(editorRef.current?.innerHTML ?? \"\")}\n dangerouslySetInnerHTML={{ __html: html }}\n />\n\n {props.headerFooterEnabled && props.footerComponent ? (\n <div className=\"hv-letterhead hv-letterhead--footer\">\n {props.footerComponent}\n </div>\n ) : null}\n\n {props.mode === \"create\" && props.signatures.length ? (\n <div className=\"hv-signatures-inline\">\n {props.signatures.map((s, i) => (\n <div key={i} className=\"hv-sign-inline\">\n <img\n src={s.signatureImageUrl}\n alt=\"\"\n className=\"hv-sign-img\"\n />\n <div>\n <div className=\"hv-sign-name\">{s.signedBy}</div>\n <div className=\"hv-sign-date\">\n {new Date(s.dateSigned).toLocaleString()}\n </div>\n </div>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n </div>\n </div>\n );\n});\n\nfunction replaceExt(name: string, ext: string) {\n const base = name.includes(\".\") ? name.slice(0, name.lastIndexOf(\".\")) : name;\n return `${base}.${ext}`;\n}\n\nfunction escapeHtml(s: string) {\n return s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n","import DOMPurify from 'dompurify';\n\nexport function sanitizeHtml(html: string): string {\n // DOMPurify is safe to call in the browser. For SSR, callers should only run after mount.\n return DOMPurify.sanitize(html, {\n USE_PROFILES: { html: true },\n ADD_ATTR: ['target', 'rel']\n });\n}\n","'use client';\n\nimport React, { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from 'react';\nimport * as XLSX from 'xlsx';\nimport { arrayBufferToBase64 } from '../utils/fileSource';\nimport type { DocumentMode, SupportedFileType } from '../types';\n\nexport type SpreadsheetEditorHandle = {\n save: (exportPdf?: boolean) => Promise<void>;\n requestThumbnails: (index: number) => Promise<void>;\n};\n\nexport const SpreadsheetEditor = forwardRef<SpreadsheetEditorHandle, {\n mode: DocumentMode;\n fileName: string;\n arrayBuffer?: ArrayBuffer;\n locale: Record<string, string>;\n onSave: (base64: string, meta: { fileName: string; fileType: SupportedFileType; exportedAsPdf?: boolean }) => void;\n}>(function SpreadsheetEditor(props, ref) {\n const readonly = props.mode === 'view';\n const [grid, setGrid] = useState<string[][]>(() => Array.from({ length: 30 }, () => Array.from({ length: 12 }, () => '')));\n\n useEffect(() => {\n if (!props.arrayBuffer) return;\n try {\n const wb = XLSX.read(props.arrayBuffer, { type: 'array' });\n const name = wb.SheetNames[0];\n const ws = wb.Sheets[name];\n const aoa = XLSX.utils.sheet_to_json(ws, { header: 1, raw: true }) as any[][];\n const rows = Math.max(30, aoa.length);\n const cols = Math.max(12, Math.max(...aoa.map(r => (r?.length ?? 0)), 0));\n const next = Array.from({ length: rows }, (_, r) => Array.from({ length: cols }, (_, c) => {\n const v = aoa[r]?.[c];\n return v == null ? '' : String(v);\n }));\n setGrid(next);\n } catch {\n // ignore\n }\n }, [props.arrayBuffer]);\n\n async function save(exportPdf?: boolean) {\n const ws = XLSX.utils.aoa_to_sheet(grid);\n const wb = XLSX.utils.book_new();\n XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');\n const out = XLSX.write(wb, { type: 'array', bookType: 'xlsx' }) as ArrayBuffer;\n const b64 = arrayBufferToBase64(out);\n props.onSave(b64, { fileName: ensureExt(props.fileName, 'xlsx'), fileType: 'xlsx', exportedAsPdf: !!exportPdf });\n }\n\n useImperativeHandle(ref, () => ({\n save,\n requestThumbnails: async () => undefined\n }));\n\n const cols = useMemo(() => Array.from({ length: grid[0]?.length ?? 0 }, (_, i) => String.fromCharCode(65 + (i % 26))), [grid]);\n\n return (\n <div className=\"hv-sheet\">\n <div className=\"hv-sheetbar\">\n <div className=\"hv-sheetbar-title\">{props.fileName}</div>\n {!readonly ? <button className=\"hv-btn\" type=\"button\" onClick={() => void save(false)}>{props.locale['toolbar.save'] ?? 'Save'}</button> : null}\n </div>\n <div className=\"hv-sheetgrid\" role=\"table\" aria-label=\"Spreadsheet\">\n <div className=\"hv-sheetrow hv-sheetrow--header\" role=\"row\">\n <div className=\"hv-sheetcell hv-sheetcell--corner\" role=\"columnheader\" />\n {cols.map((c, i) => <div key={i} className=\"hv-sheetcell hv-sheetcell--header\" role=\"columnheader\">{c}</div>)}\n </div>\n {grid.map((row, r) => (\n <div key={r} className=\"hv-sheetrow\" role=\"row\">\n <div className=\"hv-sheetcell hv-sheetcell--header\" role=\"rowheader\">{r + 1}</div>\n {row.map((val, c) => (\n <div\n key={c}\n className=\"hv-sheetcell\"\n role=\"cell\"\n contentEditable={!readonly}\n suppressContentEditableWarning\n onInput={(e) => {\n const text = (e.currentTarget.textContent ?? '');\n setGrid((prev) => {\n const next = prev.map(rr => rr.slice());\n next[r][c] = text;\n return next;\n });\n }}\n >{val}</div>\n ))}\n </div>\n ))}\n </div>\n </div>\n );\n});\n\nfunction ensureExt(name: string, ext: string) {\n const base = name.includes('.') ? name.slice(0, name.lastIndexOf('.')) : name;\n return `${base}.${ext}`;\n}\n","'use client';\n\nimport React, { useEffect, useMemo, useState } from 'react';\nimport type { SupportedFileType } from '../types';\n\nexport function ImageRenderer({ arrayBuffer, fileType, fileName }: { arrayBuffer?: ArrayBuffer; fileType: SupportedFileType; fileName: string }) {\n const [zoom, setZoom] = useState(1);\n const url = useMemo(() => {\n if (!arrayBuffer) return undefined;\n const mime = fileType === 'svg' ? 'image/svg+xml' : fileType === 'png' ? 'image/png' : 'image/jpeg';\n return URL.createObjectURL(new Blob([arrayBuffer], { type: mime }));\n }, [arrayBuffer, fileType]);\n\n useEffect(() => {\n return () => { if (url) URL.revokeObjectURL(url); };\n }, [url]);\n\n return (\n <div className=\"hv-doc\">\n <div className=\"hv-mini-toolbar\">\n <div className=\"hv-title\">{fileName}</div>\n <div className=\"hv-spacer\" />\n <button type=\"button\" className=\"hv-btn\" onClick={() => setZoom((z) => Math.max(0.25, z - 0.25))}>-</button>\n <div className=\"hv-zoom\">{Math.round(zoom * 100)}%</div>\n <button type=\"button\" className=\"hv-btn\" onClick={() => setZoom((z) => Math.min(4, z + 0.25))}>+</button>\n </div>\n <div className=\"hv-center\">\n {url ? <img src={url} alt={fileName} style={{ transform: `scale(${zoom})` }} className=\"hv-image\" /> : <div className=\"hv-loading\">Loading…</div>}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport React, { useEffect, useMemo, useState } from 'react';\nimport JSZip from 'jszip';\nimport type { PageLayout } from '../types';\n\ntype Slide = { index: number; text: string };\n\nfunction decodeXml(s: string): string {\n return s\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\");\n}\n\nfunction extractText(xml: string) {\n return [...xml.matchAll(/<a:t>(.*?)<\\/a:t>/g)].map(m => decodeXml(m[1] || '')).join(' ').trim();\n}\n\nexport function PptxRenderer(props: {\n arrayBuffer?: ArrayBuffer;\n layout: PageLayout;\n currentPage: number;\n onCurrentPageChange: (p: number) => void;\n onSlideCount: (n: number) => void;\n onThumbs: (thumbs: (string|undefined)[]) => void;\n}) {\n const [slides, setSlides] = useState<Slide[]>([]);\n const [thumbs, setThumbs] = useState<(string | undefined)[]>([]);\n\n useEffect(() => {\n let cancelled = false;\n (async () => {\n setSlides([]); setThumbs([]);\n if (!props.arrayBuffer) { props.onSlideCount(1); setSlides([{index:1,text:'No content'}]); return; }\n const zip = await JSZip.loadAsync(props.arrayBuffer);\n const files = Object.keys(zip.files).filter(p => /^ppt\\/slides\\/slide\\d+\\.xml$/.test(p)).sort((a,b)=>{\n const na = Number(a.match(/slide(\\d+)\\.xml/)?.[1]||0);\n const nb = Number(b.match(/slide(\\d+)\\.xml/)?.[1]||0);\n return na-nb;\n });\n const out: Slide[] = [];\n for (let i=0;i<files.length;i++) {\n const xml = await zip.file(files[i])!.async('string');\n out.push({ index:i+1, text: extractText(xml) });\n }\n if (cancelled) return;\n const count = Math.max(1,out.length);\n props.onSlideCount(count);\n setSlides(out.length?out:[{index:1,text:'(empty)'}]);\n setThumbs(Array.from({length:count}, (_,i)=>`data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgThumb(i+1))}`));\n })().catch(()=>{\n props.onSlideCount(1);\n setSlides([{index:1,text:'Unable to render this .pptx in-browser.'}]);\n setThumbs([undefined]);\n });\n return ()=>{cancelled=true;};\n }, [props.arrayBuffer]);\n\n useEffect(()=>{ props.onThumbs(thumbs); }, [thumbs]);\n\n const pagesToShow = useMemo(()=>{\n if (props.layout==='side-by-side') return [props.currentPage, Math.min(slides.length||props.currentPage+1, props.currentPage+1)];\n return [props.currentPage];\n }, [props.currentPage, props.layout, slides.length]);\n\n return (\n <div className=\"hv-doc\">\n <div className={props.layout==='side-by-side' ? 'hv-pages hv-pages--two' : 'hv-pages'}>\n {pagesToShow.map(p=>{\n const s = slides[p-1];\n return (\n <div key={p} className=\"hv-slide\" tabIndex={0} onFocus={()=>props.onCurrentPageChange(p)}>\n <div className=\"hv-slide-title\">Slide {p}</div>\n <div className=\"hv-slide-text\">{s?.text || ''}</div>\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nfunction svgThumb(n: number) {\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"180\" height=\"100\"><rect width=\"100%\" height=\"100%\" rx=\"12\" fill=\"#111827\"/><text x=\"50%\" y=\"54%\" font-size=\"18\" fill=\"#e5e7eb\" text-anchor=\"middle\">${n}</text></svg>`;\n}\n"],"mappings":"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","names":["useEffect","useMemo","useRef","useState","jsx","jsxs","jsx","jsxs","jsx","jsxs","url","useEffect","useMemo","useRef","useState","jsx","jsxs","useMemo","useRef","useState","useEffect","b64","forwardRef","useEffect","useImperativeHandle","useMemo","useState","jsx","jsxs","forwardRef","SpreadsheetEditor","useState","useEffect","cols","_","useImperativeHandle","useMemo","useEffect","useMemo","useState","jsx","jsxs","useEffect","useMemo","useState","jsx","jsxs","jsx","jsxs","useMemo","useState","useEffect","useRef","arrayBufferToBase64"]}