@nulib/clover 4.1.0 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (345) hide show
  1. package/README.md +1 -1
  2. package/dist/components/Body/useControlsVisibility.mjs +35 -13
  3. package/dist/components/Canvas/CanvasView.mjs +33 -4
  4. package/dist/components/Canvas/ChaptersMenu.mjs +6 -1
  5. package/dist/components/Canvas/ControlMenu.mjs +9 -2
  6. package/dist/components/Canvas/Controls.mjs +17 -4
  7. package/dist/components/Canvas/FrameAnimation.mjs +3 -0
  8. package/dist/components/Canvas/ImageControls.mjs +8 -3
  9. package/dist/components/Canvas/Placeholder.mjs +5 -2
  10. package/dist/components/Canvas/RowFits.mjs +3 -1
  11. package/dist/components/Canvas/media/MediaBody.mjs +3 -0
  12. package/dist/components/Canvas/media/Player.mjs +3 -0
  13. package/dist/components/Canvas/media/Transport.mjs +3 -0
  14. package/dist/components/Canvas/media/useMediaElement.mjs +32 -9
  15. package/dist/components/Items/masonry.mjs +2 -0
  16. package/dist/components/Map/MapView.mjs +42 -2
  17. package/dist/components/Map/maplibre-sheet.mjs +5 -0
  18. package/dist/components/Map/sheet.mjs +19 -0
  19. package/dist/components/Map/worker.mjs +28 -1
  20. package/dist/components/Panel/Panel.mjs +47 -59
  21. package/dist/components/Panel/sections.mjs +62 -0
  22. package/dist/components/Scene/SceneView.mjs +3 -0
  23. package/dist/core/content-state.mjs +1 -11
  24. package/dist/core/load.mjs +9 -1
  25. package/dist/core/presentation.mjs +4 -5
  26. package/dist/core/sanitize.mjs +15 -3
  27. package/dist/core/svg-shape.mjs +2 -1
  28. package/dist/core/thumbnail.mjs +15 -4
  29. package/dist/core/trusted.mjs +26 -0
  30. package/dist/core/vtt.mjs +20 -9
  31. package/dist/index.d.mts +269 -6
  32. package/dist/index.mjs +13 -0
  33. package/dist/lib/pointer.mjs +1 -1
  34. package/dist/lib/renderer/CanvasRenderer.mjs +48 -7
  35. package/dist/lib/renderer/camera/CameraAnimator.mjs +39 -20
  36. package/dist/lib/renderer/input/GestureController.mjs +15 -5
  37. package/dist/map/index.d.mts +6 -1
  38. package/dist/styles/collection-select.css +1 -0
  39. package/dist/styles/core.css +1 -0
  40. package/dist/styles/default.css +1 -0
  41. package/dist/styles/items.css +1 -0
  42. package/dist/styles/map.css +1 -0
  43. package/dist/styles/media.css +1 -0
  44. package/dist/styles/panel.css +1 -0
  45. package/dist/styles/scene.css +1 -0
  46. package/dist/styles/split.css +1 -0
  47. package/dist/styles.css +1 -1
  48. package/dist/templates/default/Default.mjs +7 -0
  49. package/dist/templates/document/Document.mjs +22 -3
  50. package/dist/templates/document/Sheets.mjs +2 -0
  51. package/dist/templates/gallery/Gallery.mjs +7 -1
  52. package/dist/templates/index.d.mts +167 -6
  53. package/dist/templates/shared/Lightbox.mjs +50 -3
  54. package/dist/templates/shared/LightboxView.mjs +8 -1
  55. package/dist/templates/shared/PanelPane.mjs +13 -1
  56. package/dist/templates.css +1 -1
  57. package/dist/ui/Button.mjs +3 -1
  58. package/dist/ui/ControlCluster.mjs +6 -3
  59. package/dist/ui/Markup.mjs +8 -7
  60. package/dist/ui/Tip.mjs +6 -1
  61. package/dist/ui/adoptSheet.mjs +19 -0
  62. package/dist/ui/sheets/map.mjs +5 -0
  63. package/dist/ui/sheets/media.mjs +5 -0
  64. package/dist/ui/sheets/scene.mjs +5 -0
  65. package/dist/web-components/{About-DvyvVUK5.mjs → About-uNCjvWgs.mjs} +1 -1
  66. package/dist/web-components/{AnnotationItems-BpRcSrOM.mjs → AnnotationItems-JwlcCvPo.mjs} +1 -1
  67. package/dist/web-components/{AnnotationMenu-BDPec3iI.mjs → AnnotationMenu-BWyKEyvW.mjs} +1 -1
  68. package/dist/web-components/{AnnotationState-Chs_37Kk.mjs → AnnotationState-Bhqs75Br.mjs} +1 -1
  69. package/dist/web-components/{Annotations-CLPEq7Ro.mjs → Annotations-C7y0N8Lj.mjs} +1 -1
  70. package/dist/web-components/{Annotations-6E-oD_wg.mjs → Annotations-ZwcRh2UE.mjs} +2 -2
  71. package/dist/web-components/{Body-Ct61yxI7.mjs → Body-DyrvRDkt.mjs} +1 -1
  72. package/dist/web-components/{BodyAlert-C_Qh3Up_.mjs → BodyAlert-XV88XjL8.mjs} +1 -1
  73. package/dist/web-components/Button-BIaw5k1q.mjs +1 -0
  74. package/dist/web-components/{Camera-BPyLzZjP.mjs → Camera-7SlnmGtb.mjs} +1 -1
  75. package/dist/web-components/{Canvas2DBackend-8wFavYdl.mjs → Canvas2DBackend-DBGZRGid.mjs} +1 -1
  76. package/dist/web-components/CanvasView-CmDxczm9.mjs +2 -0
  77. package/dist/web-components/{CaptionDetails-DuwS-grE.mjs → CaptionDetails-Bxz8AXMz.mjs} +1 -1
  78. package/dist/web-components/ChaptersMenu-CMQiBqvx.mjs +1 -0
  79. package/dist/web-components/{Chevron-Cyr_cc9X.mjs → Chevron-B3XaClVT.mjs} +1 -1
  80. package/dist/web-components/{ChoiceMenu-ConzybVH.mjs → ChoiceMenu-pugo5zxI.mjs} +1 -1
  81. package/dist/web-components/{Collection-CLayN8sv.mjs → Collection-Ch_FeSKp.mjs} +1 -1
  82. package/dist/web-components/{CollectionSelect-D2d8dGJ4.mjs → CollectionSelect-2jDEkOcK.mjs} +1 -1
  83. package/dist/web-components/{Connected-CBQ6xyhr.mjs → Connected-3hnIPSWM.mjs} +1 -1
  84. package/dist/web-components/{Connected-DMXG3imZ.mjs → Connected-Bne3I5E1.mjs} +1 -1
  85. package/dist/web-components/{Connected-pyd0EBD3.mjs → Connected-DuANHN93.mjs} +1 -1
  86. package/dist/web-components/{Contents-tCMXBYDK.mjs → Contents-DIQrin_-.mjs} +1 -1
  87. package/dist/web-components/ControlMenu-BydnCTTQ.mjs +1 -0
  88. package/dist/web-components/ControlsFade-CleBsk-W.mjs +1 -0
  89. package/dist/web-components/CountMenu-CReBYVwu.mjs +1 -0
  90. package/dist/web-components/Cue-2zGQuUOC.mjs +1 -0
  91. package/dist/web-components/Document-pjc2qOX4.mjs +1 -0
  92. package/dist/web-components/{DomLayers-BxPU05-D.mjs → DomLayers-D9X_FPto.mjs} +1 -1
  93. package/dist/web-components/{Download-Bku9Vptk.mjs → Download-B8MpVqgk.mjs} +1 -1
  94. package/dist/web-components/{EntryBodies-77vDudCb.mjs → EntryBodies-DdpRfU5U.mjs} +1 -1
  95. package/dist/web-components/{EntryThumbnail-BxQWKW6e.mjs → EntryThumbnail-DM7Zjj1z.mjs} +1 -1
  96. package/dist/web-components/{FieldPill-nFGsaru9.mjs → FieldPill-BAql8_6s.mjs} +1 -1
  97. package/dist/web-components/{FrameAnimation-BvKiSXcm.mjs → FrameAnimation-Dj46RxuL.mjs} +1 -1
  98. package/dist/web-components/Gallery-B9FNA02Z.mjs +1 -0
  99. package/dist/web-components/{HideToggle-TEhY4TS4.mjs → HideToggle-duXvDvDw.mjs} +1 -1
  100. package/dist/web-components/ImageControls-DODKjC0d.mjs +1 -0
  101. package/dist/web-components/{Items-CudZ4Lnb.mjs → Items-BHTQJU7T.mjs} +1 -1
  102. package/dist/web-components/{Label-f07N5Fld.mjs → Label-D4dlrtpH.mjs} +1 -1
  103. package/dist/web-components/{LanguageChoice-B5VM21DV.mjs → LanguageChoice-DR3X-dtJ.mjs} +1 -1
  104. package/dist/web-components/LightboxView-D-aBaKfB.mjs +1 -0
  105. package/dist/web-components/{ListEnd-M39M62Cl.mjs → ListEnd-CQ4vX-NW.mjs} +1 -1
  106. package/dist/web-components/{Loaded-oGFyBuos.mjs → Loaded-DsNSPXWf.mjs} +1 -1
  107. package/dist/web-components/{LoadedCanvas-IvpSzPO6.mjs → LoadedCanvas-Cq7_O2bw.mjs} +1 -1
  108. package/dist/web-components/LoadedMap-0_prxuA4.mjs +1 -0
  109. package/dist/web-components/{Loading-YxuKrDAM.mjs → Loading-4PmhMeZ-.mjs} +1 -1
  110. package/dist/web-components/{Map-Cw9j3gi3.mjs → Map-B29Ba50b.mjs} +1 -1
  111. package/dist/web-components/MapView-nHeg39Kz.mjs +3 -0
  112. package/dist/web-components/Markup-BZ7l5GbG.mjs +2 -0
  113. package/dist/web-components/MediaBody-DH-rr_0N.mjs +1 -0
  114. package/dist/web-components/{MediaBody-JnKnoIqY.mjs → MediaBody-eSThjFzH.mjs} +1 -1
  115. package/dist/web-components/{NavDate-BCCOyycx.mjs → NavDate-0MsHRjBW.mjs} +1 -1
  116. package/dist/web-components/{Navigator-Bx4zS0Yr.mjs → Navigator-qJ79A8Nk.mjs} +1 -1
  117. package/dist/web-components/{Pager-B9GvQ64b.mjs → Pager-SPd_u0qz.mjs} +1 -1
  118. package/dist/web-components/{PagerLayout-BF33VZL_.mjs → PagerLayout-CkSwDAnp.mjs} +1 -1
  119. package/dist/web-components/Panel-C8r3EsWn.mjs +1 -0
  120. package/dist/web-components/PanelPart-BA1NoeLA.mjs +1 -0
  121. package/dist/web-components/{PanelToggle-bPcIULGZ.mjs → PanelToggle-CrKP8BqE.mjs} +1 -1
  122. package/dist/web-components/{PartOfManifest-HLg-r00O.mjs → PartOfManifest-BdDSxK4k.mjs} +1 -1
  123. package/dist/web-components/{Pending-BxGjjnqq.mjs → Pending-CmgVU1kF.mjs} +1 -1
  124. package/dist/web-components/{PlaceBox-D-Zhe9-U.mjs → PlaceBox-D7HLNGxE.mjs} +1 -1
  125. package/dist/web-components/Placeholder-DVAlXejQ.mjs +1 -0
  126. package/dist/web-components/{Position-TYnzcm8e.mjs → Position-C6KUAceQ.mjs} +1 -1
  127. package/dist/web-components/{Primitives-C6VJXxZD.mjs → Primitives-ClQVjY6x.mjs} +1 -1
  128. package/dist/web-components/{Provider-DyB0wpeO.mjs → Provider-C0IUdU6v.mjs} +1 -1
  129. package/dist/web-components/{ReadMore-De_0T7lc.mjs → ReadMore-BiEJA4yO.mjs} +1 -1
  130. package/dist/web-components/Root-Drt5N4_s.mjs +1 -0
  131. package/dist/web-components/Scene-C7t16NjC.mjs +1 -0
  132. package/dist/web-components/SceneView-BHg37-rs.mjs +1 -0
  133. package/dist/web-components/{Search-DgT8OPsK.mjs → Search-Bpd_lGzH.mjs} +1 -1
  134. package/dist/web-components/{Sections-d1acn7qm.mjs → Sections-D_bS5IQH.mjs} +1 -1
  135. package/dist/web-components/{StandaloneItems-DUb4YKCB.mjs → StandaloneItems-YV9O9M8F.mjs} +1 -1
  136. package/dist/web-components/{Status-CcU3u6P4.mjs → Status-BCG7AN9B.mjs} +1 -1
  137. package/dist/web-components/{Steps-nlSCzbDQ.mjs → Steps-Dnn8Ajqf.mjs} +1 -1
  138. package/dist/web-components/TargetItems-xxbtePln.mjs +1 -0
  139. package/dist/web-components/Timeline-Danuk_Nn.mjs +1 -0
  140. package/dist/web-components/Tip-DPFWlNLu.mjs +1 -0
  141. package/dist/web-components/{Transcript-bSA3cx_K.mjs → Transcript-C-_DbUO5.mjs} +1 -1
  142. package/dist/web-components/{Transport-DjOYI-fR.mjs → Transport-BKona8RD.mjs} +1 -1
  143. package/dist/web-components/Transport-Bonmu77-.mjs +1 -0
  144. package/dist/web-components/{annotation-collection-D8emkElk.mjs → annotation-collection-nmxzo_hO.mjs} +1 -1
  145. package/dist/web-components/{annotation-name-DbWjhgra.mjs → annotation-name-DoUUo-8D.mjs} +1 -1
  146. package/dist/web-components/{annotations-content-Bg6aVAGC.mjs → annotations-content-Cl1upbdd.mjs} +1 -1
  147. package/dist/web-components/{body-Ct8dmQdW.mjs → body-DC8Oq8rY.mjs} +1 -1
  148. package/dist/web-components/{canvas-goEZLqEd.mjs → canvas-gzoTnBxw.mjs} +1 -1
  149. package/dist/web-components/{cloverEngine-Df7cMwOP.mjs → cloverEngine-CFL1Bd7n.mjs} +1 -1
  150. package/dist/web-components/{content-state-reader-CNmBpG1L.mjs → content-state-reader-DYbmXxCp.mjs} +1 -1
  151. package/dist/web-components/controlGlyphs-d7KUIUwi.mjs +1 -0
  152. package/dist/web-components/{controls-BZr16sYQ.mjs → controls-VC9D1mwr.mjs} +1 -1
  153. package/dist/web-components/custom-elements.json +41 -3
  154. package/dist/web-components/{downloads-EjJ6Hpip.mjs → downloads-D2cnWDbs.mjs} +1 -1
  155. package/dist/web-components/{dragToClose-X9NbZOhA.mjs → dragToClose-CzYeh_12.mjs} +1 -1
  156. package/dist/web-components/{engine-DMoc0tff.mjs → engine-Dcfyp2DV.mjs} +1 -1
  157. package/dist/web-components/{engines-BmB81VXR.mjs → engines-BMr7naGM.mjs} +1 -1
  158. package/dist/web-components/{fetchManifest-CwQC6cCh.mjs → fetchManifest-DxptUh4u.mjs} +1 -1
  159. package/dist/web-components/{fromManifest-DrAmY1lB.mjs → fromManifest-BpPFLVyZ.mjs} +1 -1
  160. package/dist/web-components/{glyphs-BFK_hvJJ.mjs → glyphs-BCnJl8py.mjs} +1 -1
  161. package/dist/web-components/hooks-Dz_5UXXp.mjs +1 -0
  162. package/dist/web-components/{image-layers-D2nQC4R-.mjs → image-layers-BPnq7jk1.mjs} +1 -1
  163. package/dist/web-components/{imageService-iFElsopt.mjs → imageService-DFPkPNfe.mjs} +1 -1
  164. package/dist/web-components/index-ClM6Kq8w.mjs +1 -0
  165. package/dist/web-components/index.d.mts +5 -3
  166. package/dist/web-components/index.mjs +1 -1
  167. package/dist/web-components/items-BHporT5i.mjs +1 -0
  168. package/dist/web-components/{items-BnEnc5ot.mjs → items-D03KhDg6.mjs} +1 -1
  169. package/dist/web-components/label-r0ki6r1U.mjs +1 -0
  170. package/dist/web-components/{layout-Djwu8f4R.mjs → layout-DVa_DnGH.mjs} +1 -1
  171. package/dist/web-components/{link-0lUlTZlw.mjs → link-DxXxMXiw.mjs} +1 -1
  172. package/dist/web-components/logo-Br42Vlsk.mjs +1 -0
  173. package/dist/web-components/maplibre-sheet-CfiZ6JFk.mjs +1 -0
  174. package/dist/web-components/masonry-BZCdA3bV.mjs +1 -0
  175. package/dist/web-components/{models-BF2pqufA.mjs → models-pO77sm3z.mjs} +1 -1
  176. package/dist/web-components/{nodes-ChQRLDGU.mjs → nodes-CmL3eoRE.mjs} +1 -1
  177. package/dist/web-components/{overlayImage-MKrcgDep.mjs → overlayImage-DFGetjMh.mjs} +1 -1
  178. package/dist/web-components/{panel-C13V6w6E.mjs → panel-B1vzUm6_.mjs} +1 -1
  179. package/dist/web-components/part-DmRBh4pf.mjs +1 -0
  180. package/dist/web-components/{playerSurface-DG1XipTq.mjs → playerSurface-CQ1wrIAQ.mjs} +1 -1
  181. package/dist/web-components/pointer-DWnCT3D3.mjs +1 -0
  182. package/dist/web-components/{provider-DiUkZYiW.mjs → provider-U7xzX_0T.mjs} +1 -1
  183. package/dist/web-components/{range-regions-CqGjyM76.mjs → range-regions-Di_lmVqZ.mjs} +1 -1
  184. package/dist/web-components/{read-more-D8RJYdtQ.mjs → read-more-BtA1sriO.mjs} +1 -1
  185. package/dist/web-components/{readingLanguages-BWOLZK2k.mjs → readingLanguages-Ptho-Co9.mjs} +1 -1
  186. package/dist/web-components/rendererSurface-BgZPnAwj.mjs +22 -0
  187. package/dist/web-components/{renderers-LtRX5pT0.mjs → renderers-hoD3WKYA.mjs} +1 -1
  188. package/dist/web-components/{resource-Cfydiy4m.mjs → resource-DuTMsPEj.mjs} +1 -1
  189. package/dist/web-components/{sanitize-qIOeyIww.mjs → sanitize-BedC_UE5.mjs} +3 -3
  190. package/dist/web-components/{save-file-dZyOpXgY.mjs → save-file-CLB5IM4a.mjs} +1 -1
  191. package/dist/web-components/{search-BfUZJM3a.mjs → search-Dd2Y1dsZ.mjs} +1 -1
  192. package/dist/web-components/shared-CCg1Iag8.mjs +1 -0
  193. package/dist/web-components/{show-link-DgLJzG7k.mjs → show-link-NjacLIdz.mjs} +1 -1
  194. package/dist/web-components/{sizedImage-NHzhcBYk.mjs → sizedImage-CKOGmqhN.mjs} +1 -1
  195. package/dist/web-components/{split-CuFiKjin.mjs → split-CcoXZcGX.mjs} +1 -1
  196. package/dist/web-components/{status-C3etlkhY.mjs → status-B4a3Izph.mjs} +1 -1
  197. package/dist/web-components/styles-C7PVxtkQ.mjs +1 -0
  198. package/dist/web-components/svg-shape-D1K-WNrY.mjs +1 -0
  199. package/dist/web-components/three.mjs +1 -1
  200. package/dist/web-components/thumbnail-ez20ssEY.mjs +1 -0
  201. package/dist/web-components/{tip-D5YgaIWW.mjs → tip-DeFPN33O.mjs} +1 -1
  202. package/dist/web-components/{toggle-CZGB65VZ.mjs → toggle-CGSnnjW-.mjs} +1 -1
  203. package/dist/web-components/trusted-Bvpx307M.mjs +1 -0
  204. package/dist/web-components/{useContainerName-hKQjEt7a.mjs → useContainerName-BfyeBf6_.mjs} +1 -1
  205. package/dist/web-components/useControlsVisibility-oRiMiQhD.mjs +1 -0
  206. package/dist/web-components/useLazyPanelPane-CReKsr8z.mjs +1 -0
  207. package/dist/web-components/{useNearViewport-CDbHQUBk.mjs → useNearViewport-BADiMpLi.mjs} +1 -1
  208. package/dist/web-components/{useScrollTrack-D9l_P3_B.mjs → useScrollTrack-9QsMaHSx.mjs} +1 -1
  209. package/dist/web-components/viewer/{AnnotationItems-DtsnDXPM.mjs → AnnotationItems-Cvh3jfmf.mjs} +1 -1
  210. package/dist/web-components/viewer/{AnnotationMenu-C-Mz6CCn.mjs → AnnotationMenu-d5PT7q8D.mjs} +1 -1
  211. package/dist/web-components/viewer/{AnnotationState-5pim5K72.mjs → AnnotationState-DbtYTHMy.mjs} +1 -1
  212. package/dist/web-components/viewer/{Annotations-Cqn1TkzD.mjs → Annotations-DKWYJOo2.mjs} +2 -2
  213. package/dist/web-components/viewer/{Annotations-CxwN9FkB.mjs → Annotations-D_wg4O99.mjs} +1 -1
  214. package/dist/web-components/viewer/{Canvas2DBackend-C-ZMSCak.mjs → Canvas2DBackend-B4IXvdsN.mjs} +1 -1
  215. package/dist/web-components/viewer/{CaptionDetails-CRD-gSZP.mjs → CaptionDetails-Bxh9VD7n.mjs} +1 -1
  216. package/dist/web-components/viewer/ChaptersMenu-CaAIaRZN.mjs +1 -0
  217. package/dist/web-components/viewer/{ChoiceMenu-ByGzQQx1.mjs → ChoiceMenu-Clp4Zeog.mjs} +1 -1
  218. package/dist/web-components/viewer/{Collection-m0GCcsfQ.mjs → Collection-C5BfoUOH.mjs} +1 -1
  219. package/dist/web-components/viewer/Connected-9VGl2Xnx.mjs +1 -0
  220. package/dist/web-components/viewer/{Connected-Dvx7wtot.mjs → Connected-Cd2qwuuo.mjs} +1 -1
  221. package/dist/web-components/viewer/{Contents-CwDpfiJY.mjs → Contents-CsG9e7v2.mjs} +1 -1
  222. package/dist/web-components/viewer/ControlMenu-q_u_UC8q.mjs +1 -0
  223. package/dist/web-components/viewer/ControlsFade-Db3IWArv.mjs +1 -0
  224. package/dist/web-components/viewer/CountMenu-Dn0-z5A9.mjs +1 -0
  225. package/dist/web-components/viewer/Cue-slOJQhPI.mjs +1 -0
  226. package/dist/web-components/viewer/Document-r3Sz3RfH.mjs +1 -0
  227. package/dist/web-components/viewer/{DomLayers-hc0qARQc.mjs → DomLayers-CwHg1jZg.mjs} +1 -1
  228. package/dist/web-components/viewer/{Download-MO-1Rik4.mjs → Download-Clx_e2ga.mjs} +1 -1
  229. package/dist/web-components/viewer/{EntryBodies-g-OEwEsk.mjs → EntryBodies-B4SnV6NJ.mjs} +1 -1
  230. package/dist/web-components/viewer/{EntryThumbnail-DcIDYATi.mjs → EntryThumbnail-CsAqKh38.mjs} +1 -1
  231. package/dist/web-components/viewer/{FieldPill-B9S21lxw.mjs → FieldPill-NQfq8SXA.mjs} +1 -1
  232. package/dist/web-components/viewer/{FrameAnimation-qI9cZPEs.mjs → FrameAnimation-wN2VNW7D.mjs} +1 -1
  233. package/dist/web-components/viewer/Gallery-nX9kQlft.mjs +1 -0
  234. package/dist/web-components/viewer/{HideToggle-D8wH49mq.mjs → HideToggle-B843JuKU.mjs} +1 -1
  235. package/dist/web-components/viewer/ImageControls--qeUY5kg.mjs +1 -0
  236. package/dist/web-components/viewer/{LanguageChoice-CRqsCBAp.mjs → LanguageChoice-CZ6K3Mhv.mjs} +1 -1
  237. package/dist/web-components/viewer/LightboxView-BcbP3cJD.mjs +1 -0
  238. package/dist/web-components/viewer/{ListEnd-D9Obxie4.mjs → ListEnd-DbYDv46a.mjs} +1 -1
  239. package/dist/web-components/viewer/MapView-Dj7Iq7P2.mjs +3 -0
  240. package/dist/web-components/viewer/MediaBody-TN4XsCm7.mjs +1 -0
  241. package/dist/web-components/viewer/{MediaBody-D5ff6xy-.mjs → MediaBody-iAxGgXNy.mjs} +1 -1
  242. package/dist/web-components/viewer/{NavDate-BnfDG57h.mjs → NavDate-Clj6OMa6.mjs} +1 -1
  243. package/dist/web-components/viewer/{Navigator-BNwjmkXY.mjs → Navigator-DPdR3SYX.mjs} +1 -1
  244. package/dist/web-components/viewer/{PagerLayout-C8jraHqs.mjs → PagerLayout-CtlmDRjI.mjs} +1 -1
  245. package/dist/web-components/viewer/PanelPart-DzZWRlK1.mjs +1 -0
  246. package/dist/web-components/viewer/{PartOfManifest-DX7H0V4g.mjs → PartOfManifest-NAXs2DYd.mjs} +1 -1
  247. package/dist/web-components/viewer/{PlaceBox-CCWfzsNU.mjs → PlaceBox-C2k5Fsfo.mjs} +1 -1
  248. package/dist/web-components/viewer/Placeholder-DF6dRMjt.mjs +1 -0
  249. package/dist/web-components/viewer/{Search-CsdYzdq1.mjs → Search-DoUc8tWu.mjs} +1 -1
  250. package/dist/web-components/viewer/{StandaloneItems-BfvBxbUm.mjs → StandaloneItems-DuXasJO0.mjs} +1 -1
  251. package/dist/web-components/viewer/{Steps-BH8ZApS4.mjs → Steps-B3MrG4Cv.mjs} +1 -1
  252. package/dist/web-components/viewer/TargetItems-DOFSQtYR.mjs +1 -0
  253. package/dist/web-components/viewer/{Transcript-DXLv5WR9.mjs → Transcript-Dy-FHWMo.mjs} +1 -1
  254. package/dist/web-components/viewer/Transport-C5wkxVOF.mjs +1 -0
  255. package/dist/web-components/viewer/{Transport-C-fh7Kx2.mjs → Transport-CUXmY_jW.mjs} +1 -1
  256. package/dist/web-components/viewer/{annotation-collection-Cjd8Dgyl.mjs → annotation-collection-A0PNdPhI.mjs} +1 -1
  257. package/dist/web-components/viewer/annotation-name-CfQs7Mb2.mjs +1 -0
  258. package/dist/web-components/viewer/{annotations-content-BARXoAz-.mjs → annotations-content-B52-zM99.mjs} +1 -1
  259. package/dist/web-components/viewer/{cloverEngine-CumnJPKO.mjs → cloverEngine-4sgpB7Rz.mjs} +1 -1
  260. package/dist/web-components/viewer/{content-state-reader-DuvyLThu.mjs → content-state-reader-vtATl-W3.mjs} +1 -1
  261. package/dist/web-components/viewer/{dragToClose-CFCxhUxn.mjs → dragToClose-B4rj1D3r.mjs} +1 -1
  262. package/dist/web-components/viewer/{fetchManifest-qNB_KgxL.mjs → fetchManifest-gAj8phm4.mjs} +1 -1
  263. package/dist/web-components/viewer/{host-GTHX2fPK.mjs → host-Hv8WXfiF.mjs} +1 -1
  264. package/dist/web-components/viewer/{image-layers-DKOuaRTj.mjs → image-layers-gFEDKVkV.mjs} +1 -1
  265. package/dist/web-components/viewer/index.mjs +1 -1
  266. package/dist/web-components/viewer/{link-BlaM0tCa.mjs → link-DIh6ysyo.mjs} +1 -1
  267. package/dist/web-components/viewer/{overlayImage-RVpv69R5.mjs → overlayImage-BRjcH40Q.mjs} +1 -1
  268. package/dist/web-components/viewer/{range-regions-CIZiAHOp.mjs → range-regions-uPqjKIER.mjs} +1 -1
  269. package/dist/web-components/viewer/{renderers-Dw1klwlx.mjs → renderers-C5EfPrd7.mjs} +1 -1
  270. package/dist/web-components/viewer/{save-file-EvzaBEJN.mjs → save-file-dIa0LCAn.mjs} +1 -1
  271. package/dist/web-components/viewer/{search-x1QL_bth.mjs → search-Bbv9dCNq.mjs} +1 -1
  272. package/dist/web-components/viewer/styles-L1HpSoL2.mjs +1 -0
  273. package/dist/web-components/viewer/useControlsVisibility-jopIdHZi.mjs +1 -0
  274. package/dist/web-components/viewer/useLazyPanelPane-CoPgtYkx.mjs +1 -0
  275. package/dist/web-components/viewer/viewer-DqpSyvH-.mjs +29 -0
  276. package/dist/web-components/viewer/vtt-DpgB_K8v.mjs +5 -0
  277. package/dist/web-components/viewer-D2lGdifc.mjs +1 -0
  278. package/dist/web-components/vtt-KUQbi4PK.mjs +5 -0
  279. package/dist/web-components/worker-C9aVbya_.mjs +1 -0
  280. package/package.json +2 -1
  281. package/dist/web-components/Button-L8ZMy5lY.mjs +0 -1
  282. package/dist/web-components/CanvasView-2Fj9nT06.mjs +0 -2
  283. package/dist/web-components/ChaptersMenu-Bj2EqtVJ.mjs +0 -1
  284. package/dist/web-components/ControlMenu-D1zkB0qX.mjs +0 -1
  285. package/dist/web-components/ControlsFade-BNXVTL_Q.mjs +0 -1
  286. package/dist/web-components/CountMenu-Dnzb7lKo.mjs +0 -1
  287. package/dist/web-components/Cue-CUGmPS3k.mjs +0 -1
  288. package/dist/web-components/Document-D-8nalCX.mjs +0 -1
  289. package/dist/web-components/Gallery-4Hd58afA.mjs +0 -1
  290. package/dist/web-components/ImageControls-CZO7WoPb.mjs +0 -1
  291. package/dist/web-components/LightboxView-C4OASmkg.mjs +0 -1
  292. package/dist/web-components/LoadedMap-WATGNLxl.mjs +0 -1
  293. package/dist/web-components/MapView-3OxoCr5l.mjs +0 -3
  294. package/dist/web-components/Markup-DW75Jx3j.mjs +0 -2
  295. package/dist/web-components/MediaBody-CLtd0bf0.mjs +0 -1
  296. package/dist/web-components/Panel-BvDpCn6K.mjs +0 -1
  297. package/dist/web-components/PanelPart-Bd4lSUrP.mjs +0 -1
  298. package/dist/web-components/Placeholder-DzY5hcbk.mjs +0 -1
  299. package/dist/web-components/Root-Bt3NNBFb.mjs +0 -1
  300. package/dist/web-components/Scene-DrOM9YlD.mjs +0 -1
  301. package/dist/web-components/SceneView-DA7Yg20p.mjs +0 -1
  302. package/dist/web-components/TargetItems-BDJM3Ar-.mjs +0 -1
  303. package/dist/web-components/Timeline-BfdN3lIv.mjs +0 -1
  304. package/dist/web-components/Tip-OCB88zwY.mjs +0 -1
  305. package/dist/web-components/Transport-DaIhfZqC.mjs +0 -1
  306. package/dist/web-components/hooks-BhtNDs_1.mjs +0 -1
  307. package/dist/web-components/index-FJEpXukG.mjs +0 -1
  308. package/dist/web-components/items-BPPrqbeh.mjs +0 -1
  309. package/dist/web-components/label-DauFa5sg.mjs +0 -1
  310. package/dist/web-components/logo-DWPxaZaG.mjs +0 -1
  311. package/dist/web-components/masonry-0QfzOgbB.mjs +0 -1
  312. package/dist/web-components/part-CekFWrtz.mjs +0 -1
  313. package/dist/web-components/pointer-YQppt0at.mjs +0 -1
  314. package/dist/web-components/rendererSurface-BkbGDL_Z.mjs +0 -22
  315. package/dist/web-components/shared-DkY2a89G.mjs +0 -1
  316. package/dist/web-components/styles-DkkVOSUQ.mjs +0 -1
  317. package/dist/web-components/svg-shape-DLY3g7oq.mjs +0 -1
  318. package/dist/web-components/thumbnail-DecrVnpj.mjs +0 -1
  319. package/dist/web-components/useControlsVisibility-DPg8uAkW.mjs +0 -1
  320. package/dist/web-components/useLazyPanelPane-eby-OI1V.mjs +0 -1
  321. package/dist/web-components/viewer/ChaptersMenu-Brcq3yJv.mjs +0 -1
  322. package/dist/web-components/viewer/Connected-Bmc_CdUD.mjs +0 -1
  323. package/dist/web-components/viewer/ControlMenu-TcO85hDf.mjs +0 -1
  324. package/dist/web-components/viewer/ControlsFade-BoZ4ABAE.mjs +0 -1
  325. package/dist/web-components/viewer/CountMenu-0-ie8kIZ.mjs +0 -1
  326. package/dist/web-components/viewer/Cue-DxmAS9Gx.mjs +0 -1
  327. package/dist/web-components/viewer/Document-BsryuYJ1.mjs +0 -1
  328. package/dist/web-components/viewer/Gallery-BOgUqfqw.mjs +0 -1
  329. package/dist/web-components/viewer/ImageControls-ZoEC9jWd.mjs +0 -1
  330. package/dist/web-components/viewer/LightboxView-BB-GcbYr.mjs +0 -1
  331. package/dist/web-components/viewer/MapView-DQSwUzd7.mjs +0 -3
  332. package/dist/web-components/viewer/MediaBody-CIw2nTlj.mjs +0 -1
  333. package/dist/web-components/viewer/PanelPart-YNbBI9SQ.mjs +0 -1
  334. package/dist/web-components/viewer/Placeholder-CsEkLhz7.mjs +0 -1
  335. package/dist/web-components/viewer/TargetItems-BebPFr-c.mjs +0 -1
  336. package/dist/web-components/viewer/Transport-CY6BWfMi.mjs +0 -1
  337. package/dist/web-components/viewer/annotation-name-CwmgQFia.mjs +0 -1
  338. package/dist/web-components/viewer/styles-I7_LWFGj.mjs +0 -1
  339. package/dist/web-components/viewer/useControlsVisibility-C_SQHIVR.mjs +0 -1
  340. package/dist/web-components/viewer/useLazyPanelPane-UuGDJrf_.mjs +0 -1
  341. package/dist/web-components/viewer/viewer-DJrQuNs1.mjs +0 -29
  342. package/dist/web-components/viewer/vtt-C2G89SWH.mjs +0 -5
  343. package/dist/web-components/viewer-Br44EEba.mjs +0 -1
  344. package/dist/web-components/vtt-Dd0c7psH.mjs +0 -5
  345. package/dist/web-components/worker-CjXN0dku.mjs +0 -1
