@embedpdf/react 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.
Files changed (232) hide show
  1. package/dist/AnnotationList-CkijRHet-HEFNUIZe.d.cts +877 -0
  2. package/dist/AnnotationList-CkijRHet-HEFNUIZe.d.ts +877 -0
  3. package/dist/actions.cjs +25 -5
  4. package/dist/actions.cjs.map +1 -1
  5. package/dist/actions.d.cts +18 -5
  6. package/dist/actions.d.ts +18 -5
  7. package/dist/actions.js +22 -6
  8. package/dist/actions.js.map +1 -1
  9. package/dist/anchored-DeX95xSd.d.ts +85 -0
  10. package/dist/anchored-DzN3JywS.d.cts +85 -0
  11. package/dist/anchored.cjs +71 -28
  12. package/dist/anchored.cjs.map +1 -1
  13. package/dist/anchored.d.cts +2 -45
  14. package/dist/anchored.d.ts +2 -45
  15. package/dist/anchored.js +56 -19
  16. package/dist/anchored.js.map +1 -1
  17. package/dist/annotation-B48UT2ln.d.ts +302 -0
  18. package/dist/annotation-C1ttM8Wj.js +708 -0
  19. package/dist/annotation-C1ttM8Wj.js.map +1 -0
  20. package/dist/annotation-C9dVwo9b.d.cts +302 -0
  21. package/dist/annotation-Dex5EBda.cjs +830 -0
  22. package/dist/annotation-Dex5EBda.cjs.map +1 -0
  23. package/dist/annotation.cjs +20 -783
  24. package/dist/annotation.d.cts +2 -2
  25. package/dist/annotation.d.ts +2 -2
  26. package/dist/annotation.js +2 -768
  27. package/dist/commands.cjs +68 -28
  28. package/dist/commands.cjs.map +1 -1
  29. package/dist/commands.d.cts +37 -10
  30. package/dist/commands.d.ts +37 -10
  31. package/dist/commands.js +68 -31
  32. package/dist/commands.js.map +1 -1
  33. package/dist/form-55izw0jS.js +511 -0
  34. package/dist/form-55izw0jS.js.map +1 -0
  35. package/dist/form-BNqQfGGH.cjs +548 -0
  36. package/dist/form-BNqQfGGH.cjs.map +1 -0
  37. package/dist/form.cjs +5 -5
  38. package/dist/form.d.cts +32 -25
  39. package/dist/form.d.ts +32 -25
  40. package/dist/form.js +2 -3
  41. package/dist/history.cjs +38 -0
  42. package/dist/history.cjs.map +1 -0
  43. package/dist/history.d.cts +27 -0
  44. package/dist/history.d.ts +27 -0
  45. package/dist/history.js +27 -0
  46. package/dist/history.js.map +1 -0
  47. package/dist/i18n.cjs +26 -30
  48. package/dist/i18n.cjs.map +1 -1
  49. package/dist/i18n.d.cts +24 -21
  50. package/dist/i18n.d.ts +24 -21
  51. package/dist/i18n.js +24 -31
  52. package/dist/i18n.js.map +1 -1
  53. package/dist/index.cjs +213 -57
  54. package/dist/index.d.cts +32 -31
  55. package/dist/index.d.ts +32 -31
  56. package/dist/index.js +33 -29
  57. package/dist/inert-CmBEbKCn.cjs +19 -0
  58. package/dist/inert-CmBEbKCn.cjs.map +1 -0
  59. package/dist/inert-D8fkennb.js +14 -0
  60. package/dist/inert-D8fkennb.js.map +1 -0
  61. package/dist/interaction.cjs +48 -102
  62. package/dist/interaction.cjs.map +1 -1
  63. package/dist/interaction.d.cts +23 -32
  64. package/dist/interaction.d.ts +23 -32
  65. package/dist/interaction.js +33 -102
  66. package/dist/interaction.js.map +1 -1
  67. package/dist/link.cjs +65 -104
  68. package/dist/link.cjs.map +1 -1
  69. package/dist/link.d.cts +21 -16
  70. package/dist/link.d.ts +22 -17
  71. package/dist/link.js +67 -107
  72. package/dist/link.js.map +1 -1
  73. package/dist/measurement.cjs +56 -0
  74. package/dist/measurement.cjs.map +1 -0
  75. package/dist/measurement.d.cts +38 -0
  76. package/dist/measurement.d.ts +38 -0
  77. package/dist/measurement.js +42 -0
  78. package/dist/measurement.js.map +1 -0
  79. package/dist/metadata.cjs +20 -7
  80. package/dist/metadata.cjs.map +1 -1
  81. package/dist/metadata.d.cts +22 -7
  82. package/dist/metadata.d.ts +22 -7
  83. package/dist/metadata.js +20 -10
  84. package/dist/metadata.js.map +1 -1
  85. package/dist/page-edit.cjs +7 -3
  86. package/dist/page-edit.cjs.map +1 -1
  87. package/dist/page-edit.d.cts +6 -2
  88. package/dist/page-edit.d.ts +6 -2
  89. package/dist/page-edit.js +7 -4
  90. package/dist/page-edit.js.map +1 -1
  91. package/dist/page-layers-Bkaaz8Zf.js +26 -0
  92. package/dist/page-layers-Bkaaz8Zf.js.map +1 -0
  93. package/dist/page-layers-BloZDoOV.cjs +37 -0
  94. package/dist/page-layers-BloZDoOV.cjs.map +1 -0
  95. package/dist/page-view.cjs +89 -82
  96. package/dist/page-view.cjs.map +1 -1
  97. package/dist/page-view.d.cts +14 -7
  98. package/dist/page-view.d.ts +18 -11
  99. package/dist/page-view.js +86 -81
  100. package/dist/page-view.js.map +1 -1
  101. package/dist/redaction.cjs +30 -15
  102. package/dist/redaction.cjs.map +1 -1
  103. package/dist/redaction.d.cts +27 -9
  104. package/dist/redaction.d.ts +27 -9
  105. package/dist/redaction.js +29 -18
  106. package/dist/redaction.js.map +1 -1
  107. package/dist/render.cjs +71 -46
  108. package/dist/render.cjs.map +1 -1
  109. package/dist/render.d.cts +17 -5
  110. package/dist/render.d.ts +17 -5
  111. package/dist/render.js +70 -49
  112. package/dist/render.js.map +1 -1
  113. package/dist/runtime-B6xcPsEb.js +398 -0
  114. package/dist/runtime-B6xcPsEb.js.map +1 -0
  115. package/dist/runtime-DBEBlpQV.d.cts +237 -0
  116. package/dist/runtime-V3MVMb91.d.ts +237 -0
  117. package/dist/runtime-fzpGv78v.cjs +555 -0
  118. package/dist/runtime-fzpGv78v.cjs.map +1 -0
  119. package/dist/runtime.cjs +45 -324
  120. package/dist/runtime.d.cts +2 -2
  121. package/dist/runtime.d.ts +2 -2
  122. package/dist/runtime.js +2 -306
  123. package/dist/search.cjs +81 -50
  124. package/dist/search.cjs.map +1 -1
  125. package/dist/search.d.cts +36 -24
  126. package/dist/search.d.ts +36 -24
  127. package/dist/search.js +81 -53
  128. package/dist/search.js.map +1 -1
  129. package/dist/selection.cjs +105 -108
  130. package/dist/selection.cjs.map +1 -1
  131. package/dist/selection.d.cts +54 -26
  132. package/dist/selection.d.ts +56 -28
  133. package/dist/selection.js +103 -110
  134. package/dist/selection.js.map +1 -1
  135. package/dist/shell.cjs +36 -21
  136. package/dist/shell.cjs.map +1 -1
  137. package/dist/shell.d.cts +32 -17
  138. package/dist/shell.d.ts +32 -17
  139. package/dist/shell.js +36 -24
  140. package/dist/shell.js.map +1 -1
  141. package/dist/signature.cjs +29 -48
  142. package/dist/signature.cjs.map +1 -1
  143. package/dist/signature.d.cts +26 -26
  144. package/dist/signature.d.ts +26 -26
  145. package/dist/signature.js +30 -48
  146. package/dist/signature.js.map +1 -1
  147. package/dist/stage-BIG6aeVd.cjs +369 -0
  148. package/dist/stage-BIG6aeVd.cjs.map +1 -0
  149. package/dist/stage-ByFPD-Fv.d.cts +117 -0
  150. package/dist/stage-DaboaheR.d.ts +117 -0
  151. package/dist/stage-DoVekb83.js +302 -0
  152. package/dist/stage-DoVekb83.js.map +1 -0
  153. package/dist/stage-scope-CQgCuf1w.cjs +46 -0
  154. package/dist/stage-scope-CQgCuf1w.cjs.map +1 -0
  155. package/dist/stage-scope-D7ZeNduT.js +23 -0
  156. package/dist/stage-scope-D7ZeNduT.js.map +1 -0
  157. package/dist/stage.cjs +12 -235
  158. package/dist/stage.d.cts +2 -116
  159. package/dist/stage.d.ts +2 -116
  160. package/dist/stage.js +3 -228
  161. package/dist/stamp.cjs +41 -35
  162. package/dist/stamp.cjs.map +1 -1
  163. package/dist/stamp.d.cts +25 -18
  164. package/dist/stamp.d.ts +25 -18
  165. package/dist/stamp.js +40 -37
  166. package/dist/stamp.js.map +1 -1
  167. package/dist/state-0K1I5cM4.d.cts +29 -0
  168. package/dist/state-0K1I5cM4.d.ts +29 -0
  169. package/dist/state-CbgxhwLA.js +62 -0
  170. package/dist/state-CbgxhwLA.js.map +1 -0
  171. package/dist/state-CsfZy_Eq.cjs +73 -0
  172. package/dist/state-CsfZy_Eq.cjs.map +1 -0
  173. package/dist/svg-shapes-Dm1yTR1b.js +40 -0
  174. package/dist/svg-shapes-Dm1yTR1b.js.map +1 -0
  175. package/dist/svg-shapes-zo0GNkc9.cjs +53 -0
  176. package/dist/svg-shapes-zo0GNkc9.cjs.map +1 -0
  177. package/dist/toolbar.cjs +297 -295
  178. package/dist/toolbar.cjs.map +1 -1
  179. package/dist/toolbar.d.cts +58 -68
  180. package/dist/toolbar.d.ts +67 -77
  181. package/dist/toolbar.js +271 -293
  182. package/dist/toolbar.js.map +1 -1
  183. package/dist/view-manager.cjs +34 -0
  184. package/dist/view-manager.cjs.map +1 -0
  185. package/dist/view-manager.d.cts +21 -0
  186. package/dist/view-manager.d.ts +21 -0
  187. package/dist/view-manager.js +23 -0
  188. package/dist/view-manager.js.map +1 -0
  189. package/package.json +41 -38
  190. package/dist/AnnotationListSnapshot-D3mFut1e-C_GMpK25.d.cts +0 -546
  191. package/dist/AnnotationListSnapshot-D3mFut1e-C_GMpK25.d.ts +0 -546
  192. package/dist/annotation-BCED_p9H.d.cts +0 -160
  193. package/dist/annotation-anchors-CetwM1g7.js +0 -15
  194. package/dist/annotation-anchors-CetwM1g7.js.map +0 -1
  195. package/dist/annotation-anchors-DuYRBJLl.cjs +0 -26
  196. package/dist/annotation-anchors-DuYRBJLl.cjs.map +0 -1
  197. package/dist/annotation-hooks-BB5ZhPpf.cjs +0 -16
  198. package/dist/annotation-hooks-BB5ZhPpf.cjs.map +0 -1
  199. package/dist/annotation-hooks-Df8EmzDO.js +0 -11
  200. package/dist/annotation-hooks-Df8EmzDO.js.map +0 -1
  201. package/dist/annotation-k38KDlIZ.d.ts +0 -160
  202. package/dist/annotation-menu.cjs +0 -64
  203. package/dist/annotation-menu.cjs.map +0 -1
  204. package/dist/annotation-menu.d.cts +0 -33
  205. package/dist/annotation-menu.d.ts +0 -33
  206. package/dist/annotation-menu.js +0 -48
  207. package/dist/annotation-menu.js.map +0 -1
  208. package/dist/annotation.cjs.map +0 -1
  209. package/dist/annotation.js.map +0 -1
  210. package/dist/form-BVumS7up.cjs +0 -926
  211. package/dist/form-BVumS7up.cjs.map +0 -1
  212. package/dist/form-CK3mp99m.js +0 -895
  213. package/dist/form-CK3mp99m.js.map +0 -1
  214. package/dist/rolldown-runtime-BBjsoOtd.js +0 -27
  215. package/dist/runtime-DE76hlnl.d.ts +0 -216
  216. package/dist/runtime-umHA_xHt.d.cts +0 -216
  217. package/dist/runtime.cjs.map +0 -1
  218. package/dist/runtime.js.map +0 -1
  219. package/dist/scrollbar.cjs +0 -241
  220. package/dist/scrollbar.cjs.map +0 -1
  221. package/dist/scrollbar.d.cts +0 -42
  222. package/dist/scrollbar.d.ts +0 -42
  223. package/dist/scrollbar.js +0 -213
  224. package/dist/scrollbar.js.map +0 -1
  225. package/dist/stage.cjs.map +0 -1
  226. package/dist/stage.js.map +0 -1
  227. package/dist/views.cjs +0 -35
  228. package/dist/views.cjs.map +0 -1
  229. package/dist/views.d.cts +0 -21
  230. package/dist/views.d.ts +0 -21
  231. package/dist/views.js +0 -27
  232. package/dist/views.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"annotation-Dex5EBda.cjs","names":["stateHook","annotationState","settingsHook","AnnotationToken","useProjectorBinding","useOptionalSelector","AnnotationHostToken","sameSelectionAnchor","Anchored","AnnotationToken","sameCreationDraftAnchor","sameRotationAnchor","React","INERT","SvgShapes","MITER_LIMIT","useCapability","AnnotationHostToken","useSelector","useViewerSettings","shallowArray","usePage","useOptionalSelector","InteractionToken","useOptionalCapability","createShownUrls","RenderToken","annotationKey","pickRequestedFile","AnnotationToken","devWarn","sameAnnotationAnchor","useDocumentId","useKernelValue"],"sources":["../src/annotation-hooks.ts","../src/annotation-menu.tsx","../src/annotation.tsx"],"sourcesContent":["/**\n * The annotation hooks other feature entries use too (the form plugin reads\n * the selection), kept apart so they don't import the whole annotation\n * feature: the state and the settings, each from its declaration.\n */\nimport { AnnotationToken, annotationState } from '@embedpdf/plugin-annotation/contract';\n\nimport { settingsHook, stateHook } from './state';\n\n/**\n * The annotation state: `status` (`'loading'` until every annotation is in,\n * then `'ready'`), the `selected` annotations, the one `hovered` under the\n * pointer and the text box being typed in (`editing`). Re-renders only when a\n * field changes, or the value `select` picks. Empty without a document.\n */\nexport const useAnnotationState = stateHook(annotationState);\n\n/**\n * The annotation settings (`snap`, `chrome`, `afterCreate`, `tools`), or the\n * value `select` picks. They belong to the plugin, so they read without a\n * document; change them with `useAnnotation().updateSettings()`.\n */\nexport const useAnnotationSettings = settingsHook(AnnotationToken);\n","/**\n * Annotation menus: thin anchor plumbing over the one `<Anchored>` primitive.\n * They come from `/annotation`; this module stays apart so it doesn't pull\n * in the layer.\n *\n * These work identically under `<Stage>` (mount in the overlay slot; the\n * camera projects, no DOM reads) and `<PageView>` (measured and portalled):\n * the surface provides the projector, the menu doesn't care.\n *\n * No action bags: actions come from `useAnnotation()` and the state hooks,\n * which subscribe properly and compose across plugins. Render props carry\n * only the anchor's data (the draft menu's progress); the selection menu\n * takes plain children.\n */\nimport * as React from 'react';\nimport { AnnotationToken } from '@embedpdf/plugin-annotation/contract';\nimport { AnnotationToken as AnnotationHostToken } from '@embedpdf/plugin-annotation/contract/host';\nimport type { CreationDraftAnchor, RotationAnchor } from '@embedpdf/core-annotation';\nimport {\n paint,\n paintDefault,\n sameCreationDraftAnchor,\n sameRotationAnchor,\n sameSelectionAnchor,\n} from '@embedpdf/web';\nimport { Anchored, useProjectorBinding, type AnchoredPlacement } from './anchored';\nimport { useAnnotationSettings } from './annotation-hooks';\nimport { useOptionalSelector } from './runtime';\n\nexport interface AnnotationMenuProps {\n children: React.ReactNode;\n /** Gap in screen px between the selection box and the menu (default 15). */\n gap?: number;\n /** Where to place the menu relative to the selection box. Default 'top'. */\n placement?: AnchoredPlacement;\n}\n\n/**\n * Your own menu next to the selection (one anchor, also for a selection over\n * several pages), clear of the rotation handle. It hides while the selection\n * is dragged, resized or turned. What's in it is yours: build it from\n * `useAnnotation()` and `useAnnotationState()`.\n */\nexport function AnnotationMenu({ children, gap = 15, placement = 'top' }: AnnotationMenuProps) {\n // Reading the binding subscribes this component to projection changes\n // (its identity is the revision), so the anchor read below re-runs with\n // fresh view facts in the same commit as the surface: the rotation\n // handle's offset is screen-constant, so its page-space position depends\n // on the page's live view scale.\n const { projector } = useProjectorBinding();\n const anchor = useOptionalSelector(\n AnnotationHostToken,\n (annotation) => {\n const selectionAnchor = annotation.selection.getAnchor();\n if (!selectionAnchor) return null;\n const env = projector.viewEnv(selectionAnchor.page);\n return env ? annotation.getSelectionAnchorIn(env) : selectionAnchor;\n },\n null,\n sameSelectionAnchor,\n );\n if (!anchor) return null;\n return (\n <Anchored\n anchor={{\n page: anchor.page,\n bounds: anchor.bounds,\n ...(anchor.rotationHandle ? { avoid: [anchor.rotationHandle] } : {}),\n }}\n placement={placement}\n gap={gap}\n >\n {children}\n </Anchored>\n );\n}\n\nexport interface AnnotationDraftMenuProps {\n /** Render prop receiving the shape being drawn (`subtype`, `pointCount`,\n * `minPoints`, `canFinish`, …). The verbs are capability calls:\n * `useAnnotation().draft.finish()` and `.draft.cancel()`. */\n children: (anchor: CreationDraftAnchor) => React.ReactNode;\n /** Gap in screen px between the draft anchor and the menu (default 8). */\n gap?: number;\n /** Where to place the menu relative to the draft anchor. Default 'top'. */\n placement?: AnchoredPlacement;\n}\n\n/** Floats over a live multi-click creation draft (polygon, polyline, …). */\nexport function AnnotationDraftMenu({\n children,\n gap = 8,\n placement = 'top',\n}: AnnotationDraftMenuProps) {\n const anchor = useOptionalSelector(\n AnnotationToken,\n (annotation) => annotation.draft.get(),\n null,\n sameCreationDraftAnchor,\n );\n if (!anchor) return null;\n return (\n <Anchored anchor={anchor} placement={placement} gap={gap}>\n {children(anchor)}\n </Anchored>\n );\n}\n\nexport interface AnnotationRotationBadgeProps {\n /** Render prop receiving the rotation in progress (`angle`, degrees\n * clockwise, as the commit will apply it). Without it, the badge shows the\n * angle in the `chrome.readout` colors, when `chrome.readout.enabled`. */\n children?: (rotation: RotationAnchor) => React.ReactNode;\n /** Gap in screen px between the pointer and the badge (default 16). */\n gap?: number;\n /** Where to place the badge relative to the pointer. Default 'right'. */\n placement?: AnchoredPlacement;\n}\n\n/**\n * Follows the pointer while a selection is being turned, upright however the\n * page is shown: it floats over the page like the menus, not in it. Shows\n * nothing when no rotation is in progress.\n */\nexport function AnnotationRotationBadge({\n children,\n gap = 16,\n placement = 'right',\n}: AnnotationRotationBadgeProps) {\n const rotation = useOptionalSelector(\n AnnotationToken,\n (annotation) => annotation.selection.getRotationAnchor(),\n null,\n sameRotationAnchor,\n );\n const readout = useAnnotationSettings((settings) => settings.chrome.readout);\n if (!rotation || (!children && !readout.enabled)) return null;\n return (\n <Anchored\n anchor={{ page: rotation.page, bounds: { ...rotation.at, width: 0, height: 0 } }}\n placement={placement}\n gap={gap}\n >\n {children ? (\n children(rotation)\n ) : (\n <div\n style={{\n pointerEvents: 'none',\n whiteSpace: 'nowrap',\n borderRadius: 4,\n padding: '2px 6px',\n fontFamily: paintDefault('font-mono'),\n fontSize: 12,\n background: paint('readout-background', readout.background),\n color: paint('readout-color', readout.color),\n }}\n >\n {rotation.angle}°\n </div>\n )}\n </Anchored>\n );\n}\n","/**\n * The React view of @embedpdf/plugin-annotation.\n *\n * Pure paint: it reads the per-page render items and chrome and draws them.\n * Pointer events arrive through the interaction hub (the Stage's forwarding),\n * and the cursor is driven by the hub too (the edit handler claims\n * move/pointer/resize on hover). Each annotation resolves to one native node:\n * a vector scene, the engine's baked /AP <img>, or a registered behavior; a\n * renderer may wrap or replace it. Every chrome color is a setting painted\n * through `paint()`, so its `--epdf-annotation-*` CSS variable wins.\n *\n * What isn't React lives in `@embedpdf/web`, the same for every framework:\n * the scene as SVG elements, the chrome's paint and pixels, the text box\n * editor, which drawing each annotation gets and the behaviors renderers\n * register, and the object URLs of baked appearances and the stamp ghost.\n *\n * The hooks follow every plugin's four: `useAnnotation()` (the API),\n * `useAnnotationState()` (status, selected, hovered, editing),\n * `useAnnotationEvent()` and `useAnnotationSettings()`; the reads a component\n * follows on their own are `useAnnotationList()`, `useAnnotationDefaults()`,\n * `useAnnotationProperties()` and `useAnnotationAnchor()`.\n */\n\n// One-line-per-feature: registration travels with the UI.\nexport * from '@embedpdf/plugin-annotation';\nimport type { EventHook, PageRef } from '@embedpdf/core';\nimport {\n hasLiveDrawing,\n scene,\n MITER_LIMIT,\n type FieldValues,\n type Point,\n type RenderItem,\n} from '@embedpdf/core-annotation';\nimport {\n AnnotationToken,\n annotationKey,\n type Annotation,\n type AnnotationAnchor,\n type AnnotationCapability,\n type AnnotationFilter,\n type AnnotationProperties,\n type AnnotationRef,\n type ChromeSettings,\n type CommentsApi,\n type CommentThread,\n type FilePickerProvider,\n type HandleRole,\n type TextItem,\n type ToolDefaults,\n} from '@embedpdf/plugin-annotation';\n// The render layer is framework code, so it resolves the full host lens\n// (page items, chrome, appearances…). Same runtime token as the public one,\n// only the type differs. App code never imports this.\nimport {\n AnnotationToken as AnnotationHostToken,\n previewBucket,\n} from '@embedpdf/plugin-annotation/contract/host';\nimport { InteractionToken } from '@embedpdf/plugin-interaction/contract';\nimport { RenderToken } from '@embedpdf/plugin-render/contract/host';\nimport {\n annotationChromePaint,\n annotationDrawingOf,\n bakedAppearanceOf,\n chromeInPixels,\n createShownUrls,\n createTextBoxEditorFollower,\n editingTextKeyOf,\n enrichCommentThreads,\n frameInPixels,\n ghostOpacity,\n installFilePickerProvider,\n layerTextBoxesOf,\n loadAppearanceUrls,\n loadObjectUrl,\n lookFrameOf,\n pickRequestedFile,\n pictureOrPainting,\n rasterInFrame,\n rectInPixels,\n registerRendererBehaviors,\n sameAnnotationAnchor,\n sceneViewBox,\n shownAppearance,\n svgShapesOf,\n textBoxEditorScaleOf,\n textBoxStyleOf,\n textPlateInPixels,\n type AnnotationChromePaint,\n type AppearanceUrl,\n type FrameFraction,\n} from '@embedpdf/web';\nimport { useEffect, useRef, useState } from 'react';\nimport * as React from 'react';\n\nexport type {\n CreationDraftAnchor,\n RenderItem,\n LineEnding,\n LineEndings,\n Style,\n AnnotationFlags,\n FieldValues,\n TextAlign,\n TextStyle,\n} from '@embedpdf/core-annotation';\nimport { devWarn } from './dev';\nimport { usePaintsPagePart } from './page-layers';\nimport { useAnnotationSettings } from './annotation-hooks';\nimport { INERT } from './inert';\nimport {\n shallowArray,\n useCapability,\n useCapabilityEvent,\n useDocumentId,\n useKernelValue,\n useOptionalCapability,\n useOptionalSelector,\n usePage,\n useSelector,\n useViewerSettings,\n} from './runtime';\nimport type { PageContextValue, PageLayout } from './runtime';\nimport { SvgShapes } from './svg-shapes';\n\nexport { useAnnotationSettings, useAnnotationState } from './annotation-hooks';\nexport {\n AnnotationDraftMenu,\n AnnotationMenu,\n AnnotationRotationBadge,\n type AnnotationDraftMenuProps,\n type AnnotationMenuProps,\n type AnnotationRotationBadgeProps,\n} from './annotation-menu';\n\n// ── renderers ────────────────────────────────────────────────────────────────\n\n/** The box a renderer draws into: the size to draw at, how it's turned, and how it's scaled. */\nexport interface AnnotationFrame {\n /** Its width in pixels at the annotation's 100% size, before its turn: draw at this. */\n width: number;\n /** Its height in pixels at the annotation's 100% size, before its turn: draw at this. */\n height: number;\n /**\n * How it's turned on screen, degrees clockwise: the page's turn and the\n * annotation's own. 0 is upright; turn your content by `-rotation` to keep\n * it upright.\n */\n rotation: number;\n /**\n * How much the layer scales what you draw, with the page: the zoom, or for\n * an annotation that keeps its size on screen, the zoom up to 1.\n */\n scale: number;\n}\n\n/**\n * What a renderer's component gets: the annotation, the frame to draw into,\n * and the layer's own drawing of it to keep or wrap. The layer keeps handling\n * the pointer (select, move, resize) unless the renderer is `interactive`.\n */\nexport interface AnnotationRendererProps {\n /** The annotation, as `get()` returns it. */\n annotation: Annotation;\n /**\n * The box you draw into. The layer places, turns and scales it like the\n * annotation's own drawing, also during a drag, a resize or a turn. Fill it\n * (`width: 100%; height: 100%`) and draw at the annotation's 100% size: your\n * text and borders scale with the page.\n */\n frame: AnnotationFrame;\n /** The layer's own drawing of it, filling the frame. Render it to keep the original look and add to it. */\n native: React.ReactNode;\n /** The engine's picture of the annotation as an image (`url`), or `null`. `native` draws it in place. */\n appearance: { url: string } | null;\n /** True while the pointer is over it. */\n hovered: boolean;\n /** True while it's selected. */\n selected: boolean;\n /** True when what you draw takes the pointer (see `interactive` on the renderer). */\n interactive: boolean;\n}\n\n/**\n * What a sibling plugin's renderer gets for the annotations its behavior owns\n * (the form plugin's fill controls). It places its own controls: `item` is the\n * layer's projection of the annotation (its box, style, text and raster box,\n * in page coordinates), and `page.transform.toPixels()` turns those into the\n * layer's pixels.\n */\nexport interface BehaviorRendererProps {\n annotation: Annotation;\n item: RenderItem;\n page: PageContextValue;\n /** The layer's own drawing of it, where the layer draws it. */\n native: React.ReactNode;\n hovered: boolean;\n selected: boolean;\n interactive: boolean;\n}\n\n/** What an `interactive` function is asked: the annotation, and the active tool. */\nexport interface AnnotationInteractiveContext {\n annotation: Annotation;\n toolId: string;\n}\n\n/**\n * One rule: \"draw these annotations with this component\". `for` gets the\n * annotation with all its fields; the first renderer that matches wins.\n * Without `interactive` the component only draws: the layer keeps handling\n * the pointer. With `interactive` (or a function asked whenever it matters)\n * the component takes the pointer, and the annotation can't be selected or\n * moved while it does.\n *\n * Define the list once, outside your component or in `useMemo`: the layer\n * registers each entry, and a new list every render registers them again.\n *\n * `{ behavior, component }` draws what a sibling plugin's behavior owns (the\n * form plugin's fill controls); the plugin decides when it's engaged.\n */\nexport type AnnotationRenderer =\n | { behavior: string; component: React.ComponentType<BehaviorRendererProps> }\n | {\n /** A stable id for the registration (optional; generated). */\n id?: string;\n for: (annotation: Annotation) => boolean;\n component: React.ComponentType<AnnotationRendererProps>;\n interactive?: boolean | ((context: AnnotationInteractiveContext) => boolean);\n /**\n * Scale what you draw with the page (the default): you draw at the\n * annotation's 100% size. `false`: you draw at its size on screen, and\n * size things yourself from `frame.scale`.\n */\n scale?: boolean;\n };\n\n/** What a handle component you draw yourself gets. */\nexport interface HandleProps {\n /** The handle's center, in pixels on the page. */\n at: Point;\n /** The `size` from the settings, px. */\n size: number;\n /** The selection's rotation (degrees clockwise), so a square handle can turn with it. */\n rotation: number;\n /** A box's `'corner'` or `'side'`, or one `'point'` of a line or a polygon. */\n kind: HandleRole;\n /** True while it's being dragged. */\n active: boolean;\n}\n\n/** What a rotation handle component gets: a handle's props, and where its stalk starts on the box. */\nexport interface RotationHandleProps extends Omit<HandleProps, 'kind'> {\n /** Where the stalk starts on the box, in pixels on the page. */\n from: Point;\n}\n\n/** Your own handles, drawn in place of the layer's. The viewer still decides where they can be grabbed. */\nexport interface AnnotationLayerComponents {\n Handle?: React.ComponentType<HandleProps>;\n RotationHandle?: React.ComponentType<RotationHandleProps>;\n}\n\nexport interface AnnotationLayerProps {\n /** Your own look for some annotations ({@link AnnotationRenderer}). */\n renderers?: AnnotationRenderer[];\n /** Your own handles and rotation handle. */\n components?: AnnotationLayerComponents;\n}\n\n/** How much the layer scales the look around it: 1 outside a look, or in one drawn at its size on screen. */\nconst LookScaleContext = React.createContext(1);\n\n/**\n * The box an annotation draws into, placed, sized and turned like the\n * annotation (`item.frame`) inside the page layer, which the page itself\n * turns. The annotation's own drawing and any look of yours draw inside it.\n */\nfunction AnnotationFrame({\n item,\n page,\n interactive = false,\n inert = false,\n children,\n}: {\n item: RenderItem;\n page: PageContextValue;\n interactive?: boolean;\n inert?: boolean;\n children: React.ReactNode;\n}) {\n const box = frameInPixels(item.frame, page.transform);\n return (\n <div\n {...(inert ? INERT : {})}\n style={{\n position: 'absolute',\n left: box.left,\n top: box.top,\n width: box.width,\n height: box.height,\n transform: box.transform,\n transformOrigin: 'center',\n // On the frame: a turned frame groups what is inside it, so blending on\n // an inner element would stop blending with the page.\n mixBlendMode: item.blend,\n // An interactive renderer takes the pointer: the layer's own `none` ends here.\n pointerEvents: interactive ? 'auto' : 'none',\n }}\n >\n {children}\n </div>\n );\n}\n\n/** SVG attribute names as React props: `stroke-width` is `strokeWidth`. */\n/**\n * The scene, filling the item's frame: drawn upright in it, the frame turns\n * it. The core computed the box and the painted scene; `@embedpdf/web`\n * describes each scene node as one SVG element, so there is no per-kind\n * logic and no bounds math here.\n */\nfunction Shape({ item }: { item: RenderItem }) {\n // Nothing to draw until the annotation has area (the 0×0 draft at mouse-down).\n const viewBox = sceneViewBox(item.box);\n if (!viewBox) return null;\n return (\n <svg\n viewBox={viewBox}\n style={{\n position: 'absolute',\n left: 0,\n top: 0,\n width: '100%',\n height: '100%',\n overflow: 'visible',\n pointerEvents: 'none',\n // A ghost is see-through as a whole, so its fill and stroke don't stack.\n ...(item.source === 'ghost' ? { opacity: ghostOpacity(item.ghostOpacity ?? 0.5) } : {}),\n }}\n >\n <SvgShapes shapes={svgShapesOf(scene(item), { miterLimit: MITER_LIMIT })} />\n </svg>\n );\n}\n\n/** The engine's raster inside the item's frame, where `item.raster` puts it, at any frame size. */\nfunction BakedImage({ url, box }: { url: string; box: FrameFraction }) {\n return (\n <img\n src={url}\n alt=\"\"\n draggable={false}\n style={{\n position: 'absolute',\n left: box.left,\n top: box.top,\n width: box.width,\n height: box.height,\n // The AP box is sized in content units; a global `img { max-width: 100% }`\n // reset would otherwise clamp it to the containing block and distort the\n // aspect. This bites specifically when the box is wider than that block —\n // a landscape stamp whose unrotated box overhangs a view-rotated (portrait)\n // page — so honour the explicit size.\n maxWidth: 'none',\n maxHeight: 'none',\n pointerEvents: 'none',\n // The turn the engine took out of the raster, put back about its middle.\n transform: box.transform,\n transformOrigin: 'center',\n }}\n />\n );\n}\n\n/**\n * The armed stamp's ghost: a see-through render of the payload drawn in the\n * exact box a click would place it (the plugin computes it with the same fit\n * + clamp as placement). Every other tool's ghost rides `pageItems` like a\n * drawing in progress. The preview bytes live in the capability closure; this\n * layer owns only the object-URL lifetime, keyed on the armed stamp — a new\n * arm swaps the image, a disarm (or tool change) drops it.\n */\nfunction ToolGhostImage({ page }: { page: PageContextValue }) {\n const anno = useCapability(AnnotationHostToken);\n const ghost = useSelector(AnnotationHostToken, (annotation) =>\n annotation.getImageGhost(page.ref),\n );\n const armed = useSelector(AnnotationHostToken, (annotation) => annotation.getArmedStamp());\n const [url, setUrl] = useState<string | null>(null);\n // The ghost is a bitmap of vector artwork, right at one size: ask for the\n // bucket that covers the box's device width (points × device px per point),\n // so it stays sharp at every zoom and density. The plugin caches per bucket.\n const bucket = ghost ? previewBucket(ghost.box.width * page.transform.renderScale) : 0;\n\n useEffect(() => {\n if (!bucket) {\n setUrl(null);\n return;\n }\n // The previous bucket's image stays up until this one resolves: no\n // flicker while a zoom crosses a bucket boundary.\n return loadObjectUrl(() => anno.renderArmedStampPreview(bucket), setUrl);\n }, [anno, armed, bucket]);\n\n if (!ghost || !url) return null;\n const frame = rectInPixels(ghost.box, page.transform);\n return (\n <img\n src={url}\n alt=\"\"\n draggable={false}\n style={{\n position: 'absolute',\n left: frame.left,\n top: frame.top,\n width: frame.width,\n height: frame.height,\n // Same explicit-size rule as BakedImage: never let a global img reset\n // clamp the box and distort the aspect.\n maxWidth: 'none',\n maxHeight: 'none',\n pointerEvents: 'none',\n opacity: ghostOpacity(ghost.opacity),\n ...(ghost.rot ? { transform: `rotate(${ghost.rot}deg)`, transformOrigin: 'center' } : {}),\n }}\n />\n );\n}\n\n// ── the selection's chrome ───────────────────────────────────────────────────\n\n/** The chrome settings, painted: follows the settings and the viewer's accent live. */\nfunction useChromePaint(): { chrome: ChromeSettings; painted: AnnotationChromePaint } {\n const chrome = useAnnotationSettings((settings) => settings.chrome);\n const accent = useViewerSettings((settings) => settings.accent);\n const painted = React.useMemo(() => annotationChromePaint(chrome, accent), [chrome, accent]);\n return { chrome, painted };\n}\n\n/** A handle as the layer draws it: a square or a circle, `size` px across. */\nfunction DefaultHandle({\n at,\n size,\n rotation,\n shape,\n style,\n}: {\n at: Point;\n size: number;\n rotation: number;\n shape: 'square' | 'circle';\n style: React.CSSProperties;\n}) {\n if (shape === 'circle') {\n return <circle cx={at.x} cy={at.y} r={size / 2} strokeWidth={1.5} style={style} />;\n }\n return (\n <rect\n x={at.x - size / 2}\n y={at.y - size / 2}\n width={size}\n height={size}\n strokeWidth={1.5}\n style={style}\n // The square rides a rotated box's orientation (spin about itself).\n {...(rotation ? { transform: `rotate(${rotation} ${at.x} ${at.y})` } : {})}\n />\n );\n}\n\nfunction Chrome({\n page,\n components,\n}: {\n page: PageContextValue;\n components?: AnnotationLayerComponents;\n}) {\n // The page's view scale converts the screen-pixel chrome settings into\n // content units inside the plugin (rotation handle offset, grab zones):\n // screen-constant at every zoom. What this draws is in screen pixels already.\n const scale = page.transform.viewScale;\n const rotation = page.transform.rotation;\n const zoom = page.transform.zoom;\n const nodes = useSelector(\n AnnotationHostToken,\n (annotation) => annotation.listChromeNodes(page.ref, scale, rotation, zoom),\n shallowArray,\n );\n const { chrome, painted } = useChromePaint();\n const Handle = components?.Handle;\n const RotationHandle = components?.RotationHandle;\n // Your own handles draw as HTML over the page; the layer's as SVG.\n const custom: React.ReactNode[] = [];\n const svg = chromeInPixels(nodes, page.transform).map((node, i) => {\n switch (node.kind) {\n case 'handle':\n if (Handle) {\n custom.push(\n <Handle\n key={i}\n at={node.at}\n size={chrome.handles.size}\n rotation={node.rotation}\n kind={node.role}\n active={node.active}\n />,\n );\n return null;\n }\n return (\n <DefaultHandle\n key={i}\n at={node.at}\n size={chrome.handles.size}\n rotation={node.rotation}\n shape={chrome.handles.shape}\n style={painted.handle}\n />\n );\n case 'guide':\n return (\n <line\n key={i}\n x1={node.from.x}\n y1={node.from.y}\n x2={node.to.x}\n y2={node.to.y}\n shapeRendering=\"crispEdges\"\n style={painted.guide}\n />\n );\n case 'turned-outline':\n return <polygon key={i} points={node.points} fill=\"none\" style={painted.outline} />;\n case 'rotation-guides':\n return (\n <g key={i}>\n {node.lines.map((line, j) => (\n <line\n key={j}\n x1={line.from.x}\n y1={line.from.y}\n x2={line.to.x}\n y2={line.to.y}\n opacity={line.opacity}\n style={painted.rotationGuide}\n />\n ))}\n </g>\n );\n case 'rotation-handle':\n if (RotationHandle) {\n custom.push(\n <RotationHandle\n key={i}\n at={node.at}\n from={node.from}\n size={chrome.rotationHandle.size}\n rotation={0}\n active={false}\n />,\n );\n return null;\n }\n return (\n <g key={i}>\n {chrome.rotationHandle.stalk && (\n <line\n x1={node.from.x}\n y1={node.from.y}\n x2={node.at.x}\n y2={node.at.y}\n strokeWidth={1}\n style={{ stroke: painted.rotationHandle.stroke }}\n />\n )}\n <circle\n cx={node.at.x}\n cy={node.at.y}\n r={chrome.rotationHandle.size / 2}\n strokeWidth={1.5}\n style={painted.rotationHandle}\n />\n </g>\n );\n // The box dragged to select keeps its own look (a see-through accent\n // fill, always dashed); the selection outline follows the settings.\n case 'marquee':\n return (\n <rect\n key={i}\n x={node.box.left}\n y={node.box.top}\n width={node.box.width}\n height={node.box.height}\n strokeWidth={1}\n strokeDasharray=\"4 3\"\n style={painted.marquee}\n />\n );\n case 'outline':\n return (\n <rect\n key={i}\n x={node.box.left}\n y={node.box.top}\n width={node.box.width}\n height={node.box.height}\n fill=\"none\"\n style={painted.outline}\n />\n );\n }\n });\n return (\n <>\n <svg style={{ position: 'absolute', inset: 0, overflow: 'visible', pointerEvents: 'none' }}>\n {svg}\n </svg>\n {custom.length > 0 && (\n <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>{custom}</div>\n )}\n </>\n );\n}\n\n// ── text boxes ───────────────────────────────────────────────────────────────\n\n/**\n * Make an element the editor of a text box: `@embedpdf/web`'s text box\n * editor binds it (rich text, focus and `contentEditable` following\n * `item.editing`, presses kept inside), and its follower attaches again for\n * another element or document and hands it the item and the scale. Returns\n * the ref callback for the element.\n */\nfunction useTextBoxEditor(\n item: TextItem | null,\n scale: number,\n): (element: HTMLElement | null) => void {\n const anno = useCapability(AnnotationHostToken);\n const [element, setElement] = useState<HTMLElement | null>(null);\n const [follower] = useState(() => createTextBoxEditorFollower<AnnotationRef>());\n // On every item or scale change too: the editor redraws only when the text differs.\n useEffect(\n () => follower.follow(element, anno, item, scale),\n [follower, anno, element, item, scale],\n );\n useEffect(() => () => follower.detach(), [follower]);\n return setElement;\n}\n\n/** A free text annotation: the same styled element for reading and typing. */\nfunction FreeText({ item, page }: { item: TextItem; page: PageContextValue }) {\n // The element is the engine's text plate: the box inset by its padding.\n const plate = textPlateInPixels(item, page.transform);\n const ref = useTextBoxEditor(item, plate.scale);\n const { painted } = useChromePaint();\n return (\n <div\n ref={ref}\n suppressContentEditableWarning\n style={{\n position: 'absolute',\n left: plate.left,\n top: plate.top,\n width: plate.width,\n // Fixed to the plate: the box never grows with its text; it scrolls\n // while typing and clips otherwise, where the baked /AP clips.\n height: plate.height,\n ...textBoxStyleOf(item.css, plate.scale),\n boxSizing: 'border-box',\n // The box's fill and border are the vector scene's, under this layer.\n background: 'transparent',\n whiteSpace: 'pre-wrap',\n overflowWrap: 'break-word',\n overflowY: item.editing ? 'auto' : 'hidden',\n overflowX: 'hidden',\n outline: item.editing ? `1px solid ${painted.textOutline}` : 'none',\n cursor: item.editing ? 'text' : 'default',\n // A plain text box turns about its centre, as the baked /AP does.\n ...(item.rot ? { transform: `rotate(${item.rot}deg)`, transformOrigin: 'center' } : {}),\n // Not typing: clicks fall through to the shapes (select, move, resize).\n pointerEvents: item.editing ? 'auto' : 'none',\n }}\n />\n );\n}\n\n/** What `useRichTextEditor()` gives the element you draw a text box with. */\nexport interface RichTextEditor {\n /** Put it on your element: it becomes the editor. */\n ref: (element: HTMLElement | null) => void;\n /** The box's body style as CSS: font, size, color and alignment. While typing it takes the pointer too. */\n style: React.CSSProperties;\n /** True while someone types in the box. */\n editing: boolean;\n}\n\nconst NO_STYLE: React.CSSProperties = {};\n\n/**\n * Make your own element the editor of a text box you draw yourself (a\n * renderer for free text): it draws the runs, turns typing back into runs,\n * keeps the caret when the style changes, and handles pasting, input methods\n * and the format shortcuts. The formatting calls (`text.toggleFormat`,\n * `selection.update`) work on it as they do on the built-in one.\n */\nexport function useRichTextEditor(annotation: Annotation): RichTextEditor {\n const page = usePage();\n const zoom = page.transform.zoom;\n const rotation = page.transform.rotation;\n const key = annotationKey(annotation.ref);\n const item = useOptionalSelector(\n AnnotationHostToken,\n (anno) =>\n anno\n .listTextItems(page.ref, { zoom, rotation })\n .find((text) => text.ref !== null && annotationKey(text.ref) === key) ?? null,\n null,\n );\n // Pixels per point where the element is: inside a scaled look, at the\n // annotation's 100% size; the look's scale does the rest.\n const scale = textBoxEditorScaleOf(item, page.transform, React.useContext(LookScaleContext));\n const ref = useTextBoxEditor(item, scale);\n // While typing, the element takes the pointer (the caret, a drag over words).\n const style = React.useMemo<React.CSSProperties>(\n () =>\n item\n ? { ...textBoxStyleOf(item.css, scale), ...(item.editing ? { pointerEvents: 'auto' } : {}) }\n : NO_STYLE,\n [item, scale],\n );\n return { ref, style, editing: item?.editing ?? false };\n}\n\n// ── renderers that take the pointer ──────────────────────────────────────────\n\n/**\n * Register the behaviors this layer's `interactive` renderers need, through\n * `@embedpdf/web`'s `registerRendererBehaviors`: counted per capability and\n * entry, since the layer mounts once per page. Entry identity is the key,\n * hence the \"define entries outside render\" rule on {@link AnnotationRenderer}.\n * Once they are registered the layer draws again: its drawings ask them.\n */\nfunction useRendererBehaviors(\n anno: Parameters<typeof registerRendererBehaviors<Annotation>>[0],\n activeToolId: () => string,\n renderers?: AnnotationRenderer[],\n): void {\n const toolRef = useRef(activeToolId);\n toolRef.current = activeToolId;\n const [, setRegistrations] = useState(0);\n useEffect(() => {\n if (!renderers) return;\n const release = registerRendererBehaviors(anno, renderers, () => toolRef.current());\n setRegistrations((count) => count + 1);\n return release;\n }, [anno, renderers]);\n}\n\n/**\n * Draws a page's annotations, the selection's outline and handles, the tool's\n * preview and the text boxes being typed in. Put it above the rendered page:\n * while it's there, the render layer leaves the annotations out of the\n * page's picture.\n */\nexport function AnnotationLayer({ renderers, components }: AnnotationLayerProps = {}) {\n const page = usePage();\n const anno = useCapability(AnnotationHostToken);\n // The active tool decides which interactive renderers take the pointer, so\n // a tool change repaints the layer (`interactive` functions read it live).\n useOptionalSelector(InteractionToken, (interaction) => interaction.getActiveToolId(), '');\n const interaction = useOptionalCapability(InteractionToken);\n // The page's view env (relative zoom + total display rotation) projects\n // screen-anchored (`noZoom`/`noRotate`) annotations to their effective\n // footprint inside the plugin: no flag logic lives in the framework.\n // `transform.zoom` (not `viewScale`): 1 = the page's physical 100%.\n const viewZoom = page.transform.zoom;\n const viewRotation = page.transform.rotation;\n const items = useSelector(\n AnnotationHostToken,\n (annotation) => annotation.listPageItems(page.ref, { zoom: viewZoom, rotation: viewRotation }),\n shallowArray,\n );\n const texts = useSelector(\n AnnotationHostToken,\n (annotation) => annotation.listTextItems(page.ref, { zoom: viewZoom, rotation: viewRotation }),\n shallowArray,\n );\n // `null` until the page's first pictures arrive.\n const [urls, setUrls] = useState<Record<string, AppearanceUrl> | null>(null);\n // The pictures shown stay valid until the next ones are shown.\n const [shown] = useState(createShownUrls);\n useEffect(() => () => shown.release(), [shown]);\n useRendererBehaviors(anno, () => (interaction?.getActiveToolId() as string) ?? '', renderers);\n usePaintsPagePart(page.ref, 'annotations');\n // Entry identity keys the behavior registration, so an inline `renderers`\n // array registers again on every render. Detect it once: a fresh array\n // whose entries are the previous ones.\n const previousRenderers = useRef(renderers);\n if (\n renderers &&\n previousRenderers.current &&\n renderers !== previousRenderers.current &&\n shallowArray(renderers, previousRenderers.current)\n ) {\n devWarn(\n 'annotation-renderers-inline',\n '<AnnotationLayer renderers> was given a new array with the same entries — define it ' +\n 'outside render (module scope or useMemo), because entry identity keys the behavior registration.',\n );\n }\n previousRenderers.current = renderers;\n\n // Baked annotations render from engine rasters: fetch again when the\n // page's baked set or an /AP version changes (a freshly placed stamp, a\n // resize whose re-bake resolved), and at appearance-scale crossings. A move\n // or a turn leaves the epoch as it is (the blit repositions the same\n // pixels), and live gestures don't touch it either: no mid-drag fetches.\n const bakedKey = useSelector(AnnotationHostToken, (annotation) =>\n annotation.getAppearanceEpoch(page.ref),\n );\n // The appearance scale follows the document's render policy: zoom ticks\n // inside an appearance-lattice rung re-bake nothing; crossing 1→2 re-bakes\n // once. Without the render plugin, only this session's pictures load.\n const bakeScale = useOptionalSelector(\n RenderToken,\n (render) => render.getAppearanceScale(page.transform.renderScale),\n page.transform.renderScale,\n );\n\n useEffect(\n () =>\n loadAppearanceUrls(\n shown,\n (signal) => anno.renderAppearances(page.ref, bakeScale, signal),\n annotationKey,\n setUrls,\n ),\n [shown, anno, page.ref, bakeScale, bakedKey],\n );\n\n /** The text box being typed in, by key. */\n const editingKey = editingTextKeyOf(texts, annotationKey);\n\n return (\n <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>\n {items.map((item) => {\n // The default look, inside the item's frame: the engine's raster where\n // the core places it (following a move as it happens), or the scene.\n const state = item.annotation?.appearanceState ?? null;\n const shows = pictureOrPainting({\n pending: item.source !== 'baked',\n picture: urls && shownAppearance(urls, item.id, state),\n version: item.pictureVersion ?? 0,\n loaded: urls !== null,\n paint: () => (hasLiveDrawing(item) ? item : null),\n });\n const native: React.ReactNode =\n shows?.kind === 'painting' ? (\n // shapes, cloudy, markup: all painted via scene()\n <Shape item={item} />\n ) : shows?.kind === 'picture' && item.raster ? (\n <BakedImage url={shows.picture.url} box={rasterInFrame(item.raster, item.frame)} />\n ) : null;\n const framed = (\n content: React.ReactNode,\n options?: { interactive?: boolean; inert?: boolean },\n ) => (\n <AnnotationFrame key={item.id} item={item} page={page} {...options}>\n {content}\n </AnnotationFrame>\n );\n const annotation = item.annotation;\n if (!annotation) return framed(native);\n /** Your look in the frame: drawn at the annotation's 100% size and scaled with the page, unless it opts out. */\n const look = (\n entry: Extract<AnnotationRenderer, { for: unknown }>,\n interactive: boolean,\n ): React.ReactNode => {\n const pixels = frameInPixels(item.frame, page.transform);\n const scaled = entry.scale !== false;\n const Look = entry.component;\n const drawn = (\n <Look\n annotation={annotation}\n frame={lookFrameOf(pixels, scaled)}\n native={native}\n appearance={urls && bakedAppearanceOf(urls, item.id, state)}\n hovered={item.hovered ?? false}\n selected={item.selected}\n interactive={interactive}\n />\n );\n if (!scaled) return drawn;\n return (\n <div\n style={{\n position: 'absolute',\n left: 0,\n top: 0,\n width: pixels.design.width,\n height: pixels.design.height,\n transform: `scale(${pixels.scale})`,\n transformOrigin: '0 0',\n }}\n >\n <LookScaleContext.Provider value={pixels.scale}>{drawn}</LookScaleContext.Provider>\n </div>\n );\n };\n\n // Ownership beats looks: an engaged behavior's renderer is\n // authoritative (form fill controls own their DOM); `for` rules apply\n // only to what the layer owns, and draw without the pointer. While its\n // text box is typed in, a look's editor (`useRichTextEditor`) takes\n // the keys: an inert subtree can't.\n const typing = editingKey !== null && annotationKey(annotation.ref) === editingKey;\n const drawing = annotationDrawingOf(annotation, anno, renderers, typing);\n switch (drawing.kind) {\n case 'owned': {\n // Its controls place themselves in the layer; the native drawing keeps its frame.\n const Owner = drawing.entry.component;\n return (\n <Owner\n key={item.id}\n annotation={annotation}\n item={item}\n page={page}\n native={framed(native)}\n hovered={item.hovered ?? false}\n selected={item.selected}\n interactive\n />\n );\n }\n case 'look':\n return framed(look(drawing.entry, drawing.interactive), {\n interactive: drawing.interactive,\n inert: drawing.inert,\n });\n case 'native':\n // Inert when an engaged behavior has no renderer of yours: its\n // plugin owns the input (a link's anchor takes the click), and the\n // annotation keeps its own look.\n return framed(native, { inert: drawing.inert });\n }\n })}\n {/* A text box your renderer draws is edited there (`useRichTextEditor`). */}\n {layerTextBoxesOf(texts, items, renderers, annotationKey).map((text) => (\n <FreeText key={text.id} item={text} page={page} />\n ))}\n <ToolGhostImage page={page} />\n <Chrome page={page} components={components} />\n </div>\n );\n}\n\n/**\n * The default file-picker provider: the built-in file dialog (from\n * `@embedpdf/web`), honouring the tool's `accept` filter. This is the adapter\n * fulfilling the plugin's DOM-free port — the dialog lives in the framework\n * layer, never in the plugin.\n */\nexport const filePickerProvider: FilePickerProvider = pickRequestedFile;\n\n/**\n * Install the file-picker provider for the active document — the one port\n * behind every click-then-pick tool (a stamp `'prompt'` source, the file-\n * attachment tool). Call once at a document-scoped spot (not inside\n * `<AnnotationLayer>`, which is per page). Defaults to\n * {@link filePickerProvider}, so a bare `useFilePickerProvider()` makes all of\n * them work out of the box; pass a custom provider (asset library, cloud\n * drive — switch on `req.subtype` / `req.toolId`) or `null` to make\n * click-then-pick tools inert. Cleared on unmount.\n */\nexport function useFilePickerProvider(\n provider: FilePickerProvider | null = filePickerProvider,\n): void {\n const anno = useOptionalCapability(AnnotationToken);\n useEffect(() => {\n if (!anno) return;\n // One port per document: a second caller silently replaces the first.\n return installFilePickerProvider(anno, provider, () =>\n devWarn(\n 'file-picker-provider-twice',\n 'useFilePickerProvider() is called from two mounted components for the same document — ' +\n 'the later one wins. Call it once, at a document-scoped spot.',\n ),\n );\n }, [anno, provider]);\n}\n\nexport function useAnnotation(): AnnotationCapability {\n return useCapability(AnnotationToken);\n}\n\n/** Listen to one annotation event while the component is mounted: `useAnnotationEvent((annotation) => annotation.onCreated, handler)`. */\nexport function useAnnotationEvent<T>(\n select: (annotation: AnnotationCapability) => EventHook<T>,\n handler: (event: T) => void,\n): void {\n useCapabilityEvent(AnnotationToken, select, handler);\n}\n\nconst NO_ANNOTATIONS: readonly Annotation[] = [];\n\n/**\n * The annotations matching `filter` (some pages, one kind), in drawing order,\n * as the user sees them; the same array while they stay the same. Empty\n * without a document.\n */\nexport function useAnnotationList(filter?: AnnotationFilter): readonly Annotation[] {\n const key = filter\n ? `${(filter.pages ?? [])\n .map((page) => (typeof page === 'number' ? `#${page}` : page.objectNumber))\n .join(',')}|${filter.pages ? 'p' : ''}|${filter.subtype ?? ''}`\n : '';\n // Keyed by value, so an inline filter object never subscribes again.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const stable = React.useMemo(() => filter, [key]);\n return useOptionalSelector(\n AnnotationToken,\n (annotation) => annotation.list(stable),\n NO_ANNOTATIONS,\n shallowArray,\n );\n}\n\nconst NO_DEFAULTS: ToolDefaults = {};\n\n/**\n * A tool's defaults: the fields its next annotation starts with, over the\n * engine's. The component re-renders when they change, so a color picker\n * always shows the current color. Empty without a document.\n */\nexport function useAnnotationDefaults(toolId: string): ToolDefaults {\n return useOptionalSelector(\n AnnotationToken,\n (annotation) => annotation.tools.getDefaults(toolId),\n NO_DEFAULTS,\n );\n}\n\nconst NO_PROPERTIES: AnnotationProperties = { properties: [], values: {}, mixed: [] };\n\n/**\n * What a style panel shows: the selection's properties (`selection.getProperties()`),\n * or, given a tool id, the tool's (`tools.getProperties(id)`). The component\n * re-renders when they change. Empty without a document.\n */\nexport function useAnnotationProperties(toolId?: string): AnnotationProperties {\n return useOptionalSelector(\n AnnotationToken,\n (annotation) =>\n toolId === undefined\n ? annotation.selection.getProperties()\n : annotation.tools.getProperties(toolId),\n NO_PROPERTIES,\n );\n}\n\n/**\n * An anchor for `<Anchored>` that keeps a card or a badge attached to one\n * annotation: its page and the box around what it shows, following a move\n * as it happens. `null` for `null`, or an annotation that isn't here. The\n * component re-renders when the annotation moves, not while people scroll or\n * zoom: a note that keeps its size on screen hands `<Anchored>` its\n * `boundsIn`.\n */\nexport function useAnnotationAnchor(ref: AnnotationRef | null): AnnotationAnchor | null {\n const key = ref ? annotationKey(ref) : null;\n // Keyed by value, so an inline ref never subscribes again.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const stable = React.useMemo(() => ref, [key]);\n return useOptionalSelector(\n AnnotationHostToken,\n (annotation) => (stable ? annotation.getAnnotationAnchor(stable) : null),\n null,\n sameAnnotationAnchor,\n );\n}\n\n// ── Comments (the conversation plane) ────────────────────────────────────────\n\n/**\n * A {@link CommentThread} enriched with its page's live display position —\n * the framework-layer join (`enrichCommentThreads` in `@embedpdf/web`).\n * Identity stays `page` (like every annotation surface); these two fields\n * are presentation, tracking page moves and deletes.\n */\nexport interface CommentThreadView extends CommentThread {\n /** Current 0-based display index of the thread's page; `-1` when the page\n * is no longer in the document (one-frame teardown race on delete). */\n pageIndex: number;\n /** The page's `/PageLabels` label when the PDF declares one (\"iv\", \"A-2\"),\n * else the 1-based position as a string — print it verbatim. */\n pageLabel: string;\n}\n\n/** The comments API: the `comments` part of `useAnnotation()`. Pair it with\n * {@link useCommentThreads} for the threads to show. */\nexport function useComments(): CommentsApi {\n return useCapability(AnnotationToken).comments;\n}\n\nconst EMPTY_PAGES: readonly PageLayout[] = [];\nconst NO_THREADS: readonly CommentThread[] = [];\n\n/**\n * Every comment thread in the document, display-ordered (page position →\n * top of page → creation date) and enriched with `pageIndex`/`pageLabel`.\n * Subscribed to both stores: annotation writes (own, remote, hydration)\n * recompute the threads; page moves/deletes re-run the join. Reference-\n * stable between changes — safe to memo child renders on the array.\n */\nexport function useCommentThreads(): CommentThreadView[] {\n const docId = useDocumentId();\n const threads = useOptionalSelector(\n AnnotationToken,\n (annotation) => annotation.comments.listThreads(),\n NO_THREADS,\n );\n const pages = useKernelValue((kernel) =>\n docId ? kernel.documents.listPages(docId) : EMPTY_PAGES,\n );\n return React.useMemo(() => enrichCommentThreads(threads, pages), [threads, pages]);\n}\n\n/** The enriched thread containing any member ref (root, reply, grouped part,\n * state annotation), or null. */\nexport function useCommentThread(ref: AnnotationRef | null): CommentThreadView | null {\n const views = useCommentThreads();\n const api = useOptionalCapability(AnnotationToken);\n if (ref == null || !api) return null;\n const thread = api.comments.getThread(ref);\n if (!thread) return null;\n return (\n views.find((view) => annotationKey(view.root.ref) === annotationKey(thread.root.ref)) ?? null\n );\n}\n"],"mappings":"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"}