@embedpdf/viewer-chrome 3.0.0-next.13 → 3.0.0-next.15
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 +175 -132
- package/dist/annotation-fonts-BqoLZ4Mp.js +80 -0
- package/dist/annotation-fonts-BqoLZ4Mp.js.map +1 -0
- package/dist/annotation-fonts-Dt0IQXhz.cjs +91 -0
- package/dist/annotation-fonts-Dt0IQXhz.cjs.map +1 -0
- package/dist/annotation-style--rPIZsuP.js +879 -0
- package/dist/annotation-style--rPIZsuP.js.map +1 -0
- package/dist/annotation-style-Bzvvp8-N.cjs +879 -0
- package/dist/annotation-style-Bzvvp8-N.cjs.map +1 -0
- package/dist/ar-D9XKAmDx.js +567 -0
- package/dist/ar-D9XKAmDx.js.map +1 -0
- package/dist/ar-DnEj5vbP.cjs +567 -0
- package/dist/ar-DnEj5vbP.cjs.map +1 -0
- package/dist/chrome.cjs +378 -221
- package/dist/chrome.cjs.map +1 -1
- package/dist/chrome.d.cts +5 -34
- package/dist/chrome.d.ts +5 -34
- package/dist/chrome.js +377 -218
- package/dist/chrome.js.map +1 -1
- package/dist/commands-BmgxhJ8B.js +953 -0
- package/dist/commands-BmgxhJ8B.js.map +1 -0
- package/dist/commands-CYt4SFUX.cjs +1060 -0
- package/dist/commands-CYt4SFUX.cjs.map +1 -0
- package/dist/commands.cjs +12 -595
- package/dist/commands.d.cts +29 -4
- package/dist/commands.d.ts +29 -4
- package/dist/commands.js +2 -593
- package/dist/comments-panel-MUVgLCBI.js +514 -0
- package/dist/comments-panel-MUVgLCBI.js.map +1 -0
- package/dist/comments-panel-pEcQg4Vs.cjs +514 -0
- package/dist/comments-panel-pEcQg4Vs.cjs.map +1 -0
- package/dist/de-Bdr4aWzm.js +566 -0
- package/dist/de-Bdr4aWzm.js.map +1 -0
- package/dist/de-Dv6zvbnd.cjs +566 -0
- package/dist/de-Dv6zvbnd.cjs.map +1 -0
- package/dist/dialog-B5GBisKv.js +55 -0
- package/dist/dialog-B5GBisKv.js.map +1 -0
- package/dist/dialog-t8F13BL_.cjs +60 -0
- package/dist/dialog-t8F13BL_.cjs.map +1 -0
- package/dist/es-BP09DR9w.cjs +566 -0
- package/dist/es-BP09DR9w.cjs.map +1 -0
- package/dist/es-BSXz5tBv.js +566 -0
- package/dist/es-BSXz5tBv.js.map +1 -0
- package/dist/form-design-panel-B5MXTZ96.cjs +418 -0
- package/dist/form-design-panel-B5MXTZ96.cjs.map +1 -0
- package/dist/form-design-panel-vWWU9uB-.js +418 -0
- package/dist/form-design-panel-vWWU9uB-.js.map +1 -0
- package/dist/fr-BBQQn7tJ.cjs +566 -0
- package/dist/fr-BBQQn7tJ.cjs.map +1 -0
- package/dist/fr-Ckn3K9v1.js +566 -0
- package/dist/fr-Ckn3K9v1.js.map +1 -0
- package/dist/he-DRsG7bH7.cjs +567 -0
- package/dist/he-DRsG7bH7.cjs.map +1 -0
- package/dist/he-wdGU5PkU.js +567 -0
- package/dist/he-wdGU5PkU.js.map +1 -0
- package/dist/icons-BrK5iVL8.js +856 -0
- package/dist/icons-BrK5iVL8.js.map +1 -0
- package/dist/icons-x0Tc05bs.cjs +1010 -0
- package/dist/icons-x0Tc05bs.cjs.map +1 -0
- package/dist/index.cjs +3162 -5106
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +636 -143
- package/dist/index.d.ts +636 -143
- package/dist/index.js +3083 -4975
- package/dist/index.js.map +1 -1
- package/dist/it-BuP4o0xQ.cjs +566 -0
- package/dist/it-BuP4o0xQ.cjs.map +1 -0
- package/dist/it-Us-VmvIu.js +566 -0
- package/dist/it-Us-VmvIu.js.map +1 -0
- package/dist/ja-Cizj0-5O.js +566 -0
- package/dist/ja-Cizj0-5O.js.map +1 -0
- package/dist/ja-DovEd6ts.cjs +566 -0
- package/dist/ja-DovEd6ts.cjs.map +1 -0
- package/dist/ko-B-qJEol2.cjs +566 -0
- package/dist/ko-B-qJEol2.cjs.map +1 -0
- package/dist/ko-DlrXliE1.js +566 -0
- package/dist/ko-DlrXliE1.js.map +1 -0
- package/dist/labels-BiM9wp9K.cjs +21 -0
- package/dist/labels-BiM9wp9K.cjs.map +1 -0
- package/dist/labels-C6_i87Oj.js +16 -0
- package/dist/labels-C6_i87Oj.js.map +1 -0
- package/dist/link-editor-CSjqPnj1.cjs +125 -0
- package/dist/link-editor-CSjqPnj1.cjs.map +1 -0
- package/dist/link-editor-SxM1nnJU.js +125 -0
- package/dist/link-editor-SxM1nnJU.js.map +1 -0
- package/dist/measurement-Bs61XWbJ.js +325 -0
- package/dist/measurement-Bs61XWbJ.js.map +1 -0
- package/dist/measurement-CcCsHPOX.cjs +326 -0
- package/dist/measurement-CcCsHPOX.cjs.map +1 -0
- package/dist/nl-0aF7M_0h.js +566 -0
- package/dist/nl-0aF7M_0h.js.map +1 -0
- package/dist/nl-D3KZDDiJ.cjs +566 -0
- package/dist/nl-D3KZDDiJ.cjs.map +1 -0
- package/dist/pl-BW--AaCI.js +566 -0
- package/dist/pl-BW--AaCI.js.map +1 -0
- package/dist/pl-DSFhAUqx.cjs +566 -0
- package/dist/pl-DSFhAUqx.cjs.map +1 -0
- package/dist/pt-C5S-8MC5.cjs +566 -0
- package/dist/pt-C5S-8MC5.cjs.map +1 -0
- package/dist/pt-DIhpU5pT.js +566 -0
- package/dist/pt-DIhpU5pT.js.map +1 -0
- package/dist/redact-confirm-B6j36TPw.js +83 -0
- package/dist/redact-confirm-B6j36TPw.js.map +1 -0
- package/dist/redact-confirm-CX_SY2ZN.cjs +83 -0
- package/dist/redact-confirm-CX_SY2ZN.cjs.map +1 -0
- package/dist/redaction-panel-BmoIl-Ll.cjs +96 -0
- package/dist/redaction-panel-BmoIl-Ll.cjs.map +1 -0
- package/dist/redaction-panel-IJDshSJI.js +96 -0
- package/dist/redaction-panel-IJDshSJI.js.map +1 -0
- package/dist/search-panel-HfIhJm1M.js +249 -0
- package/dist/search-panel-HfIhJm1M.js.map +1 -0
- package/dist/search-panel-s9IoiOtv.cjs +249 -0
- package/dist/search-panel-s9IoiOtv.cjs.map +1 -0
- package/dist/sheet-BDsa_Sup.cjs +442 -0
- package/dist/sheet-BDsa_Sup.cjs.map +1 -0
- package/dist/sheet-R6XDgyEf.js +365 -0
- package/dist/sheet-R6XDgyEf.js.map +1 -0
- package/dist/sign-dialog-CgnR7akj.cjs +155 -0
- package/dist/sign-dialog-CgnR7akj.cjs.map +1 -0
- package/dist/sign-dialog-GDqCoQhA.js +155 -0
- package/dist/sign-dialog-GDqCoQhA.js.map +1 -0
- package/dist/signature-inspector-DyO313Qf.cjs +166 -0
- package/dist/signature-inspector-DyO313Qf.cjs.map +1 -0
- package/dist/signature-inspector-okFz8do6.js +166 -0
- package/dist/signature-inspector-okFz8do6.js.map +1 -0
- package/dist/signature-maker-BhCmYyHD.js +393 -0
- package/dist/signature-maker-BhCmYyHD.js.map +1 -0
- package/dist/signature-maker-BoYa8vgA.cjs +393 -0
- package/dist/signature-maker-BoYa8vgA.cjs.map +1 -0
- package/dist/signatures-panel-B56PC6d9.cjs +300 -0
- package/dist/signatures-panel-B56PC6d9.cjs.map +1 -0
- package/dist/signatures-panel-CgnFfhFm.js +300 -0
- package/dist/signatures-panel-CgnFfhFm.js.map +1 -0
- package/dist/stamp-store-BHvRs-Do.cjs +147 -0
- package/dist/stamp-store-BHvRs-Do.cjs.map +1 -0
- package/dist/stamp-store-WuF-L3Jj.js +112 -0
- package/dist/stamp-store-WuF-L3Jj.js.map +1 -0
- package/dist/stamps-panel-B9NYGayn.cjs +231 -0
- package/dist/stamps-panel-B9NYGayn.cjs.map +1 -0
- package/dist/stamps-panel-CDO0FPyK.js +231 -0
- package/dist/stamps-panel-CDO0FPyK.js.map +1 -0
- package/dist/toolbar-CJu2wKTU.cjs +1659 -0
- package/dist/toolbar-CJu2wKTU.cjs.map +1 -0
- package/dist/toolbar-z9od3tKl.js +1564 -0
- package/dist/toolbar-z9od3tKl.js.map +1 -0
- package/dist/zh-cn-3tmMeHqv.cjs +566 -0
- package/dist/zh-cn-3tmMeHqv.cjs.map +1 -0
- package/dist/zh-cn-CxkUUBct.js +566 -0
- package/dist/zh-cn-CxkUUBct.js.map +1 -0
- package/package.json +6 -4
- package/src/styles.css +153 -89
- package/dist/commands.cjs.map +0 -1
- package/dist/commands.js.map +0 -1
- package/dist/es-DYwzfxyt.cjs +0 -293
- package/dist/es-DYwzfxyt.cjs.map +0 -1
- package/dist/es-sN6uqBgD.js +0 -293
- package/dist/es-sN6uqBgD.js.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["InteractionToken","CommandsToken","InteractionToken","StampToken","StageToken","RedactionToken","AnnotationToken","StageToken","AnnotationToken","SearchToken","StageToken","FormToken","ShellToken","chromeHelpers","validateChrome"],"sources":["../src/config/stage.ts","../src/config/demo-tools.plugin.ts","../src/locales/en.ts","../src/config-context.tsx","../src/handle.ts","../src/ui/icons.tsx","../src/ui/theme.tsx","../src/config/default-stamps.ts","../src/ui/stamp-store.tsx","../src/ui/quick-stamps.tsx","../src/ui/menu.tsx","../src/ui/toolbar.tsx","../src/ui/annotation-fonts.tsx","../src/ui/link-editor.tsx","../src/ui/strip-bar.tsx","../src/ui/annotation-strip.tsx","../src/ui/selection-strip.tsx","../src/ui/tab-bar.tsx","../src/ui/tool-cursor.tsx","../src/ui/annotation-flags.tsx","../src/ui/annotation-style.tsx","../src/ui/comment-config.ts","../src/ui/comments-panel.tsx","../src/ui/redaction-panel.tsx","../src/ui/search-panel.tsx","../src/ui/stamps-panel.tsx","../src/ui/signatures-panel.tsx","../src/ui/panels.tsx","../src/ui/redact-confirm.tsx","../src/ui/sign-dialog.tsx","../src/ui/signature-bridge.tsx","../src/ui/signature-inspector.tsx","../src/ui/signature-maker.tsx","../src/ui/document-boot.tsx","../src/Shell.tsx","../src/viewer.tsx"],"sourcesContent":["/**\n * The Stage is a LENS: one document can be viewed through several at once. The\n * thumbnail sidebar is a second lens over the SAME document — a single-column,\n * fixed-zoom grid with its own camera, fully independent of the main view.\n *\n * The token lives here (not in App.tsx) because two places need it: App wires the\n * `stagePlugin` lens with it, and the sidebar renders `<Stage token={...}>` off it.\n */\nimport { createCapabilityToken } from '@embedpdf/react/runtime';\nimport type { StageCapability } from '@embedpdf/react/stage';\n\nexport const ThumbsStageToken = createCapabilityToken<StageCapability>('stage-thumbs');\n","import { definePlugin } from '@embedpdf/react/runtime';\nimport { InteractionToken } from '@embedpdf/react/interaction';\n\n/**\n * Example-only: register the still-unimplemented authoring tools as INERT\n * interaction tools. v3 doesn't yet ship a signature plugin, but this is a\n * CHROME demo — its job is selection state and layout, not the tool's effect.\n * Registering them as real (behaviourless) tools lets every tool button in\n * every mode band go through the SAME path (`InteractionToken.activateTool`),\n * so `active` is uniform and honest: the button really is the active tool; it\n * just has no handler behind it.\n *\n * Everything else in the Insert band is REAL now: stamps come from the stamp\n * plugin's libraries (armed by the stamps sidebar), and image/attachment are\n * the annotation plugin's click-then-pick tools. The annotate + shapes tools\n * were never here either — nor the form palette (the form plugin's\n * draw-to-place).\n */\nconst INERT_TOOLS: ReadonlyArray<{ id: string; cursor: string }> = [\n // insert mode (redact is REAL now — plugin-annotation ships the composed\n // tool and plugin-redaction the destructive apply; `image` is a real\n // click-then-pick stamp preset, see viewer.tsx)\n { id: 'signature', cursor: 'copy' },\n];\n\nexport const demoToolsPlugin = () =>\n definePlugin({\n id: 'demo-tools',\n scope: 'document',\n requires: [InteractionToken],\n init: (ctx) => {\n const interaction = ctx.get(InteractionToken);\n for (const tool of INERT_TOOLS) {\n // No `enables` → no gesture/handler wakes up: the tool is selectable\n // (cursor + active state) but behaviourless. Exactly what a chrome demo\n // needs from the signature tool v3 doesn't ship yet.\n interaction.registerTool({ id: tool.id, cursor: tool.cursor, enables: new Set<string>() });\n }\n },\n });\n","import type { Locale } from '@embedpdf/react/i18n';\n\n/**\n * English pack. Strings belong to the PRODUCT, not the plugins — the\n * `commands.*` namespace mirrors the v2 snippet packs so translations carry\n * over; `demo.*` is this example's own chrome.\n */\nexport const en: Locale = {\n code: 'en',\n name: 'English',\n translations: {\n commands: {\n zoom: {\n in: 'Zoom In',\n out: 'Zoom Out',\n fitPage: 'Fit to Page',\n fitWidth: 'Fit to Width',\n automatic: 'Automatic',\n menu: 'Zoom',\n level: 'Zoom Level',\n p50: '50%',\n p100: '100%',\n p150: '150%',\n p200: '200%',\n p400: '400%',\n },\n pan: 'Pan',\n pointer: 'Pointer',\n sidebar: 'Sidebar',\n search: 'Search',\n comment: 'Comment',\n style: 'Style',\n menu: 'Menu',\n viewControls: 'View Controls',\n download: 'Download',\n print: 'Print',\n fullscreen: 'Full Screen',\n spread: { group: 'Page Layout', none: 'Single Page', odd: 'Two Page', even: 'Cover Page' },\n scroll: { group: 'Scrolling', vertical: 'Vertical', horizontal: 'Horizontal' },\n rotate: {\n group: 'Rotate',\n clockwise: 'Rotate Clockwise',\n counterclockwise: 'Rotate Counter-Clockwise',\n },\n mode: {\n group: 'Mode',\n view: 'View',\n annotate: 'Annotate',\n shapes: 'Shapes',\n insert: 'Insert',\n form: 'Form',\n redact: 'Redact',\n },\n annotate: {\n highlight: 'Highlight',\n strikeout: 'Strikeout',\n underline: 'Underline',\n squiggly: 'Squiggly',\n ink: 'Draw',\n inkHighlight: 'Ink Highlighter',\n text: 'Text',\n insertText: 'Insert Text',\n replaceText: 'Replace Text',\n callout: 'Callout',\n note: 'Comment',\n link: 'Link',\n gotoLink: 'Go to link',\n removeLink: 'Remove link',\n delete: 'Delete',\n group: 'Group',\n ungroup: 'Ungroup',\n stampFromSelection: 'Make stamp',\n strip: 'Annotation actions',\n },\n selection: {\n copy: 'Copy',\n strip: 'Text selection actions',\n },\n shapes: {\n rectangle: 'Rectangle',\n circle: 'Circle',\n line: 'Line',\n arrow: 'Arrow',\n polygon: 'Polygon',\n polyline: 'Polyline',\n },\n insert: {\n stamp: 'Rubber Stamp',\n attachment: 'Attach File',\n signature: 'Signature',\n image: 'Image',\n },\n form: {\n textfield: 'Text Field',\n checkbox: 'Checkbox',\n radio: 'Radio Button',\n select: 'Dropdown',\n listbox: 'List Box',\n signature: 'Signature Field',\n },\n redact: {\n mark: 'Mark for Redaction',\n applyAll: 'Apply Redactions',\n clearAll: 'Clear Marks',\n panel: 'Redactions',\n },\n undo: 'Undo',\n redo: 'Redo',\n },\n passwordPrompt: {\n title: 'Password required',\n required: 'This document is password protected. Enter the password to open it.',\n incorrect: 'The password was incorrect. Please try again.',\n incorrectWarning: 'Incorrect password',\n label: 'Password',\n placeholder: 'Enter password',\n cancel: 'Cancel',\n open: 'Open',\n opening: 'Opening…',\n },\n documentError: {\n title: 'Couldn’t open document',\n unknown: 'The document could not be opened.',\n close: 'Close document',\n },\n // Annotation type names — the comment sidebar's icon tooltips. Keys carry\n // over from the v2 packs so existing translations still resolve.\n annotation: {\n comment: 'Comment',\n highlight: 'Highlight',\n underline: 'Underline',\n squiggly: 'Squiggly',\n strikeout: 'Strikethrough',\n square: 'Square',\n circle: 'Circle',\n line: 'Line',\n polygon: 'Polygon',\n polyline: 'Polyline',\n ink: 'Ink',\n freeText: 'Text',\n stamp: 'Stamp',\n caret: 'Caret',\n redact: 'Redact',\n fileAttachment: 'Attachment',\n },\n demo: {\n starting: 'Starting viewer…',\n opening: 'Opening document…',\n more: 'More',\n thumbnails: 'Thumbnails',\n outline: 'Outline',\n searchPlaceholder: 'Search document…',\n searchTitle: 'Search',\n searchCaseSensitive: 'Case sensitive',\n searchWholeWord: 'Whole word',\n searchRegex: 'Regular expression',\n searchSearching: 'Searching…',\n searchResults: '{count} results found',\n searchNoResults: 'No results',\n searchPage: 'Page {page}',\n commentsTitle: 'Comments',\n commentsForbidden: 'You don\\u2019t have access to comments on this document.',\n commentsLoading: 'Loading comments…',\n commentsError: 'Comments failed to load.',\n commentsRetry: 'Retry',\n commentsEmpty: 'No comments yet. Use the note tool to start a thread.',\n commentsAnonymous: 'Unknown',\n commentsPage: 'Page {page}',\n commentCount: '{count} comment',\n commentCountPlural: '{count} comments',\n commentsReply: 'Reply',\n commentsReplyPlaceholder: 'Reply…',\n commentsAddPlaceholder: 'Add a comment…',\n commentsDelete: 'Delete comment',\n commentsDeleteThread: 'Delete thread',\n commentsEdit: 'Edit comment',\n commentsStatus: 'Status',\n commentsStatusNone: 'No status',\n commentsStatusAccepted: 'Accepted',\n commentsStatusRejected: 'Rejected',\n commentsStatusCancelled: 'Cancelled',\n commentsStatusCompleted: 'Completed',\n styleTitle: 'Style',\n empty: 'Nothing here yet in this demo panel.',\n page: 'Page {current} of {total}',\n cancel: 'Cancel',\n pageBadge: 'p. {page}',\n redactionTitle: 'Redactions',\n redactionEmpty: 'No pending redactions. Use the Redact tool to mark text or areas.',\n redactionArea: 'Area mark',\n redactionText: 'Text mark',\n redactionRemove: 'Remove mark',\n redactConfirmTitle: 'Apply redactions?',\n redactConfirmBody:\n 'Permanently remove the content under {count} redaction marks. This cannot be undone.',\n redactConfirmCollateral: '{count} other annotations will also be removed.',\n redactApply: 'Apply',\n redactApplying: 'Applying…',\n formatLabel: 'Format',\n redactLabelTitle: 'Redaction label',\n redactLabelPlaceholder: 'e.g. REDACTED',\n redactLabelRepeat: 'Repeat label across region',\n stampsTitle: 'Stamps',\n stampsAll: 'All stamps',\n stampsLoading: 'Loading stamps…',\n stampsEmpty: 'No stamps yet. Import a PDF to turn each of its pages into a stamp.',\n stampsRemoveStamp: 'Remove stamp',\n stampsArmedHint: 'Click a page to place the stamp.',\n stampsImport: 'Import PDF…',\n stampsImporting: 'Importing…',\n stampsImportHint: 'Import a PDF as a stamp library — each page becomes one stamp.',\n stampsRemoveLibrary: 'Remove library',\n stampsExportLibrary: 'Export library as PDF',\n stampsCustomLibrary: 'My stamps',\n stampsCustomLabel: 'Custom stamp',\n stampsError: 'The built-in stamps could not be loaded.',\n stampsArmError: 'That stamp could not be armed.',\n stampsImportError: 'That PDF could not be imported as a stamp library.',\n quickStampsLabel: 'Quick stamps',\n signaturesTitle: 'Signatures',\n signaturesEmpty: 'No signatures yet. Create one to sign with.',\n signaturesNew: 'New signature…',\n signaturesArmedHint:\n 'Click a signature field to sign it, or anywhere on a page to place the mark.',\n signaturesTargetHint: 'Pick a mark for the selected field.',\n signaturesInDocument: 'In this document',\n signaturesNone: 'This document has no signature fields.',\n signaturesValidate: 'Validate',\n signaturesValidating: 'Validating…',\n signaturesSigned: 'Signed',\n signaturesUnsigned: 'Unsigned',\n signaturesRename: 'Rename',\n signaturesRemove: 'Remove',\n signaturesExport: 'Export as PDF',\n signaturesAddInitials: 'Add initials',\n signatureLabel: 'Signature',\n initialsLabel: 'Initials',\n makerTitle: 'New signature',\n makerName: 'Name',\n makerNamePlaceholder: 'Your name',\n makerDraw: 'Draw',\n makerType: 'Type',\n makerUpload: 'Upload',\n makerTypePlaceholder: 'Type your name',\n makerFont: 'Font',\n makerUploadHint: 'Choose a PNG, JPEG, or one-page PDF',\n makerClear: 'Clear',\n makerOptional: '(optional)',\n makerSave: 'Save',\n makerSaving: 'Saving…',\n makerError: 'The signature could not be saved.',\n signTitle: 'Sign this field',\n signReason: 'Reason',\n signLocation: 'Location',\n signKind: 'What may change afterwards',\n signKindApproval: 'Approval signature — form filling and more signatures stay valid',\n signKindCertifyAnnotate: 'Certify — allow comments, form filling and signatures',\n signKindCertifyFill: 'Certify — allow form filling and signatures only',\n signKindCertifyLocked: 'Certify — allow no changes',\n signButton: 'Sign',\n signSigning: 'Signing…',\n signFill: 'Place without signing',\n signError: 'The field could not be signed.',\n inspectTitle: 'Signature',\n inspectSigner: 'Signed by',\n inspectReason: 'Reason',\n inspectLocation: 'Location',\n inspectTime: 'Time',\n inspectIntegrity: 'Document',\n inspectCryptography: 'Signature',\n inspectTrust: 'Signer',\n inspectChanges: 'Changes since',\n inspectDownload: 'Download signed version',\n verdictValid: 'Valid',\n verdictValidUntrusted: 'Valid, signer not trusted',\n verdictInvalid: 'Invalid — modified after signing',\n verdictWillInvalidate: 'Valid, invalid once saved',\n signaturesInvalidating:\n 'This change will invalidate {field} when the document is saved. Undo it to keep the signature.',\n verdictIndeterminate: 'Could not be verified',\n verdictUnchanged: 'None',\n verdictRestored: 'Changed, then restored',\n inspectLaterRevisions: 'Revisions after signing',\n verdictPermitted: 'Permitted',\n verdictForbidden: 'Not permitted',\n },\n },\n};\n","/**\n * The resolved customization, as React context. The chrome schema and the\n * user's extra icons are RESOLVED ONCE in <FullViewer> and read here by the\n * shell, menus, and strips — no component imports the default schema value\n * directly, so \"the host replaced the chrome\" is invisible below this line.\n *\n * The default context value is the default config: components render correctly\n * in tests and stories without a provider.\n */\nimport { createContext, useContext } from 'react';\nimport type { BarSchema, ChromeSchema, MenuSchema } from '@embedpdf/react/toolbar';\nimport { defaultChrome, getMenu, getModeBar, getStrip } from './config/chrome';\nimport type { IconDef } from './ui/icons';\nimport type { SignatureMode, SignerPort, TrustPort } from '@embedpdf/react/signature';\n\nexport interface StampsCustomization {\n /** `false`: no built-in library. A string: URL template with `{locale}`. */\n readonly defaultLibrary?: false | string;\n /** Library kinds the stamps sidebar lists. Default `['stamps']`. */\n readonly sidebar?: ReadonlyArray<string>;\n /** Quick marks in the Insert toolbar: asset ids (`library:name`) from any\n * library, or one library's whole set. Default none. */\n readonly toolbar?: ReadonlyArray<string> | { readonly library: string };\n}\n\nexport interface SignaturesCustomization {\n /** Which marks a person keeps. Default both. */\n readonly kinds?: ReadonlyArray<'signature' | 'initials'>;\n /** `'one'`: a single person per browser (no \"new signature\" once one exists). Default `'many'`. */\n readonly libraries?: 'one' | 'many';\n /** What placing a mark on a field does; default `sign` with a signer, else `visual`. */\n readonly mode?: SignatureMode;\n /** The key holder — `webCryptoSigner`, `remoteSigner`, `personalSigner`, or a thunk resolving one per signing. */\n readonly signer?: SignerPort | (() => Promise<SignerPort>);\n /** Trust anchors for validation; none → verdicts top out at \"valid, signer unknown\". */\n readonly trust?: TrustPort;\n /** Offer a certification (first signature, DocMDP) in the sign dialog. Default false. */\n readonly allowCertify?: boolean;\n /** Script faces for typed marks: registered on the viewer's engine on first use. */\n readonly fonts?: ReadonlyArray<{\n readonly key: string;\n readonly url: string;\n readonly label: string;\n }>;\n}\n\n/** A font for free-text annotations beyond the standard 14. */\nexport interface AnnotationFontSpec {\n /** The stable id a free-text `fontFamily` carries — the engine key AND the\n * CSS family the live editor renders with. Not one of the 14 standard names. */\n readonly key: string;\n /** Where the TTF/OTF bytes come from (same-origin or CORS-enabled). */\n readonly url: string;\n /** The picker's label. */\n readonly label: string;\n /** Family / style refinements for fallback matching; inferred from the file\n * when omitted. */\n readonly familyName?: string;\n readonly weight?: number;\n readonly italic?: boolean;\n}\n\nexport interface AnnotationsCustomization {\n /**\n * Fonts the free-text style panel offers beyond the standard 14. Each is\n * fetched once when the viewer mounts, registered on the viewer's engine\n * under its `key`, and mounted as a `@font-face` of the same name — so the\n * DOM editor shows the face the appearance stream will bake. A font whose\n * URL fails is skipped with a console warning. On the cloud engine (no\n * `engine.fonts`) they are not offered: fonts there are a server policy.\n */\n readonly fonts?: ReadonlyArray<AnnotationFontSpec>;\n}\n\nexport interface ResolvedViewerConfig {\n readonly chrome: ChromeSchema;\n /** User-registered icons — additive over the built-in set. */\n readonly icons: Readonly<Record<string, IconDef>>;\n readonly stamps: StampsCustomization;\n readonly signatures: SignaturesCustomization;\n readonly annotations: AnnotationsCustomization;\n}\n\nconst DEFAULT_CONFIG: ResolvedViewerConfig = {\n chrome: defaultChrome,\n icons: {},\n stamps: {},\n signatures: {},\n annotations: {},\n};\n\nconst ViewerConfigContext = createContext<ResolvedViewerConfig>(DEFAULT_CONFIG);\n\nexport const ViewerConfigProvider = ViewerConfigContext.Provider;\n\nexport function useChromeSchema(): ChromeSchema {\n return useContext(ViewerConfigContext).chrome;\n}\n\nexport function useMenuSchema(id: string): MenuSchema | undefined {\n return getMenu(useContext(ViewerConfigContext).chrome, id);\n}\n\nexport function useModeBarSchema(id: string): BarSchema | undefined {\n return getModeBar(useContext(ViewerConfigContext).chrome, id);\n}\n\nexport function useStripSchema(id: string): BarSchema | undefined {\n return getStrip(useContext(ViewerConfigContext).chrome, id);\n}\n\nexport function useCustomIcons(): Readonly<Record<string, IconDef>> {\n return useContext(ViewerConfigContext).icons;\n}\n\nexport function useStampsConfig(): StampsCustomization {\n return useContext(ViewerConfigContext).stamps;\n}\n\nexport function useSignaturesConfig(): SignaturesCustomization {\n return useContext(ViewerConfigContext).signatures;\n}\n\nexport function useAnnotationsConfig(): AnnotationsCustomization {\n return useContext(ViewerConfigContext).annotations;\n}\n","/**\n * The viewer handle — `el.viewer`, the DRIVE door of the customization model.\n *\n * Deliberately a THIN SKIN over the kernel: `get()` returns each plugin's\n * PUBLIC capability lens exactly as the plugin defined it (the internal/public\n * two-lens split in the plugins IS the curation — this file adds no facade,\n * no second vocabulary, no second write path). `watch()` is the kernel's one\n * change stream, selector-shaped — `useSelector` without React. The command\n * trio is the UI altitude of the same system, for anything button-shaped.\n *\n * Rule of thumb (docs): buttons speak commands; code speaks capabilities.\n *\n * The chrome itself runs on these exact primitives (customer #1), so parity\n * between \"what our UI can do\" and \"what el.viewer can do\" is structural.\n */\nimport type {\n CapabilityToken,\n DocumentsCapability,\n Kernel,\n Unsubscribe,\n} from '@embedpdf/react/runtime';\nimport { CommandsToken, resolvedCommandsEqual } from '@embedpdf/react/commands';\nimport type { ResolvedCommand } from '@embedpdf/react/commands';\n\n/** `get`/`tryGet` bound to one document (see {@link ViewerHandle.forDocument}). */\nexport interface ScopedViewerHandle {\n get<T>(token: CapabilityToken<T>): T;\n tryGet<T>(token: CapabilityToken<T>): T | null;\n}\n\nexport interface ViewerHandle extends ScopedViewerHandle {\n /** The document registry — the tab model: list/open/close/setActive/…. */\n readonly documents: DocumentsCapability;\n\n /** `get`/`tryGet` with document-scoped tokens bound to `documentId`\n * instead of the active document. */\n forDocument(documentId: string): ScopedViewerHandle;\n\n /**\n * Re-run `select` on every kernel change; call `cb` when the selected value\n * really changed (`isEqual`, default `Object.is` — capability getters return\n * stable references between model changes, so identity works). Returns the\n * unsubscribe. This is the ONLY reactivity primitive; DOM events on the\n * element are sugar over it.\n */\n watch<T>(\n select: () => T,\n cb: (value: T, previous: T) => void,\n isEqual?: (a: T, b: T) => boolean,\n ): Unsubscribe;\n\n // ── commands: the UI vocabulary layered on the same capabilities ──────────\n execute(id: string, documentId?: string): void;\n resolve(id: string, documentId?: string): ResolvedCommand | null;\n /** `watch` sugar for one command's resolved state (label/icon/enabled/active). */\n watchCommand(id: string, cb: (cmd: ResolvedCommand | null) => void): Unsubscribe;\n}\n\nexport function createViewerHandle(kernel: Kernel): ViewerHandle {\n const watch = <T>(\n select: () => T,\n cb: (value: T, previous: T) => void,\n isEqual: (a: T, b: T) => boolean = Object.is,\n ): Unsubscribe => {\n let previous = select();\n return kernel.subscribe(() => {\n const next = select();\n if (isEqual(previous, next)) return;\n const before = previous;\n previous = next;\n cb(next, before);\n });\n };\n\n const commands = () => kernel.capability(CommandsToken);\n\n return {\n documents: kernel.documents,\n get: (token) => kernel.capability(token),\n tryGet: (token) => kernel.tryCapability(token),\n forDocument: (documentId) => ({\n get: (token) => kernel.capability(token, documentId),\n tryGet: (token) => kernel.tryCapability(token, documentId),\n }),\n watch,\n execute: (id, documentId) => commands().execute(id, documentId),\n resolve: (id, documentId) => commands().resolve(id, documentId) ?? null,\n watchCommand: (id, cb) =>\n watch(() => commands().resolve(id) ?? null, cb, resolvedCommandsEqual),\n };\n}\n","/**\n * Icon set — the snippet's Tabler-style stroke icons, extracted to path data\n * (from viewers/snippet/src/components/icons) and rendered by one <Icon>\n * component. Names match the snippet's icon registry so command `icon` ids\n * carry over verbatim. Stroke-based (currentColor); a few glyphs carry filled\n * sub-paths, marked `fill: true`.\n *\n * ACCENT SLOTS: a tool glyph tags the sub-paths that preview the tool's\n * drawing defaults — `stroke`/`fill: 'primary' | 'secondary'` paint from the\n * command's resolved `iconAccent` (slot placement ported 1:1 from the v2\n * hand-authored components). With no accent, a slotted stroke inherits\n * currentColor and a slotted fill renders nothing — pixel-identical to the\n * untagged glyph, so non-tool surfaces never change.\n *\n * GENERATED by scratchpad/extract-icons.mjs — 93 icons (slot tags by hand).\n */\nimport * as React from 'react';\nimport { useCustomIcons } from '../config-context';\n\nexport type PathSpec =\n | string\n | {\n d: string;\n /** Fill paint: `true` = currentColor (a filled glyph part); a slot\n * name = that accent color (nothing when the accent is absent). */\n fill?: boolean | 'primary' | 'secondary';\n /** Stroke paint: a slot name = that accent color (currentColor when\n * the accent is absent). */\n stroke?: 'primary' | 'secondary';\n };\n\n/** A registrable icon: 24×24 stroke path data (Tabler/Lucide-style), exactly\n * the shape of the built-in set — user icons are not a lesser kind. */\nexport type IconDef = readonly PathSpec[];\n\n/** The two tintable slots — structurally identical to plugin-commands'\n * IconAccent, kept local so the icon set stays dependency-free. */\nexport interface IconAccent {\n primary?: string;\n secondary?: string;\n}\n\nexport const ICON_PATHS: Record<string, readonly PathSpec[]> = {\n alertTriangle: [\n 'M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z',\n ],\n alignBottom: [\n 'M3 19v-14a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z',\n 'M11 17h2',\n 'M9 14h6',\n 'M10 11h4',\n ],\n alignCenter: ['M4 6l16 0', 'M8 12l8 0', 'M6 18l12 0'],\n alignLeft: ['M4 6l16 0', 'M4 12l10 0', 'M4 18l14 0'],\n alignMiddle: [\n 'M3 19v-14a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z',\n 'M11 15h2',\n 'M9 12h6',\n 'M10 9h4',\n ],\n alignRight: ['M4 6l16 0', 'M10 12l10 0', 'M6 18l14 0'],\n alignTop: [\n 'M3 19v-14a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z',\n 'M11 13h2',\n 'M9 10h6',\n 'M10 7h4',\n ],\n arrowBackUp: ['M9 14l-4 -4l4 -4', 'M5 10h11a4 4 0 1 1 0 8h-1'],\n arrowForwardUp: ['M15 14l4 -4l-4 -4', 'M19 10h-11a4 4 0 1 0 0 8h1'],\n bold: ['M7 5h6a3.5 3.5 0 0 1 0 7h-6z', 'M13 12h1a3.5 3.5 0 0 1 0 7h-7v-7'],\n book: [\n 'M3 19a9 9 0 0 1 9 0a9 9 0 0 1 9 0',\n 'M3 6a9 9 0 0 1 9 0a9 9 0 0 1 9 0',\n 'M3 6l0 13',\n 'M12 6l0 13',\n 'M21 6l0 13',\n ],\n book2: [\n 'M19 4v16h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12z',\n 'M19 16h-12a2 2 0 0 0 -2 2',\n 'M9 8h6',\n ],\n callout: [\n {\n d: 'M20 6v4a1 1 0 0 1 -1 1h-14a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h14a1 1 0 0 1 1 1',\n stroke: 'primary',\n fill: 'secondary',\n },\n { d: 'M17 11v6h-9', stroke: 'primary' },\n { d: 'M8 15l-2 2l2 2', stroke: 'primary' },\n ],\n check: ['M5 12l5 5l10 -10'],\n chevronDown: ['M6 9l6 6l6 -6'],\n chevronLeft: ['M15 6l-6 6l6 6'],\n chevronRight: ['M9 6l6 6l-6 6'],\n circle: [\n { d: 'M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0', stroke: 'primary', fill: 'secondary' },\n ],\n comment: [\n 'M12 11v.01',\n 'M8 11v.01',\n 'M16 11v.01',\n 'M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3z',\n ],\n copy: [\n 'M7 7m0 2.667a2.667 2.667 0 0 1 2.667 -2.667h8.666a2.667 2.667 0 0 1 2.667 2.667v8.666a2.667 2.667 0 0 1 -2.667 2.667h-8.666a2.667 2.667 0 0 1 -2.667 -2.667z',\n 'M4.012 16.737a2.005 2.005 0 0 1 -1.012 -1.737v-10c0 -1.1 .9 -2 2 -2h10c.75 0 1.158 .385 1.5 1',\n ],\n deviceFloppy: [\n 'M6 4h10l4 4v10a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2',\n 'M12 14m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M14 4l0 4l-6 0l0 -4',\n ],\n dots: [\n 'M5 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n 'M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n 'M19 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n ],\n doublePage: [\n 'M3 3m0 1a1 1 0 0 1 1 -1h16a1 1 0 0 1 1 1v16a1 1 0 0 1 -1 1h-16a1 1 0 0 1 -1 -1zm9 -1v18',\n ],\n download: ['M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2', 'M7 11l5 5l5 -5', 'M12 4l0 12'],\n externalLink: [\n 'M12 6h-6a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-6',\n 'M11 13l9 -9',\n 'M15 4h5v5',\n ],\n eye: ['M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z'],\n file: ['M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z'],\n fileImport: [\n 'M14 3v4a1 1 0 0 0 1 1h4',\n 'M5 13v-8a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2h-5.5m-9.5 -2h7m-3 -3l3 3l-3 3',\n ],\n fitToPage: [\n 'M12 20h-6a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h6',\n 'M18 14v7',\n 'M18 3v7',\n 'M15 18l3 3l3 -3',\n 'M15 6l3 -3l3 3',\n ],\n fitToWidth: [\n 'M4 12v-6a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v6',\n 'M10 18h-7',\n 'M21 18h-7',\n 'M6 15l-3 3l3 3',\n 'M18 15l3 3l-3 3',\n ],\n formCheckbox: [\n 'M3 5a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-14',\n 'M9 12l2 2l4 -4',\n ],\n formListbox: [\n 'M3 5a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-14',\n 'M11 8h6',\n 'M11 12h6',\n 'M11 16h6',\n 'M7 8l0 .01',\n 'M7 12l0 .01',\n 'M7 16l0 .01',\n ],\n formRadio: [\n { d: 'M9 12a2 2 0 1 0 6 0a2 2 0 1 0 -6 0', fill: true },\n 'M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0',\n ],\n formSelect: [\n 'M3 5a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-14',\n 'M9 11l3 3l3 -3',\n ],\n formTextfield: [\n 'M12 3a3 3 0 0 0 -3 3v12a3 3 0 0 0 3 3',\n 'M6 3a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3',\n 'M13 7h7a1 1 0 0 1 1 1v8a1 1 0 0 1 -1 1h-7',\n 'M5 7h-1a1 1 0 0 0 -1 1v8a1 1 0 0 0 1 1h1',\n 'M17 12h.01',\n 'M13 12h.01',\n ],\n freeText: [\n { d: 'M4 7v-2h12v2', stroke: 'primary' },\n { d: 'M10 5v14', stroke: 'primary' },\n { d: 'M12 19h-4', stroke: 'primary' },\n { d: 'M15 13v-1h6v1', stroke: 'primary' },\n { d: 'M18 12v7', stroke: 'primary' },\n { d: 'M17 19h2', stroke: 'primary' },\n ],\n fullscreen: [\n 'M4 8v-2a2 2 0 0 1 2 -2h2',\n 'M4 16v2a2 2 0 0 0 2 2h2',\n 'M16 4h2a2 2 0 0 1 2 2v2',\n 'M16 20h2a2 2 0 0 0 2 -2v-2',\n ],\n fullscreenExit: [\n 'M4 8v-2c0 -.551 .223 -1.05 .584 -1.412',\n 'M4 16v2a2 2 0 0 0 2 2h2',\n 'M16 4h2a2 2 0 0 1 2 2v2',\n 'M16 20h2c.545 0 1.04 -.218 1.4 -.572',\n 'M3 3l18 18',\n ],\n group: [\n 'M3 5a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M17 5a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M3 19a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M17 19a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M5 7v10',\n 'M19 7v10',\n 'M7 5h10',\n 'M7 19h10',\n 'M8 8H12.8V11.2H16V16H11.2V12.8H8V8Z',\n ],\n hand: [\n 'M8 13v-7.5a1.5 1.5 0 0 1 3 0v6.5',\n 'M11 5.5v-2a1.5 1.5 0 1 1 3 0v8.5',\n 'M14 5.5a1.5 1.5 0 0 1 3 0v6.5',\n 'M17 7.5a1.5 1.5 0 0 1 3 0v8.5a6 6 0 0 1 -6 6h-2h.208a6 6 0 0 1 -5.012 -2.7a69.74 69.74 0 0 1 -.196 -.3c-.312 -.479 -1.407 -2.388 -3.286 -5.728a1.5 1.5 0 0 1 .536 -2.022a1.867 1.867 0 0 1 2.28 .28l1.47 1.47',\n ],\n highlight: [\n // the v2 marker block behind the \"A\" — visible only when accented\n {\n d: 'M4 6h16a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2H4a2 2 0 0 1 -2 -2V8a2 2 0 0 1 2 -2z',\n fill: 'primary',\n },\n 'M8 16v-8a4 4 0 1 1 8 0v8',\n 'M8 10h8',\n ],\n horizontal: ['M7 8l-4 4l4 4', 'M17 8l4 4l-4 4', 'M3 12l18 0'],\n inkHighlighter: [\n 'M3 19h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4',\n 'M12.5 5.5l4 4',\n 'M4.5 13.5l4 4',\n { d: 'M21 15v4h-8l4 -4l4 0', stroke: 'primary', fill: 'primary' },\n ],\n insertText: [\n { d: 'M3 7v-2h12v2', stroke: 'primary' },\n { d: 'M9 5v14', stroke: 'primary' },\n { d: 'M7 19h4', stroke: 'primary' },\n { d: 'M18 15l2 2h-5', stroke: 'primary' },\n { d: 'M18 19l2 -2', stroke: 'primary' },\n ],\n italic: ['M11 5l6 0', 'M7 19l6 0', 'M14 5l-4 14'],\n line: [{ d: 'M20 4l-16 16', stroke: 'primary' }],\n // Both strokes tag the `primary` accent slot so the arrow glyph previews the\n // tool's stroke colour (like the plain `line` icon); with no accent they render\n // as currentColor — identical to the untagged glyph.\n lineArrow: [\n { d: 'M20 4l-16 16', stroke: 'primary' },\n { d: 'M16 3h5v5', stroke: 'primary' },\n ],\n link: [\n 'M9 15l6 -6',\n 'M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464',\n 'M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463',\n ],\n linkOff: [\n 'M9 15l3 -3m2 -2l1 -1',\n 'M11 6l.463 -.536a5 5 0 0 1 7.072 7.071l-.534 .464',\n 'M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463',\n 'M3 3l18 18',\n ],\n listTree: ['M9 6h11', 'M12 12h8', 'M15 18h5', 'M5 6v.01', 'M8 12v.01', 'M11 18v.01'],\n lock: [\n 'M5 11h14a2 2 0 0 1 2 2v7a2 2 0 0 1 -2 2H5a2 2 0 0 1 -2 -2v-7a2 2 0 0 1 2 -2z',\n 'M7 11V7a5 5 0 0 1 10 0v4',\n ],\n marqueeSelect: [\n 'M17 20h6',\n 'M20 17v6',\n 'M4 13v-2',\n 'M4 6v-1a1 1 0 0 1 1 -1h1',\n 'M6 20h-1a1 1 0 0 1 -1 -1v-1',\n 'M11 4h2',\n 'M11 20h2',\n 'M18 4h1a1 1 0 0 1 1 1v1',\n 'M20 11v2',\n ],\n menu: ['M4 8l16 0', 'M4 16l16 0'],\n message: [\n 'M8 9h8',\n 'M8 13h6',\n 'M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12',\n ],\n palette: [\n 'M12 21a9 9 0 0 1 0 -18c4.97 0 9 3.582 9 8c0 1.06 -.474 2.078 -1.318 2.828c-.844 .75 -1.989 1.172 -3.182 1.172h-2.5a2 2 0 0 0 -1 3.75a1.3 1.3 0 0 1 -1 2.25',\n 'M8.5 10.5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n 'M12.5 7.5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n 'M16.5 10.5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n ],\n paperclip: [\n 'M15 7l-6.5 6.5a1.5 1.5 0 0 0 3 3l6.5 -6.5a3 3 0 0 0 -6 -6l-6.5 6.5a4.5 4.5 0 0 0 9 9l6.5 -6.5',\n ],\n pencilMarker: [\n 'm9.109 16.275 8.856-8.097c.812-.743.87-2.014.127-2.826s-2.014-.869-2.826-.127L6.41 13.322l-.127 2.826zM13.79 6.575l2.7 2.952',\n {\n d: 'M19.375 20.125c.569.063-4.05-.562-6.412-.437s-4.759 1.229-6.857 1.625c-1.764.687-3.404-.938-1.981-2.5',\n stroke: 'primary',\n },\n ],\n photo: [\n 'M15 8h.01',\n 'M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12z',\n 'M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5',\n 'M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3',\n ],\n // hand-added: the v2 file draws <line> primitives the extractor skips\n plus: ['M12 5l0 14', 'M5 12l14 0'],\n pointer: [\n 'M7.904 17.563a1.2 1.2 0 0 0 2.228 .308l2.09 -3.093l4.907 4.907a1.067 1.067 0 0 0 1.509 0l1.047 -1.047a1.067 1.067 0 0 0 0 -1.509l-4.907 -4.907l3.113 -2.09a1.2 1.2 0 0 0 -.309 -2.228l-13.582 -3.904l3.904 13.563z',\n ],\n polygon: [\n {\n d: 'M13.163 2.168l8.021 5.828c.694 .504 .984 1.397 .719 2.212l-3.064 9.43a1.978 1.978 0 0 1 -1.881 1.367h-9.916a1.978 1.978 0 0 1 -1.881 -1.367l-3.064 -9.43a1.978 1.978 0 0 1 .719 -2.212l8.021 -5.828a1.978 1.978 0 0 1 2.326 0z',\n stroke: 'primary',\n fill: 'secondary',\n },\n ],\n print: [\n 'M17 17h2a2 2 0 0 0 2 -2v-4a2 2 0 0 0 -2 -2h-14a2 2 0 0 0 -2 2v4a2 2 0 0 0 2 2h2',\n 'M17 9v-4a2 2 0 0 0 -2 -2h-6a2 2 0 0 0 -2 2v4',\n 'M7 13m0 2a2 2 0 0 1 2 -2h6a2 2 0 0 1 2 2v4a2 2 0 0 1 -2 2h-6a2 2 0 0 1 -2 -2z',\n ],\n redact: [\n 'M7 4h10',\n 'M12 4v8',\n 'M-7 24l12 -12',\n 'M-3 24l12 -12',\n 'M1 24l12 -12',\n 'M5 24l12 -12',\n 'M9 24l12 -12',\n 'M13 24l12 -12',\n 'M17 24l12 -12',\n 'M21 24l12 -12',\n 'M25 24l12 -12',\n ],\n // v2 parity: dashed frame + a SMALL rounded hatched box (v2 clips the\n // hatch via <clipPath>; this icon system is plain paths, so the hatch\n // segments are pre-clipped to the 10..22 box analytically).\n redactArea: [\n 'M6 20h-1a2 2 0 0 1 -2 -2v-1',\n 'M3 13v-3',\n 'M3 6v-1a2 2 0 0 1 2 -2h1',\n 'M10 3h3',\n 'M17 3h1a2 2 0 0 1 2 2v1',\n 'M12 10h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2v-8a2 2 0 0 1 2 -2z',\n 'M10 12l2 -2',\n 'M10 16l6 -6',\n 'M10 20l10 -10',\n 'M12 22l10 -10',\n 'M16 22l6 -6',\n 'M20 22l2 -2',\n ],\n redactCombined: [\n 'M6 20h-1a2 2 0 0 1 -2 -2v-1',\n 'M3 13v-3',\n 'M20 13v-3',\n 'M3 6v-1a2 2 0 0 1 2 -2h1',\n 'M10 3h3',\n 'M17 3h1a2 2 0 0 1 2 2v1',\n 'M8 8h8',\n 'M12 8v7',\n 'M6 19l12 -12',\n 'M6 23l12 -12',\n 'M10 23l12 -12',\n 'M14 27l12 -12',\n 'M14 23l12 -12',\n ],\n redactionSidebar: [\n 'M4 6a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z',\n 'M15 4v16',\n 'M7 8h5',\n 'M7 11h5',\n 'M7 14h4',\n ],\n replaceText: [\n { d: 'M3 7v-2h12v2', stroke: 'primary' },\n { d: 'M9 5v14', stroke: 'primary' },\n { d: 'M7 19h4', stroke: 'primary' },\n { d: 'M20 14l2 2h-3', stroke: 'primary' },\n { d: 'M20 18l2 -2', stroke: 'primary' },\n { d: 'M19 16a3 3 0 1 0 2 5.236', stroke: 'primary' },\n ],\n rotateClockwise: ['M4.05 11a8 8 0 1 1 .5 4m-.5 5v-5h5'],\n rotateCounterClockwise: ['M19.95 11a8 8 0 1 0 -.5 4m.5 5v-5h-5'],\n rubberStamp: [\n 'M21 17.85h-18c0 -4.05 1.421 -4.05 3.79 -4.05c5.21 0 1.21 -4.59 1.21 -6.8a4 4 0 1 1 8 0c0 2.21 -4 6.8 1.21 6.8c2.369 0 3.79 0 3.79 4.05',\n 'M5 21h14',\n ],\n rubberStampPlus: [\n 'M21 17.85h-18c0 -4.05 1.421 -4.05 3.79 -4.05c5.21 0 1.21 -4.59 1.21 -6.8a4 4 0 0 1 4.9 -4.1',\n 'M16 10c0 1.2 -4 3.8 1.21 3.8c2.369 0 3.79 0 3.79 4.05',\n 'M5 21h14',\n 'M16 5h6',\n 'M19 2v6',\n ],\n save: [\n 'M6 4h10l4 4v10a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2',\n 'M12 14m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M14 4l0 4l-6 0l0 -4',\n ],\n screenshot: [\n 'M7 19a2 2 0 0 1 -2 -2',\n 'M5 13v-2',\n 'M5 7a2 2 0 0 1 2 -2',\n 'M11 5h2',\n 'M17 5a2 2 0 0 1 2 2',\n 'M19 11v2',\n 'M19 17v4',\n 'M21 19h-4',\n 'M13 19h-2',\n ],\n search: ['M10 10m-7 0a7 7 0 1 0 14 0a7 7 0 1 0 -14 0', 'M21 21l-6 -6'],\n settings: [\n 'M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z',\n 'M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0',\n ],\n sidebar: [\n 'M4 18v-12a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z',\n 'M10 18v-12a2 2 0 0 1 2 -2h6a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-6a2 2 0 0 1 -2 -2z',\n ],\n signature: [\n 'M3 17c3.333 -3.333 5 -6 5 -8c0 -3 -1 -3 -2 -3s-2.032 1.085 -2 3c.034 2.048 1.658 4.877 2.5 6c1.5 2 2.5 2.5 3.5 1l2 -3c.333 2.667 1.333 4 3 4c.53 0 2.639 -2 3 -2c.517 0 1.517 .667 3 2',\n ],\n singlePage: ['M5 3m0 1a1 1 0 0 1 1 -1h12a1 1 0 0 1 1 1v16a1 1 0 0 1 -1 1h-12a1 1 0 0 1 -1 -1z'],\n square: [\n {\n d: 'M3 3m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z',\n stroke: 'primary',\n fill: 'secondary',\n },\n ],\n squares: [\n 'M8 10a2 2 0 0 1 2 -2h9a2 2 0 0 1 2 2v9a2 2 0 0 1 -2 2h-9a2 2 0 0 1 -2 -2z',\n 'M16 8v-3a2 2 0 0 0 -2 -2h-9a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h3',\n ],\n squiggly: [\n 'M8 16v-8a4 4 0 1 1 8 0v8',\n 'M8 10h8',\n { d: 'M4 20c1.5 -1.5 3.5 -1.5 5 0s3.5 1.5 5 0 3.5 -1.5 5 0', stroke: 'primary' },\n ],\n strikethrough: ['M8 16v-8a4 4 0 1 1 8 0v8', { d: 'M4 10h16', stroke: 'primary' }],\n text: [\n 'M6.5 15.5m-3.5 0a3.5 3.5 0 1 0 7 0a3.5 3.5 0 1 0 -7 0',\n 'M14 19v-10.5a3.5 3.5 0 0 1 7 0v10.5',\n 'M14 13h7',\n 'M10 12v7',\n ],\n trash: [\n 'M4 7l16 0',\n 'M10 11l0 6',\n 'M14 11l0 6',\n 'M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12',\n 'M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3',\n ],\n underline: [{ d: 'M4 20h16', stroke: 'primary' }, 'M8 16v-8a4 4 0 1 1 8 0v8', 'M8 10h8'],\n // the v2 ungroup glyph: two separated rounded rects\n ungroup: [\n 'M4 5a1 1 0 0 1 1 -1h5a1 1 0 0 1 1 1v5a1 1 0 0 1 -1 1h-5a1 1 0 0 1 -1 -1z',\n 'M13 14a1 1 0 0 1 1 -1h5a1 1 0 0 1 1 1v5a1 1 0 0 1 -1 1h-5a1 1 0 0 1 -1 -1z',\n ],\n unlock: ['M7 11V7a5 5 0 0 1 9.9-1'],\n vertical: ['M8 7l4 -4l4 4', 'M8 17l4 4l4 -4', 'M12 3l0 18'],\n viewSettings: [\n 'M12 14m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M12 10.5v1.5',\n 'M12 16v1.5',\n 'M15.031 12.25l-1.299 .75',\n 'M10.268 15l-1.3 .75',\n 'M15 15.803l-1.285 -.773',\n 'M10.285 12.97l-1.285 -.773',\n 'M14 3v4a1 1 0 0 0 1 1h4',\n 'M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z',\n ],\n widgetEdit: [\n 'M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1',\n 'M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415',\n 'M16 5l3 3',\n ],\n x: ['M18 6l-12 12', 'M6 6l12 12'],\n zigzag: [{ d: 'M12 2.4L21.36 11.76L2.64 12.24L12 21.6', stroke: 'primary' }],\n zoomIn: ['M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0', 'M9 12h6', 'M12 9v6'],\n zoomInArea: [\n 'M15 13v4',\n 'M13 15h4',\n 'M15 15m-5 0a5 5 0 1 0 10 0a5 5 0 1 0 -10 0',\n 'M22 22l-3 -3',\n 'M6 18h-1a2 2 0 0 1 -2 -2v-1',\n 'M3 11v-1',\n 'M3 6v-1a2 2 0 0 1 2 -2h1',\n 'M10 3h1',\n 'M15 3h1a2 2 0 0 1 2 2v1',\n ],\n zoomOut: ['M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0', 'M9 12l6 0'],\n};\n\nexport type IconName = keyof typeof ICON_PATHS;\n\nexport interface IconProps {\n name: string;\n size?: number;\n strokeWidth?: number;\n className?: string;\n title?: string;\n /** Paints the glyph's slot-tagged sub-paths (a tool previewing its\n * drawing defaults). Absent → the plain, untinted glyph. */\n accent?: IconAccent;\n}\n\n/** One SVG renderer for every icon. Unknown names render nothing (caller shows\n * a text fallback), so a missing glyph never throws. */\nexport function Icon({ name, size = 20, strokeWidth = 2, className, title, accent }: IconProps) {\n // Registry semantics: user icons are additive and a colliding name WINS —\n // re-skinning a built-in glyph is a supported move, not an accident.\n const custom = useCustomIcons();\n const paths = custom[name] ?? ICON_PATHS[name];\n if (!paths) return null;\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n role=\"img\"\n aria-hidden={title ? undefined : true}\n aria-label={title}\n >\n {paths.map((p, i) => {\n if (typeof p === 'string') return <path key={i} d={p} />;\n const fill = p.fill === true ? 'currentColor' : p.fill ? accent?.[p.fill] : undefined;\n // a stroke slot paints from the accent, inheriting currentColor\n // without one; a fill-ONLY path never gets an outline (the v2 look)\n const stroke = p.stroke ? accent?.[p.stroke] : p.fill ? 'none' : undefined;\n return <path key={i} d={p.d} fill={fill ?? 'none'} stroke={stroke} />;\n })}\n </svg>\n );\n}\n\nexport const hasIcon = (name: string): boolean => name in ICON_PATHS;\n","/**\n * Light/dark theme — one class, and the CSS variables in styles.css do the\n * rest (both toolbars, sidebars, popovers, and the canvas re-theme from it).\n * The mode comes from the embedder's `theme` preference; the chrome ships no\n * switch of its own, so a host that wants one drives this through `set`. The\n * class lands on <html> by default; a delivery that must not touch the page\n * (the <embedpdf-viewer> shadow root) passes `target` and the class stays\n * inside its own subtree. An explicit preference outranks the OS setting.\n */\nimport { createContext, useContext, useEffect, useMemo, useState } from 'react';\n\nexport type ThemeMode = 'light' | 'dark';\nexport type ThemePreference = ThemeMode | 'system';\n\nconst ThemeCtx = createContext<{\n mode: ThemeMode;\n toggle: () => void;\n set: (m: ThemeMode) => void;\n} | null>(null);\n\nconst systemMode = (): ThemeMode =>\n typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light';\n\nexport function ThemeProvider({\n children,\n preference = 'system',\n target,\n}: {\n children: React.ReactNode;\n /** Initial mode; 'system' (default) follows the OS setting. */\n preference?: ThemePreference;\n /** Where the `.dark` class goes. Default: document.documentElement. */\n target?: HTMLElement | null;\n}) {\n const [mode, setMode] = useState<ThemeMode>(() =>\n preference === 'system' ? systemMode() : preference,\n );\n useEffect(() => {\n (target ?? document.documentElement).classList.toggle('dark', mode === 'dark');\n }, [mode, target]);\n const value = useMemo(\n () => ({ mode, toggle: () => setMode((m) => (m === 'dark' ? 'light' : 'dark')), set: setMode }),\n [mode],\n );\n return <ThemeCtx.Provider value={value}>{children}</ThemeCtx.Provider>;\n}\n\nexport function useTheme() {\n const ctx = useContext(ThemeCtx);\n if (!ctx) throw new Error('useTheme must be used within <ThemeProvider>');\n return ctx;\n}\n","/**\n * The viewer's BUILT-IN stamp library: `@embedpdf/default-stamps`, the\n * standard rubber stamps as one Acrobat-compatible PDF per locale.\n *\n * Delivery: the library ships INSIDE whatever ships this viewer. The package\n * exposes each locale as a lazy ES module (`@embedpdf/default-stamps/library`),\n * so it travels through the module graph like any other code — every bundler\n * splits it into a chunk served from the app's own origin, the CDN snippet\n * carries it as a sibling chunk in its folder, and nothing is fetched from a\n * third party. `stamps.defaultLibrary` overrides that:\n * - `false` → no built-in library, no request (air-gapped);\n * - a URL template → exactly that (`{locale}` slot), for self-hosted copies.\n *\n * Loading is LAZY (first open of the stamps panel, never at boot) and\n * locale-aware: the chrome locale leads, the browser languages break ties\n * for the locales the chrome does not translate itself, and a locale change\n * while a default library is loaded swaps it for the new one. The file names\n * itself (`/Title`, `Id: embedpdf-standard`), so no overrides are passed.\n */\nimport { LOCALES, loadDefaultLibrary } from '@embedpdf/default-stamps/library';\nimport { negotiateLocale } from '@embedpdf/react/i18n';\nimport type { StampCapability } from '@embedpdf/react/stamp';\n\n/** The built-in library's PieceInfo id — excluded from persistence (it is\n * loaded again on every first open, in the locale of that moment). */\nexport const DEFAULT_LIBRARY_ID = 'embedpdf-standard';\n\nexport type DefaultLibrarySource = false | string | undefined;\n\n/** Which shipped locale to show for the chrome's locale + the browser's. */\nexport function resolveStampsLocale(chromeLocale: string): string {\n const languages = typeof navigator !== 'undefined' ? (navigator.languages ?? []) : [];\n return negotiateLocale(LOCALES, [chromeLocale, ...languages]) ?? 'en';\n}\n\nconst fetchBytes = async (url: string): Promise<Uint8Array> => {\n const response = await fetch(url);\n if (!response.ok) throw new Error(`${url}: HTTP ${response.status}`);\n return new Uint8Array(await response.arrayBuffer());\n};\n\n/** The library bytes for `locale`: your URL when you gave one, otherwise the\n * copy that shipped with the viewer. Never anything else. */\nconst defaultLibraryBytes = (locale: string, source: string | undefined) =>\n source ? fetchBytes(source.replace('{locale}', locale)) : loadDefaultLibrary(locale);\n\n/** Per workspace: the locale the default library was last brought to, and\n * the in-flight work — the panel mounts and unmounts with the sidebar, so\n * this cannot live in component state. */\nconst loads = new WeakMap<StampCapability, { locale: string; promise: Promise<void> }>();\n\n/**\n * Bring the built-in library to `locale`. Idempotent per workspace and\n * locale; a locale change swaps the loaded default (remove, then import);\n * a default the user removed in this session stays removed — the locale is\n * recorded, nothing is re-added. An embedder that seeded a library under\n * the same id is left alone.\n */\nexport function ensureDefaultLibrary(\n stamp: StampCapability,\n locale: string,\n source: DefaultLibrarySource,\n): Promise<void> {\n if (source === false) return Promise.resolve();\n const current = loads.get(stamp);\n if (current?.locale === locale) return current.promise;\n const run = async () => {\n await current?.promise.catch(() => undefined);\n const loaded = stamp.library(DEFAULT_LIBRARY_ID);\n if (loaded?.locale === locale) return;\n if (current && !loaded) return; // removed by the user this session\n if (loaded) await stamp.removeLibrary(DEFAULT_LIBRARY_ID);\n await stamp.importLibraryPdf(await defaultLibraryBytes(locale, source));\n };\n const promise = run();\n loads.set(stamp, { locale, promise });\n return promise;\n}\n","/**\n * The user's stamp libraries live in the browser (IndexedDB): restored ONCE\n * per workspace, written on every change, for as long as the viewer lives —\n * a signature made while the stamps sidebar is closed is persisted exactly\n * like a stamp imported while it is open. The built-in library is never\n * stored (it is fetched again next time, in the locale of that moment); the\n * panels that need it bring it in lazily through `ensureDefaultLibrary`.\n *\n * Mounted once in the Shell, workspace-scoped (the stamp plugin is).\n */\nimport { useEffect } from 'react';\nimport {\n indexedDbByteStore,\n persistStampLibraries,\n restoreStampLibraries,\n useStamp,\n type StampCapability,\n} from '@embedpdf/react/stamp';\nimport { DEFAULT_LIBRARY_ID } from '../config/default-stamps';\n\nconst store =\n typeof indexedDB === 'undefined'\n ? null\n : indexedDbByteStore('embedpdf-stamps', { storeName: 'libraries' });\n\nconst restored = new WeakMap<StampCapability, Promise<unknown>>();\n\n/** Bring the stored libraries back — once per workspace, whoever asks first. */\nexport const restoreStampLibrariesOnce = (stamp: StampCapability): Promise<unknown> => {\n let pending = restored.get(stamp);\n if (!pending) {\n pending = store ? restoreStampLibraries(stamp, store) : Promise.resolve();\n restored.set(stamp, pending);\n }\n return pending;\n};\n\nexport function StampLibraryStore() {\n const stamp = useStamp();\n useEffect(() => {\n void restoreStampLibrariesOnce(stamp);\n return store\n ? persistStampLibraries(stamp, store, { except: [DEFAULT_LIBRARY_ID] })\n : undefined;\n }, [stamp]);\n return null;\n}\n","/**\n * Quick marks in the toolbar: a row of stamp thumbnails that ARM on click —\n * the checkmark, the cross, whatever the embedder configured\n * (`stamps.toolbar`: asset ids, or one library's assets). The hover ghost and\n * the click placement are the annotation plugin's, exactly as from the\n * sidebar; only the picker moved. Renders nothing until the assets exist.\n * Lives in the workspace toolbar, so it reads the ACTIVE document's tool.\n */\nimport { useEffect } from 'react';\nimport { InteractionToken } from '@embedpdf/react/interaction';\nimport { useLocale, useT } from '@embedpdf/react/i18n';\nimport { useDocumentId, useOptionalSelector } from '@embedpdf/react/runtime';\nimport {\n StampToken,\n useArmStampAsset,\n useStamp,\n useStampAssetPreviewUrl,\n useStampAssets,\n type StampAsset,\n} from '@embedpdf/react/stamp';\nimport { useStampsConfig } from '../config-context';\nimport {\n DEFAULT_LIBRARY_ID,\n ensureDefaultLibrary,\n resolveStampsLocale,\n} from '../config/default-stamps';\nimport { restoreStampLibrariesOnce } from './stamp-store';\nimport { buttonClass } from './toolbar';\n\nexport function QuickStamps() {\n const t = useT();\n const stamp = useStamp();\n const config = useStampsConfig();\n const { locale } = useLocale();\n const assets = useStampAssets();\n const documentId = useDocumentId();\n const { armAsset } = useArmStampAsset();\n const activeToolId = useOptionalSelector(InteractionToken, (c) => c.activeToolId(), null);\n const armedId = useOptionalSelector(\n StampToken,\n (c) => (documentId ? (c.armedAsset(documentId)?.id ?? null) : null),\n null,\n );\n const ids = Array.isArray(config.toolbar)\n ? config.toolbar\n : config.toolbar && 'library' in config.toolbar\n ? (stamp.library(config.toolbar.library)?.assetIds ?? [])\n : [];\n\n // A quick mark from the built-in library needs that library loaded — the\n // one case the toolbar pays for it at boot. The user's own libraries are\n // restored by the workspace store.\n const wantsDefault = ids.some((id) => id.startsWith(`${DEFAULT_LIBRARY_ID}:`));\n useEffect(() => {\n if (!wantsDefault) return;\n restoreStampLibrariesOnce(stamp)\n .then(() => ensureDefaultLibrary(stamp, resolveStampsLocale(locale), config.defaultLibrary))\n .catch((err) => console.error('[embedpdf] quick stamps failed:', err));\n // `config` is init-stable; only the locale re-runs this.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [stamp, locale, wantsDefault]);\n\n const shown = ids\n .map((id) => assets.find((a) => a.id === id))\n .filter((a): a is StampAsset => !!a);\n if (shown.length === 0 || !documentId) return null;\n return (\n <div className=\"flex items-center gap-1\" role=\"group\" aria-label={t('demo.quickStampsLabel')}>\n {shown.map((asset) => (\n <QuickStampButton\n key={asset.id}\n asset={asset}\n active={activeToolId === 'stamp' && armedId === asset.id}\n onArm={() =>\n void armAsset(asset.id).catch((e) => console.error('[embedpdf] arm failed', e))\n }\n />\n ))}\n </div>\n );\n}\n\nfunction QuickStampButton({\n asset,\n active,\n onArm,\n}: {\n asset: StampAsset;\n active: boolean;\n onArm: () => void;\n}) {\n const url = useStampAssetPreviewUrl(asset.id);\n return (\n <button\n type=\"button\"\n onClick={onArm}\n title={asset.label}\n aria-label={asset.label}\n aria-pressed={active || undefined}\n className={buttonClass(active, true)}\n >\n {url ? (\n <img src={url} alt=\"\" className=\"h-5 w-5 object-contain\" draggable={false} />\n ) : (\n <span className=\"text-xs\">{asset.label}</span>\n )}\n </button>\n );\n}\n","/**\n * Menu rendering — a MenuSchema (a tree of command ids) rendered as rows.\n * Reused by the toolbar dropdowns (document / zoom / page-settings) AND by the\n * overflow menu's inline submenu expansion, so a command's menu form is\n * identical wherever it surfaces. Rows resolve live through the command\n * registry: label, icon, active tick, enabled state.\n */\nimport { useState } from 'react';\nimport { useCommand, useCommands } from '@embedpdf/react/commands';\nimport { useT } from '@embedpdf/react/i18n';\nimport type { MenuSchema } from '@embedpdf/react/toolbar';\nimport { Icon } from './icons';\nimport { useMenuSchema } from '../config-context';\n\nexport function MenuRow({ commandId, onRun }: { commandId: string; onRun?: () => void }) {\n const cmd = useCommand(commandId);\n const commands = useCommands();\n if (!cmd || !cmd.visible) return null;\n return (\n <button\n type=\"button\"\n role={cmd.active ? 'menuitemradio' : 'menuitem'}\n part={cmd.active ? 'menu-item menu-item-active' : 'menu-item'}\n aria-checked={cmd.active || undefined}\n disabled={!cmd.enabled}\n onClick={() => {\n commands.execute(commandId);\n onRun?.();\n }}\n // v2 shows selection as a blue-tinted row (bg-interactive-selected +\n // text-accent), never a checkmark — the icon column stays the command's\n // own icon.\n className={`flex w-full items-center gap-3 rounded-md px-2.5 py-1.5 text-left text-sm transition-colors disabled:pointer-events-none disabled:opacity-40 ${\n cmd.active ? 'bg-selected text-accent' : 'text-fg-secondary hover:bg-hover'\n }`}\n >\n {cmd.icon && (\n <Icon\n name={cmd.icon}\n size={16}\n accent={cmd.iconAccent}\n className={cmd.active ? '' : 'text-fg-muted'}\n />\n )}\n <span className=\"flex-1 truncate\">{cmd.label}</span>\n </button>\n );\n}\n\n/** One section-separated menu, by schema id. */\nexport function MenuBody({ menuId, onRun }: { menuId: string; onRun?: () => void }) {\n const t = useT();\n const menu: MenuSchema | undefined = useMenuSchema(menuId);\n if (!menu) return null;\n return (\n <div className=\"min-w-52 p-1\">\n {menu.sections.map((section, i) => (\n <div key={i}>\n {i > 0 && <div className=\"bg-border-subtle my-1 h-px\" />}\n {section.labelKey && (\n <div className=\"text-fg-muted px-2.5 pb-1 pt-1.5 text-[11px] font-semibold uppercase tracking-wide\">\n {t(section.labelKey)}\n </div>\n )}\n {section.items.map((id) => (\n <MenuRow key={id} commandId={id} onRun={onRun} />\n ))}\n </div>\n ))}\n </div>\n );\n}\n\n/** The popover shell: a floating surface + click-away scrim. */\nexport function Popover({\n children,\n onClose,\n align = 'start',\n}: {\n children: React.ReactNode;\n onClose: () => void;\n align?: 'start' | 'end';\n}) {\n return (\n <>\n <div className=\"fixed inset-0 z-40\" onClick={onClose} />\n <div\n part=\"menu\"\n className={`border-border-subtle bg-elevated absolute top-full z-50 mt-1 rounded-lg border shadow-xl ${\n align === 'end' ? 'right-0' : 'left-0'\n }`}\n >\n {children}\n </div>\n </>\n );\n}\n\n/** A menu dropdown that expands inline (used inside the overflow menu, where a\n * submenu can't anchor to an off-screen trigger). */\nexport function InlineSubmenu({ menuId, label }: { menuId: string; label: string }) {\n const [open, setOpen] = useState(false);\n return (\n <div>\n <button\n type=\"button\"\n onClick={() => setOpen((o) => !o)}\n className=\"text-fg-secondary hover:bg-hover flex w-full items-center gap-3 rounded-md px-2.5 py-1.5 text-left text-sm\"\n >\n <span className=\"flex-1 truncate\">{label}</span>\n <Icon name={open ? 'chevronDown' : 'chevronRight'} size={16} />\n </button>\n {open && (\n <div className=\"border-border-subtle ml-3 border-l pl-1\">\n <MenuBody menuId={menuId} />\n </div>\n )}\n </div>\n );\n}\n","/**\n * The app's toolbar look — Tailwind render props over the headless <Toolbar>.\n * The app owns the pixels; ui-core owns the physics (measure → solve →\n * overflow). Nothing here knows about breakpoints or widths.\n *\n * Styling is a 1:1 port of the v2 snippet's components:\n * Button → viewers/snippet/src/components/ui/button.tsx\n * TabButton → viewers/snippet/src/components/ui/tab-button.tsx (underline)\n * zoom widget → viewers/snippet/src/components/custom-zoom-toolbar.tsx\n * mode select → viewers/snippet/src/components/mode-select-button.tsx\n */\nimport { useEffect, useState } from 'react';\nimport { useOptionalCapability, useOptionalSelector } from '@embedpdf/react/runtime';\nimport { Toolbar } from '@embedpdf/react/toolbar';\nimport type {\n BarSchema,\n CollapsedGroupView,\n GroupDisclosureView,\n OverflowMenuView,\n} from '@embedpdf/react/toolbar';\nimport { useCommands } from '@embedpdf/react/commands';\nimport type { ResolvedCommand } from '@embedpdf/react/commands';\nimport { QuickStamps } from './quick-stamps';\nimport { useMenus } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { StageToken } from '@embedpdf/react/stage';\nimport { Icon } from './icons';\nimport { MenuBody, Popover, InlineSubmenu } from './menu';\n\n// ── the v2 Button recipe ──────────────────────────────────────────────────────\nconst BTN_BASE =\n 'flex h-8 w-auto min-w-8 cursor-pointer items-center justify-center rounded-md p-[5px] transition-colors';\nconst BTN_HOVER = 'hover:bg-hover hover:ring hover:ring-accent';\nconst BTN_ACTIVE = 'border-none bg-selected text-accent shadow ring ring-accent';\nconst BTN_DISABLED = 'cursor-not-allowed opacity-50 hover:bg-transparent hover:ring-0';\n\nexport const buttonClass = (active: boolean, enabled = true): string =>\n `${BTN_BASE} ${active ? BTN_ACTIVE : BTN_HOVER} ${enabled ? '' : BTN_DISABLED}`;\n\n// ── the v2 TabButton recipe (the underline) ───────────────────────────────────\nconst TAB_BASE =\n 'flex h-8 w-auto min-w-8 cursor-pointer items-center justify-center rounded-none border-b-2 px-2 py-1 text-sm transition-colors hover:bg-transparent hover:border-b-fg-muted';\nconst TAB_ACTIVE = 'border-b-accent text-accent hover:border-b-accent';\nconst TAB_INACTIVE = 'border-b-transparent';\n\nconst tabClass = (active: boolean, enabled = true): string =>\n `${TAB_BASE} ${active ? TAB_ACTIVE : TAB_INACTIVE} ${enabled ? '' : 'cursor-not-allowed opacity-50'}`;\n\n// ── a single command button (icon / icon+label / label=tab) ──────────────────\nfunction CommandButton({\n cmd,\n variant,\n run,\n}: {\n cmd: ResolvedCommand;\n variant: string;\n run: () => void;\n}) {\n const isTab = variant === 'label';\n\n // v2 buttons carry NO caret — a menu command is a plain icon button; the\n // `menu:` declaration still drives aria-haspopup and the anchored popover.\n const button = (\n <button\n type=\"button\"\n onClick={run}\n disabled={!cmd.enabled}\n aria-pressed={cmd.active || undefined}\n aria-haspopup={cmd.menu ? 'menu' : undefined}\n aria-label={cmd.label}\n title={cmd.label}\n // Shadow parts — the RESTYLE door: page CSS reaches these via\n // `embedpdf-viewer::part(toolbar-button)` etc. Part names are public\n // API; the vocabulary is deliberately small (see README).\n part={\n isTab\n ? `mode-tab${cmd.active ? ' mode-tab-active' : ''}`\n : `toolbar-button${cmd.active ? ' toolbar-button-active' : ''}`\n }\n className={isTab ? tabClass(cmd.active, cmd.enabled) : buttonClass(cmd.active, cmd.enabled)}\n >\n {isTab ? (\n <span className=\"whitespace-nowrap px-1\">{cmd.label}</span>\n ) : variant === 'icon+label' ? (\n <span className=\"flex items-center whitespace-nowrap text-sm\">\n {cmd.icon && (\n <Icon name={cmd.icon} size={20} accent={cmd.iconAccent} className=\"mr-1.5 shrink-0\" />\n )}\n <span>{cmd.label}</span>\n </span>\n ) : cmd.icon ? (\n <Icon name={cmd.icon} size={20} accent={cmd.iconAccent} />\n ) : (\n <span className=\"text-sm\">{cmd.label}</span>\n )}\n </button>\n );\n\n if (!cmd.menu) return button;\n return <MenuAnchoredButton cmd={cmd}>{button}</MenuAnchoredButton>;\n}\n\nfunction MenuAnchoredButton({\n cmd,\n children,\n}: {\n cmd: ResolvedCommand;\n children: React.ReactNode;\n}) {\n const menus = useMenus();\n const open = cmd.menu ? menus.isOpen(cmd.menu) : false;\n return (\n <span className=\"relative inline-flex\">\n {children}\n {open && cmd.menu && (\n <Popover onClose={() => menus.close(cmd.menu!)}>\n <MenuBody menuId={cmd.menu} onRun={() => menus.close(cmd.menu!)} />\n </Popover>\n )}\n </span>\n );\n}\n\n// ── the inline zoom widget — v2's custom-zoom-toolbar, 1:1 ───────────────────\nfunction ZoomControls() {\n const commands = useCommands();\n const menus = useMenus();\n const stage = useOptionalCapability(StageToken);\n // Null-safe: the zoom strip is main-toolbar chrome, mounted before any\n // document exists — it reads 100% until a Stage is there to ask.\n const level = useOptionalSelector(StageToken, (c) => c.zoomLevel(), 1);\n const pct = Math.round((level ?? 1) * 100);\n const [inputValue, setInputValue] = useState(String(pct));\n useEffect(() => setInputValue(String(pct)), [pct]);\n\n const submit = (e: React.FormEvent) => {\n e.preventDefault();\n const value = parseFloat(inputValue);\n if (!isNaN(value) && value > 0) stage?.zoomTo({ level: value / 100 });\n };\n\n return (\n <div className=\"relative\">\n <div className=\"bg-hover flex items-center rounded\">\n {/* editable zoom percentage */}\n <form\n onSubmit={submit}\n className=\"flex min-w-0 flex-nowrap items-center overflow-hidden whitespace-nowrap\"\n >\n <input\n name=\"zoom\"\n type=\"text\"\n inputMode=\"numeric\"\n pattern=\"\\d*\"\n aria-label=\"Set zoom\"\n className=\"h-6 w-8 min-w-0 shrink border-0 bg-transparent p-0 text-right text-sm outline-none focus:outline-none\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value.replace(/[^0-9]/g, ''))}\n onBlur={() => {\n if (!inputValue || parseFloat(inputValue) <= 0) setInputValue(String(pct));\n }}\n />\n <span className=\"shrink-0 text-sm\">%</span>\n </form>\n {/* zoom menu chevron */}\n <button\n type=\"button\"\n aria-haspopup=\"menu\"\n aria-expanded={menus.isOpen('zoom')}\n title=\"Zoom options\"\n className={buttonClass(false)}\n onClick={() => menus.toggle('zoom')}\n >\n <Icon name=\"chevronDown\" size={20} />\n </button>\n <button\n type=\"button\"\n title=\"Zoom out\"\n className={buttonClass(false)}\n onClick={() => commands.execute('zoom:out')}\n >\n <Icon name=\"zoomOut\" size={20} />\n </button>\n <button\n type=\"button\"\n title=\"Zoom in\"\n className={buttonClass(false)}\n onClick={() => commands.execute('zoom:in')}\n >\n <Icon name=\"zoomIn\" size={20} />\n </button>\n </div>\n {menus.isOpen('zoom') && (\n <Popover onClose={() => menus.close('zoom')}>\n <MenuBody menuId=\"zoom\" onRun={() => menus.close('zoom')} />\n </Popover>\n )}\n </div>\n );\n}\n\n/** The 'button' variant of the zoom slot — a single icon that opens the menu. */\nfunction ZoomButton() {\n const menus = useMenus();\n return (\n <span className=\"relative inline-flex\">\n <button\n type=\"button\"\n title=\"Zoom\"\n aria-haspopup=\"menu\"\n aria-expanded={menus.isOpen('zoom')}\n className={buttonClass(menus.isOpen('zoom'))}\n onClick={() => menus.toggle('zoom')}\n >\n <Icon name=\"zoomIn\" size={20} />\n </button>\n {menus.isOpen('zoom') && (\n <Popover onClose={() => menus.close('zoom')}>\n <MenuBody menuId=\"zoom\" onRun={() => menus.close('zoom')} />\n </Popover>\n )}\n </span>\n );\n}\n\n// ── a shed group's in-strip disclosure (v2's overflow-tabs-button, derived) ──\nfunction GroupTrigger({ view }: { view: GroupDisclosureView }) {\n const [open, setOpen] = useState(false);\n // The active tab may be hiding behind the chevron — hint at it, tab-style.\n const activeHidden = view.commands.some((c) => c.active);\n return (\n <span className=\"relative inline-flex\">\n <button\n type=\"button\"\n onClick={() => setOpen((o) => !o)}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n className={tabClass(activeHidden)}\n >\n <Icon name=\"chevronDown\" size={18} />\n </button>\n {open && (\n <Popover onClose={() => setOpen(false)}>\n <div className=\"min-w-44 p-1\">\n {view.commands.map((c) => (\n <button\n key={c.id}\n type=\"button\"\n role={view.role === 'tabs' ? 'menuitemradio' : 'menuitem'}\n aria-checked={view.role === 'tabs' ? c.active : undefined}\n disabled={!c.enabled}\n onClick={() => {\n view.execute(c.id);\n setOpen(false);\n }}\n className={`flex w-full items-center gap-2 rounded-md px-2.5 py-1.5 text-left text-sm disabled:cursor-not-allowed disabled:opacity-50 ${\n c.active ? 'bg-selected text-accent' : 'text-fg-secondary hover:bg-hover'\n }`}\n >\n {c.label}\n </button>\n ))}\n </div>\n </Popover>\n )}\n </span>\n );\n}\n\n// ── the collapsed modes group — v2's mode-select-button, 1:1 ─────────────────\nfunction CollapsedModes({ view }: { view: CollapsedGroupView }) {\n const [open, setOpen] = useState(false);\n const active = view.commands.find((c) => c.active) ?? view.commands[0];\n // v2 highlights the control whenever a non-default mode is active.\n const isActive = Boolean(active?.active && active.id !== 'mode:view');\n return (\n <div style={{ width: 100 }} className=\"relative\">\n <button\n type=\"button\"\n onClick={() => setOpen((o) => !o)}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n className=\"bg-surface hover:bg-hover flex w-full cursor-pointer appearance-none items-center rounded-md py-1.5 pl-3 pr-2 text-[13px] transition-colors\"\n >\n <span\n className={`min-w-0 flex-1 truncate text-left ${isActive ? 'text-accent' : 'text-fg'}`}\n >\n {active?.label}\n </span>\n <Icon\n name=\"chevronDown\"\n size={16}\n className={isActive ? 'text-accent' : 'text-fg-secondary'}\n />\n </button>\n {open && (\n <Popover onClose={() => setOpen(false)}>\n <div className=\"min-w-44 p-1\">\n {view.commands.map((c) => (\n <button\n key={c.id}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={c.active}\n onClick={() => {\n view.execute(c.id);\n setOpen(false);\n }}\n className={`flex w-full items-center gap-2 rounded-md px-2.5 py-1.5 text-left text-sm ${\n c.active ? 'bg-selected text-accent' : 'text-fg-secondary hover:bg-hover'\n }`}\n >\n {c.label}\n </button>\n ))}\n </div>\n </Popover>\n )}\n </div>\n );\n}\n\n// ── the derived overflow menu ────────────────────────────────────────────────\nfunction OverflowMenu({ view }: { view: OverflowMenuView }) {\n const t = useT();\n if (!view.isOpen) return null;\n return (\n <Popover onClose={view.close} align=\"end\">\n <div className=\"min-w-56 p-1\">\n {view.sections.map((section, i) => (\n <div key={i}>\n {i > 0 && <div className=\"bg-border-subtle my-1 h-px\" />}\n {section.labelKey && (\n <div className=\"text-fg-muted px-2.5 pb-1 pt-1.5 text-[11px] font-semibold uppercase tracking-wide\">\n {t(section.labelKey)}\n </div>\n )}\n {section.rows.map((row) => {\n const cmd = view.resolve(row.command);\n if (!cmd) return null;\n if (row.type === 'submenu') {\n return <InlineSubmenu key={row.command} menuId={row.menu} label={cmd.label} />;\n }\n return (\n <button\n key={row.command}\n type=\"button\"\n role={section.role === 'radio' ? 'menuitemradio' : 'menuitem'}\n aria-checked={section.role === 'radio' ? cmd.active : undefined}\n disabled={!cmd.enabled}\n onClick={() => {\n view.execute(row.command);\n view.close();\n }}\n // Same blue-highlight selection as the dropdown menus — no\n // checkmark; the icon column stays the command's own icon.\n className={`flex w-full items-center gap-3 rounded-md px-2.5 py-1.5 text-left text-sm transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${\n cmd.active ? 'bg-selected text-accent' : 'text-fg-secondary hover:bg-hover'\n }`}\n >\n {cmd.icon && (\n <Icon name={cmd.icon} size={16} className={cmd.active ? '' : 'text-fg-muted'} />\n )}\n <span className=\"flex-1 truncate\">{cmd.label}</span>\n </button>\n );\n })}\n </div>\n ))}\n </div>\n </Popover>\n );\n}\n\nfunction OverflowTrigger({ isOpen, toggle }: { isOpen: boolean; toggle: () => void }) {\n const t = useT();\n return (\n <button\n type=\"button\"\n onClick={toggle}\n aria-haspopup=\"menu\"\n aria-expanded={isOpen}\n title={t('demo.more')}\n className={buttonClass(isOpen)}\n >\n <Icon name=\"dots\" size={20} />\n </button>\n );\n}\n\n// ── the assembled toolbar ────────────────────────────────────────────────────\nexport function AppToolbar({ bar, className }: { bar: BarSchema; className?: string }) {\n return (\n <Toolbar\n bar={bar}\n gap={8} // v2 toolbar gap-2\n separatorWidth={1}\n className={className}\n renderCommand={(cmd, variant, run) => <CommandButton cmd={cmd} variant={variant} run={run} />}\n renderCustom={{\n 'zoom-controls': (variant) => (variant === 'inline' ? <ZoomControls /> : <ZoomButton />),\n 'quick-stamps': () => <QuickStamps />,\n }}\n renderCollapsed={(view) => (view.id === 'modes' ? <CollapsedModes view={view} /> : undefined)}\n renderGroupTrigger={(view) => <GroupTrigger view={view} />}\n renderSeparator={() => <span className=\"bg-border h-6 w-px self-center\" />}\n renderOverflowTrigger={(isOpen, toggle) => (\n <OverflowTrigger isOpen={isOpen} toggle={toggle} />\n )}\n renderOverflowMenu={(view) => <OverflowMenu view={view} />}\n />\n );\n}\n","/**\n * The configured annotation fonts (`annotations.fonts`), loaded once per\n * viewer: fetch the bytes → register them on the viewer's engine under the\n * key (what a free-text `fontFamily` carries and what the engine embeds) →\n * mount the same bytes as a `@font-face` named by that key (what the plugin's\n * `cssFontFamily` emits for a registered font, so the live editor renders the\n * face the appearance stream will bake). The style panel lists a font only\n * once BOTH have happened — an offered key always resolves on write.\n */\nimport { createContext, useContext, useEffect, useState, type ReactNode } from 'react';\nimport { useKernel } from '@embedpdf/react/runtime';\nimport { mountWebFont } from '@embedpdf/web';\nimport { useAnnotationsConfig } from '../config-context';\n\nexport interface LoadedAnnotationFont {\n readonly key: string;\n readonly label: string;\n}\n\nconst LoadedFontsContext = createContext<readonly LoadedAnnotationFont[]>([]);\n\nexport function AnnotationFontsProvider({ children }: { children: ReactNode }) {\n const kernel = useKernel();\n const { fonts } = useAnnotationsConfig();\n const [loaded, setLoaded] = useState<readonly LoadedAnnotationFont[]>([]);\n\n useEffect(() => {\n const engineFonts = kernel.engine.fonts;\n // The cloud engine registers no fonts (a server policy), so a key could\n // never resolve on write: offer nothing rather than a font that fails.\n if (!fonts?.length || !engineFonts) return;\n let cancelled = false;\n const unmounts: Array<() => void> = [];\n void (async () => {\n for (const font of fonts) {\n try {\n const response = await fetch(font.url);\n if (!response.ok) throw new Error(`${font.url}: HTTP ${response.status}`);\n const bytes = new Uint8Array(await response.arrayBuffer());\n if (cancelled) return;\n await engineFonts.register({\n key: font.key,\n familyName: font.familyName,\n weight: font.weight,\n italic: font.italic,\n data: bytes,\n });\n const unmount = await mountWebFont(font.key, bytes, {\n weight: font.weight,\n style: font.italic ? 'italic' : 'normal',\n });\n if (cancelled) {\n unmount();\n return;\n }\n unmounts.push(unmount);\n setLoaded((prev) =>\n prev.some((f) => f.key === font.key)\n ? prev\n : [...prev, { key: font.key, label: font.label }],\n );\n } catch (error) {\n console.warn(`[embedpdf] annotation font \"${font.key}\" was not loaded:`, error);\n }\n }\n })();\n return () => {\n cancelled = true;\n for (const unmount of unmounts) unmount();\n };\n }, [kernel, fonts]);\n\n return <LoadedFontsContext.Provider value={loaded}>{children}</LoadedFontsContext.Provider>;\n}\n\n/** The configured fonts that are registered AND mounted, in config order. */\nexport function useAnnotationFonts(): readonly LoadedAnnotationFont[] {\n return useContext(LoadedFontsContext);\n}\n","/**\n * The link editor POPOVER — v2's \"add a link\" popup, reborn. It rides the\n * SAME selection anchor as the action strip (`<AnnotationMenu>` solves\n * WHERE), opening from the strip's link icon (`annotation:link` toggles the\n * `link-editor` shell surface) and rendering IN PLACE of the strip while\n * open — one anchored card at a time.\n *\n * Reads the selection's current target from selection props (the `linkOf`\n * lens — parents derive from their committed child annotations) and writes\n * through the ONE `updateSelection({ link })` path; the plugin's reconciler\n * materializes/retargets the attached children. Links are a VERB on the\n * selection, not a style — which is why this is a popover, not a sidebar\n * section.\n */\nimport { useState, type ReactNode } from 'react';\nimport { useAnnotation, useSelectionProps } from '@embedpdf/react/annotation';\nimport type { PdfLinkTarget } from '@embedpdf/react/link';\nimport { useKernel } from '@embedpdf/react/runtime';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\n\nfunction ModeToggle({\n active,\n title,\n onClick,\n children,\n}: {\n active: boolean;\n title: string;\n onClick: () => void;\n children: ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n title={title}\n onClick={onClick}\n className={`rounded border px-2.5 py-1 text-xs font-medium transition-colors ${\n active\n ? 'border-accent bg-accent text-on-accent'\n : 'border-border bg-surface text-fg hover:bg-hover'\n }`}\n >\n {children}\n </button>\n );\n}\n\nexport function LinkEditorCard({ onClose }: { onClose: () => void }) {\n const t = useT();\n const kernel = useKernel();\n const anno = useAnnotation();\n const props = useSelectionProps();\n const value = (props.values.link ?? null) as PdfLinkTarget | null;\n const [mode, setMode] = useState<'uri' | 'page'>(value?.kind === 'goto' ? 'page' : 'uri');\n const [uri, setUri] = useState(value?.kind === 'uri' ? value.uri : '');\n const [pageNo, setPageNo] = useState('1');\n\n const apply = () => {\n if (mode === 'uri') {\n const trimmed = uri.trim();\n if (!trimmed) return;\n anno.updateSelection({ link: { kind: 'uri', uri: trimmed } });\n onClose();\n return;\n }\n // Page number (1-based) → the page's OBJECT NUMBER (stable across moves).\n const activeId = kernel.documents.activeId();\n const meta = activeId ? kernel.getState().core.documents[activeId] : null;\n const layout = meta?.pages[Math.max(0, Number(pageNo) - 1)];\n if (!layout) return;\n anno.updateSelection({\n link: { kind: 'goto', destination: { kind: 'fit', pageObjectNumber: layout.pageObjectNumber } },\n });\n onClose();\n };\n\n const inputCls =\n 'border-border bg-surface text-fg focus:border-accent w-full rounded border px-2.5 py-1.5 text-sm outline-none';\n return (\n <div className=\"border-border bg-surface w-64 rounded-lg border p-3 shadow-lg\">\n <div className=\"mb-2 flex items-center justify-between\">\n <span className=\"text-fg text-sm font-semibold\">{t('commands.annotate.link')}</span>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"text-fg-muted hover:bg-hover grid h-6 w-6 place-items-center rounded\"\n >\n <Icon name=\"x\" size={14} />\n </button>\n </div>\n <div className=\"mb-2 flex gap-1.5\">\n <ModeToggle title=\"Link to a URL\" active={mode === 'uri'} onClick={() => setMode('uri')}>\n URL\n </ModeToggle>\n <ModeToggle title=\"Link to a page\" active={mode === 'page'} onClick={() => setMode('page')}>\n Page\n </ModeToggle>\n </div>\n {mode === 'uri' ? (\n <input\n type=\"url\"\n className={inputCls}\n placeholder=\"https://…\"\n autoFocus\n value={uri}\n onChange={(e) => setUri(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && apply()}\n />\n ) : (\n <input\n type=\"number\"\n min={1}\n className={inputCls}\n placeholder=\"Page number\"\n autoFocus\n value={pageNo}\n onChange={(e) => setPageNo(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && apply()}\n />\n )}\n <button\n type=\"button\"\n className=\"bg-accent text-on-accent mt-2.5 w-full rounded px-2 py-1.5 text-sm font-medium\"\n onClick={apply}\n >\n {value == null ? 'Add link' : 'Update link'}\n </button>\n </div>\n );\n}\n","/**\n * The floating strip's PIXELS, shared by every contextual strip (annotation\n * selection, text selection, …): a rounded toolbar of command buttons with\n * derived group separators. The WHERE is each strip's menu component\n * (`<AnnotationMenu>`, `<SelectionMenu>`); the WHICH is the commands'\n * `visible`/`enabled` derivations via `useStripView`. This file only draws.\n */\nimport { Fragment } from 'react';\nimport type { ResolvedCommand } from '@embedpdf/react/commands';\nimport type { useStripView } from '@embedpdf/react/toolbar';\nimport { buttonClass } from './toolbar';\nimport { Icon } from './icons';\n\nfunction StripButton({ cmd, run }: { cmd: ResolvedCommand; run: () => void }) {\n return (\n <button\n type=\"button\"\n onClick={run}\n disabled={!cmd.enabled}\n aria-pressed={cmd.active || undefined}\n aria-label={cmd.label}\n title={cmd.label}\n className={buttonClass(cmd.active, cmd.enabled)}\n >\n {cmd.icon && <Icon name={cmd.icon} size={20} accent={cmd.iconAccent} />}\n </button>\n );\n}\n\nexport function StripBar({\n view,\n label,\n}: {\n view: NonNullable<ReturnType<typeof useStripView>>;\n label: string;\n}) {\n return (\n <div\n role=\"toolbar\"\n aria-label={label}\n className=\"border-border-subtle bg-elevated flex items-center gap-1 rounded-lg border p-1 shadow-xl\"\n >\n {view.groups.map((g, i) => (\n <Fragment key={g.id}>\n {i > 0 && <span aria-hidden className=\"bg-border h-5 w-px\" />}\n {g.commands.map((cmd) => (\n <StripButton key={cmd.id} cmd={cmd} run={() => view.execute(cmd.id)} />\n ))}\n </Fragment>\n ))}\n </div>\n );\n}\n","/**\n * The ANNOTATION-selection floating strip:\n *\n * config/chrome.ts `strips.annotation` declares WHAT may appear\n * each command's visible/enabled decides WHICH items show\n * <AnnotationMenu> solves WHERE (camera transform,\n * rotate-knob dodging, pointer isolation)\n *\n * useStripView is the live intersection: hidden commands drop out, empty\n * groups vanish, null when nothing applies. Mounted in the Stage `overlay`\n * slot. The pixels are the shared <StripBar>.\n */\nimport { useEffect } from 'react';\nimport { AnnotationMenu } from '@embedpdf/react/annotation-menu';\nimport { useAnnotationSelection } from '@embedpdf/react/annotation';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useStripView } from '@embedpdf/react/toolbar';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useStripSchema } from '../config-context';\nimport { LinkEditorCard } from './link-editor';\nimport { StripBar } from './strip-bar';\n\nexport function AnnotationStrip() {\n const t = useT();\n const view = useStripView(useStripSchema('annotation'));\n // The link editor popover rides the SAME anchor and REPLACES the strip\n // while open — one anchored card at a time (v2's popup, on the projector).\n const editor = useSurface('link-editor');\n const selection = useAnnotationSelection();\n // A stale editor never outlives its selection.\n useEffect(() => {\n if (!selection.length && editor.isOpen) editor.close();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selection.length, editor.isOpen]);\n if (!view) return null;\n return (\n <AnnotationMenu placement=\"bottom\" gap={15}>\n {editor.isOpen ? (\n <LinkEditorCard onClose={editor.close} />\n ) : (\n <StripBar view={view} label={t('commands.annotate.strip')} />\n )}\n </AnnotationMenu>\n );\n}\n","/**\n * The TEXT-SELECTION floating strip:\n *\n * config/chrome.ts `strips.selection` declares WHAT may appear\n * each command's visible/enabled decides WHICH items show\n * <SelectionMenu> solves WHERE (settles on pointer-up,\n * camera transform, pointer isolation)\n *\n * `useStripView` is the live intersection: with copy denied (no\n * doc.text.copy) every command drops out and this renders nothing — no\n * empty bubble. Mounted in the Stage `overlay` slot.\n */\nimport { SelectionMenu } from '@embedpdf/react/selection';\nimport { useStripView } from '@embedpdf/react/toolbar';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useStripSchema } from '../config-context';\nimport { StripBar } from './strip-bar';\n\nexport function SelectionStrip() {\n const t = useT();\n const view = useStripView(useStripSchema('selection'));\n if (!view) return null;\n return (\n <SelectionMenu placement=\"bottom\" gap={12}>\n <StripBar view={view} label={t('commands.selection.strip')} />\n </SelectionMenu>\n );\n}\n","/**\n * The document tab bar — a 1:1 port of v2's tab-bar.tsx\n * (viewers/snippet/src/components/tab-bar.tsx): rounded-top tabs on the\n * surface-alt strip, the active tab merging into the toolbar surface below,\n * close-× on the active tab, and a + button opening a real file dialog.\n *\n * v2 needed a DocumentManager capability; here the kernel's document registry\n * (useDocuments) already is the tab model — open/close/setActive, reactive.\n */\nimport { useRef } from 'react';\nimport { useDocuments } from '@embedpdf/react/runtime';\nimport type { OpenInput } from '@embedpdf/react/runtime';\nimport { Icon } from './icons';\n\nexport type TabBarVisibility = 'always' | 'multiple' | 'never';\n\nexport function TabBar({\n visibility = 'always',\n allowOpenFile = true,\n}: {\n visibility?: TabBarVisibility;\n allowOpenFile?: boolean;\n}) {\n const { docs, activeId, setActive, close, open } = useDocuments();\n const fileInput = useRef<HTMLInputElement>(null);\n\n const shouldShow = visibility === 'always' || (visibility === 'multiple' && docs.length > 1);\n if (!shouldShow) return null;\n\n const openFile = async (file: File) => {\n const bytes = new Uint8Array(await file.arrayBuffer());\n const source: OpenInput = { kind: 'bytes', id: `${file.name}-${Date.now()}`, bytes };\n await open(source, { name: file.name });\n };\n\n return (\n <div className=\"bg-surface-alt flex items-end pr-2 pt-2\">\n <div className=\"flex flex-1 items-end overflow-x-auto pl-4\">\n {docs.map((doc) => {\n const isActive = activeId === doc.id;\n return (\n <div\n key={doc.id}\n onClick={() => setActive(doc.id)}\n role=\"tab\"\n part={isActive ? 'tab tab-active' : 'tab'}\n tabIndex={0}\n aria-selected={isActive}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setActive(doc.id);\n }\n }}\n className={`group relative flex min-w-[120px] max-w-[240px] cursor-pointer items-center gap-2 rounded-t-lg px-4 py-2 text-sm font-medium transition-all ${\n isActive\n ? 'bg-surface text-fg z-10'\n : 'bg-surface-alt text-fg-secondary hover:bg-hover hover:text-fg'\n }`}\n >\n {/* lifecycle glyphs — the tab exists from the moment open()\n was called; these show what its document is doing */}\n {doc.status === 'loading' && (\n <span\n className=\"border-border-subtle border-t-accent h-3 w-3 flex-shrink-0 animate-spin rounded-full border\"\n aria-label=\"Loading\"\n />\n )}\n {doc.status === 'locked' && (\n <Icon name=\"lock\" size={13} className=\"text-fg-muted flex-shrink-0\" />\n )}\n {doc.status === 'error' && (\n <Icon name=\"alertTriangle\" size={13} className=\"flex-shrink-0 text-red-500\" />\n )}\n <span className=\"min-w-0 flex-1 truncate\">\n {doc.name ?? `Document ${doc.id.slice(0, 8)}`}\n </span>\n\n {/* close — on the active tab, and never the last document\n (an empty workspace is designable, but not this demo's goal) */}\n {isActive && docs.length > 1 && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n void close(doc.id);\n }}\n aria-label={`Close ${doc.name ?? 'document'}`}\n className=\"hover:bg-hover flex-shrink-0 cursor-pointer rounded-full p-1 opacity-100 transition-all\"\n >\n <Icon name=\"x\" size={14} />\n </button>\n )}\n </div>\n );\n })}\n\n {allowOpenFile && (\n <>\n <button\n type=\"button\"\n onClick={() => fileInput.current?.click()}\n aria-label=\"Open File\"\n title=\"Open File\"\n className=\"text-fg-secondary hover:bg-hover hover:text-fg mb-1.5 ml-1 flex-shrink-0 cursor-pointer rounded p-1.5 transition-colors\"\n >\n <Icon name=\"plus\" size={14} />\n </button>\n <input\n ref={fileInput}\n type=\"file\"\n accept=\".pdf,application/pdf\"\n className=\"hidden\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (file) void openFile(file);\n e.target.value = '';\n }}\n />\n </>\n )}\n </div>\n </div>\n );\n}\n","/**\n * THIS viewer's armed-tool cursor: the toolbar's own icon riding the pointer\n * as a real CSS cursor (OS-composited — zero lag, unlike any DOM follower).\n * The library owns arbitration (unmapped hover claims win, page gaps fall\n * back to the arrow — see `useToolCursor`); this module only decides what the\n * cursor LOOKS like. It reuses the SAME icon set and the SAME accent\n * derivation as the toolbar buttons (TOOL_ICONS is recorded by the command\n * definitions), so the cursor is pixel-identical to the button the user just\n * pressed — recolor the tool and both follow. A tool without a command icon\n * keeps its declared keyword cursor.\n *\n * ONE table decides the shape ({@link GLYPHS}): cursor KEYWORDS are the\n * affordances — a tool declares its base ('crosshair' to draw, 'copy' to\n * place), the selection handler claims 'text' over text — and each mapped\n * keyword is redrawn as its glyph + the tool's icon. Keywords the table omits\n * stay native: a markup tool's 'default' base is the bare arrow (identity\n * appears exactly where the action is possible — over text), a foreign 'move'\n * over an annotation drops the icon. A new tool gets the right cursor from\n * what it declares; nothing tool-specific lives here.\n *\n * The image: a white-haloed glyph at the hotspot (readable on any page color)\n * with the icon at its top right — 40px, under the 128px cursor ceiling;\n * Chromium may briefly show the default arrow when a >32px cursor would\n * overlap browser UI (anti-spoofing), which is fine mid-viewport.\n */\nimport { useToolCursor, useTool } from '@embedpdf/react/interaction';\nimport { useAnnotationDefaults } from '@embedpdf/react/annotation';\nimport { TOOL_ICONS } from '../config/commands';\nimport { ICON_PATHS } from './icons';\nimport type { IconAccent } from './icons';\n\nconst SIZE = 40;\nconst HOTSPOT = { x: 8, y: 28 };\nconst INK = '#1a1a1a';\nconst HALO = '#ffffff';\n/** The drag-and-drop \"will place a copy\" green (Chrome's DnD badge). */\nconst PLACE_GREEN = '#34a853';\n\n/** The icon's paths as SVG markup — the string twin of `<Icon>`'s render loop\n * (same fill/stroke slot rules), with a white halo pass underneath so the\n * glyph stays readable over page content. */\nfunction iconGlyph(name: string, accent?: IconAccent): string | null {\n const paths = ICON_PATHS[name];\n if (!paths) return null;\n const halo: string[] = [];\n const draw: string[] = [];\n for (const p of paths) {\n const spec = typeof p === 'string' ? { d: p, fill: undefined, stroke: undefined } : p;\n // Slot rules, mirrored from <Icon>: a fill slot paints from the accent\n // (nothing without one), a stroke slot falls back to the ink, and a\n // fill-only path never gets an outline.\n const fill = spec.fill === true ? INK : spec.fill ? accent?.[spec.fill] : undefined;\n const stroke = spec.stroke ? (accent?.[spec.stroke] ?? INK) : spec.fill ? 'none' : INK;\n halo.push(`<path d=\"${spec.d}\" fill=\"none\" stroke=\"${HALO}\" stroke-width=\"3.5\"/>`);\n draw.push(`<path d=\"${spec.d}\" fill=\"${fill ?? 'none'}\" stroke=\"${stroke}\"/>`);\n }\n return halo.join('') + draw.join('');\n}\n\n/** The action glyph drawn at the hotspot: what a click DOES here. */\ntype Glyph = 'crosshair' | 'ibeam' | 'plus';\n\nconst haloed = (x1: number, y1: number, x2: number, y2: number): string =>\n `<line x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"${HALO}\" stroke-width=\"3\"/>` +\n `<line x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"${INK}\" stroke-width=\"1.25\"/>`;\n\nfunction actionGlyph(glyph: Glyph): string {\n const { x, y } = HOTSPOT;\n if (glyph === 'crosshair') {\n return haloed(x, y - 6, x, y + 6) + haloed(x - 6, y, x + 6, y);\n }\n if (glyph === 'ibeam') {\n return (\n haloed(x, y - 6.5, x, y + 6.5) +\n haloed(x - 2.5, y - 6.5, x + 2.5, y - 6.5) +\n haloed(x - 2.5, y + 6.5, x + 2.5, y + 6.5)\n );\n }\n // plus: the DnD copy affordance — green disc, white plus.\n return (\n `<circle cx=\"${x}\" cy=\"${y}\" r=\"7.5\" fill=\"${PLACE_GREEN}\" stroke=\"${HALO}\" stroke-width=\"1.5\"/>` +\n `<line x1=\"${x}\" y1=\"${y - 3.5}\" x2=\"${x}\" y2=\"${y + 3.5}\" stroke=\"${HALO}\" stroke-width=\"2\"/>` +\n `<line x1=\"${x - 3.5}\" y1=\"${y}\" x2=\"${x + 3.5}\" y2=\"${y}\" stroke=\"${HALO}\" stroke-width=\"2\"/>`\n );\n}\n\nfunction cursorSvg(glyph: Glyph, icon: string, accent?: IconAccent): string {\n const g = iconGlyph(icon, accent);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${SIZE}\" height=\"${SIZE}\" ` +\n `viewBox=\"0 0 ${SIZE} ${SIZE}\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\">` +\n actionGlyph(glyph) +\n (g\n ? `<g transform=\"translate(17 3) scale(${(20 / 24).toFixed(4)})\" stroke-width=\"2\">${g}</g>`\n : '') +\n `</svg>`\n );\n}\n\n/** keyword → glyph: how each affordance is drawn when a tool icon rides\n * along. Draw tools declare 'crosshair', place tools (stamp/signature/image)\n * declare 'copy', and the selection handler claims 'text' over text — which\n * keywords ever SHOW is decided by those declarations and claims, never\n * here. 'default' is deliberately absent: the bare arrow means \"no action\n * here\", so it never carries an icon. */\nconst GLYPHS: Record<string, Glyph> = {\n crosshair: 'crosshair',\n text: 'ibeam',\n copy: 'plus',\n};\n\n/** Mount once (renders nothing): keeps the armed tool's cursor skin in sync\n * with its toolbar icon + live defaults. */\nexport function ArmedToolCursor() {\n const { activeToolId } = useTool();\n // Live accent: a `setDefaults` recolor re-renders us and rebuilds the cursor.\n const d = useAnnotationDefaults(activeToolId);\n const entry = TOOL_ICONS[activeToolId];\n const accent = entry?.accent\n ? {\n primary: d[entry.accent.primary] ?? undefined,\n secondary: entry.accent.secondary ? (d[entry.accent.secondary] ?? undefined) : undefined,\n }\n : undefined;\n useToolCursor(\n entry\n ? {\n toolId: activeToolId,\n cursors: Object.fromEntries(\n Object.entries(GLYPHS).map(([keyword, glyph]) => [\n keyword,\n { svg: cursorSvg(glyph, entry.icon, accent), hotspot: HOTSPOT },\n ]),\n ),\n }\n : null,\n );\n return null;\n}\n","/**\n * The annotation FLAGS section — a live test surface for `/F` (ISO 32000\n * Table 167). Select any annotation(s) and toggle flags; the writes go through\n * the plugin's `updateSelectionFlags` (optimistic, flags-only engine patch),\n * and the reads come from `useSelectionFlags` (per-flag value, `null` when the\n * selection disagrees → indeterminate checkbox).\n *\n * Things to try:\n * - `locked`: the selection keeps its outline but loses handles/knob; move,\n * restyle and delete are refused; unchecking it here still works.\n * - `hidden` / `noView`: the annotation disappears (it stays selected, so\n * this panel can bring it back).\n * - `readOnly`: visible but no longer clickable — deselect and try.\n * - `noZoom` / `noRotate`: zoom or rotate the page; the body keeps its\n * screen size / stays upright, anchored at its top-left corner.\n * - `print`: flip it off and print/flatten elsewhere — the annotation is\n * excluded (viewer rendering is unaffected).\n */\nimport { useAnnotation, useSelectionFlags, type AnnotationFlags } from '@embedpdf/react/annotation';\nimport { useEffect, useRef } from 'react';\n\nconst FLAG_ROWS: { key: keyof AnnotationFlags; label: string; hint: string }[] = [\n { key: 'print', label: 'Print', hint: 'Include when the page is printed' },\n { key: 'hidden', label: 'Hidden', hint: 'Gone everywhere: screen, clicks, print' },\n { key: 'noView', label: 'No view', hint: 'Hidden on screen, may still print' },\n {\n key: 'toggleNoView',\n label: 'Toggle no view',\n hint: 'Reveal a no-view annotation while selected',\n },\n { key: 'readOnly', label: 'Read only', hint: 'Visible but not clickable' },\n { key: 'locked', label: 'Locked', hint: 'No move / resize / delete / restyle' },\n { key: 'lockedContents', label: 'Locked contents', hint: 'Text cannot change; geometry can' },\n { key: 'noZoom', label: 'No zoom', hint: 'Screen-constant size (anchored top-left)' },\n { key: 'noRotate', label: 'No rotate', hint: 'Stays upright when the page rotates' },\n { key: 'invisible', label: 'Invisible', hint: 'Legacy: hide unknown subtypes' },\n];\n\nfunction FlagRow({\n label,\n hint,\n value,\n onToggle,\n}: {\n label: string;\n hint: string;\n value: boolean | null;\n onToggle: (next: boolean) => void;\n}) {\n const ref = useRef<HTMLInputElement>(null);\n // `null` = the selected annotations disagree → the native indeterminate state.\n useEffect(() => {\n if (ref.current) ref.current.indeterminate = value === null;\n }, [value]);\n return (\n <label className=\"hover:bg-hover flex cursor-pointer items-start gap-2.5 rounded px-1.5 py-1.5\">\n <input\n ref={ref}\n type=\"checkbox\"\n className=\"accent-accent mt-0.5\"\n checked={value === true}\n onChange={() => onToggle(value !== true)}\n />\n <span className=\"min-w-0\">\n <span className=\"text-fg block text-sm leading-tight\">{label}</span>\n <span className=\"text-fg-muted block text-xs leading-tight\">{hint}</span>\n </span>\n </label>\n );\n}\n\n/** The `/F` flags of the current selection, live-editable. Renders nothing\n * when nothing is selected (the style panel shows its tool defaults then). */\nexport function AnnotationFlagsSection() {\n const annotation = useAnnotation();\n const flags = useSelectionFlags();\n if (!flags) return null;\n return (\n <section className=\"border-border mt-2 border-t pt-4\">\n <p className=\"text-fg-muted mb-2 text-[11px] font-semibold uppercase tracking-wide\">\n Flags (/F)\n </p>\n <div className=\"flex flex-col\">\n {FLAG_ROWS.map((row) => (\n <FlagRow\n key={row.key}\n label={row.label}\n hint={row.hint}\n value={flags[row.key]}\n onToggle={(next) => annotation.updateSelectionFlags({ [row.key]: next })}\n />\n ))}\n </div>\n </section>\n );\n}\n","/**\n * The annotation style panel — the v2 snippet's style sidebar, rebuilt the v3\n * way. The plugin owns the schema AND the state; this file owns only how each\n * PropSpec renders and the flat patch it writes back. There is NO per-subtype\n * branching here: a new annotation kind that declares its `PropSpec[]` in the\n * kind table gets a working style panel for free.\n *\n * Data flow (mirrors examples/react's AnnotationSidebar):\n * selection present → useSelectionProps() specs/values, write updateSelection()\n * nothing selected → propsForTool(tool) specs + useAnnotationDefaults(tool)\n * values, write setDefaults(tool, …)\n *\n * The look is ported 1:1 from viewers/snippet's annotation-sidebar (six-column\n * swatch grid, range slider, SVG stroke / line-ending dropdowns, font-size\n * combo, align toggles), retinted from v2's `bg-bg-input`/`text-fg-primary`\n * tokens to this app's semantic ones (bg-surface / text-fg / border-border …).\n */\nimport { useEffect, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\nimport {\n useAnnotation,\n useSelectionProps,\n useAnnotationDefaults,\n useAnnotationSelected,\n type PropKey,\n type PropSpec,\n type AnnotationPropsPatch,\n type Border,\n type BlendMode,\n type LineEnding,\n type LineEndings,\n type TextAlign,\n} from '@embedpdf/react/annotation';\nimport { useTool } from '@embedpdf/react/interaction';\nimport { useOptionalCapability } from '@embedpdf/react/runtime';\nimport { RedactionToken } from '@embedpdf/react/redaction';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\nimport { useAnnotationFonts } from './annotation-fonts';\nimport { AnnotationFlagsSection } from './annotation-flags';\n\n// ── app-level vocabulary (a viewer's decision, like v2's color presets) ──────\n// The engine schema says WHICH controls to show; these lists say what the app\n// offers inside a color / font / stroke picker.\nconst PRESET_COLORS = [\n '#000000',\n '#5f6368',\n '#e44234',\n '#ff8b00',\n '#ffd500',\n '#00cc66',\n '#00b8d9',\n '#4a90e2',\n '#9b51e0',\n '#f272c8',\n '#a0522d',\n '#ffffff',\n];\n\nconst FONT_OPTIONS: { v: string; label: string }[] = [\n { v: 'helvetica', label: 'Helvetica' },\n { v: 'helvetica-bold', label: 'Helvetica Bold' },\n { v: 'times-roman', label: 'Times Roman' },\n { v: 'courier', label: 'Courier' },\n];\n\nconst FONT_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 24, 36, 48, 72];\n\nconst BORDER_OPTS: { key: string; make: () => Border }[] = [\n { key: 'solid', make: () => ({ kind: 'solid' }) },\n { key: 'dashed-6-2', make: () => ({ kind: 'dashed', dash: [6, 2] }) },\n { key: 'dashed-3-3', make: () => ({ kind: 'dashed', dash: [3, 3] }) },\n { key: 'dashed-1-2', make: () => ({ kind: 'dashed', dash: [1, 2] }) },\n { key: 'cloudy-1', make: () => ({ kind: 'cloudy', intensity: 1 }) },\n { key: 'cloudy-2', make: () => ({ kind: 'cloudy', intensity: 2 }) },\n];\nconst borderKey = (b: Border): string =>\n b.kind === 'cloudy'\n ? `cloudy-${b.intensity >= 2 ? 2 : 1}`\n : b.kind === 'dashed'\n ? `dashed-${b.dash.join('-')}`\n : 'solid';\n\nconst LINE_ENDINGS: { v: LineEnding; label: string }[] = [\n { v: 'none', label: 'None' },\n { v: 'open-arrow', label: 'Open arrow' },\n { v: 'closed-arrow', label: 'Closed arrow' },\n { v: 'r-open-arrow', label: 'Reverse open' },\n { v: 'r-closed-arrow', label: 'Reverse closed' },\n { v: 'circle', label: 'Circle' },\n { v: 'square', label: 'Square' },\n { v: 'diamond', label: 'Diamond' },\n { v: 'butt', label: 'Butt' },\n { v: 'slash', label: 'Slash' },\n];\n\nconst BLEND_MODES: { v: BlendMode; label: string }[] = [\n { v: 'normal', label: 'Normal' },\n { v: 'multiply', label: 'Multiply' },\n { v: 'screen', label: 'Screen' },\n { v: 'overlay', label: 'Overlay' },\n { v: 'darken', label: 'Darken' },\n { v: 'lighten', label: 'Lighten' },\n { v: 'color-dodge', label: 'Color Dodge' },\n { v: 'color-burn', label: 'Color Burn' },\n { v: 'hard-light', label: 'Hard Light' },\n { v: 'soft-light', label: 'Soft Light' },\n { v: 'difference', label: 'Difference' },\n { v: 'exclusion', label: 'Exclusion' },\n { v: 'hue', label: 'Hue' },\n { v: 'saturation', label: 'Saturation' },\n { v: 'color', label: 'Color' },\n { v: 'luminosity', label: 'Luminosity' },\n];\n\n// ── layout primitives ────────────────────────────────────────────────────────\nfunction Field({\n label,\n mixed,\n children,\n}: {\n label: string;\n mixed?: boolean;\n children: ReactNode;\n}) {\n return (\n <section className=\"mb-5\">\n <label className=\"text-fg mb-2 block text-sm font-medium\">\n {label}\n {mixed && <span className=\"text-fg-muted ml-1.5 text-xs font-normal\">(mixed)</span>}\n </label>\n {children}\n </section>\n );\n}\n\n// ── color swatch grid ────────────────────────────────────────────────────────\nconst isTransparent = (c: string | null) =>\n c == null ||\n c === 'transparent' ||\n (/^#([0-9a-f]{8})$/i.test(c) && c.slice(-2).toLowerCase() === '00');\n\nfunction Swatch({\n color,\n active,\n onSelect,\n}: {\n color: string;\n active: boolean;\n onSelect: (c: string) => void;\n}) {\n const style = isTransparent(color)\n ? {\n backgroundColor: '#fff',\n backgroundImage:\n 'linear-gradient(45deg, transparent 40%, #ef4444 40%, #ef4444 60%, transparent 60%)',\n backgroundSize: '100% 100%',\n }\n : { backgroundColor: color };\n return (\n <button\n type=\"button\"\n title={color}\n onClick={() => onSelect(color)}\n className={`border-border-strong h-5 w-5 rounded-full border ${active ? 'outline-accent outline outline-2 outline-offset-2' : ''}`}\n style={style}\n />\n );\n}\n\nfunction SwatchGrid({\n value,\n onSelect,\n allowTransparent,\n}: {\n value: string | null | undefined;\n onSelect: (c: string) => void;\n allowTransparent?: boolean;\n}) {\n const active = (c: string) => c.toLowerCase() === (value ?? '').toLowerCase();\n return (\n <div className=\"grid grid-cols-6 gap-x-1 gap-y-3\">\n {PRESET_COLORS.map((c) => (\n <Swatch key={c} color={c} active={active(c)} onSelect={onSelect} />\n ))}\n {allowTransparent && (\n <Swatch color=\"transparent\" active={isTransparent(value ?? null)} onSelect={onSelect} />\n )}\n </div>\n );\n}\n\n// ── range slider ─────────────────────────────────────────────────────────────\nfunction RangeSlider({\n value,\n min,\n max,\n step,\n onChange,\n}: {\n value: number;\n min: number;\n max: number;\n step: number;\n onChange: (n: number) => void;\n}) {\n return (\n <input\n type=\"range\"\n className=\"accent-accent mb-1.5 h-1 w-full cursor-pointer\"\n value={value}\n min={min}\n max={max}\n step={step}\n onChange={(e) => onChange(parseFloat(e.target.value))}\n />\n );\n}\n\n// ── dropdown shell (open state, outside-click, trigger + panel) ───────────────\nfunction useOutsideClose(open: boolean, close: () => void) {\n const rootRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n if (!open) return;\n const onDoc = (e: MouseEvent) => {\n // composedPath, NOT contains(e.target): at the document level an event\n // from inside the viewer's shadow root retargets to the host element, so\n // contains() reads every inside click as outside and unmounts the panel\n // on mousedown — before the option's click can fire.\n if (rootRef.current && !e.composedPath().includes(rootRef.current)) close();\n };\n document.addEventListener('mousedown', onDoc);\n return () => document.removeEventListener('mousedown', onDoc);\n }, [open, close]);\n return rootRef;\n}\n\nfunction DropdownShell({\n trigger,\n children,\n}: {\n trigger: ReactNode;\n children: (close: () => void) => ReactNode;\n}) {\n const [open, setOpen] = useState(false);\n const rootRef = useOutsideClose(open, () => setOpen(false));\n return (\n <div ref={rootRef} className=\"relative w-full\">\n <button\n type=\"button\"\n onClick={() => setOpen((o) => !o)}\n className=\"border-border bg-surface text-fg flex w-full items-center justify-between gap-2 rounded border px-3 py-1.5\"\n >\n {trigger}\n <Icon name=\"chevronDown\" size={16} className=\"text-fg-secondary shrink-0\" />\n </button>\n {open && (\n <div className=\"border-border bg-elevated absolute z-10 mt-1 max-h-60 w-full overflow-y-auto rounded border p-1 shadow-lg\">\n {children(() => setOpen(false))}\n </div>\n )}\n </div>\n );\n}\n\nfunction OptionRow({\n selected,\n onClick,\n children,\n}: {\n selected: boolean;\n onClick: () => void;\n children: ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={`hover:bg-hover flex w-full items-center rounded px-2 py-1.5 text-left text-sm ${selected ? 'bg-selected text-accent' : 'text-fg'}`}\n >\n {children}\n </button>\n );\n}\n\n// ── stroke / border preview + picker ─────────────────────────────────────────\nfunction borderSvg(b: Border): ReactNode {\n if (b.kind === 'cloudy') {\n const r = b.intensity >= 2 ? 5 : 3;\n const n = Math.ceil(80 / (r * 2));\n const step = 80 / n;\n const baseline = r + 1;\n const viewH = r * 2 + 2;\n const parts = [`M 0 ${baseline}`];\n for (let i = 0; i < n; i++) parts.push(`A ${r} ${r} 0 0 1 ${step * (i + 1)} ${baseline}`);\n return (\n <svg width=\"80\" height={viewH} viewBox={`0 0 80 ${viewH}`}>\n <path\n d={parts.join(' ')}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n }\n const dash = b.kind === 'dashed' ? b.dash.join(' ') : undefined;\n return (\n <svg width=\"80\" height=\"8\" viewBox=\"0 0 80 8\">\n <line\n x1=\"0\"\n y1=\"4\"\n x2=\"80\"\n y2=\"4\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeDasharray={dash}\n />\n </svg>\n );\n}\n\nfunction BorderSelect({\n value,\n cloudy,\n onChange,\n}: {\n value: Border;\n cloudy: boolean;\n onChange: (b: Border) => void;\n}) {\n const opts = cloudy ? BORDER_OPTS : BORDER_OPTS.filter((o) => !o.key.startsWith('cloudy'));\n return (\n <DropdownShell trigger={<span className=\"text-fg-secondary\">{borderSvg(value)}</span>}>\n {(close) =>\n opts.map((o) => {\n const b = o.make();\n return (\n <OptionRow\n key={o.key}\n selected={borderKey(value) === o.key}\n onClick={() => {\n onChange(b);\n close();\n }}\n >\n <span className=\"text-fg-secondary\">{borderSvg(b)}</span>\n </OptionRow>\n );\n })\n }\n </DropdownShell>\n );\n}\n\n// ── line-ending preview + picker ─────────────────────────────────────────────\nconst LE_MARKERS: Partial<Record<LineEnding, ReactNode>> = {\n square: <path d=\"M68 -4 L76 -4 L76 4 L68 4 Z\" />,\n circle: <circle cx=\"72\" cy=\"0\" r=\"4\" />,\n diamond: <path d=\"M72 -5 L77 0 L72 5 L67 0 Z\" />,\n 'open-arrow': <path d=\"M67 -5 L77 0 L67 5\" fill=\"none\" />,\n 'closed-arrow': <path d=\"M67 -5 L77 0 L67 5 Z\" />,\n 'r-open-arrow': <path d=\"M77 -5 L67 0 L77 5\" fill=\"none\" />,\n 'r-closed-arrow': <path d=\"M77 -5 L67 0 L77 5 Z\" />,\n butt: <path d=\"M72 -5 L72 5\" fill=\"none\" />,\n slash: <path d=\"M67 -5 L77 5\" fill=\"none\" />,\n};\nconst LE_LINE_END: Partial<Record<LineEnding, number>> = {\n square: 68,\n circle: 68,\n diamond: 67,\n 'open-arrow': 76,\n 'closed-arrow': 67,\n 'r-open-arrow': 67,\n 'r-closed-arrow': 67,\n butt: 72,\n slash: 72,\n};\n\nfunction LineEndingPreview({ name, side }: { name: LineEnding; side: 'start' | 'end' }) {\n const marker = LE_MARKERS[name];\n const lineEndX = LE_LINE_END[name] ?? 77;\n const transform = side === 'start' ? 'rotate(180 40 10)' : undefined;\n return (\n <svg width=\"80\" height=\"20\" viewBox=\"0 0 80 20\" className=\"text-fg\">\n <g transform={transform}>\n <line x1=\"4\" y1=\"10\" x2={lineEndX} y2=\"10\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n {marker && (\n <g\n transform=\"translate(0, 10)\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n >\n {marker}\n </g>\n )}\n </g>\n </svg>\n );\n}\n\nfunction LineEndingSelect({\n side,\n value,\n onChange,\n}: {\n side: 'start' | 'end';\n value: LineEnding;\n onChange: (v: LineEnding) => void;\n}) {\n return (\n <DropdownShell trigger={<LineEndingPreview name={value} side={side} />}>\n {(close) =>\n LINE_ENDINGS.map((o) => (\n <OptionRow\n key={o.v}\n selected={value === o.v}\n onClick={() => {\n onChange(o.v);\n close();\n }}\n >\n <LineEndingPreview name={o.v} side={side} />\n </OptionRow>\n ))\n }\n </DropdownShell>\n );\n}\n\n// ── font family picker ───────────────────────────────────────────────────────\nfunction FontFamilySelect({ value, onChange }: { value: string; onChange: (v: string) => void }) {\n // The standard faces plus the configured fonts that are registered and\n // mounted (`annotations.fonts`) — a registered key is a `fontFamily` value\n // like any standard name.\n const configured = useAnnotationFonts();\n const options = [...FONT_OPTIONS, ...configured.map((f) => ({ v: f.key, label: f.label }))];\n const current = options.find((o) => o.v === value);\n return (\n <DropdownShell trigger={<span className=\"text-fg text-sm\">{current?.label ?? value}</span>}>\n {(close) =>\n options.map((o) => (\n <OptionRow\n key={o.v}\n selected={o.v === value}\n onClick={() => {\n onChange(o.v);\n close();\n }}\n >\n {o.label}\n </OptionRow>\n ))\n }\n </DropdownShell>\n );\n}\n\n// ── font-size combo (number input + preset dropdown) ─────────────────────────\nfunction FontSizeCombo({ value, onChange }: { value: number; onChange: (n: number) => void }) {\n const [open, setOpen] = useState(false);\n const rootRef = useOutsideClose(open, () => setOpen(false));\n // Typed text is a DRAFT until Enter or blur (Escape discards): committing\n // per keystroke would apply \"2\" on the way to \"24\" — to the selected text\n // while editing. Presets commit at once.\n const [draft, setDraft] = useState<string | null>(null);\n const commit = () => {\n if (draft === null) return;\n const n = parseInt(draft, 10);\n setDraft(null);\n if (Number.isFinite(n) && n > 0 && n !== value) onChange(n);\n };\n return (\n <div ref={rootRef} className=\"relative w-full\">\n <input\n type=\"number\"\n min={1}\n value={draft ?? value}\n onChange={(e) => setDraft(e.target.value)}\n onBlur={commit}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n commit();\n setOpen(false);\n } else if (e.key === 'Escape') {\n setDraft(null);\n setOpen(false);\n }\n }}\n onClick={() => setOpen(true)}\n className=\"border-border bg-surface text-fg w-full rounded border px-2 py-1.5 pr-7 text-sm\"\n />\n <button\n type=\"button\"\n tabIndex={-1}\n onClick={() => setOpen((o) => !o)}\n className=\"absolute inset-y-0 right-1 flex items-center\"\n >\n <Icon name=\"chevronDown\" size={16} className=\"text-fg-secondary\" />\n </button>\n {open && (\n <div className=\"border-border bg-elevated absolute z-10 mt-1 max-h-48 w-full overflow-y-auto rounded border p-1 shadow-lg\">\n {FONT_SIZES.map((sz) => (\n <OptionRow\n key={sz}\n selected={sz === value}\n onClick={() => {\n setDraft(null);\n onChange(sz);\n setOpen(false);\n }}\n >\n {sz}\n </OptionRow>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction BlendModeSelect({\n value,\n onChange,\n}: {\n value: BlendMode;\n onChange: (mode: BlendMode) => void;\n}) {\n return (\n <select\n value={value}\n onChange={(event) => onChange(event.target.value as BlendMode)}\n className=\"border-border bg-surface text-fg w-full rounded border px-3 py-1.5 text-sm\"\n >\n {BLEND_MODES.map((mode) => (\n <option key={mode.v} value={mode.v}>\n {mode.label}\n </option>\n ))}\n </select>\n );\n}\n\n// ── align toggle ─────────────────────────────────────────────────────────────\nfunction Toggle({\n active,\n title,\n onClick,\n keepFocus,\n children,\n}: {\n active: boolean;\n title: string;\n onClick: () => void;\n /** Don't take focus on press — a text editor's selection survives the click. */\n keepFocus?: boolean;\n children: ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n title={title}\n onClick={onClick}\n onMouseDown={keepFocus ? (e) => e.preventDefault() : undefined}\n className={`flex h-9 w-9 items-center justify-center rounded border transition-colors ${\n active\n ? 'border-accent bg-accent text-on-accent'\n : 'border-border bg-surface text-fg hover:bg-hover'\n }`}\n >\n {children}\n </button>\n );\n}\n\n// ── rich-text formatting: bold / italic / underline in one row ──────────────\ntype FormatSpec = Extract<PropSpec, { key: 'bold' | 'italic' | 'underline' }>;\nconst isFormatSpec = (spec: PropSpec): spec is FormatSpec =>\n spec.key === 'bold' || spec.key === 'italic' || spec.key === 'underline';\n\n/**\n * The format toggles a free-text kind declares, in one row. While the text\n * editor holds a range they read and write that range's runs (the plugin\n * routes `updateSelection`); otherwise the annotation's body. The buttons\n * keep focus in the editor so the range survives the click.\n */\nfunction FormatToggles({\n specs,\n values,\n mixed,\n onChange,\n}: {\n specs: FormatSpec[];\n values: Partial<Record<PropKey, unknown>>;\n mixed: PropKey[];\n onChange: (patch: AnnotationPropsPatch) => void;\n}) {\n const t = useT();\n return (\n <Field\n label={t('demo.formatLabel', { fallback: 'Format' })}\n mixed={specs.some((s) => mixed.includes(s.key))}\n >\n <div className=\"flex gap-2\">\n {specs.map((spec) => {\n const active = values[spec.key] === true && !mixed.includes(spec.key);\n return (\n <Toggle\n key={spec.key}\n title={spec.label}\n active={active}\n keepFocus\n onClick={() => onChange({ [spec.key]: !active } as AnnotationPropsPatch)}\n >\n <Icon name={spec.key} size={18} />\n </Toggle>\n );\n })}\n </div>\n </Field>\n );\n}\n\n// ── one control per PropSpec — the entire surface an app customizes ──────────\nfunction PropControl({\n spec,\n value,\n mixed,\n onChange,\n}: {\n spec: PropSpec;\n value: unknown;\n mixed: boolean;\n onChange: (patch: AnnotationPropsPatch) => void;\n}) {\n switch (spec.key) {\n case 'color':\n case 'fontColor':\n return (\n <Field label={spec.label} mixed={mixed}>\n <SwatchGrid\n value={value as string}\n onSelect={(c) => onChange({ [spec.key]: c } as AnnotationPropsPatch)}\n />\n </Field>\n );\n case 'interiorColor':\n return (\n <Field label={spec.label} mixed={mixed}>\n <SwatchGrid\n value={value as string | null}\n allowTransparent\n onSelect={(c) => onChange({ interiorColor: c === 'transparent' ? null : c })}\n />\n </Field>\n );\n case 'opacity': {\n const v = (value as number) ?? 1;\n return (\n <Field label={spec.label} mixed={mixed}>\n <RangeSlider\n value={v}\n min={spec.min}\n max={spec.max}\n step={spec.step}\n onChange={(n) => onChange({ opacity: n })}\n />\n <span className=\"text-fg-muted text-xs\">{Math.round(v * 100)}%</span>\n </Field>\n );\n }\n case 'strokeWidth': {\n const v = (value as number) ?? spec.min;\n return (\n <Field label={spec.label} mixed={mixed}>\n <RangeSlider\n value={v}\n min={spec.min}\n max={spec.max}\n step={spec.step}\n onChange={(n) => onChange({ strokeWidth: n })}\n />\n <span className=\"text-fg-muted text-xs\">{v}px</span>\n </Field>\n );\n }\n case 'fontSize':\n return (\n <Field label={spec.label} mixed={mixed}>\n <FontSizeCombo\n value={(value as number) ?? 12}\n onChange={(n) => onChange({ fontSize: n })}\n />\n </Field>\n );\n case 'border':\n return (\n <Field label={spec.label} mixed={mixed}>\n <BorderSelect\n value={(value as Border) ?? { kind: 'solid' }}\n cloudy={spec.cloudy}\n onChange={(b) => onChange({ border: b })}\n />\n </Field>\n );\n case 'lineEndings': {\n const le = (value as LineEndings) ?? { start: 'none', end: 'none' };\n return (\n <Field label={spec.label} mixed={mixed}>\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <div className=\"text-fg-muted mb-1.5 text-xs\">Start</div>\n <LineEndingSelect\n side=\"start\"\n value={le.start}\n onChange={(v) => onChange({ lineEndings: { start: v } })}\n />\n </div>\n <div>\n <div className=\"text-fg-muted mb-1.5 text-xs\">End</div>\n <LineEndingSelect\n side=\"end\"\n value={le.end}\n onChange={(v) => onChange({ lineEndings: { end: v } })}\n />\n </div>\n </div>\n </Field>\n );\n }\n case 'fontFamily':\n return (\n <Field label={spec.label} mixed={mixed}>\n <FontFamilySelect\n value={(value as string) ?? 'helvetica'}\n onChange={(v) => onChange({ fontFamily: v })}\n />\n </Field>\n );\n case 'textAlign': {\n const alignIcon: Record<TextAlign, string> = {\n left: 'alignLeft',\n center: 'alignCenter',\n right: 'alignRight',\n };\n return (\n <Field label={spec.label} mixed={mixed}>\n <div className=\"flex gap-2\">\n {(['left', 'center', 'right'] as TextAlign[]).map((al) => (\n <Toggle\n key={al}\n title={`Align ${al}`}\n active={value === al}\n onClick={() => onChange({ textAlign: al })}\n >\n <Icon name={alignIcon[al]} size={18} />\n </Toggle>\n ))}\n </div>\n </Field>\n );\n }\n // The rich-text format toggles render as ONE row (see `FormatToggles`);\n // each spec is still declared by the kind, so a kind without rich text\n // never shows them.\n case 'bold':\n case 'italic':\n case 'underline':\n return null;\n case 'blendMode':\n return (\n <Field label={spec.label} mixed={mixed}>\n <BlendModeSelect\n value={(value as BlendMode) ?? 'normal'}\n onChange={(blendMode) => onChange({ blendMode })}\n />\n </Field>\n );\n // `link` deliberately renders NOTHING here: a link is a verb on the\n // selection, edited in the anchored popover (see ui/link-editor.tsx) —\n // never a style-panel section.\n case 'link':\n return null;\n default:\n return null;\n }\n}\n\n// ── the panel ────────────────────────────────────────────────────────────────\nfunction EmptyState() {\n return (\n <div className=\"text-fg-muted flex flex-1 flex-col items-center justify-center gap-3 p-8 text-center\">\n <Icon name=\"palette\" size={40} className=\"text-fg-disabled\" />\n <p className=\"max-w-[180px] text-sm\">\n Pick a draw tool or select an annotation to edit its style.\n </p>\n </div>\n );\n}\n\n/**\n * The schema-driven style panel. Rendered inside the right sidebar's\n * `annotation-style` surface (see ui/panels.tsx). Owns its own scroll.\n */\nexport function AnnotationStylePanel() {\n const annotation = useAnnotation();\n const { activeToolId } = useTool();\n const sel = useSelectionProps();\n const defaults = useAnnotationDefaults(activeToolId);\n const selected = useAnnotationSelected();\n\n const hasSel = sel.specs.length > 0;\n const specs = hasSel ? sel.specs : annotation.propsForTool(activeToolId);\n const values = hasSel ? sel.values : defaults;\n const write = (patch: AnnotationPropsPatch) =>\n hasSel ? annotation.updateSelection(patch) : annotation.setDefaults(activeToolId, patch);\n\n // A selection with no editable props (e.g. a stamp, or a LOCKED annotation —\n // its style is frozen) still shows its flags: that's how you unlock it.\n if (specs.length === 0 && selected.length === 0) return <EmptyState />;\n\n const context = hasSel ? `${selected.length} selected` : `${activeToolId} defaults`;\n\n return (\n <div className=\"flex-1 overflow-y-auto p-4\">\n <p className=\"text-fg-muted mb-4 text-[11px] font-semibold uppercase tracking-wide\">\n {context}\n </p>\n {specs.map((spec) =>\n spec.key === 'bold' ? (\n <FormatToggles\n key=\"format\"\n specs={specs.filter((s): s is FormatSpec => isFormatSpec(s))}\n values={values}\n mixed={hasSel ? sel.mixed : []}\n onChange={write}\n />\n ) : (\n <PropControl\n key={spec.key}\n spec={spec}\n value={values[spec.key]}\n mixed={hasSel && sel.mixed.includes(spec.key)}\n onChange={write}\n />\n ),\n )}\n {/* Redaction label (`/OverlayText` + `/Repeat`) — kind content, not a\n style prop, so it writes through the redaction plugin's setLabel. */}\n <RedactionLabelSection />\n {/* `/F` flags for whatever is selected — the live flags test surface. */}\n <AnnotationFlagsSection />\n </div>\n );\n}\n\n/**\n * Label editor shown when exactly one redaction mark is selected. The text is\n * what the destructive apply paints over the region (white-on-black by the\n * tool defaults); `repeat` tiles it. Writes ride the annotation update verb\n * via the redaction plugin, which preserves the label's `/DA` styling.\n */\nfunction RedactionLabelSection() {\n const t = useT();\n const redaction = useOptionalCapability(RedactionToken);\n const selected = useAnnotationSelected();\n const mark = selected.length === 1 && selected[0]!.subtype === 'redact' ? selected[0]! : null;\n const [draft, setDraft] = useState<string | null>(null);\n useEffect(() => setDraft(null), [mark?.ref && refKeyOfRedact(mark.ref)]);\n if (!redaction || !mark || mark.subtype !== 'redact') return null;\n\n const value = draft ?? mark.overlayText ?? '';\n const commit = () => {\n if (draft === null) return;\n void redaction.setLabel(mark.ref, { overlayText: draft.length > 0 ? draft : null });\n setDraft(null);\n };\n\n return (\n <div className=\"border-border-subtle mt-4 border-t pt-4\">\n <p className=\"text-fg-muted mb-2 text-[11px] font-semibold uppercase tracking-wide\">\n {t('demo.redactLabelTitle')}\n </p>\n <input\n type=\"text\"\n value={value}\n placeholder={t('demo.redactLabelPlaceholder')}\n onChange={(e) => setDraft(e.target.value)}\n onBlur={commit}\n onKeyDown={(e) => e.key === 'Enter' && commit()}\n className=\"border-border bg-surface text-fg w-full rounded-md border px-2 py-1.5 text-sm\"\n />\n <label className=\"text-fg mt-2 flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={mark.repeat}\n onChange={(e) => void redaction.setLabel(mark.ref, { repeat: e.target.checked })}\n />\n {t('demo.redactLabelRepeat')}\n </label>\n </div>\n );\n}\n\n/** Stable key for the effect dep — mirrors the annotation model's ref keys. */\nfunction refKeyOfRedact(ref: { kind: string } & Record<string, unknown>): string {\n return JSON.stringify(ref);\n}\n","import type { AnnotationDTO, Color } from '@embedpdf/react/annotation';\n\n/**\n * How a comment card identifies its annotation at a glance: the type's glyph,\n * tinted with THAT annotation's own colors. Ported from v2's comment-sidebar\n * config onto the v3 vocabulary — the icon names carry over verbatim (the\n * chrome icon set kept the v2 registry names and accent slots), while the\n * color model is v3's ISO-faithful one: there is exactly one `/C` (\"color\")\n * and one `/IC` (\"interiorColor\") in the spec, so `primary` is the annotation's\n * `/C` and `secondary` its interior fill where the family has one.\n */\n\nexport interface IconAccent {\n primary?: string;\n secondary?: string;\n}\n\nexport interface CommentTypeConfig {\n /** Icon name in the chrome registry. */\n icon: string;\n /** i18n key for the type's display name (tooltip). */\n labelKey: string;\n /** Fallback when the locale has no entry. */\n label: string;\n}\n\n/** `/C`-style Color → CSS. */\nexport const cssColor = (c: Color | null | undefined): string | undefined =>\n c ? `rgb(${c.r}, ${c.g}, ${c.b})` : undefined;\n\nconst TYPE_CONFIG: Record<string, CommentTypeConfig> = {\n text: { icon: 'message', labelKey: 'annotation.comment', label: 'Comment' },\n highlight: { icon: 'highlight', labelKey: 'annotation.highlight', label: 'Highlight' },\n underline: { icon: 'underline', labelKey: 'annotation.underline', label: 'Underline' },\n squiggly: { icon: 'squiggly', labelKey: 'annotation.squiggly', label: 'Squiggly' },\n strikeout: { icon: 'strikethrough', labelKey: 'annotation.strikeout', label: 'Strikethrough' },\n square: { icon: 'square', labelKey: 'annotation.square', label: 'Square' },\n circle: { icon: 'circle', labelKey: 'annotation.circle', label: 'Circle' },\n line: { icon: 'line', labelKey: 'annotation.line', label: 'Line' },\n polygon: { icon: 'polygon', labelKey: 'annotation.polygon', label: 'Polygon' },\n polyline: { icon: 'zigzag', labelKey: 'annotation.polyline', label: 'Polyline' },\n ink: { icon: 'pencilMarker', labelKey: 'annotation.ink', label: 'Ink' },\n 'free-text': { icon: 'freeText', labelKey: 'annotation.freeText', label: 'Text' },\n stamp: { icon: 'rubberStamp', labelKey: 'annotation.stamp', label: 'Stamp' },\n caret: { icon: 'insertText', labelKey: 'annotation.caret', label: 'Caret' },\n redact: { icon: 'redact', labelKey: 'annotation.redact', label: 'Redact' },\n 'file-attachment': {\n icon: 'paperclip',\n labelKey: 'annotation.fileAttachment',\n label: 'Attachment',\n },\n};\n\nconst FALLBACK: CommentTypeConfig = {\n icon: 'message',\n labelKey: 'annotation.comment',\n label: 'Comment',\n};\n\nexport const commentTypeConfig = (a: AnnotationDTO): CommentTypeConfig =>\n TYPE_CONFIG[a.subtype] ?? FALLBACK;\n\n/**\n * The glyph's tint slots, read off the annotation itself — this is what makes\n * a card recognizable as \"that yellow highlight on page 3\". Free-text prefers\n * its `fontColor` override, since that is the color a reader actually sees.\n */\nexport const commentIconAccent = (a: AnnotationDTO): IconAccent => {\n const anyA = a as { color?: Color; interiorColor?: Color | null; fontColor?: Color };\n const primary = cssColor(anyA.fontColor ?? anyA.color);\n const secondary = cssColor(anyA.interiorColor);\n return {\n ...(primary ? { primary } : {}),\n ...(secondary ? { secondary } : {}),\n };\n};\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport { useCapability } from '@embedpdf/react/runtime';\nimport {\n AnnotationToken,\n refKey,\n useAnnotationSelection,\n useComments,\n useCommentThreads,\n useCommentsHydration,\n type AnnotationDTO,\n type AnnotationRef,\n type CommentThreadView,\n} from '@embedpdf/react/annotation';\nimport { StageToken } from '@embedpdf/react/stage';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\nimport { commentIconAccent, commentTypeConfig } from './comment-config';\n\n/**\n * The comments sidebar (right panel): a live view over the conversation\n * plane, in the shape v2's reviewers knew — page-grouped sections, and a\n * card that identifies its annotation at a glance by the type's glyph tinted\n * with that annotation's own colors. What v2 lacked, and this adds, is the\n * ISO 32000 §12.5.6.3 review status per thread.\n *\n * There is no per-page loading dance: the plugin hydrates the WHOLE document\n * at open (`listRawAll`), so the list is complete the moment `hydration()`\n * says so, whether or not a page was ever scrolled to.\n *\n * Selection is two-way, as in v2: clicking a card selects the annotation and\n * flies the camera to it (`stage.reveal`, the same verb search hits use);\n * selecting in the document scrolls that card into view here.\n *\n * Every action routes through the `comments` verbs — plain annotation writes\n * on the one optimistic pipeline — and every control is gated by\n * `permissionsFor`, the engine's own collab-resolver mirrors: what shows here\n * is what the engine will allow.\n */\n\nconst REVIEW_STATES = ['none', 'accepted', 'rejected', 'cancelled', 'completed'] as const;\n\nconst dateLabel = (iso: string | null): string => {\n if (!iso) return '';\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '';\n return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });\n};\n\nexport function CommentsPanel() {\n const t = useT();\n const hydration = useCommentsHydration();\n const comments = useComments();\n const threads = useCommentThreads();\n const anno = useCapability(AnnotationToken);\n const stage = useCapability(StageToken);\n const selection = useAnnotationSelection();\n const scrollRef = useRef<HTMLDivElement>(null);\n const cardRefs = useRef<Record<string, HTMLLIElement | null>>({});\n\n /** Which thread the document's selection points at — ANY member counts, so\n * selecting a reply's parent shape highlights the same card. */\n const selectedThreadKey = useMemo(() => {\n for (const id of selection) {\n const dto = anno.getSelected().find((a) => refKey(a.ref) === id || a.nm === id);\n const ref = dto?.ref ?? null;\n const thread = ref ? comments.thread(ref) : null;\n if (thread) return refKey(thread.root.ref);\n }\n return null;\n // `selection` identity changes on every selection write — the right key.\n }, [selection, anno, comments]);\n\n // Reverse sync: the selected card scrolls itself into view (v2 centered it).\n useEffect(() => {\n if (!selectedThreadKey || !scrollRef.current) return;\n const el = cardRefs.current[selectedThreadKey];\n if (!el) return;\n const container = scrollRef.current;\n const top =\n el.offsetTop - container.clientHeight / 2 + el.clientHeight / 2 - container.offsetTop;\n container.scrollTo({ top, behavior: 'smooth' });\n }, [selectedThreadKey]);\n\n /** Click a card: select the annotation AND fly the camera to it. */\n const goTo = (view: CommentThreadView) => {\n anno.select(view.root.ref);\n if (view.pageIndex < 0) return;\n // Anchor values are viewport FRACTIONS (0–1), not v2's percentages:\n // the annotation lands a third down the viewport, the find-bar feel.\n stage?.reveal(view.pageIndex, {\n ...(view.contentRect ? { rect: view.contentRect } : {}),\n anchor: { x: 'center', y: 0.35 },\n behavior: 'smooth',\n });\n };\n\n // Page-grouped, preserving the lens's display order within each page.\n const byPage = useMemo(() => {\n const groups = new Map<number, CommentThreadView[]>();\n for (const v of threads) {\n const arr = groups.get(v.pageIndex);\n if (arr) arr.push(v);\n else groups.set(v.pageIndex, [v]);\n }\n return [...groups.entries()].sort((a, b) => a[0] - b[0]);\n }, [threads]);\n\n if (hydration.status === 'loading') return <Empty icon=\"comment\" text={t('demo.commentsLoading')} />;\n if (hydration.status === 'forbidden')\n return <Empty icon=\"lock\" text={t('demo.commentsForbidden')} />;\n if (hydration.status === 'error') {\n return (\n <Empty icon=\"alertTriangle\" text={t('demo.commentsError')}>\n <button\n type=\"button\"\n onClick={() => void comments.rehydrate()}\n className=\"bg-accent text-on-accent rounded-md px-3 py-1.5 text-sm font-medium\"\n >\n {t('demo.commentsRetry')}\n </button>\n </Empty>\n );\n }\n if (threads.length === 0) return <Empty icon=\"comment\" text={t('demo.commentsEmpty')} />;\n\n return (\n <div ref={scrollRef} className=\"min-h-0 flex-1 overflow-y-auto\">\n <div className=\"flex flex-col gap-5 p-3\">\n {byPage.map(([pageIndex, group]) => (\n <div key={pageIndex} className=\"flex flex-col gap-2\">\n <div className=\"bg-surface sticky top-0 z-10\">\n <div className=\"border-border-subtle border-b pb-1.5\">\n <h3 className=\"text-fg text-sm font-semibold\">\n {t('demo.commentsPage', { params: { page: group[0]!.pageLabel } })}\n </h3>\n <p className=\"text-fg-muted text-xs\">\n {t(group.length === 1 ? 'demo.commentCount' : 'demo.commentCountPlural', {\n params: { count: String(group.length) },\n })}\n </p>\n </div>\n </div>\n <ul className=\"flex flex-col gap-2\">\n {group.map((view) => {\n const key = refKey(view.root.ref);\n return (\n <ThreadCard\n key={key}\n view={view}\n selected={selectedThreadKey === key}\n onSelect={() => goTo(view)}\n cardRef={(el) => {\n cardRefs.current[key] = el;\n }}\n />\n );\n })}\n </ul>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nfunction Empty({\n icon,\n text,\n children,\n}: {\n icon: string;\n text: string;\n children?: React.ReactNode;\n}) {\n return (\n <div className=\"flex flex-col items-center gap-3 px-4 py-10 text-center\">\n <Icon name={icon} size={32} className=\"text-fg-muted\" />\n <p className=\"text-fg-muted text-sm\">{text}</p>\n {children}\n </div>\n );\n}\n\nfunction ThreadCard({\n view,\n selected,\n onSelect,\n cardRef,\n}: {\n view: CommentThreadView;\n selected: boolean;\n onSelect: () => void;\n cardRef: (el: HTMLLIElement | null) => void;\n}) {\n const t = useT();\n const comments = useComments();\n const [reply, setReply] = useState('');\n const perms = comments.permissionsFor(view.root.ref);\n const config = commentTypeConfig(view.root);\n const status = view.review.mine?.state ?? 'none';\n const latest = view.review.lastChange;\n\n const sendReply = () => {\n const text = reply.trim();\n if (!text) return;\n setReply('');\n void comments.reply(view.root.ref, text);\n };\n\n return (\n <li\n ref={cardRef}\n onClick={onSelect}\n className={`bg-surface cursor-pointer rounded-lg border shadow-sm transition-all hover:shadow-md ${\n selected ? 'border-accent ring-accent/40 ring-2' : 'border-border-subtle'\n }`}\n >\n <div className=\"flex flex-col gap-2 p-3\">\n {/* identity row: the annotation's own glyph + color is the anchor */}\n <div className=\"flex items-start gap-2.5\">\n <div\n className=\"bg-hover mt-0.5 grid h-8 w-8 shrink-0 place-items-center rounded-full\"\n title={t(config.labelKey, { fallback: config.label })}\n >\n <Icon name={config.icon} size={18} accent={commentIconAccent(view.root)} />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-baseline gap-2\">\n <span className=\"text-fg truncate text-sm font-medium\">\n {view.root.author ?? t('demo.commentsAnonymous')}\n </span>\n <span className=\"text-fg-muted ml-auto shrink-0 text-xs\">\n {dateLabel(view.root.modified ?? view.root.created)}\n </span>\n </div>\n {latest && (\n <span className=\"bg-accent-light text-accent mt-1 inline-block rounded px-1.5 py-0.5 text-[11px] font-medium\">\n {statusLabel(t, latest.state)}\n {latest.by ? ` — ${latest.by}` : ''}\n </span>\n )}\n </div>\n {perms.canDeleteThread && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n void comments.removeThread(view.root.ref);\n }}\n className=\"text-fg-muted hover:text-fg grid h-6 w-6 shrink-0 place-items-center rounded\"\n title={t('demo.commentsDeleteThread')}\n >\n <Icon name=\"trash\" size={14} />\n </button>\n )}\n </div>\n\n <CommentBody annotationRef={view.root.ref} text={view.root.contents ?? ''} deletable={false} />\n\n {view.replies.length > 0 && (\n <div className=\"border-border-subtle flex flex-col gap-2 border-t pt-2\">\n {view.replies.map((r) => (\n <Reply key={refKey(r.ref)} dto={r} />\n ))}\n </div>\n )}\n\n <div className=\"border-border-subtle flex flex-col gap-1.5 border-t pt-2\">\n {perms.canSetStatus && (\n <label\n className=\"text-fg-muted flex items-center gap-2 text-xs\"\n onClick={(e) => e.stopPropagation()}\n >\n {t('demo.commentsStatus')}\n <select\n value={status}\n onChange={(e) => void comments.setStatus(view.root.ref, e.target.value)}\n className=\"border-border bg-surface text-fg flex-1 rounded-md border px-1.5 py-1 text-xs outline-none\"\n >\n {REVIEW_STATES.map((s) => (\n <option key={s} value={s}>\n {statusLabel(t, s)}\n </option>\n ))}\n </select>\n </label>\n )}\n {perms.canReply && (\n <div className=\"flex items-center gap-1.5\" onClick={(e) => e.stopPropagation()}>\n <input\n type=\"text\"\n value={reply}\n placeholder={\n view.root.contents || view.replies.length\n ? t('demo.commentsReplyPlaceholder')\n : t('demo.commentsAddPlaceholder')\n }\n onChange={(e) => setReply(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && sendReply()}\n className=\"border-border bg-surface text-fg focus:border-accent w-full min-w-0 flex-1 rounded-md border px-2 py-1 text-sm outline-none\"\n />\n <button\n type=\"button\"\n onClick={sendReply}\n disabled={!reply.trim()}\n className=\"text-accent disabled:text-fg-muted grid h-7 w-7 shrink-0 place-items-center rounded-md\"\n title={t('demo.commentsReply')}\n >\n <Icon name=\"arrowForwardUp\" size={16} />\n </button>\n </div>\n )}\n </div>\n </div>\n </li>\n );\n}\n\nfunction Reply({ dto }: { dto: AnnotationDTO }) {\n const t = useT();\n return (\n <div className=\"border-border-subtle ml-1 border-l-2 pl-2\">\n <div className=\"flex items-baseline gap-2\">\n <span className=\"text-fg-secondary text-xs font-medium\">\n {dto.author ?? t('demo.commentsAnonymous')}\n </span>\n <span className=\"text-fg-muted text-[11px]\">\n {dateLabel(dto.modified ?? dto.created)}\n </span>\n </div>\n <CommentBody annotationRef={dto.ref} text={dto.contents ?? ''} deletable />\n </div>\n );\n}\n\n/** One comment's text with inline edit (own, unlocked) and delete (replies). */\nfunction CommentBody({\n annotationRef,\n text,\n deletable,\n}: {\n annotationRef: AnnotationRef;\n text: string;\n deletable: boolean;\n}) {\n const t = useT();\n const comments = useComments();\n const perms = comments.permissionsFor(annotationRef);\n const [draft, setDraft] = useState<string | null>(null);\n\n if (draft !== null) {\n const save = () => {\n const next = draft.trim();\n setDraft(null);\n if (next && next !== text) void comments.edit(annotationRef, next);\n };\n return (\n <textarea\n value={draft}\n autoFocus\n rows={2}\n onClick={(e) => e.stopPropagation()}\n onChange={(e) => setDraft(e.target.value)}\n onBlur={save}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n save();\n }\n if (e.key === 'Escape') setDraft(null);\n }}\n className=\"border-accent bg-surface text-fg w-full resize-none rounded-md border px-2 py-1 text-sm outline-none\"\n />\n );\n }\n if (!text && !perms.canEditText && !deletable) return null;\n return (\n <div className=\"group/body flex items-start gap-1\">\n <p className=\"text-fg min-w-0 flex-1 whitespace-pre-wrap text-sm\">{text}</p>\n {perms.canEditText && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n setDraft(text);\n }}\n className=\"text-fg-muted hover:text-fg grid h-5 w-5 shrink-0 place-items-center rounded opacity-0 group-hover/body:opacity-100\"\n title={t('demo.commentsEdit')}\n >\n <Icon name=\"pencilMarker\" size={12} />\n </button>\n )}\n {deletable && perms.canDelete && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n void comments.remove(annotationRef);\n }}\n className=\"text-fg-muted hover:text-fg grid h-5 w-5 shrink-0 place-items-center rounded opacity-0 group-hover/body:opacity-100\"\n title={t('demo.commentsDelete')}\n >\n <Icon name=\"trash\" size={12} />\n </button>\n )}\n </div>\n );\n}\n\nfunction statusLabel(t: ReturnType<typeof useT>, state: string): string {\n switch (state) {\n case 'none':\n return t('demo.commentsStatusNone');\n case 'accepted':\n return t('demo.commentsStatusAccepted');\n case 'rejected':\n return t('demo.commentsStatusRejected');\n case 'cancelled':\n return t('demo.commentsStatusCancelled');\n case 'completed':\n return t('demo.commentsStatusCompleted');\n default:\n return state; // custom vocabularies render verbatim\n }\n}\n","import { useEffect } from 'react';\nimport { useCapability } from '@embedpdf/react/runtime';\nimport { AnnotationToken } from '@embedpdf/react/annotation';\nimport { usePendingRedactions, useRedaction } from '@embedpdf/react/redaction';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\n\n/**\n * The pending-redactions review panel (right sidebar). The list is a LIVE view\n * over the annotation plane — deleting a mark here is deleting the annotation.\n * \"Apply all\" routes through the confirm modal: the apply is irreversible.\n */\nexport function RedactionPanel() {\n const t = useT();\n const redaction = useRedaction();\n const pending = usePendingRedactions();\n const anno = useCapability(AnnotationToken);\n const confirm = useSurface('redact-confirm');\n\n // The annotation plane loads lazily per page; pull every page in so the\n // panel shows marks on pages never scrolled to.\n useEffect(() => {\n void redaction.preparePending();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"min-h-0 flex-1 overflow-y-auto p-2\">\n {pending.length === 0 ? (\n <div className=\"flex flex-col items-center gap-3 px-4 py-10 text-center\">\n <Icon name=\"redactionSidebar\" size={32} className=\"text-fg-muted\" />\n <p className=\"text-fg-muted text-sm\">{t('demo.redactionEmpty')}</p>\n </div>\n ) : (\n <ul className=\"flex flex-col gap-1\">\n {pending.map((item) => (\n <li key={item.id}>\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => anno.select(item.ref)}\n onKeyDown={(e) => e.key === 'Enter' && anno.select(item.ref)}\n className=\"hover:bg-hover group flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-left\"\n >\n <Icon\n name={item.kind === 'area' ? 'redactArea' : 'redact'}\n size={16}\n className=\"text-fg-muted shrink-0\"\n />\n <span className=\"text-fg min-w-0 flex-1 truncate text-sm\">\n {item.overlayText ??\n t(item.kind === 'area' ? 'demo.redactionArea' : 'demo.redactionText')}\n </span>\n <span className=\"text-fg-muted shrink-0 text-xs\">\n {t('demo.pageBadge', {\n params: { page: item.pageIndex >= 0 ? String(item.pageIndex + 1) : '?' },\n })}\n </span>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n void anno.delete(item.ref);\n }}\n className=\"text-fg-muted hover:text-fg grid h-6 w-6 shrink-0 place-items-center rounded opacity-0 group-hover:opacity-100\"\n title={t('demo.redactionRemove')}\n >\n <Icon name=\"trash\" size={14} />\n </button>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n <div className=\"border-border-subtle flex shrink-0 gap-2 border-t p-3\">\n <button\n type=\"button\"\n disabled={pending.length === 0}\n onClick={() => {\n for (const item of pending) void anno.delete(item.ref);\n }}\n className=\"border-border text-fg hover:bg-hover flex-1 rounded-md border px-3 py-1.5 text-sm disabled:opacity-40\"\n >\n {t('commands.redact.clearAll')}\n </button>\n <button\n type=\"button\"\n disabled={pending.length === 0 || !redaction.canApply() || redaction.applying}\n onClick={() => confirm.open()}\n className=\"flex-1 rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-40\"\n >\n {t('commands.redact.applyAll')}\n </button>\n </div>\n </div>\n );\n}\n","/**\n * The search panel — the v2 snippet's search sidebar on the v3 plugin-search\n * capability. ONE shape end to end: the flat `SearchQuery` {text, regex,\n * matchCase, wholeWord} is what the engine matches, what the plugin stores\n * (document-scoped, survives the sidebar closing), and what this box renders.\n * The panel keeps only a DRAFT of it for keystroke/debounce echo.\n *\n * Data flow:\n * type / toggle → validateSearchQuery → (debounced) search(draftQuery)\n * useSearchState() → query / status / hitCount / activeIndex (reactive)\n * useSelector(SearchToken, c => c.hits()) → the streamed hit list\n * click a hit / prev / next → goTo/prev/next (capability reveals it on-page)\n *\n * The look is ported 1:1 from viewers/snippet's search-sidebar (magnifier\n * input with clear button, option checkboxes, results-found counter with\n * prev/next, per-page grouped snippet list with the match bolded and the\n * active hit accented), retinted to this app's semantic tokens. The regex\n * toggle is new in v3 (v2 had no pattern search); matchDiacritics exists in\n * the engine but is deliberately not exposed here — v2 parity.\n */\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useSearch,\n useSearchState,\n validateSearchQuery,\n SearchToken,\n} from '@embedpdf/react/search';\nimport type { SearchHit, SearchQuery, SearchSnippet } from '@embedpdf/react/search';\nimport { useSelector } from '@embedpdf/react/runtime';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\nimport { buttonClass } from './toolbar';\n\nconst DEBOUNCE_MS = 300;\n\n/** Field-wise equality on the flat query — the mount/echo no-op guard. */\nconst sameQuery = (a: SearchQuery | null, b: SearchQuery) =>\n a != null &&\n a.text === b.text &&\n !!a.regex === !!b.regex &&\n !!a.matchCase === !!b.matchCase &&\n !!a.wholeWord === !!b.wholeWord;\n\n// ── option checkbox (v2's peer-checked custom box) ───────────────────────────\nfunction Checkbox({\n label,\n checked,\n onChange,\n}: {\n label: string;\n checked: boolean;\n onChange: (v: boolean) => void;\n}) {\n return (\n <label className=\"text-fg-secondary flex cursor-pointer select-none items-center gap-2 text-xs font-medium\">\n <span className=\"relative flex h-4 w-4 items-center justify-center\">\n <input\n type=\"checkbox\"\n checked={checked}\n onChange={(e) => onChange(e.target.checked)}\n className=\"border-border bg-surface checked:border-accent checked:bg-accent peer h-4 w-4 shrink-0 appearance-none rounded-[3px] border transition-colors\"\n />\n <svg\n viewBox=\"0 0 24 24\"\n className=\"text-on-accent pointer-events-none absolute h-3 w-3 opacity-0 peer-checked:opacity-100\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={3}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </span>\n {label}\n </label>\n );\n}\n\n// ── one result row: a snippet with the match bolded, active = accented ───────\nfunction renderSnippet(s: SearchSnippet | undefined) {\n if (!s) return null;\n const end = s.matchStart + s.matchLength;\n return (\n <>\n {s.text.slice(0, s.matchStart)}\n <span className=\"text-accent font-semibold\">{s.text.slice(s.matchStart, end)}</span>\n {s.text.slice(end)}\n </>\n );\n}\n\nfunction HitLine({\n hit,\n active,\n onClick,\n}: {\n hit: SearchHit;\n active: boolean;\n onClick: () => void;\n}) {\n const ref = useRef<HTMLButtonElement>(null);\n // Keep the active hit visible as prev/next walks the list.\n useEffect(() => {\n if (active) ref.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, [active]);\n return (\n <button\n ref={ref}\n type=\"button\"\n onClick={onClick}\n className={`w-full rounded border p-2 text-left text-sm transition-colors ${\n active\n ? 'border-accent bg-accent-light text-fg'\n : 'border-border-subtle bg-surface text-fg-secondary hover:bg-hover'\n }`}\n >\n <span>{renderSnippet(hit.snippet)}</span>\n </button>\n );\n}\n\n// ── the panel ────────────────────────────────────────────────────────────────\nexport function SearchPanel() {\n const t = useT();\n const search = useSearch();\n const { query, status, hitCount, activeIndex } = useSearchState();\n const hits = useSelector(SearchToken, (c) => c.hits());\n\n // `query` is the document-scoped stored search (survives the sidebar\n // closing). The box is a controlled draft that STARTS from it; the panel is\n // keyed on the document (see panels.tsx), so this one-time seed is always\n // the right document's query — switching tabs remounts and reseeds.\n const [draft, setDraft] = useState(() => query?.text ?? '');\n const [matchCase, setMatchCase] = useState(() => query?.matchCase ?? false);\n const [wholeWord, setWholeWord] = useState(() => query?.wholeWord ?? false);\n const [regex, setRegex] = useState(() => query?.regex ?? false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n // The draft IS a SearchQuery — same shape the engine matches on.\n const draftQuery: SearchQuery = { text: draft, regex, matchCase, wholeWord };\n // Early feedback on keystroke: the same validator the engine enforces\n // (regex dialect). Invalid patterns never fire a query.\n const validation = draft && regex ? validateSearchQuery(draftQuery) : { ok: true as const };\n\n // Debounced query. The sameQuery guard makes the mount pass (and our own\n // echo coming back through state) a no-op — nothing re-runs until the user\n // actually changes the text or a toggle. Clearing the box clears results.\n useEffect(() => {\n // No-ops: invalid pattern, draft already the stored query (mount pass /\n // our own echo), or an empty box with nothing stored to clear.\n if (!validation.ok || sameQuery(query, draftQuery)) return;\n if (draft === '' && query === null) return;\n const id = setTimeout(() => search.search(draftQuery), DEBOUNCE_MS);\n return () => clearTimeout(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [draft, matchCase, wholeWord, regex, query, validation.ok, search]);\n\n // Group hits by page, preserving page order, for the sectioned list.\n const grouped = useMemo(() => {\n const map = new Map<number, { hit: SearchHit; index: number }[]>();\n hits.forEach((hit, index) => {\n const arr = map.get(hit.pageIndex);\n if (arr) arr.push({ hit, index });\n else map.set(hit.pageIndex, [{ hit, index }]);\n });\n return [...map.entries()].sort((a, b) => a[0] - b[0]);\n }, [hits]);\n\n const searching = status === 'searching';\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"p-3\">\n {/* input: magnifier + clear */}\n <div className=\"relative\">\n <div className=\"text-fg-muted pointer-events-none absolute inset-y-0 left-0 flex items-center pl-2.5\">\n <Icon name=\"search\" size={16} />\n </div>\n <input\n ref={inputRef}\n type=\"text\"\n value={draft}\n placeholder={t('demo.searchPlaceholder')}\n onChange={(e) => setDraft(e.target.value)}\n className={`bg-surface text-fg w-full rounded-md border py-1.5 pl-8 pr-9 text-sm outline-none focus:ring-1 ${\n validation.ok\n ? 'border-border focus:border-accent focus:ring-accent'\n : 'border-red-400 focus:border-red-400 focus:ring-red-400'\n }`}\n />\n {draft && (\n <button\n type=\"button\"\n onClick={() => {\n setDraft('');\n inputRef.current?.focus();\n }}\n className=\"text-fg-muted hover:text-fg-secondary absolute inset-y-0 right-0 flex items-center pr-2.5\"\n >\n <Icon name=\"x\" size={16} />\n </button>\n )}\n </div>\n\n {/* the invalid-pattern message, straight from the shared validator */}\n {!validation.ok && <p className=\"mt-1.5 text-xs text-red-500\">{validation.message}</p>}\n\n {/* options — the three VS Code toggles, all composable */}\n <div className=\"mt-3 flex flex-col gap-2\">\n <Checkbox\n label={t('demo.searchCaseSensitive')}\n checked={matchCase}\n onChange={setMatchCase}\n />\n <Checkbox label={t('demo.searchWholeWord')} checked={wholeWord} onChange={setWholeWord} />\n <Checkbox label={t('demo.searchRegex')} checked={regex} onChange={setRegex} />\n </div>\n\n <hr className=\"border-border-subtle mb-2 mt-4\" />\n\n {/* results counter + prev/next */}\n {status !== 'idle' && (\n <div className=\"flex h-8 items-center justify-between\">\n <div className=\"text-fg-muted text-xs\">\n {hitCount === 0\n ? t(searching ? 'demo.searchSearching' : 'demo.searchNoResults')\n : t('demo.searchResults', { params: { count: hitCount } })}\n </div>\n {hitCount > 1 && (\n <div className=\"flex items-center\">\n <button\n type=\"button\"\n title=\"Previous\"\n className={buttonClass(false)}\n onClick={() => search.prev()}\n >\n <Icon name=\"chevronLeft\" size={20} />\n </button>\n <button\n type=\"button\"\n title=\"Next\"\n className={buttonClass(false)}\n onClick={() => search.next()}\n >\n <Icon name=\"chevronRight\" size={20} />\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* per-page grouped results */}\n <div className=\"flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto px-3 pb-3\">\n {grouped.map(([pageIndex, items]) => (\n <div key={pageIndex} className=\"mt-2 first:mt-0\">\n <div className=\"bg-surface/80 text-fg-muted py-2 text-xs backdrop-blur\">\n {t('demo.searchPage', { params: { page: pageIndex + 1 } })}\n </div>\n <div className=\"flex flex-col gap-2\">\n {items.map(({ hit, index }) => (\n <HitLine\n key={index}\n hit={hit}\n active={index === activeIndex}\n onClick={() => search.goTo(index)}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n","/**\n * The stamps sidebar (right panel) — v2's rubber-stamp sidebar on v3 parts.\n * The stamp plugin owns the libraries, the asset bytes and the cached\n * previews; this panel is the PICKER over them:\n *\n * a library <select> (\"All stamps\" + one per library, shown once there\n * are two) → a two-column grid of thumbnails → click a stamp → `armAsset`\n * arms the annotation plugin's stamp tool → hovering a page ghosts the\n * exact placement → each click on a page places one.\n *\n * Deliberately NOT a file dialog: picking arbitrary image bytes is the Image\n * tool's job (a click-then-pick tool, `insert:add-image`). The stamp button\n * opens a library; a library is a set of reusable, named assets — the two\n * gestures are different, so they are different controls.\n *\n * The panel stays open while you place, so a stamp can be dropped on several\n * pages and swapped without a round trip through the toolbar. A command can\n * open it ON a library (`annotation:stamp-from-selection` → \"My stamps\")\n * through the surface's open props.\n */\nimport { useEffect, useRef, useState } from 'react';\nimport { useTool } from '@embedpdf/react/interaction';\nimport {\n useArmStampAsset,\n useStamp,\n useStampAssetPreviewUrl,\n useStampAssets,\n useStampLibraries,\n type StampAsset,\n} from '@embedpdf/react/stamp';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useLocale, useT } from '@embedpdf/react/i18n';\nimport { useStampsConfig } from '../config-context';\nimport {\n DEFAULT_LIBRARY_ID,\n ensureDefaultLibrary,\n resolveStampsLocale,\n} from '../config/default-stamps';\nimport { Icon } from './icons';\nimport { restoreStampLibrariesOnce } from './stamp-store';\n\nconst ALL = 'all';\n\nexport function StampsPanel() {\n const t = useT();\n const stamp = useStamp();\n const { defaultLibrary, sidebar } = useStampsConfig();\n // Which catalogs this sidebar shows (`stamps.sidebar`): the plain stamps by\n // default — never the people's marks, which have their own panel.\n const libraries = useStampLibraries({ kind: sidebar ?? ['stamps'] });\n const assets = useStampAssets();\n const { armAsset } = useArmStampAsset();\n const { activeToolId } = useTool();\n const { locale } = useLocale();\n const surface = useSurface('stamps');\n const fileRef = useRef<HTMLInputElement>(null);\n const [armedId, setArmedId] = useState<string | null>(null);\n const [busy, setBusy] = useState<'loading' | 'importing' | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [picked, setPicked] = useState<string>(ALL);\n\n // A command opened the panel ON a library (v2's `selectedLibraryId` prop).\n const openedOn = surface.props?.libraryId;\n useEffect(() => {\n if (typeof openedOn === 'string') setPicked(openedOn);\n }, [openedOn]);\n\n // First open: the user's stored libraries (the workspace store restores\n // them; this only awaits it), THEN the built-in library for this locale —\n // never at viewer boot, so a viewer whose user never opens this panel pays\n // nothing for it. A locale change while open swaps the built-in library;\n // the user's own are untouched.\n useEffect(() => {\n let live = true;\n setBusy('loading');\n restoreStampLibrariesOnce(stamp)\n .then(() => ensureDefaultLibrary(stamp, resolveStampsLocale(locale), defaultLibrary))\n .catch((err: unknown) => {\n console.error('[embedpdf] default stamps failed:', err);\n if (live) setError(t('demo.stampsError'));\n })\n .finally(() => live && setBusy(null));\n return () => {\n live = false;\n };\n // `t` and `defaultLibrary` are init-stable; only the locale re-runs this.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [stamp, locale]);\n\n // The interaction hub owns tool state: leaving the stamp tool (picking\n // another tool, pressing Escape) un-highlights the gallery.\n useEffect(() => {\n if (activeToolId !== 'stamp') setArmedId(null);\n }, [activeToolId]);\n\n const arm = (asset: StampAsset) => {\n setError(null);\n setArmedId(asset.id);\n void armAsset(asset.id).catch((err) => {\n console.error('[embedpdf] arm stamp failed:', err);\n setArmedId(null);\n setError(t('demo.stampsArmError'));\n });\n };\n\n const importPdf = (file: File) => {\n setError(null);\n setBusy('importing');\n // The file name is only a FALLBACK: an Acrobat-authored or previously\n // exported library names itself through its /Title.\n stamp\n .importLibraryPdf(file, { name: file.name.replace(/\\.pdf$/i, '') })\n .then((id) => setPicked(id))\n .catch((err) => {\n console.error('[embedpdf] stamp library import failed:', err);\n setError(t('demo.stampsImportError'));\n })\n .finally(() => setBusy(null));\n };\n\n /** The library as the PDF it is — title, registry, artwork — for Acrobat\n * or another viewer. */\n const exportPdf = (libraryId: string, name: string) => {\n const bytes = stamp.exportLibrary(libraryId);\n if (!bytes) return;\n const blob = new Blob([bytes as BlobPart], { type: 'application/pdf' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = `${name || 'stamps'}.pdf`;\n a.click();\n URL.revokeObjectURL(url);\n };\n\n // A removed library falls back to \"All\"; the picker never names a ghost.\n // One library needs no picker: it is simply the selection (so its export\n // button is reachable).\n const selectedId =\n libraries.length === 1\n ? libraries[0].id\n : libraries.some((library) => library.id === picked)\n ? picked\n : ALL;\n const selected = selectedId === ALL ? null : (libraries.find((l) => l.id === selectedId) ?? null);\n const shown = selectedId === ALL ? assets : assets.filter((a) => a.libraryId === selectedId);\n const isDefault = (libraryId: string) => libraryId === DEFAULT_LIBRARY_ID;\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n {libraries.length > 0 && (\n <div className=\"border-border-subtle flex items-center gap-1 border-b p-2\">\n {libraries.length > 1 ? (\n <select\n value={selectedId}\n onChange={(event) => setPicked(event.target.value)}\n aria-label={t('demo.stampsTitle')}\n className=\"border-border bg-surface text-fg min-w-0 flex-1 rounded border px-2 py-1.5 text-sm\"\n >\n <option value={ALL}>{t('demo.stampsAll')}</option>\n {libraries.map((library) => (\n <option key={library.id} value={library.id}>\n {library.name}\n </option>\n ))}\n </select>\n ) : (\n <span className=\"text-fg-muted min-w-0 flex-1 truncate px-1 text-xs font-semibold uppercase tracking-wide\">\n {libraries[0].name}\n </span>\n )}\n {selected && (\n <>\n <button\n type=\"button\"\n onClick={() => exportPdf(selected.id, selected.name)}\n title={t('demo.stampsExportLibrary')}\n className=\"text-fg-muted hover:text-fg grid h-7 w-7 shrink-0 place-items-center rounded\"\n >\n <Icon name=\"download\" size={14} />\n </button>\n {!isDefault(selected.id) && (\n <button\n type=\"button\"\n onClick={() => void stamp.removeLibrary(selected.id)}\n title={t('demo.stampsRemoveLibrary')}\n className=\"text-fg-muted hover:text-fg grid h-7 w-7 shrink-0 place-items-center rounded\"\n >\n <Icon name=\"trash\" size={14} />\n </button>\n )}\n </>\n )}\n </div>\n )}\n\n <div className=\"min-h-0 flex-1 overflow-y-auto p-3\">\n {busy === 'loading' && shown.length === 0 ? (\n <div className=\"flex flex-col items-center gap-3 px-4 py-10 text-center\">\n <div className=\"border-border-subtle border-t-accent h-6 w-6 animate-spin rounded-full border-2\" />\n <p className=\"text-fg-muted text-sm\">{t('demo.stampsLoading')}</p>\n </div>\n ) : shown.length === 0 ? (\n <div className=\"flex flex-col items-center gap-3 px-4 py-10 text-center\">\n <Icon name=\"rubberStamp\" size={32} className=\"text-fg-muted\" />\n <p className=\"text-fg-muted text-sm\">{t('demo.stampsEmpty')}</p>\n </div>\n ) : (\n <ul className=\"grid grid-cols-2 gap-3\">\n {shown.map((asset) => (\n <li key={asset.id} className=\"group relative\">\n <StampAssetCell\n asset={asset}\n armed={armedId === asset.id}\n onArm={() => arm(asset)}\n />\n {!isDefault(asset.libraryId) && (\n <button\n type=\"button\"\n onClick={() => void stamp.removeAsset(asset.id)}\n title={t('demo.stampsRemoveStamp')}\n className=\"bg-surface border-border text-fg-muted hover:text-fg absolute right-1 top-1 grid h-5 w-5 place-items-center rounded-full border opacity-0 shadow-sm focus:opacity-100 group-hover:opacity-100\"\n >\n <Icon name=\"x\" size={12} />\n </button>\n )}\n </li>\n ))}\n </ul>\n )}\n </div>\n\n {(error || armedId) && (\n <div\n className={`border-border-subtle shrink-0 border-t px-3 py-2 text-xs ${\n error ? 'text-red-600' : 'text-fg-muted'\n }`}\n >\n {error ?? t('demo.stampsArmedHint')}\n </div>\n )}\n\n <div className=\"border-border-subtle shrink-0 border-t p-3\">\n <button\n type=\"button\"\n disabled={busy != null}\n onClick={() => fileRef.current?.click()}\n title={t('demo.stampsImportHint')}\n className=\"border-border text-fg hover:bg-hover flex w-full items-center justify-center gap-2 rounded-md border px-3 py-1.5 text-sm disabled:opacity-40\"\n >\n <Icon name=\"rubberStampPlus\" size={16} />\n {busy === 'importing' ? t('demo.stampsImporting') : t('demo.stampsImport')}\n </button>\n <input\n ref={fileRef}\n type=\"file\"\n accept=\"application/pdf\"\n className=\"hidden\"\n onChange={(e) => {\n const file = e.currentTarget.files?.[0];\n e.currentTarget.value = ''; // allow re-picking the same file\n if (file) importPdf(file);\n }}\n />\n </div>\n </div>\n );\n}\n\n/** One grid cell: the plugin's cached preview through the object-URL hook\n * (the DOM resource's lifetime belongs to the framework layer, not the\n * store). Image only, as v2 — the artwork IS the label; the label is the\n * tooltip for the curious. */\nfunction StampAssetCell({\n asset,\n armed,\n onArm,\n}: {\n asset: StampAsset;\n armed: boolean;\n onArm: () => void;\n}) {\n const url = useStampAssetPreviewUrl(asset.id);\n return (\n <button\n type=\"button\"\n onClick={onArm}\n title={asset.label}\n aria-pressed={armed}\n className={`flex aspect-square w-full items-center justify-center rounded-md border p-2 ${\n armed\n ? 'border-accent bg-accent-light ring-accent ring-2'\n : 'border-border-subtle hover:border-border hover:bg-hover'\n }`}\n >\n {url ? (\n <img src={url} alt={asset.label} className=\"max-h-full max-w-full object-contain\" />\n ) : (\n <span className=\"text-fg truncate text-sm\">{asset.label}</span>\n )}\n </button>\n );\n}\n","/**\n * The signatures sidebar (right panel) — Preview's signature sheet on v3\n * parts. One row per PERSON: a stamp library of kind `signatures` holding a\n * full signature and, optionally, initials. Nothing is stored beyond the\n * file; rename/export/delete are the library verbs.\n *\n * pick a mark → with a TARGET field (\"sign here\" was clicked, or a\n * signature widget selected) the mark goes into that field by the\n * plugin's mode; otherwise it ARMS — hover a page for the ghost, click a\n * signature field to sign it, click anywhere else to drop it as a stamp.\n *\n * Below the people: the signature fields of THIS document, signed or not,\n * with their verdicts — click an unsigned one to target it, a signed one to\n * inspect it.\n */\nimport { useEffect, useState } from 'react';\nimport { useTool } from '@embedpdf/react/interaction';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useSurface } from '@embedpdf/react/shell';\nimport {\n useArmStampAsset,\n useStamp,\n useStampAssetPreviewUrl,\n type StampAsset,\n} from '@embedpdf/react/stamp';\nimport {\n useSignature,\n useSignatureSnapshot,\n useSignatureTarget,\n useSignatureVerdicts,\n useSignatureEvent,\n useSignerRows,\n type SignatureDTO,\n type SignatureVerdict,\n type SignerRow,\n} from '@embedpdf/react/signature';\nimport { useSignaturesConfig } from '../config-context';\nimport { Icon } from './icons';\nimport { restoreStampLibrariesOnce } from './stamp-store';\n\nconst fieldLabel = (\n field: { kind: 'fqn'; name: string } | { kind: 'objectNumber'; fieldObjectNumber: number },\n): string => (field.kind === 'fqn' ? field.name : `#${field.fieldObjectNumber}`);\n\nexport function SignaturesPanel() {\n const t = useT();\n const stamp = useStamp();\n const signature = useSignature();\n const config = useSignaturesConfig();\n const rows = useSignerRows();\n const { target, busy } = useSignatureTarget();\n const { armAsset } = useArmStampAsset();\n const { activeToolId } = useTool();\n const maker = useSurface('signature-maker');\n const [armedId, setArmedId] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n // Acrobat's warning: an unsaved edit just turned a signature that held into\n // one a save would invalidate. Shown until the next verdicts land.\n const [invalidating, setInvalidating] = useState<string | null>(null);\n useSignatureEvent((event) => {\n if (event.type === 'invalidating')\n setInvalidating(signature.signatureOf(event.field)?.fieldName ?? fieldLabel(event.field));\n else if (\n event.type === 'validated' &&\n !event.verdicts.some(\n (v) => v.summary === 'invalid' && v.modifications.basis === 'working-copy',\n )\n )\n setInvalidating(null);\n });\n\n // The people live in the same store as the stamps: bring them back on\n // first open (a no-op when the store component already did).\n useEffect(() => {\n void restoreStampLibrariesOnce(stamp);\n }, [stamp]);\n useEffect(() => {\n if (activeToolId !== 'stamp') setArmedId(null);\n }, [activeToolId]);\n\n const pick = (asset: StampAsset) => {\n setError(null);\n if (target) {\n void signature.placeMark({ assetId: asset.id }, { field: target }).catch((err) => {\n console.error('[embedpdf] placing the mark failed:', err);\n setError(t('demo.signError'));\n });\n return;\n }\n setArmedId(asset.id);\n void armAsset(asset.id).catch((err) => {\n console.error('[embedpdf] arm mark failed:', err);\n setArmedId(null);\n setError(t('demo.stampsArmError'));\n });\n };\n\n const canAddPerson = (config.libraries ?? 'many') === 'many' || rows.length === 0;\n const wantsInitials = (config.kinds ?? ['signature', 'initials']).includes('initials');\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"min-h-0 flex-1 overflow-y-auto p-3\">\n {rows.length === 0 ? (\n <div className=\"flex flex-col items-center gap-3 px-4 py-8 text-center\">\n <Icon name=\"signature\" size={32} className=\"text-fg-muted\" />\n <p className=\"text-fg-muted text-sm\">{t('demo.signaturesEmpty')}</p>\n </div>\n ) : (\n <ul className=\"flex flex-col gap-3\">\n {rows.map((row) => (\n <SignerRowView\n key={row.libraryId}\n row={row}\n armedId={armedId}\n wantsInitials={wantsInitials}\n onPick={pick}\n onAddInitials={() =>\n maker.open({ exclusive: 'modal', props: { libraryId: row.libraryId } })\n }\n />\n ))}\n </ul>\n )}\n <DocumentSignatures />\n </div>\n\n {invalidating && (\n <div className=\"border-border-subtle shrink-0 border-t px-3 py-2 text-xs text-amber-700\">\n {t('demo.signaturesInvalidating', { params: { field: invalidating } })}\n </div>\n )}\n {(error || target || armedId) && (\n <div\n className={`border-border-subtle shrink-0 border-t px-3 py-2 text-xs ${\n error ? 'text-red-600' : 'text-fg-muted'\n }`}\n >\n {error ??\n (target\n ? busy\n ? t('demo.signSigning')\n : t('demo.signaturesTargetHint')\n : t('demo.signaturesArmedHint'))}\n </div>\n )}\n\n {canAddPerson ? (\n <div className=\"border-border-subtle shrink-0 border-t p-3\">\n <button\n type=\"button\"\n onClick={() => maker.open({ exclusive: 'modal' })}\n className=\"border-border text-fg hover:bg-hover flex w-full items-center justify-center gap-2 rounded-md border px-3 py-1.5 text-sm\"\n >\n <Icon name=\"plus\" size={16} />\n {t('demo.signaturesNew')}\n </button>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction SignerRowView({\n row,\n armedId,\n wantsInitials,\n onPick,\n onAddInitials,\n}: {\n row: SignerRow;\n armedId: string | null;\n wantsInitials: boolean;\n onPick: (asset: StampAsset) => void;\n onAddInitials: () => void;\n}) {\n const t = useT();\n const stamp = useStamp();\n const [renaming, setRenaming] = useState<string | null>(null);\n\n const exportPdf = () => {\n const bytes = stamp.exportLibrary(row.libraryId);\n if (!bytes) return;\n const blob = new Blob([bytes as BlobPart], { type: 'application/pdf' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = `${row.name || 'signature'}.pdf`;\n a.click();\n URL.revokeObjectURL(url);\n };\n const commitRename = () => {\n const name = renaming?.trim();\n setRenaming(null);\n if (name && name !== row.name) void stamp.updateLibrary(row.libraryId, { name });\n };\n const iconButton = 'text-fg-muted hover:text-fg grid h-6 w-6 shrink-0 place-items-center rounded';\n\n return (\n <li className=\"border-border-subtle rounded-md border p-2\">\n <div className=\"flex items-center gap-1\">\n {renaming !== null ? (\n <input\n autoFocus\n value={renaming}\n onChange={(e) => setRenaming(e.target.value)}\n onBlur={commitRename}\n onKeyDown={(e) => {\n if (e.key === 'Enter') commitRename();\n if (e.key === 'Escape') setRenaming(null);\n }}\n className=\"border-border bg-surface text-fg min-w-0 flex-1 rounded border px-1.5 py-0.5 text-sm\"\n />\n ) : (\n <span className=\"text-fg min-w-0 flex-1 truncate text-sm font-medium\">{row.name}</span>\n )}\n <button\n type=\"button\"\n onClick={() => setRenaming(row.name)}\n title={t('demo.signaturesRename')}\n className={iconButton}\n >\n <Icon name=\"pencilMarker\" size={13} />\n </button>\n <button\n type=\"button\"\n onClick={exportPdf}\n title={t('demo.signaturesExport')}\n className={iconButton}\n >\n <Icon name=\"download\" size={13} />\n </button>\n <button\n type=\"button\"\n onClick={() => void stamp.removeLibrary(row.libraryId)}\n title={t('demo.signaturesRemove')}\n className={iconButton}\n >\n <Icon name=\"trash\" size={13} />\n </button>\n </div>\n <div className=\"mt-2 grid grid-cols-[2fr_1fr] gap-2\">\n {row.signatures.map((asset) => (\n <MarkThumb\n key={asset.id}\n asset={asset}\n label={t('demo.signatureLabel')}\n armed={armedId === asset.id}\n onPick={() => onPick(asset)}\n />\n ))}\n {wantsInitials ? (\n row.initials ? (\n <MarkThumb\n asset={row.initials}\n label={t('demo.initialsLabel')}\n armed={armedId === row.initials.id}\n onPick={() => onPick(row.initials!)}\n />\n ) : (\n <button\n type=\"button\"\n onClick={onAddInitials}\n title={t('demo.signaturesAddInitials')}\n className=\"border-border-subtle text-fg-muted hover:bg-hover flex h-16 items-center justify-center rounded-md border border-dashed text-xs\"\n >\n <Icon name=\"plus\" size={14} />\n </button>\n )\n ) : null}\n </div>\n </li>\n );\n}\n\nfunction MarkThumb({\n asset,\n label,\n armed,\n onPick,\n}: {\n asset: StampAsset;\n label: string;\n armed: boolean;\n onPick: () => void;\n}) {\n const url = useStampAssetPreviewUrl(asset.id);\n return (\n <button\n type=\"button\"\n onClick={onPick}\n title={label}\n aria-pressed={armed}\n className={`flex h-16 items-center justify-center rounded-md border p-1 ${\n armed\n ? 'border-accent bg-accent-light ring-accent ring-2'\n : 'border-border-subtle hover:border-border hover:bg-hover'\n }`}\n >\n {url ? (\n <img src={url} alt={label} className=\"max-h-full max-w-full object-contain\" />\n ) : (\n <span className=\"text-fg-muted text-xs\">{label}</span>\n )}\n </button>\n );\n}\n\n/** The signature fields of this document, with their state. */\nfunction DocumentSignatures() {\n const t = useT();\n const signature = useSignature();\n const snapshot = useSignatureSnapshot();\n const verdicts = useSignatureVerdicts();\n const { target } = useSignatureTarget();\n const [validating, setValidating] = useState(false);\n const fields = snapshot?.signatures ?? [];\n const verdictOf = (dto: SignatureDTO) =>\n verdicts?.find((v) => v.signature.index === dto.index) ?? null;\n // Three honest states: valid; valid on disk but unsaved edits would\n // invalidate it (the verdict judged the working copy); invalid on disk.\n const verdictLabel = (v: SignatureVerdict | null): string =>\n !v\n ? t('demo.signaturesSigned')\n : v.summary === 'valid'\n ? t('demo.verdictValid')\n : v.summary === 'valid-untrusted'\n ? t('demo.verdictValidUntrusted')\n : v.summary === 'indeterminate'\n ? t('demo.verdictIndeterminate')\n : v.modifications.basis === 'working-copy'\n ? t('demo.verdictWillInvalidate')\n : t('demo.verdictInvalid');\n const verdictTone = (v: SignatureVerdict | null): string =>\n !v || v.summary === 'indeterminate'\n ? 'text-fg-muted'\n : v.summary === 'invalid'\n ? v.modifications.basis === 'working-copy'\n ? 'text-amber-600'\n : 'text-red-600'\n : v.summary === 'valid-untrusted'\n ? 'text-amber-600'\n : 'text-green-600';\n const isTarget = (dto: SignatureDTO) =>\n !!target &&\n (target.kind === 'fqn'\n ? target.name === dto.fieldName\n : target.fieldObjectNumber ===\n (dto.field.kind === 'objectNumber' ? dto.field.fieldObjectNumber : -1));\n const validate = () => {\n setValidating(true);\n void signature.validate().finally(() => setValidating(false));\n };\n\n return (\n <div className=\"mt-4\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-fg-muted text-xs font-semibold uppercase tracking-wide\">\n {t('demo.signaturesInDocument')}\n </span>\n {fields.some((f) => f.signed) ? (\n <button\n type=\"button\"\n disabled={validating}\n onClick={validate}\n className=\"text-accent text-xs hover:underline disabled:opacity-60\"\n >\n {validating ? t('demo.signaturesValidating') : t('demo.signaturesValidate')}\n </button>\n ) : null}\n </div>\n {fields.length === 0 ? (\n <p className=\"text-fg-muted mt-1 text-xs\">{t('demo.signaturesNone')}</p>\n ) : (\n <ul className=\"mt-1 flex flex-col gap-1\">\n {fields.map((dto) => {\n const verdict = verdictOf(dto);\n return (\n <li key={dto.index}>\n <button\n type=\"button\"\n onClick={() =>\n dto.signed ? signature.inspect(dto.field) : signature.setTarget(dto.field)\n }\n className={`hover:bg-hover flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm ${\n isTarget(dto) ? 'bg-accent-light' : ''\n }`}\n >\n <Icon\n name={dto.signed ? 'check' : 'signature'}\n size={14}\n className={dto.signed ? 'text-green-600' : 'text-fg-muted'}\n />\n <span className=\"text-fg min-w-0 flex-1 truncate\">{dto.fieldName}</span>\n <span\n className={`shrink-0 text-right text-xs ${dto.signed ? verdictTone(verdict) : 'text-fg-muted'}`}\n >\n {dto.signed ? verdictLabel(verdict) : t('demo.signaturesUnsigned')}\n </span>\n </button>\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n}\n","/**\n * The static chrome around the toolbars: the left/right sidebars (shell\n * surfaces) and the bottom page-controls overlay. Deliberately minimal —\n * chrome-parity scope. Panels read their open state from plugin-shell; the\n * app owns their DOM.\n *\n * There is no built-in header: branding, a locale picker and a theme switch\n * are the EMBEDDER's chrome, not the viewer's. The frame keeps a `header`\n * socket for a slotted one (see Shell).\n */\nimport { useEffect } from 'react';\nimport { useSelector, useDocumentId } from '@embedpdf/react/runtime';\nimport { Stage, StageToken, usePages } from '@embedpdf/react/stage';\nimport { RenderLayer } from '@embedpdf/react/render';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { ThumbsStageToken } from '../config/stage';\nimport { Icon } from './icons';\nimport { AnnotationStylePanel } from './annotation-style';\nimport { CommentsPanel } from './comments-panel';\nimport { RedactionPanel } from './redaction-panel';\nimport { SearchPanel } from './search-panel';\nimport { StampsPanel } from './stamps-panel';\nimport { SignaturesPanel } from './signatures-panel';\n\n// ── left sidebar (thumbnails / outline tabs) ─────────────────────────────────\nexport function LeftSidebar() {\n const t = useT();\n const sidebar = useSurface('sidebar');\n if (!sidebar.isOpen) return null;\n return (\n <aside className=\"border-border-subtle bg-surface flex w-60 shrink-0 flex-col border-r\">\n <div className=\"border-border-subtle flex items-center gap-1 border-b p-2\">\n <span className=\"bg-accent-light text-accent rounded-md px-2 py-1 text-xs font-medium\">\n {t('demo.thumbnails')}\n </span>\n <span className=\"text-fg-muted rounded-md px-2 py-1 text-xs font-medium\">\n {t('demo.outline')}\n </span>\n <div className=\"flex-1\" />\n <button\n type=\"button\"\n onClick={sidebar.close}\n className=\"text-fg-muted hover:bg-hover grid h-7 w-7 place-items-center rounded-md\"\n >\n <Icon name=\"x\" size={16} />\n </button>\n </div>\n <ThumbnailList />\n </aside>\n );\n}\n\n// The thumbnail rail: the SAME document through the thumbnail Stage lens (a\n// single-column, fixed-zoom grid — see App's `stage-thumbs` plugin). Click a\n// thumb to navigate the MAIN lens; the rail follows the main view. Read-only —\n// no page edits (rotate/move/delete), just the page bitmap and its number.\nfunction ThumbnailList() {\n const { currentPage, goToPage } = usePages(); // the MAIN lens\n const { reveal } = usePages(ThumbsStageToken); // the SIDEBAR lens\n // Follow the main view: when its current page changes, make that thumb visible —\n // minimal movement, zero when it's already on screen.\n useEffect(() => reveal(currentPage), [currentPage, reveal]);\n return (\n <Stage\n token={ThumbsStageToken}\n zoomGestures={false} // fixed-magnification rail: cmd+wheel/pinch scrolls, never zooms\n className=\"flex-1\"\n style={{ position: 'relative' }}\n pageChrome={(page) => (\n <>\n {/* BOX-SPACE chrome: the click target + selection border hug the page\n box; the number sits in the reserved bottom band. Neither rotates. */}\n <button\n type=\"button\"\n onClick={() => goToPage(page.pageIndex)}\n title={`Page ${page.pageIndex + 1}`}\n style={{\n position: 'absolute',\n top: page.frame.top,\n left: page.frame.left,\n right: page.frame.right,\n bottom: page.frame.bottom,\n cursor: 'pointer',\n boxSizing: 'border-box',\n borderRadius: 4,\n border:\n page.pageIndex === currentPage\n ? '2px solid var(--ep-accent)'\n : '1px solid var(--ep-border-subtle)',\n boxShadow:\n page.pageIndex === currentPage ? '0 0 0 2px var(--ep-accent-light)' : 'none',\n }}\n />\n <div\n style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n height: page.frame.bottom,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 11,\n color: 'var(--ep-fg-muted)',\n pointerEvents: 'none',\n }}\n >\n {page.pageIndex + 1}\n </div>\n </>\n )}\n >\n {/* page-space content: the bitmap, which rotates with the page */}\n {() => <RenderLayer />}\n </Stage>\n );\n}\n\n// ── right sidebar (search / comment / style / redaction / stamps) ────────────\nexport function RightSidebar() {\n const t = useT();\n // Keys the SearchPanel below: the panel seeds its query box from the active\n // document's search state on mount, so it must remount when the active\n // document changes (switching tabs with the sidebar open) to re-seed.\n const documentId = useDocumentId();\n const search = useSurface('search');\n const comment = useSurface('comment');\n const style = useSurface('annotation-style');\n const redaction = useSurface('redaction');\n const stamps = useSurface('stamps');\n const signatures = useSurface('signatures');\n const active = search.isOpen\n ? 'search'\n : comment.isOpen\n ? 'comment'\n : style.isOpen\n ? 'style'\n : redaction.isOpen\n ? 'redaction'\n : stamps.isOpen\n ? 'stamps'\n : signatures.isOpen\n ? 'signatures'\n : null;\n if (!active) return null;\n\n const titleKey =\n active === 'search'\n ? 'demo.searchTitle'\n : active === 'comment'\n ? 'demo.commentsTitle'\n : active === 'redaction'\n ? 'demo.redactionTitle'\n : active === 'stamps'\n ? 'demo.stampsTitle'\n : active === 'signatures'\n ? 'demo.signaturesTitle'\n : 'demo.styleTitle';\n const close =\n active === 'search'\n ? search.close\n : active === 'comment'\n ? comment.close\n : active === 'redaction'\n ? redaction.close\n : active === 'stamps'\n ? stamps.close\n : active === 'signatures'\n ? signatures.close\n : style.close;\n\n return (\n <aside className=\"border-border-subtle bg-surface flex w-72 shrink-0 flex-col border-l\">\n <div className=\"border-border-subtle flex items-center justify-between border-b p-3\">\n <span className=\"text-fg text-sm font-semibold\">{t(titleKey)}</span>\n <button\n type=\"button\"\n onClick={close}\n className=\"text-fg-muted hover:bg-hover grid h-7 w-7 place-items-center rounded-md\"\n >\n <Icon name=\"x\" size={16} />\n </button>\n </div>\n {active === 'style' ? (\n <AnnotationStylePanel />\n ) : active === 'search' ? (\n <SearchPanel key={documentId ?? 'none'} />\n ) : active === 'redaction' ? (\n <RedactionPanel />\n ) : active === 'stamps' ? (\n <StampsPanel />\n ) : active === 'signatures' ? (\n <SignaturesPanel />\n ) : (\n <CommentsPanel key={documentId ?? 'none'} />\n )}\n </aside>\n );\n}\n\n// ── bottom page-controls overlay ─────────────────────────────────────────────\nexport function PageControls() {\n const t = useT();\n // the Stage cursor is a 0-based display index; people count from 1\n const current = useSelector(StageToken, (c) => c.currentPage() + 1);\n const total = useSelector(StageToken, (c) => c.pageCount());\n if (!total) return null;\n return (\n <div className=\"pointer-events-none absolute inset-x-0 bottom-5 flex justify-center\">\n <div className=\"border-border-subtle bg-elevated/95 text-fg-secondary pointer-events-auto rounded-full border px-4 py-1.5 text-sm shadow-lg backdrop-blur\">\n {t('demo.page', { params: { current, total } })}\n </div>\n </div>\n );\n}\n","import { useState } from 'react';\nimport { useRedaction } from '@embedpdf/react/redaction';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\n\n/**\n * The apply-all confirm modal (`redact-confirm` shell surface, `exclusive:\n * 'modal'` via the command router). Shows the pending count and the\n * CLIENT-SIDE collateral estimate — other annotations the apply will destroy —\n * before anything irreversible happens. The authoritative collateral count\n * comes back on the result.\n */\nexport function RedactConfirmModal() {\n const t = useT();\n const surface = useSurface('redact-confirm');\n const redaction = useRedaction();\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n if (!surface.isOpen) return null;\n\n const count = redaction.pendingCount();\n const collateral = redaction.estimateCollateral();\n\n const apply = async () => {\n setBusy(true);\n setError(null);\n try {\n await redaction.applyAll();\n surface.close();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <div className=\"fixed inset-0 z-50 grid place-items-center bg-black/40\">\n <div className=\"border-border bg-surface w-96 rounded-lg border p-4 shadow-xl\">\n <h2 className=\"text-fg text-base font-semibold\">{t('demo.redactConfirmTitle')}</h2>\n <p className=\"text-fg-muted mt-2 text-sm\">\n {t('demo.redactConfirmBody', { params: { count } })}\n </p>\n {collateral > 0 ? (\n <p className=\"mt-2 text-sm font-medium text-red-600\">\n {t('demo.redactConfirmCollateral', { params: { count: collateral } })}\n </p>\n ) : null}\n {error ? <p className=\"mt-2 text-sm text-red-600\">{error}</p> : null}\n <div className=\"mt-4 flex justify-end gap-2\">\n <button\n type=\"button\"\n disabled={busy}\n onClick={surface.close}\n className=\"border-border text-fg hover:bg-hover rounded-md border px-3 py-1.5 text-sm\"\n >\n {t('demo.cancel')}\n </button>\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => void apply()}\n className=\"rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-60\"\n >\n {busy ? t('demo.redactApplying') : t('demo.redactApply')}\n </button>\n </div>\n </div>\n </div>\n );\n}\n","/**\n * The sign dialog (`signature-sign` modal surface): a mark met a field and\n * the mode is `ask` — or a \"sign here\" flow wants the facts first. Shows\n * the mark as it will sit in the field, takes reason and location, offers\n * a certification when the config allows it, and either SEALS the field\n * (`signField`) or only draws the mark into it (`fillField`).\n */\nimport { useState } from 'react';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useStampAssetPreviewUrl } from '@embedpdf/react/stamp';\nimport { useSignature, type FormFieldRef, type Mark } from '@embedpdf/react/signature';\n\nexport function SignDialog() {\n const t = useT();\n const surface = useSurface('signature-sign');\n const signature = useSignature();\n const [reason, setReason] = useState('');\n const [location, setLocation] = useState('');\n // What the signature declares about later changes: a plain approval (form\n // filling and further signatures keep it valid; Acrobat's reading), or a\n // certification with its DocMDP permission. Only the FIRST signature can certify.\n const [signKind, setSignKind] = useState<'approval' | 'certify-3' | 'certify-2' | 'certify-1'>(\n 'approval',\n );\n const [busy, setBusy] = useState<'sign' | 'fill' | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const field = surface.props?.field as FormFieldRef | undefined;\n const mark = surface.props?.mark as Mark | undefined;\n const assetId = mark && 'assetId' in mark ? mark.assetId : null;\n const preview = useStampAssetPreviewUrl(assetId);\n if (!surface.isOpen || !field || !mark) return null;\n\n const attribution = {\n ...(reason.trim() ? { reason: reason.trim() } : {}),\n ...(location.trim() ? { location: location.trim() } : {}),\n };\n const run = async (kind: 'sign' | 'fill') => {\n setBusy(kind);\n setError(null);\n try {\n if (kind === 'sign') {\n await signature.signField({\n field,\n mark,\n attribution,\n ...(signKind !== 'approval' && signature.canCertify()\n ? { certify: { permission: Number(signKind.slice(-1)) as 1 | 2 | 3 } }\n : {}),\n });\n } else {\n await signature.fillField(field, mark);\n }\n surface.close();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(null);\n }\n };\n\n const input = 'border-border bg-surface text-fg w-full rounded border px-2 py-1.5 text-sm';\n return (\n <div className=\"fixed inset-0 z-50 grid place-items-center bg-black/40\">\n <div className=\"border-border bg-surface w-96 rounded-lg border p-4 shadow-xl\">\n <h2 className=\"text-fg text-base font-semibold\">{t('demo.signTitle')}</h2>\n <div className=\"border-border-subtle mt-3 flex h-24 items-center justify-center rounded-md border p-2\">\n {preview ? (\n <img src={preview} alt=\"\" className=\"max-h-full max-w-full object-contain\" />\n ) : (\n <span className=\"text-fg-muted text-sm\">{t('demo.signatureLabel')}</span>\n )}\n </div>\n <label className=\"text-fg-muted mt-3 block text-xs\">\n {t('demo.signReason')}\n <input value={reason} onChange={(e) => setReason(e.target.value)} className={input} />\n </label>\n <label className=\"text-fg-muted mt-2 block text-xs\">\n {t('demo.signLocation')}\n <input value={location} onChange={(e) => setLocation(e.target.value)} className={input} />\n </label>\n {signature.canCertify() ? (\n <label className=\"text-fg-muted mt-3 block text-xs\">\n {t('demo.signKind')}\n <select\n value={signKind}\n onChange={(e) => setSignKind(e.target.value as typeof signKind)}\n className={input}\n >\n <option value=\"approval\">{t('demo.signKindApproval')}</option>\n <option value=\"certify-3\">{t('demo.signKindCertifyAnnotate')}</option>\n <option value=\"certify-2\">{t('demo.signKindCertifyFill')}</option>\n <option value=\"certify-1\">{t('demo.signKindCertifyLocked')}</option>\n </select>\n </label>\n ) : null}\n {error ? <p className=\"mt-2 text-sm text-red-600\">{error}</p> : null}\n <div className=\"mt-4 flex justify-end gap-2\">\n <button\n type=\"button\"\n disabled={busy != null}\n onClick={surface.close}\n className=\"border-border text-fg hover:bg-hover rounded-md border px-3 py-1.5 text-sm\"\n >\n {t('demo.cancel')}\n </button>\n {signature.canFill() ? (\n <button\n type=\"button\"\n disabled={busy != null}\n onClick={() => void run('fill')}\n className=\"border-border text-fg hover:bg-hover rounded-md border px-3 py-1.5 text-sm disabled:opacity-60\"\n >\n {t('demo.signFill')}\n </button>\n ) : null}\n {signature.canSign() ? (\n <button\n type=\"button\"\n disabled={busy != null}\n onClick={() => void run('sign')}\n className=\"bg-accent text-on-accent rounded-md px-3 py-1.5 text-sm disabled:opacity-60\"\n >\n {busy === 'sign' ? t('demo.signSigning') : t('demo.signButton')}\n </button>\n ) : null}\n </div>\n </div>\n </div>\n );\n}\n","/**\n * The signature plugin's UI intents → shell surfaces. The plugin owns the\n * act and says WHAT happened; the chrome decides WHAT OPENS:\n *\n * target (a \"sign here\" click) → the signatures panel, right side\n * ask (mode 'ask' met a field) → the sign dialog (modal)\n * inspect (a signed field clicked) → the validation popover\n *\n * Mounted once per document view; renders nothing.\n */\nimport { useSignatureEvent } from '@embedpdf/react/signature';\nimport { useShell } from '@embedpdf/react/shell';\n\nexport function SignatureBridge() {\n const shell = useShell();\n useSignatureEvent((event) => {\n switch (event.type) {\n case 'target':\n if (event.field) shell.open('signatures', { exclusive: 'right' });\n return;\n case 'ask':\n shell.open('signature-sign', {\n exclusive: 'modal',\n props: { field: event.field, mark: event.mark },\n });\n return;\n case 'inspect':\n shell.open('signature-inspector', { props: { field: event.field } });\n return;\n case 'invalidating':\n // The notice lives in the signatures panel; make sure it is seen.\n shell.open('signatures', { exclusive: 'right' });\n return;\n default:\n return;\n }\n });\n return null;\n}\n","/**\n * The validation popover (`signature-inspector` surface): what a signed\n * field's signature says and whether it holds — the four independent facts\n * (integrity, cryptography, trust, changes since) and the signer's claims,\n * anchored at the widget when its box is known, plus the signed revision as\n * a download (the exact bytes the signature covers). Mounted in the Stage\n * overlay so `<Anchored>` can project onto the page.\n */\nimport { useEffect, useState } from 'react';\nimport { Anchored } from '@embedpdf/react/anchored';\nimport { useSelector } from '@embedpdf/react/runtime';\nimport { FormToken } from '@embedpdf/react/form';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport {\n useSignature,\n useSignatureSnapshot,\n useSignatureVerdicts,\n type FormFieldRef,\n type SignatureVerdict,\n} from '@embedpdf/react/signature';\nimport { Icon } from './icons';\n\nconst verdictKey = (v: SignatureVerdict | null): string =>\n !v\n ? 'demo.verdictIndeterminate'\n : v.summary === 'valid'\n ? 'demo.verdictValid'\n : v.summary === 'valid-untrusted'\n ? 'demo.verdictValidUntrusted'\n : v.summary === 'invalid'\n ? v.modifications.basis === 'working-copy'\n ? 'demo.verdictWillInvalidate'\n : 'demo.verdictInvalid'\n : 'demo.verdictIndeterminate';\n\n/** A PDF date string (`D:YYYYMMDDHHmmSSZ` or with a zone offset) as a locale date; the raw text when it is not one. */\nconst pdfDate = (raw: string): string => {\n const m = /^D:(\\d{4})(\\d{2})?(\\d{2})?(\\d{2})?(\\d{2})?(\\d{2})?(Z|[+-]\\d{2}'?\\d{2}'?)?/.exec(raw);\n if (!m) return raw;\n const [, y, mo = '01', d = '01', h = '00', mi = '00', s = '00', zone] = m;\n const offset =\n !zone || zone === 'Z'\n ? 'Z'\n : `${zone[0]}${zone.slice(1, 3)}:${zone.slice(3).replace(/'/g, '') || '00'}`;\n const date = new Date(`${y}-${mo}-${d}T${h}:${mi}:${s}${offset}`);\n return Number.isNaN(date.getTime()) ? raw : date.toLocaleString();\n};\n\nconst tone = (summary: SignatureVerdict['summary'] | null): string =>\n summary === 'valid'\n ? 'text-green-600'\n : summary === 'invalid'\n ? 'text-red-600'\n : summary === 'valid-untrusted'\n ? 'text-amber-600'\n : 'text-fg-muted';\n\nexport function SignatureInspector() {\n const t = useT();\n const surface = useSurface('signature-inspector');\n const signature = useSignature();\n const snapshot = useSignatureSnapshot();\n const verdicts = useSignatureVerdicts();\n const [validating, setValidating] = useState(false);\n const field = surface.props?.field as FormFieldRef | undefined;\n const dto = field ? signature.signatureOf(field) : null;\n const verdict = field ? signature.verdictOf(field) : null;\n const widget = dto?.widget ?? null;\n const box = useSelector(FormToken, (c) =>\n widget && widget.annotObjectNumber > 0\n ? (c.fillItem(widget.annotObjectNumber)?.box ?? null)\n : null,\n );\n\n // Open on a field never validated: judge it now.\n useEffect(() => {\n if (!surface.isOpen || !dto?.signed || verdicts) return;\n setValidating(true);\n void signature.validate().finally(() => setValidating(false));\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [surface.isOpen, dto?.index]);\n\n if (!surface.isOpen || !field || !dto || !snapshot) return null;\n\n const revalidate = () => {\n setValidating(true);\n void signature.validate().finally(() => setValidating(false));\n };\n const summary = verdict?.summary ?? null;\n const modifications = verdict?.modifications.verdict ?? null;\n const row = (label: string, value: string, className = 'text-fg') => (\n <div className=\"flex items-baseline justify-between gap-3 text-xs\">\n <span className=\"text-fg-muted\">{label}</span>\n <span className={`text-right ${className}`}>{value}</span>\n </div>\n );\n\n const card = (\n <div className=\"border-border bg-elevated w-72 rounded-lg border p-3 text-sm shadow-xl\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-fg font-semibold\">{t('demo.inspectTitle')}</span>\n <button\n type=\"button\"\n onClick={surface.close}\n className=\"text-fg-muted hover:bg-hover grid h-6 w-6 place-items-center rounded\"\n aria-label={t('demo.cancel')}\n >\n <Icon name=\"x\" size={14} />\n </button>\n </div>\n <p className={`mt-1 text-sm font-medium ${tone(summary)}`}>\n {validating ? t('demo.signaturesValidating') : t(verdictKey(verdict))}\n </p>\n <div className=\"mt-2 flex flex-col gap-1\">\n {row(t('demo.inspectSigner'), dto.signer.name ?? '—')}\n {dto.signer.reason ? row(t('demo.inspectReason'), dto.signer.reason) : null}\n {dto.signer.location ? row(t('demo.inspectLocation'), dto.signer.location) : null}\n {dto.signer.claimedTime\n ? row(t('demo.inspectTime'), pdfDate(dto.signer.claimedTime))\n : null}\n </div>\n <div className=\"border-border-subtle mt-2 flex flex-col gap-1 border-t pt-2\">\n {row(\n t('demo.inspectIntegrity'),\n verdict?.integrity ?? '—',\n tone(\n verdict?.integrity === 'valid'\n ? 'valid'\n : verdict?.integrity === 'invalid'\n ? 'invalid'\n : null,\n ),\n )}\n {row(t('demo.inspectCryptography'), verdict?.cryptography ?? '—')}\n {row(t('demo.inspectTrust'), verdict?.trust ?? '—')}\n {row(\n t('demo.inspectChanges'),\n modifications === 'unchanged'\n ? verdict?.modifications.undone\n ? t('demo.verdictRestored')\n : t('demo.verdictUnchanged')\n : modifications === 'permitted'\n ? t('demo.verdictPermitted')\n : modifications === 'forbidden'\n ? t('demo.verdictForbidden')\n : '—',\n modifications === 'forbidden' ? 'text-red-600' : 'text-fg',\n )}\n {verdict?.modifications.laterRevisions\n ? row(t('demo.inspectLaterRevisions'), String(verdict.modifications.laterRevisions))\n : null}\n </div>\n <div className=\"mt-3 flex justify-end gap-2\">\n <button\n type=\"button\"\n disabled={validating}\n onClick={revalidate}\n className=\"border-border text-fg hover:bg-hover rounded-md border px-2 py-1 text-xs disabled:opacity-60\"\n >\n {t('demo.signaturesValidate')}\n </button>\n <DownloadRevision field={field} />\n </div>\n </div>\n );\n\n if (widget && widget.pageObjectNumber > 0 && box) {\n return (\n <Anchored anchor={{ pon: widget.pageObjectNumber, bounds: box }} placement=\"bottom\" gap={8}>\n {card}\n </Anchored>\n );\n }\n return <div className=\"absolute right-4 top-4 z-40\">{card}</div>;\n}\n\n/** The signed revision — the exact bytes the signature covers — as a file. */\nfunction DownloadRevision({ field }: { field: FormFieldRef }) {\n const t = useT();\n const signature = useSignature();\n const dto = signature.signatureOf(field);\n const [busy, setBusy] = useState(false);\n if (!dto || dto.revisionIndex === null) return null;\n const revisionIndex = dto.revisionIndex;\n const run = async () => {\n setBusy(true);\n try {\n const bytes = await signature.revisionBytes(revisionIndex);\n const blob = new Blob([bytes as BlobPart], { type: 'application/pdf' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = `${dto.fieldName}-signed.pdf`;\n a.click();\n URL.revokeObjectURL(url);\n } catch (err) {\n console.error('[embedpdf] signed revision download failed:', err);\n } finally {\n setBusy(false);\n }\n };\n return (\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => void run()}\n className=\"border-border text-fg hover:bg-hover rounded-md border px-2 py-1 text-xs disabled:opacity-60\"\n >\n {t('demo.inspectDownload')}\n </button>\n );\n}\n","/**\n * The mark maker (`signature-maker` modal surface): a person's signature and\n * initials, drawn, typed, or uploaded, saved as ONE library of kind\n * `signatures` — the file IS the person (Preview's model). Chrome code over\n * the stamp plugin's generic calls: `createLibrary` + `addAsset({ mark })`;\n * rename/export/delete are the library verbs. Opened on an existing library\n * (`props.libraryId`) it only adds the missing initials.\n */\nimport { useEffect, useRef, useState } from 'react';\nimport { useKernel } from '@embedpdf/react/runtime';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useStamp, type MarkSource } from '@embedpdf/react/stamp';\nimport {\n INITIALS_MARK_NAME,\n SIGNATURE_MARK_NAME,\n SIGNATURES_LIBRARY_KIND,\n} from '@embedpdf/react/signature';\nimport { useSignaturesConfig } from '../config-context';\nimport { Icon } from './icons';\n\ntype Tab = 'draw' | 'type' | 'upload';\ntype Stroke = Array<{ x: number; y: number }>;\n\nconst PAD = { width: 360, height: 120 };\nconst BUILTIN_FONTS: ReadonlyArray<{ key: string; label: string }> = [\n { key: 'helvetica-oblique', label: 'Helvetica' },\n { key: 'times-italic', label: 'Times' },\n];\n\n/** One pad: draw / type / upload, producing a `MarkSource` or null. */\nfunction MarkPad({\n value,\n onChange,\n fonts,\n registerFont,\n}: {\n value: MarkSource | null;\n onChange: (mark: MarkSource | null) => void;\n fonts: ReadonlyArray<{ key: string; label: string }>;\n registerFont: (key: string) => Promise<void>;\n}) {\n const t = useT();\n const [tab, setTab] = useState<Tab>('draw');\n const [strokes, setStrokes] = useState<Stroke[]>([]);\n const [text, setText] = useState('');\n const [font, setFont] = useState(fonts[0]?.key ?? 'helvetica-oblique');\n const [fileName, setFileName] = useState<string | null>(null);\n const canvas = useRef<HTMLCanvasElement>(null);\n const drawing = useRef<Stroke | null>(null);\n\n // Paint the strokes (device-pixel sharp).\n useEffect(() => {\n const el = canvas.current;\n if (!el) return;\n const dpr = window.devicePixelRatio || 1;\n el.width = PAD.width * dpr;\n el.height = PAD.height * dpr;\n const ctx = el.getContext('2d');\n if (!ctx) return;\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n ctx.clearRect(0, 0, PAD.width, PAD.height);\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n ctx.lineWidth = 2.5;\n ctx.strokeStyle = getComputedStyle(el).color || '#000';\n for (const stroke of strokes) {\n ctx.beginPath();\n stroke.forEach((p, i) => (i === 0 ? ctx.moveTo(p.x, p.y) : ctx.lineTo(p.x, p.y)));\n ctx.stroke();\n }\n }, [strokes, tab]);\n\n const point = (e: React.PointerEvent<HTMLCanvasElement>) => {\n const r = e.currentTarget.getBoundingClientRect();\n return { x: e.clientX - r.left, y: e.clientY - r.top };\n };\n const commitStrokes = (next: Stroke[]) => {\n setStrokes(next);\n onChange(\n next.length ? { kind: 'ink', strokes: next, color: '#000000', strokeWidth: 2.5 } : null,\n );\n };\n const commitText = async (next: string, key: string) => {\n setText(next);\n setFont(key);\n if (!next.trim()) {\n onChange(null);\n return;\n }\n await registerFont(key);\n onChange({ kind: 'text', text: next.trim(), fontFamily: key, color: '#000000', fontSize: 36 });\n };\n const pickFile = (file: File) => {\n setFileName(file.name);\n onChange(\n file.type === 'application/pdf'\n ? { kind: 'pdf', source: file, pageIndex: 0 }\n : { kind: 'image', source: file },\n );\n };\n\n const tabClass = (id: Tab) =>\n `rounded px-2 py-1 text-xs font-medium ${tab === id ? 'bg-accent text-on-accent' : 'text-fg-muted hover:bg-hover'}`;\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center gap-1\">\n <button type=\"button\" className={tabClass('draw')} onClick={() => setTab('draw')}>\n {t('demo.makerDraw')}\n </button>\n <button type=\"button\" className={tabClass('type')} onClick={() => setTab('type')}>\n {t('demo.makerType')}\n </button>\n <button type=\"button\" className={tabClass('upload')} onClick={() => setTab('upload')}>\n {t('demo.makerUpload')}\n </button>\n <div className=\"flex-1\" />\n {value ? (\n <button\n type=\"button\"\n onClick={() => {\n commitStrokes([]);\n setText('');\n setFileName(null);\n onChange(null);\n }}\n className=\"text-fg-muted hover:text-fg text-xs\"\n >\n {t('demo.makerClear')}\n </button>\n ) : null}\n </div>\n {tab === 'draw' ? (\n <canvas\n ref={canvas}\n style={{ width: PAD.width, height: PAD.height, touchAction: 'none' }}\n className=\"border-border-subtle bg-surface text-fg rounded-md border\"\n onPointerDown={(e) => {\n e.currentTarget.setPointerCapture(e.pointerId);\n drawing.current = [point(e)];\n setStrokes((s) => [...s, drawing.current!]);\n }}\n onPointerMove={(e) => {\n if (!drawing.current) return;\n drawing.current.push(point(e));\n setStrokes((s) => [...s.slice(0, -1), [...drawing.current!]]);\n }}\n onPointerUp={() => {\n if (!drawing.current) return;\n const done = drawing.current;\n drawing.current = null;\n setStrokes((s) => {\n const next = [...s.slice(0, -1), done];\n commitStrokes(next);\n return next;\n });\n }}\n />\n ) : tab === 'type' ? (\n <div className=\"flex flex-col gap-2\">\n <input\n value={text}\n placeholder={t('demo.makerTypePlaceholder')}\n onChange={(e) => void commitText(e.target.value, font)}\n className=\"border-border bg-surface text-fg w-full rounded border px-2 py-1.5 text-sm\"\n />\n <label className=\"text-fg-muted flex items-center gap-2 text-xs\">\n {t('demo.makerFont')}\n <select\n value={font}\n onChange={(e) => void commitText(text, e.target.value)}\n className=\"border-border bg-surface text-fg rounded border px-2 py-1 text-xs\"\n >\n {fonts.map((f) => (\n <option key={f.key} value={f.key}>\n {f.label}\n </option>\n ))}\n </select>\n </label>\n </div>\n ) : (\n <label className=\"border-border-subtle text-fg-muted hover:bg-hover flex h-24 cursor-pointer items-center justify-center rounded-md border border-dashed text-sm\">\n {fileName ?? t('demo.makerUploadHint')}\n <input\n type=\"file\"\n accept=\"image/png,image/jpeg,application/pdf\"\n className=\"hidden\"\n onChange={(e) => {\n const file = e.currentTarget.files?.[0];\n e.currentTarget.value = '';\n if (file) pickFile(file);\n }}\n />\n </label>\n )}\n </div>\n );\n}\n\nexport function SignatureMakerModal() {\n const t = useT();\n const surface = useSurface('signature-maker');\n const stamp = useStamp();\n const kernel = useKernel();\n const config = useSignaturesConfig();\n const [name, setName] = useState('');\n const [signatureMark, setSignatureMark] = useState<MarkSource | null>(null);\n const [initialsMark, setInitialsMark] = useState<MarkSource | null>(null);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const existingId = surface.props?.libraryId as string | undefined;\n const existing = existingId ? stamp.library(existingId) : null;\n const wantsInitials = (config.kinds ?? ['signature', 'initials']).includes('initials');\n const fonts = [\n ...(config.fonts ?? []).map((f) => ({ key: f.key, label: f.label })),\n ...BUILTIN_FONTS,\n ];\n const registered = useRef(new Set<string>());\n // A configured script face is registered on the engine the stamp plugin\n // authors with (the viewer's own) the first time a typed mark uses it.\n const registerFont = async (key: string) => {\n const spec = config.fonts?.find((f) => f.key === key);\n if (!spec || registered.current.has(key) || !kernel.engine.fonts) return;\n const response = await fetch(spec.url);\n if (!response.ok) throw new Error(`${spec.url}: HTTP ${response.status}`);\n await kernel.engine.fonts.register({ key, data: new Uint8Array(await response.arrayBuffer()) });\n registered.current.add(key);\n };\n\n if (!surface.isOpen) return null;\n\n const canSave = existing ? initialsMark != null : name.trim().length > 0 && signatureMark != null;\n const save = async () => {\n setBusy(true);\n setError(null);\n try {\n if (existing) {\n await stamp.addAsset({\n libraryId: existing.id,\n name: INITIALS_MARK_NAME,\n label: t('demo.initialsLabel'),\n mark: initialsMark!,\n });\n } else {\n const libraryId = await stamp.createLibrary(name.trim(), { kind: SIGNATURES_LIBRARY_KIND });\n await stamp.addAsset({\n libraryId,\n name: SIGNATURE_MARK_NAME,\n label: t('demo.signatureLabel'),\n mark: signatureMark!,\n });\n if (initialsMark) {\n await stamp.addAsset({\n libraryId,\n name: INITIALS_MARK_NAME,\n label: t('demo.initialsLabel'),\n mark: initialsMark,\n });\n }\n }\n setName('');\n setSignatureMark(null);\n setInitialsMark(null);\n surface.close();\n } catch (err) {\n console.error('[embedpdf] saving the signature failed:', err);\n setError(t('demo.makerError'));\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <div className=\"fixed inset-0 z-50 grid place-items-center bg-black/40\">\n <div className=\"border-border bg-surface w-[26rem] rounded-lg border p-4 shadow-xl\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-fg text-base font-semibold\">\n {existing ? t('demo.signaturesAddInitials') : t('demo.makerTitle')}\n </h2>\n <button\n type=\"button\"\n onClick={surface.close}\n className=\"text-fg-muted hover:bg-hover grid h-7 w-7 place-items-center rounded-md\"\n aria-label={t('demo.cancel')}\n >\n <Icon name=\"x\" size={16} />\n </button>\n </div>\n {existing ? null : (\n <label className=\"text-fg-muted mt-3 block text-xs\">\n {t('demo.makerName')}\n <input\n value={name}\n placeholder={t('demo.makerNamePlaceholder')}\n onChange={(e) => setName(e.target.value)}\n className=\"border-border bg-surface text-fg mt-1 w-full rounded border px-2 py-1.5 text-sm\"\n />\n </label>\n )}\n {existing ? null : (\n <div className=\"mt-3\">\n <p className=\"text-fg mb-1 text-xs font-semibold uppercase tracking-wide\">\n {t('demo.signatureLabel')}\n </p>\n <MarkPad\n value={signatureMark}\n onChange={setSignatureMark}\n fonts={fonts}\n registerFont={registerFont}\n />\n </div>\n )}\n {wantsInitials ? (\n <div className=\"mt-3\">\n <p className=\"text-fg mb-1 text-xs font-semibold uppercase tracking-wide\">\n {t('demo.initialsLabel')}\n {existing ? null : (\n <span className=\"text-fg-muted ml-1 font-normal normal-case tracking-normal\">\n {t('demo.makerOptional')}\n </span>\n )}\n </p>\n <MarkPad\n value={initialsMark}\n onChange={setInitialsMark}\n fonts={fonts}\n registerFont={registerFont}\n />\n </div>\n ) : null}\n {error ? <p className=\"mt-2 text-sm text-red-600\">{error}</p> : null}\n <div className=\"mt-4 flex justify-end gap-2\">\n <button\n type=\"button\"\n disabled={busy}\n onClick={surface.close}\n className=\"border-border text-fg hover:bg-hover rounded-md border px-3 py-1.5 text-sm\"\n >\n {t('demo.cancel')}\n </button>\n <button\n type=\"button\"\n disabled={busy || !canSave}\n onClick={() => void save()}\n className=\"bg-accent text-on-accent rounded-md px-3 py-1.5 text-sm disabled:opacity-60\"\n >\n {busy ? t('demo.makerSaving') : t('demo.makerSave')}\n </button>\n </div>\n </div>\n </div>\n );\n}\n","/**\n * Boot-state panes for the document area — what renders INSTEAD of the Stage\n * while the selected tab's document isn't ready:\n *\n * `locked` → <PasswordPrompt/> (per-tab, v2's document-password-prompt port)\n * `error` → <DocumentError/>\n *\n * Both are per-TAB, not modal: several tabs can be locked/broken at once and\n * switching tabs stays free. The prompt drives ONE call —\n * `documents.unlock(id, { password })` — identical on the local (worker loads\n * the parked bytes) and cloud (/access grant) engines. The \"incorrect\" copy\n * keys on a real rejection: either this session's failed attempt, or\n * `passwordProvided` (a config-supplied password the engine already rejected).\n */\nimport { useState } from 'react';\nimport { useDocumentId, useDocuments } from '@embedpdf/react/runtime';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\n\nexport function PasswordPrompt() {\n const docId = useDocumentId();\n const { docs, unlock, close } = useDocuments();\n const t = useT();\n const [password, setPassword] = useState('');\n const [rejected, setRejected] = useState(false);\n const [busy, setBusy] = useState(false);\n\n const doc = docs.find((d) => d.id === docId);\n if (!docId || !doc) return null;\n const incorrect = rejected || doc.passwordProvided === true;\n\n const submit = async () => {\n if (busy || !password.trim()) return;\n setBusy(true);\n try {\n await unlock(docId, { password });\n // success → the tab promotes to ready and this pane unmounts\n } catch {\n setRejected(true);\n setPassword('');\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <div className=\"bg-app flex h-full w-full items-center justify-center p-8\">\n <div className=\"bg-surface border-border w-full max-w-sm rounded-xl border p-6 shadow-lg\">\n <div className=\"flex flex-col items-center text-center\">\n <div className=\"bg-accent-light mb-4 rounded-full p-4\">\n <Icon name=\"lock\" size={28} className=\"text-accent\" />\n </div>\n <h3 className=\"text-fg text-lg font-semibold\">{t('passwordPrompt.title')}</h3>\n {doc.name && <p className=\"text-fg-muted mt-1 text-sm\">{doc.name}</p>}\n </div>\n\n <p className=\"text-fg-secondary mt-4 text-center text-sm\">\n {incorrect ? t('passwordPrompt.incorrect') : t('passwordPrompt.required')}\n </p>\n\n <div className=\"mt-5\">\n <label className=\"text-fg mb-1.5 block text-sm font-medium\" htmlFor=\"doc-password\">\n {t('passwordPrompt.label')}\n </label>\n <input\n id=\"doc-password\"\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && void submit()}\n disabled={busy}\n placeholder={t('passwordPrompt.placeholder')}\n className=\"bg-surface border-border focus:border-accent focus:ring-accent text-fg placeholder:text-fg-muted block w-full rounded-md border px-3 py-2.5 text-sm focus:outline-none focus:ring-1 disabled:opacity-50\"\n autoFocus\n />\n </div>\n\n {incorrect && (\n <div className=\"mt-3 flex items-center gap-2 rounded-md border border-red-500/40 bg-red-500/10 p-3\">\n <Icon name=\"alertTriangle\" size={16} className=\"flex-shrink-0 text-red-500\" />\n <p className=\"text-sm text-red-500\">{t('passwordPrompt.incorrectWarning')}</p>\n </div>\n )}\n\n <div className=\"mt-6 flex gap-3\">\n <button\n type=\"button\"\n onClick={() => void close(docId)}\n disabled={busy}\n className=\"border-border text-fg-secondary hover:bg-hover flex-1 cursor-pointer rounded-md border px-4 py-2.5 text-sm font-medium transition-colors disabled:opacity-50\"\n >\n {t('passwordPrompt.cancel')}\n </button>\n <button\n type=\"button\"\n onClick={() => void submit()}\n disabled={busy || !password.trim()}\n className=\"bg-accent text-on-accent flex-1 cursor-pointer rounded-md px-4 py-2.5 text-sm font-medium transition-colors hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {busy ? t('passwordPrompt.opening') : t('passwordPrompt.open')}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\nexport function DocumentError() {\n const docId = useDocumentId();\n const { docs, close } = useDocuments();\n const t = useT();\n const doc = docs.find((d) => d.id === docId);\n if (!docId || !doc) return null;\n\n return (\n <div className=\"bg-app flex h-full w-full items-center justify-center p-8\">\n <div className=\"bg-surface border-border flex max-w-sm flex-col items-center rounded-xl border p-6 text-center shadow-lg\">\n <div className=\"mb-4 rounded-full bg-red-500/10 p-4\">\n <Icon name=\"alertTriangle\" size={28} className=\"text-red-500\" />\n </div>\n <h3 className=\"text-fg text-lg font-semibold\">{t('documentError.title')}</h3>\n {doc.name && <p className=\"text-fg-muted mt-1 text-sm\">{doc.name}</p>}\n <p className=\"text-fg-secondary mt-2 text-sm\">{t('documentError.unknown')}</p>\n <button\n type=\"button\"\n onClick={() => void close(docId)}\n className=\"bg-accent text-on-accent mt-5 w-full cursor-pointer rounded-md px-4 py-2.5 text-sm font-medium transition-colors hover:opacity-90\"\n >\n {t('documentError.close')}\n </button>\n </div>\n </div>\n );\n}\n","/**\n * The viewer shell — the snippet's layout, driven entirely by the v3 commands\n * + measured-toolbar system.\n *\n * ── header socket (empty unless a child fills it) ─────────\n * ── main toolbar (measured; auto-overflows) ───────────────\n * ── mode band (DERIVED from the shell's open mode surface) ─\n * left sidebar │ Stage (pages) │ right sidebar\n * ──────────── page-controls overlay ──────────────────────\n *\n * The workspace/document split is structural: header + toolbars are\n * workspace-scoped and render at t≈0 (translated, measured) while the wasm\n * engine still boots; everything document-scoped sits inside <DocumentGate>,\n * whose fallback is the empty-workspace state (v2's loader, but UNDER a live\n * toolbar instead of replacing the whole app).\n *\n * Which mode band shows is not stored anywhere: it's a projection of\n * plugin-shell's exclusive 'mode' surface, read null-safely so the band simply\n * doesn't exist without a document.\n */\nimport { useMemo, type ReactNode } from 'react';\nimport {\n DocumentGate,\n useDocumentId,\n useDocumentStatus,\n useOptionalSelector,\n} from '@embedpdf/react/runtime';\nimport { Stage } from '@embedpdf/react/stage';\nimport { Scrollbar } from '@embedpdf/react/scrollbar';\nimport { RenderLayer } from '@embedpdf/react/render';\nimport { SelectionClipboard, SelectionHandles, SelectionLayer } from '@embedpdf/react/selection';\nimport { AnnotationLayer, useFilePickerProvider } from '@embedpdf/react/annotation';\nimport { LinkLayer } from '@embedpdf/react/link';\nimport type { AnnotationRenderer } from '@embedpdf/react/annotation';\nimport { useActionsUiAdapter } from '@embedpdf/react/actions';\nimport { formWidgetRenderer } from '@embedpdf/react/form';\nimport { SearchLayer } from '@embedpdf/react/search';\nimport { useCommandShortcuts } from '@embedpdf/react/commands';\nimport { ShellToken } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { getModeBar } from './config/chrome';\nimport { useChromeSchema } from './config-context';\nimport { AppToolbar } from './ui/toolbar';\nimport { AnnotationFontsProvider } from './ui/annotation-fonts';\nimport { AnnotationStrip } from './ui/annotation-strip';\nimport { SelectionStrip } from './ui/selection-strip';\nimport { TabBar } from './ui/tab-bar';\nimport { ArmedToolCursor } from './ui/tool-cursor';\nimport { LeftSidebar, RightSidebar, PageControls } from './ui/panels';\nimport { RedactConfirmModal } from './ui/redact-confirm';\nimport { SignDialog } from './ui/sign-dialog';\nimport { SignatureBridge } from './ui/signature-bridge';\nimport { SignatureInspector } from './ui/signature-inspector';\nimport { SignatureMakerModal } from './ui/signature-maker';\nimport { StampLibraryStore } from './ui/stamp-store';\nimport { DocumentError, PasswordPrompt } from './ui/document-boot';\n\n// Annotation renderers — module scope, per the AnnotationRenderer identity\n// rule. One entry today: form widgets render as fill controls while the form\n// plugin's Behavior is engaged.\nconst ANNOTATION_RENDERERS: AnnotationRenderer[] = [formWidgetRenderer];\n\nfunction ModeBand({ edge }: { edge: 'top' | 'bottom' }) {\n const schema = useChromeSchema();\n // The mode list is DERIVED from the chrome's modeBars keys — adding a custom\n // mode is one command + one bar schema in config, not a shell change.\n const modeSurfaces = useMemo(() => Object.keys(schema.modeBars ?? {}), [schema]);\n const activeMode = useOptionalSelector(\n ShellToken,\n (s) => modeSurfaces.find((m) => s.isOpen(m)) ?? null,\n null,\n );\n if (!activeMode) return null;\n const bar = getModeBar(schema, activeMode);\n if (!bar) return null;\n return (\n <div\n className={`border-border bg-surface-alt flex shrink-0 items-center px-4 py-2 ${\n edge === 'top' ? 'border-b' : 'border-t'\n }`}\n >\n <AppToolbar bar={bar} className=\"w-full\" />\n </div>\n );\n}\n\n/** The empty-workspace state: shown while the initial documents (and the\n * engine behind them) are still loading — or if the user closes every tab. */\nfunction OpeningDocuments() {\n const t = useT();\n return (\n <div className=\"grid h-full w-full place-items-center\">\n <div className=\"text-fg-muted flex flex-col items-center gap-3\">\n <div className=\"border-border-subtle border-t-accent h-8 w-8 animate-spin rounded-full border-2\" />\n <div className=\"text-sm\">{t('demo.opening')}</div>\n </div>\n </div>\n );\n}\n\n/**\n * The document area's lifecycle switch. A `locked` tab shows its password\n * prompt, an `error` tab its error pane — per TAB (keyed by document), so\n * several can coexist and tab switching stays free. Everything else is the\n * ready-gated Stage; the gate's fallback covers `loading`.\n */\nfunction DocumentArea({ children }: { children: ReactNode }) {\n const docId = useDocumentId();\n const status = useDocumentStatus();\n if (status === 'locked') return <PasswordPrompt key={docId} />;\n if (status === 'error') return <DocumentError key={docId} />;\n return <DocumentGate fallback={<OpeningDocuments />}>{children}</DocumentGate>;\n}\n\nexport function Shell() {\n useCommandShortcuts();\n // Click-then-pick tools (stamp, file attachment) → click a page → file dialog\n // opens → the file lands where you clicked. One line: the default provider is\n // the built-in file picker honouring each tool's `accept` filter (swap it for\n // a custom picker, or pass null to disable). The plugin stays DOM-free.\n useFilePickerProvider();\n // The ONE UI port for the action engine AND every script-produced effect:\n // sanitized URI opens, Named `Print`, script alerts (boot/lifecycle nags\n // suppressed by default), and script page navigation.\n useActionsUiAdapter();\n const schema = useChromeSchema();\n\n // The FRAME: region arrangement & visibility from the chrome value (see\n // FrameSchema). Regions render as named <slot> sockets with the built-ins\n // as fallback — light-DOM children of <embedpdf-viewer> replace them; in\n // plain light DOM a slot just displays its fallback (UA display:contents),\n // so this package's direct React consumers see no difference. A region\n // hidden by the frame hides its socket too: visibility outranks content.\n const frame = schema.frame ?? {};\n const toolbarEdge = frame.toolbar ?? 'top';\n\n // main toolbar — measured; degrades + overflows with zero config.\n // Deliberately OUTSIDE the gate: chrome renders before any document.\n // Bar id 'main' is the shell's one structural expectation — an owned\n // chrome without it simply has no main toolbar. Its mode band rides the\n // CONTENT side, whichever edge the frame picked.\n const toolbarBand = schema.bars.main && (\n <div\n part=\"toolbar\"\n className={`border-border bg-surface flex shrink-0 items-center px-4 py-2 ${\n toolbarEdge === 'top' ? 'border-b' : 'border-t'\n }`}\n >\n <AppToolbar bar={schema.bars.main} className=\"w-full\" />\n </div>\n );\n\n return (\n <AnnotationFontsProvider>\n <div className=\"bg-app text-fg flex h-full flex-col\">\n {/* the user's stamp + signature libraries: restored once, persisted for\n the workspace's lifetime (workspace-scoped, like the stamp plugin) */}\n <StampLibraryStore />\n {/* The header socket. The chrome ships NO header of its own — branding,\n locale pickers and theme switches are the embedder's chrome, not the\n viewer's — so this renders nothing until a child fills the slot. */}\n {(frame.header ?? true) && <slot name=\"header\" />}\n\n {/* the v2 document tab bar — the kernel's document registry IS the tab model */}\n {(frame.tabs ?? 'always') !== 'never' && (\n <slot name=\"tabs\">\n <TabBar visibility={frame.tabs ?? 'always'} />\n </slot>\n )}\n\n {toolbarEdge === 'top' && (\n <>\n {toolbarBand}\n <ModeBand edge=\"top\" />\n </>\n )}\n\n <div className=\"relative flex min-h-0 flex-1\">\n <DocumentArea>\n <LeftSidebar />\n <div className=\"relative min-w-0 flex-1\">\n {/* the armed tool's cursor: its toolbar icon as a real CSS cursor\n (zero-lag; the hub hides it over annotations/fields/gaps) */}\n <ArmedToolCursor />\n {/* ctrl/cmd+C and native Edit→Copy for the text selection —\n prefetches on commit so the copy event answers synchronously.\n Renders nothing; mount ONCE per document view. */}\n <SelectionClipboard />\n <Stage\n overlay={\n <>\n <AnnotationStrip />\n <SelectionStrip />\n {/* a signed field's facts, anchored at its widget */}\n <SignatureInspector />\n {/* touch: draggable start/end selection handles (long-press\n selects a word; the lollipops grow it from there) */}\n <SelectionHandles />\n {/* headless scrollbars: geometry/behavior from the stage's\n scroller contract; the look is index.css (data-attrs) */}\n <Scrollbar axis=\"y\" />\n <Scrollbar axis=\"x\" />\n </>\n }\n className=\"h-full w-full\"\n style={{ background: 'var(--ep-canvas)' }}\n >\n {() => (\n <>\n {/* Base + deep-zoom tiles in one layer. Tiles engage by\n demand arithmetic when the view wants more pixels than\n the base budget supplies — the thumbnail rail's demand\n never does, so it mounts the same layer for free. */}\n <RenderLayer annotations={false} />\n <SelectionLayer />\n <SearchLayer />\n {/* Clickable links (nav plane): anchors under the default\n pointer/pan tools; stands down whenever an authoring\n tool is active (the annotation plane owns links then).\n Below the AnnotationLayer so an editing free-text box\n wins pointer hits; the annotation layer's own surface\n is pointer-events: none, so clicks fall through to the\n anchors everywhere else. */}\n <LinkLayer />\n {/* Form widgets plug into the annotation stack: engaged\n (fill mode) they render as fill controls over the baked\n appearance; under the Form tab they're plain editable\n annotations. */}\n <AnnotationLayer renderers={ANNOTATION_RENDERERS} />\n </>\n )}\n </Stage>\n <PageControls />\n </div>\n <RightSidebar />\n <RedactConfirmModal />\n {/* signatures: plugin intents → surfaces; the dialogs they open */}\n <SignatureBridge />\n <SignDialog />\n <SignatureMakerModal />\n </DocumentArea>\n </div>\n\n {toolbarEdge === 'bottom' && (\n <>\n <ModeBand edge=\"bottom\" />\n {toolbarBand}\n </>\n )}\n </div>\n </AnnotationFontsProvider>\n );\n}\n","/**\n * The full viewer, as a component — and the customization CONTRACT. The\n * `ViewerCustomization` surface here is the exact shape that later powers\n * `EmbedPDF.init({...})` and every framework wrapper, because all of it is\n * plain data (see README.md).\n *\n * Two semantics, on purpose:\n * - REGISTRIES (commands / icons / strings) merge ADDITIVELY over the\n * defaults by id; a colliding id overrides.\n * - STRUCTURE (chrome) is an owned VALUE: the default, a transform of it,\n * or the host's own schema — never merged.\n *\n * The engine stays a prop — choosing local-wasm vs cloud is the host's\n * decision, and each delivery wires its own. The chrome —\n * toolbars, translations, theme — renders at t≈0; only the pages wait on\n * the engine. Customization is mount-time (exactly like v2's init config);\n * changing these props on a mounted viewer does not rebuild the workspace.\n */\n// One import line per feature: each subpath carries the\n// plugin AND its UI; delete a line and the feature leaves the bundle.\nimport { useEffect, useState, type ReactNode } from 'react';\nimport { Viewer, useKernel } from '@embedpdf/react/runtime';\nimport type { Engine, EngineFactory, InitialDocument } from '@embedpdf/react/runtime';\nimport { stagePlugin } from '@embedpdf/react/stage';\nimport { renderPlugin } from '@embedpdf/react/render';\nimport { pageEditPlugin } from '@embedpdf/react/page-edit';\nimport { feedbackPlugin, interactionPlugin, vibrationFeedback } from '@embedpdf/react/interaction';\nimport { selectionPlugin } from '@embedpdf/react/selection';\nimport { annotationPlugin } from '@embedpdf/react/annotation';\nimport { stampPlugin } from '@embedpdf/react/stamp';\nimport { redactionPlugin } from '@embedpdf/react/redaction';\nimport { actionsPlugin } from '@embedpdf/react/actions';\nimport { formPlugin } from '@embedpdf/react/form';\nimport { signaturePlugin } from '@embedpdf/react/signature';\nimport { linkPlugin } from '@embedpdf/react/link';\nimport { searchPlugin } from '@embedpdf/react/search';\nimport { i18nPlugin, negotiateLocale, useT } from '@embedpdf/react/i18n';\nimport type { Locale, TranslationDictionary } from '@embedpdf/react/i18n';\nimport { commandsPlugin } from '@embedpdf/react/commands';\nimport type { CommandDef } from '@embedpdf/react/commands';\nimport { shellPlugin } from '@embedpdf/react/shell';\nimport { chromeHelpers, validateChrome } from '@embedpdf/react/toolbar';\nimport type { ChromeHelpers, ChromeSchema } from '@embedpdf/react/toolbar';\nimport { ThumbsStageToken } from './config/stage';\nimport { defaultChrome } from './config/chrome';\nimport { defaultCommands } from './config/commands';\nimport { demoToolsPlugin } from './config/demo-tools.plugin';\nimport { en } from './locales/en';\nimport {\n ViewerConfigProvider,\n type ResolvedViewerConfig,\n type StampsCustomization,\n} from './config-context';\nimport type { AnnotationsCustomization, SignaturesCustomization } from './config-context';\nimport { createViewerHandle, type ViewerHandle } from './handle';\nimport { ICON_PATHS, type IconDef } from './ui/icons';\nimport { ThemeProvider, type ThemePreference } from './ui/theme';\nimport { Shell } from './Shell';\n\n/** Lazy built-in packs — a strings override for one of these wraps its loader. */\nconst BUILTIN_LOADERS: Record<string, () => Promise<Locale>> = {\n es: () => import('./locales/es').then((m) => m.es),\n};\n\nconst isDict = (v: unknown): v is TranslationDictionary => typeof v === 'object' && v !== null;\n\n/**\n * Deep-merge `over` into `base` (immutably), expanding dotted keys —\n * `{ 'acme.send': 'X' }` and `{ acme: { send: 'X' } }` are the same override.\n */\nfunction mergeTranslations(\n base: TranslationDictionary,\n over: TranslationDictionary,\n): TranslationDictionary {\n const out: Record<string, string | TranslationDictionary> = { ...base };\n for (const [key, value] of Object.entries(over)) {\n const path = key.split('.');\n let node = out;\n for (let i = 0; i < path.length - 1; i++) {\n const prev = node[path[i]];\n node = (node[path[i]] = isDict(prev) ? { ...prev } : {}) as Record<\n string,\n string | TranslationDictionary\n >;\n }\n const leaf = path[path.length - 1];\n const prev = node[leaf];\n node[leaf] =\n typeof value === 'string' ? value : mergeTranslations(isDict(prev) ? prev : {}, value);\n }\n return out;\n}\n\nconst mergeLocale = (pack: Locale, over?: TranslationDictionary): Locale =>\n over ? { ...pack, translations: mergeTranslations(pack.translations, over) } : pack;\n\n/**\n * The customization surface — identical in the vanilla snippet and every\n * framework wrapper. See README.md for the ladder this implements.\n */\nexport interface ViewerCustomization {\n /** ADDITIVE over the default vocabulary; a colliding id overrides. */\n commands?: readonly CommandDef[];\n /** ADDITIVE 24×24 stroke icons by name; a colliding name overrides. */\n icons?: Readonly<Record<string, IconDef>>;\n /** Per-locale translation overrides/additions; dotted keys expand. A code\n * with no built-in pack becomes a new locale (falls back to English). */\n strings?: Readonly<Record<string, TranslationDictionary>>;\n /** 'auto' (default) negotiates from the browser languages. */\n locale?: 'auto' | (string & {});\n /** Feature gating: a disabled category vanishes from every surface. */\n disabledCategories?: readonly string[];\n /** The structure — a value you OWN: the default (pass nothing), a transform\n * of it, or your own schema. Never merged. */\n chrome?: ChromeSchema | ((base: ChromeSchema, helpers: ChromeHelpers) => ChromeSchema);\n /** The stamps sidebar's built-in library. `false`: none (air-gapped, no\n * request). A string: a URL template with a `{locale}` slot for a\n * self-hosted copy of `@embedpdf/default-stamps`. Default: the copy that\n * ships with the viewer, as a lazy chunk of your own build — no CDN. */\n stamps?: StampsCustomization;\n /** Digital signatures: the signer, trust anchors, the mode (sign / visual /\n * ask), which marks a person keeps, and script faces for typed marks. With\n * no signer, a mark placed on a field is drawn in without sealing. */\n signatures?: SignaturesCustomization;\n /** Annotations: fonts the free-text style panel offers beyond the standard\n * 14 — fetched, registered on the engine and mounted for the live editor. */\n annotations?: AnnotationsCustomization;\n /** Light/dark preference (string shorthand), or the full theme config with\n * `--ep-*` token overrides. Tokens are applied by the DELIVERY (the custom\n * element adopts them into its shadow root); direct consumers of this\n * package set the `--ep-*` variables in their own CSS instead. */\n theme?: ThemePreference | ThemeConfig;\n}\n\n/** Token overrides — names WITHOUT the `--ep-` prefix ('accent', 'surface'…). */\nexport type ThemeTokens = Readonly<Record<string, string>>;\n\nexport interface ThemeConfig {\n /** 'system' (default) follows the OS. */\n preference?: ThemePreference;\n /** Applied in BOTH modes (a later sheet: wins over the defaults). */\n tokens?: ThemeTokens;\n /** Dark-mode-only overrides, applied over `tokens`. */\n dark?: ThemeTokens;\n}\n\n/** Normalize the shorthand — deliveries use this to read one shape. */\nexport const themeConfigOf = (theme: ThemePreference | ThemeConfig | undefined): ThemeConfig =>\n typeof theme === 'string' ? { preference: theme } : (theme ?? {});\n\nexport interface FullViewerProps extends ViewerCustomization {\n /** Instance (borrowed) or thunk (viewer-owned) — the Viewer's own contract. */\n engine: Engine | EngineFactory;\n /** Documents to open at mount; more arrive via the tab bar's open button. */\n initialDocuments?: InitialDocument[];\n /** Shown while the workspace boots. Default: a translated pulse line. */\n fallback?: ReactNode;\n /** Where the theme's `.dark` class goes — a DELIVERY concern, not user\n * config: the custom element passes its shadow wrapper so theming never\n * touches the host page. Default: document.documentElement. */\n themeTarget?: HTMLElement | null;\n /** Called once the workspace kernel is live, with the viewer handle — the\n * DRIVE surface (`el.viewer` on the custom element, `onReady` on the\n * wrappers). Capabilities resolve from the moment this fires; document-\n * scoped calls simply await their document. */\n onViewer?: (viewer: ViewerHandle) => void;\n}\n\n/** Inside <Viewer>: mints the handle from the live kernel, reports it up. */\nfunction HandleBridge({ onViewer }: { onViewer: (viewer: ViewerHandle) => void }) {\n const kernel = useKernel();\n useEffect(() => {\n onViewer(createViewerHandle(kernel));\n // Init-only like everything else: re-fires only if the KERNEL changes\n // (a remount), never because the callback prop identity churned.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [kernel]);\n return null;\n}\n\nfunction Booting() {\n const t = useT();\n return (\n <div className=\"bg-app text-fg-muted grid h-full place-items-center\">\n <div className=\"animate-pulse text-sm\">{t('demo.starting')}</div>\n </div>\n );\n}\n\nexport function FullViewer({\n engine,\n initialDocuments,\n fallback,\n commands,\n icons,\n strings,\n locale = 'auto',\n disabledCategories,\n chrome,\n stamps,\n signatures,\n annotations,\n theme,\n themeTarget,\n onViewer,\n}: FullViewerProps) {\n // Customization is INIT-ONLY, exactly like v2's `EmbedPDF.init` (and like\n // the Viewer's own engine/plugins contract): the whole config resolves ONCE\n // from the mount-time props, so inline literals — the idiomatic way to pass\n // it — never churn plugin identities. Later prop changes are ignored.\n const [resolved] = useState(() => {\n // ── registries: additive, user wins by id ───────────────────────────────\n const byId = new Map(defaultCommands.map((c) => [c.id, c]));\n for (const c of commands ?? []) byId.set(c.id, c);\n const resolvedCommands = [...byId.values()];\n\n // ── structure: an owned value (default | transform | replacement) ───────\n const resolvedChrome =\n typeof chrome === 'function'\n ? chrome(defaultChrome, chromeHelpers)\n : (chrome ?? defaultChrome);\n\n // ── locale packs: overrides merge into built-ins; unknown codes become\n // new locales that fall back to English ──────────────────────────────\n const overrides = strings ?? {};\n const locales: Locale[] = [mergeLocale(en, overrides.en)];\n const loaders: Record<string, () => Promise<Locale>> = {};\n for (const [code, load] of Object.entries(BUILTIN_LOADERS)) {\n const over = overrides[code];\n loaders[code] = over ? () => load().then((pack) => mergeLocale(pack, over)) : load;\n }\n for (const [code, over] of Object.entries(overrides)) {\n if (code === 'en' || code in BUILTIN_LOADERS) continue;\n locales.push({ code, name: code, translations: mergeTranslations({}, over) });\n }\n const codes = [...new Set(['en', ...Object.keys(BUILTIN_LOADERS), ...Object.keys(overrides)])];\n const initial =\n locale === 'auto'\n ? (negotiateLocale(codes, typeof navigator !== 'undefined' ? navigator.languages : []) ??\n 'en')\n : locale;\n\n return {\n commands: resolvedCommands,\n chrome: resolvedChrome,\n icons: icons ?? {},\n stamps: stamps ?? {},\n signatures: signatures ?? {},\n annotations: annotations ?? {},\n i18n: { locales, loaders, initial },\n };\n });\n\n // Dev guardrail: every id the chrome references must exist; every icon a\n // command names must resolve. Warnings name the exact id (README promise).\n useEffect(() => {\n if (process.env.NODE_ENV === 'production') return;\n const ids = new Set(resolved.commands.map((c) => c.id));\n for (const problem of validateChrome(resolved.chrome, ids)) {\n console.warn(`[embedpdf] chrome: ${problem}`);\n }\n for (const c of resolved.commands) {\n if (c.icon && !(c.icon in ICON_PATHS) && !(c.icon in resolved.icons)) {\n console.warn(`[embedpdf] command \"${c.id}\": unknown icon \"${c.icon}\"`);\n }\n }\n }, [resolved]);\n\n const [plugins] = useState(() => [\n stagePlugin({ layout: 'vertical' }), // main lens (tools engage via interactionPlugin below)\n // Thumbnail lens over the SAME document: a single-column grid at a fixed small\n // zoom, its own camera. Click a thumb to navigate the main lens; the sidebar\n // follows the main view (see ui/panels ThumbnailList).\n stagePlugin({\n id: 'stage-thumbs',\n token: ThumbsStageToken,\n layout: 'grid',\n columns: 1, // single column, like the v2 snippet's thumbnail rail\n sizing: 'uniform', // equalize pages so the pixel target hits every thumb\n zoom: { pageWidth: 150 }, // thumbs are 150 SCREEN px wide — for ANY document\n padding: 12,\n gap: { px: 16 }, // UI-stable spacing between thumbs\n pageFrame: { top: 0, right: 0, bottom: 20, left: 0 }, // reserved label band (screen px)\n fitAlign: { x: 'center', y: 'start' }, // few pages? thumbs hug the TOP\n scrollBehavior: 'instant',\n }),\n renderPlugin(),\n pageEditPlugin(),\n interactionPlugin(),\n // Platform haptics, default-on: the Vibration API where it exists\n // (Android), a safe silent no-op elsewhere — iOS Safari included, until\n // Apple ships a haptics API. Native shells swap in their own provider\n // (`wkFeedback`) instead.\n feedbackPlugin({ provider: vibrationFeedback }),\n selectionPlugin(),\n // The arrow tool is a `line` preset — same subtype, an arrowhead default. This is\n // the whole integration for a new tool: one `tools` entry + a command/toolbar\n // slot (see config/commands.ts + config/chrome.ts).\n annotationPlugin({\n tools: [\n {\n id: 'arrow',\n extends: 'line',\n defaults: { lineEndings: { start: 'none', end: 'open-arrow' } },\n },\n // The Insert tab's Image button: a `stamp` preset whose payload comes\n // from the file-picker port, narrowed to rasters. Click the spot, the\n // dialog opens, the picture lands there. Its own tool id (not `stamp`)\n // keeps it out of the stamp panel's armed state and gives it its own\n // cursor icon.\n {\n id: 'image',\n extends: 'stamp',\n source: { kind: 'prompt', accept: 'image/png,image/jpeg' },\n },\n ],\n }),\n // Stamp LIBRARIES (workspace-scoped): named reusable assets — the built-in\n // set plus any PDF the user imports, each page one vector stamp. The\n // stamps sidebar is the picker; placement rides annotation's armed stamp.\n stampPlugin(),\n // The action engine: /A and /AA trees dispatch through one policy-gated\n // executor spine, and THE JavaScript switch lives here (the per-document\n // ScriptHost realm; form's K/V/C/F pipeline rides its transaction port,\n // stamp's dynamic templates evaluate in detached realms it mints).\n actionsPlugin({\n javascript: { enabled: true, identity: { name: 'John Doe', corporation: 'Acme Inc' } },\n }),\n // Forms: fillable under the default pointer/pan (widgets render as fill\n // controls), editable under the Form tab's 'form-edit' + palette tools.\n formPlugin(),\n // Signatures: the ACT — a mark (a signatures-library asset) dropped on a\n // signature field signs it through the configured signer, or is drawn in\n // without sealing when there is none. Marks themselves are the stamp\n // plugin's; the panel lists libraries of kind 'signatures'.\n signaturePlugin({\n mode: resolved.signatures.mode,\n signer: resolved.signatures.signer,\n trust: resolved.signatures.trust,\n allowCertify: resolved.signatures.allowCertify,\n }),\n // Links: navigable under the default pointer/pan ('link-nav'), editable\n // under the link tool — the annotation plane then owns them (select, move,\n // retarget via the style panel's Link control).\n linkPlugin(),\n // Redaction: marking is the annotation plane's composed `redact` tool; this\n // plugin adds the pending-queue view + the destructive apply.\n redactionPlugin(),\n searchPlugin(),\n demoToolsPlugin(),\n i18nPlugin({\n locale: resolved.i18n.initial,\n fallbackLocale: 'en',\n locales: resolved.i18n.locales,\n loaders: resolved.i18n.loaders,\n }),\n commandsPlugin({\n commands: resolved.commands,\n disabledCategories: disabledCategories ? [...disabledCategories] : undefined,\n }),\n shellPlugin(),\n ]);\n\n // Structural subset of `resolved`, identity-stable across renders.\n const config: ResolvedViewerConfig = resolved;\n\n return (\n <ThemeProvider preference={themeConfigOf(theme).preference} target={themeTarget}>\n <Viewer\n engine={engine}\n plugins={plugins}\n initialDocuments={initialDocuments}\n fallback={fallback ?? <Booting />}\n >\n <ViewerConfigProvider value={config}>\n {onViewer && <HandleBridge onViewer={onViewer} />}\n <Shell />\n </ViewerConfigProvider>\n </Viewer>\n </ThemeProvider>\n );\n}\n"],"mappings":"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CL;EACA;EACA;CACF;CACA,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CAIA,YAAY;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,gBAAgB;EACd;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,kBAAkB;EAChB;EACA;EACA;EACA;EACA;CACF;CACA,aAAa;EACX;GAAE,GAAG;GAAgB,QAAQ;EAAU;EACvC;GAAE,GAAG;GAAW,QAAQ;EAAU;EAClC;GAAE,GAAG;GAAW,QAAQ;EAAU;EAClC;GAAE,GAAG;GAAiB,QAAQ;EAAU;EACxC;GAAE,GAAG;GAAe,QAAQ;EAAU;EACtC;GAAE,GAAG;GAA4B,QAAQ;EAAU;CACrD;CACA,iBAAiB,CAAC,oCAAoC;CACtD,wBAAwB,CAAC,sCAAsC;CAC/D,aAAa,CACX,0IACA,UACF;CACA,iBAAiB;EACf;EACA;EACA;EACA;EACA;CACF;CACA,MAAM;EACJ;EACA;EACA;CACF;CACA,YAAY;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,QAAQ,CAAC,8CAA8C,cAAc;CACrE,UAAU,CACR,+gBACA,oCACF;CACA,SAAS,CACP,oFACA,iFACF;CACA,WAAW,CACT,wLACF;CACA,YAAY,CAAC,iFAAiF;CAC9F,QAAQ,CACN;EACE,GAAG;EACH,QAAQ;EACR,MAAM;CACR,CACF;CACA,SAAS,CACP,6EACA,8DACF;CACA,UAAU;EACR;EACA;EACA;GAAE,GAAG;GAAwD,QAAQ;EAAU;CACjF;CACA,eAAe,CAAC,4BAA4B;EAAE,GAAG;EAAY,QAAQ;CAAU,CAAC;CAChF,MAAM;EACJ;EACA;EACA;EACA;CACF;CACA,OAAO;EACL;EACA;EACA;EACA;EACA;CACF;CACA,WAAW;EAAC;GAAE,GAAG;GAAY,QAAQ;EAAU;EAAG;EAA4B;CAAS;CAEvF,SAAS,CACP,4EACA,4EACF;CACA,QAAQ,CAAC,yBAAyB;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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["directionOf","StageToken","RenderToken","LinkToken","SelectionToken","SearchToken","AnnotationToken","StampToken","MeasurementToken","RedactionToken","FormToken","SignatureToken","PageEditToken","MetadataToken","ActionsToken","DocumentsToken","InteractionToken","CommandsToken","ShellToken","I18nToken","SearchToken","ShellToken","AnnotationToken","StampToken","SignatureToken","RedactionToken","FormToken","StageToken","sameStrings","ShellToken","ShellToken","StageToken","ShellToken","formatShortcut","AnnotationToken","FormToken","CommandsToken","I18nToken","HeadlessViewer"],"sources":["../src/config/stage.ts","../src/locales/en.ts","../src/locales/index.ts","../src/handle.ts","../src/plugin-settings.ts","../src/ui/theme.tsx","../src/config/panels.ts","../src/ui/scroll-hiding.ts","../src/ui/compact.ts","../src/layout-root.tsx","../src/places.tsx","../src/ui/lazy.tsx","../src/ui/strip-bar.tsx","../src/ui/annotation-strip.tsx","../src/ui/document-boot.tsx","../src/ui/drop-to-open.tsx","../src/ui/go-to-page.tsx","../src/ui/panel-layout.ts","../src/ui/panel-frame.tsx","../src/ui/panel-switcher.tsx","../src/ui/panels.tsx","../src/ui/placed-components.tsx","../src/ui/refusal-notice.tsx","../src/ui/rotation-badge.tsx","../src/ui/selection-strip.tsx","../src/ui/shortcuts-sheet.tsx","../src/ui/signature-bridge.tsx","../src/ui/unsaved-changes.tsx","../src/ui/tab-bar.tsx","../src/ui/tool-cursor.tsx","../src/Shell.tsx","../src/viewer.tsx"],"sourcesContent":["/**\n * The Stage is a lens: one document can be viewed through several at once. The\n * thumbnail sidebar is a second lens over the same document — a fixed-zoom grid\n * that wraps to the panel's width, with its own camera, fully independent of the\n * main view. `viewer.get('thumbnails')` is its Stage, and `plugins.thumbnails`\n * its settings.\n *\n * The token lives here (not in viewer.tsx) because several places need it: the\n * viewer wires the `stagePlugin` lens with it, the sidebar renders\n * `<Stage token={...}>` off it, and the `viewer` finds it by name.\n */\nimport { createCapabilityToken } from '@embedpdf/react/runtime';\nimport type { StageCapability } from '@embedpdf/react/stage';\n\nexport const ThumbsStageToken = createCapabilityToken<StageCapability>('stage-thumbs');\n","import type { Locale } from '@embedpdf/react/i18n';\n\n/**\n * English pack: the viewer's words, and the source every other pack translates key for key,\n * with the same `{name}` slots (`packages/viewer/main/test/chrome/locales.test.ts` checks it).\n * A new string gets its key here and in every other pack. The `commands.*` keys match\n * EmbedPDF's own command strings, so those translations resolve too.\n */\nexport const en: Locale = {\n code: 'en',\n name: 'English',\n translations: {\n measurement: {\n title: 'Measurements',\n distance: 'Distance',\n perimeter: 'Perimeter',\n area: 'Area',\n areaUnit: 'Area unit',\n resetLabel: 'Reset label position',\n calibrate: 'Calibrate scale',\n scale: 'Scale',\n custom: 'Custom',\n unavailable: 'Unavailable',\n instructions:\n 'Drag to measure a distance, then click to place its dimension line. Click vertices for a perimeter or area and double-click to finish. Area boundaries must not cross; an unavailable preview cannot be finished. Press Escape to cancel. Drag the label itself to move it.',\n sessionOnly: 'This engine keeps page calibration for this session only.',\n allPages: 'Apply to all pages',\n recalculate: 'Recalculate existing measurements',\n preset: 'Scale preset',\n choosePreset: 'Choose a preset',\n unit: 'Unit',\n precision: 'Precision',\n selection: 'Selected measurements',\n report: '{updated} updated · {skipped} skipped · {failed} failed',\n knownLength: 'Enter the real length represented by the line you just drew.',\n length: 'Known length',\n apply: 'Apply scale',\n applying: 'Applying…',\n },\n commands: {\n zoom: {\n in: 'Zoom In',\n out: 'Zoom Out',\n fitPage: 'Fit to Page',\n fitWidth: 'Fit to Width',\n automatic: 'Automatic',\n menu: 'Zoom',\n level: 'Zoom Level',\n p50: '50%',\n p100: '100%',\n p150: '150%',\n p200: '200%',\n p400: '400%',\n },\n pan: 'Pan',\n pointer: 'Pointer',\n comment: 'Comment',\n style: 'Style',\n menu: 'Menu',\n viewControls: 'View Controls',\n open: 'Open',\n download: 'Download',\n print: 'Print',\n fullscreen: 'Full Screen',\n spread: { group: 'Page Layout', none: 'Single Page', odd: 'Two Page', even: 'Cover Page' },\n scroll: { group: 'Scrolling', vertical: 'Vertical', horizontal: 'Horizontal' },\n rotate: {\n group: 'Rotate',\n clockwise: 'Rotate Clockwise',\n counterclockwise: 'Rotate Counter-Clockwise',\n },\n mode: {\n measure: 'Measure',\n group: 'Mode',\n view: 'View',\n annotate: 'Annotate',\n shapes: 'Shapes',\n insert: 'Insert',\n form: 'Form',\n redact: 'Redact',\n },\n annotate: {\n cancelCreation: 'Cancel drawing',\n highlight: 'Highlight',\n strikeout: 'Strikeout',\n underline: 'Underline',\n squiggly: 'Squiggly',\n ink: 'Draw',\n inkHighlight: 'Ink Highlighter',\n text: 'Text',\n insertText: 'Insert Text',\n replaceText: 'Replace Text',\n callout: 'Callout',\n note: 'Comment',\n link: 'Link',\n gotoLink: 'Go to link',\n removeLink: 'Remove link',\n delete: 'Delete',\n group: 'Group',\n ungroup: 'Ungroup',\n stampFromSelection: 'Make stamp',\n strip: 'Annotation actions',\n },\n selection: {\n copy: 'Copy',\n strip: 'Text selection actions',\n },\n shapes: {\n rectangle: 'Rectangle',\n circle: 'Circle',\n line: 'Line',\n arrow: 'Arrow',\n polygon: 'Polygon',\n polyline: 'Polyline',\n },\n insert: {\n stamp: 'Rubber Stamp',\n attachment: 'Attach File',\n signature: 'Signature',\n image: 'Image',\n },\n form: {\n textfield: 'Text Field',\n checkbox: 'Checkbox',\n radio: 'Radio Button',\n select: 'Dropdown',\n listbox: 'List Box',\n button: 'Button',\n signature: 'Signature Field',\n // The Form mode's design switch, which opens the form designer's sidebar.\n design: 'Form design',\n },\n redact: {\n mark: 'Mark for Redaction',\n applyAll: 'Apply Redactions',\n clearAll: 'Clear Marks',\n },\n undo: 'Undo',\n redo: 'Redo',\n page: {\n next: 'Next Page',\n previous: 'Previous Page',\n first: 'First Page',\n last: 'Last Page',\n goTo: 'Go to Page',\n },\n find: 'Find',\n shortcuts: 'Keyboard Shortcuts',\n // Why a command isn't there, by the permission the scope leaves out\n // (dots and colons as dashes); `{label}` is the command's label.\n notAllowed: {\n default: \"{label} isn't allowed\",\n 'annotations-create': \"Adding annotations isn't allowed\",\n 'doc-annotate-modify': \"Changing annotations isn't allowed\",\n 'doc-annotate-read': \"Viewing annotations isn't allowed\",\n 'doc-download': \"Downloading isn't allowed\",\n 'doc-forms-modify': \"Editing form fields isn't allowed\",\n 'doc-print': \"Printing isn't allowed\",\n 'doc-text-copy': \"Copying isn't allowed\",\n 'doc-text-search': \"Searching isn't allowed\",\n },\n turnedOff: \"{label} isn't available\",\n },\n passwordPrompt: {\n title: 'Password required',\n required: 'This document is password protected. Enter the password to open it.',\n incorrect: 'The password was incorrect. Please try again.',\n incorrectWarning: 'Incorrect password',\n label: 'Password',\n placeholder: 'Enter password',\n cancel: 'Cancel',\n open: 'Open',\n opening: 'Opening…',\n },\n // The drop target over the pages while a PDF is dragged over them.\n dropToOpen: { label: 'Drop a PDF to open it' },\n // A document that couldn't be opened: why, by its error, in its tab and on its pane.\n documentError: {\n title: 'Couldn’t open document',\n unknown: 'The document could not be opened.',\n notFound: 'The file wasn’t found.',\n notAllowed: 'You don’t have access to this document.',\n damaged: 'This file isn’t a PDF, or it’s damaged.',\n unsupported: 'This viewer can’t open this kind of document.',\n retry: 'Try again',\n close: 'Close document',\n },\n // The document tabs.\n tabs: {\n close: 'Close {name}',\n loading: 'Loading',\n untitled: 'Document {id}',\n },\n // Closing a tab whose document has changes that weren't downloaded.\n closeUnsaved: {\n title: 'Close without saving?',\n body: '“{name}” has changes that weren’t downloaded. They’ll be lost.',\n cancel: 'Cancel',\n close: 'Close without saving',\n },\n // The View only label in the main bar, while nothing can change the document.\n viewOnly: {\n label: 'View only',\n turnedOff: 'The tools that change this document are turned off',\n notAllowed: 'You can read this document, but not change it',\n },\n panel: {\n close: 'Close',\n resize: 'Resize {title}',\n },\n menu: {\n back: 'Back',\n },\n // The keyboard shortcuts sheet (`?`): its groups of commands.\n shortcuts: {\n document: 'Document',\n viewing: 'Viewing',\n editing: 'Editing',\n other: 'Other',\n },\n // The Go to Page dialog's button.\n goToPage: { go: 'Go' },\n // The built-in panels' titles, which are their buttons' labels too.\n panels: {\n thumbnails: 'Thumbnails',\n outline: 'Outline',\n attachments: 'Attachments',\n search: 'Search',\n comments: 'Comments',\n style: 'Style',\n stamps: 'Stamps',\n signatures: 'Signatures',\n redaction: 'Redactions',\n measurement: 'Measurements',\n formDesign: 'Form design',\n // The tooltip of a panel's title, which opens the other panels on its side.\n switch: 'Switch panel',\n },\n // Annotation type names — the comment sidebar's icon tooltips. Keys match\n // the published snippet packs, so existing translations resolve.\n annotation: {\n comment: 'Comment',\n highlight: 'Highlight',\n underline: 'Underline',\n squiggly: 'Squiggly',\n strikeout: 'Strikethrough',\n square: 'Square',\n circle: 'Circle',\n line: 'Line',\n polygon: 'Polygon',\n polyline: 'Polyline',\n ink: 'Ink',\n freeText: 'Text',\n stamp: 'Stamp',\n caret: 'Caret',\n redact: 'Redact',\n fileAttachment: 'Attachment',\n // The style panel's labels, as the annotation kinds name them (`labelKey`), by wording:\n // one field is called different things by different kinds.\n style: {\n opacity: 'Opacity',\n stroke: 'Stroke',\n fill: 'Fill',\n color: 'Color',\n strokeWidth: 'Stroke width',\n border: 'Border',\n borderStyle: 'Border style',\n borderColor: 'Border color',\n borderWidth: 'Border width',\n background: 'Background',\n outline: 'Outline',\n lineEndings: 'Line endings',\n blendMode: 'Blend mode',\n font: 'Font',\n fontSize: 'Font size',\n textColor: 'Text color',\n bold: 'Bold',\n italic: 'Italic',\n underline: 'Underline',\n align: 'Align',\n alignment: 'Alignment',\n label: 'Label',\n labelFont: 'Label font',\n labelSize: 'Label size',\n labelColor: 'Label color',\n icon: 'Icon',\n link: 'Link',\n },\n // The annotation flags (`/F`).\n flags: {\n print: 'Print',\n hidden: 'Hidden',\n noView: 'No view',\n toggleNoView: 'Toggle no view',\n readOnly: 'Read only',\n locked: 'Locked',\n lockedContents: 'Locked contents',\n noZoom: 'No zoom',\n noRotate: 'No rotate',\n invisible: 'Invisible',\n },\n borderStyles: { solid: 'Solid', dashed: 'Dashed', cloudy: 'Cloudy' },\n lineEndings: {\n none: 'None',\n square: 'Square',\n circle: 'Circle',\n diamond: 'Diamond',\n openArrow: 'Open arrow',\n closedArrow: 'Closed arrow',\n butt: 'Butt',\n reverseOpenArrow: 'Reverse open arrow',\n reverseClosedArrow: 'Reverse closed arrow',\n slash: 'Slash',\n },\n blendModes: {\n normal: 'Normal',\n multiply: 'Multiply',\n screen: 'Screen',\n overlay: 'Overlay',\n darken: 'Darken',\n lighten: 'Lighten',\n colorDodge: 'Color dodge',\n colorBurn: 'Color burn',\n hardLight: 'Hard light',\n softLight: 'Soft light',\n difference: 'Difference',\n exclusion: 'Exclusion',\n hue: 'Hue',\n saturation: 'Saturation',\n color: 'Color',\n luminosity: 'Luminosity',\n },\n // The standard PDF fonts, by their names: a language may keep them as they are.\n fonts: {\n courier: 'Courier',\n courierBold: 'Courier Bold',\n courierBoldOblique: 'Courier Bold Oblique',\n courierOblique: 'Courier Oblique',\n helvetica: 'Helvetica',\n helveticaBold: 'Helvetica Bold',\n helveticaBoldOblique: 'Helvetica Bold Oblique',\n helveticaOblique: 'Helvetica Oblique',\n timesRoman: 'Times Roman',\n timesBold: 'Times Bold',\n timesBoldItalic: 'Times Bold Italic',\n timesItalic: 'Times Italic',\n symbol: 'Symbol',\n zapfDingbats: 'Zapf Dingbats',\n },\n alignments: { left: 'Left', center: 'Center', right: 'Right' },\n noteIcons: {\n comment: 'Comment',\n key: 'Key',\n note: 'Note',\n help: 'Help',\n newParagraph: 'New paragraph',\n paragraph: 'Paragraph',\n insert: 'Insert',\n },\n attachmentIcons: {\n pushPin: 'Push pin',\n paperclip: 'Paperclip',\n graph: 'Graph',\n tag: 'Tag',\n },\n },\n // A form field's settings, as the form plugin names them (`labelKey`).\n form: {\n settings: {\n name: 'Name',\n tooltip: 'Tooltip',\n required: 'Required',\n readOnly: 'Read-only',\n noExport: \"Don't export\",\n defaultValue: 'Default value',\n maxLength: 'Maximum length',\n multiline: 'Several lines',\n password: 'Password',\n comb: 'One character per box',\n radiosInUnison: 'Buttons with one value turn on together',\n keepOneOn: 'Keep one on',\n options: 'Options',\n allowTyping: 'Allow typing',\n multiSelect: 'Several choices',\n },\n },\n // A thumbnail's tooltip.\n thumbnails: { page: 'Page {page}' },\n // The form designer's sidebar: the fields by page, and the selected one's buttons.\n formDesign: {\n empty: 'No fields yet. Pick a field tool to add one.',\n page: 'Page {page}',\n allFields: 'All fields',\n buttons: 'Buttons',\n boxes: 'Boxes',\n box: 'Box {number}',\n addButton: 'Add a button',\n addBox: 'Add a box',\n },\n // The style panel's own words around the properties.\n stylePanel: {\n mixed: '(mixed)',\n // A color swatch that takes the color away.\n transparent: 'Transparent',\n lineStart: 'Start',\n lineEnd: 'End',\n empty: 'Pick a draw tool or select an annotation to edit its style.',\n selected: '{count} selected',\n toolDefaults: '{tool} defaults',\n defaults: 'Defaults',\n },\n // The flags section of the style panel: its title, and what each flag does.\n annotationFlags: {\n title: 'Flags (/F)',\n print: 'Include when the page is printed',\n hidden: 'Gone everywhere: screen, clicks, print',\n noView: 'Hidden on screen, may still print',\n toggleNoView: 'Reveal a no-view annotation while selected',\n readOnly: 'Visible but not clickable',\n locked: 'No move / resize / delete / restyle',\n lockedContents: 'Text cannot change; geometry can',\n noZoom: 'Screen-constant size (anchored top-left)',\n noRotate: 'Stays upright when the page rotates',\n invisible: 'Legacy: hide unknown subtypes',\n },\n // The link editor over a selected annotation.\n linkEditor: {\n toUrl: 'Link to a URL',\n url: 'URL',\n toPage: 'Link to a page',\n page: 'Page',\n urlPlaceholder: 'https://…',\n pagePlaceholder: 'Page number',\n add: 'Add link',\n update: 'Update link',\n },\n demo: {\n starting: 'Starting viewer…',\n opening: 'Opening document…',\n more: 'More',\n searchPlaceholder: 'Search document…',\n searchCaseSensitive: 'Case sensitive',\n searchWholeWord: 'Whole word',\n searchRegex: 'Regular expression',\n searchSearching: 'Searching…',\n searchResults: '{count} results found',\n searchNoResults: 'No results',\n searchPrevious: 'Previous result',\n searchNext: 'Next result',\n searchPage: 'Page {page}',\n commentsForbidden: 'You don\\u2019t have access to comments on this document.',\n commentsLoading: 'Loading comments…',\n commentsError: 'Comments failed to load.',\n commentsRetry: 'Retry',\n commentsEmpty: 'No comments yet. Use the note tool to start a thread.',\n commentsEmptyReadOnly: 'No comments on this document.',\n commentsAnonymous: 'Unknown',\n commentsPage: 'Page {page}',\n commentCount: '{count} comment',\n commentCountPlural: '{count} comments',\n commentsReply: 'Reply',\n commentsReplyPlaceholder: 'Reply…',\n commentsAddPlaceholder: 'Add a comment…',\n commentsDelete: 'Delete comment',\n commentsDeleteThread: 'Delete thread',\n commentsEdit: 'Edit comment',\n commentsStatus: 'Status',\n commentsStatusNone: 'No status',\n commentsStatusAccepted: 'Accepted',\n commentsStatusRejected: 'Rejected',\n commentsStatusCancelled: 'Cancelled',\n commentsStatusCompleted: 'Completed',\n empty: 'Nothing here yet in this demo panel.',\n page: 'Page {current} of {total}',\n goToPage: 'Go to page',\n cancel: 'Cancel',\n pageBadge: 'p. {page}',\n redactionEmpty: 'No pending redactions. Use the Redact tool to mark text or areas.',\n redactionArea: 'Area mark',\n redactionText: 'Text mark',\n redactionRemove: 'Remove mark',\n redactConfirmTitle: 'Apply redactions?',\n redactConfirmBody:\n 'Permanently remove the content under {count} redaction marks. This cannot be undone.',\n redactConfirmCollateral: '{count} other annotations will also be removed.',\n redactApply: 'Apply',\n redactApplying: 'Applying…',\n formatLabel: 'Format',\n fieldSettingsTitle: 'Field',\n fieldOptionLabel: 'Label',\n fieldOptionValue: 'Value',\n fieldOptionAdd: 'Add option',\n fieldOptionRemove: 'Remove option',\n fieldNone: 'None',\n redactLabelTitle: 'Redaction label',\n redactLabelPlaceholder: 'e.g. REDACTED',\n redactLabelRepeat: 'Repeat label across region',\n stampsAll: 'All stamps',\n stampsLoading: 'Loading stamps…',\n stampsEmpty: 'No stamps yet. Import a PDF to turn each of its pages into a stamp.',\n stampsRemoveStamp: 'Remove stamp',\n stampsArmedHint: 'Click a page to place the stamp.',\n stampsImport: 'Import PDF…',\n stampsImporting: 'Importing…',\n stampsImportHint: 'Import a PDF as a stamp library — each page becomes one stamp.',\n stampsRemoveLibrary: 'Remove library',\n stampsExportLibrary: 'Export library as PDF',\n stampsCustomLibrary: 'My stamps',\n stampsCustomLabel: 'Custom stamp',\n stampsError: 'The built-in stamps could not be loaded.',\n stampsArmError: 'That stamp could not be armed.',\n stampsImportError: 'That PDF could not be imported as a stamp library.',\n quickStampsLabel: 'Quick stamps',\n signaturesEmpty: 'No signatures yet. Create one to sign with.',\n signaturesNew: 'New signature…',\n signaturesArmedHint:\n 'Click a signature field to sign it, or anywhere on a page to place the mark.',\n signaturesTargetHint: 'Pick a mark for the selected field.',\n signaturesInDocument: 'In this document',\n signaturesNone: 'This document has no signature fields.',\n signaturesValidate: 'Validate',\n signaturesValidating: 'Validating…',\n signaturesSigned: 'Signed',\n signaturesUnsigned: 'Unsigned',\n signaturesRename: 'Rename',\n signaturesRemove: 'Remove',\n signaturesExport: 'Export as PDF',\n signaturesAddInitials: 'Add initials',\n signatureLabel: 'Signature',\n initialsLabel: 'Initials',\n makerTitle: 'New signature',\n makerName: 'Name',\n makerNamePlaceholder: 'Your name',\n makerDraw: 'Draw',\n makerType: 'Type',\n makerUpload: 'Upload',\n makerTypePlaceholder: 'Type your name',\n makerFont: 'Font',\n makerUploadHint: 'Choose a PNG, JPEG, or one-page PDF',\n makerClear: 'Clear',\n makerOptional: '(optional)',\n makerSave: 'Save',\n makerSaving: 'Saving…',\n makerError: 'The signature could not be saved.',\n signTitle: 'Sign this field',\n signReason: 'Reason',\n signLocation: 'Location',\n signKind: 'What may change afterwards',\n signKindApproval: 'Approval signature — form filling and more signatures stay valid',\n signKindCertifyAnnotate: 'Certify — allow comments, form filling and signatures',\n signKindCertifyFill: 'Certify — allow form filling and signatures only',\n signKindCertifyLocked: 'Certify — allow no changes',\n signButton: 'Sign',\n signSigning: 'Signing…',\n signFill: 'Place without signing',\n signError: 'The field could not be signed.',\n inspectTitle: 'Signature',\n inspectSigner: 'Signed by',\n inspectReason: 'Reason',\n inspectLocation: 'Location',\n inspectTime: 'Time',\n inspectIntegrity: 'Document',\n inspectCryptography: 'Signature',\n inspectTrust: 'Signer',\n inspectChanges: 'Changes since',\n inspectDownload: 'Download signed version',\n verdictValid: 'Valid',\n verdictValidUntrusted: 'Valid, signer not trusted',\n verdictInvalid: 'Invalid — modified after signing',\n verdictWillInvalidate: 'Valid, invalid once saved',\n signaturesInvalidating:\n 'This change will invalidate {field} when the document is saved. Undo it to keep the signature.',\n verdictIndeterminate: 'Could not be verified',\n verdictUnchanged: 'None',\n verdictRestored: 'Changed, then restored',\n inspectLaterRevisions: 'Revisions after signing',\n verdictPermitted: 'Permitted',\n verdictForbidden: 'Not permitted',\n },\n },\n};\n","/**\n * The viewer's languages: English in every build, the others each in a chunk of its own that\n * loads the first time the viewer shows it, and the languages an app adds or changes through\n * `strings`. A language reads right to left when its pack says so (Arabic, Hebrew), or, for a\n * language from `strings`, when its code names a right-to-left script (`fa`, `ur`, `und-Arab`).\n */\nimport { negotiateLocale } from '@embedpdf/react/i18n';\nimport type { Locale, TextDirection, TranslationDictionary } from '@embedpdf/react/i18n';\n\nimport { en } from './en';\n\nexport { en };\n\n/** A language that loads when it's first shown. */\nexport type LocalePackLoader = () => Promise<Locale>;\n\n/** The viewer's languages besides English, by code. */\nexport const LOCALE_LOADERS: Readonly<Record<string, LocalePackLoader>> = {\n de: () => import('./de').then((module) => module.de),\n fr: () => import('./fr').then((module) => module.fr),\n es: () => import('./es').then((module) => module.es),\n it: () => import('./it').then((module) => module.it),\n nl: () => import('./nl').then((module) => module.nl),\n pt: () => import('./pt').then((module) => module.pt),\n pl: () => import('./pl').then((module) => module.pl),\n ja: () => import('./ja').then((module) => module.ja),\n 'zh-CN': () => import('./zh-cn').then((module) => module.zhCN),\n ko: () => import('./ko').then((module) => module.ko),\n ar: () => import('./ar').then((module) => module.ar),\n he: () => import('./he').then((module) => module.he),\n};\n\n/**\n * The language a `locale` value shows, among `codes`: the browser's languages for `'auto'`,\n * else the closest to the one asked for (`'es-MX'` shows `'es'`), else English.\n */\nexport const localeCodeOf = (locale: string, codes: readonly string[]): string =>\n negotiateLocale(\n codes,\n locale !== 'auto' ? [locale] : typeof navigator !== 'undefined' ? navigator.languages : [],\n ) ?? 'en';\n\nconst isDictionary = (value: unknown): value is TranslationDictionary =>\n typeof value === 'object' && value !== null;\n\n/**\n * `over` merged into `base`, both left as they are, with dotted keys expanded:\n * `{ 'acme.send': 'X' }` and `{ acme: { send: 'X' } }` are the same strings.\n */\nexport function mergeTranslations(\n base: TranslationDictionary,\n over: TranslationDictionary,\n): TranslationDictionary {\n const merged: Record<string, string | TranslationDictionary> = { ...base };\n for (const [key, value] of Object.entries(over)) {\n const path = key.split('.');\n let node = merged;\n for (let i = 0; i < path.length - 1; i++) {\n const previous = node[path[i]];\n node = (node[path[i]] = isDictionary(previous) ? { ...previous } : {}) as Record<\n string,\n string | TranslationDictionary\n >;\n }\n const leaf = path[path.length - 1];\n const existing = node[leaf];\n node[leaf] =\n typeof value === 'string'\n ? value\n : mergeTranslations(isDictionary(existing) ? existing : {}, value);\n }\n return merged;\n}\n\nconst withStrings = (pack: Locale, over: TranslationDictionary | undefined): Locale =>\n over ? { ...pack, translations: mergeTranslations(pack.translations, over) } : pack;\n\n/** Scripts written right to left, by their ISO 15924 code. */\nconst RIGHT_TO_LEFT_SCRIPTS = new Set([\n 'Adlm',\n 'Arab',\n 'Aran',\n 'Hebr',\n 'Mand',\n 'Mend',\n 'Nkoo',\n 'Rohg',\n 'Samr',\n 'Syrc',\n 'Thaa',\n 'Yezi',\n]);\n\n/**\n * How a language reads, from the script its code names (`ku-Arab`) or, without one, the script\n * it is usually written in (`fa` is written in Arabic script). `'ltr'` for a code the browser\n * can't read.\n */\nexport function directionOf(code: string): TextDirection {\n try {\n const { script } = new Intl.Locale(code).maximize();\n return script !== undefined && RIGHT_TO_LEFT_SCRIPTS.has(script) ? 'rtl' : 'ltr';\n } catch {\n return 'ltr';\n }\n}\n\n/** A language's name in itself (`'svenska'` for `sv`); its code where the browser has none. */\nfunction nameOf(code: string): string {\n try {\n return new Intl.DisplayNames([code], { type: 'language' }).of(code) ?? code;\n } catch {\n return code;\n }\n}\n\n/** The viewer's languages, with the app's `strings` in them. */\nexport interface ViewerLocales {\n /** The languages there from the start: English, and each one `strings` adds. */\n readonly locales: readonly Locale[];\n /** The viewer's other languages, loaded the first time they show. */\n readonly loaders: Readonly<Record<string, LocalePackLoader>>;\n /** Every language's code, English first: what `locale` is matched against. */\n readonly codes: readonly string[];\n}\n\n/**\n * The viewer's languages with the app's `strings` over them. A code of one of the viewer's\n * languages (in any case: `zh-cn` is `zh-CN`) changes that language's words; any other code\n * becomes a language of its own, which falls back to English for the words it doesn't give.\n */\nexport function localesOf(\n strings: Readonly<Record<string, TranslationDictionary>> = {},\n): ViewerLocales {\n const builtInCodes = ['en', ...Object.keys(LOCALE_LOADERS)];\n const builtInCodeOf = (code: string) =>\n builtInCodes.find((builtIn) => builtIn.toLowerCase() === code.toLowerCase());\n // The app's strings by the code they're shown under, a built-in language's code as the viewer\n // spells it.\n const byCode = new Map<string, TranslationDictionary>();\n for (const [code, over] of Object.entries(strings)) {\n const shownAs = builtInCodeOf(code) ?? code;\n byCode.set(shownAs, mergeTranslations(byCode.get(shownAs) ?? {}, over));\n }\n\n const locales: Locale[] = [withStrings(en, byCode.get('en'))];\n const loaders: Record<string, LocalePackLoader> = {};\n for (const [code, load] of Object.entries(LOCALE_LOADERS)) {\n const over = byCode.get(code);\n loaders[code] = over ? () => load().then((pack) => withStrings(pack, over)) : load;\n }\n for (const [code, over] of byCode) {\n if (builtInCodeOf(code) !== undefined) continue;\n locales.push({ code, name: nameOf(code), direction: directionOf(code), translations: over });\n }\n return { locales, loaders, codes: [...new Set([...builtInCodes, ...byCode.keys()])] };\n}\n","/**\n * The `viewer`: how an app reaches the viewer from code (`element.viewer`, `onReady`).\n *\n * A thin skin over the kernel: `get()` returns each plugin's public capability exactly as the\n * plugin defines it, by the plugin's name or its token, and adds no facade, no second vocabulary\n * and no second write path. `documents` and `commands` are two of those capabilities, with their\n * own events. `watch()` is the kernel's one change stream, selector-shaped: `useSelector` without\n * a framework.\n *\n * The chrome runs on these same capabilities, so what the viewer's own buttons can do and what\n * an app's code can do are the same by construction.\n *\n * A `viewer` lives as long as the viewer it reaches. Once that one unmounts, or mounts again\n * with a new config, it is done: the listeners added through it stop, and its calls refuse with\n * `instance-closed` (see {@link createViewer}).\n */\nimport { ActionsToken, type ActionsCapability } from '@embedpdf/react/actions';\nimport { AnnotationToken, type AnnotationCapability } from '@embedpdf/react/annotation';\nimport { CommandsToken, type CommandsCapability } from '@embedpdf/react/commands';\nimport { FormToken, type FormCapability } from '@embedpdf/react/form';\nimport { I18nToken, type I18nCapability } from '@embedpdf/react/i18n';\nimport { InteractionToken, type InteractionCapability } from '@embedpdf/react/interaction';\nimport { LinkToken, type LinkCapability } from '@embedpdf/react/link';\nimport { MeasurementToken, type MeasurementCapability } from '@embedpdf/react/measurement';\nimport { MetadataToken, type MetadataCapability } from '@embedpdf/react/metadata';\nimport { PageEditToken, type PageEditCapability } from '@embedpdf/react/page-edit';\nimport { RedactionToken, type RedactionCapability } from '@embedpdf/react/redaction';\nimport { RenderToken, type RenderCapability } from '@embedpdf/react/render';\nimport { DocumentsToken, PluginError, isReadMember } from '@embedpdf/react/runtime';\nimport type {\n CapabilityToken,\n DocumentsCapability,\n Kernel,\n Unsubscribe,\n} from '@embedpdf/react/runtime';\nimport { SearchToken, type SearchCapability } from '@embedpdf/react/search';\nimport { SelectionToken, type SelectionCapability } from '@embedpdf/react/selection';\nimport { ShellToken, type ShellCapability } from '@embedpdf/react/shell';\nimport { SignatureToken, type SignatureCapability } from '@embedpdf/react/signature';\nimport { StageToken, type StageCapability } from '@embedpdf/react/stage';\nimport { StampToken, type StampCapability } from '@embedpdf/react/stamp';\n\nimport { ThumbsStageToken } from './config/stage';\n\n/** Each plugin's API, by the plugin's name: what `viewer.get(name)` returns. */\nexport interface ViewerPlugins {\n readonly stage: StageCapability;\n /** The thumbnails panel's Stage: a second lens over the same document. */\n readonly thumbnails: StageCapability;\n readonly render: RenderCapability;\n readonly link: LinkCapability;\n readonly selection: SelectionCapability;\n readonly search: SearchCapability;\n readonly annotation: AnnotationCapability;\n readonly stamp: StampCapability;\n readonly measurement: MeasurementCapability;\n readonly redaction: RedactionCapability;\n readonly form: FormCapability;\n readonly signature: SignatureCapability;\n readonly pageEdit: PageEditCapability;\n /** The document's title, author and your own fields; `ensureLoaded()` reads them. */\n readonly metadata: MetadataCapability;\n readonly actions: ActionsCapability;\n readonly documents: DocumentsCapability;\n readonly interaction: InteractionCapability;\n readonly commands: CommandsCapability;\n readonly shell: ShellCapability;\n readonly i18n: I18nCapability;\n}\n\n/** A plugin's name, as `viewer.get()` and the `plugins` config take it. */\nexport type PluginName = keyof ViewerPlugins;\n\n/**\n * The viewer's plugins by name: the names `get()` takes, the same as the `plugins` config's.\n * Only plugins the viewer registers are here, so every name resolves.\n */\nexport const VIEWER_PLUGINS: {\n readonly [Name in PluginName]: CapabilityToken<ViewerPlugins[Name]>;\n} = {\n stage: StageToken,\n thumbnails: ThumbsStageToken,\n render: RenderToken,\n link: LinkToken,\n selection: SelectionToken,\n search: SearchToken,\n annotation: AnnotationToken,\n stamp: StampToken,\n measurement: MeasurementToken,\n redaction: RedactionToken,\n form: FormToken,\n signature: SignatureToken,\n pageEdit: PageEditToken,\n metadata: MetadataToken,\n actions: ActionsToken,\n documents: DocumentsToken,\n interaction: InteractionToken,\n commands: CommandsToken,\n shell: ShellToken,\n i18n: I18nToken,\n};\n\n/** `get`/`tryGet` bound to one document (see {@link Viewer.forDocument}). */\nexport interface ScopedViewer {\n /**\n * A plugin's API, by its name (`'search'`) or its token (`SearchToken`). Throws when the\n * viewer has no such plugin, when the plugin belongs to a document and none is open, and\n * `instance-closed` once the viewer is done.\n */\n get<Name extends PluginName>(name: Name): ViewerPlugins[Name];\n get<Capability>(token: CapabilityToken<Capability>): Capability;\n /**\n * Like `get`, but `null` when the plugin isn't available: none by that name, no document, one\n * still opening, or the viewer is done.\n */\n tryGet<Name extends PluginName>(name: Name): ViewerPlugins[Name] | null;\n tryGet<Capability>(token: CapabilityToken<Capability>): Capability | null;\n}\n\n/** The viewer, from code: `element.viewer`, and what `onReady` gets. */\nexport interface Viewer extends ScopedViewer {\n /** The documents: open, close, switch, download, and their events. `get('documents')`. */\n readonly documents: DocumentsCapability;\n /** The commands: run one, read one, turn features on and off, and their events. `get('commands')`. */\n readonly commands: CommandsCapability;\n\n /** `get`/`tryGet` for one document, whether it's the active one or not. */\n forDocument(documentId: string): ScopedViewer;\n\n /**\n * Run `read` on every change in the viewer, and call `onChange` when what it returns changed\n * (`isEqual`, default `Object.is`: capability getters return the same object until their value\n * changes, so identity works). Returns a function that stops it.\n */\n watch<T>(\n read: () => T,\n onChange: (value: T, previous: T) => void,\n isEqual?: (left: T, right: T) => boolean,\n ): Unsubscribe;\n}\n\n/** The key of the kernel on a {@link Viewer}, for the framework wrappers only. */\nexport const VIEWER_KERNEL: unique symbol = Symbol.for('@embedpdf/viewer/kernel');\n\n/** The plugins a viewer resolves by name: {@link VIEWER_PLUGINS}, or more. */\nexport type PluginTokens = Readonly<Record<string, CapabilityToken<unknown>>>;\n\n/** A `viewer`, and the end of its life. */\nexport interface ViewerLifetime {\n readonly viewer: Viewer;\n /**\n * The viewer it reaches is gone: every listener added through the `viewer` stops, and every\n * call refuses with `instance-closed`. Idempotent.\n */\n dispose(): void;\n}\n\nconst GONE =\n 'this viewer is gone: it was unmounted, or mounted again with a new config. Use the viewer ' +\n 'the new onReady gives you.';\n\n/** A member that subscribes: an event (`onOpened`) or a registration (`registerTool`). */\nconst SUBSCRIBES = /^(?:on|register)(?:[A-Z]|$)/;\n\nconst isPlainObject = (value: unknown): value is object => {\n if (typeof value !== 'object' || value === null) return false;\n const prototype: unknown = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\n\n/**\n * Make the `viewer` from a live kernel; `plugins` are the names its `get()` takes.\n *\n * Every API the `viewer` hands out (`get()`, `documents`, `commands`) is the plugin's own\n * capability seen through a lens that ends with the viewer: while it lives, every member is the\n * capability's; once {@link ViewerLifetime.dispose} runs, the listeners and registrations made\n * through it are removed, a read (`get*`, `list*`, `is*`, `has*`, `can*`) throws\n * `instance-closed`, every other call returns a promise that rejects with it, and a new\n * subscription does nothing.\n */\nexport function createViewer(kernel: Kernel, plugins: PluginTokens): ViewerLifetime {\n let disposed = false;\n const subscriptions = new Set<Unsubscribe>();\n const goneError = (capability: string) => new PluginError('instance-closed', capability, GONE);\n\n /** Keep a subscription made through the viewer, so `dispose()` can end it. */\n const keep = (unsubscribe: Unsubscribe): Unsubscribe => {\n const end = () => {\n subscriptions.delete(end);\n unsubscribe();\n };\n subscriptions.add(end);\n return end;\n };\n\n const lenses = new WeakMap<object, object>();\n /** The capability (or one of its namespaces, `annotation.comments`) as the viewer hands it out. */\n const lensOf = <Api extends object>(api: Api, capability: string): Api => {\n const existing = lenses.get(api);\n if (existing) return existing as Api;\n const members = new Map<string, { readonly value: unknown; readonly member: unknown }>();\n const memberOf = (key: string, value: (...args: unknown[]) => unknown): unknown => {\n if (SUBSCRIBES.test(key)) {\n return (...args: unknown[]) => {\n if (disposed) return () => {};\n const unsubscribe = value.apply(api, args);\n return typeof unsubscribe === 'function' ? keep(unsubscribe as Unsubscribe) : unsubscribe;\n };\n }\n if (isReadMember(key)) {\n return (...args: unknown[]) => {\n if (disposed) throw goneError(capability);\n return value.apply(api, args);\n };\n }\n return (...args: unknown[]) =>\n disposed ? Promise.reject(goneError(capability)) : value.apply(api, args);\n };\n const read = (key: string | symbol): unknown => {\n const value: unknown = Reflect.get(api, key, api);\n if (typeof key === 'symbol') return value;\n if (isPlainObject(value)) return lensOf(value, capability);\n if (typeof value !== 'function') return value;\n // The same function on every read, while the capability's member is the same.\n const known = members.get(key);\n if (known?.value === value) return known.member;\n const member = memberOf(key, value as (...args: unknown[]) => unknown);\n members.set(key, { value, member });\n return member;\n };\n // Over an empty object rather than the capability, so a frozen capability's members can be\n // handed out as the lens's own.\n const lens = new Proxy(\n {},\n {\n get: (_target, key) => read(key),\n has: (_target, key) => Reflect.has(api, key),\n ownKeys: () => Reflect.ownKeys(api),\n getOwnPropertyDescriptor: (_target, key) => {\n const own = Reflect.getOwnPropertyDescriptor(api, key);\n return own && { configurable: true, enumerable: own.enumerable, value: read(key) };\n },\n },\n ) as Api;\n lenses.set(api, lens);\n return lens;\n };\n\n const tokenNamed = (name: string): CapabilityToken<unknown> | null =>\n Object.prototype.hasOwnProperty.call(plugins, name) ? (plugins[name] ?? null) : null;\n const tokenOf = (plugin: string | CapabilityToken<unknown>): CapabilityToken<unknown> => {\n if (typeof plugin !== 'string') return plugin;\n const token = tokenNamed(plugin);\n if (!token) {\n throw new Error(\n `[embedpdf] the viewer has no plugin named \"${plugin}\". Its plugins: ` +\n `${Object.keys(plugins).join(', ')}.`,\n );\n }\n return token;\n };\n\n const scopedTo = (documentId: string | undefined): ScopedViewer => {\n function get<Name extends PluginName>(name: Name): ViewerPlugins[Name];\n function get<Capability>(token: CapabilityToken<Capability>): Capability;\n function get(plugin: string | CapabilityToken<unknown>): unknown {\n const token = tokenOf(plugin);\n if (disposed) throw goneError(token.name);\n return lensOf(kernel.capability(token, documentId) as object, token.name);\n }\n function tryGet<Name extends PluginName>(name: Name): ViewerPlugins[Name] | null;\n function tryGet<Capability>(token: CapabilityToken<Capability>): Capability | null;\n function tryGet(plugin: string | CapabilityToken<unknown>): unknown {\n const token = typeof plugin === 'string' ? tokenNamed(plugin) : plugin;\n const api = token && !disposed ? kernel.tryCapability(token, documentId) : null;\n return api === null ? null : lensOf(api as object, token!.name);\n }\n return { get, tryGet };\n };\n\n const watch = <T>(\n read: () => T,\n onChange: (value: T, previous: T) => void,\n isEqual: (left: T, right: T) => boolean = Object.is,\n ): Unsubscribe => {\n if (disposed) return () => {};\n let previous = read();\n return keep(\n kernel.subscribe(() => {\n const next = read();\n if (isEqual(previous, next)) return;\n const before = previous;\n previous = next;\n onChange(next, before);\n }),\n );\n };\n\n const viewer: Viewer = {\n ...scopedTo(undefined),\n documents: lensOf(kernel.documents, DocumentsToken.name),\n commands: lensOf(kernel.capability(CommandsToken), CommandsToken.name),\n forDocument: scopedTo,\n watch,\n };\n // Not part of the viewer's API: the framework wrappers read it to give the components they\n // slot into the viewer this kernel, so headless hooks work there. Non-enumerable, and keyed\n // by a registered symbol so a wrapper reads it without importing this package.\n Object.defineProperty(viewer, VIEWER_KERNEL, { value: kernel });\n\n const dispose = () => {\n if (disposed) return;\n disposed = true;\n for (const end of [...subscriptions]) end();\n };\n return { viewer, dispose };\n}\n\n/**\n * The `viewer` of the kernel a viewer runs on now: one per kernel, made once it has started\n * (before anything renders), and done when it goes. Your commands reach it as `viewer`, and\n * `onReady` gets the same one.\n */\nexport interface ViewerSlot {\n /** The `viewer` for this kernel: made the first time, the same one after that. */\n attach(kernel: Kernel): Viewer;\n /** The `viewer` now, or `null` before a kernel has started and after it went. */\n current(): Viewer | null;\n /** This kernel went: its `viewer` is done. Another kernel's stays. */\n release(kernel: Kernel): void;\n}\n\nexport function createViewerSlot(plugins: PluginTokens): ViewerSlot {\n let held: { readonly kernel: Kernel; readonly lifetime: ViewerLifetime } | null = null;\n return {\n attach: (kernel) => {\n if (held?.kernel !== kernel) {\n held?.lifetime.dispose();\n held = { kernel, lifetime: createViewer(kernel, plugins) };\n }\n return held.lifetime.viewer;\n },\n current: () => held?.lifetime.viewer ?? null,\n release: (kernel) => {\n if (held?.kernel !== kernel) return;\n held.lifetime.dispose();\n held = null;\n },\n };\n}\n","/**\n * The `plugins` config: each built-in plugin's settings by the plugin's name, and plugins of your\n * own.\n *\n * A built-in's settings merge over the viewer's own for that plugin the way every plugin merges\n * settings (`mergeSettings`: plain objects key by key, arrays and other values whole). Two\n * plugins take settings only the viewer has, next to their own: `stamp` (the standard stamps, the\n * quick stamps) and `signature` (which marks people keep, the fonts for typed ones). A plugin\n * definition under a name the viewer doesn't use joins the viewer, and `viewer.get(name)` is its\n * API. Anything else is left out, with a warning that names the closest plugin.\n */\nimport { didYouMean } from '@embedpdf/core-ui';\nimport { mergeSettings, type AnyPlugin, type DeepPartial } from '@embedpdf/react/runtime';\nimport type { actionsPlugin } from '@embedpdf/react/actions';\nimport type { annotationPlugin } from '@embedpdf/react/annotation';\nimport type { commandsPlugin } from '@embedpdf/react/commands';\nimport type { formPlugin } from '@embedpdf/react/form';\nimport type { i18nPlugin } from '@embedpdf/react/i18n';\nimport type { interactionPlugin } from '@embedpdf/react/interaction';\nimport type { measurementPlugin } from '@embedpdf/react/measurement';\nimport type { redactionPlugin } from '@embedpdf/react/redaction';\nimport type { renderPlugin } from '@embedpdf/react/render';\nimport type { searchPlugin } from '@embedpdf/react/search';\nimport type { selectionPlugin } from '@embedpdf/react/selection';\nimport type { signaturePlugin } from '@embedpdf/react/signature';\nimport type { stagePlugin } from '@embedpdf/react/stage';\nimport type { stampPlugin } from '@embedpdf/react/stamp';\nimport { VIEWER_PLUGINS, type PluginName } from './handle';\n\n/** What a plugin factory takes, or `never` for a factory that takes nothing. */\ntype ConfigOf<Factory extends (...args: never[]) => unknown> =\n Parameters<Factory> extends [] ? never : NonNullable<Parameters<Factory>[0]>;\n\n/** What the viewer adds to the stamp plugin's settings, for its own panel and toolbar. Read once. */\nexport interface ViewerStampSettings {\n /**\n * Where the standard stamps come from: `true`, the copy that ships inside your build (a lazy\n * chunk, loaded when the stamps panel first opens); a URL with a `{locale}` slot, used exactly\n * as given; `false`, none and no request. Default `true`.\n */\n readonly standard?: boolean | string;\n /**\n * Stamps shown as buttons in the Insert toolbar, each as `library:name`: `standard` is the\n * standard stamps (`'standard:Approved'`), any other library goes by its id. Default none.\n */\n readonly quick?: readonly string[];\n /** The kinds of library the stamps panel lists. Default `['stamps']`. */\n readonly sidebar?: readonly string[];\n}\n\n/**\n * A font for typed signatures: its TrueType or OpenType file, from `url` or as `data`, read and\n * registered on the engine the first time someone types a mark in the signature maker.\n */\nexport interface SignatureFont {\n /** The engine's key for it. */\n readonly key: string;\n /** What the font picker shows. */\n readonly label: string;\n /** Where the file comes from (same-origin or CORS-enabled). */\n readonly url?: string;\n /** The file's bytes, in place of `url`. */\n readonly data?: Uint8Array | ArrayBuffer;\n}\n\n/** What the viewer adds to the signature plugin's settings, for its own panel and dialogs. Read once. */\nexport interface ViewerSignatureSettings {\n /** Which marks people keep. Default both. */\n readonly kinds?: readonly ('signature' | 'initials')[];\n /** Fonts for typed signatures, in the order the maker offers them. Default three handwriting fonts. */\n readonly fonts?: readonly SignatureFont[];\n /** `'one'`: a single person per browser, so no new person once one exists. Default `'many'`. */\n readonly libraries?: 'one' | 'many';\n}\n\nconst VIEWER_STAMP_KEYS = ['standard', 'quick', 'sidebar'] as const;\nconst VIEWER_SIGNATURE_KEYS = ['kinds', 'fonts', 'libraries'] as const;\n\n/** The settings each built-in plugin takes in `plugins`: what its factory takes. */\ninterface BuiltInSettings {\n readonly stage: Omit<ConfigOf<typeof stagePlugin>, 'id' | 'token'>;\n readonly thumbnails: Omit<ConfigOf<typeof stagePlugin>, 'id' | 'token'>;\n readonly render: ConfigOf<typeof renderPlugin>;\n readonly link: never;\n readonly selection: ConfigOf<typeof selectionPlugin>;\n readonly search: ConfigOf<typeof searchPlugin>;\n readonly annotation: ConfigOf<typeof annotationPlugin>;\n readonly stamp: ConfigOf<typeof stampPlugin> & ViewerStampSettings;\n readonly measurement: ConfigOf<typeof measurementPlugin>;\n readonly redaction: ConfigOf<typeof redactionPlugin>;\n readonly form: ConfigOf<typeof formPlugin>;\n readonly signature: ConfigOf<typeof signaturePlugin> & ViewerSignatureSettings;\n readonly pageEdit: never;\n readonly metadata: never;\n readonly actions: ConfigOf<typeof actionsPlugin>;\n readonly documents: never;\n readonly interaction: ConfigOf<typeof interactionPlugin>;\n readonly commands: ConfigOf<typeof commandsPlugin>;\n readonly shell: never;\n readonly i18n: ConfigOf<typeof i18nPlugin>;\n}\n\n/** A built-in plugin's settings, as its page in the headless docs lists them. */\nexport type PluginSettings<Name extends PluginName> = BuiltInSettings[Name];\n\n/**\n * The `plugins` config: a built-in plugin's settings under its name (`stage: { spread: 'odd' }`),\n * and a plugin of your own as its definition under a name of your choice\n * (`analytics: analyticsPlugin()`), which `viewer.get('analytics')` then finds.\n */\nexport type ViewerPluginsConfig = {\n readonly [Name in PluginName]?: PluginSettings<Name>;\n} & {\n readonly [name: string]: object | undefined;\n};\n\n/** The built-in plugins that take no settings. */\nconst WITHOUT_SETTINGS: ReadonlySet<string> = new Set<PluginName>([\n 'link',\n 'pageEdit',\n 'metadata',\n 'documents',\n 'shell',\n]);\n\nconst isBuiltIn = (name: string): name is PluginName =>\n Object.prototype.hasOwnProperty.call(VIEWER_PLUGINS, name);\n\nconst isObject = (value: unknown): value is object => typeof value === 'object' && value !== null;\n\n/** Whether a value is a plugin definition: what a plugin factory such as `searchPlugin()` returns. */\nexport function isPluginDefinition(value: unknown): value is AnyPlugin {\n if (!isObject(value)) return false;\n const { id, create } = value as { readonly id?: unknown; readonly create?: unknown };\n return typeof id === 'string' && typeof create === 'function';\n}\n\n/** A plugin of your own from `plugins`, and the name `viewer.get()` finds it by. */\nexport interface OwnPlugin {\n readonly name: string;\n readonly plugin: AnyPlugin;\n}\n\n/** A built-in plugin's own settings: what its factory takes, without the viewer's. */\nexport type OwnSettings<Name extends PluginName> = Name extends 'stamp'\n ? Omit<PluginSettings<'stamp'>, keyof ViewerStampSettings>\n : Name extends 'signature'\n ? Omit<PluginSettings<'signature'>, keyof ViewerSignatureSettings>\n : PluginSettings<Name>;\n\n/** What the viewer takes from `plugins`. */\nexport interface PluginsConfigRead {\n /** The built-ins' own settings, each an object. */\n readonly settings: { readonly [Name in PluginName]?: OwnSettings<Name> };\n /** What the viewer adds to two plugins' settings, from the same objects. */\n readonly viewer: {\n readonly stamp: ViewerStampSettings;\n readonly signature: ViewerSignatureSettings;\n };\n /** The plugins of your own, in the order the config names them. */\n readonly own: readonly OwnPlugin[];\n /** What was left out, and why, one sentence each. */\n readonly problems: readonly string[];\n}\n\n/** Read `plugins`: the built-ins' settings, the plugins of your own, and what's wrong. */\nexport function readPluginsConfig(plugins: ViewerPluginsConfig | undefined): PluginsConfigRead {\n const settings: Record<string, object> = {};\n const own: OwnPlugin[] = [];\n const problems: string[] = [];\n for (const [name, value] of Object.entries(plugins ?? {})) {\n if (value === undefined) continue;\n if (!isBuiltIn(name)) {\n if (isPluginDefinition(value)) own.push({ name, plugin: value });\n else {\n problems.push(\n `\"${name}\" is not one of the viewer's plugins, and not a plugin definition` +\n didYouMean(name, Object.keys(VIEWER_PLUGINS)),\n );\n }\n } else if (isPluginDefinition(value)) {\n problems.push(\n `\"${name}\" is the viewer's own ${name} plugin: give it settings, or give your plugin ` +\n 'a name of its own',\n );\n } else if (WITHOUT_SETTINGS.has(name)) {\n problems.push(`the ${name} plugin takes no settings`);\n } else if (!isObject(value) || Array.isArray(value)) {\n problems.push(`the ${name} plugin's settings are an object`);\n } else {\n settings[name] = value;\n }\n }\n const viewer = {\n stamp: takeViewerSettings<ViewerStampSettings>(settings, 'stamp', VIEWER_STAMP_KEYS),\n signature: takeViewerSettings<ViewerSignatureSettings>(\n settings,\n 'signature',\n VIEWER_SIGNATURE_KEYS,\n ),\n };\n return { settings: settings as PluginsConfigRead['settings'], viewer, own, problems };\n}\n\n/** Take the viewer's own `keys` out of plugin `name`'s settings in `settings`, and return them. */\nfunction takeViewerSettings<Viewer extends object>(\n settings: Record<string, object>,\n name: PluginName,\n keys: readonly (keyof Viewer & string)[],\n): Viewer {\n const given = settings[name] as Readonly<Record<string, unknown>> | undefined;\n if (!given) return {} as Viewer;\n const viewer: Record<string, unknown> = {};\n const own: Record<string, unknown> = { ...given };\n for (const key of keys) {\n if (own[key] !== undefined) viewer[key] = own[key];\n delete own[key];\n }\n settings[name] = own;\n return viewer as Viewer;\n}\n\n/** A plugin's settings: the app's, from `plugins`, over the viewer's own for that plugin. */\nexport function settingsOver<Settings extends object>(\n viewerSettings: Settings,\n settings: Settings | undefined,\n): Settings {\n return mergeSettings(viewerSettings, settings as DeepPartial<Settings> | undefined);\n}\n","/**\n * Light/dark theme — one class, and the CSS variables in styles.css do the\n * rest (both toolbars, sidebars, popovers, and the canvas re-theme from it).\n * The mode follows the embedder's `theme` preference while the viewer runs;\n * `'system'` follows the OS setting, and switches when the user changes it.\n * The class lands on <html> by default; a delivery that must not touch the\n * page (the <embedpdf-viewer> shadow root) passes `target` and the class stays\n * inside its own subtree. The theme's tokens are CSS variables too: a delivery\n * applies {@link themeTokenCss} on the viewer's root.\n */\nimport { createContext, useContext, useEffect, useLayoutEffect, useMemo, useState } from 'react';\n\nexport type ThemeMode = 'light' | 'dark';\nexport type ThemePreference = ThemeMode | 'system';\n\n// ── tokens ───────────────────────────────────────────────────────────────────\n\n/**\n * The viewer's look, by name: each is the CSS variable `--epdf-<name>`, which the chrome's\n * stylesheet declares with a default for each mode and mixes every other shade from.\n */\nexport const THEME_TOKENS = [\n 'accent',\n 'background',\n 'surface',\n 'surface-raised',\n 'text',\n 'text-muted',\n 'border',\n 'hover',\n 'canvas',\n 'radius',\n 'font',\n] as const;\n\n/** A token's name: `surface` is the CSS variable `--epdf-surface`. */\nexport type ThemeToken = (typeof THEME_TOKENS)[number];\n\n/** Token values by name, each a CSS value: `{ surface: '#fbfaf7', radius: '2px' }`. */\nexport type ThemeTokens = { readonly [Name in ThemeToken]?: string };\n\nexport interface ThemeConfig {\n /** 'system' (default) follows the OS. */\n preference?: ThemePreference;\n /** The accent color in both modes: the same as `tokens.accent`, which wins when both are set. */\n accent?: string;\n /** Token values for both modes, over the viewer's defaults. */\n tokens?: ThemeTokens;\n /** Token values for dark mode only, over `tokens`. */\n dark?: ThemeTokens;\n}\n\n/** Normalize the shorthand — deliveries use this to read one shape. */\nexport const themeConfigOf = (theme: ThemePreference | ThemeConfig | undefined): ThemeConfig =>\n typeof theme === 'string' ? { preference: theme } : (theme ?? {});\n\nconst isThemeToken = (name: string): name is ThemeToken =>\n (THEME_TOKENS as readonly string[]).includes(name);\n\n/** The declarations of `tokens` that are tokens with a CSS value; each other entry warns. */\nfunction tokenDeclarations(tokens: ThemeTokens): string {\n return Object.entries(tokens)\n .filter(([name, value]) => {\n if (value === undefined) return false;\n if (!isThemeToken(name)) {\n console.warn(`[embedpdf] theme: \"${name}\" isn't a token, ignored`);\n return false;\n }\n if (typeof value !== 'string' || /[{};]/.test(value)) {\n console.warn(`[embedpdf] theme: ignoring the invalid value of \"${name}\"`);\n return false;\n }\n return true;\n })\n .map(([name, value]) => `--epdf-${name}:var(--embedpdf-host-${name},${value});`)\n .join('');\n}\n\n/**\n * The CSS that applies a theme's tokens on the viewer's root (`root`, a selector), for a sheet\n * after the chrome's: its tokens win over the defaults in both modes by coming later, and its\n * dark ones win in dark by naming the class too. A value is a default only: the page's own\n * `--epdf-*` variable still wins, read on the host as the chrome's stylesheet does. Empty when\n * the theme sets no token.\n */\nexport function themeTokenCss(theme: ThemePreference | ThemeConfig | undefined, root: string) {\n const { accent, tokens, dark } = themeConfigOf(theme);\n const both = tokenDeclarations({ ...(accent === undefined ? null : { accent }), ...tokens });\n const darkOnly = dark ? tokenDeclarations(dark) : '';\n return (both ? `${root}{${both}}` : '') + (darkOnly ? `${root}.dark{${darkOnly}}` : '');\n}\n\nconst ThemeCtx = createContext<{ mode: ThemeMode } | null>(null);\n\nconst DARK_QUERY = '(prefers-color-scheme: dark)';\n\nconst systemMode = (): ThemeMode =>\n typeof window !== 'undefined' && window.matchMedia?.(DARK_QUERY).matches ? 'dark' : 'light';\n\nexport function ThemeProvider({\n children,\n preference = 'system',\n target,\n}: {\n children: React.ReactNode;\n /** The mode, or 'system' (default) to follow the OS setting. */\n preference?: ThemePreference;\n /** Where the `.dark` class goes. Default: document.documentElement. */\n target?: HTMLElement | null;\n}) {\n const [system, setSystem] = useState<ThemeMode>(systemMode);\n useEffect(() => {\n if (preference !== 'system' || typeof window === 'undefined' || !window.matchMedia) return;\n const query = window.matchMedia(DARK_QUERY);\n const follow = () => setSystem(query.matches ? 'dark' : 'light');\n follow();\n query.addEventListener('change', follow);\n return () => query.removeEventListener('change', follow);\n }, [preference]);\n const mode = preference === 'system' ? system : preference;\n // Before the paint, so the viewer never shows a frame in the other mode.\n useLayoutEffect(() => {\n (target ?? document.documentElement).classList.toggle('dark', mode === 'dark');\n }, [mode, target]);\n const value = useMemo(() => ({ mode }), [mode]);\n return <ThemeCtx.Provider value={value}>{children}</ThemeCtx.Provider>;\n}\n\n/** The mode the viewer shows now. */\nexport function useTheme() {\n const ctx = useContext(ThemeCtx);\n if (!ctx) throw new Error('useTheme must be used within <ThemeProvider>');\n return ctx;\n}\n","/**\n * The panels a layout brings, as commands. Every panel gets `panel:<id>`, which\n * opens and closes it, labeled and drawn as the layout's panel says (its\n * `title` or `titleKey`, its `icon`). Which side a panel is on is the layout's\n * too; the panels on one side take turns where they're drawn (ui/panels.tsx).\n * The built-in panels add what their commands need: the feature that turns\n * them off, whether the session may use them (the owning plugin's `can*`\n * check), when there is something to show, and whether opening one puts the\n * cursor in it. Search also brings Find (`search:find`, Ctrl/Cmd+F), which\n * opens it with the cursor in its field and never closes it.\n */\nimport { panelCommandOf, type LayoutData, type LayoutPanel } from '@embedpdf/core-ui';\nimport { AnnotationToken } from '@embedpdf/react/annotation';\nimport type { CommandDef } from '@embedpdf/react/commands';\nimport { FormToken } from '@embedpdf/react/form';\nimport { RedactionToken } from '@embedpdf/react/redaction';\nimport { SearchToken } from '@embedpdf/react/search';\nimport { ShellToken } from '@embedpdf/react/shell';\nimport { SignatureToken } from '@embedpdf/react/signature';\nimport { StampToken } from '@embedpdf/react/stamp';\n\nimport type { Feature } from '../features';\nimport type { PanelSide } from '../ui/panel-layout';\n\ntype Panels = NonNullable<LayoutData['panels']>;\n\nconst isPanel = (value: unknown): value is LayoutPanel =>\n typeof value === 'object' && value !== null;\n\n/** The side a panel opens on: `end` unless it says `start`. */\nexport const panelSideOf = (panel: LayoutPanel): PanelSide =>\n panel.side === 'start' ? 'start' : 'end';\n\n/** The ids of the layout's panels on `side`, in layout order. */\nexport function panelsOnSide(data: LayoutData, side: PanelSide): string[] {\n return Object.entries(data.panels ?? {})\n .filter(([, panel]) => isPanel(panel) && panelSideOf(panel) === side)\n .map(([id]) => id);\n}\n\n/** What a built-in panel's command adds to the layout's panel. */\ntype PanelCommandFacts = Pick<CommandDef, 'allowed' | 'notAllowedKey' | 'visible'> & {\n readonly categories: readonly Feature[];\n /** Opening it asks for the cursor (`open(id, { focus: true })`), for a panel you type in. */\n readonly focus?: boolean;\n};\n\n/** The search panel's id in the layout. */\nconst SEARCH_PANEL = 'search';\n\n/** Searching, which the search panel and Find need: without it every query is refused. */\nconst SEARCHES: Pick<CommandDef, 'allowed' | 'notAllowedKey'> & {\n readonly categories: readonly Feature[];\n} = {\n categories: ['search'],\n allowed: (commandContext) => commandContext.tryGet(SearchToken)?.canSearch() ?? true,\n notAllowedKey: 'commands.notAllowed.doc-text-search',\n};\n\n/**\n * Find: the search panel with the cursor in its field, its text selected so typing replaces it.\n * It opens search, or keeps it open, and never closes it, and Ctrl/Cmd+F runs it from a text\n * field in the viewer too (the search field itself among them).\n */\nconst FIND_COMMAND: CommandDef = {\n id: 'search:find',\n labelKey: 'commands.find',\n icon: 'search',\n shortcut: 'Mod+F',\n shortcutInTextFields: true,\n ...SEARCHES,\n run: (commandContext) => commandContext.tryGet(ShellToken)?.open(SEARCH_PANEL, { focus: true }),\n};\n\nconst BUILT_IN_PANELS: ReadonlyMap<string, PanelCommandFacts> = new Map<string, PanelCommandFacts>([\n ['thumbnails', { categories: ['thumbnails'] }],\n // The engine reads no outline, and no plugin lists the document's attached files: these two\n // panels have nothing to show, so they never show.\n ['outline', { categories: ['outline'], visible: () => false }],\n ['attachments', { categories: ['attachments'], visible: () => false }],\n // Without searching the panel has no job; its button puts the cursor in the field, as Find does.\n [SEARCH_PANEL, { ...SEARCHES, focus: true }],\n // Without it there is nothing this panel could show.\n [\n 'comments',\n {\n categories: ['comments'],\n allowed: (commandContext) => commandContext.tryGet(AnnotationToken)?.canRead() ?? true,\n notAllowedKey: 'commands.notAllowed.doc-annotate-read',\n },\n ],\n ['style', { categories: ['annotations'] }],\n // The stamp libraries are the stamp plugin's: without it there is nothing to pick.\n [\n 'stamps',\n {\n categories: ['stamps'],\n allowed: (commandContext) =>\n commandContext.tryGet(StampToken)?.canPlace(commandContext.documentId ?? undefined) ?? true,\n notAllowedKey: 'commands.notAllowed.annotations-create',\n visible: (commandContext) => commandContext.tryGet(StampToken) != null,\n },\n ],\n // A person's marks are stamp libraries; the document's signatures are the signature plugin's.\n [\n 'signatures',\n {\n categories: ['signatures'],\n visible: (commandContext) =>\n commandContext.tryGet(StampToken) != null && commandContext.tryGet(SignatureToken) != null,\n },\n ],\n // Useful to a session that can propose marks or apply them; with neither power the panel\n // could only show other people's pending marks.\n [\n 'redaction',\n {\n categories: ['redaction'],\n allowed: (commandContext) => {\n const redaction = commandContext.tryGet(RedactionToken);\n return redaction ? redaction.canMark() || redaction.canApply() : true;\n },\n },\n ],\n ['measurement', { categories: ['measurement'] }],\n // The form designer's sidebar: for a session that may design forms, and in Form mode only,\n // so it closes as Form mode does (`form:design` is its switch).\n [\n 'form-design',\n {\n categories: ['forms.building'],\n allowed: (commandContext) => commandContext.tryGet(FormToken)?.canDesign() ?? true,\n visible: (commandContext) => commandContext.tryGet(ShellToken)?.isOpen('mode:form') ?? false,\n },\n ],\n]);\n\n/**\n * A `panel:<id>` command for each of the layout's panels that has none yet (`isTaken` says which\n * ids do): it opens the panel, or closes it when it's open. Without a title, its button reads\n * the panel's id. A search panel brings Find too.\n */\nexport function panelCommandsFor(\n panels: LayoutData['panels'],\n isTaken: (id: string) => boolean,\n): CommandDef[] {\n return Object.entries(panels ?? {}).flatMap(([id, panel]): CommandDef[] => {\n const commandId = panelCommandOf(id);\n if (!isPanel(panel)) return [];\n const find = id === SEARCH_PANEL && !isTaken(FIND_COMMAND.id) ? [FIND_COMMAND] : [];\n if (isTaken(commandId)) return find;\n const { focus, ...facts } = BUILT_IN_PANELS.get(id) ?? {};\n return [\n {\n id: commandId,\n label: panel.title ?? (panel.titleKey === undefined ? id : undefined),\n labelKey: panel.titleKey,\n icon: panel.icon,\n panel: focus ? { id, focus } : id,\n ...facts,\n },\n ...find,\n ];\n });\n}\n\n/** Whether two layouts' panels are the same, field for field. */\nexport const samePanels = (left: Panels | undefined, right: Panels | undefined): boolean =>\n left === right || JSON.stringify(left ?? {}) === JSON.stringify(right ?? {});\n","/**\n * Which bar gets out of the way while the pages scroll, and what a scroll is.\n * On a phone (a compact viewer), a floating bar that holds the page number\n * hides while the pages move and comes back once they have been still for a\n * moment. Only a move at the same zoom is a scroll: a zoom keeps it.\n */\nimport type { BarSchema, ViewerSize } from '@embedpdf/core-ui';\n\n/** The slot of the built-in page number item. */\nexport const PAGE_NUMBER_SLOT = 'page-number';\n\n/** How long after the pages stop scrolling the page number comes back. */\nexport const SCROLL_SETTLE_MS = 700;\n\n/** The camera of the pages: where they are, and their zoom. */\nexport interface ScrollCamera {\n readonly x: number;\n readonly y: number;\n readonly zoom: number;\n}\n\n/** Whether the camera moving from `previous` to `next` is a scroll: it moved, at the same zoom. */\nexport function isScrollOf(previous: ScrollCamera, next: ScrollCamera): boolean {\n return previous.zoom === next.zoom && (previous.x !== next.x || previous.y !== next.y);\n}\n\n/** Whether `bar` holds the custom item drawn in `slot`. */\nexport function holdsSlot(bar: BarSchema, slot: string): boolean {\n const { start = [], center = [], end = [] } = bar.sections;\n return [...start, ...center, ...end].some((group) =>\n group.items.some(\n (child) => typeof child === 'object' && 'slot' in child && child.slot === slot,\n ),\n );\n}\n\n/** Whether a floating bar hides while the pages scroll: on a phone, when it holds the page number. */\nexport function hidesWhileScrolling(bar: BarSchema | null, size: ViewerSize): boolean {\n return size === 'compact' && bar !== null && holdsSlot(bar, PAGE_NUMBER_SLOT);\n}\n","/**\n * What a phone's layout does by itself, as hooks: a bar that gets out of the\n * way while the pages scroll (`scroll-hiding.ts`), unless something in it has\n * focus, like the page number being typed; and the edges of the screen the\n * viewer reaches, so it keeps clear of the notch and the home bar there\n * (`screen-edges.ts`).\n */\nimport { useOptionalCapability } from '@embedpdf/react/runtime';\nimport { StageToken } from '@embedpdf/react/stage';\nimport { deepActiveElementOf, observeClientGeometry } from '@embedpdf/web';\nimport { useEffect, useLayoutEffect, useState, type RefObject } from 'react';\n\nimport {\n NO_SCREEN_EDGES,\n sameScreenEdges,\n screenEdgesOf,\n windowSizeOf,\n type ScreenEdges,\n} from './screen-edges';\nimport { SCROLL_SETTLE_MS, isScrollOf, type ScrollCamera } from './scroll-hiding';\n\n/**\n * Whether the bar `bar` points at is hidden now: while `enabled`, from the first scroll of the\n * main pages until they have been still for {@link SCROLL_SETTLE_MS}.\n */\nexport function useHiddenWhileScrolling(\n enabled: boolean,\n bar: RefObject<HTMLElement | null>,\n): boolean {\n const stage = useOptionalCapability(StageToken);\n const [hidden, setHidden] = useState(false);\n useEffect(() => {\n if (!enabled || !stage) return undefined;\n let previous: ScrollCamera = stage.getCamera();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const stop = stage.onCameraChanged(({ camera }) => {\n const scrolled = isScrollOf(previous, camera);\n previous = camera;\n const element = bar.current;\n if (!scrolled || !element) return;\n const active = deepActiveElementOf(element.ownerDocument);\n if (active && element.contains(active)) return;\n setHidden(true);\n clearTimeout(timer);\n timer = setTimeout(() => setHidden(false), SCROLL_SETTLE_MS);\n });\n return () => {\n stop();\n clearTimeout(timer);\n setHidden(false);\n };\n }, [enabled, stage, bar]);\n return hidden;\n}\n\n/**\n * The edges of the window the element `element` points at reaches: measured before the first\n * paint, and again when it resizes or the window resizes or scrolls.\n */\nexport function useScreenEdges(element: RefObject<HTMLElement | null>): ScreenEdges {\n const [edges, setEdges] = useState(NO_SCREEN_EDGES);\n useLayoutEffect(() => {\n const target = element.current;\n if (!target) return undefined;\n const measure = () => {\n const next = screenEdgesOf(target.getBoundingClientRect(), windowSizeOf(target));\n setEdges((previous) => (sameScreenEdges(previous, next) ? previous : next));\n };\n measure();\n const resizes = new ResizeObserver(measure);\n resizes.observe(target);\n const stopGeometry = observeClientGeometry(measure);\n return () => {\n stopGeometry();\n resizes.disconnect();\n };\n }, [element]);\n return edges;\n}\n","/**\n * The viewer's root element, and the layout resolved on it.\n *\n * One ResizeObserver on the root measures the viewer (its width, and from it\n * the size), a media query says whether the main pointer is a finger, and the\n * language gives the direction: together the env, and the `layout` function\n * runs again whenever it changes. The direction is the root's `dir`, so the\n * viewer reads its own language's way whatever the page around it does. A\n * finger as the main pointer marks the root `data-touch` (every button and\n * menu row is then 44 px tall, styles.css), and the root keeps clear of the\n * notch and the home bar on the edges of the screen it reaches. Under\n * the root, the bars leave out the tab of a mode whose bars show nothing and\n * the button of a menu that shows nothing; an open mode whose tab goes falls\n * back to View; a bar with a new mode gets its `mode:<mode>` command, and each\n * panel its `panel:<id>`, with a command of yours of the same id merged over\n * it; and each problem with the layout is logged once. The root takes focus on\n * a press anywhere in the viewer that lands on nothing focusable (the pages),\n * so the viewer's keys reach it from there.\n */\nimport {\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n type RefObject,\n} from 'react';\nimport {\n VIEW_MODE_COMMAND,\n compileBar,\n menuOf,\n modeCommandOf,\n modesOf,\n omittedCommandsOf,\n resolveLayout,\n sizeOf,\n validateLayout,\n type BarSchema,\n type Layout,\n type LayoutData,\n type LayoutEnv,\n type MenuSection,\n} from '@embedpdf/core-ui';\nimport { useCommands } from '@embedpdf/react/commands';\nimport { useI18nState } from '@embedpdf/react/i18n';\nimport {\n useDocumentId,\n useKernelValue,\n useOptionalCapability,\n useOptionalSelector,\n} from '@embedpdf/react/runtime';\nimport { ShellToken } from '@embedpdf/react/shell';\nimport { observeWidth } from '@embedpdf/web';\nimport { defaultLayout } from './config/chrome';\nimport {\n modeCommandsFor,\n modeSpecsOf,\n openModeSurfaceOf,\n sameModeSpecs,\n type ModeSpec,\n} from './config/modes';\nimport { panelCommandsFor, samePanels } from './config/panels';\nimport {\n DEFAULT_ENV,\n ResolvedLayoutProvider,\n stripOf,\n useLayoutOption,\n useViewerCommands,\n type ResolvedLayout,\n} from './config-context';\nimport { useScreenEdges } from './ui/compact';\nimport { safeAreaPaddingOf } from './ui/screen-edges';\nimport { FOCUS_ROOT_ATTRIBUTE } from './ui/viewer-layer';\n\nconst COARSE_POINTER = '(pointer: coarse)';\n\nconst isCoarsePointer = (): boolean =>\n typeof matchMedia === 'function' && matchMedia(COARSE_POINTER).matches;\n\nconst sameStrings = (left: readonly string[], right: readonly string[]): boolean =>\n left.length === right.length && left.every((value, i) => value === right[i]);\n\n/** `value`, or the last one when it equals that one: a value that stays the same object while equal. */\nfunction useEqualValue<T>(value: T, isEqual: (left: T, right: T) => boolean): T {\n const last = useRef(value);\n if (last.current !== value && !isEqual(last.current, value)) last.current = value;\n return last.current;\n}\n\n/**\n * The env of the element `root` points at: measured before the first paint, then on every\n * change. `null` for the first render, before there is anything to measure.\n */\nfunction useMeasuredEnv(root: RefObject<HTMLElement | null>): LayoutEnv | null {\n const dir = useI18nState((state) => state.direction);\n const [width, setWidth] = useState<number | null>(null);\n const [touch, setTouch] = useState(isCoarsePointer);\n useLayoutEffect(() => {\n const element = root.current;\n return element\n ? observeWidth(element, (measured) => setWidth(Math.round(measured)))\n : undefined;\n }, [root]);\n useEffect(() => {\n if (typeof matchMedia !== 'function') return undefined;\n const query = matchMedia(COARSE_POINTER);\n const update = () => setTouch(query.matches);\n query.addEventListener('change', update);\n return () => query.removeEventListener('change', update);\n }, []);\n return useMemo(\n () => (width === null ? null : { size: sizeOf(width), width, touch, dir }),\n [width, touch, dir],\n );\n}\n\n/**\n * The viewer's root: a `<div>` the layout is measured on, providing the resolved layout to\n * everything inside it. Its children render once per change of their own, not per resize.\n * `rootRef`, when given, is set to the root.\n */\nexport function LayoutRoot({\n className,\n rootRef,\n children,\n}: {\n className?: string;\n rootRef?: RefObject<HTMLDivElement>;\n children: ReactNode;\n}) {\n const ownRoot = useRef<HTMLDivElement>(null);\n const root = rootRef ?? ownRoot;\n const measured = useMeasuredEnv(root);\n // The first render, before the root is measured, lays out as a wide viewer; the measured\n // env replaces it before the browser paints.\n const env = measured ?? DEFAULT_ENV;\n const option = useLayoutOption();\n const layout = useMemo(() => resolveLayout(option, defaultLayout, env), [option, env]);\n const data = layout.toJSON();\n\n const commands = useCommands();\n const documentId = useDocumentId() ?? undefined;\n const omitted = useKernelValue(\n () => omittedCommandsOf(data, (id) => commands.resolveCommand(id, documentId)),\n sameStrings,\n );\n\n // A bar keeps its object while it stays the same, so a resize that changes nothing in it\n // doesn't make its toolbar start over.\n const compiled = useRef(new Map<string, { readonly key: string; readonly value: unknown }>());\n const resolved = useMemo<ResolvedLayout>(() => {\n const stable = <T,>(name: string, value: T): T => {\n const key = JSON.stringify(value);\n const previous = compiled.current.get(name);\n if (previous?.key === key) return previous.value as T;\n compiled.current.set(name, { key, value });\n return value;\n };\n const omit = new Set(omitted);\n const bars = new Map<string, BarSchema>();\n for (const id of Object.keys(data.bars ?? {}))\n bars.set(id, stable(`bar:${id}`, compileBar(data, id, { omit })!));\n const bar = (id: string) => bars.get(id) ?? null;\n const strips = {\n selection: stable('strip:selection', stripOf(data, 'selection', bar)),\n annotation: stable('strip:annotation', stripOf(data, 'annotation', bar)),\n };\n const menus = new Map<string, readonly MenuSection[]>();\n for (const id of Object.keys(data.menus ?? {}))\n menus.set(id, stable(`menu:${id}`, menuOf(data, id)!));\n return {\n data,\n env,\n bar,\n strip: (target) => strips[target],\n menu: (id) => menus.get(id) ?? null,\n };\n }, [data, env, omitted]);\n\n // The tabs on show: a mode's tab goes when its bars show nothing, and when its own command is\n // hidden (turned off with its feature, or not allowed).\n const tabs = useKernelValue(\n () =>\n modesOf(data)\n .map(modeCommandOf)\n .filter(\n (id) =>\n !omitted.includes(id) && commands.resolveCommand(id, documentId)?.visible === true,\n ),\n sameStrings,\n );\n\n useModeCommands(useEqualValue(modeSpecsOf(data), sameModeSpecs));\n usePanelCommands(useEqualValue(data.panels, samePanels));\n useModeFallback(tabs);\n useLayoutWarnings(measured === null ? null : layout);\n\n const edges = useScreenEdges(root);\n return (\n <div\n ref={root}\n // Focusable but not a Tab stop: a press on the pages gives the viewer focus.\n tabIndex={-1}\n {...{ [FOCUS_ROOT_ATTRIBUTE]: '' }}\n dir={env.dir}\n data-touch={env.touch ? '' : undefined}\n className={className}\n style={safeAreaPaddingOf(edges)}\n >\n <ResolvedLayoutProvider value={resolved}>{children}</ResolvedLayoutProvider>\n </div>\n );\n}\n\n/**\n * Registers a command for each mode that has none, for as long as the layout has the mode, with\n * a command of yours of the same id merged over it.\n */\nfunction useModeCommands(specs: readonly ModeSpec[]): void {\n const commands = useCommands();\n const yours = useViewerCommands();\n // Before paint, so a new mode's tab is there in the first frame.\n useLayoutEffect(() => {\n const definitions = modeCommandsFor(\n specs,\n (id) => commands.hasCommand(id) && !yours.isYours(id),\n ).map(yours.over);\n return definitions.length > 0\n ? commands.registerCommands(definitions, { replace: true })\n : undefined;\n }, [commands, specs, yours]);\n}\n\n/**\n * Registers a `panel:<id>` command for each panel that has none, for as long as the layout has\n * the panel, with a command of yours of the same id merged over it; a panel whose title or icon\n * changes gets its command again.\n */\nfunction usePanelCommands(panels: LayoutData['panels']): void {\n const commands = useCommands();\n const yours = useViewerCommands();\n // Before paint, so a panel's button is there in the first frame.\n useLayoutEffect(() => {\n const definitions = panelCommandsFor(\n panels,\n (id) => commands.hasCommand(id) && !yours.isYours(id),\n ).map(yours.over);\n return definitions.length > 0\n ? commands.registerCommands(definitions, { replace: true })\n : undefined;\n }, [commands, panels, yours]);\n}\n\n/** Back to View when the open mode has no tab: its bars show nothing, or the layout lost it. */\nfunction useModeFallback(tabs: readonly string[]): void {\n const commands = useCommands();\n const shell = useOptionalCapability(ShellToken);\n const openMode = useOptionalSelector(ShellToken, openModeSurfaceOf, null);\n useEffect(() => {\n if (openMode === null || tabs.includes(openMode)) return;\n shell?.close(openMode);\n commands.execute(VIEW_MODE_COMMAND).catch(() => {});\n }, [commands, shell, openMode, tabs]);\n}\n\n/**\n * Logs each problem with the layout once, with the closest id that exists; `null` while there is\n * no measured layout to check. The viewer still starts.\n */\nfunction useLayoutWarnings(layout: Layout | null): void {\n const commands = useCommands();\n const logged = useRef(new Set<string>());\n useEffect(() => {\n if (layout === null) return;\n // The bundle a page loads from a CDN has no development mode, so this always runs: a typo\n // that quietly loses a button costs more than a console line.\n const problems = validateLayout(layout, {\n commands: commands.listCommandIds(),\n hasCommand: (id) => commands.hasCommand(id),\n });\n for (const problem of problems) {\n if (logged.current.has(problem)) continue;\n logged.current.add(problem);\n console.warn(`[embedpdf] layout: ${problem}`);\n }\n }, [commands, layout]);\n}\n","/**\n * The layout's places, drawn: the bars along each edge of the viewer, and the\n * bars floating over the pages.\n *\n * An edge's bars stack from the outside in, each followed by the bars that ride\n * along it on the side of the pages. Bars at `start` and `end` are vertical and\n * follow the viewer's direction (the `dir` on its root), so they swap sides in\n * a right-to-left language. A floating bar draws as a pill around its items,\n * over the pages and under the bars over a selection. Each bar tells what opens\n * from it where it is ({@link BarEdgeProvider}). A bar with nothing visible\n * draws nothing, and a bar with a mode shows while that mode is open. On a\n * phone, a floating bar with the page number hides while the pages scroll.\n */\nimport {\n FLOAT_POSITIONS,\n commandOfUnit,\n edgeStackOf,\n floatStackOf,\n hasVisibleUnits,\n hostOf,\n modeCommandOf,\n normalizeBar,\n type BarEdge as LayoutEdge,\n type BarSchema,\n type FloatPosition,\n type SectionName,\n} from '@embedpdf/core-ui';\nimport { useCommands } from '@embedpdf/react/commands';\nimport { useDocumentId, useKernelValue, useOptionalSelector } from '@embedpdf/react/runtime';\nimport { ShellToken } from '@embedpdf/react/shell';\nimport { isolatePointerDown } from '@embedpdf/web';\nimport { useEffect, useLayoutEffect, useMemo, useRef } from 'react';\n\nimport { openModeSurfaceOf } from './config/modes';\nimport { useLayoutEnv, useResolvedLayout } from './config-context';\nimport { BarEdgeProvider, type BarEdge } from './ui/bar-edge';\nimport { useHiddenWhileScrolling } from './ui/compact';\nimport { hidesWhileScrolling } from './ui/scroll-hiding';\nimport { AppToolbar } from './ui/toolbar';\n\n/** Whether anything in the bar is visible now: a bar with nothing visible draws nothing. */\nfunction useBarShows(bar: BarSchema | null): boolean {\n const commands = useCommands();\n const documentId = useDocumentId() ?? undefined;\n const normalized = useMemo(() => (bar ? normalizeBar(bar) : null), [bar]);\n return useKernelValue(\n () =>\n normalized !== null &&\n hasVisibleUnits(normalized, (unit) => {\n const command = commandOfUnit(unit);\n return command !== null && commands.resolveCommand(command, documentId)?.visible === true;\n }),\n );\n}\n\n/** The bars of `stack` that show now: a bar without a mode, or one whose mode is open. */\nfunction useShownBars(stack: readonly string[]): string[] {\n const { data } = useResolvedLayout();\n const openMode = useOptionalSelector(ShellToken, openModeSurfaceOf, null);\n return stack.filter((id) => {\n const mode = data.bars?.[id]?.mode;\n return mode === undefined || openMode === modeCommandOf(mode);\n });\n}\n\n// ── the edges ────────────────────────────────────────────────────────────────\n\n/** The line between a bar and the pages: on its inner side. */\nconst INNER_BORDER: Record<LayoutEdge, string> = {\n top: 'border-b',\n bottom: 'border-t',\n start: 'border-e',\n end: 'border-s',\n};\n\n/** One bar along an edge: its toolbar in a band, or nothing when nothing in it is visible. */\nfunction EdgeBar({ id, edge, rides }: { id: string; edge: LayoutEdge; rides: boolean }) {\n const bar = useResolvedLayout().bar(id);\n const shows = useBarShows(bar);\n if (!bar || !shows) return null;\n const vertical = edge === 'start' || edge === 'end';\n return (\n <BarEdgeProvider value={edge}>\n <div\n // Every bar is the `toolbar` part, which page CSS reaches through `::part()`.\n part=\"toolbar\"\n data-bar={id}\n className={`border-border flex shrink-0 ${\n vertical ? 'flex-col px-2 py-4' : 'items-center px-4 py-2'\n } ${rides ? 'bg-surface-alt' : 'bg-surface'} ${INNER_BORDER[edge]}`}\n >\n <AppToolbar\n bar={bar}\n orientation={vertical ? 'vertical' : 'horizontal'}\n className={vertical ? 'min-h-0 flex-1' : 'w-full'}\n />\n </div>\n </BarEdgeProvider>\n );\n}\n\n/**\n * The bars along one edge, from the outside in, each followed by the bars riding along it. The\n * outside comes first in the document on the top and start edges, and last on the bottom and end.\n */\nexport function EdgeBars({ edge }: { edge: LayoutEdge }) {\n const { data } = useResolvedLayout();\n const stack = useShownBars(useMemo(() => edgeStackOf(data, edge), [data, edge]));\n const ordered = edge === 'top' || edge === 'start' ? stack : [...stack].reverse();\n return (\n <>\n {ordered.map((id) => (\n <EdgeBar key={id} id={id} edge={edge} rides={hostOf(data.bars?.[id]?.place) !== null} />\n ))}\n </>\n );\n}\n\n// ── over the pages ───────────────────────────────────────────────────────────\n\n/** Where a floating bar's items sit across the pages: its section of a one-section bar. */\nconst ALIGN_OF: Record<FloatPosition, SectionName> = {\n 'top-start': 'start',\n top: 'center',\n 'top-end': 'end',\n start: 'start',\n end: 'end',\n 'bottom-start': 'start',\n bottom: 'center',\n 'bottom-end': 'end',\n};\n\n/**\n * Where the bars floating at a position stack: 20 px in from the edges of the pages, which clears\n * their 12 px scrollbars; the first bar is nearest the edge, the bars riding along it inside it.\n * No transform: it would hold the fixed layers of the menus that open from the bars.\n */\nconst STACK_CLASS: Record<FloatPosition, string> = {\n 'top-start': 'top-5 flex-col',\n top: 'top-5 flex-col',\n 'top-end': 'top-5 flex-col',\n start: 'inset-y-5 flex-col justify-center',\n end: 'inset-y-5 flex-col justify-center',\n 'bottom-start': 'bottom-5 flex-col-reverse',\n bottom: 'bottom-5 flex-col-reverse',\n 'bottom-end': 'bottom-5 flex-col-reverse',\n};\n\n/** The toolbar's sections, in the order the headless toolbar draws them. */\nconst SECTION_ORDER: readonly SectionName[] = ['start', 'center', 'end'];\n\n/**\n * A floating bar opens its menus toward the other half of the viewer; one in the middle of a side\n * opens them downward.\n */\nconst edgeOfFloat = (position: FloatPosition): BarEdge =>\n position.startsWith('bottom') ? 'float-bottom' : 'float-top';\n\n/** `bar` with all its groups, in order, in one section. */\nfunction inOneSection(bar: BarSchema, section: SectionName): BarSchema {\n const groups = [\n ...(bar.sections.start ?? []),\n ...(bar.sections.center ?? []),\n ...(bar.sections.end ?? []),\n ];\n return { id: bar.id, sections: { [section]: groups } };\n}\n\n/**\n * One floating bar. Its toolbar spans the room across the pages, so it fits what there is, and\n * holds the bar in the one section that puts it where it floats; the `float-pill` variant\n * (styles.css) draws that section as the pill. Presses on the bar stay off the pages.\n */\nfunction FloatingBar({ id, position }: { id: string; position: FloatPosition }) {\n const bar = useResolvedLayout().bar(id);\n const shows = useBarShows(bar);\n const placed = useMemo(\n () => (bar ? inOneSection(bar, ALIGN_OF[position]) : null),\n [bar, position],\n );\n const lane = useRef<HTMLDivElement>(null);\n const drawn = placed !== null && shows;\n useEffect(() => (drawn && lane.current ? isolatePointerDown(lane.current) : undefined), [drawn]);\n const { size } = useLayoutEnv();\n const hidden = useHiddenWhileScrolling(hidesWhileScrolling(bar, size), lane);\n // The pill, the bar's `toolbar` part, is the section of the toolbar that holds the bar. The\n // headless toolbar draws its sections first, in order and without attributes of ours, and\n // keeps the same elements while it's there: naming them once it has drawn them is enough.\n useLayoutEffect(() => {\n const sections = lane.current?.querySelectorAll(':scope > [role=\"toolbar\"] > div');\n sections?.forEach((section, index) => {\n if (SECTION_ORDER[index] === ALIGN_OF[position]) section.setAttribute('part', 'toolbar');\n else section.removeAttribute('part');\n });\n }, [drawn, position]);\n if (!drawn) return null;\n return (\n <BarEdgeProvider value={edgeOfFloat(position)}>\n <div\n ref={lane}\n data-bar={id}\n data-scroll-hidden={hidden ? '' : undefined}\n className=\"flex w-full transition-opacity duration-200\"\n >\n <AppToolbar\n bar={placed}\n className=\"float-pill:pointer-events-auto float-pill:rounded-full float-pill:border float-pill:border-border-subtle float-pill:bg-elevated/95 float-pill:p-0.5 float-pill:shadow-lg pointer-events-none w-full\"\n />\n </div>\n </BarEdgeProvider>\n );\n}\n\n/** The bars floating over the pages, stacked at each of their positions. */\nexport function FloatingBars() {\n const { data } = useResolvedLayout();\n const stacks = useMemo(\n () =>\n FLOAT_POSITIONS.map((position) => ({ position, stack: floatStackOf(data, position) })).filter(\n ({ stack }) => stack.length > 0,\n ),\n [data],\n );\n return (\n <>\n {stacks.map(({ position, stack }) => (\n <FloatingStack key={position} position={position} stack={stack} />\n ))}\n </>\n );\n}\n\nfunction FloatingStack({ position, stack }: { position: FloatPosition; stack: readonly string[] }) {\n const shown = useShownBars(stack);\n if (shown.length === 0) return null;\n return (\n <div\n data-float={position}\n className={`pointer-events-none absolute inset-x-5 flex gap-2 ${STACK_CLASS[position]}`}\n >\n {shown.map((id) => (\n <FloatingBar key={id} id={id} position={position} />\n ))}\n </div>\n );\n}\n","/**\n * A feature's interface, loaded on first use. Each panel, dialog and inspector that belongs to\n * one feature is a chunk of its own: it isn't part of the viewer's first load, so the pages show\n * sooner. Once a document shows and the browser is idle, the viewer fetches those chunks in the\n * background ({@link FeaturePrefetch}), one per idle moment, so the first open is instant in\n * practice; one opened before that loads right then. Until its chunk arrives a component draws\n * nothing; afterwards it renders as if it had always been there.\n *\n * A dialog or an inspector mounts with the viewer and draws itself only while its surface is\n * open; it is given `shownWhile`, a hook that says when, so its chunk isn't needed before.\n */\nimport { Suspense, lazy, useEffect, type ComponentType } from 'react';\n\ninterface LazyOptions {\n /** A hook: whether the component shows now. Until it first does, its chunk isn't needed. */\n readonly shownWhile?: () => boolean;\n}\n\n/** Every lazy component's chunk, as the one load it shares with its component. */\nconst chunks: (() => Promise<unknown>)[] = [];\n\n/** `load`'s component, imported when it first renders (and `shownWhile` says it shows). */\nexport function lazyComponent<Props extends object>(\n load: () => Promise<ComponentType<Props>>,\n { shownWhile }: LazyOptions = {},\n): ComponentType<Props> {\n let loading: Promise<ComponentType<Props>> | null = null;\n // One load shared by the component and the background fetch; a failed one is tried again.\n const loadOnce = () =>\n (loading ??= load().catch((error: unknown) => {\n loading = null;\n throw error;\n }));\n chunks.push(loadOnce);\n // `lazy` types its component's props with a ref; these components take none.\n const Loaded = lazy(async () => ({\n default: await loadOnce(),\n })) as unknown as ComponentType<Props>;\n const Lazy = (props: Props) => (\n <Suspense fallback={null}>\n <Loaded {...props} />\n </Suspense>\n );\n if (!shownWhile) return Lazy;\n return function WhenShown(props: Props) {\n return shownWhile() ? <Lazy {...props} /> : null;\n };\n}\n\n/** How long the background fetch waits for an idle moment before it fetches anyway. */\nconst IDLE_TIMEOUT_MS = 10_000;\n/** Without idle callbacks (Safari), a pause between fetches instead. */\nconst NO_IDLE_DELAY_MS = 1_000;\n\n/** Run `run` once the browser is idle: an idle callback, or a pause where there are none. */\nfunction whenIdle(run: () => void): () => void {\n if (typeof requestIdleCallback === 'function') {\n const handle = requestIdleCallback(run, { timeout: IDLE_TIMEOUT_MS });\n return () => cancelIdleCallback(handle);\n }\n const timer = setTimeout(run, NO_IDLE_DELAY_MS);\n return () => clearTimeout(timer);\n}\n\nlet prefetching: 'not-yet' | 'running' | 'done' = 'not-yet';\n\n/** Fetch every lazy chunk not loaded yet, one per idle moment. Once per page; each fetch shares its component's load. */\nfunction prefetchChunks(): () => void {\n if (prefetching !== 'not-yet') return () => {};\n prefetching = 'running';\n const queue = [...chunks];\n let cancel: () => void = () => {};\n let stopped = false;\n const next = () => {\n const load = queue.shift();\n if (stopped) return;\n if (!load) {\n prefetching = 'done';\n return;\n }\n cancel = whenIdle(() => {\n // A chunk that fails to load (offline) is tried again when its component first renders.\n void load()\n .catch(() => {})\n .finally(next);\n });\n };\n next();\n return () => {\n stopped = true;\n cancel();\n if (prefetching === 'running') prefetching = 'not-yet';\n };\n}\n\n/**\n * Mounted where a document shows: once it has, fetches the features' chunks in the background\n * while the browser is idle. Draws nothing.\n */\nexport function FeaturePrefetch() {\n useEffect(() => prefetchChunks(), []);\n return null;\n}\n","/**\n * The floating strip's pixels, shared by every contextual strip (annotation\n * selection, text selection, …): a rounded toolbar of command buttons with\n * derived group separators. The where is each strip's menu component\n * (`<AnnotationMenu>`, `<SelectionMenu>`); the which is the commands'\n * `visible`/`enabled` derivations via `useStripView`. This file only draws.\n *\n * The strips sit above what's selected, and below it when there's no room, so\n * a menu from one opens on the strip's side, away from the selection (the\n * `selection` edge); it flips when there's no room there. Each strip is a\n * `toolbar` part and its buttons `toolbar-button` parts, like any bar's.\n */\nimport type { ResolvedCommand } from '@embedpdf/react/commands';\nimport type { useStripView } from '@embedpdf/react/toolbar';\nimport { Fragment } from 'react';\n\nimport { BarEdgeProvider } from './bar-edge';\nimport { Icon } from './icons';\nimport { MenuAnchor } from './menu';\nimport { buttonClass, buttonPart } from './toolbar';\n\nfunction StripButton({ cmd, run }: { cmd: ResolvedCommand; run: () => void }) {\n // A menu command is active while its menu is open at this button: it says it's expanded.\n const draw = (active: boolean) => (\n <button\n type=\"button\"\n onClick={run}\n disabled={!cmd.enabled}\n aria-pressed={cmd.menu ? undefined : active || undefined}\n aria-haspopup={cmd.menu ? 'menu' : undefined}\n aria-expanded={cmd.menu ? active : undefined}\n aria-label={cmd.label}\n title={cmd.label}\n part={buttonPart(active)}\n className={buttonClass(active, cmd.enabled)}\n >\n {cmd.icon && <Icon name={cmd.icon} size={20} accent={cmd.iconAccent} />}\n </button>\n );\n if (!cmd.menu) return draw(cmd.active);\n return <MenuAnchor menuId={cmd.menu}>{draw}</MenuAnchor>;\n}\n\nexport function StripBar({\n view,\n label,\n}: {\n view: NonNullable<ReturnType<typeof useStripView>>;\n label: string;\n}) {\n return (\n <BarEdgeProvider value=\"selection\">\n <div\n role=\"toolbar\"\n aria-label={label}\n part=\"toolbar\"\n className=\"border-border-subtle bg-elevated flex items-center gap-1 rounded-lg border p-1 shadow-xl\"\n >\n {view.groups.map((group, i) => (\n <Fragment key={group.id}>\n {i > 0 && <span aria-hidden className=\"bg-border h-5 w-px\" />}\n {group.commands.map((cmd) => (\n <StripButton key={cmd.id} cmd={cmd} run={() => view.execute(cmd.id)} />\n ))}\n </Fragment>\n ))}\n </div>\n </BarEdgeProvider>\n );\n}\n","/**\n * The annotation-selection floating strip:\n *\n * config/chrome.ts `strips.annotation` declares what may appear\n * each command's visible/enabled decides which items show\n * <AnnotationMenu> solves where (camera transform,\n * rotate-knob dodging, pointer isolation):\n * above the selection, below it without\n * room above\n *\n * useStripView is the live intersection: hidden commands drop out, empty\n * groups vanish, null when nothing applies. Mounted in the Stage `overlay`\n * slot. The pixels are the shared <StripBar>.\n */\nimport { useEffect } from 'react';\nimport { AnnotationMenu, useAnnotationState } from '@embedpdf/react/annotation';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useStripView } from '@embedpdf/react/toolbar';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useStripSchema } from '../config-context';\nimport { lazyComponent } from './lazy';\nimport { StripBar } from './strip-bar';\n\n// The link editor loads the first time someone edits a link.\nconst LinkEditorCard = lazyComponent(() => import('./link-editor').then((ui) => ui.LinkEditorCard));\n\nexport function AnnotationStrip() {\n const t = useT();\n const view = useStripView(useStripSchema('annotation'));\n // The link editor popover rides the same anchor and replaces the strip\n // while open — one anchored card at a time, on the projector.\n const editor = useSurface('link-editor');\n const selection = useAnnotationState((state) => state.selected);\n // A stale editor never outlives its selection.\n useEffect(() => {\n if (!selection.length && editor.isOpen) editor.close();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selection.length, editor.isOpen]);\n if (!view) return null;\n return (\n <AnnotationMenu placement=\"top\" gap={15}>\n {editor.isOpen ? (\n <LinkEditorCard onClose={editor.close} />\n ) : (\n <StripBar view={view} label={t('commands.annotate.strip')} />\n )}\n </AnnotationMenu>\n );\n}\n","/**\n * Boot-state panes for the document area — what renders instead of the Stage\n * while the selected tab's document isn't ready:\n *\n * `locked` → <PasswordPrompt/>\n * `error` → <DocumentError/>, which says why and can try again\n *\n * Both are per-tab, not modal: several tabs can be locked/broken at once and\n * switching tabs stays free. The prompt drives one call —\n * `documents.unlock(id, { password })` — identical on the local (worker loads\n * the parked bytes) and cloud (/access grant) engines. The \"incorrect\" copy\n * keys on a real rejection: either this session's failed attempt, or\n * `passwordProvided` (a config-supplied password the engine already rejected).\n */\nimport { useT } from '@embedpdf/react/i18n';\nimport {\n useDocumentId,\n useDocuments,\n useDocumentsState,\n type PluginErrorInfo,\n} from '@embedpdf/react/runtime';\nimport { useState } from 'react';\n\nimport { Icon } from './icons';\n\nexport function PasswordPrompt() {\n const docId = useDocumentId();\n const { unlock, close } = useDocuments();\n const docs = useDocumentsState((state) => state.documents);\n const t = useT();\n const [password, setPassword] = useState('');\n const [rejected, setRejected] = useState(false);\n const [busy, setBusy] = useState(false);\n\n const doc = docs.find((documentInfo) => documentInfo.id === docId);\n if (!docId || !doc) return null;\n const incorrect = rejected || doc.passwordProvided === true;\n\n const submit = async () => {\n if (busy || !password.trim()) return;\n setBusy(true);\n try {\n await unlock(docId, { password });\n // success → the tab promotes to ready and this pane unmounts\n } catch {\n setRejected(true);\n setPassword('');\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <div className=\"bg-app flex h-full w-full items-center justify-center p-8\">\n <div className=\"bg-surface border-border w-full max-w-sm rounded-xl border p-6 shadow-lg\">\n <div className=\"flex flex-col items-center text-center\">\n <div className=\"bg-accent-light mb-4 rounded-full p-4\">\n <Icon name=\"lock\" size={28} className=\"text-accent\" />\n </div>\n <h3 className=\"text-fg text-lg font-semibold\">{t('passwordPrompt.title')}</h3>\n {doc.name && <p className=\"text-fg-muted mt-1 text-sm\">{doc.name}</p>}\n </div>\n\n <p className=\"text-fg-secondary mt-4 text-center text-sm\">\n {incorrect ? t('passwordPrompt.incorrect') : t('passwordPrompt.required')}\n </p>\n\n <div className=\"mt-5\">\n <label className=\"text-fg mb-1.5 block text-sm font-medium\" htmlFor=\"doc-password\">\n {t('passwordPrompt.label')}\n </label>\n <input\n id=\"doc-password\"\n type=\"password\"\n value={password}\n onChange={(event) => setPassword(event.target.value)}\n onKeyDown={(event) => event.key === 'Enter' && void submit()}\n disabled={busy}\n placeholder={t('passwordPrompt.placeholder')}\n className=\"bg-surface border-border focus:border-accent focus:ring-accent text-fg placeholder:text-fg-muted block w-full rounded-md border px-3 py-2.5 text-sm focus:outline-none focus:ring-1 disabled:opacity-50\"\n autoFocus\n />\n </div>\n\n {incorrect && (\n <div className=\"mt-3 flex items-center gap-2 rounded-md border border-red-500/40 bg-red-500/10 p-3\">\n <Icon name=\"alertTriangle\" size={16} className=\"flex-shrink-0 text-red-500\" />\n <p className=\"text-sm text-red-500\">{t('passwordPrompt.incorrectWarning')}</p>\n </div>\n )}\n\n <div className=\"mt-6 flex gap-3\">\n <button\n type=\"button\"\n onClick={() => void close(docId)}\n disabled={busy}\n className=\"border-border text-fg-secondary hover:bg-hover flex-1 cursor-pointer rounded-md border px-4 py-2.5 text-sm font-medium transition-colors disabled:opacity-50\"\n >\n {t('passwordPrompt.cancel')}\n </button>\n <button\n type=\"button\"\n onClick={() => void submit()}\n disabled={busy || !password.trim()}\n className=\"bg-accent text-on-accent flex-1 cursor-pointer rounded-md px-4 py-2.5 text-sm font-medium transition-colors hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {busy ? t('passwordPrompt.opening') : t('passwordPrompt.open')}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\n/**\n * The key of the words that say why a document couldn't be opened, from its error's code: it\n * isn't there, the user may not open it, it isn't a PDF (or is damaged), this engine can't open\n * it, or something else went wrong.\n */\nexport function errorReasonKeyOf(error: PluginErrorInfo | undefined): string {\n switch (error?.code) {\n case 'not-found':\n return 'documentError.notFound';\n case 'permission-denied':\n return 'documentError.notAllowed';\n case 'invalid-input':\n return 'documentError.damaged';\n case 'unsupported':\n return 'documentError.unsupported';\n default:\n return 'documentError.unknown';\n }\n}\n\n/**\n * A document that couldn't be opened: why, **Try again** (the same source, in the same tab), and\n * Close.\n */\nexport function DocumentError() {\n const docId = useDocumentId();\n const { close, retry } = useDocuments();\n const docs = useDocumentsState((state) => state.documents);\n const t = useT();\n const doc = docs.find((documentInfo) => documentInfo.id === docId);\n if (!docId || !doc) return null;\n\n return (\n <div className=\"bg-app flex h-full w-full items-center justify-center p-8\">\n <div\n role=\"alert\"\n className=\"bg-surface border-border flex max-w-sm flex-col items-center rounded-xl border p-6 text-center shadow-lg\"\n >\n <div className=\"mb-4 rounded-full bg-red-500/10 p-4\">\n <Icon name=\"alertTriangle\" size={28} className=\"text-red-500\" />\n </div>\n <h3 className=\"text-fg text-lg font-semibold\">{t('documentError.title')}</h3>\n {doc.name && <p className=\"text-fg-muted mt-1 text-sm\">{doc.name}</p>}\n <p className=\"text-fg-secondary mt-2 text-sm\" data-epdf-error-reason=\"\">\n {t(errorReasonKeyOf(doc.error))}\n </p>\n <div className=\"mt-5 flex w-full gap-3\">\n <button\n type=\"button\"\n onClick={() => void close(docId)}\n className=\"border-border text-fg-secondary hover:bg-hover flex-1 cursor-pointer rounded-md border px-4 py-2.5 text-sm font-medium transition-colors\"\n >\n {t('documentError.close')}\n </button>\n {/* The tab shows it loading at once, and this again if it fails again. */}\n <button\n type=\"button\"\n onClick={() => void retry(docId).catch(() => {})}\n className=\"bg-accent text-on-accent flex-1 cursor-pointer rounded-md px-4 py-2.5 text-sm font-medium transition-colors hover:opacity-90\"\n >\n {t('documentError.retry')}\n </button>\n </div>\n </div>\n </div>\n );\n}\n","/**\n * Drop a PDF on the viewer to open it as a new tab: the `document:open` command, given the\n * dropped files. While a file is dragged over, a drop target says so. It takes drops only while\n * that command is there (`config/open-files.ts`); a drag of text, of an annotation, or of files\n * that aren't PDFs is left to the page.\n */\nimport { useCommand, useCommands } from '@embedpdf/react/commands';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useRef, useState, type DragEvent, type ReactNode } from 'react';\n\nimport { isPdfFile, mayCarryPdf, OPEN_COMMAND_ID, type OpenFilesArgs } from '../config/open-files';\n\nexport function DropToOpen({ className, children }: { className: string; children: ReactNode }) {\n const t = useT();\n const commands = useCommands();\n const open = useCommand(OPEN_COMMAND_ID);\n const available = open.visible && open.enabled;\n // A drag enters and leaves every element it crosses: count them, so the target stays until\n // the drag leaves this box.\n const entered = useRef(0);\n const [over, setOver] = useState(false);\n\n const takes = (event: DragEvent) => available && mayCarryPdf(event.dataTransfer);\n const reset = () => {\n entered.current = 0;\n setOver(false);\n };\n\n return (\n <div\n className={className}\n onDragEnter={(event) => {\n if (!takes(event)) return;\n event.preventDefault();\n entered.current += 1;\n setOver(true);\n }}\n onDragOver={(event) => {\n if (!takes(event)) return;\n event.preventDefault();\n event.dataTransfer.dropEffect = 'copy';\n }}\n onDragLeave={() => {\n if (entered.current === 0) return;\n entered.current -= 1;\n if (entered.current === 0) setOver(false);\n }}\n onDrop={(event) => {\n reset();\n if (!takes(event)) return;\n // A drop this box took is the viewer's: the browser doesn't show the file in place of\n // the page, and the files that aren't PDFs are left out.\n event.preventDefault();\n event.stopPropagation();\n const files = Array.from(event.dataTransfer.files).filter(isPdfFile);\n if (files.length === 0) return;\n const args: OpenFilesArgs = { files };\n // A failing command reports itself through the commands' onExecutionFailed.\n void commands.execute(OPEN_COMMAND_ID, { args }).catch(() => {});\n }}\n >\n {children}\n {over && (\n <div\n data-epdf-drop-target=\"\"\n className=\"border-accent bg-accent-light/60 pointer-events-none absolute inset-2 z-40 grid place-items-center rounded-lg border-2 border-dashed\"\n >\n <span className=\"bg-elevated text-fg rounded-full px-4 py-1.5 text-sm font-medium shadow-lg\">\n {t('dropToOpen.label', { fallback: 'Drop a PDF to open it' })}\n </span>\n </div>\n )}\n </div>\n );\n}\n","/**\n * The Go to Page dialog, which `page:go-to` opens when it has no page to go to: the page's\n * number, typed. Enter or Go goes there (past either end is that end); Escape or Cancel keeps\n * the page.\n */\nimport { useT } from '@embedpdf/react/i18n';\nimport { useOptionalCapability } from '@embedpdf/react/runtime';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { StageToken, useStageState } from '@embedpdf/react/stage';\nimport { useId, useState } from 'react';\n\nimport { GO_TO_PAGE_DIALOG } from '../config/commands';\nimport { Dialog } from './dialog';\nimport { NUMBER_SLOT } from './page-number';\n\nexport function GoToPageDialog() {\n const surface = useSurface(GO_TO_PAGE_DIALOG);\n return surface.isOpen ? <GoToPageForm onClose={surface.close} /> : null;\n}\n\nfunction GoToPageForm({ onClose }: { onClose: () => void }) {\n const t = useT();\n const titleId = useId();\n const stage = useOptionalCapability(StageToken);\n // The Stage cursor is a 0-based display index; people count from 1.\n const current = useStageState((state) => state.currentPageIndex + 1);\n const total = useStageState((state) => state.pageCount);\n const [draft, setDraft] = useState(() => String(current));\n\n const go = () => {\n const page = Number.parseInt(draft, 10);\n if (Number.isFinite(page) && total > 0) {\n stage?.goToPage(Math.min(Math.max(page, 1), total) - 1);\n }\n onClose();\n };\n const [before, after = ''] = t('demo.page', {\n params: { current: NUMBER_SLOT, total },\n }).split(NUMBER_SLOT);\n\n return (\n <Dialog\n labelledBy={titleId}\n onClose={onClose}\n className=\"border-border bg-surface w-80 rounded-lg border p-4 shadow-xl\"\n >\n <form\n onSubmit={(event) => {\n event.preventDefault();\n go();\n }}\n >\n <h2 id={titleId} className=\"text-fg text-base font-semibold\">\n {t('commands.page.goTo')}\n </h2>\n <label className=\"text-fg-secondary mt-3 flex items-center gap-2 text-sm\">\n {before}\n <input\n type=\"text\"\n inputMode=\"numeric\"\n aria-label={t('demo.goToPage')}\n value={draft}\n onChange={(event) => setDraft(event.target.value.replace(/[^0-9]/g, ''))}\n onFocus={(event) => event.currentTarget.select()}\n // Room for the longest number, and one more digit's worth for the caret.\n style={{ width: `${String(total).length + 2}ch` }}\n className=\"border-border bg-surface text-fg focus:border-accent focus:ring-accent rounded-md border px-1.5 py-1 text-center tabular-nums outline-none focus:ring-1\"\n />\n {after}\n </label>\n <div className=\"mt-4 flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"border-border text-fg hover:bg-hover rounded-md border px-3 py-1.5 text-sm\"\n >\n {t('demo.cancel')}\n </button>\n <button\n type=\"submit\"\n className=\"bg-accent text-on-accent hover:bg-accent-hover rounded-md px-3 py-1.5 text-sm\"\n >\n {t('goToPage.go')}\n </button>\n </div>\n </form>\n </Dialog>\n );\n}\n","/**\n * How a panel opens and how wide it is. By default a panel docks beside the\n * pages in a wide viewer, opens over their edge at medium widths and is a\n * sheet on a phone; its layout `present` changes that, for every size or for\n * some. A docked panel's inner edge, the one beside the pages, drags between\n * the narrowest and the widest its layout `width` allows; it is on the panel's\n * right at the start in a left-to-right language and on its left at the end,\n * the other way round in a right-to-left one.\n */\nimport {\n panelPresentationsOf,\n panelWidthFieldsOf,\n type PanelPresentation,\n type PanelPresentationBySize,\n type PanelWidth,\n type ViewerSize,\n} from '@embedpdf/core-ui';\n\n/** The side of the pages a panel opens on. */\nexport type PanelSide = 'start' | 'end';\n\n/** The writing direction the panel's sides follow. */\nexport type PanelDirection = 'ltr' | 'rtl';\n\n/** A panel's widths in px, every one given: where it starts, the narrowest and the widest. */\nexport interface PanelWidths {\n readonly initial: number;\n readonly min: number;\n readonly max: number;\n}\n\n/** The widths of a panel whose layout doesn't give them. */\nexport const DEFAULT_PANEL_WIDTHS: PanelWidths = { initial: 288, min: 200, max: 640 };\n\n/** How far one arrow key moves a docked panel's edge; with Shift, four times as far. */\nexport const PANEL_WIDTH_STEP_PX = 16;\n\n/** How much of the pages an overlay leaves uncovered, so a click on them can close it. */\nexport const OVERLAY_CLEARANCE_PX = 48;\n\n/** How a panel opens at each size when its layout doesn't say. */\nexport const DEFAULT_PRESENTATIONS: Readonly<Record<ViewerSize, PanelPresentation>> = {\n compact: 'sheet',\n medium: 'overlay',\n expanded: 'dock',\n};\n\n/** How a panel opens at `size`: what its layout `present` says for that size, else the default. */\nexport function presentationOf(\n size: ViewerSize,\n present?: PanelPresentation | PanelPresentationBySize,\n): PanelPresentation {\n return (\n (present === undefined ? undefined : panelPresentationsOf(present)[size]) ??\n DEFAULT_PRESENTATIONS[size]\n );\n}\n\n/** A panel's widths from its layout `width`, the rest the defaults. A `min` over the `max` is the `max`. */\nexport function panelWidthsOf(width?: number | PanelWidth): PanelWidths {\n const given = width === undefined ? {} : panelWidthFieldsOf(width);\n const max = given.max ?? DEFAULT_PANEL_WIDTHS.max;\n const min = Math.min(given.min ?? DEFAULT_PANEL_WIDTHS.min, max);\n return { initial: given.initial ?? DEFAULT_PANEL_WIDTHS.initial, min, max };\n}\n\n/** The widest a docked panel gets in a viewer `viewerWidth` px wide: never more than half of it. */\nexport function maxPanelWidthOf(viewerWidth: number, widths: PanelWidths): number {\n return Math.max(widths.min, Math.min(widths.max, Math.floor(viewerWidth / 2)));\n}\n\n/** `width` kept between the narrowest and the widest the panel gets in this viewer. */\nexport function clampPanelWidth(width: number, viewerWidth: number, widths: PanelWidths): number {\n const widest = maxPanelWidthOf(viewerWidth, widths);\n return Math.round(Math.min(widest, Math.max(widths.min, width)));\n}\n\n/** An overlay's width: its panel's, leaving some of the pages uncovered. */\nexport function overlayWidthOf(width: number, viewerWidth: number): number {\n return Math.round(Math.max(0, Math.min(width, viewerWidth - OVERLAY_CLEARANCE_PX)));\n}\n\n/** A docked panel's inner edge: the side it's on, and how far it can go in this viewer. */\nexport interface PanelEdge {\n readonly side: PanelSide;\n readonly dir: PanelDirection;\n /** The viewer's width, in px. */\n readonly viewerWidth: number;\n readonly widths: PanelWidths;\n}\n\n/** `1` when moving the inner edge to the right widens the panel, `-1` when it narrows it. */\nexport function widenDirectionOf(side: PanelSide, dir: PanelDirection): 1 | -1 {\n return (side === 'start') === (dir === 'ltr') ? 1 : -1;\n}\n\n/** The width after the inner edge moves `dx` px (rightward positive) from where it was at `width`. */\nexport function widthAfterDrag(width: number, dx: number, edge: PanelEdge): number {\n return clampPanelWidth(\n width + dx * widenDirectionOf(edge.side, edge.dir),\n edge.viewerWidth,\n edge.widths,\n );\n}\n\n/**\n * The width after `key` on the inner edge, or null for a key that doesn't move it: the arrows\n * move the edge left or right, Home makes the panel its narrowest and End its widest.\n */\nexport function widthAfterKey(\n width: number,\n key: string,\n shiftKey: boolean,\n edge: PanelEdge,\n): number | null {\n const step = PANEL_WIDTH_STEP_PX * (shiftKey ? 4 : 1);\n if (key === 'ArrowRight') return widthAfterDrag(width, step, edge);\n if (key === 'ArrowLeft') return widthAfterDrag(width, -step, edge);\n if (key === 'Home') return clampPanelWidth(edge.widths.min, edge.viewerWidth, edge.widths);\n if (key === 'End') return maxPanelWidthOf(edge.viewerWidth, edge.widths);\n return null;\n}\n","/**\n * The frame every panel opens in: its header (the title, or what the panel\n * puts there, and a close button) and one of three ways to open, the panel's\n * `present` for the viewer's size, or else the default for it\n * (`panel-layout.ts`):\n *\n * - dock: beside the pages, which make room for it. Its inner edge drags it\n * wider or narrower, by pointer or with the arrow keys on the edge, within\n * the panel's `width` limits, unless it isn't `resizable`. The viewer\n * remembers that width per panel while it runs, and tells the app\n * (`onPanelResize`). It is part of the page: Tab reaches it in order, and\n * it never takes focus.\n * - overlay: over the edge of the pages, which stay where they are and dim.\n * A click on them closes it; the bars around the pages keep working.\n * - sheet: up from the bottom of the viewer, over everything (`sheet.tsx`).\n *\n * An overlay or a sheet takes focus when it opens, closes on Escape and gives\n * focus back to the button that opened it. A sheet keeps Tab inside it; from\n * an overlay Tab moves on to the rest of the viewer. A panel that holds a\n * list closes from either when one of its items is picked\n * ({@link useCloseOnPick}). The frame is named after its title for assistive\n * technology: a region when docked, a dialog otherwise (modal as a sheet).\n */\nimport type { PanelPresentation, PanelPresentationBySize, PanelWidth } from '@embedpdf/core-ui';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useKernel } from '@embedpdf/react/runtime';\nimport {\n useId,\n useLayoutEffect,\n useReducer,\n useRef,\n type PointerEvent as ReactPointerEvent,\n type ReactNode,\n} from 'react';\n\nimport { useLayoutEnv, usePanelResize } from '../config-context';\nimport { Icon } from './icons';\nimport {\n clampPanelWidth,\n maxPanelWidthOf,\n overlayWidthOf,\n panelWidthsOf,\n presentationOf,\n widthAfterDrag,\n widthAfterKey,\n type PanelEdge as PanelEdgeOf,\n type PanelSide,\n type PanelWidths,\n} from './panel-layout';\nimport { CloseOnPickProvider, SCRIM_CLASS, Sheet, useCloseOnPick } from './sheet';\nimport { holdFocus } from './viewer-layer';\n\nexport { useCloseOnPick };\n\nexport interface PanelFrameProps {\n /** The panel's id: the frame's `data-epdf-panel`, and what its dragged width is kept under. */\n readonly id: string;\n readonly side: PanelSide;\n /** How it opens, at every size or per size. Default: dock, overlay, or sheet on a phone. */\n readonly present?: PanelPresentation | PanelPresentationBySize;\n /** Its width in px, or where it starts and how far it drags. Default 288, from 200 to 640. */\n readonly width?: number | PanelWidth;\n /** Whether its edge drags. Default true. */\n readonly resizable?: boolean;\n /** Its title: in its header, and the name assistive technology gives the frame. */\n readonly title: string;\n readonly onClose: () => void;\n /** Drawn in the header in place of the title: the switcher between the panels on its side. */\n readonly header?: ReactNode;\n /** It holds a list: in a sheet or an overlay, picking an item closes it ({@link useCloseOnPick}). */\n readonly list?: boolean;\n readonly children: ReactNode;\n}\n\nexport function PanelFrame(props: PanelFrameProps) {\n const { size } = useLayoutEnv();\n const present = presentationOf(size, props.present);\n if (present === 'sheet') return <SheetPanel {...props} />;\n if (present === 'overlay') return <OverlayPanel {...props} />;\n return <DockedPanel {...props} />;\n}\n\n// ── the header ───────────────────────────────────────────────────────────────\n\nfunction PanelHeader({\n title,\n header,\n onClose,\n}: {\n title: string;\n header: ReactNode;\n onClose: () => void;\n}) {\n const t = useT();\n return (\n <div\n part=\"panel-header\"\n data-epdf-panel-header=\"\"\n className=\"border-border-subtle flex min-h-11 shrink-0 items-center gap-2 border-b px-3 py-1.5\"\n >\n <div className=\"flex min-w-0 flex-1 items-center\">\n {header ?? <h2 className=\"text-fg truncate text-sm font-semibold\">{title}</h2>}\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n aria-label={t('panel.close')}\n title={t('panel.close')}\n className=\"text-fg-muted hover:bg-hover grid h-7 w-7 shrink-0 place-items-center rounded-md\"\n >\n <Icon name=\"x\" size={16} />\n </button>\n </div>\n );\n}\n\n// ── widths ───────────────────────────────────────────────────────────────────\n\n/** The width each panel was dragged to, per viewer (its kernel), for as long as the viewer runs. */\nconst draggedWidths = new WeakMap<object, Map<string, number>>();\n\nfunction draggedWidthsOf(kernel: object): Map<string, number> {\n let widths = draggedWidths.get(kernel);\n if (!widths) {\n widths = new Map();\n draggedWidths.set(kernel, widths);\n }\n return widths;\n}\n\n/**\n * The panel's width: the one it was dragged to in this viewer, else where its layout says it\n * starts. Returns it unclamped, and the setter that remembers a new one.\n */\nfunction usePanelWidth(id: string, widths: PanelWidths): [number, (width: number) => void] {\n const dragged = draggedWidthsOf(useKernel());\n const [, rerender] = useReducer((count: number) => count + 1, 0);\n const width = dragged.get(id) ?? widths.initial;\n const setWidth = (next: number) => {\n if (dragged.get(id) === next) return;\n dragged.set(id, next);\n rerender();\n };\n return [width, setWidth];\n}\n\n// ── dock ─────────────────────────────────────────────────────────────────────\n\nfunction DockedPanel({\n id,\n side,\n width,\n resizable = true,\n title,\n onClose,\n header,\n children,\n}: PanelFrameProps) {\n const env = useLayoutEnv();\n const regionId = useId();\n const widths = panelWidthsOf(width);\n const [wanted, setWidth] = usePanelWidth(id, widths);\n const shown = clampPanelWidth(wanted, env.width, widths);\n const resized = usePanelResize();\n const edge: PanelEdgeOf = { side, dir: env.dir, viewerWidth: env.width, widths };\n // Above the dimmed pages of an overlay on the other side (z-30): only the pages dim.\n return (\n <section\n id={regionId}\n role=\"region\"\n aria-label={title}\n part=\"panel\"\n data-epdf-panel={id}\n data-present=\"dock\"\n className={`bg-surface border-border-subtle relative z-[35] flex shrink-0 flex-col ${\n side === 'start' ? 'border-e' : 'border-s'\n }`}\n style={{ width: shown }}\n >\n <PanelHeader title={title} header={header} onClose={onClose} />\n <div className=\"flex min-h-0 flex-1 flex-col\">{children}</div>\n {resizable && (\n <PanelEdge\n regionId={regionId}\n edge={edge}\n title={title}\n width={shown}\n onWidth={setWidth}\n onResized={(next) => resized({ id, width: next })}\n />\n )}\n </section>\n );\n}\n\n/**\n * A docked panel's inner edge: a separator that drags the panel wider or narrower, and takes\n * the arrow keys (Home and End for the narrowest and the widest) when it has focus. `onWidth`\n * follows every move; `onResized` hears the width the user gave it, once a drag ends and on\n * each key that changes it.\n */\nfunction PanelEdge({\n regionId,\n edge,\n title,\n width,\n onWidth,\n onResized,\n}: {\n regionId: string;\n edge: PanelEdgeOf;\n title: string;\n width: number;\n onWidth: (width: number) => void;\n onResized: (width: number) => void;\n}) {\n const t = useT();\n const drag = useRef<{\n pointerId: number;\n startX: number;\n startWidth: number;\n width: number;\n } | null>(null);\n const onPointerDown = (event: ReactPointerEvent<HTMLDivElement>) => {\n if (event.pointerType === 'mouse' && event.button !== 0) return;\n // No text selection starts under the drag.\n event.preventDefault();\n event.currentTarget.setPointerCapture(event.pointerId);\n drag.current = {\n pointerId: event.pointerId,\n startX: event.clientX,\n startWidth: width,\n width,\n };\n };\n const onPointerMove = (event: ReactPointerEvent<HTMLDivElement>) => {\n const current = drag.current;\n if (!current || current.pointerId !== event.pointerId) return;\n current.width = widthAfterDrag(current.startWidth, event.clientX - current.startX, edge);\n onWidth(current.width);\n };\n const onPointerUp = (event: ReactPointerEvent<HTMLDivElement>) => {\n const current = drag.current;\n if (current?.pointerId !== event.pointerId) return;\n drag.current = null;\n if (current.width !== current.startWidth) onResized(current.width);\n };\n return (\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-controls={regionId}\n aria-label={t('panel.resize', { params: { title } })}\n aria-valuenow={width}\n aria-valuemin={edge.widths.min}\n aria-valuemax={maxPanelWidthOf(edge.viewerWidth, edge.widths)}\n tabIndex={0}\n data-epdf-panel-edge=\"\"\n className={`focus-visible:bg-accent/40 hover:bg-accent/20 absolute inset-y-0 z-10 w-2 cursor-col-resize touch-none outline-none transition-colors ${\n edge.side === 'start' ? '-end-1' : '-start-1'\n }`}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerUp}\n onKeyDown={(event) => {\n const next = widthAfterKey(width, event.key, event.shiftKey, edge);\n if (next === null) return;\n event.preventDefault();\n if (next === width) return;\n onWidth(next);\n onResized(next);\n }}\n />\n );\n}\n\n// ── overlay ──────────────────────────────────────────────────────────────────\n\n/** Where an overlay comes in from: its own side, in either direction. */\nconst OVERLAY_ENTRY: Record<PanelSide, string> = {\n start: 'start-0 border-e starting:-translate-x-full rtl:starting:translate-x-full',\n end: 'end-0 border-s starting:translate-x-full rtl:starting:-translate-x-full',\n};\n\nfunction OverlayPanel({\n id,\n side,\n width,\n title,\n onClose,\n header,\n list,\n children,\n}: PanelFrameProps) {\n const env = useLayoutEnv();\n const widths = panelWidthsOf(width);\n const [wanted] = usePanelWidth(id, widths);\n const panel = useRef<HTMLElement>(null);\n const close = useRef(onClose);\n close.current = onClose;\n useLayoutEffect(() => {\n const element = panel.current;\n if (!element) return;\n // It takes focus, and Escape closes it; Tab moves on to the bars, which keep working.\n const held = holdFocus(element, { onEscape: () => close.current(), trap: false });\n return () => held.release();\n // The overlay opens once; it closes by unmounting.\n }, []);\n return (\n <>\n {/* over the pages only, under the overlay: a click on them closes it */}\n <div\n aria-hidden=\"true\"\n data-epdf-scrim=\"\"\n className={`absolute inset-0 z-30 ${SCRIM_CLASS}`}\n onClick={() => close.current()}\n />\n <section\n ref={panel}\n role=\"dialog\"\n aria-label={title}\n part=\"panel\"\n data-epdf-panel={id}\n data-present=\"overlay\"\n className={`bg-surface border-border-subtle absolute inset-y-0 z-40 flex flex-col shadow-xl transition-[translate] duration-200 ease-out motion-reduce:transition-none ${OVERLAY_ENTRY[side]}`}\n style={{ width: overlayWidthOf(clampPanelWidth(wanted, env.width, widths), env.width) }}\n >\n <PanelHeader title={title} header={header} onClose={onClose} />\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <CloseOnPickProvider value={list ? () => close.current() : () => {}}>\n {children}\n </CloseOnPickProvider>\n </div>\n </section>\n </>\n );\n}\n\n// ── sheet ────────────────────────────────────────────────────────────────────\n\nfunction SheetPanel({ id, title, onClose, header, list, children }: PanelFrameProps) {\n return (\n <Sheet\n label={title}\n onClose={onClose}\n size=\"panel\"\n list={list}\n part=\"panel\"\n data={{ 'epdf-panel': id, present: 'sheet' }}\n header={<PanelHeader title={title} header={header} onClose={onClose} />}\n >\n {children}\n </Sheet>\n );\n}\n","/**\n * A panel's title in its header, when other panels share its side: a button\n * that opens a menu of them, the open one checked, each by its `panel:<id>`\n * command. Picking another opens it in this one's place, since the panels on\n * one side take turns; picking the open one leaves it open.\n */\nimport { panelCommandOf } from '@embedpdf/core-ui';\nimport { useCommand } from '@embedpdf/react/commands';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useState } from 'react';\n\nimport { Icon } from './icons';\nimport { MenuItem, MenuPopover } from './menu';\n\nexport function PanelSwitcher({\n id,\n title,\n panels,\n}: {\n /** The open panel. */\n id: string;\n /** Its title. */\n title: string;\n /** The panels on its side that show, this one among them, in layout order. */\n panels: readonly string[];\n}) {\n const t = useT();\n const [open, setOpen] = useState(false);\n return (\n <div className=\"relative flex min-w-0\">\n <button\n type=\"button\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n title={t('panels.switch')}\n data-epdf-panel-switcher=\"\"\n onClick={() => setOpen((previous) => !previous)}\n className=\"text-fg hover:bg-hover -ms-1.5 flex min-w-0 items-center gap-1 rounded-md px-1.5 py-1 text-sm font-semibold\"\n >\n <span className=\"truncate\">{title}</span>\n <Icon name=\"chevronDown\" size={16} className=\"text-fg-muted shrink-0\" />\n </button>\n {open && (\n <MenuPopover onClose={() => setOpen(false)}>\n <div className=\"min-w-48 p-1\">\n {panels.map((panel) => (\n <PanelRow\n key={panel}\n panel={panel}\n current={panel === id}\n onPicked={() => setOpen(false)}\n />\n ))}\n </div>\n </MenuPopover>\n )}\n </div>\n );\n}\n\n/** One panel in the menu: its command's icon and label, checked when it's the open one. */\nfunction PanelRow({\n panel,\n current,\n onPicked,\n}: {\n panel: string;\n current: boolean;\n onPicked: () => void;\n}) {\n const command = useCommand(panelCommandOf(panel));\n if (!command.visible) return null;\n return (\n <MenuItem\n command={{ ...command, active: current }}\n choice=\"radio\"\n onSelect={() => {\n // Its command toggles it: the open one would close.\n if (!current) void command.run();\n onPicked();\n }}\n />\n );\n}\n","/**\n * The layout's panels, drawn: on each side of the pages, the panel open on\n * that side, in the frame that opens it (docked beside the pages, over them,\n * or as a sheet: panel-frame.tsx). The panels on one side take turns: opening\n * one closes the other, however it was opened. The header switches between\n * the panels on the side; the body is the slot `panel:<id>`, which holds the\n * built-in content, so content of your own replaces it, and a panel of your\n * own with nothing in its slot is empty.\n *\n * Which panels are open is each document's own (the shell plugin keeps them\n * per document), so switching documents brings back that document's panels.\n * A panel whose button no longer shows (its feature turned off, or not\n * allowed) closes.\n */\nimport { panelCommandOf } from '@embedpdf/core-ui';\nimport { useCommands } from '@embedpdf/react/commands';\nimport { useT } from '@embedpdf/react/i18n';\nimport { RenderLayer } from '@embedpdf/react/render';\nimport { useDocumentId, useKernelValue, useOptionalCapability } from '@embedpdf/react/runtime';\nimport { ShellToken, useShellEvent } from '@embedpdf/react/shell';\nimport { Stage, useStage, useStageState } from '@embedpdf/react/stage';\nimport { useEffect, useLayoutEffect, useMemo, type ReactNode } from 'react';\n\nimport { panelsOnSide } from '../config/panels';\nimport { ThumbsStageToken } from '../config/stage';\nimport { useResolvedLayout } from '../config-context';\nimport { lazyComponent } from './lazy';\nimport { PanelFrame, useCloseOnPick } from './panel-frame';\nimport type { PanelSide } from './panel-layout';\nimport { PanelSwitcher } from './panel-switcher';\n\n// Each feature's panel loads the first time it opens.\nconst SearchPanel = lazyComponent(() => import('./search-panel').then((ui) => ui.SearchPanel));\nconst CommentsPanel = lazyComponent(() =>\n import('./comments-panel').then((ui) => ui.CommentsPanel),\n);\nconst MeasurementSection = lazyComponent(() =>\n import('./measurement').then((ui) => ui.MeasurementSection),\n);\nconst AnnotationStylePanel = lazyComponent(() =>\n import('./annotation-style').then((ui) => ui.AnnotationStylePanel),\n);\nconst StampsPanel = lazyComponent(() => import('./stamps-panel').then((ui) => ui.StampsPanel));\nconst SignaturesPanel = lazyComponent(() =>\n import('./signatures-panel').then((ui) => ui.SignaturesPanel),\n);\nconst RedactionPanel = lazyComponent(() =>\n import('./redaction-panel').then((ui) => ui.RedactionPanel),\n);\nconst FormDesignPanel = lazyComponent(() =>\n import('./form-design-panel').then((ui) => ui.FormDesignPanel),\n);\n\n/** What a built-in panel draws in its slot. */\ninterface BuiltInContent {\n readonly draw: (documentId: string | null) => ReactNode;\n /** It holds a list: in a sheet or an overlay, picking one of its items closes the panel. */\n readonly list?: boolean;\n}\n\nconst BUILT_IN_CONTENT: ReadonlyMap<string, BuiltInContent> = new Map<string, BuiltInContent>([\n ['thumbnails', { draw: () => <ThumbnailList />, list: true }],\n // These read the document as they mount, so each document gets its own.\n ['search', { draw: (documentId) => <SearchPanel key={documentId ?? 'none'} />, list: true }],\n ['comments', { draw: (documentId) => <CommentsPanel key={documentId ?? 'none'} /> }],\n ['measurement', { draw: (documentId) => <MeasurementSection key={documentId ?? 'none'} /> }],\n ['style', { draw: () => <AnnotationStylePanel /> }],\n ['stamps', { draw: () => <StampsPanel /> }],\n ['signatures', { draw: () => <SignaturesPanel /> }],\n ['redaction', { draw: () => <RedactionPanel /> }],\n // The form's fields and their settings: each document's own.\n ['form-design', { draw: (documentId) => <FormDesignPanel key={documentId ?? 'none'} /> }],\n]);\n\nconst NONE: readonly string[] = [];\n\nconst sameStrings = (left: readonly string[], right: readonly string[]): boolean =>\n left.length === right.length && left.every((value, i) => value === right[i]);\n\n/** One side's panels: which show (their buttons do), which are turned off, which are open. */\ninterface SideState {\n readonly shown: readonly string[];\n readonly off: readonly string[];\n readonly open: readonly string[];\n}\n\nconst sameSide = (left: SideState, right: SideState): boolean =>\n sameStrings(left.shown, right.shown) &&\n sameStrings(left.off, right.off) &&\n sameStrings(left.open, right.open);\n\n/** The panel open on one side of the pages, if any, of the layout's panels on that side. */\nexport function SidePanel({ side }: { side: PanelSide }) {\n const { data } = useResolvedLayout();\n const commands = useCommands();\n const shell = useOptionalCapability(ShellToken);\n const documentId = useDocumentId();\n const ids = useMemo(() => panelsOnSide(data, side), [data, side]);\n const { shown, off, open } = useKernelValue((): SideState => {\n const visibleOf = (id: string) =>\n commands.resolveCommand(panelCommandOf(id), documentId ?? undefined)?.visible;\n return {\n shown: ids.filter((id) => visibleOf(id) === true),\n // A panel whose command isn't registered is neither: it isn't drawn, and it isn't closed.\n off: ids.filter((id) => visibleOf(id) === false),\n open: shell ? ids.filter((id) => shell.isOpen(id)) : NONE,\n };\n }, sameSide);\n\n // Opening a panel closes the one open on its side, however it was opened.\n useShellEvent(\n (current) => current.onSurfaceOpened,\n (event) => {\n if (!shell || !ids.includes(event.id)) return;\n for (const id of ids) if (id !== event.id && shell.isOpen(id)) shell.close(id);\n },\n );\n\n // The first open panel that shows is drawn. A turned-off one closes, and so does any other\n // open on this side (opened while another document showed).\n const current = open.find((id) => shown.includes(id)) ?? null;\n useLayoutEffect(() => {\n if (!shell) return;\n for (const id of open) {\n if (id !== current && (current !== null || off.includes(id))) shell.close(id);\n }\n }, [shell, open, off, current]);\n\n if (current === null) return null;\n return <OpenPanel key={current} id={current} side={side} siblings={shown} />;\n}\n\n/** One open panel in its frame: its title or the switcher in the header, its slot as the body. */\nfunction OpenPanel({\n id,\n side,\n siblings,\n}: {\n id: string;\n side: PanelSide;\n siblings: readonly string[];\n}) {\n const t = useT();\n const panel = useResolvedLayout().data.panels?.[id];\n const shell = useOptionalCapability(ShellToken);\n const documentId = useDocumentId();\n if (!panel) return null;\n const title = panel.title ?? (panel.titleKey !== undefined ? t(panel.titleKey) : id);\n const content = BUILT_IN_CONTENT.get(id);\n return (\n <PanelFrame\n id={id}\n side={side}\n present={panel.present}\n width={panel.width}\n resizable={panel.resizable}\n title={title}\n header={\n siblings.length > 1 ? <PanelSwitcher id={id} title={title} panels={siblings} /> : undefined\n }\n list={content?.list}\n onClose={() => shell?.close(id)}\n >\n <slot name={`panel:${id}`}>{content?.draw(documentId)}</slot>\n </PanelFrame>\n );\n}\n\n// The thumbnail rail: the same document through the thumbnail Stage lens (a\n// fixed-zoom grid that wraps into as many columns as the panel's width fits —\n// see the viewer's `thumbnails` plugin). Click a thumb to navigate the main\n// lens; the rail follows the main view. Read-only — no page edits\n// (rotate/move/delete), just the page bitmap and its number.\nfunction ThumbnailList() {\n const t = useT();\n const main = useStage(); // the main lens\n const thumbs = useStage(ThumbsStageToken); // the sidebar lens\n const currentPage = useStageState((state) => state.currentPageIndex);\n // A sheet or an overlay closes once a page is picked, so you see where it took you.\n const closeOnPick = useCloseOnPick();\n // Follow the main view: when its current page changes, make that thumb visible —\n // minimal movement, zero when it's already on screen.\n useEffect(() => thumbs.reveal(currentPage), [currentPage, thumbs]);\n return (\n <Stage\n token={ThumbsStageToken}\n className=\"flex-1\"\n style={{ position: 'relative' }}\n pageChrome={(page) => (\n <>\n {/* BOX-SPACE chrome: the click target + selection border hug the page\n box; the number sits in the reserved bottom band. Neither rotates. */}\n <button\n type=\"button\"\n onClick={() => {\n main.goToPage(page.pageIndex);\n closeOnPick();\n }}\n title={t('thumbnails.page', { params: { page: page.pageIndex + 1 } })}\n // The current page in the accent with a tint around it, the others in a light line.\n className={`box-border cursor-pointer rounded ${\n page.pageIndex === currentPage\n ? 'border-accent ring-accent-light border-2 ring-2'\n : 'border-border-subtle border'\n }`}\n style={{\n position: 'absolute',\n top: page.frame.top,\n left: page.frame.left,\n right: page.frame.right,\n bottom: page.frame.bottom,\n }}\n />\n <div\n style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n height: page.frame.bottom,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 11,\n color: 'var(--epdf-text-muted)',\n pointerEvents: 'none',\n }}\n >\n {page.pageIndex + 1}\n </div>\n </>\n )}\n >\n {/* page-space content: the bitmap, which rotates with the page */}\n {() => <RenderLayer />}\n </Stage>\n );\n}\n","/**\n * The viewer's own components in your page (`<epdf-button>`, `<epdf-menu>`):\n * elements the delivery defines, drawn here by the viewer into each one's\n * own shadow root, with the toolbar's button and the viewer's menu. So they\n * look and behave like the viewer's own: a command's icon, tooltip and\n * state; a menu that opens away from its bar, flips, and takes the menu keys.\n *\n * The delivery keeps the list of them per viewer ({@link PlacedComponents}),\n * one entry per element, replaced when its attributes or rows change; the\n * shell draws what's on it ({@link PlacedComponentsHost}). Each element is\n * drawn in the viewer's own tree, so it reads the viewer's commands, icons\n * and menus, and the edge of the bar it sits in (`slotted-edges.ts`).\n */\nimport { useCommand } from '@embedpdf/react/commands';\nimport type { ResolvedCommand } from '@embedpdf/react/commands';\nimport { Fragment, useLayoutEffect, useState, useSyncExternalStore } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { BarEdgeProvider } from './bar-edge';\nimport { Icon } from './icons';\nimport { MenuItem, MenuPopover } from './menu';\nimport { useSlottedEdges } from './slotted-edges';\nimport { CommandButton, buttonClass, buttonPart } from './toolbar';\n\n// ── the list ─────────────────────────────────────────────────────────────────\n\ninterface PlacedComponentBase {\n /** The element in the page. */\n readonly host: HTMLElement;\n /** Its shadow root, where the viewer draws it. */\n readonly root: ShadowRoot;\n /** An icon by name, the viewer's or yours. */\n readonly icon: string | null;\n /** Its name, for its tooltip and screen readers. */\n readonly label: string | null;\n}\n\n/** `<epdf-button>`: a command's button, or one with an icon and a label of your own. */\nexport interface PlacedButton extends PlacedComponentBase {\n readonly kind: 'button';\n readonly command: string | null;\n}\n\n/** `<epdf-menu>`: a button that opens a menu of its rows. */\nexport interface PlacedMenu extends PlacedComponentBase {\n readonly kind: 'menu';\n readonly items: readonly PlacedMenuItem[];\n}\n\n/** `<epdf-menu-item>`: a row, a command's or one with an icon and text of your own. */\nexport interface PlacedMenuItem {\n readonly command: string | null;\n readonly icon: string | null;\n /** Its text; a command's label when it has none. */\n readonly label: string;\n /** Says the row was picked (the element's `select` event). */\n readonly select: () => void;\n}\n\nexport type PlacedComponent = PlacedButton | PlacedMenu;\n\n/** The viewer's own components placed in one viewer. */\nexport interface PlacedComponents {\n /** Every one placed, in the order they were placed. */\n list(): readonly PlacedComponent[];\n /** Calls `listener` whenever the list changes. */\n subscribe(listener: () => void): () => void;\n /** Places a component, or replaces the one with the same `host`. */\n place(component: PlacedComponent): void;\n /** Takes the component of `host` away. */\n remove(host: HTMLElement): void;\n}\n\nexport function createPlacedComponents(): PlacedComponents {\n let placed: readonly PlacedComponent[] = [];\n const listeners = new Set<() => void>();\n const change = (next: readonly PlacedComponent[]) => {\n placed = next;\n for (const listener of [...listeners]) listener();\n };\n return {\n list: () => placed,\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n place(component) {\n const index = placed.findIndex((each) => each.host === component.host);\n change(\n index < 0\n ? [...placed, component]\n : placed.map((each, i) => (i === index ? component : each)),\n );\n },\n remove(host) {\n if (placed.some((each) => each.host === host)) {\n change(placed.filter((each) => each.host !== host));\n }\n },\n };\n}\n\n// ── what the page's element says about its command ───────────────────────────\n\n/** The hosts the viewer hid, because their command isn't visible: only those it shows again. */\nconst hiddenByViewer = new WeakSet<HTMLElement>();\n\n/**\n * Say on the element in the page what its command allows: hidden while the command isn't\n * visible (or there's no such command), and unavailable to the toolbar's keys while it can't run.\n */\nfunction useHostState(host: HTMLElement, command: ResolvedCommand): void {\n const { visible, enabled } = command;\n useLayoutEffect(() => {\n if (!visible && !host.hidden) {\n host.hidden = true;\n hiddenByViewer.add(host);\n } else if (visible && hiddenByViewer.has(host)) {\n host.hidden = false;\n hiddenByViewer.delete(host);\n }\n if (enabled) host.removeAttribute('aria-disabled');\n else host.setAttribute('aria-disabled', 'true');\n }, [host, visible, enabled]);\n}\n\n// ── the button ───────────────────────────────────────────────────────────────\n\n/** An icon, else the label as text: what a button of your own shows. */\nfunction Face({ icon, label }: { icon: string | null; label: string | null }) {\n return icon ? (\n <Icon name={icon} size={20} />\n ) : (\n <span className=\"whitespace-nowrap px-1 text-sm\">{label}</span>\n );\n}\n\nfunction CommandOf({ host, commandId }: { host: HTMLElement; commandId: string }) {\n const command = useCommand(commandId);\n useHostState(host, command);\n if (!command.visible) return null;\n return <CommandButton cmd={command} variant=\"icon\" run={() => void command.run()} />;\n}\n\n/** A button of your own: its click is the element's, for your handler. */\nfunction OwnButton({ icon, label }: { icon: string | null; label: string | null }) {\n return (\n <button\n type=\"button\"\n aria-label={label ?? undefined}\n title={label ?? undefined}\n part=\"toolbar-button\"\n className={buttonClass(false)}\n >\n <Face icon={icon} label={label} />\n </button>\n );\n}\n\nfunction ButtonView({ button }: { button: PlacedButton }) {\n return button.command ? (\n <CommandOf host={button.host} commandId={button.command} />\n ) : (\n <OwnButton icon={button.icon} label={button.label} />\n );\n}\n\n// ── the menu ─────────────────────────────────────────────────────────────────\n\n/** A row of your own, in the shape a menu row reads. */\nconst ownRowOf = (item: PlacedMenuItem): ResolvedCommand => ({\n id: '',\n label: item.label,\n icon: item.icon ?? undefined,\n shortcuts: [],\n enabled: true,\n active: false,\n visible: true,\n categories: [],\n});\n\n/** A command's row: its icon, label, state and shortcut, unless the item gives its own. */\nfunction CommandRow({\n item,\n commandId,\n onPicked,\n}: {\n item: PlacedMenuItem;\n commandId: string;\n onPicked: () => void;\n}) {\n const command = useCommand(commandId);\n if (!command.visible) return null;\n const shown = {\n ...command,\n label: item.label || command.label,\n icon: item.icon ?? command.icon,\n };\n return (\n <MenuItem\n command={shown}\n choice={command.active ? 'checkbox' : 'none'}\n onSelect={() => {\n void command.run();\n item.select();\n onPicked();\n }}\n />\n );\n}\n\nfunction MenuView({ menu }: { menu: PlacedMenu }) {\n const [open, setOpen] = useState(false);\n const close = () => setOpen(false);\n return (\n <span className=\"relative inline-flex\">\n <button\n type=\"button\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-label={menu.label ?? undefined}\n title={menu.label ?? undefined}\n part={buttonPart(open)}\n className={buttonClass(open)}\n onClick={() => setOpen((previous) => !previous)}\n >\n <Face icon={menu.icon} label={menu.label} />\n </button>\n {open && (\n <MenuPopover onClose={close}>\n <div className=\"min-w-52 p-1\">\n {menu.items.map((item, index) =>\n item.command ? (\n <CommandRow key={index} item={item} commandId={item.command} onPicked={close} />\n ) : (\n <MenuItem\n key={index}\n command={ownRowOf(item)}\n choice=\"none\"\n onSelect={() => {\n item.select();\n close();\n }}\n />\n ),\n )}\n </div>\n </MenuPopover>\n )}\n </span>\n );\n}\n\n// ── drawing them ─────────────────────────────────────────────────────────────\n\n/** A key per element in the page, for as long as it lives. */\nconst keys = new WeakMap<HTMLElement, number>();\nlet nextKey = 0;\nconst keyOf = (host: HTMLElement): number => {\n let key = keys.get(host);\n if (key === undefined) {\n key = nextKey++;\n keys.set(host, key);\n }\n return key;\n};\n\n/** Draws every component placed in this viewer, each in its own shadow root. */\nexport function PlacedComponentsHost({ components }: { components: PlacedComponents }) {\n const placed = useSyncExternalStore(components.subscribe, components.list, components.list);\n const edges = useSlottedEdges();\n useSyncExternalStore(edges.subscribe, edges.version, edges.version);\n return (\n <>\n {placed.map((component) => (\n <Fragment key={keyOf(component.host)}>\n {createPortal(\n <BarEdgeProvider value={edges.edgeOf(component.host)}>\n {component.kind === 'button' ? (\n <ButtonView button={component} />\n ) : (\n <MenuView menu={component} />\n )}\n </BarEdgeProvider>,\n component.root,\n )}\n </Fragment>\n ))}\n </>\n );\n}\n","/**\n * Why a key did nothing, said in a short, polite notice that goes away by\n * itself: a shortcut whose command is turned off or not allowed, or Ctrl/Cmd+C\n * on text the user may not copy. Screen readers hear it through a live region,\n * which stays mounted so every new message is announced.\n */\nimport { useCallback, useEffect, useState, type ReactNode } from 'react';\nimport type { CommandId, CommandRefusal } from '@embedpdf/react/commands';\nimport { useT } from '@embedpdf/react/i18n';\n\n/** How long a notice stays. */\nconst NOTICE_MS = 2500;\n\nexport interface RefusalNotice {\n /** The notice, mounted once inside a positioned box of the viewer. */\n readonly element: ReactNode;\n /** For `useCommandShortcuts({ onRefused })`. */\n readonly onShortcutRefused: (commandId: CommandId, refusal: CommandRefusal) => void;\n /** For `<SelectionClipboard onRefused>`. */\n readonly onCopyRefused: () => void;\n}\n\nexport function useRefusalNotice(): RefusalNotice {\n const t = useT();\n // `count` tells two equal messages apart: the second one is announced and timed again.\n const [notice, setNotice] = useState<{ message: string; count: number } | null>(null);\n const show = useCallback(\n (message: string) => setNotice((previous) => ({ message, count: (previous?.count ?? 0) + 1 })),\n [],\n );\n\n useEffect(() => {\n if (!notice) return;\n const timer = setTimeout(() => setNotice(null), NOTICE_MS);\n return () => clearTimeout(timer);\n }, [notice]);\n\n const onShortcutRefused = useCallback(\n (_commandId: CommandId, refusal: CommandRefusal) => show(refusal.message),\n [show],\n );\n const onCopyRefused = useCallback(\n () => show(t('commands.notAllowed.doc-text-copy', { fallback: \"Copying isn't allowed\" })),\n [show, t],\n );\n\n return {\n onShortcutRefused,\n onCopyRefused,\n element: (\n <div\n role=\"status\"\n aria-live=\"polite\"\n data-epdf-refusal-notice=\"\"\n className=\"pointer-events-none absolute inset-x-0 bottom-16 z-30 flex justify-center\"\n >\n {notice && (\n <div\n key={notice.count}\n className=\"border-border-subtle bg-elevated/95 text-fg rounded-full border px-4 py-1.5 text-sm shadow-lg backdrop-blur\"\n >\n {notice.message}\n </div>\n )}\n </div>\n ),\n };\n}\n","/**\n * The angle a selection is being turned to, beside the pointer:\n *\n * <AnnotationRotationBadge> solves where (the pointer, upright on any\n * page rotation: it floats over the page)\n * this file is the look\n *\n * Mounted in the Stage `overlay` slot; it shows only while a rotation runs.\n */\nimport { AnnotationRotationBadge } from '@embedpdf/react/annotation';\n\nexport function RotationBadge() {\n return (\n <AnnotationRotationBadge>\n {({ angle }) => (\n <div className=\"pointer-events-none whitespace-nowrap rounded bg-black/80 px-1.5 py-0.5 font-mono text-xs text-white\">\n {angle}°\n </div>\n )}\n </AnnotationRotationBadge>\n );\n}\n","/**\n * The text-selection floating strip:\n *\n * config/chrome.ts `strips.selection` declares what may appear\n * each command's visible/enabled decides which items show\n * <SelectionMenu> solves where (settles on pointer-up,\n * camera transform, pointer isolation):\n * above the selection, below it without\n * room above\n *\n * `useStripView` is the live intersection: with copy denied (no\n * doc.text.copy) every command drops out and this renders nothing — no\n * empty bubble. Mounted in the Stage `overlay` slot.\n */\nimport { SelectionMenu } from '@embedpdf/react/selection';\nimport { useStripView } from '@embedpdf/react/toolbar';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useLayoutEnv, useStripSchema } from '../config-context';\nimport { StripBar } from './strip-bar';\n\n/** Px between the selection and its bar. */\nconst GAP_PX = 12;\n\n/**\n * On a touch screen the bar also keeps clear of the selection's handles: the 12 px head each one\n * has beyond the first or last line, and the 14 px around it a finger grabs (the handles'\n * geometry in `@embedpdf/plugin-selection`).\n */\nconst TOUCH_GAP_PX = GAP_PX + 12 + 14;\n\nexport function SelectionStrip() {\n const t = useT();\n const { touch } = useLayoutEnv();\n const view = useStripView(useStripSchema('selection'));\n if (!view) return null;\n return (\n <SelectionMenu placement=\"top\" gap={touch ? TOUCH_GAP_PX : GAP_PX}>\n <StripBar view={view} label={t('commands.selection.strip')} />\n </SelectionMenu>\n );\n}\n","/**\n * The keyboard shortcuts sheet, which `?` opens (`help:shortcuts`): every command with a\n * shortcut, in groups, in the viewer's language, with its keys as this platform shows them. A\n * command that's turned off or not allowed is left out, since its keys do nothing here; so is\n * one that isn't there now, except a command on what's selected, which shows whether or not\n * anything is.\n */\nimport { formatShortcut } from '@embedpdf/core-ui';\nimport { useCommands, type CommandsCapability } from '@embedpdf/react/commands';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useDocumentId, useKernelValue } from '@embedpdf/react/runtime';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { isMacPlatform } from '@embedpdf/web';\nimport { useId } from 'react';\n\nimport { SHORTCUTS_DIALOG } from '../config/commands';\nimport { Dialog } from './dialog';\nimport { Icon } from './icons';\n\n/** One row: a command's label and its keys. */\nexport interface ShortcutRow {\n readonly commandId: string;\n readonly label: string;\n readonly shortcuts: readonly string[];\n}\n\n/** A group of rows under its title's translation key. */\nexport interface ShortcutGroup {\n readonly titleKey: string;\n readonly rows: readonly ShortcutRow[];\n}\n\n/** The groups, in order, by the area a command's id starts with (`zoom` for `zoom:in`). */\nconst GROUPS: readonly { readonly titleKey: string; readonly areas: readonly string[] }[] = [\n { titleKey: 'shortcuts.document', areas: ['document'] },\n {\n titleKey: 'shortcuts.viewing',\n areas: ['page', 'zoom', 'view', 'search', 'panel', 'menu', 'mode', 'help'],\n },\n {\n titleKey: 'shortcuts.editing',\n areas: ['history', 'tool', 'selection', 'annotation', 'redaction', 'measurement'],\n },\n];\n/** Every other command, yours among them. */\nconst OTHER_GROUP = 'shortcuts.other';\n\n/** The areas whose commands act on what's selected: there whether or not anything is now. */\nconst ON_A_SELECTION = new Set(['selection', 'annotation']);\n\nconst areaOf = (commandId: string): string => commandId.split(':')[0] ?? commandId;\n\n/** The sheet's groups for a document: the ones with a row, in order. */\nexport function shortcutGroupsOf(\n commands: Pick<CommandsCapability, 'listShortcuts' | 'getRefusal' | 'resolveCommand'>,\n documentId: string | undefined,\n): ShortcutGroup[] {\n const ids = [...new Set(commands.listShortcuts().map((entry) => entry.commandId))];\n const rows = ids.flatMap((commandId): ShortcutRow[] => {\n if (commands.getRefusal(commandId, documentId)) return [];\n const command = commands.resolveCommand(commandId, documentId);\n if (!command || command.shortcuts.length === 0) return [];\n if (!command.visible && !ON_A_SELECTION.has(areaOf(commandId))) return [];\n return [{ commandId, label: command.label, shortcuts: command.shortcuts }];\n });\n const groupOf = (row: ShortcutRow): string =>\n GROUPS.find((group) => group.areas.includes(areaOf(row.commandId)))?.titleKey ?? OTHER_GROUP;\n return [...GROUPS.map((group) => group.titleKey), OTHER_GROUP]\n .map((titleKey) => ({ titleKey, rows: rows.filter((row) => groupOf(row) === titleKey) }))\n .filter((group) => group.rows.length > 0);\n}\n\nconst sameGroups = (left: readonly ShortcutGroup[], right: readonly ShortcutGroup[]): boolean =>\n JSON.stringify(left) === JSON.stringify(right);\n\nexport function ShortcutsSheet() {\n const surface = useSurface(SHORTCUTS_DIALOG);\n return surface.isOpen ? <ShortcutsList onClose={surface.close} /> : null;\n}\n\nfunction ShortcutsList({ onClose }: { onClose: () => void }) {\n const t = useT();\n const titleId = useId();\n const commands = useCommands();\n const documentId = useDocumentId() ?? undefined;\n const groups = useKernelValue(() => shortcutGroupsOf(commands, documentId), sameGroups);\n const isMac = isMacPlatform();\n return (\n <Dialog\n labelledBy={titleId}\n onClose={onClose}\n className=\"border-border bg-surface w-96 rounded-lg border p-4 shadow-xl\"\n >\n <div data-epdf-shortcuts=\"\">\n <div className=\"flex items-center justify-between gap-4\">\n <h2 id={titleId} className=\"text-fg text-base font-semibold\">\n {t('commands.shortcuts')}\n </h2>\n <button\n type=\"button\"\n onClick={onClose}\n aria-label={t('panel.close')}\n title={t('panel.close')}\n className=\"text-fg-muted hover:bg-hover hover:text-fg grid h-7 w-7 place-items-center rounded-md\"\n >\n <Icon name=\"x\" size={16} />\n </button>\n </div>\n {groups.map((group) => (\n <section key={group.titleKey} className=\"mt-4\">\n <h3 className=\"text-fg-muted text-xs font-semibold\">{t(group.titleKey)}</h3>\n <dl className=\"mt-1\">\n {group.rows.map((row) => (\n <div\n key={row.commandId}\n data-epdf-shortcut=\"\"\n className=\"flex items-center justify-between gap-4 py-1 text-sm\"\n >\n <dt className=\"text-fg min-w-0 truncate\">{row.label}</dt>\n <dd className=\"flex shrink-0 gap-1\">\n {row.shortcuts.map((shortcut) => (\n <kbd\n key={shortcut}\n className=\"border-border-subtle bg-surface-alt text-fg-secondary rounded border px-1.5 py-0.5 font-sans text-xs\"\n >\n {formatShortcut(shortcut, { isMac })}\n </kbd>\n ))}\n </dd>\n </div>\n ))}\n </dl>\n </section>\n ))}\n </div>\n </Dialog>\n );\n}\n","/**\n * The signature plugin's UI intents → shell surfaces. The plugin owns the\n * act and says what happened; the chrome decides what opens:\n *\n * target (a \"sign here\" click) → the signatures panel\n * ask (mode 'ask' met a field) → the sign dialog (modal)\n * inspect (a signed field clicked) → the validation popover\n *\n * Mounted once per document view; renders nothing.\n */\nimport { useSignatureEvent } from '@embedpdf/react/signature';\nimport { useShell } from '@embedpdf/react/shell';\n\nexport function SignatureBridge() {\n const shell = useShell();\n useSignatureEvent(\n (signature) => signature.onTargetChanged,\n (event) => {\n if (event.field) shell.open('signatures');\n },\n );\n useSignatureEvent(\n (signature) => signature.onSignRequested,\n (event) =>\n shell.open('signature-sign', {\n exclusive: 'modal',\n props: { field: event.field, mark: event.mark },\n }),\n );\n useSignatureEvent(\n (signature) => signature.onInspectionRequested,\n (event) => shell.open('signature-inspector', { props: { field: event.field } }),\n );\n // The notice lives in the signatures panel; make sure it is seen.\n useSignatureEvent(\n (signature) => signature.onInvalidationPredicted,\n () => shell.open('signatures'),\n );\n return null;\n}\n","/**\n * Changes that would be lost. A document has unsaved changes once it changed since it opened or\n * since its last download (`hasUnsavedChanges`, always false on an engine that stores every\n * change as it's made). While one has, leaving the page asks first ({@link LeaveWarning}), and\n * closing its tab asks first ({@link CloseUnsavedDialog}). What the app's code closes, or a new\n * `src` replaces, is the app's call and closes without asking.\n */\nimport { useT } from '@embedpdf/react/i18n';\nimport { useDocumentsState } from '@embedpdf/react/runtime';\nimport { useEffect, useId } from 'react';\n\nimport { Dialog } from './dialog';\n\n/** While any document has unsaved changes, the browser asks before the page is left. */\nexport function LeaveWarning() {\n const unsaved = useDocumentsState((state) =>\n state.documents.some((document) => document.hasUnsavedChanges),\n );\n useEffect(() => {\n if (!unsaved) return;\n const warn = (event: BeforeUnloadEvent) => {\n event.preventDefault();\n // What browsers before Chrome 119 ask for; the text itself is the browser's own.\n event.returnValue = '';\n };\n window.addEventListener('beforeunload', warn);\n return () => window.removeEventListener('beforeunload', warn);\n }, [unsaved]);\n return null;\n}\n\n/** Asks before a tab with unsaved changes closes: Cancel keeps it, the other button closes it. */\nexport function CloseUnsavedDialog({\n name,\n onCancel,\n onClose,\n}: {\n /** The name of the document whose tab would close, as its tab shows it. */\n name: string;\n onCancel: () => void;\n /** Close it, and lose its changes. */\n onClose: () => void;\n}) {\n const t = useT();\n const titleId = useId();\n return (\n <Dialog\n labelledBy={titleId}\n onClose={onCancel}\n className=\"border-border bg-surface w-96 rounded-lg border p-4 shadow-xl\"\n >\n <h2 id={titleId} className=\"text-fg text-base font-semibold\">\n {t('closeUnsaved.title')}\n </h2>\n <p className=\"text-fg-muted mt-2 text-sm\">{t('closeUnsaved.body', { params: { name } })}</p>\n <div className=\"mt-4 flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"border-border text-fg hover:bg-hover rounded-md border px-3 py-1.5 text-sm\"\n >\n {t('closeUnsaved.cancel')}\n </button>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700\"\n >\n {t('closeUnsaved.close')}\n </button>\n </div>\n </Dialog>\n );\n}\n","/**\n * The document tab bar: rounded-top tabs on the surface-alt strip, the active\n * tab merging into the toolbar surface below, and close-× on the active tab.\n * Opening another file is the `document:open` command (config/open-files.ts),\n * behind the document menu's Open row and a PDF dropped on the pages. A tab\n * with unsaved changes asks before it closes; a failed one says why on its\n * warning sign.\n *\n * The kernel's document registry is the tab model: `useDocumentsState()` for\n * the tabs, `useDocuments()` for close/setActive; there is no separate\n * document manager.\n */\nimport { useT } from '@embedpdf/react/i18n';\nimport { useDocuments, useDocumentsState, type DocumentInfo } from '@embedpdf/react/runtime';\nimport { useState } from 'react';\n\nimport { errorReasonKeyOf } from './document-boot';\nimport { Icon } from './icons';\nimport { CloseUnsavedDialog } from './unsaved-changes';\n\nexport type TabBarVisibility = 'always' | 'multiple' | 'never';\n\nexport function TabBar({\n visibility,\n}: {\n /** When the tabs show: the layout's `tabs` (`tabsOf`). */\n visibility: TabBarVisibility;\n}) {\n const { setActive, close } = useDocuments();\n const { documents, activeId } = useDocumentsState();\n const t = useT();\n // The tab that asks before it closes: its document's id, and the name it shows.\n const [closing, setClosing] = useState<{ id: string; name: string } | null>(null);\n\n const shouldShow = visibility === 'always' || (visibility === 'multiple' && documents.length > 1);\n if (!shouldShow) return null;\n\n const closeTab = (document: DocumentInfo, name: string) => {\n if (document.hasUnsavedChanges) setClosing({ id: document.id, name });\n else void close(document.id);\n };\n\n return (\n <div className=\"bg-surface-alt flex items-end pr-2 pt-2\">\n <div className=\"flex flex-1 items-end overflow-x-auto pl-4\">\n {documents.map((document) => {\n const isActive = activeId === document.id;\n const name =\n document.name ?? t('tabs.untitled', { params: { id: document.id.slice(0, 8) } });\n return (\n <div\n key={document.id}\n onClick={() => setActive(document.id)}\n role=\"tab\"\n part={isActive ? 'tab tab-active' : 'tab'}\n tabIndex={0}\n aria-selected={isActive}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n setActive(document.id);\n }\n }}\n className={`group relative flex min-w-[120px] max-w-[240px] cursor-pointer items-center gap-2 rounded-t-lg px-4 py-2 text-sm font-medium transition-all ${\n isActive\n ? 'bg-surface text-fg z-10'\n : 'bg-surface-alt text-fg-secondary hover:bg-hover hover:text-fg'\n }`}\n >\n {/* lifecycle glyphs — the tab exists from the moment open()\n was called; these show what its document is doing */}\n {document.status === 'loading' && (\n <span\n className=\"border-border-subtle border-t-accent h-3 w-3 flex-shrink-0 animate-spin rounded-full border\"\n aria-label={t('tabs.loading')}\n />\n )}\n {document.status === 'locked' && (\n <Icon name=\"lock\" size={13} className=\"text-fg-muted flex-shrink-0\" />\n )}\n {document.status === 'error' && (\n <span\n className=\"flex flex-shrink-0\"\n role=\"img\"\n aria-label={t(errorReasonKeyOf(document.error))}\n title={t(errorReasonKeyOf(document.error))}\n >\n <Icon name=\"alertTriangle\" size={13} className=\"text-red-500\" />\n </span>\n )}\n <span className=\"min-w-0 flex-1 truncate\">{name}</span>\n\n {/* close — on the active tab, and never the last document\n (an empty workspace is designable, but not this demo's goal) */}\n {isActive && documents.length > 1 && (\n <button\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n closeTab(document, name);\n }}\n aria-label={t('tabs.close', { params: { name } })}\n className=\"hover:bg-hover flex-shrink-0 cursor-pointer rounded-full p-1 opacity-100 transition-all\"\n >\n <Icon name=\"x\" size={14} />\n </button>\n )}\n </div>\n );\n })}\n </div>\n {closing && (\n <CloseUnsavedDialog\n name={closing.name}\n onCancel={() => setClosing(null)}\n onClose={() => {\n setClosing(null);\n void close(closing.id);\n }}\n />\n )}\n </div>\n );\n}\n","/**\n * This viewer's armed-tool cursor: the toolbar's own icon riding the pointer\n * as a real CSS cursor (OS-composited — zero lag, unlike any DOM follower).\n * The library owns arbitration (unmapped hover claims win, page gaps fall\n * back to the arrow — see `useToolCursor`); this module only decides what the\n * cursor looks like. It reuses the same icon set and the same accent\n * derivation as the toolbar buttons (TOOL_ICONS is recorded by the command\n * definitions), so the cursor is pixel-identical to the button the user just\n * pressed — recolor the tool and both follow. A tool without a command icon\n * keeps its declared keyword cursor.\n *\n * One table decides the shape ({@link glyphs}): cursor keywords are the\n * affordances — a tool declares its base ('crosshair' to draw, 'copy' to\n * place), the selection handler claims 'text' over text — and each mapped\n * keyword is redrawn as its glyph + the tool's icon. Keywords the table omits\n * stay native: a markup tool's 'default' base is the bare arrow (identity\n * appears exactly where the action is possible — over text), a foreign 'move'\n * over an annotation drops the icon. A new tool gets the right cursor from\n * what it declares; nothing tool-specific lives here.\n *\n * A tool whose ghost follows the pointer (a note's or attachment's icon, an\n * armed stamp's image) gets no skin: the ghost already shows what a click\n * places, so its cursor stays the plain keyword it declares.\n *\n * The image: a white-haloed glyph at the hotspot (readable on any page color)\n * with the icon at its top right — 40px, under the 128px cursor ceiling;\n * Chromium may briefly show the default arrow when a >32px cursor would\n * overlap browser UI (anti-spoofing), which is fine mid-viewport.\n */\nimport { useInteractionState, useToolCursor } from '@embedpdf/react/interaction';\nimport { useAnnotation, useAnnotationDefaults } from '@embedpdf/react/annotation';\nimport { TOOL_ICONS } from '../config/commands';\nimport { useCustomIcons } from '../config-context';\nimport { iconPathsOf } from './icons';\nimport type { IconAccent, IconDef, PathSpec } from './icons';\n\nconst SIZE = 40;\nconst HOTSPOT = { x: 8, y: 28 };\nconst INK = '#1a1a1a';\nconst HALO = '#ffffff';\n/** The drag-and-drop \"will place a copy\" green (Chrome's DnD badge). */\nconst PLACE_GREEN = '#34a853';\n\n/** The icon's paths as SVG markup — the string twin of `<Icon>`'s render loop\n * (same fill/stroke slot rules), with a white halo pass underneath so the\n * glyph stays readable over page content. */\nfunction iconGlyph(\n name: string,\n accent: IconAccent | undefined,\n custom: Readonly<Record<string, IconDef>>,\n): string | null {\n const paths = iconPathsOf(name, custom);\n if (!paths) return null;\n const halo: string[] = [];\n const draw: string[] = [];\n for (const path of paths) {\n const spec: Exclude<PathSpec, string> =\n typeof path === 'string' ? { d: path, fill: undefined, stroke: undefined } : path;\n // Slot rules, mirrored from <Icon>: a fill slot paints from the accent\n // (nothing without one), a stroke slot falls back to the ink, and a\n // fill-only path never gets an outline.\n const fill = spec.fill === true ? INK : spec.fill ? accent?.[spec.fill] : undefined;\n const stroke = spec.stroke ? (accent?.[spec.stroke] ?? INK) : spec.fill ? 'none' : INK;\n halo.push(`<path d=\"${spec.d}\" fill=\"none\" stroke=\"${HALO}\" stroke-width=\"3.5\"/>`);\n const decoration = [\n ['stroke-width', spec.strokeWidth],\n ['stroke-dasharray', spec.strokeDasharray],\n ['stroke-opacity', spec.strokeOpacity],\n ['fill-opacity', spec.fillOpacity],\n ]\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => `${key}=\"${value}\"`)\n .join(' ');\n draw.push(`<path d=\"${spec.d}\" fill=\"${fill ?? 'none'}\" stroke=\"${stroke}\" ${decoration}/>`);\n }\n return halo.join('') + draw.join('');\n}\n\n/** The action glyph drawn at the hotspot: what a click does here. */\ntype Glyph = 'crosshair' | 'ibeam' | 'plus';\n\nconst haloed = (x1: number, y1: number, x2: number, y2: number): string =>\n `<line x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"${HALO}\" stroke-width=\"3\"/>` +\n `<line x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"${INK}\" stroke-width=\"1.25\"/>`;\n\nfunction actionGlyph(glyph: Glyph): string {\n const { x, y } = HOTSPOT;\n if (glyph === 'crosshair') {\n return haloed(x, y - 6, x, y + 6) + haloed(x - 6, y, x + 6, y);\n }\n if (glyph === 'ibeam') {\n return (\n haloed(x, y - 6.5, x, y + 6.5) +\n haloed(x - 2.5, y - 6.5, x + 2.5, y - 6.5) +\n haloed(x - 2.5, y + 6.5, x + 2.5, y + 6.5)\n );\n }\n // plus: the DnD copy affordance — green disc, white plus.\n return (\n `<circle cx=\"${x}\" cy=\"${y}\" r=\"7.5\" fill=\"${PLACE_GREEN}\" stroke=\"${HALO}\" stroke-width=\"1.5\"/>` +\n `<line x1=\"${x}\" y1=\"${y - 3.5}\" x2=\"${x}\" y2=\"${y + 3.5}\" stroke=\"${HALO}\" stroke-width=\"2\"/>` +\n `<line x1=\"${x - 3.5}\" y1=\"${y}\" x2=\"${x + 3.5}\" y2=\"${y}\" stroke=\"${HALO}\" stroke-width=\"2\"/>`\n );\n}\n\nfunction cursorSvg(\n glyph: Glyph,\n icon: string,\n accent: IconAccent | undefined,\n custom: Readonly<Record<string, IconDef>>,\n): string {\n const iconMarkup = iconGlyph(icon, accent, custom);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${SIZE}\" height=\"${SIZE}\" ` +\n `viewBox=\"0 0 ${SIZE} ${SIZE}\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\">` +\n actionGlyph(glyph) +\n (iconMarkup\n ? `<g transform=\"translate(17 3) scale(${(20 / 24).toFixed(4)})\" stroke-width=\"2\">${iconMarkup}</g>`\n : '') +\n `</svg>`\n );\n}\n\n/** keyword → glyph: how each affordance is drawn when a tool icon rides\n * along. Draw tools declare 'crosshair', place tools (stamp/signature/image)\n * declare 'copy', and the selection handler claims 'text' over text — which\n * keywords ever show is decided by those declarations and claims, never\n * here. 'default' is deliberately absent: the bare arrow means \"no action\n * here\", so it never carries an icon. */\nconst GLYPHS: Record<string, Glyph> = {\n crosshair: 'crosshair',\n text: 'ibeam',\n copy: 'plus',\n};\n\n/** Mount once (renders nothing): keeps the armed tool's cursor skin in sync\n * with its toolbar icon + live defaults. */\nexport function ArmedToolCursor() {\n // Without a document there is no active tool; the pointer has no cursor image.\n const activeToolId = useInteractionState((state) => state.activeToolId) ?? 'pointer';\n // Live accent: a `tools.updateDefaults` recolor re-renders us and rebuilds the cursor.\n const defaults = useAnnotationDefaults(activeToolId);\n // Your icon of the tool's name, when you gave one: the button shows it too.\n const custom = useCustomIcons();\n // What a click places follows the pointer: the cursor carries no icon.\n const ghostFollows = Boolean(useAnnotation().tools.get(activeToolId)?.ghost);\n const entry = ghostFollows ? undefined : TOOL_ICONS[activeToolId];\n const colorOf = (key: string) => (defaults[key] as string | null | undefined) ?? undefined;\n const accent = entry?.accent\n ? {\n primary: colorOf(entry.accent.primary),\n secondary: entry.accent.secondary ? colorOf(entry.accent.secondary) : undefined,\n }\n : undefined;\n useToolCursor(\n entry\n ? {\n toolId: activeToolId,\n cursors: Object.fromEntries(\n Object.entries(GLYPHS).map(([keyword, glyph]) => [\n keyword,\n { svg: cursorSvg(glyph, entry.icon, accent, custom), hotspot: HOTSPOT },\n ]),\n ),\n }\n : null,\n );\n return null;\n}\n","/**\n * The viewer shell — the layout's bars around the pages, driven entirely by\n * the commands + measured-toolbar system.\n *\n * ── header socket (empty unless a child fills it) ──────────────────────\n * ── document tabs (or the `tabs` region) ───────────────────────────────\n * ── the top edge's bars, outside in (main, its mode bar) ───────────────\n * start │ start │ │ end │ end\n * bars │ panel │ pages, the floating bars │ panel │ bars\n * │ │ over them (with no document: │ │\n * │ │ the `empty` region) │ │\n * ── the bottom edge's bars, outside in from the bottom ─────────────────\n * ── footer socket (empty unless a child fills it) ──────────────────────\n *\n * The top and bottom bars run the full width; the start and end bars stand\n * between them at the viewer's edges, and a docked panel sits inside them,\n * beside the pages (places.tsx draws the bars). The workspace/document split\n * is structural: header + toolbars are workspace-scoped and render at t≈0\n * (translated, measured) while the wasm engine still boots; everything\n * document-scoped sits inside <DocumentGate>, whose fallback is the\n * empty-workspace state, shown under a live toolbar rather than replacing the\n * whole app. The floating bars float over the pages, so they come with them.\n *\n * Which mode bar shows is not stored anywhere: it's a projection of\n * plugin-shell's exclusive 'mode' surface, read null-safely so the bar simply\n * doesn't exist without a document.\n */\nimport { tabsOf } from '@embedpdf/core-ui';\nimport { useActionsUiAdapter } from '@embedpdf/react/actions';\nimport { AnnotationLayer, useFilePickerProvider } from '@embedpdf/react/annotation';\nimport { useCommandShortcuts } from '@embedpdf/react/commands';\nimport { FormLayer } from '@embedpdf/react/form';\nimport { useT } from '@embedpdf/react/i18n';\nimport { LinkLayer } from '@embedpdf/react/link';\nimport { useMeasurementState } from '@embedpdf/react/measurement';\nimport { RenderLayer } from '@embedpdf/react/render';\nimport { DocumentGate, useDocument, useDocumentId } from '@embedpdf/react/runtime';\nimport { SearchLayer } from '@embedpdf/react/search';\nimport { SelectionClipboard, SelectionHandles, SelectionLayer } from '@embedpdf/react/selection';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { Scrollbar, Stage } from '@embedpdf/react/stage';\nimport { useRef, type ReactNode } from 'react';\n\nimport { useLayoutEnv, useResolvedLayout } from './config-context';\nimport { LayoutRoot } from './layout-root';\nimport { EdgeBars, FloatingBars } from './places';\nimport { AnnotationFontsProvider } from './ui/annotation-fonts';\nimport { AnnotationStrip } from './ui/annotation-strip';\nimport { DocumentError, PasswordPrompt } from './ui/document-boot';\nimport { DropToOpen } from './ui/drop-to-open';\nimport { GoToPageDialog } from './ui/go-to-page';\nimport { FeaturePrefetch, lazyComponent } from './ui/lazy';\nimport { SidePanel } from './ui/panels';\nimport { PlacedComponentsHost, type PlacedComponents } from './ui/placed-components';\nimport { useRefusalNotice } from './ui/refusal-notice';\nimport { RotationBadge } from './ui/rotation-badge';\nimport { SelectionStrip } from './ui/selection-strip';\nimport { ShortcutsSheet } from './ui/shortcuts-sheet';\nimport { SignatureBridge } from './ui/signature-bridge';\nimport { StampLibraryStore } from './ui/stamp-store';\nimport { TabBar } from './ui/tab-bar';\nimport { ArmedToolCursor } from './ui/tool-cursor';\nimport { LeaveWarning } from './ui/unsaved-changes';\n\n// The dialogs and the inspector of a feature: each loads the first time it opens.\nconst useRedactConfirmOpen = () => useSurface('redact-confirm').isOpen;\nconst useCalibrating = () => useMeasurementState((state) => state.calibrationRequest !== null);\nconst useSignDialogOpen = () => useSurface('signature-sign').isOpen;\nconst useSignatureMakerOpen = () => useSurface('signature-maker').isOpen;\nconst useSignatureInspectorOpen = () => useSurface('signature-inspector').isOpen;\nconst RedactConfirmModal = lazyComponent(\n () => import('./ui/redact-confirm').then((ui) => ui.RedactConfirmModal),\n { shownWhile: useRedactConfirmOpen },\n);\nconst CalibrationDialog = lazyComponent(\n () => import('./ui/measurement').then((ui) => ui.CalibrationDialog),\n { shownWhile: useCalibrating },\n);\nconst SignDialog = lazyComponent(() => import('./ui/sign-dialog').then((ui) => ui.SignDialog), {\n shownWhile: useSignDialogOpen,\n});\nconst SignatureMakerModal = lazyComponent(\n () => import('./ui/signature-maker').then((ui) => ui.SignatureMakerModal),\n { shownWhile: useSignatureMakerOpen },\n);\nconst SignatureInspector = lazyComponent(\n () => import('./ui/signature-inspector').then((ui) => ui.SignatureInspector),\n { shownWhile: useSignatureInspectorOpen },\n);\n\n/** The document tabs, as the layout says: always, while more than one document is open, or never. */\nfunction DocumentTabs() {\n const visibility = tabsOf(useResolvedLayout().data);\n if (visibility === 'never') return null;\n return (\n <slot name=\"tabs\">\n <TabBar visibility={visibility} />\n </slot>\n );\n}\n\n/** The empty-workspace state: shown while the initial documents (and the\n * engine behind them) are still loading — or if the user closes every tab. */\nfunction OpeningDocuments() {\n const t = useT();\n return (\n <div className=\"grid h-full w-full place-items-center\">\n <div className=\"text-fg-muted flex flex-col items-center gap-3\">\n <div className=\"border-border-subtle border-t-accent h-8 w-8 animate-spin rounded-full border-2\" />\n <div className=\"text-sm\">{t('demo.opening')}</div>\n </div>\n </div>\n );\n}\n\n/**\n * The document area's lifecycle switch. With no document open it shows the\n * `empty` region, or nothing. A `locked` tab shows its password prompt, an\n * `error` tab its error pane — per tab (keyed by document), so several can\n * coexist and tab switching stays free. Everything else is the ready-gated\n * Stage; the gate's fallback covers `loading`.\n */\nfunction DocumentArea({ children }: { children: ReactNode }) {\n const docId = useDocumentId();\n const status = useDocument((document) => document.status);\n if (docId === null) {\n return (\n <div className=\"min-w-0 flex-1 overflow-auto\">\n <slot name=\"empty\" />\n </div>\n );\n }\n if (status === 'locked') return <PasswordPrompt key={docId} />;\n if (status === 'error') return <DocumentError key={docId} />;\n return <DocumentGate fallback={<OpeningDocuments />}>{children}</DocumentGate>;\n}\n\n/**\n * What's drawn over the pages: it follows the viewer's direction, while the pages under it keep\n * their own left-to-right layout (the Stage is `direction: ltr`).\n */\nfunction OverPages({ children }: { children: ReactNode }) {\n const { dir } = useLayoutEnv();\n return (\n <div dir={dir} className=\"contents\">\n {children}\n </div>\n );\n}\n\nexport function Shell({ components }: { components?: PlacedComponents }) {\n // A shortcut or Copy that's refused says why in a notice.\n const refusals = useRefusalNotice();\n // The keys and copies reach this viewer only while focus is inside it (its own components,\n // and yours slotted into it), so two viewers on a page never both take one, and the page\n // keeps its own.\n const root = useRef<HTMLDivElement>(null);\n useCommandShortcuts({ target: root, onRefused: refusals.onShortcutRefused });\n // Click-then-pick tools (stamp, file attachment) → click a page → file dialog\n // opens → the file lands where you clicked. One line: the default provider is\n // the built-in file picker honouring each tool's `accept` filter (swap it for\n // a custom picker, or pass null to disable). The plugin stays DOM-free.\n useFilePickerProvider();\n // The one UI port for the action engine and every script-produced effect:\n // sanitized URI opens, Named `Print`, script alerts (boot/lifecycle nags\n // suppressed by default), and script page navigation.\n useActionsUiAdapter();\n\n // Regions render as named <slot> sockets with the built-ins as fallback —\n // light-DOM children of <embedpdf-viewer> replace them; in plain light DOM a\n // slot just displays its fallback (UA display:contents), so this package's\n // direct React consumers see no difference. A region nobody fills shows\n // nothing, or the viewer's own (the tabs). The bars are measured and fit\n // with zero config, and sit outside the gate: they render before any\n // document. The root measures the viewer for the layout (layout-root.tsx).\n return (\n <AnnotationFontsProvider>\n <LayoutRoot rootRef={root} className=\"bg-app text-fg flex h-full flex-col outline-none\">\n {/* the viewer's own components in the page (<epdf-button>, <epdf-menu>), each drawn\n in its own shadow root */}\n {components && <PlacedComponentsHost components={components} />}\n {/* the user's stamp + signature libraries: restored once, persisted for\n the workspace's lifetime (workspace-scoped, like the stamp plugin) */}\n <StampLibraryStore />\n {/* leaving the page asks first while a document has unsaved changes */}\n <LeaveWarning />\n {/* The header socket. The chrome ships NO header of its own — branding,\n locale pickers and theme switches are the embedder's chrome, not the\n viewer's — so this renders nothing until a child fills the slot. */}\n <slot name=\"header\" />\n\n {/* the document tab bar — the kernel's document registry IS the tab model */}\n <DocumentTabs />\n\n <EdgeBars edge=\"top\" />\n\n <div className=\"relative flex min-h-0 flex-1\">\n {refusals.element}\n <EdgeBars edge=\"start\" />\n {/* a PDF dropped here opens as a new tab, as Open in the document menu does */}\n <DropToOpen className=\"relative flex min-w-0 flex-1\">\n <DocumentArea>\n <SidePanel side=\"start\" />\n <div className=\"relative min-w-0 flex-1\">\n {/* the armed tool's cursor: its toolbar icon as a real CSS cursor\n (zero-lag; the hub hides it over annotations/fields/gaps) */}\n <ArmedToolCursor />\n {/* ctrl/cmd+C and native Edit→Copy for the text selection, while focus is\n inside the viewer — prefetches on commit so the copy event answers\n synchronously. Renders nothing; mount once per document view. */}\n <SelectionClipboard target={root} onRefused={refusals.onCopyRefused} />\n <Stage\n overlay={\n <OverPages>\n {/* the floating bars: over the pages, under the bars over a selection */}\n <FloatingBars />\n <AnnotationStrip />\n {/* the angle a selection is being turned to, by the pointer */}\n <RotationBadge />\n <SelectionStrip />\n {/* a signed field's facts, anchored at its widget */}\n <SignatureInspector />\n {/* touch: draggable start/end selection handles (long-press\n selects a word; the lollipops grow it from there) */}\n <SelectionHandles />\n {/* headless scrollbars: geometry/behavior from the stage's\n scroller contract; the look is index.css (data-attrs) */}\n <Scrollbar axis=\"y\" />\n <Scrollbar axis=\"x\" />\n </OverPages>\n }\n className=\"h-full w-full\"\n style={{ background: 'var(--epdf-canvas)', direction: 'ltr' }}\n >\n {() => (\n <>\n {/* Base + deep-zoom tiles in one layer. Tiles engage by\n demand arithmetic when the view wants more pixels than\n the base budget supplies — the thumbnail rail's demand\n never does, so it mounts the same layer for free. */}\n <RenderLayer />\n <SelectionLayer />\n <SearchLayer />\n {/* Clickable links (nav plane): anchors under the default\n pointer/pan tools; stands down whenever an authoring\n tool is active (the annotation plane owns links then).\n Below the AnnotationLayer so an editing free-text box\n wins pointer hits; the annotation layer's own surface\n is pointer-events: none, so clicks fall through to the\n anchors everywhere else. */}\n <LinkLayer />\n <AnnotationLayer />\n {/* The fields' pictures, and fill controls over them\n while the active tool fills forms; the render layer\n leaves the fields to it, as it leaves the annotations\n to the annotation layer. */}\n <FormLayer />\n </>\n )}\n </Stage>\n </div>\n <SidePanel side=\"end\" />\n <RedactConfirmModal />\n <CalibrationDialog />\n <GoToPageDialog />\n <ShortcutsSheet />\n {/* signatures: plugin intents → surfaces; the dialogs they open */}\n <SignatureBridge />\n {/* once a document shows: the features' panels and dialogs, fetched while idle */}\n <FeaturePrefetch />\n <SignDialog />\n <SignatureMakerModal />\n </DocumentArea>\n </DropToOpen>\n <EdgeBars edge=\"end\" />\n </div>\n\n <EdgeBars edge=\"bottom\" />\n\n {/* The footer socket: below everything, empty until a child fills it. */}\n <slot name=\"footer\" />\n </LayoutRoot>\n </AnnotationFontsProvider>\n );\n}\n","/**\n * The full viewer, as a component — and the customization contract. The\n * `ViewerCustomization` surface here is the exact shape that later powers\n * `EmbedPDF.init({...})` and every framework wrapper, because all of it is\n * plain data (see README.md).\n *\n * Two semantics, on purpose:\n * - registries (commands / icons / strings) merge additively over the\n * defaults by id; a colliding id overrides.\n * - structure (layout) is an owned value: the default, edits of it (a\n * function of the default and the viewer's env), or the host's own\n * layout — never merged.\n *\n * The engine stays a prop — choosing local-wasm vs cloud is the host's\n * decision, and each delivery wires its own. The chrome — toolbars,\n * translations, theme — renders at t≈0; only the pages wait on the engine.\n * Customization is mount-time, except `theme`, `locale`, `disable` and\n * `readOnly`, which follow their props (see {@link FollowProps}); changing any\n * other prop on a mounted viewer does not rebuild the workspace.\n */\n// One import line per feature: each subpath carries the\n// plugin and its UI; delete a line and the feature leaves the bundle.\nimport { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from 'react';\nimport { Viewer as HeadlessViewer, useKernel } from '@embedpdf/react/runtime';\nimport type {\n CapabilityToken,\n Engine,\n EngineFactory,\n Identity,\n InitialDocument,\n} from '@embedpdf/react/runtime';\nimport { stagePlugin } from '@embedpdf/react/stage';\nimport { renderPlugin } from '@embedpdf/react/render';\nimport { pageEditPlugin } from '@embedpdf/react/page-edit';\nimport { metadataPlugin } from '@embedpdf/react/metadata';\nimport { feedbackPlugin, interactionPlugin, vibrationFeedback } from '@embedpdf/react/interaction';\nimport { selectionPlugin } from '@embedpdf/react/selection';\nimport { AnnotationToken, annotationPlugin } from '@embedpdf/react/annotation';\nimport { stampPlugin } from '@embedpdf/react/stamp';\nimport { measurementPlugin } from '@embedpdf/react/measurement';\nimport { redactionPlugin } from '@embedpdf/react/redaction';\nimport { actionsPlugin } from '@embedpdf/react/actions';\nimport { FormToken, formPlugin } from '@embedpdf/react/form';\nimport { signaturePlugin } from '@embedpdf/react/signature';\nimport { linkPlugin } from '@embedpdf/react/link';\nimport { searchPlugin } from '@embedpdf/react/search';\nimport { I18nToken, i18nPlugin, useT } from '@embedpdf/react/i18n';\nimport type { TranslationDictionary } from '@embedpdf/react/i18n';\nimport { CommandsToken, commandsPlugin } from '@embedpdf/react/commands';\nimport type { NotAllowedMode } from '@embedpdf/react/commands';\nimport { historyPlugin } from '@embedpdf/react/history';\nimport { shellPlugin } from '@embedpdf/react/shell';\nimport type { LayoutOption } from '@embedpdf/core-ui';\nimport { ThumbsStageToken } from './config/stage';\nimport { defaultCommands, toolCommandsFor } from './config/commands';\nimport { resolveViewerCommands, type CommandDef } from './config/viewer-commands';\nimport { localeCodeOf, localesOf } from './locales';\nimport {\n ViewerConfigProvider,\n type PanelResizeEvent,\n type ResolvedViewerConfig,\n type ViewerFont,\n} from './config-context';\nimport {\n bothAllow,\n byHandSettingsOf,\n disabledSettingsOf,\n sameByHand,\n type ByHandSettings,\n type DisabledSettings,\n type Feature,\n type ReadOnlyExceptions,\n} from './features';\nimport {\n VIEWER_PLUGINS,\n createViewerSlot,\n type PluginTokens,\n type Viewer,\n type ViewerSlot,\n} from './handle';\nimport {\n readPluginsConfig,\n settingsOver,\n type PluginSettings,\n type PluginsConfigRead,\n type ViewerPluginsConfig,\n} from './plugin-settings';\nimport { hasIcon, type IconDef } from './ui/icons';\nimport { isMacPlatform } from '@embedpdf/web';\nimport { ThemeProvider, themeConfigOf, type ThemeConfig, type ThemePreference } from './ui/theme';\nimport { Shell } from './Shell';\nimport type { PlacedComponents } from './ui/placed-components';\nimport { SlottedEdgesProvider, createSlottedEdges } from './ui/slotted-edges';\n\n/**\n * The customization surface — identical in the vanilla snippet and every\n * framework wrapper. See README.md for the ladder this implements.\n */\nexport interface ViewerCustomization {\n /**\n * Your commands, beside the built-in ones. One with a built-in id changes that one, field by\n * field: what it leaves out stays. A shortcut of yours wins over a built-in one with the same\n * keys.\n */\n commands?: readonly CommandDef[];\n /** Your icons by name: 24×24 path data. One with a built-in icon's name replaces it. */\n icons?: Readonly<Record<string, IconDef>>;\n /**\n * Words by language code, over the viewer's own: a built-in button's label under its command's\n * id (`'document:download'`), your own keys (`labelKey`, `titleKey`), dotted keys expanded. A\n * code the viewer has no language for becomes one, falling back to English, and reads right to\n * left when its code's script does (`fa`, `ur`).\n */\n strings?: Readonly<Record<string, TranslationDictionary>>;\n /** 'auto' (default) negotiates from the browser languages. Follows its prop. */\n locale?: 'auto' | (string & {});\n /**\n * What this viewer doesn't have, everywhere at once: features (`'annotations'`), their parts\n * (`'annotations.highlight'`) and single commands (`'tool:highlight'`: a name with a colon).\n * Follows its prop.\n */\n disable?: readonly (Feature | (string & {}))[];\n /**\n * Every feature that changes the document off, or all of them but `except`, on top of\n * `disable`. Only the interface: plugins keep working for your code. Follows its prop.\n */\n readOnly?: boolean | ReadOnlyExceptions;\n /**\n * What the user may do: the permissions the engine checks on every call, from a button or\n * from code. Left out, they may do everything. Documents opened after a change use the new one.\n */\n scope?: readonly string[];\n /** Who the user is: the author of what they write. */\n identity?: Identity;\n /** What the scope doesn't allow: `'hide'` it (default), or `'disable'` it with the reason. */\n notAllowed?: NotAllowedMode;\n /**\n * Where every toolbar, button, menu and panel goes: a layout of your own, or a function that\n * gets the default layout and the viewer's env (`size`, `width`, `touch`, `dir`) and returns\n * yours. The function runs again when the env changes. Never merged.\n */\n layout?: LayoutOption;\n /**\n * Each plugin's settings, by the plugin's name, as its page in the headless docs lists them\n * (`stage: { spread: 'odd' }`), over the viewer's own; and a plugin of your own as its\n * definition (`analytics: analyticsPlugin()`), which `viewer.get('analytics')` then finds.\n * Where the viewer's own keys set a plugin's settings too, both count and each only takes\n * away: the plugin's `disabledCategories` and `disabledCommands` add to what `disable` and\n * `readOnly` turn off, and its `editable` and `fillable` keep only what both allow. A list of\n * definitions (`annotation.tools`, `commands.commands`, `i18n.locales`) adds to the viewer's.\n * The language is `locale`'s, and `notAllowed`, when given, wins over the plugin's. `stamp`\n * and `signature` also take settings only the viewer has: the standard and quick stamps, and\n * which marks people keep and their fonts. Read once.\n */\n plugins?: ViewerPluginsConfig;\n /** Light/dark preference (string shorthand), or the full theme config: the\n * accent and the other tokens. Tokens are applied by the delivery (the\n * custom element adopts them into its shadow root); direct\n * consumers of this package set the `--epdf-*` variables in their own CSS\n * instead. Follows its prop. */\n theme?: ThemePreference | ThemeConfig;\n /**\n * Called with the `viewer` once it's live, before any document has opened: capabilities\n * resolve from then on, and document-scoped calls wait for their document. Read once.\n */\n onReady?: (viewer: Viewer) => void;\n /**\n * Called with the active document's id whenever it changes: the first document that opens,\n * a switch to another tab, and `null` once the last one closes. Read once.\n */\n onDocumentChange?: (documentId: string | null) => void;\n /**\n * Called when the user has resized a panel, with its id and new width in px: once a drag of\n * its edge ends, and on each arrow key there. Keep the width to start the panel at it next\n * time (`layout.panel(id, { width: { initial } })`). Read once.\n */\n onPanelResize?: (event: PanelResizeEvent) => void;\n}\n\nexport interface FullViewerProps extends ViewerCustomization {\n /** Instance (borrowed) or thunk (viewer-owned) — the Viewer's own contract. */\n engine: Engine | EngineFactory;\n /** Documents to open at mount; more arrive via the tab bar's open button. */\n initialDocuments?: InitialDocument[];\n /** Shown while the workspace boots. Default: a translated pulse line. */\n fallback?: ReactNode;\n /** Where the theme's `.dark` class goes — a delivery concern, not user\n * config: the custom element passes its shadow wrapper so theming never\n * touches the host page. Default: document.documentElement. */\n themeTarget?: HTMLElement | null;\n /**\n * The viewer's own components placed in the page (`<epdf-button>`, `<epdf-menu>`), which the\n * viewer draws — a delivery concern: the custom element passes the ones inside it.\n */\n components?: PlacedComponents;\n /**\n * Fonts beyond the standard 14 for the engine (a delivery's `engine.fonts`): each is read\n * once, registered on a local engine and mounted for the live text editor, and the style\n * panel offers it. A cloud engine's fonts are its server's, so none are offered there.\n */\n fonts?: readonly ViewerFont[];\n}\n\n/**\n * Inside <HeadlessViewer>: reports the live kernel's `viewer` (the one your commands get too),\n * then the active document: the one already active (the initial documents open with the\n * kernel, a delivery's own in `onReady`), and every change after it. The `viewer` is done when\n * this unmounts, with the kernel it reaches: its listeners stop before the documents close.\n */\nfunction HandleBridge({\n slot,\n onReady,\n onDocumentChange,\n}: Pick<ViewerCustomization, 'onReady' | 'onDocumentChange'> & { slot: ViewerSlot }) {\n const kernel = useKernel();\n // Before the first paint, so what the delivery opens on arrival (the element's `src`) is a\n // tab by the time the shell first shows.\n useLayoutEffect(() => {\n const viewer = slot.attach(kernel);\n onReady?.(viewer);\n if (onDocumentChange) {\n viewer.watch(\n () => viewer.documents.getActiveId(),\n (documentId) => onDocumentChange(documentId),\n );\n const active = viewer.documents.getActiveId();\n if (active !== null) onDocumentChange(active);\n }\n return () => slot.release(kernel);\n // Init-only like everything else: re-fires only if the kernel changes\n // (a remount), never because a callback prop's identity churned.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [kernel]);\n return null;\n}\n\nconst sameList = (left: readonly string[], right: readonly string[]): boolean =>\n left.length === right.length && left.every((name, index) => name === right[index]);\n\n/**\n * What `disable` and `readOnly` turn off, with what the app's `plugins` settings turn off too:\n * each only takes away.\n */\nfunction turnedOffOf(\n disable: ViewerCustomization['disable'],\n readOnly: ViewerCustomization['readOnly'],\n settings: PluginsConfigRead['settings'],\n): { readonly disabled: DisabledSettings; readonly byHand: ByHandSettings } {\n const disabled = disabledSettingsOf(disable, readOnly);\n const byHand = byHandSettingsOf(disable, readOnly);\n const union = (viewers: readonly string[], apps: readonly string[] | undefined) =>\n apps?.length ? [...new Set([...viewers, ...apps])] : viewers;\n return {\n disabled: {\n disabledCategories: union(disabled.disabledCategories, settings.commands?.disabledCategories),\n disabledCommands: union(disabled.disabledCommands, settings.commands?.disabledCommands),\n },\n byHand: {\n editable: bothAllow(byHand.editable, settings.annotation?.editable ?? true),\n fillable: bothAllow(byHand.fillable, settings.form?.fillable ?? true),\n },\n };\n}\n\n/**\n * Inside <HeadlessViewer>: the props that follow their value while the viewer runs. `registered`\n * is what the plugins were registered with, when the props were first read; a value that differs\n * from the last one goes to the plugin that owns it, so a theme change never undoes what the\n * app's code turned off. `settings` are the app's `plugins` settings, which still count.\n */\nfunction FollowProps({\n registered,\n settings,\n locale,\n disable,\n readOnly,\n}: {\n registered: {\n readonly locale: string;\n readonly disabled: DisabledSettings;\n readonly byHand: ByHandSettings;\n };\n settings: PluginsConfigRead['settings'];\n locale: string;\n disable: ViewerCustomization['disable'];\n readOnly: ViewerCustomization['readOnly'];\n}) {\n const kernel = useKernel();\n // The kernel starts after the first render, so a prop may have changed before this mounts.\n const applied = useRef(registered);\n // In the render that brought the change, so the plugin has it when the prop's setter returns.\n useLayoutEffect(() => {\n const { disabled, byHand } = turnedOffOf(disable, readOnly, settings);\n const previous = applied.current;\n applied.current = { locale, disabled, byHand };\n // What a turned-off feature made stays in the document, frozen: no one changes it by hand.\n if (!sameByHand(previous.byHand.editable, byHand.editable)) {\n kernel.settingsOf(AnnotationToken).updateSettings({ editable: byHand.editable });\n }\n if (!sameByHand(previous.byHand.fillable, byHand.fillable)) {\n kernel.settingsOf(FormToken).updateSettings({ fillable: byHand.fillable });\n }\n if (\n !sameList(previous.disabled.disabledCategories, disabled.disabledCategories) ||\n !sameList(previous.disabled.disabledCommands, disabled.disabledCommands)\n ) {\n kernel.capability(CommandsToken).updateSettings(disabled);\n }\n if (previous.locale !== locale) {\n // A newer switch cancels this one, which rejects; the newer one shows.\n kernel\n .capability(I18nToken)\n .setLocale(locale)\n .catch(() => {});\n }\n });\n return null;\n}\n\nfunction Booting() {\n const t = useT();\n return (\n <div className=\"bg-app text-fg-muted grid h-full place-items-center\">\n <div className=\"animate-pulse text-sm\">{t('demo.starting')}</div>\n </div>\n );\n}\n\nexport function FullViewer({\n engine,\n initialDocuments,\n fallback,\n commands,\n icons,\n strings,\n locale = 'auto',\n disable,\n readOnly,\n scope,\n identity,\n notAllowed,\n layout,\n plugins: pluginsConfig,\n fonts,\n theme,\n themeTarget,\n components,\n onReady,\n onDocumentChange,\n onPanelResize,\n}: FullViewerProps) {\n // Which bar each slotted toolbar item is in, for the viewer's own components inside it.\n const [slottedEdges] = useState(createSlottedEdges);\n // Customization is init-only, like the Viewer's own engine/plugins\n // contract: the whole config resolves once from the mount-time props, so\n // inline literals — the idiomatic way to pass it — never churn plugin\n // identities. Later prop changes are ignored, except the ones FollowProps\n // and ThemeProvider follow.\n const [resolved] = useState(() => {\n // ── languages: the app's strings in the viewer's, and languages of its own ──\n const { locales, loaders, codes } = localesOf(strings);\n\n // ── plugins: the app's settings for the built-ins, and its own plugins ──\n const pluginsRead = readPluginsConfig(pluginsConfig);\n const tokens: Record<string, CapabilityToken<unknown>> = { ...VIEWER_PLUGINS };\n for (const { name, plugin } of pluginsRead.own) if (plugin.token) tokens[name] = plugin.token;\n\n // ── commands: yours over the built-in ones, a command for each tool of yours ──\n // The kernel's `viewer`, made when it starts: what `onReady` and your commands get.\n const slot = createViewerSlot(tokens as PluginTokens);\n const builtInIds = new Set(defaultCommands.map((command) => command.id));\n const builtIns = [\n ...defaultCommands,\n ...toolCommandsFor(pluginsRead.settings.annotation?.tools ?? [], (id) => builtInIds.has(id)),\n ];\n const viewerCommands = resolveViewerCommands(\n builtIns,\n commands ?? [],\n { plugins: tokens as PluginTokens, viewer: slot.current },\n { isMac: isMacPlatform() },\n );\n\n return {\n slot,\n viewerCommands,\n // Structure: resolved at the viewer's env by the shell's layout root.\n layout,\n icons: icons ?? {},\n stamp: pluginsRead.viewer.stamp,\n signature: pluginsRead.viewer.signature,\n fonts: fonts ?? [],\n onPanelResize,\n i18n: { locales, loaders, codes, initial: localeCodeOf(locale, codes) },\n plugins: pluginsRead,\n tokens: tokens as PluginTokens,\n ...turnedOffOf(disable, readOnly, pluginsRead.settings),\n };\n });\n\n // Dev guardrail: every icon a command names must resolve. Warnings name the\n // exact id (README promise); the layout's ids are checked where it resolves.\n useEffect(() => {\n if (process.env.NODE_ENV === 'production') return;\n for (const command of resolved.viewerCommands.commands) {\n if (command.icon && !hasIcon(command.icon) && !(command.icon in resolved.icons)) {\n console.warn(`[embedpdf] command \"${command.id}\": unknown icon \"${command.icon}\"`);\n }\n }\n }, [resolved]);\n\n // In every build, as the layout's: a misspelled plugin name quietly loses its settings.\n useEffect(() => {\n for (const problem of resolved.plugins.problems) console.warn(`[embedpdf] plugins: ${problem}`);\n }, [resolved]);\n\n // The app's settings for each built-in plugin, from `plugins`.\n const { settings } = resolved.plugins;\n const [plugins] = useState(() => [\n // The main lens (tools engage via interactionPlugin below).\n stagePlugin(settingsOver<PluginSettings<'stage'>>({ layout: 'vertical' }, settings.stage)),\n // Thumbnail lens over the same document (`thumbnails` in `plugins`): a grid at a\n // fixed small zoom, its own camera, wrapping into as many columns as the panel's\n // width fits. Click a thumb to navigate the main lens; the sidebar follows the\n // main view (see ui/panels ThumbnailList).\n // Each setting the app gives replaces the viewer's whole, as a Stage's own\n // `updateSettings()` does: `zoom: { level: 0.2 }` is that zoom, not a mix.\n stagePlugin({\n layout: 'grid',\n columns: 'auto', // one column at the default width; more as the panel widens\n sizing: 'uniform', // equalize pages so the pixel target hits every thumb\n zoom: { pageWidth: 150 }, // thumbs are 150 screen px wide — for any document\n padding: 12,\n gap: { px: 16 }, // UI-stable spacing between thumbs\n pageFrame: { top: 0, right: 0, bottom: 20, left: 0 }, // reserved label band (screen px)\n fitAlign: { x: 'center', y: 'start' }, // few pages? thumbs hug the top\n scrollBehavior: 'instant',\n interaction: false, // click-to-navigate: a drag never reaches the document's tools\n zoomGestures: false, // a fixed-magnification rail: Cmd+wheel and pinch scroll it\n ...settings.thumbnails,\n id: 'stage-thumbs',\n token: ThumbsStageToken,\n }),\n renderPlugin(settings.render),\n pageEditPlugin(),\n // The document's title, author and your own fields, read the first time something asks\n // (`viewer.get('metadata').ensureLoaded()`, `useMetadataState()`), never as a document opens.\n metadataPlugin(),\n interactionPlugin(settings.interaction),\n // Platform haptics, default-on: the Vibration API where it exists\n // (Android), a safe silent no-op elsewhere — iOS Safari included, until\n // Apple ships a haptics API. Native shells swap in their own provider\n // (`wkFeedback`) instead.\n feedbackPlugin({ provider: vibrationFeedback }),\n selectionPlugin(settings.selection),\n // The arrow tool is a `line` preset — same subtype, an arrowhead default. This is\n // the whole integration for a new tool: one `tools` entry + a command/toolbar\n // slot (see config/commands.ts + config/chrome.ts).\n annotationPlugin({\n ...settings.annotation,\n tools: [\n // Shapes and lines show their ghost: what a click places follows the\n // pointer (the arrow inherits the line's).\n { id: 'square', ghost: true },\n { id: 'circle', ghost: true },\n { id: 'line', ghost: true },\n {\n id: 'arrow',\n extends: 'line',\n defaults: { lineEndings: { start: 'none', end: 'open-arrow' } },\n },\n // The Insert tab's Image button: a `stamp` preset whose payload comes\n // from the file-picker port, narrowed to rasters. Click the spot, the\n // dialog opens, the picture lands there. Its own tool id (not `stamp`)\n // keeps it out of the stamp panel's armed state and gives it its own\n // cursor icon.\n {\n id: 'image',\n extends: 'stamp',\n source: { kind: 'prompt', accept: 'image/png,image/jpeg' },\n },\n // The app's own after the viewer's: one with the same id changes it.\n ...(settings.annotation?.tools ?? []),\n ],\n // What a turned-off feature made stays, but no one changes it by hand.\n editable: resolved.byHand.editable,\n }),\n // Undo and redo of what the user changes, one history per document.\n historyPlugin(),\n // Stamp libraries (workspace-scoped): named reusable assets — the built-in\n // set plus any PDF the user imports, each page one vector stamp. The\n // stamps sidebar is the picker; placement rides annotation's armed stamp.\n // Libraries open on a local engine: the viewer's own unless the host\n // names one (`assetEngine`; a cloud viewer has to).\n stampPlugin(settings.stamp),\n // The action engine: /A and /AA trees dispatch through one policy-gated\n // executor spine, and the JavaScript switch lives here (the per-document\n // ScriptHost realm; form's K/V/C/F pipeline rides its transaction port,\n // stamp's dynamic templates evaluate in detached realms it mints).\n // Scripts ask who the user is (`identity.name`): the document's user, from\n // the viewer's identity or the token.\n actionsPlugin(\n settingsOver<PluginSettings<'actions'>>({ javascript: { enabled: true } }, settings.actions),\n ),\n // Forms: fillable under the default pointer/pan (widgets render as fill\n // controls), editable under the Form tab's 'form-edit' + palette tools.\n formPlugin({ ...settings.form, fillable: resolved.byHand.fillable }),\n // Signatures: the act — a mark (a signatures-library asset) dropped on a\n // signature field signs it through the configured key, or is drawn in\n // without sealing when there is none. Marks themselves are the stamp\n // plugin's; the panel lists libraries of kind 'signatures'.\n signaturePlugin(settings.signature),\n // Links: navigable under the default pointer/pan ('link-nav'), editable\n // under the link tool — the annotation plane then owns them (select, move,\n // retarget via the style panel's Link control).\n linkPlugin(),\n // Redaction: marking is the annotation plane's composed `redact` tool; this\n // plugin adds the pending-queue view + the destructive apply.\n redactionPlugin(settings.redaction),\n measurementPlugin(settings.measurement),\n searchPlugin(settings.search),\n i18nPlugin({\n fallbackLocale: 'en',\n ...settings.i18n,\n locale: resolved.i18n.initial,\n locales: [...resolved.i18n.locales, ...(settings.i18n?.locales ?? [])],\n loaders: { ...resolved.i18n.loaders, ...settings.i18n?.loaders },\n }),\n commandsPlugin({\n ...settings.commands,\n commands: [...resolved.viewerCommands.commands, ...(settings.commands?.commands ?? [])],\n ...resolved.disabled,\n ...(notAllowed ? { notAllowed } : {}),\n }),\n shellPlugin(),\n // The app's own plugins, under the names `viewer.get()` finds them by.\n ...resolved.plugins.own.map(({ plugin }) => plugin),\n ]);\n\n // Structural subset of `resolved`, identity-stable across renders.\n const config: ResolvedViewerConfig = resolved;\n\n return (\n <ThemeProvider preference={themeConfigOf(theme).preference} target={themeTarget}>\n <HeadlessViewer\n engine={engine}\n plugins={plugins}\n initialDocuments={initialDocuments}\n scope={scope}\n identity={identity}\n fallback={fallback ?? <Booting />}\n onReady={(kernel) => void resolved.slot.attach(kernel)}\n >\n <ViewerConfigProvider value={config}>\n <FollowProps\n registered={{\n locale: resolved.i18n.initial,\n disabled: resolved.disabled,\n byHand: resolved.byHand,\n }}\n settings={settings}\n locale={localeCodeOf(locale, resolved.i18n.codes)}\n disable={disable}\n readOnly={readOnly}\n />\n <HandleBridge\n slot={resolved.slot}\n onReady={onReady}\n onDocumentChange={onDocumentChange}\n />\n <SlottedEdgesProvider value={slottedEdges}>\n <Shell components={components} />\n </SlottedEdgesProvider>\n </ViewerConfigProvider>\n </HeadlessViewer>\n </ThemeProvider>\n );\n}\n"],"mappings":"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"}
|