@@ -8,18 +8,17 @@ function isPresentation4(resource) {
8
8
  );
9
9
  }
10
10
  let upgrader = null;
11
+ let reader = null;
11
12
  function preloadUpgrader() {
13
+ reader ?? (reader = import("./upgrade.mjs"));
12
14
  upgrader ?? (upgrader = import("@iiif/parser/presentation-4/upgrader").then(
13
15
  ({ upgradePresentation3To4 }) => upgradePresentation3To4
14
16
  ));
15
- return upgrader;
17
+ return Promise.all([upgrader, reader]);
16
18
  }
17
19
  async function toPresentation4(resource) {
18
20
  if (isPresentation4(resource)) return resource;
19
- const [toFour, { upgrade }] = await Promise.all([
20
- preloadUpgrader(),
21
- import("./upgrade.mjs")
22
- ]);
21
+ const [toFour, { upgrade }] = await preloadUpgrader();
23
22
  return await upgrade(resource, toFour);
24
23
  }
25
24
  export {
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import DOMPurify from "dompurify";
3
+ import { trustedPolicy, trusted } from "./trusted.mjs";
3
4
  const TAGS = ["a", "b", "br", "i", "img", "p", "small", "span", "sub", "sup"];
4
5
  const ATTRIBUTES = ["href", "alt", "src", "height", "width", "lang", "dir"];
5
6
  const URI_SAFE = ["height", "width", "lang", "dir"];
@@ -87,7 +88,7 @@ function tidy(html) {
87
88
  var _a;
88
89
  if (!html) return html;
89
90
  const box = document.createElement("template");
90
- box.innerHTML = html;
91
+ box.innerHTML = trusted(html);
91
92
  for (const image of box.content.querySelectorAll("img:not([src])"))
92
93
  image.remove();
93
94
  for (const paragraph of box.content.querySelectorAll("p"))
@@ -150,8 +151,19 @@ function purifier() {
150
151
  }
151
152
  function sanitizeHTML(html, { markdown = false } = {}) {
152
153
  if (typeof window === "undefined") return html;
153
- return tidy(purifier().sanitize(html, markdown ? MARKDOWN_CONFIG : CONFIG));
154
+ const config = markdown ? MARKDOWN_CONFIG : CONFIG;
155
+ const policy = trustedPolicy();
156
+ return tidy(
157
+ purifier().sanitize(
158
+ html,
159
+ policy ? {
160
+ ...config,
161
+ TRUSTED_TYPES_POLICY: policy
162
+ } : config
163
+ )
164
+ );
154
165
  }
155
166
  export {
156
- sanitizeHTML
167
+ sanitizeHTML,
168
+ trusted
157
169
  };
@@ -1,4 +1,5 @@
1
1
  "use client";
2
+ import { trusted } from "./trusted.mjs";
2
3
  const NUMBER = /^-?(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?$/i;
3
4
  const POINTS = /^[\d\s.,eE+-]*$/;
4
5
  const PATH = /^[\d\s.,eE+\-MmLlHhVvCcSsQqTtAaZz]*$/;
@@ -16,7 +17,7 @@ function readSvgShape(svg) {
16
17
  if (typeof DOMParser === "undefined" || !svg) return null;
17
18
  let doc;
18
19
  try {
19
- doc = new DOMParser().parseFromString(svg, "image/svg+xml");
20
+ doc = new DOMParser().parseFromString(trusted(svg), "image/svg+xml");
20
21
  } catch {
21
22
  return null;
22
23
  }
@@ -17,27 +17,38 @@ function regionShare(region, { width, height }) {
17
17
  const [across, down] = match[1] ? [100, 100] : [width, height];
18
18
  return { x: x / across, y: y / down, width: w / across, height: h / down };
19
19
  }
20
- function imageSource(image, region = "full") {
20
+ function imageSource(image, region = "full", sized = false) {
21
21
  if (!image) return null;
22
22
  const service = findImageServiceId(image.service);
23
23
  if (service) {
24
- return region === "full" ? { service, fallback: image.id } : { service, region, fallback: image.id };
24
+ if (region !== "full") return { service, region, fallback: image.id };
25
+ const { width, height } = image;
26
+ return sized && image.id && width > 0 && height > 0 ? { service, fallback: image.id, fallbackSize: { width, height } } : { service, fallback: image.id };
25
27
  }
26
28
  return image.id ? { src: image.id } : null;
27
29
  }
28
30
  function thumbnailSource(resource) {
29
31
  const value = resource;
30
32
  if (!value) return null;
31
- return imageSource(asArray(value.thumbnail)[0]) ?? imageSource(firstPaintedImage(value)) ?? imageSource(firstPaintedImage(value.placeholderContainer)) ?? imageSource(firstPaintedImage(value.accompanyingContainer));
33
+ return imageSource(
34
+ asArray(value.thumbnail)[0],
35
+ "full",
36
+ true
37
+ ) ?? imageSource(firstPaintedImage(value)) ?? imageSource(firstPaintedImage(value.placeholderContainer)) ?? imageSource(firstPaintedImage(value.accompanyingContainer));
32
38
  }
33
39
  function stillSource(resource) {
34
40
  const value = resource;
35
41
  if (!value) return null;
36
- return imageSource(firstPaintedImage(value)) ?? imageSource(firstPaintedImage(value.placeholderContainer)) ?? imageSource(firstPaintedImage(value.accompanyingContainer)) ?? imageSource(asArray(value.thumbnail)[0]);
42
+ return imageSource(firstPaintedImage(value)) ?? imageSource(firstPaintedImage(value.placeholderContainer)) ?? imageSource(firstPaintedImage(value.accompanyingContainer)) ?? imageSource(asArray(value.thumbnail)[0], "full", true);
37
43
  }
38
44
  async function resolveThumbnail(source, size = 200, request) {
39
45
  if (source.src) return source.src;
40
46
  if (!source.service) return source.fallback;
47
+ const own = source.fallbackSize;
48
+ if (own && source.fallback && source.region === void 0) {
49
+ const longer = Math.max(own.width, own.height);
50
+ if (longer >= size && longer <= size * 2) return source.fallback;
51
+ }
41
52
  try {
42
53
  const info = await fetchInfo(source.service, { request });
43
54
  const share = typeof source.region === "string" ? regionShare(source.region, info) : source.region;
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ let policy;
3
+ function trustedPolicy() {
4
+ if (policy === void 0) {
5
+ const factory = globalThis.trustedTypes;
6
+ try {
7
+ policy = (factory == null ? void 0 : factory.createPolicy("clover", {
8
+ createHTML: (html) => html,
9
+ createScriptURL: () => {
10
+ throw new TypeError("Clover makes no script URLs");
11
+ }
12
+ })) ?? null;
13
+ } catch {
14
+ policy = null;
15
+ }
16
+ }
17
+ return policy;
18
+ }
19
+ function trusted(html) {
20
+ var _a;
21
+ return ((_a = trustedPolicy()) == null ? void 0 : _a.createHTML(html)) ?? html;
22
+ }
23
+ export {
24
+ trusted,
25
+ trustedPolicy
26
+ };
package/dist/core/vtt.mjs CHANGED
@@ -22,8 +22,7 @@ function cueText(raw) {
22
22
  return code > 0 && code <= 1114111 ? String.fromCodePoint(code) : entity;
23
23
  });
24
24
  }
25
- function parseVtt(text) {
26
- var _a, _b;
25
+ function vttBlocks(text) {
27
26
  const cues = [];
28
27
  const blocks = text.replace(/\r\n?/g, "\n").split(/\n{2,}/);
29
28
  for (const block of blocks) {
@@ -32,14 +31,25 @@ function parseVtt(text) {
32
31
  if (timing === -1) continue;
33
32
  const [from, rest] = lines[timing].split("-->");
34
33
  const start = seconds(from);
35
- const end = seconds(rest.trim().split(/\s+/)[0]);
34
+ const [until, ...settings] = rest.trim().split(/\s+/);
35
+ const end = seconds(until);
36
36
  if (!Number.isFinite(start) || !Number.isFinite(end)) continue;
37
- const raw = lines.slice(timing + 1).join("\n");
38
- const voice = (_b = (_a = /<v(?:\.[^\s>]+)*\s+([^>]+)>/.exec(raw)) == null ? void 0 : _a[1]) == null ? void 0 : _b.trim();
39
- const body = cueText(raw);
40
- cues.push({ start, end, text: body, ...voice ? { voice } : {} });
37
+ cues.push({
38
+ id: timing ? lines[0] : "",
39
+ start,
40
+ end,
41
+ settings: settings.join(" "),
42
+ raw: lines.slice(timing + 1).join("\n")
43
+ });
41
44
  }
42
- return cues.sort((a, b) => a.start - b.start);
45
+ return cues;
46
+ }
47
+ function parseVtt(text) {
48
+ return vttBlocks(text).map(({ start, end, raw }) => {
49
+ var _a, _b;
50
+ const voice = (_b = (_a = /<v(?:\.[^\s>]+)*\s+([^>]+)>/.exec(raw)) == null ? void 0 : _a[1]) == null ? void 0 : _b.trim();
51
+ return { start, end, text: cueText(raw), ...voice ? { voice } : {} };
52
+ }).sort((a, b) => a.start - b.start);
43
53
  }
44
54
  function cueAt(cues, time) {
45
55
  let low = 0;
@@ -107,5 +117,6 @@ export {
107
117
  loadText,
108
118
  loadVtt,
109
119
  paragraphsOf,
110
- parseVtt
120
+ parseVtt,
121
+ vttBlocks
111
122
  };
package/dist/index.d.mts CHANGED
@@ -721,6 +721,15 @@ export interface GestureOptions {
721
721
  * or sound, always fitted to the Body).
722
722
  */
723
723
  navigable: boolean;
724
+ /**
725
+ * A mouse or pen drag tracks the pointer 1:1 and glides on after a fast release. Off,
726
+ * the drag is eased instead and stops where the pointer does. A finger always tracks 1:1 and flicks.
727
+ */
728
+ flickEnabled: boolean;
729
+ /** Release speed, px/s, below which a drag does not flick. */
730
+ flickMinSpeed: number;
731
+ /** Seconds of release velocity the flick travels. */
732
+ flickMomentum: number;
724
733
  }
725
734
  export type BackendPreference = "auto" | BackendKind;
726
735
  export type CanvasRendererEvent =
@@ -793,6 +802,9 @@ export interface RegionShare {
793
802
  * nor than its limits, at level 0 only a size it lists (Mat, 2026-10-24: "be
794
803
  * responsible when making IIIF image server requests"). What a manifest says of a
795
804
  * service is not trusted to say what its server does.
805
+ * - A `thumbnail` whose own `width` and `height` already fit the size (`resolveThumbnail`)
806
+ * is used as the manifest gives it, with no `info.json` read: the publisher's own URL,
807
+ * not one built from what a service says.
796
808
  * - Without a service, the image itself is used.
797
809
  */
798
810
  export interface ThumbnailSource {
@@ -807,6 +819,11 @@ export interface ThumbnailSource {
807
819
  region?: RegionShare | string;
808
820
  /** Used if the service cannot answer. */
809
821
  fallback?: string;
822
+ /** The pixels `fallback` is, as its own `width` and `height` say (a `thumbnail`'s). */
823
+ fallbackSize?: {
824
+ width: number;
825
+ height: number;
826
+ };
810
827
  }
811
828
  /**
812
829
  * Where a resource's thumbnail comes from, to be sized by `resolveThumbnail`. Null if it
@@ -823,6 +840,9 @@ export declare function stillSource(resource: unknown): ThumbnailSource | null;
823
840
  /**
824
841
  * A source's URL at about `size` pixels on its longer side: a service's, made from its own
825
842
  * `info.json` (`sizedImageUrl`), else the fallback, as where the service cannot answer.
843
+ * The fallback itself, with no `info.json` read, when it is all of the image and its
844
+ * longer side is from `size` to twice it: no blurrier than the service would be asked
845
+ * for, and not much heavier.
826
846
  */
827
847
  export declare function resolveThumbnail(source: ThumbnailSource, size?: number, request?: CloverRequest): Promise<string | undefined>;
828
848
  /**
@@ -919,7 +939,14 @@ export type ControlButtonProps = {
919
939
  lang?: string;
920
940
  /** The key the Canvas answers to for this control, when it has one. */
921
941
  "aria-keyshortcuts"?: string;
942
+ /** Absent while the control would do nothing, as at the greatest zoom. */
922
943
  onClick?: React.MouseEventHandler<HTMLButtonElement>;
944
+ /**
945
+ * `true` while the control would do nothing: zoom in at the greatest zoom, zoom out at
946
+ * the least, reset at home. Spread it with the rest, never as `disabled`, which would
947
+ * take the button from the keyboard (WCAG 2.4.3), and dim it.
948
+ */
949
+ "aria-disabled"?: true;
923
950
  /** On a control that opens a menu (the Choice control): its state and target. */
924
951
  "aria-expanded"?: boolean;
925
952
  "aria-controls"?: string;
@@ -987,11 +1014,20 @@ export interface CloverCanvasOptions {
987
1014
  minZoomImageRatio?: number;
988
1015
  /** Seconds for an animation to close most of its distance. 0 disables easing. */
989
1016
  animationTime?: number;
1017
+ /**
1018
+ * Seconds each animation (zoom, glide, home) takes, on a fixed-length spring. Unset,
1019
+ * the camera eases by `animationTime` instead.
1020
+ */
1021
+ animationDuration?: number;
1022
+ /** With `animationDuration`, how much of the movement comes early: higher starts faster. Default 6.5. */
1023
+ springStiffness?: number;
1024
+ /** Hold the image inside its bounds while dragging. Default true; false lets it spring back on release. */
1025
+ constrainDuringPan?: boolean;
990
1026
  /**
991
1027
  * Milliseconds the controls and navigator stay after a mouse (or a pen that hovers)
992
- * stops moving, as the Player's `hideDelay`. Default 2000; `Infinity` keeps them once
993
- * shown. A finger, or a pen that does not hover, has no timer: a tap on the picture
994
- * shows them, and another hides them. Focus that no press brought holds them too.
1028
+ * stops moving, or a finger lifts, as the Player's `hideDelay`. Default 3000; `Infinity`
1029
+ * keeps them once shown. A tap on the picture shows them, and another hides them. Focus
1030
+ * that no press brought holds them, and so does a paused recording.
995
1031
  * A Timeline's: a Canvas's controls stay in sight, for now (Mat, 2026-11-01).
996
1032
  */
997
1033
  hideDelay?: number;
@@ -1611,8 +1647,36 @@ export interface LogoProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement
1611
1647
  * picture.
1612
1648
  */
1613
1649
  export declare function Logo({ of, value, alt, className, ...rest }: LogoProps): React.JSX.Element | null;
1650
+ /**
1651
+ * A section `Panel` draws by itself, from what the Root's resource holds. `sections`
1652
+ * chooses among them; each still shows only where there is data for it.
1653
+ */
1654
+ export type PanelSection = "about" | "targets" | "collection" | "contents" | "search" | "map" | "transcript" | "annotations";
1655
+ /**
1656
+ * The default sections a `Panel` in this Root would have, in its order: About, and each
1657
+ * other one the resource has data for, narrowed to `sections` where the page names the
1658
+ * ones it wants. None of them, and the panel draws nothing, so a layout of your own can
1659
+ * ask first and leave out the pane that would hold it:
1660
+ *
1661
+ * ```jsx
1662
+ * const sections = Clover.usePanelSections(["contents", "search"]);
1663
+ * return sections.length ? <Clover.Panel sections={sections} /> : null;
1664
+ * ```
1665
+ *
1666
+ * Asking costs nothing a `Panel` does not already cost: the same reads of the Root, one
1667
+ * for each section, so a change that moves none of them re-renders nothing.
1668
+ */
1669
+ export declare function usePanelSections(sections?: readonly PanelSection[]): PanelSection[];
1614
1670
  /** How the sections are laid out. */
1615
1671
  export type SectionsLayout = "tabs" | "accordion";
1672
+ /**
1673
+ * What a page calls a section, in place of Clover's own word for it: its words, taken to
1674
+ * be in the page's language, or its words by language tag, one of which the tab carries
1675
+ * as its `lang` where it is not the page's (WCAG 3.1.2).
1676
+ */
1677
+ export type PanelSectionLabel = string | Readonly<Record<string, string>>;
1678
+ /** A label for any of the default sections, by its value. */
1679
+ export type PanelSectionLabels = Partial<Record<PanelSection, PanelSectionLabel>>;
1616
1680
  export interface TabProps {
1617
1681
  /** Identifies the tab, for `value` / `defaultValue` on the panel. */
1618
1682
  value: string;
@@ -1678,7 +1742,22 @@ export interface PanelProps extends Omit<React.HTMLAttributes<HTMLElement>, "def
1678
1742
  */
1679
1743
  languages?: boolean;
1680
1744
  /**
1681
- * `Clover.Tab`s. Without any, the panel has the tabs Clover has data for: About,
1745
+ * Which of the default sections the panel may have, in Clover's own order: with
1746
+ * `["contents", "search"]` it has those two and no About. Each still shows only where
1747
+ * the resource has data for it, so a resource with none of them draws no panel at all.
1748
+ * `Tab` children win over it. Default: every section.
1749
+ */
1750
+ sections?: readonly PanelSection[];
1751
+ /**
1752
+ * What a default section's tab or heading says, in place of Clover's own word for it:
1753
+ * `{ annotations: "Chapters" }`, or `{ annotations: { en: "Chapters", de: "Kapitel" } }`
1754
+ * to say it in several, read in the one Clover speaks and marked with its language
1755
+ * where that is not the page's (WCAG 3.1.2). A `Tab` of your own says it in `label`.
1756
+ */
1757
+ labels?: PanelSectionLabels;
1758
+ /**
1759
+ * `Clover.Tab`s, the panel's sections whole, in their order: they win over `sections`.
1760
+ * Without any, the panel has the tabs Clover has data for: About,
1682
1761
  * Contents when the Manifest has Ranges, Search when it has a Content Search service, a
1683
1762
  * Map when it (or a Canvas or annotation) has navPlace or a georeference,
1684
1763
  * a Transcript when the view's media has captions or a plain-text transcript, and
@@ -1698,6 +1777,14 @@ export interface PanelProps extends Omit<React.HTMLAttributes<HTMLElement>, "def
1698
1777
  * <Clover.Tab value="notes" label="Notes"><MyNotes /></Clover.Tab>
1699
1778
  * </Clover.Panel>
1700
1779
  * ```
1780
+ *
1781
+ * To keep Clover's own sections but not all of them, name the ones you want in
1782
+ * `sections`: each still shows only where the resource has data for it, and a resource
1783
+ * with none of them has no panel.
1784
+ *
1785
+ * ```jsx
1786
+ * <Clover.Panel sections={["contents", "search", "transcript", "annotations"]} />
1787
+ * ```
1701
1788
  */
1702
1789
  export declare const Panel: React.ForwardRefExoticComponent<PanelProps & React.RefAttributes<HTMLElement>>;
1703
1790
  export interface AboutProps extends React.HTMLAttributes<HTMLElement> {
@@ -1940,6 +2027,167 @@ export declare function search(service: SearchService, query: string, { request,
1940
2027
  request?: CloverRequest;
1941
2028
  signal?: AbortSignal;
1942
2029
  }): Promise<SearchResults>;
2030
+ /**
2031
+ * Whether a Manifest has anything to put on a map: navPlace on the Collection, Manifest,
2032
+ * a Canvas or an annotation, a GeoJSON annotation body, or a georeferencing annotation.
2033
+ * Only a look, never a read: the panel asks it to offer a Map tab, and the reading
2034
+ * (`core/geo.ts`) belongs to the map entry, so an app without a map carries none of it.
2035
+ */
2036
+ export declare function hasMapData(manifest: Manifest | null, collection?: Presentation4Collection | null): boolean;
2037
+ /**
2038
+ * Where a IIIF resource is, read for a map: navPlace (on a Collection, Manifest, Canvas
2039
+ * or Annotation, and annotation bodies that are GeoJSON), and Georeference Extension
2040
+ * annotations, reduced to what a basic overlay needs. Framework-free and small: the map
2041
+ * itself, and MapLibre, load only when a `Map` is shown.
2042
+ *
2043
+ * - navPlace: https://iiif.io/api/extension/navplace/
2044
+ * - Georeference: https://iiif.io/api/extension/georef/
2045
+ */
2046
+ export type Position = [
2047
+ number,
2048
+ number
2049
+ ];
2050
+ export interface GeoGeometry {
2051
+ type: string;
2052
+ coordinates?: unknown;
2053
+ geometries?: GeoGeometry[];
2054
+ }
2055
+ export interface MapFeature {
2056
+ type: "Feature";
2057
+ id?: string | number;
2058
+ geometry: GeoGeometry;
2059
+ /**
2060
+ * Flat, for MapLibre (which turns nested objects into strings): the text to show and
2061
+ * its language, the Canvas it belongs to, and any simplestyle keys it carried (`fill`,
2062
+ * `stroke`, …).
2063
+ */
2064
+ properties: Record<string, string | number | boolean> & {
2065
+ title?: string;
2066
+ titleLang?: string;
2067
+ canvasId?: string;
2068
+ /** The annotation it is a body of (Cookbook 0139), which a press on it selects. */
2069
+ annotationId?: string;
2070
+ /** The Collection's member it locates (Cookbook 0318), which a press on it opens. */
2071
+ manifestId?: string;
2072
+ /** Its owner's `navDate`, as written, shown with its name (Cookbook 0318). */
2073
+ navDate?: string;
2074
+ };
2075
+ }
2076
+ export interface MapFeatureCollection {
2077
+ type: "FeatureCollection";
2078
+ features: MapFeature[];
2079
+ }
2080
+ /** A georeferenced image, reduced to an affine overlay. */
2081
+ export interface Georeference {
2082
+ id: string;
2083
+ /** The Canvas it georeferences, when it targets one. */
2084
+ canvasId?: string;
2085
+ /** Ground control points: image pixel [x, y] ↔ [longitude, latitude]. */
2086
+ points: Array<{
2087
+ resource: Position;
2088
+ geo: Position;
2089
+ }>;
2090
+ /** The extent the points are measured in: the Canvas, or the image service. */
2091
+ width: number;
2092
+ height: number;
2093
+ /** The part of the image that is map (an SvgSelector polygon), in the same units. */
2094
+ mask?: Position[];
2095
+ /** Its name: the annotation's label, or the Canvas's. */
2096
+ label?: LanguageMapLike;
2097
+ /** What to draw: an image body (or a bare image service), sized by `overlayImageUrl`. */
2098
+ image: Record<string, unknown>;
2099
+ }
2100
+ /**
2101
+ * Every navPlace feature of the Root's resource: the Collection's, each of its members'
2102
+ * (Cookbook 0318: a Collection of Manifests, each where it is), the Manifest's, each
2103
+ * Canvas's, and each loaded annotation's (its `navPlace`, or a GeoJSON body as Cookbook
2104
+ * 0139 has). A feature from a member names that member, the open one's place its own
2105
+ * Manifest's where it gives one, in the member's place in the Collection's order; one
2106
+ * from a Canvas or annotation names that Canvas. Memoized on the Manifest (and the
2107
+ * Collection), so the same collection comes back while nothing changes.
2108
+ */
2109
+ export declare function navPlaceOf(manifest: Manifest | null, collection?: Presentation4Collection | null, language?: string): MapFeatureCollection;
2110
+ /**
2111
+ * One Georeference Extension annotation as an overlay: its control points, the extent
2112
+ * they are measured in, its mask, and the image to draw (the Canvas's painted image, or
2113
+ * the image service it targets directly). Null when it cannot be drawn: fewer than three
2114
+ * points, no extent, or nothing to draw.
2115
+ */
2116
+ export declare function readGeoreference(annotation: Json, canvas?: Json): Georeference | null;
2117
+ /**
2118
+ * The georeferenced images of the Manifest's Canvases, from their loaded annotation pages.
2119
+ * Memoized on the Manifest: embedding a fetched page makes a new one.
2120
+ */
2121
+ export declare function georeferencesOf(manifest: Manifest | null): Georeference[];
2122
+ /**
2123
+ * The first-order polynomial (affine) transform that best fits the control points, image
2124
+ * pixels to [longitude, latitude], by least squares in Web Mercator. Exact for three
2125
+ * points. Null when the points are collinear.
2126
+ */
2127
+ export declare function affineTransform(points: Georeference["points"]): ((pixel: Position) => Position) | null;
2128
+ /**
2129
+ * Where the image's corners land, in the order MapLibre's image and canvas sources take
2130
+ * them: top left, top right, bottom right, bottom left. Null when the points do not fix
2131
+ * a transform.
2132
+ */
2133
+ export declare function cornersOf(georeference: Georeference): [
2134
+ Position,
2135
+ Position,
2136
+ Position,
2137
+ Position
2138
+ ] | null;
2139
+ /** The [[west, south], [east, north]] that holds the features and the overlays. */
2140
+ export declare function boundsOf(features: MapFeature[], overlays?: Georeference[]): [
2141
+ Position,
2142
+ Position
2143
+ ] | null;
2144
+ export interface MapProps extends Omit<React.HTMLAttributes<HTMLElement>, "onSelect"> {
2145
+ /**
2146
+ * Standalone: a IIIF resource (URL or object) to map: its navPlace, and its Canvases'
2147
+ * georeferenced images. Inside a `Root`, leave it out to map the Root's.
2148
+ */
2149
+ iiifContent?: IIIFContent;
2150
+ /** GeoJSON to draw (a FeatureCollection, Feature or geometry), as navPlace is. */
2151
+ navPlace?: unknown;
2152
+ /** Georeference Extension annotations to overlay, on a Canvas or an image service. */
2153
+ georeferences?: unknown[];
2154
+ /** Draw georeferenced images over the basemap. Default true. */
2155
+ overlay?: boolean;
2156
+ /** The overlays' opacity, 0 to 1. Default 0.75. */
2157
+ overlayOpacity?: number;
2158
+ /** A MapLibre style URL, used as it is. Default: Clover's relief basemap (OpenFreeMap). */
2159
+ styleUrl?: string;
2160
+ /**
2161
+ * Where MapLibre's worker is served from, to serve your own (see the Map docs). By
2162
+ * default Clover brings it, from a `blob:` URL.
2163
+ */
2164
+ workerUrl?: string;
2165
+ /** Zoom with the wheel or trackpad. Default false, so an embedded map never traps page scroll. */
2166
+ scrollZoom?: boolean;
2167
+ /**
2168
+ * A place was chosen, on the map or in its list. Inside a `Root`, choosing one on a
2169
+ * Canvas also goes there.
2170
+ */
2171
+ onSelect?: (feature: MapFeature) => void;
2172
+ /** Standalone: credentials, headers and `fetch`. */
2173
+ request?: CloverRequest;
2174
+ /** Standalone: the language to read IIIF text in. */
2175
+ language?: string;
2176
+ /**
2177
+ * Clover's higher-contrast mode: the accent kept to rings, outlines and marks, and never
2178
+ * under words or a glyph, where the controls' dark fill takes its place, edged in the
2179
+ * accent. Inside a `Root`, the Root's too; on wherever the reader's system asks for more
2180
+ * contrast. Default `false`.
2181
+ */
2182
+ highContrast?: boolean;
2183
+ /**
2184
+ * The basemap's credits, behind an ⓘ in the map's lower corner. Default true. A basemap's license
2185
+ * may ask for its credits: give them on the page yourself before setting this false.
2186
+ */
2187
+ credits?: boolean;
2188
+ as?: React.ElementType;
2189
+ }
2190
+ declare const CloverMap: React.ForwardRefExoticComponent<MapProps & React.RefAttributes<HTMLElement>>;
1943
2191
  /** Serve MapLibre's worker from `url` for every map Clover draws (a Viewer's Map tab included). */
1944
2192
  export declare function setMapWorkerUrl(url: string | undefined): void;
1945
2193
  export interface CollectionProps extends React.HTMLAttributes<HTMLElement> {
@@ -2085,7 +2333,7 @@ export interface SceneProps {
2085
2333
  options?: {
2086
2334
  /** Credentials and headers for the Scene and its models. Inside a `Root`, the Root's. */
2087
2335
  request?: CloverRequest;
2088
- /** Milliseconds the controls stay after a mouse stops moving, as `Canvas`'s. */
2336
+ /** Milliseconds the controls stay after a mouse stops or a finger lifts, as `Canvas`'s. */
2089
2337
  hideDelay?: number;
2090
2338
  };
2091
2339
  /**
@@ -2541,6 +2789,19 @@ export type DefaultProps = Omit<RootProps, "children"> & {
2541
2789
  * stacked boxes each opened by its heading, or `"tabs"`.
2542
2790
  */
2543
2791
  panelLayout?: PanelLayout;
2792
+ /**
2793
+ * The panel's sections, from Clover's own: with
2794
+ * `["contents", "search", "transcript", "annotations"]` it has those four, each still
2795
+ * only where the resource has data for it, and no panel at all where it has none of
2796
+ * them. Default: every section.
2797
+ */
2798
+ panelSections?: readonly PanelSection[];
2799
+ /**
2800
+ * What a panel section's tab or heading says, in place of Clover's own word for it:
2801
+ * `{ annotations: "Chapters" }`, or a word by language tag to say it in several (the
2802
+ * Panel's `labels`).
2803
+ */
2804
+ panelLabels?: PanelSectionLabels;
2544
2805
  /** The downloads, from a Download button beside the panel's About heading. Default `true`. */
2545
2806
  download?: boolean;
2546
2807
  /**
@@ -2573,8 +2834,10 @@ export type DefaultProps = Omit<RootProps, "children"> & {
2573
2834
  * The Body's `collapseControls`.
2574
2835
  */
2575
2836
  collapseControls?: "auto" | "always";
2837
+ /** The Body's Canvas `options`: its gestures, zoom limits and motion. */
2838
+ canvasOptions?: CloverCanvasOptions;
2576
2839
  };
2577
- declare function Default({ className, header, headingLevel, panel, defaultPanelOpen, panelLayout, download, languages, items, singleItem, storageKey, fill, collapseControls, ...root }: DefaultProps): React.JSX.Element;
2840
+ declare function Default({ className, header, headingLevel, panel, defaultPanelOpen, panelLayout, panelSections, panelLabels, download, languages, items, singleItem, storageKey, fill, collapseControls, canvasOptions, ...root }: DefaultProps): React.JSX.Element;
2578
2841
  /**
2579
2842
  * A layout the Viewer draws: one from `@nulib/clover/templates`, or a component of your
2580
2843
  * own that takes the `Clover.Root` props.
package/dist/index.mjs CHANGED
@@ -11,6 +11,7 @@ import { Status } from "./components/Status/Status.mjs";
11
11
  import { Homepage, Id, Metadata, PartOf, Rendering, RequiredStatement, Rights, SeeAlso, Summary, Thumbnail, Value } from "./components/Primitives/Primitives.mjs";
12
12
  import { Logo, Provider } from "./components/Provider/Provider.mjs";
13
13
  import { Panel, Tab } from "./components/Panel/Panel.mjs";
14
+ import { usePanelSections } from "./components/Panel/sections.mjs";
14
15
  import { About } from "./components/Panel/About.mjs";
15
16
  import { Annotations } from "./components/Annotations/Annotations.mjs";
16
17
  import { Transcript } from "./components/Transcript/Transcript.mjs";
@@ -20,6 +21,9 @@ import { Split, SplitHandle, SplitPane } from "./components/Split/Split.mjs";
20
21
  import { Search } from "./components/Search/Search.mjs";
21
22
  import { search } from "./core/search.mjs";
22
23
  import { SEARCH_SET_ID, searchServiceOf } from "./core/search-service.mjs";
24
+ import { CloverMap } from "./components/Map/Map.mjs";
25
+ import { affineTransform, boundsOf, cornersOf, georeferencesOf, navPlaceOf, readGeoreference } from "./core/geo.mjs";
26
+ import { hasMapData } from "./core/geo-detect.mjs";
23
27
  import { setMapWorkerUrl } from "./core/map-config.mjs";
24
28
  import { Collection } from "./components/Collection/Collection.mjs";
25
29
  import { CollectionSelect } from "./components/CollectionSelect/CollectionSelect.mjs";
@@ -63,6 +67,7 @@ export {
63
67
  Items,
64
68
  Label,
65
69
  Logo,
70
+ CloverMap as Map,
66
71
  Metadata,
67
72
  Next,
68
73
  Panel,
@@ -92,18 +97,25 @@ export {
92
97
  Transcript,
93
98
  Value,
94
99
  Viewer,
100
+ affineTransform,
101
+ boundsOf,
95
102
  buildContentState,
96
103
  chaptersOf,
104
+ cornersOf,
97
105
  cueAt,
98
106
  currentContents,
99
107
  decodeContentState,
100
108
  Viewer2 as default,
101
109
  encodeContentState,
110
+ georeferencesOf,
102
111
  groupViews,
112
+ hasMapData,
103
113
  initCloverI18n,
104
114
  localize,
115
+ navPlaceOf,
105
116
  parseVtt,
106
117
  readAs,
118
+ readGeoreference,
107
119
  regionSource,
108
120
  resolveBehavior,
109
121
  resolveDirection,
@@ -127,6 +139,7 @@ export {
127
139
  useManifest,
128
140
  useNavigation,
129
141
  useOneOpen,
142
+ usePanelSections,
130
143
  useProvider,
131
144
  useSequence,
132
145
  useStatus,
@@ -20,7 +20,7 @@ function isInteractive(target, bodyBox) {
20
20
  var _a;
21
21
  let node = target;
22
22
  while (node && node !== bodyBox) {
23
- if (node instanceof HTMLButtonElement || node instanceof HTMLAnchorElement || node instanceof HTMLInputElement || node instanceof HTMLSelectElement || ((_a = node.dataset) == null ? void 0 : _a.cloverCanvasInteractive) !== void 0) {
23
+ if (node instanceof HTMLButtonElement || node instanceof HTMLAnchorElement || node instanceof HTMLInputElement || node instanceof HTMLLabelElement || node instanceof HTMLSelectElement || ((_a = node.dataset) == null ? void 0 : _a.cloverCanvasInteractive) !== void 0) {
24
24
  return true;
25
25
  }
26
26
  node = node.parentElement;