web-doc 0.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 (308) hide show
  1. package/LICENSE-APACHE +201 -0
  2. package/LICENSE-MIT +21 -0
  3. package/README.md +148 -0
  4. package/THIRD_PARTY_NOTICES.md +20 -0
  5. package/bin/copy-assets.mjs +27 -0
  6. package/dist/abort.d.ts +1 -0
  7. package/dist/abort.js +18 -0
  8. package/dist/adapters/bitmap.d.ts +9 -0
  9. package/dist/adapters/bitmap.js +63 -0
  10. package/dist/adapters/csv-parser.d.ts +7 -0
  11. package/dist/adapters/csv-parser.js +124 -0
  12. package/dist/adapters/csv.d.ts +26 -0
  13. package/dist/adapters/csv.js +231 -0
  14. package/dist/adapters/image.d.ts +41 -0
  15. package/dist/adapters/image.js +198 -0
  16. package/dist/adapters/office.d.ts +211 -0
  17. package/dist/adapters/office.js +672 -0
  18. package/dist/adapters/pdf.d.ts +32 -0
  19. package/dist/adapters/pdf.js +429 -0
  20. package/dist/adapters/svg.d.ts +17 -0
  21. package/dist/adapters/svg.js +123 -0
  22. package/dist/assets/image/index.d.ts +75 -0
  23. package/dist/assets/image/index.js +289 -0
  24. package/dist/assets/image/index_bg.wasm +0 -0
  25. package/dist/assets/image/index_bg.wasm.d.ts +12 -0
  26. package/dist/assets/legacy/index.d.ts +54 -0
  27. package/dist/assets/legacy/index.js +306 -0
  28. package/dist/assets/legacy/index_bg.wasm +0 -0
  29. package/dist/assets/legacy/index_bg.wasm.d.ts +9 -0
  30. package/dist/assets/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
  31. package/dist/assets/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
  32. package/dist/assets/pdfjs/cmaps/78-H.bcmap +0 -0
  33. package/dist/assets/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
  34. package/dist/assets/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
  35. package/dist/assets/pdfjs/cmaps/78-V.bcmap +0 -0
  36. package/dist/assets/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
  37. package/dist/assets/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
  38. package/dist/assets/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
  39. package/dist/assets/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
  40. package/dist/assets/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
  41. package/dist/assets/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
  42. package/dist/assets/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
  43. package/dist/assets/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
  44. package/dist/assets/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
  45. package/dist/assets/pdfjs/cmaps/Add-H.bcmap +0 -0
  46. package/dist/assets/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
  47. package/dist/assets/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
  48. package/dist/assets/pdfjs/cmaps/Add-V.bcmap +0 -0
  49. package/dist/assets/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
  50. package/dist/assets/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
  51. package/dist/assets/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
  52. package/dist/assets/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
  53. package/dist/assets/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
  54. package/dist/assets/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
  55. package/dist/assets/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
  56. package/dist/assets/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
  57. package/dist/assets/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
  58. package/dist/assets/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
  59. package/dist/assets/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
  60. package/dist/assets/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
  61. package/dist/assets/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
  62. package/dist/assets/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
  63. package/dist/assets/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
  64. package/dist/assets/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
  65. package/dist/assets/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
  66. package/dist/assets/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
  67. package/dist/assets/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
  68. package/dist/assets/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
  69. package/dist/assets/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
  70. package/dist/assets/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
  71. package/dist/assets/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
  72. package/dist/assets/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
  73. package/dist/assets/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
  74. package/dist/assets/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
  75. package/dist/assets/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
  76. package/dist/assets/pdfjs/cmaps/B5-H.bcmap +0 -0
  77. package/dist/assets/pdfjs/cmaps/B5-V.bcmap +0 -0
  78. package/dist/assets/pdfjs/cmaps/B5pc-H.bcmap +0 -0
  79. package/dist/assets/pdfjs/cmaps/B5pc-V.bcmap +0 -0
  80. package/dist/assets/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
  81. package/dist/assets/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
  82. package/dist/assets/pdfjs/cmaps/CNS1-H.bcmap +0 -0
  83. package/dist/assets/pdfjs/cmaps/CNS1-V.bcmap +0 -0
  84. package/dist/assets/pdfjs/cmaps/CNS2-H.bcmap +0 -0
  85. package/dist/assets/pdfjs/cmaps/CNS2-V.bcmap +3 -0
  86. package/dist/assets/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
  87. package/dist/assets/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
  88. package/dist/assets/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
  89. package/dist/assets/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
  90. package/dist/assets/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
  91. package/dist/assets/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
  92. package/dist/assets/pdfjs/cmaps/EUC-H.bcmap +0 -0
  93. package/dist/assets/pdfjs/cmaps/EUC-V.bcmap +0 -0
  94. package/dist/assets/pdfjs/cmaps/Ext-H.bcmap +0 -0
  95. package/dist/assets/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
  96. package/dist/assets/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
  97. package/dist/assets/pdfjs/cmaps/Ext-V.bcmap +0 -0
  98. package/dist/assets/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
  99. package/dist/assets/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
  100. package/dist/assets/pdfjs/cmaps/GB-H.bcmap +4 -0
  101. package/dist/assets/pdfjs/cmaps/GB-V.bcmap +0 -0
  102. package/dist/assets/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
  103. package/dist/assets/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
  104. package/dist/assets/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
  105. package/dist/assets/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
  106. package/dist/assets/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
  107. package/dist/assets/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
  108. package/dist/assets/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
  109. package/dist/assets/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
  110. package/dist/assets/pdfjs/cmaps/GBT-H.bcmap +0 -0
  111. package/dist/assets/pdfjs/cmaps/GBT-V.bcmap +0 -0
  112. package/dist/assets/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
  113. package/dist/assets/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
  114. package/dist/assets/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
  115. package/dist/assets/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
  116. package/dist/assets/pdfjs/cmaps/H.bcmap +0 -0
  117. package/dist/assets/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
  118. package/dist/assets/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
  119. package/dist/assets/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
  120. package/dist/assets/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
  121. package/dist/assets/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
  122. package/dist/assets/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
  123. package/dist/assets/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
  124. package/dist/assets/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
  125. package/dist/assets/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
  126. package/dist/assets/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
  127. package/dist/assets/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
  128. package/dist/assets/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
  129. package/dist/assets/pdfjs/cmaps/Hankaku.bcmap +0 -0
  130. package/dist/assets/pdfjs/cmaps/Hiragana.bcmap +0 -0
  131. package/dist/assets/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
  132. package/dist/assets/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
  133. package/dist/assets/pdfjs/cmaps/KSC-H.bcmap +0 -0
  134. package/dist/assets/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
  135. package/dist/assets/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
  136. package/dist/assets/pdfjs/cmaps/KSC-V.bcmap +0 -0
  137. package/dist/assets/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
  138. package/dist/assets/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
  139. package/dist/assets/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
  140. package/dist/assets/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
  141. package/dist/assets/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
  142. package/dist/assets/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
  143. package/dist/assets/pdfjs/cmaps/Katakana.bcmap +0 -0
  144. package/dist/assets/pdfjs/cmaps/LICENSE +36 -0
  145. package/dist/assets/pdfjs/cmaps/NWP-H.bcmap +0 -0
  146. package/dist/assets/pdfjs/cmaps/NWP-V.bcmap +0 -0
  147. package/dist/assets/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
  148. package/dist/assets/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
  149. package/dist/assets/pdfjs/cmaps/Roman.bcmap +0 -0
  150. package/dist/assets/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
  151. package/dist/assets/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
  152. package/dist/assets/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
  153. package/dist/assets/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
  154. package/dist/assets/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
  155. package/dist/assets/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
  156. package/dist/assets/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
  157. package/dist/assets/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
  158. package/dist/assets/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
  159. package/dist/assets/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
  160. package/dist/assets/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
  161. package/dist/assets/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
  162. package/dist/assets/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
  163. package/dist/assets/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
  164. package/dist/assets/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
  165. package/dist/assets/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
  166. package/dist/assets/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
  167. package/dist/assets/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
  168. package/dist/assets/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
  169. package/dist/assets/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
  170. package/dist/assets/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
  171. package/dist/assets/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
  172. package/dist/assets/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
  173. package/dist/assets/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
  174. package/dist/assets/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
  175. package/dist/assets/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
  176. package/dist/assets/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
  177. package/dist/assets/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
  178. package/dist/assets/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
  179. package/dist/assets/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
  180. package/dist/assets/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
  181. package/dist/assets/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
  182. package/dist/assets/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
  183. package/dist/assets/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
  184. package/dist/assets/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
  185. package/dist/assets/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
  186. package/dist/assets/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
  187. package/dist/assets/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
  188. package/dist/assets/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
  189. package/dist/assets/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
  190. package/dist/assets/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
  191. package/dist/assets/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
  192. package/dist/assets/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
  193. package/dist/assets/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
  194. package/dist/assets/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
  195. package/dist/assets/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
  196. package/dist/assets/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
  197. package/dist/assets/pdfjs/cmaps/V.bcmap +0 -0
  198. package/dist/assets/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
  199. package/dist/assets/pdfjs/iccs/CGATS001Compat-v2-micro.icc +0 -0
  200. package/dist/assets/pdfjs/iccs/LICENSE +116 -0
  201. package/dist/assets/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
  202. package/dist/assets/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
  203. package/dist/assets/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
  204. package/dist/assets/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
  205. package/dist/assets/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
  206. package/dist/assets/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
  207. package/dist/assets/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
  208. package/dist/assets/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
  209. package/dist/assets/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
  210. package/dist/assets/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
  211. package/dist/assets/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
  212. package/dist/assets/pdfjs/standard_fonts/LICENSE_LIBERATION +102 -0
  213. package/dist/assets/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
  214. package/dist/assets/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
  215. package/dist/assets/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
  216. package/dist/assets/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
  217. package/dist/assets/pdfjs/wasm/LICENSE_JBIG2 +196 -0
  218. package/dist/assets/pdfjs/wasm/LICENSE_OPENJPEG +39 -0
  219. package/dist/assets/pdfjs/wasm/LICENSE_PDFJS_JBIG2 +13 -0
  220. package/dist/assets/pdfjs/wasm/LICENSE_PDFJS_OPENJPEG +22 -0
  221. package/dist/assets/pdfjs/wasm/LICENSE_PDFJS_QCMS +22 -0
  222. package/dist/assets/pdfjs/wasm/LICENSE_QCMS +21 -0
  223. package/dist/assets/pdfjs/wasm/jbig2.wasm +0 -0
  224. package/dist/assets/pdfjs/wasm/jbig2_nowasm_fallback.js +15 -0
  225. package/dist/assets/pdfjs/wasm/openjpeg.wasm +0 -0
  226. package/dist/assets/pdfjs/wasm/openjpeg_nowasm_fallback.js +17 -0
  227. package/dist/assets/pdfjs/wasm/qcms_bg.wasm +0 -0
  228. package/dist/assets/pdfjs/wasm/quickjs-eval.js +16 -0
  229. package/dist/assets/pdfjs/wasm/quickjs-eval.wasm +0 -0
  230. package/dist/client.d.ts +20 -0
  231. package/dist/client.js +82 -0
  232. package/dist/contracts.d.ts +379 -0
  233. package/dist/contracts.js +22 -0
  234. package/dist/csv-worker.d.ts +1 -0
  235. package/dist/csv-worker.js +17 -0
  236. package/dist/detect.d.ts +15 -0
  237. package/dist/detect.js +290 -0
  238. package/dist/errors.d.ts +14 -0
  239. package/dist/errors.js +40 -0
  240. package/dist/font-manifest.d.ts +11 -0
  241. package/dist/font-manifest.js +31 -0
  242. package/dist/fonts/OFL-1.1.txt +88 -0
  243. package/dist/fonts/THIRD_PARTY_NOTICES.md +10 -0
  244. package/dist/fonts/manifest.json +83 -0
  245. package/dist/fonts/noto-sans-arabic.woff2 +0 -0
  246. package/dist/fonts/noto-sans-bengali.woff2 +0 -0
  247. package/dist/fonts/noto-sans-cjk.woff2 +0 -0
  248. package/dist/fonts/noto-sans-devanagari.woff2 +0 -0
  249. package/dist/fonts/noto-sans-gujarati.woff2 +0 -0
  250. package/dist/fonts/noto-sans-gurmukhi.woff2 +0 -0
  251. package/dist/fonts/noto-sans-japanese.woff2 +0 -0
  252. package/dist/fonts/noto-sans-kannada.woff2 +0 -0
  253. package/dist/fonts/noto-sans-korean.woff2 +0 -0
  254. package/dist/fonts/noto-sans-latin-cyrillic.woff2 +0 -0
  255. package/dist/fonts/noto-sans-malayalam.woff2 +0 -0
  256. package/dist/fonts/noto-sans-odia.woff2 +0 -0
  257. package/dist/fonts/noto-sans-tamil.woff2 +0 -0
  258. package/dist/fonts/noto-sans-telugu.woff2 +0 -0
  259. package/dist/fonts.d.ts +20 -0
  260. package/dist/fonts.js +238 -0
  261. package/dist/format.d.ts +1 -0
  262. package/dist/format.js +1 -0
  263. package/dist/headless.d.ts +18 -0
  264. package/dist/headless.js +18 -0
  265. package/dist/i18n.d.ts +4 -0
  266. package/dist/i18n.js +55 -0
  267. package/dist/image-worker.d.ts +1 -0
  268. package/dist/image-worker.js +41 -0
  269. package/dist/index.d.ts +27 -0
  270. package/dist/index.js +29 -0
  271. package/dist/interaction.d.ts +24 -0
  272. package/dist/interaction.js +183 -0
  273. package/dist/legacy-converter-worker.d.ts +1 -0
  274. package/dist/legacy-converter-worker.js +19 -0
  275. package/dist/limits.d.ts +4 -0
  276. package/dist/limits.js +162 -0
  277. package/dist/registry.d.ts +8 -0
  278. package/dist/registry.js +35 -0
  279. package/dist/render-scheduler.d.ts +8 -0
  280. package/dist/render-scheduler.js +63 -0
  281. package/dist/source.d.ts +14 -0
  282. package/dist/source.js +116 -0
  283. package/dist/spreadsheet-viewport.d.ts +34 -0
  284. package/dist/spreadsheet-viewport.js +1035 -0
  285. package/dist/styles.css +137 -0
  286. package/dist/ui-styles.d.ts +1 -0
  287. package/dist/ui-styles.js +139 -0
  288. package/dist/ui.d.ts +8 -0
  289. package/dist/ui.js +390 -0
  290. package/dist/viewer.d.ts +52 -0
  291. package/dist/viewer.js +901 -0
  292. package/dist/viewport.d.ts +54 -0
  293. package/dist/viewport.js +907 -0
  294. package/dist/worker-adapter.d.ts +24 -0
  295. package/dist/worker-adapter.js +97 -0
  296. package/dist/worker-client.d.ts +23 -0
  297. package/dist/worker-client.js +105 -0
  298. package/dist/worker-endpoint.d.ts +13 -0
  299. package/dist/worker-endpoint.js +57 -0
  300. package/dist/worker-protocol.d.ts +48 -0
  301. package/dist/worker-protocol.js +14 -0
  302. package/dist/worker.d.ts +4 -0
  303. package/dist/worker.js +4 -0
  304. package/dist/workers/csv-worker.js +160 -0
  305. package/dist/workers/image-worker.js +41 -0
  306. package/dist/workers/legacy-converter-worker.js +19 -0
  307. package/dist/workers/pdf.worker.min.mjs +28 -0
  308. package/package.json +74 -0
@@ -0,0 +1,907 @@
1
+ import { snapGraphemeOffset } from "./interaction.js";
2
+ import { SpreadsheetViewport } from "./spreadsheet-viewport.js";
3
+ const BASE_WIDTH = 816;
4
+ const BASE_HEIGHT = 1056;
5
+ const PAGE_GAP = 24;
6
+ export class AdaptiveViewport {
7
+ #container;
8
+ #host;
9
+ #options;
10
+ #strategy;
11
+ #kind = "page";
12
+ constructor(container, host, options) {
13
+ this.#container = container;
14
+ this.#host = host;
15
+ this.#options = options;
16
+ this.#strategy = new ViewerViewport(container, host, options);
17
+ }
18
+ setDocument(info) {
19
+ const nextKind = info?.unit === "sheet" ? "sheet" : "page";
20
+ if (nextKind !== this.#kind) {
21
+ this.#strategy.destroy();
22
+ this.#kind = nextKind;
23
+ this.#strategy =
24
+ nextKind === "sheet"
25
+ ? new SpreadsheetViewport(this.#container, this.#host)
26
+ : new ViewerViewport(this.#container, this.#host, this.#options);
27
+ }
28
+ this.#strategy.setDocument(info);
29
+ }
30
+ update() {
31
+ this.#strategy.update();
32
+ }
33
+ panBy(deltaX, deltaY) {
34
+ this.#strategy.panBy(deltaX, deltaY);
35
+ }
36
+ goToPage(pageIndex) {
37
+ this.#strategy.goToPage(pageIndex);
38
+ }
39
+ fitWidth() {
40
+ return this.#strategy.fitWidth();
41
+ }
42
+ fitPage() {
43
+ return this.#strategy.fitPage();
44
+ }
45
+ destroy() {
46
+ this.#strategy.destroy();
47
+ }
48
+ }
49
+ export class ViewerViewport {
50
+ #host;
51
+ #container;
52
+ #root;
53
+ #spacer;
54
+ #slots = new Map();
55
+ #overscan;
56
+ #layout;
57
+ #onScroll = () => this.#handleScroll();
58
+ #onWheel = (event) => this.#handleWheel(event);
59
+ #onPointerDown = (event) => this.#handlePointerDown(event);
60
+ #onPointerMove = (event) => this.#handlePointerMove(event);
61
+ #onPointerUp = (event) => this.#handlePointerUp(event);
62
+ #onKeyDown = (event) => this.#handleKeyDown(event);
63
+ #onCopy = (event) => this.#handleCopy(event);
64
+ #onSelectionChange = () => this.#handleSelectionChange();
65
+ #pointers = new Map();
66
+ #info;
67
+ #frame = 0;
68
+ #resizeObserver;
69
+ #destroyed = false;
70
+ #appliedZoom;
71
+ #zoomSettleTimer;
72
+ #zoomGestureActive = false;
73
+ #lastPanPointer;
74
+ #pinchStart;
75
+ #cellAnchor;
76
+ #cellFocus;
77
+ #cellPointerId;
78
+ constructor(container, host, options) {
79
+ this.#container = container;
80
+ this.#host = host;
81
+ this.#overscan = Math.min(5, Math.max(0, Math.trunc(options.overscan ?? 1)));
82
+ this.#layout = options.layout ?? "continuous";
83
+ this.#appliedZoom = host.state.zoom;
84
+ this.#root = document.createElement("div");
85
+ this.#root.dataset.zrimo = "viewport";
86
+ this.#root.tabIndex = 0;
87
+ this.#root.setAttribute("role", "application");
88
+ this.#root.setAttribute("aria-label", "Document viewport");
89
+ Object.assign(this.#root.style, {
90
+ position: "relative",
91
+ overflow: "auto",
92
+ width: "100%",
93
+ height: "100%",
94
+ minHeight: "160px",
95
+ background: "var(--zrimo-background, #e9edf2)",
96
+ touchAction: "none",
97
+ contain: "strict",
98
+ scrollbarGutter: "stable both-edges",
99
+ });
100
+ this.#spacer = document.createElement("div");
101
+ Object.assign(this.#spacer.style, {
102
+ position: "relative",
103
+ minWidth: `${BASE_WIDTH}px`,
104
+ });
105
+ this.#root.append(this.#spacer);
106
+ this.#container.append(this.#root);
107
+ this.#root.addEventListener("scroll", this.#onScroll, { passive: true });
108
+ this.#root.addEventListener("wheel", this.#onWheel, { passive: false });
109
+ this.#root.addEventListener("pointerdown", this.#onPointerDown);
110
+ this.#root.addEventListener("pointermove", this.#onPointerMove);
111
+ this.#root.addEventListener("pointerup", this.#onPointerUp);
112
+ this.#root.addEventListener("pointercancel", this.#onPointerUp);
113
+ this.#root.addEventListener("keydown", this.#onKeyDown);
114
+ document.addEventListener("copy", this.#onCopy);
115
+ document.addEventListener("selectionchange", this.#onSelectionChange);
116
+ if (typeof ResizeObserver !== "undefined") {
117
+ this.#resizeObserver = new ResizeObserver(() => this.schedule());
118
+ this.#resizeObserver.observe(this.#root);
119
+ }
120
+ }
121
+ setDocument(info) {
122
+ this.#info = info;
123
+ this.#appliedZoom = this.#host.state.zoom;
124
+ this.#root.scrollTo({ left: 0, top: 0 });
125
+ this.#clearSlots();
126
+ this.schedule();
127
+ }
128
+ update() {
129
+ const zoom = this.#host.state.zoom;
130
+ if (this.#info &&
131
+ this.#layout === "continuous" &&
132
+ zoom !== this.#appliedZoom) {
133
+ const oldMetrics = pageMetrics(this.#info, this.#appliedZoom);
134
+ const newMetrics = pageMetrics(this.#info, zoom);
135
+ const pageIndex = pageAtOffset(oldMetrics, this.#root.scrollTop);
136
+ const oldTop = oldMetrics.offsets[pageIndex] ?? 0;
137
+ const newTop = newMetrics.offsets[pageIndex] ?? 0;
138
+ this.#root.scrollTop =
139
+ newTop + ((this.#root.scrollTop - oldTop) * zoom) / this.#appliedZoom;
140
+ }
141
+ this.#appliedZoom = zoom;
142
+ this.schedule();
143
+ }
144
+ panBy(deltaX, deltaY) {
145
+ this.#root.scrollLeft += deltaX;
146
+ this.#root.scrollTop += deltaY;
147
+ this.#host.onPan(this.#root.scrollLeft, this.#root.scrollTop);
148
+ this.schedule();
149
+ }
150
+ goToPage(pageIndex) {
151
+ if (this.#layout === "continuous") {
152
+ const metrics = pageMetrics(this.#info, this.#host.state.zoom);
153
+ this.#root.scrollTop = metrics.offsets[Math.max(0, pageIndex)] ?? 0;
154
+ }
155
+ this.schedule();
156
+ }
157
+ fitWidth() {
158
+ const size = naturalPageSize(this.#info, this.#host.state.pageIndex);
159
+ return Math.max(0.1, Math.min(8, (this.#root.clientWidth - 24) / size.width));
160
+ }
161
+ fitPage() {
162
+ const size = naturalPageSize(this.#info, this.#host.state.pageIndex);
163
+ return Math.max(0.1, Math.min(8, (this.#root.clientWidth - 24) / size.width, (this.#root.clientHeight - 24) / size.height));
164
+ }
165
+ schedule() {
166
+ if (this.#destroyed || this.#frame)
167
+ return;
168
+ this.#frame = requestAnimationFrame(() => {
169
+ this.#frame = 0;
170
+ this.#renderVisible();
171
+ });
172
+ }
173
+ destroy() {
174
+ if (this.#destroyed)
175
+ return;
176
+ this.#destroyed = true;
177
+ if (this.#frame)
178
+ cancelAnimationFrame(this.#frame);
179
+ if (this.#zoomSettleTimer)
180
+ clearTimeout(this.#zoomSettleTimer);
181
+ this.#resizeObserver?.disconnect();
182
+ this.#root.removeEventListener("scroll", this.#onScroll);
183
+ this.#root.removeEventListener("wheel", this.#onWheel);
184
+ this.#root.removeEventListener("pointerdown", this.#onPointerDown);
185
+ this.#root.removeEventListener("pointermove", this.#onPointerMove);
186
+ this.#root.removeEventListener("pointerup", this.#onPointerUp);
187
+ this.#root.removeEventListener("pointercancel", this.#onPointerUp);
188
+ this.#root.removeEventListener("keydown", this.#onKeyDown);
189
+ document.removeEventListener("copy", this.#onCopy);
190
+ document.removeEventListener("selectionchange", this.#onSelectionChange);
191
+ this.#clearSlots();
192
+ this.#root.remove();
193
+ }
194
+ #renderVisible() {
195
+ const info = this.#info;
196
+ const state = this.#host.state;
197
+ if (!info || state.status !== "ready") {
198
+ this.#spacer.style.height = "0px";
199
+ this.#clearSlots();
200
+ return;
201
+ }
202
+ const count = info.pageCount;
203
+ const metrics = pageMetrics(info, state.zoom);
204
+ this.#spacer.style.height =
205
+ this.#layout === "single" ? "100%" : `${metrics.totalHeight}px`;
206
+ this.#spacer.style.minWidth = `${metrics.maxWidth + 24}px`;
207
+ const range = this.#layout === "single"
208
+ ? { start: state.pageIndex, end: state.pageIndex + 1 }
209
+ : visiblePageRange(this.#root.scrollTop, this.#root.clientHeight, metrics, this.#overscan);
210
+ for (const [pageIndex, slot] of this.#slots)
211
+ if (pageIndex < range.start || pageIndex >= range.end) {
212
+ slot.controller?.abort();
213
+ slot.root.remove();
214
+ this.#slots.delete(pageIndex);
215
+ }
216
+ for (let pageIndex = range.start; pageIndex < range.end; pageIndex += 1) {
217
+ const slot = this.#slots.get(pageIndex) ?? this.#createSlot(pageIndex);
218
+ const width = metrics.widths[pageIndex] ?? BASE_WIDTH * state.zoom;
219
+ const height = metrics.heights[pageIndex] ?? BASE_HEIGHT * state.zoom;
220
+ const top = this.#layout === "single" ? 12 : (metrics.offsets[pageIndex] ?? 0) + 12;
221
+ const contentWidth = Math.max(this.#root.clientWidth, metrics.maxWidth + 24);
222
+ slot.root.style.top = `${top}px`;
223
+ slot.root.style.left = `${Math.max(12, (contentWidth - width) / 2)}px`;
224
+ slot.root.style.width = `${width}px`;
225
+ slot.root.style.minHeight = `${height}px`;
226
+ slot.root.style.transform = "none";
227
+ const highlights = this.#host
228
+ .getSearchMatches(pageIndex)
229
+ .map((match) => `${match.start}:${match.end}`)
230
+ .join(",");
231
+ const renderKey = `${state.zoom}:${window.devicePixelRatio || 1}:${highlights}`;
232
+ if (slot.renderKey === undefined ||
233
+ (!this.#zoomGestureActive && slot.renderKey !== renderKey)) {
234
+ slot.renderKey = renderKey;
235
+ this.#renderSlot(pageIndex, slot);
236
+ }
237
+ }
238
+ }
239
+ #createSlot(pageIndex) {
240
+ const root = document.createElement("div");
241
+ Object.assign(root.style, {
242
+ position: "absolute",
243
+ background: "white",
244
+ boxShadow: "0 2px 8px rgb(16 24 40 / 18%)",
245
+ overflow: "hidden",
246
+ });
247
+ root.dataset.pageIndex = String(pageIndex);
248
+ const canvas = document.createElement("canvas");
249
+ Object.assign(canvas.style, {
250
+ display: "block",
251
+ width: "100%",
252
+ height: "auto",
253
+ maxWidth: "none",
254
+ });
255
+ const textLayer = document.createElement("div");
256
+ const highlightLayer = document.createElement("div");
257
+ textLayer.dataset.zrimoLayer = "text";
258
+ highlightLayer.dataset.zrimoLayer = "highlight";
259
+ for (const layer of [highlightLayer, textLayer])
260
+ Object.assign(layer.style, {
261
+ position: "absolute",
262
+ inset: "0",
263
+ overflow: "hidden",
264
+ });
265
+ Object.assign(highlightLayer.style, {
266
+ pointerEvents: "none",
267
+ userSelect: "none",
268
+ });
269
+ Object.assign(textLayer.style, {
270
+ userSelect: "text",
271
+ cursor: "text",
272
+ });
273
+ root.append(canvas, highlightLayer, textLayer);
274
+ this.#spacer.append(root);
275
+ const slot = { root, canvas, highlightLayer, textLayer, generation: 0 };
276
+ this.#slots.set(pageIndex, slot);
277
+ return slot;
278
+ }
279
+ async #renderSlot(pageIndex, slot) {
280
+ slot.controller?.abort();
281
+ const controller = new AbortController();
282
+ slot.controller = controller;
283
+ const generation = ++slot.generation;
284
+ const zoom = this.#host.state.zoom;
285
+ try {
286
+ let renderError;
287
+ const rendering = this.#host
288
+ .renderPage(pageIndex, slot.canvas, {
289
+ zoom,
290
+ devicePixelRatio: window.devicePixelRatio || 1,
291
+ priority: pageIndex === this.#host.state.pageIndex ? "visible" : "adjacent",
292
+ signal: controller.signal,
293
+ })
294
+ .catch((error) => {
295
+ renderError = error;
296
+ });
297
+ const runs = await this.#host.getTextRuns(pageIndex, controller.signal);
298
+ if (controller.signal.aborted || slot.generation !== generation)
299
+ return;
300
+ await this.#buildTextLayers(slot.textLayer, slot.highlightLayer, pageIndex, runs, zoom, controller.signal);
301
+ if (controller.signal.aborted || slot.generation !== generation)
302
+ return;
303
+ await rendering;
304
+ if (renderError)
305
+ throw renderError;
306
+ if (controller.signal.aborted || slot.generation !== generation)
307
+ return;
308
+ const cssWidth = slot.canvas.width / (window.devicePixelRatio || 1);
309
+ const cssHeight = slot.canvas.height / (window.devicePixelRatio || 1);
310
+ slot.root.style.width = `${cssWidth}px`;
311
+ slot.root.style.height = `${cssHeight}px`;
312
+ }
313
+ catch (error) {
314
+ if (!controller.signal.aborted) {
315
+ slot.root.dataset.renderError =
316
+ error instanceof Error ? error.message : String(error);
317
+ }
318
+ }
319
+ }
320
+ async #buildTextLayers(textLayer, highlightLayer, pageIndex, runs, zoom, signal) {
321
+ textLayer.replaceChildren();
322
+ highlightLayer.replaceChildren();
323
+ const matches = this.#host.getSearchMatches(pageIndex);
324
+ if (runs.length > 0 && runs.every(isDocxTextRun)) {
325
+ const coordinateWidth = runs[0].coordinateWidth;
326
+ const coordinateHeight = runs[0].coordinateHeight;
327
+ scaleOverlay(textLayer, coordinateWidth, coordinateHeight, zoom);
328
+ scaleOverlay(highlightLayer, coordinateWidth, coordinateHeight, zoom);
329
+ const { buildDocxHighlightLayer, buildDocxTextLayer } = await import("@silurus/ooxml/docx");
330
+ if (signal.aborted)
331
+ return;
332
+ const docxRuns = runs.map(toDocxTextRunInfo);
333
+ const measureForFont = textMeasureFactory();
334
+ buildDocxHighlightLayer(highlightLayer, docxRuns, toDocxHighlightMatches(runs, matches), coordinateWidth, coordinateHeight, measureForFont, { match: "rgb(255 215 0 / 45%)" });
335
+ buildDocxTextLayer(textLayer, docxRuns, coordinateWidth, coordinateHeight, undefined, measureForFont);
336
+ annotateTextSpans(textLayer, pageIndex, runs);
337
+ return;
338
+ }
339
+ if (runs.length > 0 && runs.every(isPdfTextRun)) {
340
+ const coordinateWidth = runs[0].coordinateWidth;
341
+ const coordinateHeight = runs[0].coordinateHeight;
342
+ scaleOverlay(textLayer, coordinateWidth, coordinateHeight, zoom);
343
+ scaleOverlay(highlightLayer, coordinateWidth, coordinateHeight, zoom);
344
+ buildPdfTextLayers(textLayer, highlightLayer, pageIndex, runs, matches);
345
+ return;
346
+ }
347
+ resetOverlay(textLayer);
348
+ resetOverlay(highlightLayer);
349
+ let logicalOffset = 0;
350
+ for (const run of runs) {
351
+ const logicalStart = run.logicalStart ?? logicalOffset;
352
+ const logicalEnd = run.logicalEnd ?? logicalStart + run.text.length;
353
+ const span = document.createElement("span");
354
+ span.textContent = run.text;
355
+ span.dataset.pageIndex = String(pageIndex);
356
+ span.dataset.start = String(logicalStart);
357
+ span.dataset.end = String(logicalEnd);
358
+ if (run.row !== undefined)
359
+ span.dataset.row = String(run.row);
360
+ if (run.column !== undefined)
361
+ span.dataset.column = String(run.column);
362
+ Object.assign(span.style, {
363
+ position: "absolute",
364
+ left: `${run.x * zoom}px`,
365
+ top: `${run.y * zoom}px`,
366
+ width: `${Math.max(1, run.width * zoom)}px`,
367
+ height: `${Math.max(1, run.height * zoom)}px`,
368
+ color: "transparent",
369
+ whiteSpace: "pre",
370
+ lineHeight: `${Math.max(1, run.height * zoom)}px`,
371
+ direction: run.direction ?? "ltr",
372
+ font: run.font,
373
+ fontSize: run.font === undefined && run.fontSize !== undefined
374
+ ? `${run.fontSize * zoom}px`
375
+ : undefined,
376
+ letterSpacing: run.letterSpacingPx === undefined
377
+ ? undefined
378
+ : `${run.letterSpacingPx * zoom}px`,
379
+ transform: run.transform,
380
+ transformOrigin: run.transform ? "top left" : undefined,
381
+ });
382
+ textLayer.append(span);
383
+ if (matches.some((match) => match.start < logicalEnd && match.end > logicalStart)) {
384
+ const highlight = document.createElement("div");
385
+ Object.assign(highlight.style, {
386
+ position: "absolute",
387
+ left: `${run.x * zoom}px`,
388
+ top: `${run.y * zoom}px`,
389
+ width: `${Math.max(1, run.width * zoom)}px`,
390
+ height: `${Math.max(1, run.height * zoom)}px`,
391
+ background: "var(--zrimo-highlight, rgb(255 215 0 / 45%))",
392
+ pointerEvents: "none",
393
+ });
394
+ highlightLayer.append(highlight);
395
+ }
396
+ logicalOffset = logicalEnd;
397
+ }
398
+ }
399
+ #handleScroll() {
400
+ const state = this.#host.state;
401
+ if (this.#layout === "continuous" && state.pageCount > 0) {
402
+ const metrics = pageMetrics(this.#info, state.zoom);
403
+ const visible = pageAtOffset(metrics, this.#root.scrollTop + this.#root.clientHeight * 0.35);
404
+ if (visible !== state.pageIndex)
405
+ this.#host.onVisiblePage(visible);
406
+ }
407
+ this.#host.onPan(this.#root.scrollLeft, this.#root.scrollTop);
408
+ this.schedule();
409
+ }
410
+ #handleWheel(event) {
411
+ if (!event.ctrlKey && !event.metaKey)
412
+ return;
413
+ event.preventDefault();
414
+ const factor = Math.exp(-event.deltaY * 0.002);
415
+ this.#deferCrispRender();
416
+ this.#host.onZoom(this.#host.state.zoom * factor);
417
+ }
418
+ #handlePointerDown(event) {
419
+ const target = event.target;
420
+ const row = Number(target.dataset.row);
421
+ const column = Number(target.dataset.column);
422
+ if (Number.isInteger(row) &&
423
+ row > 0 &&
424
+ Number.isInteger(column) &&
425
+ column > 0) {
426
+ this.#root.focus({ preventScroll: true });
427
+ const cell = { sheetIndex: this.#host.state.pageIndex, row, column };
428
+ this.#cellAnchor = cell;
429
+ this.#cellFocus = cell;
430
+ this.#cellPointerId = event.pointerId;
431
+ this.#selectCellRange(cell);
432
+ this.#capturePointer(event);
433
+ return;
434
+ }
435
+ if (event.button !== 0 || target.closest("[data-start]"))
436
+ return;
437
+ event.preventDefault();
438
+ this.#cellAnchor = undefined;
439
+ this.#cellFocus = undefined;
440
+ this.#root.focus({ preventScroll: true });
441
+ this.#pointers.set(event.pointerId, { x: event.clientX, y: event.clientY });
442
+ this.#capturePointer(event);
443
+ if (this.#pointers.size === 1)
444
+ this.#lastPanPointer = { x: event.clientX, y: event.clientY };
445
+ else if (this.#pointers.size === 2) {
446
+ this.#pinchStart = {
447
+ distance: pointerDistance(this.#pointers),
448
+ zoom: this.#host.state.zoom,
449
+ };
450
+ this.#lastPanPointer = undefined;
451
+ }
452
+ }
453
+ #handlePointerMove(event) {
454
+ if (this.#cellPointerId === event.pointerId &&
455
+ this.#cellAnchor &&
456
+ this.#cellFocus) {
457
+ const target = document.elementFromPoint(event.clientX, event.clientY);
458
+ const cell = target?.closest("[data-row][data-column]");
459
+ const row = Number(cell?.dataset.row);
460
+ const column = Number(cell?.dataset.column);
461
+ if (Number.isInteger(row) &&
462
+ row > 0 &&
463
+ Number.isInteger(column) &&
464
+ column > 0) {
465
+ this.#cellFocus = {
466
+ sheetIndex: this.#cellAnchor.sheetIndex,
467
+ row,
468
+ column,
469
+ };
470
+ this.#selectCellRange(this.#cellFocus);
471
+ }
472
+ return;
473
+ }
474
+ if (!this.#pointers.has(event.pointerId))
475
+ return;
476
+ this.#pointers.set(event.pointerId, { x: event.clientX, y: event.clientY });
477
+ if (this.#pointers.size >= 2 && this.#pinchStart) {
478
+ event.preventDefault();
479
+ const distance = pointerDistance(this.#pointers);
480
+ if (this.#pinchStart.distance > 0) {
481
+ this.#deferCrispRender();
482
+ this.#host.onZoom(this.#pinchStart.zoom * (distance / this.#pinchStart.distance));
483
+ }
484
+ return;
485
+ }
486
+ const previous = this.#lastPanPointer;
487
+ if (previous)
488
+ this.panBy(previous.x - event.clientX, previous.y - event.clientY);
489
+ this.#lastPanPointer = { x: event.clientX, y: event.clientY };
490
+ }
491
+ #handlePointerUp(event) {
492
+ if (this.#cellPointerId === event.pointerId) {
493
+ this.#cellPointerId = undefined;
494
+ this.#releasePointer(event.pointerId);
495
+ return;
496
+ }
497
+ this.#pointers.delete(event.pointerId);
498
+ this.#releasePointer(event.pointerId);
499
+ if (this.#pointers.size < 2)
500
+ this.#pinchStart = undefined;
501
+ this.#lastPanPointer = this.#pointers.values().next().value;
502
+ }
503
+ #handleKeyDown(event) {
504
+ if (event.shiftKey && this.#cellAnchor && this.#cellFocus) {
505
+ const delta = keyCellDelta(event.key);
506
+ if (delta) {
507
+ event.preventDefault();
508
+ this.#cellFocus = {
509
+ ...this.#cellFocus,
510
+ row: Math.max(1, this.#cellFocus.row + delta.row),
511
+ column: Math.max(1, this.#cellFocus.column + delta.column),
512
+ };
513
+ this.#selectCellRange(this.#cellFocus);
514
+ return;
515
+ }
516
+ }
517
+ const pageStep = Math.max(48, this.#root.clientHeight * 0.9);
518
+ switch (event.key) {
519
+ case "PageDown":
520
+ event.preventDefault();
521
+ if (this.#layout === "single")
522
+ this.#host.onVisiblePage(Math.min(this.#host.state.pageCount - 1, this.#host.state.pageIndex + 1));
523
+ else
524
+ this.panBy(0, pageStep);
525
+ break;
526
+ case "PageUp":
527
+ event.preventDefault();
528
+ if (this.#layout === "single")
529
+ this.#host.onVisiblePage(Math.max(0, this.#host.state.pageIndex - 1));
530
+ else
531
+ this.panBy(0, -pageStep);
532
+ break;
533
+ case "ArrowDown":
534
+ event.preventDefault();
535
+ this.panBy(0, 48);
536
+ break;
537
+ case "ArrowUp":
538
+ event.preventDefault();
539
+ this.panBy(0, -48);
540
+ break;
541
+ case "ArrowRight":
542
+ event.preventDefault();
543
+ this.panBy(48, 0);
544
+ break;
545
+ case "ArrowLeft":
546
+ event.preventDefault();
547
+ this.panBy(-48, 0);
548
+ break;
549
+ case "+":
550
+ case "=":
551
+ if (event.ctrlKey || event.metaKey) {
552
+ event.preventDefault();
553
+ this.#host.onZoom(this.#host.state.zoom * 1.2);
554
+ }
555
+ break;
556
+ case "-":
557
+ if (event.ctrlKey || event.metaKey) {
558
+ event.preventDefault();
559
+ this.#host.onZoom(this.#host.state.zoom / 1.2);
560
+ }
561
+ break;
562
+ }
563
+ }
564
+ #handleCopy(event) {
565
+ if (document.activeElement !== this.#root &&
566
+ !this.#root.contains(document.activeElement))
567
+ return;
568
+ const text = this.#host.getSelectionText();
569
+ if (text === undefined)
570
+ return;
571
+ if (event.clipboardData) {
572
+ event.preventDefault();
573
+ event.clipboardData.setData("text/plain", text);
574
+ return;
575
+ }
576
+ void globalThis.navigator?.clipboard?.writeText(text).catch(() => { });
577
+ }
578
+ #selectCellRange(focus) {
579
+ const anchor = this.#cellAnchor ?? focus;
580
+ this.#host.onCellSelection({
581
+ sheetIndex: anchor.sheetIndex,
582
+ startRow: anchor.row,
583
+ startColumn: anchor.column,
584
+ endRow: focus.row,
585
+ endColumn: focus.column,
586
+ });
587
+ }
588
+ #capturePointer(event) {
589
+ try {
590
+ this.#root.setPointerCapture(event.pointerId);
591
+ }
592
+ catch {
593
+ // Synthetic events and older engines may not expose an active pointer.
594
+ }
595
+ }
596
+ #releasePointer(pointerId) {
597
+ try {
598
+ if (this.#root.hasPointerCapture(pointerId))
599
+ this.#root.releasePointerCapture(pointerId);
600
+ }
601
+ catch {
602
+ // Pointer may already have been released by the browser.
603
+ }
604
+ }
605
+ #deferCrispRender() {
606
+ this.#zoomGestureActive = true;
607
+ if (this.#zoomSettleTimer)
608
+ clearTimeout(this.#zoomSettleTimer);
609
+ this.#zoomSettleTimer = setTimeout(() => {
610
+ this.#zoomSettleTimer = undefined;
611
+ this.#zoomGestureActive = false;
612
+ this.schedule();
613
+ }, 120);
614
+ }
615
+ #handleSelectionChange() {
616
+ const selection = document.getSelection();
617
+ if (!selection || selection.isCollapsed || selection.rangeCount === 0)
618
+ return;
619
+ const range = selection.getRangeAt(0);
620
+ const start = parentTextSpan(range.startContainer);
621
+ const end = parentTextSpan(range.endContainer);
622
+ if (!start ||
623
+ !end ||
624
+ !this.#root.contains(start) ||
625
+ !this.#root.contains(end))
626
+ return;
627
+ const startPageIndex = Number(start.dataset.pageIndex);
628
+ const endPageIndex = Number(end.dataset.pageIndex);
629
+ const startText = start.textContent ?? "";
630
+ const endText = end.textContent ?? "";
631
+ const rawStartOffset = endpointOffset(start, range.startContainer, range.startOffset);
632
+ const rawEndOffset = endpointOffset(end, range.endContainer, range.endOffset);
633
+ const snappedStartOffset = snapGraphemeOffset(startText, rawStartOffset, "start");
634
+ const snappedEndOffset = snapGraphemeOffset(endText, rawEndOffset, "end");
635
+ if (rawStartOffset !== snappedStartOffset ||
636
+ rawEndOffset !== snappedEndOffset) {
637
+ const startNode = firstTextNode(start);
638
+ const endNode = firstTextNode(end);
639
+ if (startNode && endNode) {
640
+ const adjusted = document.createRange();
641
+ adjusted.setStart(startNode, snappedStartOffset);
642
+ adjusted.setEnd(endNode, snappedEndOffset);
643
+ selection.removeAllRanges();
644
+ selection.addRange(adjusted);
645
+ }
646
+ }
647
+ const startOffset = Number(start.dataset.start) + snappedStartOffset;
648
+ const endOffset = Number(end.dataset.start) + snappedEndOffset;
649
+ this.#host.onTextSelection({
650
+ startPageIndex,
651
+ startOffset,
652
+ endPageIndex,
653
+ endOffset,
654
+ });
655
+ }
656
+ #clearSlots() {
657
+ for (const slot of this.#slots.values()) {
658
+ slot.controller?.abort();
659
+ slot.root.remove();
660
+ }
661
+ this.#slots.clear();
662
+ }
663
+ }
664
+ function naturalPageSize(info, pageIndex) {
665
+ const candidate = info?.pageSizes?.[pageIndex];
666
+ return candidate &&
667
+ Number.isFinite(candidate.width) &&
668
+ candidate.width > 0 &&
669
+ Number.isFinite(candidate.height) &&
670
+ candidate.height > 0
671
+ ? candidate
672
+ : { width: BASE_WIDTH, height: BASE_HEIGHT };
673
+ }
674
+ function pageMetrics(info, zoom) {
675
+ const count = info?.pageCount ?? 0;
676
+ const widths = [];
677
+ const heights = [];
678
+ const offsets = [];
679
+ let top = 0;
680
+ let maxWidth = 1;
681
+ for (let pageIndex = 0; pageIndex < count; pageIndex += 1) {
682
+ const size = naturalPageSize(info, pageIndex);
683
+ const width = size.width * zoom;
684
+ const height = size.height * zoom;
685
+ offsets.push(top);
686
+ widths.push(width);
687
+ heights.push(height);
688
+ maxWidth = Math.max(maxWidth, width);
689
+ top += height + PAGE_GAP;
690
+ }
691
+ return {
692
+ widths,
693
+ heights,
694
+ offsets,
695
+ totalHeight: Math.max(1, top),
696
+ maxWidth,
697
+ };
698
+ }
699
+ function pageAtOffset(metrics, offset) {
700
+ if (metrics.offsets.length === 0)
701
+ return 0;
702
+ const target = Math.max(0, offset);
703
+ let low = 0;
704
+ let high = metrics.offsets.length - 1;
705
+ while (low < high) {
706
+ const middle = Math.ceil((low + high) / 2);
707
+ if (metrics.offsets[middle] <= target)
708
+ low = middle;
709
+ else
710
+ high = middle - 1;
711
+ }
712
+ return low;
713
+ }
714
+ function visiblePageRange(scrollOffset, viewportHeight, metrics, overscan) {
715
+ const count = metrics.offsets.length;
716
+ if (count === 0)
717
+ return { start: 0, end: 0 };
718
+ const start = pageAtOffset(metrics, scrollOffset);
719
+ const end = pageAtOffset(metrics, Math.max(0, scrollOffset) + Math.max(0, viewportHeight));
720
+ return {
721
+ start: Math.max(0, start - overscan),
722
+ end: Math.min(count, end + overscan + 1),
723
+ };
724
+ }
725
+ function pointerDistance(pointers) {
726
+ const [first, second] = Array.from(pointers.values());
727
+ return first && second
728
+ ? Math.hypot(second.x - first.x, second.y - first.y)
729
+ : 0;
730
+ }
731
+ function keyCellDelta(key) {
732
+ if (key === "ArrowDown")
733
+ return { row: 1, column: 0 };
734
+ if (key === "ArrowUp")
735
+ return { row: -1, column: 0 };
736
+ if (key === "ArrowRight")
737
+ return { row: 0, column: 1 };
738
+ if (key === "ArrowLeft")
739
+ return { row: 0, column: -1 };
740
+ return undefined;
741
+ }
742
+ function parentTextSpan(node) {
743
+ return node instanceof HTMLElement
744
+ ? node.closest("[data-start]")
745
+ : (node.parentElement?.closest("[data-start]") ?? null);
746
+ }
747
+ function endpointOffset(span, node, offset) {
748
+ if (node === span)
749
+ return offset <= 0 ? 0 : (span.textContent?.length ?? 0);
750
+ return offset;
751
+ }
752
+ function firstTextNode(span) {
753
+ return span.firstChild instanceof Text ? span.firstChild : null;
754
+ }
755
+ function isDocxTextRun(run) {
756
+ return (run.textLayer === "docx" &&
757
+ typeof run.font === "string" &&
758
+ typeof run.fontSize === "number" &&
759
+ Number.isFinite(run.fontSize) &&
760
+ typeof run.coordinateWidth === "number" &&
761
+ Number.isFinite(run.coordinateWidth) &&
762
+ run.coordinateWidth > 0 &&
763
+ typeof run.coordinateHeight === "number" &&
764
+ Number.isFinite(run.coordinateHeight) &&
765
+ run.coordinateHeight > 0);
766
+ }
767
+ function isPdfTextRun(run) {
768
+ return (run.textLayer === "pdf" &&
769
+ typeof run.font === "string" &&
770
+ typeof run.fontSize === "number" &&
771
+ Number.isFinite(run.fontSize) &&
772
+ typeof run.coordinateWidth === "number" &&
773
+ Number.isFinite(run.coordinateWidth) &&
774
+ run.coordinateWidth > 0 &&
775
+ typeof run.coordinateHeight === "number" &&
776
+ Number.isFinite(run.coordinateHeight) &&
777
+ run.coordinateHeight > 0);
778
+ }
779
+ function buildPdfTextLayers(textLayer, highlightLayer, pageIndex, runs, matches) {
780
+ const measureForFont = textMeasureFactory();
781
+ for (const run of runs) {
782
+ const start = run.logicalStart ?? 0;
783
+ const end = run.logicalEnd ?? start + run.text.length;
784
+ const measured = measureForFont(run.font)(run.text);
785
+ const scaleX = measured > 0 ? run.width / measured : 1;
786
+ const span = document.createElement("span");
787
+ span.textContent = run.text;
788
+ span.dataset.pageIndex = String(pageIndex);
789
+ span.dataset.start = String(start);
790
+ span.dataset.end = String(end);
791
+ Object.assign(span.style, {
792
+ position: "absolute",
793
+ left: `${run.x}px`,
794
+ top: `${run.y}px`,
795
+ color: "transparent",
796
+ whiteSpace: "pre",
797
+ lineHeight: "1",
798
+ font: run.font,
799
+ direction: run.direction ?? "ltr",
800
+ transform: `${run.transform ?? ""} scaleX(${scaleX})`.trim(),
801
+ transformOrigin: "top left",
802
+ });
803
+ textLayer.append(span);
804
+ if (matches.some((match) => match.start < end && match.end > start)) {
805
+ const highlight = document.createElement("div");
806
+ Object.assign(highlight.style, {
807
+ position: "absolute",
808
+ left: `${run.x}px`,
809
+ top: `${run.y}px`,
810
+ width: `${Math.max(1, run.width)}px`,
811
+ height: `${Math.max(1, run.height)}px`,
812
+ background: "var(--zrimo-highlight, rgb(255 215 0 / 45%))",
813
+ pointerEvents: "none",
814
+ transform: run.transform,
815
+ transformOrigin: run.transform ? "top left" : undefined,
816
+ });
817
+ highlightLayer.append(highlight);
818
+ }
819
+ }
820
+ }
821
+ function toDocxTextRunInfo(run) {
822
+ return {
823
+ text: run.text,
824
+ x: run.x,
825
+ y: run.y,
826
+ w: run.width,
827
+ h: run.height,
828
+ font: run.font,
829
+ fontSize: run.fontSize,
830
+ ...(run.letterSpacingPx === undefined
831
+ ? {}
832
+ : { letterSpacingPx: run.letterSpacingPx }),
833
+ ...(run.transform === undefined ? {} : { transform: run.transform }),
834
+ ...(run.eastAsianVert === undefined
835
+ ? {}
836
+ : { eastAsianVert: run.eastAsianVert }),
837
+ ...(run.hyperlink === undefined ? {} : { hyperlink: run.hyperlink }),
838
+ };
839
+ }
840
+ function toDocxHighlightMatches(runs, matches) {
841
+ return matches.flatMap((match) => {
842
+ const slices = [];
843
+ let offset = 0;
844
+ runs.forEach((run, runIndex) => {
845
+ const runStart = run.logicalStart ?? offset;
846
+ const runEnd = run.logicalEnd ?? runStart + run.text.length;
847
+ offset = runEnd;
848
+ const start = Math.max(match.start, runStart);
849
+ const end = Math.min(match.end, runEnd);
850
+ if (start < end)
851
+ slices.push({
852
+ runIndex,
853
+ start: start - runStart,
854
+ end: end - runStart,
855
+ });
856
+ });
857
+ return slices.length > 0 ? [{ slices, active: false }] : [];
858
+ });
859
+ }
860
+ function annotateTextSpans(layer, pageIndex, runs) {
861
+ const spans = Array.from(layer.children).filter((node) => node instanceof HTMLElement);
862
+ let offset = 0;
863
+ runs.forEach((run, index) => {
864
+ const span = spans[index];
865
+ if (!span)
866
+ return;
867
+ const start = run.logicalStart ?? offset;
868
+ const end = run.logicalEnd ?? start + run.text.length;
869
+ offset = end;
870
+ span.dataset.pageIndex = String(pageIndex);
871
+ span.dataset.start = String(start);
872
+ span.dataset.end = String(end);
873
+ if (run.row !== undefined)
874
+ span.dataset.row = String(run.row);
875
+ if (run.column !== undefined)
876
+ span.dataset.column = String(run.column);
877
+ });
878
+ }
879
+ function scaleOverlay(layer, width, height, zoom) {
880
+ Object.assign(layer.style, {
881
+ inset: "auto",
882
+ left: "0",
883
+ top: "0",
884
+ width: `${width}px`,
885
+ height: `${height}px`,
886
+ transform: `scale(${zoom})`,
887
+ transformOrigin: "top left",
888
+ });
889
+ }
890
+ function resetOverlay(layer) {
891
+ Object.assign(layer.style, {
892
+ inset: "0",
893
+ width: "auto",
894
+ height: "auto",
895
+ transform: "none",
896
+ transformOrigin: "top left",
897
+ });
898
+ }
899
+ function textMeasureFactory() {
900
+ const canvas = document.createElement("canvas");
901
+ const context = canvas.getContext("2d");
902
+ return (font) => {
903
+ if (context)
904
+ context.font = font;
905
+ return (text) => context?.measureText(text).width ?? 0;
906
+ };
907
+ }