@l1yp/file-viewer 0.1.0 → 0.1.2

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 (439) hide show
  1. package/README.md +2 -0
  2. package/dist/FileViewer.js +2 -0
  3. package/dist/FileViewer.js.map +1 -0
  4. package/dist/FileViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  5. package/dist/FileViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  6. package/dist/components/AppxViewer.js +2 -0
  7. package/dist/components/AppxViewer.js.map +1 -0
  8. package/dist/components/AppxViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  9. package/dist/components/AppxViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  10. package/dist/components/ArchiveBrowser.js +2 -0
  11. package/dist/components/ArchiveBrowser.js.map +1 -0
  12. package/dist/components/ArchiveBrowser.vue_vue_type_script_setup_true_lang.js +2 -0
  13. package/dist/components/ArchiveBrowser.vue_vue_type_script_setup_true_lang.js.map +1 -0
  14. package/dist/components/AudioViewer.js +2 -0
  15. package/dist/components/AudioViewer.js.map +1 -0
  16. package/dist/components/AudioViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  17. package/dist/components/AudioViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  18. package/dist/components/BinObjBrowser.js +2 -0
  19. package/dist/components/BinObjBrowser.js.map +1 -0
  20. package/dist/components/BinObjBrowser.vue_vue_type_script_setup_true_lang.js +2 -0
  21. package/dist/components/BinObjBrowser.vue_vue_type_script_setup_true_lang.js.map +1 -0
  22. package/dist/components/CertViewer.js +2 -0
  23. package/dist/components/CertViewer.js.map +1 -0
  24. package/dist/components/CertViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  25. package/dist/components/CertViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  26. package/dist/components/ClassViewer.js +2 -0
  27. package/dist/components/ClassViewer.js.map +1 -0
  28. package/dist/components/ClassViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  29. package/dist/components/ClassViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  30. package/dist/components/CodeBlock.js +2 -0
  31. package/dist/components/CodeBlock.js.map +1 -0
  32. package/dist/components/CodeBlock.vue_vue_type_script_setup_true_lang.js +2 -0
  33. package/dist/components/CodeBlock.vue_vue_type_script_setup_true_lang.js.map +1 -0
  34. package/dist/components/CodeView.js +2 -0
  35. package/dist/components/CodeView.js.map +1 -0
  36. package/dist/components/CodeView.vue_vue_type_script_setup_true_lang.js +2 -0
  37. package/dist/components/CodeView.vue_vue_type_script_setup_true_lang.js.map +1 -0
  38. package/dist/components/CsvViewer.js +2 -0
  39. package/dist/components/CsvViewer.js.map +1 -0
  40. package/dist/components/CsvViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  41. package/dist/components/CsvViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  42. package/dist/components/DicomViewer.js +2 -0
  43. package/dist/components/DicomViewer.js.map +1 -0
  44. package/dist/components/DicomViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  45. package/dist/components/DicomViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  46. package/dist/components/DocxNavigationPane.js +9 -0
  47. package/dist/components/DocxNavigationPane.js.map +1 -0
  48. package/dist/components/DocxNavigationPane.vue.d.ts +23 -0
  49. package/dist/components/DocxNavigationPane.vue_vue_type_script_setup_true_lang.js +98 -0
  50. package/dist/components/DocxNavigationPane.vue_vue_type_script_setup_true_lang.js.map +1 -0
  51. package/dist/components/DocxViewer.js +3 -1
  52. package/dist/components/DocxViewer.js.map +1 -0
  53. package/dist/components/DocxViewer.vue_vue_type_script_setup_true_lang.js +72 -37
  54. package/dist/components/DocxViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  55. package/dist/components/DrawioViewer.js +2 -0
  56. package/dist/components/DrawioViewer.js.map +1 -0
  57. package/dist/components/DrawioViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  58. package/dist/components/DrawioViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  59. package/dist/components/DxfViewer.js +2 -0
  60. package/dist/components/DxfViewer.js.map +1 -0
  61. package/dist/components/DxfViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  62. package/dist/components/DxfViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  63. package/dist/components/EbookViewer.js +2 -0
  64. package/dist/components/EbookViewer.js.map +1 -0
  65. package/dist/components/EbookViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  66. package/dist/components/EbookViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  67. package/dist/components/EmlViewer.js +2 -0
  68. package/dist/components/EmlViewer.js.map +1 -0
  69. package/dist/components/EmlViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  70. package/dist/components/EmlViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  71. package/dist/components/EplViewer.js +2 -0
  72. package/dist/components/EplViewer.js.map +1 -0
  73. package/dist/components/EplViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  74. package/dist/components/EplViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  75. package/dist/components/FileViewerBody.js +3 -1
  76. package/dist/components/FileViewerBody.js.map +1 -0
  77. package/dist/components/FileViewerBody.vue.d.ts +5 -0
  78. package/dist/components/FileViewerBody.vue_vue_type_script_setup_true_lang.js +250 -247
  79. package/dist/components/FileViewerBody.vue_vue_type_script_setup_true_lang.js.map +1 -0
  80. package/dist/components/FileViewerPanel.js +2 -0
  81. package/dist/components/FileViewerPanel.js.map +1 -0
  82. package/dist/components/FileViewerPanel.vue_vue_type_script_setup_true_lang.js +2 -0
  83. package/dist/components/FileViewerPanel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  84. package/dist/components/FontViewer.js +2 -0
  85. package/dist/components/FontViewer.js.map +1 -0
  86. package/dist/components/FontViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  87. package/dist/components/FontViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  88. package/dist/components/FrontmatterCard.js +2 -0
  89. package/dist/components/FrontmatterCard.js.map +1 -0
  90. package/dist/components/FrontmatterCard.vue_vue_type_script_setup_true_lang.js +2 -0
  91. package/dist/components/FrontmatterCard.vue_vue_type_script_setup_true_lang.js.map +1 -0
  92. package/dist/components/GeoViewer.js +2 -0
  93. package/dist/components/GeoViewer.js.map +1 -0
  94. package/dist/components/GeoViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  95. package/dist/components/GeoViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  96. package/dist/components/HarViewer.js +2 -0
  97. package/dist/components/HarViewer.js.map +1 -0
  98. package/dist/components/HarViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  99. package/dist/components/HarViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  100. package/dist/components/HexViewer.js +2 -0
  101. package/dist/components/HexViewer.js.map +1 -0
  102. package/dist/components/HexViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  103. package/dist/components/HexViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  104. package/dist/components/HprofViewer.js +2 -0
  105. package/dist/components/HprofViewer.js.map +1 -0
  106. package/dist/components/HprofViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  107. package/dist/components/HprofViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  108. package/dist/components/ImageLightbox.js +2 -0
  109. package/dist/components/ImageLightbox.js.map +1 -0
  110. package/dist/components/ImageLightbox.vue_vue_type_script_setup_true_lang.js +2 -0
  111. package/dist/components/ImageLightbox.vue_vue_type_script_setup_true_lang.js.map +1 -0
  112. package/dist/components/InlineText.js +2 -0
  113. package/dist/components/InlineText.js.map +1 -0
  114. package/dist/components/JksViewer.js +2 -0
  115. package/dist/components/JksViewer.js.map +1 -0
  116. package/dist/components/JksViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  117. package/dist/components/JksViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  118. package/dist/components/JsonlViewer.js +2 -0
  119. package/dist/components/JsonlViewer.js.map +1 -0
  120. package/dist/components/JsonlViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  121. package/dist/components/JsonlViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  122. package/dist/components/LogViewer.js +2 -0
  123. package/dist/components/LogViewer.js.map +1 -0
  124. package/dist/components/LogViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  125. package/dist/components/LogViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  126. package/dist/components/LrcViewer.js +2 -0
  127. package/dist/components/LrcViewer.js.map +1 -0
  128. package/dist/components/LrcViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  129. package/dist/components/LrcViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  130. package/dist/components/MarkdownTable.js +2 -0
  131. package/dist/components/MarkdownTable.js.map +1 -0
  132. package/dist/components/MarkdownTable.vue_vue_type_script_setup_true_lang.js +2 -0
  133. package/dist/components/MarkdownTable.vue_vue_type_script_setup_true_lang.js.map +1 -0
  134. package/dist/components/MarkdownText.js +2 -0
  135. package/dist/components/MarkdownText.js.map +1 -0
  136. package/dist/components/MhtViewer.js +2 -0
  137. package/dist/components/MhtViewer.js.map +1 -0
  138. package/dist/components/MhtViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  139. package/dist/components/MhtViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  140. package/dist/components/MindMapView.js +2 -0
  141. package/dist/components/MindMapView.js.map +1 -0
  142. package/dist/components/MindMapView.vue_vue_type_script_setup_true_lang.js +2 -0
  143. package/dist/components/MindMapView.vue_vue_type_script_setup_true_lang.js.map +1 -0
  144. package/dist/components/MissingDependency.js +2 -0
  145. package/dist/components/MissingDependency.js.map +1 -0
  146. package/dist/components/MissingDependency.vue_vue_type_script_setup_true_lang.js +2 -0
  147. package/dist/components/MissingDependency.vue_vue_type_script_setup_true_lang.js.map +1 -0
  148. package/dist/components/ModelViewer.js +2 -0
  149. package/dist/components/ModelViewer.js.map +1 -0
  150. package/dist/components/ModelViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  151. package/dist/components/ModelViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  152. package/dist/components/MsiViewer.js +2 -0
  153. package/dist/components/MsiViewer.js.map +1 -0
  154. package/dist/components/MsiViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  155. package/dist/components/MsiViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  156. package/dist/components/NotebookViewer.js +2 -0
  157. package/dist/components/NotebookViewer.js.map +1 -0
  158. package/dist/components/NotebookViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  159. package/dist/components/NotebookViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  160. package/dist/components/PdfViewer.js +2 -0
  161. package/dist/components/PdfViewer.js.map +1 -0
  162. package/dist/components/PdfViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  163. package/dist/components/PdfViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  164. package/dist/components/PptxNavigationPane.js +9 -0
  165. package/dist/components/PptxNavigationPane.js.map +1 -0
  166. package/dist/components/PptxNavigationPane.vue.d.ts +20 -0
  167. package/dist/components/PptxNavigationPane.vue_vue_type_script_setup_true_lang.js +120 -0
  168. package/dist/components/PptxNavigationPane.vue_vue_type_script_setup_true_lang.js.map +1 -0
  169. package/dist/components/PptxViewer.js +3 -1
  170. package/dist/components/PptxViewer.js.map +1 -0
  171. package/dist/components/PptxViewer.vue_vue_type_script_setup_true_lang.js +71 -39
  172. package/dist/components/PptxViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  173. package/dist/components/PsdViewer.js +2 -0
  174. package/dist/components/PsdViewer.js.map +1 -0
  175. package/dist/components/PsdViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  176. package/dist/components/PsdViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  177. package/dist/components/QmcAudioViewer.js +2 -0
  178. package/dist/components/QmcAudioViewer.js.map +1 -0
  179. package/dist/components/QmcAudioViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  180. package/dist/components/QmcAudioViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  181. package/dist/components/RasterViewer.js +2 -0
  182. package/dist/components/RasterViewer.js.map +1 -0
  183. package/dist/components/RasterViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  184. package/dist/components/RasterViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  185. package/dist/components/RtfViewer.js +2 -0
  186. package/dist/components/RtfViewer.js.map +1 -0
  187. package/dist/components/RtfViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  188. package/dist/components/RtfViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  189. package/dist/components/SevenZipBrowser.js +2 -0
  190. package/dist/components/SevenZipBrowser.js.map +1 -0
  191. package/dist/components/SevenZipBrowser.vue_vue_type_script_setup_true_lang.js +2 -0
  192. package/dist/components/SevenZipBrowser.vue_vue_type_script_setup_true_lang.js.map +1 -0
  193. package/dist/components/SqliteViewer.js +2 -0
  194. package/dist/components/SqliteViewer.js.map +1 -0
  195. package/dist/components/SqliteViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  196. package/dist/components/SqliteViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  197. package/dist/components/SubtitleViewer.js +2 -0
  198. package/dist/components/SubtitleViewer.js.map +1 -0
  199. package/dist/components/SubtitleViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  200. package/dist/components/SubtitleViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  201. package/dist/components/XlsxChart.js +2 -0
  202. package/dist/components/XlsxChart.js.map +1 -0
  203. package/dist/components/XlsxChart.vue_vue_type_script_setup_true_lang.js +2 -0
  204. package/dist/components/XlsxChart.vue_vue_type_script_setup_true_lang.js.map +1 -0
  205. package/dist/components/XlsxViewer.js +3 -1
  206. package/dist/components/XlsxViewer.js.map +1 -0
  207. package/dist/components/XlsxViewer.vue_vue_type_script_setup_true_lang.js +301 -304
  208. package/dist/components/XlsxViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  209. package/dist/components/XmindViewer.js +2 -0
  210. package/dist/components/XmindViewer.js.map +1 -0
  211. package/dist/components/XmindViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  212. package/dist/components/XmindViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  213. package/dist/components/ZipBrowser.js +3 -1
  214. package/dist/components/ZipBrowser.js.map +1 -0
  215. package/dist/components/ZipBrowser.vue.d.ts +3 -1
  216. package/dist/components/ZipBrowser.vue_vue_type_script_setup_true_lang.js +154 -122
  217. package/dist/components/ZipBrowser.vue_vue_type_script_setup_true_lang.js.map +1 -0
  218. package/dist/components/ZoomImage.js +2 -0
  219. package/dist/components/ZoomImage.js.map +1 -0
  220. package/dist/components/ZoomImage.vue_vue_type_script_setup_true_lang.js +2 -0
  221. package/dist/components/ZoomImage.vue_vue_type_script_setup_true_lang.js.map +1 -0
  222. package/dist/components/epl/EplCodeBlock.js +2 -0
  223. package/dist/components/epl/EplCodeBlock.js.map +1 -0
  224. package/dist/components/epl/EplCodeBlock.vue_vue_type_script_setup_true_lang.js +2 -0
  225. package/dist/components/epl/EplCodeBlock.vue_vue_type_script_setup_true_lang.js.map +1 -0
  226. package/dist/components/epl/EplDoc.js +2 -0
  227. package/dist/components/epl/EplDoc.js.map +1 -0
  228. package/dist/components/epl/EplDoc.vue_vue_type_script_setup_true_lang.js +2 -0
  229. package/dist/components/epl/EplDoc.vue_vue_type_script_setup_true_lang.js.map +1 -0
  230. package/dist/components/epl/EplMethod.js +2 -0
  231. package/dist/components/epl/EplMethod.js.map +1 -0
  232. package/dist/components/epl/EplMethod.vue_vue_type_script_setup_true_lang.js +2 -0
  233. package/dist/components/epl/EplMethod.vue_vue_type_script_setup_true_lang.js.map +1 -0
  234. package/dist/components/epl/EplResource.js +2 -0
  235. package/dist/components/epl/EplResource.js.map +1 -0
  236. package/dist/components/epl/EplResource.vue_vue_type_script_setup_true_lang.js +2 -0
  237. package/dist/components/epl/EplResource.vue_vue_type_script_setup_true_lang.js.map +1 -0
  238. package/dist/components/epl/EplTree.js +2 -0
  239. package/dist/components/epl/EplTree.js.map +1 -0
  240. package/dist/components/epl/EplTree.vue_vue_type_script_setup_true_lang.js +2 -0
  241. package/dist/components/epl/EplTree.vue_vue_type_script_setup_true_lang.js.map +1 -0
  242. package/dist/components/epl/EplVarTable.js +2 -0
  243. package/dist/components/epl/EplVarTable.js.map +1 -0
  244. package/dist/components/epl/EplVarTable.vue_vue_type_script_setup_true_lang.js +2 -0
  245. package/dist/components/epl/EplVarTable.vue_vue_type_script_setup_true_lang.js.map +1 -0
  246. package/dist/components/epl/numbering.js +2 -0
  247. package/dist/components/epl/numbering.js.map +1 -0
  248. package/dist/components/icons/Icon.js +2 -0
  249. package/dist/components/icons/Icon.js.map +1 -0
  250. package/dist/components/icons/Icon.vue_vue_type_script_setup_true_lang.js +2 -0
  251. package/dist/components/icons/Icon.vue_vue_type_script_setup_true_lang.js.map +1 -0
  252. package/dist/components/icons/iconPaths.js +2 -0
  253. package/dist/components/icons/iconPaths.js.map +1 -0
  254. package/dist/components/optionalViewer.js +2 -0
  255. package/dist/components/optionalViewer.js.map +1 -0
  256. package/dist/components/ui/ClampBlock.js +2 -0
  257. package/dist/components/ui/ClampBlock.js.map +1 -0
  258. package/dist/composables/useElementNavigation.d.ts +21 -0
  259. package/dist/composables/useElementNavigation.js +63 -0
  260. package/dist/composables/useElementNavigation.js.map +1 -0
  261. package/dist/composables/useFileViewer.js +2 -0
  262. package/dist/composables/useFileViewer.js.map +1 -0
  263. package/dist/composables/useLightbox.js +2 -0
  264. package/dist/composables/useLightbox.js.map +1 -0
  265. package/dist/composables/useLogRules.js +2 -0
  266. package/dist/composables/useLogRules.js.map +1 -0
  267. package/dist/lib/aes.js +2 -0
  268. package/dist/lib/aes.js.map +1 -0
  269. package/dist/lib/appx.js +2 -0
  270. package/dist/lib/appx.js.map +1 -0
  271. package/dist/lib/archiveHtml.d.ts +49 -0
  272. package/dist/lib/archiveHtml.js +377 -0
  273. package/dist/lib/archiveHtml.js.map +1 -0
  274. package/dist/lib/asn1.js +2 -0
  275. package/dist/lib/asn1.js.map +1 -0
  276. package/dist/lib/binobj.js +2 -0
  277. package/dist/lib/binobj.js.map +1 -0
  278. package/dist/lib/brotli.js +2 -0
  279. package/dist/lib/brotli.js.map +1 -0
  280. package/dist/lib/bzip2.js +2 -0
  281. package/dist/lib/bzip2.js.map +1 -0
  282. package/dist/lib/classfile.js +2 -0
  283. package/dist/lib/classfile.js.map +1 -0
  284. package/dist/lib/codePreview.js +2 -0
  285. package/dist/lib/codePreview.js.map +1 -0
  286. package/dist/lib/codefold.js +2 -0
  287. package/dist/lib/codefold.js.map +1 -0
  288. package/dist/lib/codeformat.js +2 -0
  289. package/dist/lib/codeformat.js.map +1 -0
  290. package/dist/lib/csv.js +2 -0
  291. package/dist/lib/csv.js.map +1 -0
  292. package/dist/lib/des.js +2 -0
  293. package/dist/lib/des.js.map +1 -0
  294. package/dist/lib/diagram.js +2 -0
  295. package/dist/lib/diagram.js.map +1 -0
  296. package/dist/lib/dicom.js +2 -0
  297. package/dist/lib/dicom.js.map +1 -0
  298. package/dist/lib/dicomCodecs.js +2 -0
  299. package/dist/lib/dicomCodecs.js.map +1 -0
  300. package/dist/lib/dicomRender.js +2 -0
  301. package/dist/lib/dicomRender.js.map +1 -0
  302. package/dist/lib/docxNavigation.d.ts +31 -0
  303. package/dist/lib/docxNavigation.js +65 -0
  304. package/dist/lib/docxNavigation.js.map +1 -0
  305. package/dist/lib/dxf.js +2 -0
  306. package/dist/lib/dxf.js.map +1 -0
  307. package/dist/lib/eml.js +2 -0
  308. package/dist/lib/eml.js.map +1 -0
  309. package/dist/lib/encoding.js +2 -0
  310. package/dist/lib/encoding.js.map +1 -0
  311. package/dist/lib/epl/code/codeDataParser.js +2 -0
  312. package/dist/lib/epl/code/codeDataParser.js.map +1 -0
  313. package/dist/lib/epl/code/codeLines.js +2 -0
  314. package/dist/lib/epl/code/codeLines.js.map +1 -0
  315. package/dist/lib/epl/code/textCode.js +2 -0
  316. package/dist/lib/epl/code/textCode.js.map +1 -0
  317. package/dist/lib/epl/eplDocument.js +2 -0
  318. package/dist/lib/epl/eplDocument.js.map +1 -0
  319. package/dist/lib/epl/imageList.js +2 -0
  320. package/dist/lib/epl/imageList.js.map +1 -0
  321. package/dist/lib/epl/index.js +2 -0
  322. package/dist/lib/epl/index.js.map +1 -0
  323. package/dist/lib/epl/io/binaryReader.js +2 -0
  324. package/dist/lib/epl/io/binaryReader.js.map +1 -0
  325. package/dist/lib/epl/io/encoding.js +2 -0
  326. package/dist/lib/epl/io/encoding.js.map +1 -0
  327. package/dist/lib/epl/model/eplSystemId.js +2 -0
  328. package/dist/lib/epl/model/eplSystemId.js.map +1 -0
  329. package/dist/lib/epl/names/eplLibData.js +2 -0
  330. package/dist/lib/epl/names/eplLibData.js.map +1 -0
  331. package/dist/lib/epl/names/idToNameMap.js +2 -0
  332. package/dist/lib/epl/names/idToNameMap.js.map +1 -0
  333. package/dist/lib/epl/names/libNameProvider.js +2 -0
  334. package/dist/lib/epl/names/libNameProvider.js.map +1 -0
  335. package/dist/lib/epl/program.js +2 -0
  336. package/dist/lib/epl/program.js.map +1 -0
  337. package/dist/lib/epl/projectFileReader.js +2 -0
  338. package/dist/lib/epl/projectFileReader.js.map +1 -0
  339. package/dist/lib/fb2.js +2 -0
  340. package/dist/lib/fb2.js.map +1 -0
  341. package/dist/lib/fileType.js +2 -0
  342. package/dist/lib/fileType.js.map +1 -0
  343. package/dist/lib/fonts.js +2 -0
  344. package/dist/lib/fonts.js.map +1 -0
  345. package/dist/lib/format.js +2 -0
  346. package/dist/lib/format.js.map +1 -0
  347. package/dist/lib/frontmatter.js +2 -0
  348. package/dist/lib/frontmatter.js.map +1 -0
  349. package/dist/lib/geo.js +2 -0
  350. package/dist/lib/geo.js.map +1 -0
  351. package/dist/lib/har.js +2 -0
  352. package/dist/lib/har.js.map +1 -0
  353. package/dist/lib/highlight.js +2 -0
  354. package/dist/lib/highlight.js.map +1 -0
  355. package/dist/lib/highlightLangs.js +2 -0
  356. package/dist/lib/highlightLangs.js.map +1 -0
  357. package/dist/lib/hprof.js +2 -0
  358. package/dist/lib/hprof.js.map +1 -0
  359. package/dist/lib/ipynb.js +2 -0
  360. package/dist/lib/ipynb.js.map +1 -0
  361. package/dist/lib/jks.js +2 -0
  362. package/dist/lib/jks.js.map +1 -0
  363. package/dist/lib/jsonl.js +2 -0
  364. package/dist/lib/jsonl.js.map +1 -0
  365. package/dist/lib/lrc.js +2 -0
  366. package/dist/lib/lrc.js.map +1 -0
  367. package/dist/lib/lzma.js +2 -0
  368. package/dist/lib/lzma.js.map +1 -0
  369. package/dist/lib/markdown/blocks.js +2 -0
  370. package/dist/lib/markdown/blocks.js.map +1 -0
  371. package/dist/lib/markdown/inline.js +2 -0
  372. package/dist/lib/markdown/inline.js.map +1 -0
  373. package/dist/lib/markdown/math.js +2 -0
  374. package/dist/lib/markdown/math.js.map +1 -0
  375. package/dist/lib/markdown/segmentize.js +2 -0
  376. package/dist/lib/markdown/segmentize.js.map +1 -0
  377. package/dist/lib/markdown/styles.js +2 -0
  378. package/dist/lib/markdown/styles.js.map +1 -0
  379. package/dist/lib/mht.js +2 -0
  380. package/dist/lib/mht.js.map +1 -0
  381. package/dist/lib/midi.js +2 -0
  382. package/dist/lib/midi.js.map +1 -0
  383. package/dist/lib/mime.js +2 -0
  384. package/dist/lib/mime.js.map +1 -0
  385. package/dist/lib/mindmap.js +2 -0
  386. package/dist/lib/mindmap.js.map +1 -0
  387. package/dist/lib/mobi.js +2 -0
  388. package/dist/lib/mobi.js.map +1 -0
  389. package/dist/lib/msi.js +2 -0
  390. package/dist/lib/msi.js.map +1 -0
  391. package/dist/lib/optionalDep.js +2 -0
  392. package/dist/lib/optionalDep.js.map +1 -0
  393. package/dist/lib/pkcs12.js +2 -0
  394. package/dist/lib/pkcs12.js.map +1 -0
  395. package/dist/lib/pptxNavigation.d.ts +7 -0
  396. package/dist/lib/pptxNavigation.js +29 -0
  397. package/dist/lib/pptxNavigation.js.map +1 -0
  398. package/dist/lib/qmc.js +2 -0
  399. package/dist/lib/qmc.js.map +1 -0
  400. package/dist/lib/rar.js +2 -0
  401. package/dist/lib/rar.js.map +1 -0
  402. package/dist/lib/rawPreview.js +2 -0
  403. package/dist/lib/rawPreview.js.map +1 -0
  404. package/dist/lib/rc2.js +2 -0
  405. package/dist/lib/rc2.js.map +1 -0
  406. package/dist/lib/resolveInput.js +2 -0
  407. package/dist/lib/resolveInput.js.map +1 -0
  408. package/dist/lib/rtf.js +2 -0
  409. package/dist/lib/rtf.js.map +1 -0
  410. package/dist/lib/sevenZip.js +2 -0
  411. package/dist/lib/sevenZip.js.map +1 -0
  412. package/dist/lib/sha1.js +2 -0
  413. package/dist/lib/sha1.js.map +1 -0
  414. package/dist/lib/sha256.js +2 -0
  415. package/dist/lib/sha256.js.map +1 -0
  416. package/dist/lib/speechAudio.js +2 -0
  417. package/dist/lib/speechAudio.js.map +1 -0
  418. package/dist/lib/sqlite.js +2 -0
  419. package/dist/lib/sqlite.js.map +1 -0
  420. package/dist/lib/subtitle.js +2 -0
  421. package/dist/lib/subtitle.js.map +1 -0
  422. package/dist/lib/tarball.js +2 -0
  423. package/dist/lib/tarball.js.map +1 -0
  424. package/dist/lib/viewerFormats.js +2 -0
  425. package/dist/lib/viewerFormats.js.map +1 -0
  426. package/dist/lib/viewerKind.js +2 -0
  427. package/dist/lib/viewerKind.js.map +1 -0
  428. package/dist/lib/x509.js +2 -0
  429. package/dist/lib/x509.js.map +1 -0
  430. package/dist/lib/xlsx.js +2 -0
  431. package/dist/lib/xlsx.js.map +1 -0
  432. package/dist/lib/xlsxCharts.js +2 -0
  433. package/dist/lib/xlsxCharts.js.map +1 -0
  434. package/dist/lib/xmind.js +2 -0
  435. package/dist/lib/xmind.js.map +1 -0
  436. package/dist/lib/zip.js +2 -0
  437. package/dist/lib/zip.js.map +1 -0
  438. package/dist/style.css +1 -1
  439. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hprof.js","names":[],"sources":["../../src/lib/hprof.ts"],"sourcesContent":["/**\n * Streaming HPROF (JVM heap dump) parser — no dependency, no WASM, memory-bounded.\n *\n * An `.hprof` file is a header followed by self-describing top-level records; the big HEAP_DUMP /\n * HEAP_DUMP_SEGMENT records hold an inner stream of sub-records (CLASS_DUMP / INSTANCE_DUMP / ARRAY_DUMP /\n * GC roots) with NO length prefix, so those must be walked byte-exactly. Because a heap dump can be many GB,\n * we never load the whole file into the JS heap:\n *\n * - {@link ByteReader} pulls the file in 8 MB chunks off a {@link Blob} (the browser keeps the Blob itself,\n * possibly disk-backed); its `skip(n)` advances the cursor WITHOUT reading the skipped bytes into memory,\n * so the field data / array elements a preview never needs are never materialized.\n * - Pass A ({@link Hprof.parse}) makes ONE streaming sweep and keeps only *bounded* state: a per-class\n * histogram (instances + shallow bytes), the class → name / super / instance-field layout tables, and the\n * name string table. Nothing scales with the instance count.\n * - Pass B ({@link Hprof.collect}) answers \"show me the objects of THIS class\" with a second streaming sweep\n * that decodes only the target class's instances and collects at most {@link MAX_COLLECT} lightweight rows\n * (id + shallow size + decoded fields), skipping everything else. Memory stays ∝ the cap, independent of\n * how many instances the class actually has — the UI paginates the cap and, when a class overflows it,\n * re-runs Pass B with a field/id filter so search still spans the WHOLE file (see HprofViewer.vue).\n *\n * Shallow size only (field/element bytes + a ~2-pointer object-header estimate); retained size / dominator\n * trees need the full reference graph (a second indexing pass, à la Eclipse MAT) and are out of scope.\n *\n * The record layout follows the JDK HPROF \"binary dump format\" (agent header + 1.0.2 segmented heap dumps).\n */\n\n/** Thrown when the bytes aren't a recognizable HPROF file, or the stream ends mid-record. */\nexport class HprofParseError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'HprofParseError'\n }\n}\n\n// ── Type tags (basic-type ids used by CLASS_DUMP fields + PRIMITIVE_ARRAY_DUMP) ──────────────────\nconst T_OBJECT = 2\nconst T_BOOLEAN = 4\nconst T_CHAR = 5\nconst T_FLOAT = 6\nconst T_DOUBLE = 7\nconst T_BYTE = 8\nconst T_SHORT = 9\nconst T_INT = 10\nconst T_LONG = 11\n\n/** Byte width of a basic type. Object references are `idSize` wide; everything else is fixed. */\nfunction typeSize(type: number, idSize: number): number {\n switch (type) {\n case T_OBJECT:\n return idSize\n case T_BOOLEAN:\n case T_BYTE:\n return 1\n case T_CHAR:\n case T_SHORT:\n return 2\n case T_FLOAT:\n case T_INT:\n return 4\n case T_DOUBLE:\n case T_LONG:\n return 8\n default:\n throw new HprofParseError('未知的基础类型标记 0x' + type.toString(16))\n }\n}\n\nconst PRIM_NAME: Record<number, string> = {\n [T_BOOLEAN]: 'boolean',\n [T_CHAR]: 'char',\n [T_FLOAT]: 'float',\n [T_DOUBLE]: 'double',\n [T_BYTE]: 'byte',\n [T_SHORT]: 'short',\n [T_INT]: 'int',\n [T_LONG]: 'long',\n}\nfunction primTypeName(type: number): string {\n return PRIM_NAME[type] ?? 'type' + type\n}\n\n/**\n * Chunked, forward-only reader over a {@link Blob}. Buffers 8 MB at a time; multi-byte integers are big-endian\n * (HPROF is big-endian). Object ids / longs are read as {@link bigint} and stringified — a Map key that survives\n * the full 64-bit range (a JS number can't). {@link skip} moves the cursor past data WITHOUT reading it, the key\n * to bounded memory on huge dumps.\n */\nclass ByteReader {\n readonly size: number\n private buf: Uint8Array = new Uint8Array(0)\n private pos = 0 // consumed offset inside `buf`\n private fileCursor = 0 // file offset already pulled into `buf`\n globalPos = 0 // logical file position of the next unread byte\n\n constructor(\n private readonly blob: Blob,\n private readonly chunkSize = 8 * 1024 * 1024,\n ) {\n this.size = blob.size\n }\n\n private async ensure(n: number): Promise<void> {\n while (this.buf.length - this.pos < n) {\n if (this.fileCursor >= this.size) {\n throw new HprofParseError('文件在偏移 ' + this.globalPos + ' 处意外结束(可能已截断)')\n }\n const end = Math.min(this.fileCursor + this.chunkSize, this.size)\n const ab = await this.blob.slice(this.fileCursor, end).arrayBuffer()\n const chunk = new Uint8Array(ab)\n this.fileCursor = end\n if (this.pos > 0) {\n this.buf = this.buf.slice(this.pos)\n this.pos = 0\n }\n if (this.buf.length === 0) {\n this.buf = chunk\n } else {\n const merged = new Uint8Array(this.buf.length + chunk.length)\n merged.set(this.buf, 0)\n merged.set(chunk, this.buf.length)\n this.buf = merged\n }\n }\n }\n\n async u1(): Promise<number> {\n await this.ensure(1)\n const v = this.buf[this.pos]\n this.pos += 1\n this.globalPos += 1\n return v\n }\n async u2(): Promise<number> {\n await this.ensure(2)\n const p = this.pos\n const v = ((this.buf[p] << 8) | this.buf[p + 1]) >>> 0\n this.pos += 2\n this.globalPos += 2\n return v\n }\n async u4(): Promise<number> {\n await this.ensure(4)\n const b = this.buf\n const p = this.pos\n const v = ((b[p] << 24) | (b[p + 1] << 16) | (b[p + 2] << 8) | b[p + 3]) >>> 0\n this.pos += 4\n this.globalPos += 4\n return v\n }\n private async u8(): Promise<bigint> {\n await this.ensure(8)\n const dv = new DataView(this.buf.buffer, this.buf.byteOffset + this.pos, 8)\n const v = dv.getBigUint64(0, false)\n this.pos += 8\n this.globalPos += 8\n return v\n }\n /** An object id / reference of the file's `idSize`, returned as a decimal string (stable Map key). */\n async id(idSize: number): Promise<string> {\n if (idSize === 8) return (await this.u8()).toString()\n if (idSize === 4) return (await this.u4()).toString()\n if (idSize === 2) return (await this.u2()).toString()\n return (await this.u1()).toString()\n }\n /** Read exactly `n` bytes into a fresh array (used only for the target class's small field blobs). */\n async bytes(n: number): Promise<Uint8Array> {\n await this.ensure(n)\n const v = this.buf.slice(this.pos, this.pos + n)\n this.pos += n\n this.globalPos += n\n return v\n }\n /** NUL-terminated UTF-8 string (the HPROF magic). */\n async cstring(): Promise<string> {\n const arr: number[] = []\n for (;;) {\n const b = await this.u1()\n if (b === 0) break\n arr.push(b)\n }\n return new TextDecoder('utf-8').decode(new Uint8Array(arr))\n }\n /** Advance `n` bytes without materializing them — the memory-bounding primitive. */\n async skip(n: number): Promise<void> {\n if (n <= 0) return\n const avail = this.buf.length - this.pos\n if (n <= avail) {\n this.pos += n\n this.globalPos += n\n return\n }\n const remaining = n - avail\n this.pos = this.buf.length\n this.globalPos += avail\n this.buf = new Uint8Array(0)\n this.fileCursor += remaining // jump the file cursor; these bytes are never read\n this.globalPos += remaining\n if (this.fileCursor > this.size) {\n throw new HprofParseError('跳过范围超出文件末尾(文件可能已截断)')\n }\n }\n}\n\n// ── HPROF record tags ────────────────────────────────────────────────────────────────────────────\nconst TAG_STRING = 0x01\nconst TAG_LOAD_CLASS = 0x02\nconst TAG_HEAP_DUMP = 0x0c\nconst TAG_HEAP_DUMP_SEGMENT = 0x1c\n\n// Heap sub-record tags.\nconst SUB_CLASS_DUMP = 0x20\nconst SUB_INSTANCE_DUMP = 0x21\nconst SUB_OBJECT_ARRAY_DUMP = 0x22\nconst SUB_PRIMITIVE_ARRAY_DUMP = 0x23\n\n// GC-root sub-records carry no length; we only count them and skip their fixed payload (sizes relative to\n// idSize). Table keyed by sub-tag → extra bytes AFTER the leading object id already covered by `idSize`.\nconst GC_ROOT_EXTRA: Record<number, (idSize: number) => number> = {\n 0x01: (i) => i, // JNI global (id + global-ref id)\n 0x02: () => 8, // JNI local (+ thread serial + frame#)\n 0x03: () => 8, // java frame\n 0x04: () => 4, // native stack\n 0x05: () => 0, // sticky class\n 0x06: () => 4, // thread block\n 0x07: () => 0, // monitor used\n 0x08: () => 8, // thread object\n 0xff: () => 0, // unknown\n 0x89: () => 0, // interned string\n 0x8b: () => 0, // debugger\n 0x8d: () => 0, // vm internal\n 0x8e: () => 8, // JNI monitor\n 0x8a: () => 0, // obsolete roots\n 0x8c: () => 0,\n 0x90: () => 0,\n}\n\n/** A declared instance field of a class (name resolved lazily against the string table). */\ninterface RawField {\n nameId: string\n type: number\n}\ninterface ClassDumpInfo {\n superId: string\n instanceSize: number\n instFields: RawField[]\n}\n\n/** A resolved field slot in an instance's on-disk layout (this class's fields, then each superclass's). */\nexport interface HprofField {\n name: string\n type: number\n}\n\n/** One decoded field value of an instance. `kind` styles the display (a plain value, or an object reference). */\nexport interface HprofFieldValue {\n name: string\n /** Display string: the primitive value, `'A'` for char, `null` / `#<id>` for object references. */\n value: string\n kind: 'prim' | 'ref' | 'null'\n /** For `kind==='ref'` (non-null): the bare target object id, so the UI can jump to / dereference it. */\n refId?: string\n}\n\n/**\n * A best-effort content preview of an array object (bounded — at most {@link MAX_ARRAY_PREVIEW} elements /\n * {@link MAX_DEREF_BYTES} bytes are ever read). `char[]` / printable `byte[]` decode to `text`; `byte[]` also\n * carries `hex`; numeric arrays and object arrays list their elements (object elements are `#<id>` references).\n */\nexport interface HprofArrayPreview {\n /** Basic-type tag for a primitive array; undefined for an object array. */\n elemType?: number\n /** Element class name for an object array (e.g. `java/lang/String`). */\n elemClassName?: string\n /** True element count (the preview may be shorter). */\n length: number\n /** Decoded text (`char[]` big-endian UTF-16, or a printable `byte[]` as Latin-1). */\n text?: string\n /** First bytes of a `byte[]` as hex. */\n hex?: string\n /** Element renderings: numeric values, or `#<id>` object references (each may carry its own `refId`). */\n elements?: HprofFieldValue[]\n /** True when the preview is a prefix of the whole array. */\n truncated: boolean\n}\n\n/** One object of a class in the drill-in list. */\nexport interface HprofInstance {\n /** The instance's own object id (decimal string). */\n id: string\n /** Shallow size estimate (field bytes + object-header estimate), matching the histogram. */\n size: number\n /** Decoded instance fields in on-disk order; empty when the layout couldn't be resolved (or an array). */\n fields: HprofFieldValue[]\n /** Present when this \"object\" is actually an array — its bounded content preview. */\n array?: HprofArrayPreview\n}\n\n/** What {@link Hprof.collect} drills into: a real class, or an array pseudo-class keyed by element type/class. */\nexport type CollectTarget =\n | { kind: 'class'; classObjId: string }\n | { kind: 'primArray'; elemType: number }\n | { kind: 'objArray'; elemClassId: string }\n\n/** A class (or array pseudo-class) row of the histogram. */\nexport interface HprofClassRow {\n name: string\n count: number\n bytes: number\n /** Drill-in descriptor — present on every row (classes and arrays are both drillable). */\n target?: CollectTarget\n}\n\n/** The resolved view of a single object id, produced by {@link Hprof.resolveObjects} (jump / dereference). */\nexport type HprofObjectView =\n | { id: string; kind: 'instance'; className: string; size: number; fields: HprofFieldValue[] }\n | {\n id: string\n kind: 'primArray'\n className: string\n size: number\n length: number\n elemType: number\n /** Raw element bytes, capped at {@link MAX_DEREF_BYTES} — lets the caller decode with a String coder. */\n rawBytes: Uint8Array\n array: HprofArrayPreview\n }\n | {\n id: string\n kind: 'objArray'\n className: string\n size: number\n length: number\n array: HprofArrayPreview\n }\n | { id: string; kind: 'class'; className: string }\n\nexport interface HprofSummary {\n idSize: number\n /** Dump time — epoch milliseconds as a string (may exceed 2^53). */\n timestamp: string\n fileSize: number\n recordCount: number\n classCount: number\n instanceCount: number\n gcRoots: number\n stringCount: number\n /** Total shallow bytes across all objects + arrays. */\n heapBytes: number\n /** Histogram rows, sorted by shallow bytes descending. */\n rows: HprofClassRow[]\n}\n\n/** Result of a per-class object collection (Pass B). */\nexport interface HprofCollectResult {\n /** Collected rows (≤ {@link MAX_COLLECT}); when filtering, only matches. */\n rows: HprofInstance[]\n /** Total instances of the class in the file (or, when filtering, total matches). */\n total: number\n /** True when `total` exceeded the cap, so `rows` is a prefix — the UI should offer whole-file search. */\n truncated: boolean\n}\n\nexport interface HprofProgress {\n (pos: number, size: number): void\n}\n\ninterface CollectOptions {\n /** Max rows to keep (default {@link MAX_COLLECT}). */\n limit?: number\n /** Keep only instances whose id or any decoded field value contains this (case-insensitive) text. */\n filter?: string\n onProgress?: HprofProgress\n}\n\n/** Cap on rows Pass B keeps in memory for one class — bounds memory regardless of the real instance count. */\nexport const MAX_COLLECT = 10000\n/** Cap on array elements listed in one preview — bounds memory when an array (or String) is huge. */\nexport const MAX_ARRAY_PREVIEW = 256\n/** Cap on raw bytes read per array object when dereferencing (String text / byte[] hex) — bounds memory. */\nexport const MAX_DEREF_BYTES = 8192\n/** Cap on bytes shown in a `byte[]` hex preview. */\nconst MAX_HEX = 256\n\n// Yield to the event loop every N sub-records so a long parse never freezes the UI (an all-microtask await\n// chain never hits a macrotask boundary; the browser can't paint). Also drives the progress callback.\nconst YIELD_EVERY = 4000\nfunction nextTick(): Promise<void> {\n return new Promise((res) => setTimeout(res, 0))\n}\n\n/** Read + validate the header; leaves the cursor at the first top-level record. Returns idSize + dump time. */\nasync function readHeader(r: ByteReader): Promise<{ idSize: number; timestamp: string }> {\n const magic = await r.cstring()\n if (!magic.startsWith('JAVA PROFILE')) {\n throw new HprofParseError('不是有效的 HPROF 文件(magic: \"' + magic.slice(0, 32) + '\")')\n }\n const idSize = await r.u4()\n if (idSize !== 1 && idSize !== 2 && idSize !== 4 && idSize !== 8) {\n throw new HprofParseError('异常的 idSize:' + idSize)\n }\n const tsHi = await r.u4()\n const tsLo = await r.u4()\n const timestamp = ((BigInt(tsHi) << 32n) | BigInt(tsLo)).toString()\n return { idSize, timestamp }\n}\n\n/** Fully consume a CLASS_DUMP sub-record (cursor already past the sub-tag) and return its structural info. */\nasync function readClassDump(\n r: ByteReader,\n idSize: number,\n): Promise<{ classObjId: string; info: ClassDumpInfo }> {\n const classObjId = await r.id(idSize)\n await r.skip(4) // stack trace serial\n const superId = await r.id(idSize)\n await r.skip(idSize * 5) // class loader, signers, protection domain, reserved1, reserved2\n const instanceSize = await r.u4()\n\n const cpSize = await r.u2() // constant pool\n for (let i = 0; i < cpSize; i++) {\n await r.u2() // cp index\n const t = await r.u1()\n await r.skip(typeSize(t, idSize))\n }\n const staticCount = await r.u2() // static fields\n for (let i = 0; i < staticCount; i++) {\n await r.id(idSize) // name string id\n const t = await r.u1()\n await r.skip(typeSize(t, idSize))\n }\n const instCount = await r.u2() // instance fields (type only, no value)\n const instFields: RawField[] = []\n for (let i = 0; i < instCount; i++) {\n const nameId = await r.id(idSize)\n const type = await r.u1()\n instFields.push({ nameId, type })\n }\n return { classObjId, info: { superId, instanceSize, instFields } }\n}\n\n/**\n * Skip one heap sub-record given its tag, EXCEPT the ones the caller wants to handle. Returns a small descriptor\n * for CLASS_DUMP / INSTANCE_DUMP / arrays so each pass reacts (record layout, tally histogram, or collect), and\n * `null` for GC roots (already fully skipped here). Throws on an unknown tag — the byte stream can't be resynced.\n */\ntype SubEvent =\n | { kind: 'class'; classObjId: string; info: ClassDumpInfo }\n | { kind: 'instance'; id: string; classObjId: string; numBytes: number }\n | { kind: 'objArray'; elemClassId: string; numElements: number; shallow: number }\n | { kind: 'primArray'; elemType: number; numElements: number; shallow: number }\n\nasync function readSub(r: ByteReader, sub: number, idSize: number): Promise<SubEvent | null> {\n const rootExtra = GC_ROOT_EXTRA[sub]\n if (rootExtra) {\n await r.skip(idSize + rootExtra(idSize))\n return null\n }\n switch (sub) {\n case SUB_CLASS_DUMP: {\n const { classObjId, info } = await readClassDump(r, idSize)\n return { kind: 'class', classObjId, info }\n }\n case SUB_INSTANCE_DUMP: {\n const id = await r.id(idSize)\n await r.skip(4) // stack trace serial\n const classObjId = await r.id(idSize)\n const numBytes = await r.u4()\n // Leaves the cursor BEFORE the field bytes — the caller reads them (target class) or skips them.\n return { kind: 'instance', id, classObjId, numBytes }\n }\n case SUB_OBJECT_ARRAY_DUMP: {\n await r.id(idSize) // array object id\n await r.skip(4) // stack trace serial\n const numElements = await r.u4()\n const elemClassId = await r.id(idSize)\n await r.skip(numElements * idSize)\n const shallow = numElements * idSize + idSize * 2 + 4\n return { kind: 'objArray', elemClassId, numElements, shallow }\n }\n case SUB_PRIMITIVE_ARRAY_DUMP: {\n await r.id(idSize) // array object id\n await r.skip(4) // stack trace serial\n const numElements = await r.u4()\n const elemType = await r.u1()\n await r.skip(numElements * typeSize(elemType, idSize))\n const shallow = numElements * typeSize(elemType, idSize) + idSize * 2 + 4\n return { kind: 'primArray', elemType, numElements, shallow }\n }\n default:\n throw new HprofParseError(\n '未知的堆子记录标记 0x' + sub.toString(16) + '(偏移 ' + r.globalPos + ')',\n )\n }\n}\n\n/** Read one id-width big-endian reference out of an in-memory DataView (instance field decode). */\nfunction readIdAt(dv: DataView, off: number, idSize: number): string {\n if (idSize === 8) return dv.getBigUint64(off, false).toString()\n if (idSize === 4) return dv.getUint32(off, false).toString()\n if (idSize === 2) return dv.getUint16(off, false).toString()\n return dv.getUint8(off).toString()\n}\n\n/** Decode one instance's field bytes against a resolved layout into display values. */\nfunction decodeFields(data: Uint8Array, layout: HprofField[], idSize: number): HprofFieldValue[] {\n const dv = new DataView(data.buffer, data.byteOffset, data.byteLength)\n const out: HprofFieldValue[] = []\n let off = 0\n for (const f of layout) {\n switch (f.type) {\n case T_OBJECT: {\n const id = readIdAt(dv, off, idSize)\n off += idSize\n out.push(\n id === '0'\n ? { name: f.name, value: 'null', kind: 'null' }\n : { name: f.name, value: '#' + id, kind: 'ref', refId: id },\n )\n break\n }\n case T_BOOLEAN:\n out.push({ name: f.name, value: dv.getUint8(off) !== 0 ? 'true' : 'false', kind: 'prim' })\n off += 1\n break\n case T_BYTE:\n out.push({ name: f.name, value: String(dv.getInt8(off)), kind: 'prim' })\n off += 1\n break\n case T_CHAR: {\n const c = dv.getUint16(off, false)\n out.push({ name: f.name, value: charDisplay(c), kind: 'prim' })\n off += 2\n break\n }\n case T_SHORT:\n out.push({ name: f.name, value: String(dv.getInt16(off, false)), kind: 'prim' })\n off += 2\n break\n case T_FLOAT:\n out.push({ name: f.name, value: fmtNum(dv.getFloat32(off, false)), kind: 'prim' })\n off += 4\n break\n case T_INT:\n out.push({ name: f.name, value: String(dv.getInt32(off, false)), kind: 'prim' })\n off += 4\n break\n case T_DOUBLE:\n out.push({ name: f.name, value: fmtNum(dv.getFloat64(off, false)), kind: 'prim' })\n off += 8\n break\n case T_LONG:\n out.push({ name: f.name, value: dv.getBigInt64(off, false).toString(), kind: 'prim' })\n off += 8\n break\n default:\n off += typeSize(f.type, idSize)\n }\n }\n return out\n}\n\n// A printable char reads as `'A'`; a control/non-printable one as its \\uXXXX escape so the list stays legible.\nfunction charDisplay(code: number): string {\n if (code >= 0x20 && code !== 0x7f) return \"'\" + String.fromCharCode(code) + \"'\"\n return \"'\\\\u\" + code.toString(16).padStart(4, '0') + \"'\"\n}\nfunction fmtNum(n: number): string {\n if (Number.isNaN(n)) return 'NaN'\n if (!Number.isFinite(n)) return n > 0 ? 'Infinity' : '-Infinity'\n return String(n)\n}\n\n// ── Array content decoding (bounded previews + String dereference) ────────────────────────────────\n\n/** JVM array descriptor → readable name: `[Ljava/lang/String;` → `java/lang/String[]`, `[[I` → `int[][]`. */\nfunction arrayClassDisplay(desc: string | undefined): string {\n if (!desc) return 'Object[]'\n if (desc[0] !== '[') return desc + '[]'\n let dims = 0\n let i = 0\n while (i < desc.length && desc[i] === '[') {\n dims++\n i++\n }\n let base = desc.slice(i)\n const prim: Record<string, string> = {\n Z: 'boolean',\n B: 'byte',\n C: 'char',\n S: 'short',\n I: 'int',\n J: 'long',\n F: 'float',\n D: 'double',\n }\n if (base.startsWith('L') && base.endsWith(';')) base = base.slice(1, -1)\n else base = prim[base] ?? base\n return base + '[]'.repeat(dims)\n}\n/** Element type name of an object array = its array display minus one dimension (`java/lang/String[]` → `…String`). */\nfunction arrayElemDisplay(desc: string | undefined): string {\n const full = arrayClassDisplay(desc)\n return full.endsWith('[]') ? full.slice(0, -2) : full\n}\n\n/** One primitive value at an offset, as a display string (shared by field + array-element decoding). */\nfunction primValueAt(dv: DataView, off: number, type: number): string {\n switch (type) {\n case T_BOOLEAN:\n return dv.getUint8(off) !== 0 ? 'true' : 'false'\n case T_BYTE:\n return String(dv.getInt8(off))\n case T_CHAR:\n return charDisplay(dv.getUint16(off, false))\n case T_SHORT:\n return String(dv.getInt16(off, false))\n case T_FLOAT:\n return fmtNum(dv.getFloat32(off, false))\n case T_INT:\n return String(dv.getInt32(off, false))\n case T_DOUBLE:\n return fmtNum(dv.getFloat64(off, false))\n case T_LONG:\n return dv.getBigInt64(off, false).toString()\n default:\n return '?'\n }\n}\nfunction decodeNumericElements(raw: Uint8Array, elemType: number): HprofFieldValue[] {\n const dv = new DataView(raw.buffer, raw.byteOffset, raw.byteLength)\n const sz = typeSize(elemType, 8)\n const n = Math.min(Math.floor(raw.byteLength / sz), MAX_ARRAY_PREVIEW)\n const out: HprofFieldValue[] = []\n for (let i = 0; i < n; i++)\n out.push({ name: String(i), value: primValueAt(dv, i * sz, elemType), kind: 'prim' })\n return out\n}\n\n/** HPROF `char[]` elements are big-endian UTF-16 code units. */\nfunction charBytesToString(raw: Uint8Array): string {\n let s = ''\n const n = raw.byteLength & ~1\n for (let i = 0; i < n; i += 2) s += String.fromCharCode((raw[i] << 8) | raw[i + 1])\n return s\n}\n/** Java 9+ compact-String UTF-16 `byte[]` is in-memory order (little-endian on the usual platforms). */\nfunction utf16leBytesToString(raw: Uint8Array): string {\n let s = ''\n const n = raw.byteLength & ~1\n for (let i = 0; i < n; i += 2) s += String.fromCharCode(raw[i] | (raw[i + 1] << 8))\n return s\n}\nfunction latin1BytesToString(raw: Uint8Array): string {\n let s = ''\n for (let i = 0; i < raw.byteLength; i++) s += String.fromCharCode(raw[i])\n return s\n}\n/** A `byte[]` shown as text only when it's mostly printable Latin-1 (otherwise the caller falls back to hex). */\nfunction printableLatin1(raw: Uint8Array): string | undefined {\n if (raw.byteLength === 0) return ''\n let printable = 0\n for (let i = 0; i < raw.byteLength; i++) {\n const b = raw[i]\n if ((b >= 0x20 && b < 0x7f) || b === 9 || b === 10 || b === 13) printable++\n }\n return printable / raw.byteLength >= 0.85 ? latin1BytesToString(raw) : undefined\n}\nfunction toHex(raw: Uint8Array): string {\n const n = Math.min(raw.byteLength, MAX_HEX)\n let s = ''\n for (let i = 0; i < n; i++) s += raw[i].toString(16).padStart(2, '0') + (i < n - 1 ? ' ' : '')\n return raw.byteLength > n ? s + ' …' : s\n}\n\n/** Bounded content preview of a primitive array: `char[]`/printable `byte[]` → text, `byte[]` → hex, else values. */\nfunction buildPrimArrayPreview(\n elemType: number,\n raw: Uint8Array,\n length: number,\n): HprofArrayPreview {\n const p: HprofArrayPreview = { elemType, length, truncated: false }\n if (elemType === T_CHAR) {\n p.text = charBytesToString(raw)\n p.truncated = raw.byteLength < length * 2\n } else if (elemType === T_BYTE) {\n p.hex = toHex(raw)\n const t = printableLatin1(raw)\n if (t !== undefined) p.text = t\n p.truncated = raw.byteLength < length\n } else {\n p.elements = decodeNumericElements(raw, elemType)\n p.truncated = p.elements.length < length\n }\n return p\n}\n\n/**\n * Decode a `java.lang.String`'s backing array bytes to text. Legacy `char[]` (Java 8) is big-endian UTF-16;\n * Java 9+ `byte[]` is LATIN1 when `coder===0`, else in-memory UTF-16 (little-endian). `coder` comes from the\n * String instance's own decoded `coder` field (null for the char[] layout).\n */\nexport function decodeStringValue(raw: Uint8Array, elemType: number, coder: number | null): string {\n if (elemType === T_CHAR) return charBytesToString(raw)\n return coder === 1 ? utf16leBytesToString(raw) : latin1BytesToString(raw)\n}\n\n/**\n * A parsed heap dump. {@link parse} runs Pass A and returns this handle; {@link summary} feeds the histogram UI,\n * and {@link collect} runs Pass B on demand for one class. The originating Blob + the bounded class/name tables\n * are retained so drill-in needs no re-parse of Pass A.\n */\nexport class Hprof {\n readonly summary: HprofSummary\n private constructor(\n private readonly blob: Blob,\n summary: HprofSummary,\n private readonly idSize: number,\n private readonly classInfo: Map<string, ClassDumpInfo>,\n private readonly classNames: Map<string, string>,\n private readonly strings: Map<string, string>,\n private readonly layoutCache: Map<string, HprofField[] | null>,\n ) {\n this.summary = summary\n }\n\n /** Class name for an object id (falls back to a synthetic `<class#id>`). */\n classNameOf(classObjId: string): string {\n return this.classNames.get(classObjId) ?? '<class#' + classObjId + '>'\n }\n\n /**\n * Resolve the on-disk instance-field layout: this class's declared fields, then each superclass's, up the\n * chain (the order INSTANCE_DUMP lays field data out in). Cached. Returns null if a class in the chain has no\n * CLASS_DUMP (can't compute the layout) — the caller then shows id + size only.\n */\n private resolveLayout(classObjId: string): HprofField[] | null {\n const cached = this.layoutCache.get(classObjId)\n if (cached !== undefined) return cached\n const fields: HprofField[] = []\n let cur = classObjId\n const seen = new Set<string>()\n while (cur !== '0') {\n if (seen.has(cur)) break // defensive: a cyclic super chain shouldn't happen, but never loop forever\n seen.add(cur)\n const info = this.classInfo.get(cur)\n if (!info) {\n this.layoutCache.set(classObjId, null)\n return null\n }\n for (const f of info.instFields) {\n fields.push({\n name: this.strings.get(f.nameId) ?? '<field#' + f.nameId + '>',\n type: f.type,\n })\n }\n cur = info.superId\n }\n this.layoutCache.set(classObjId, fields)\n return fields\n }\n\n static async parse(blob: Blob, onProgress?: HprofProgress): Promise<Hprof> {\n const r = new ByteReader(blob)\n const { idSize, timestamp } = await readHeader(r)\n\n const strings = new Map<string, string>() // stringId -> name\n const classNameStrId = new Map<string, string>() // classObjId -> name stringId (LOAD_CLASS)\n const classInfo = new Map<string, ClassDumpInfo>() // classObjId -> layout/super/size (CLASS_DUMP)\n const perClass = new Map<string, { count: number; bytes: number }>()\n const objArrays = new Map<string, { count: number; bytes: number }>() // elemClassId -> tally\n const primArrays = new Map<number, { count: number; bytes: number }>() // elemType -> tally\n let gcRoots = 0\n let instanceCount = 0\n let recordCount = 0\n let classCount = 0\n let heapBytes = 0\n\n let iter = 0\n const tick = async (): Promise<void> => {\n if (++iter % YIELD_EVERY === 0) {\n onProgress?.(r.globalPos, r.size)\n await nextTick()\n }\n }\n\n while (r.globalPos < r.size) {\n const tag = await r.u1()\n await r.u4() // record time (ignored)\n const length = await r.u4()\n const recEnd = r.globalPos + length\n recordCount++\n\n if (tag === TAG_STRING) {\n const sid = await r.id(idSize)\n const strBytes = await r.bytes(length - idSize)\n strings.set(sid, new TextDecoder('utf-8').decode(strBytes))\n } else if (tag === TAG_LOAD_CLASS) {\n await r.u4() // class serial\n const classObjId = await r.id(idSize)\n await r.u4() // stack trace serial\n const nameId = await r.id(idSize)\n classNameStrId.set(classObjId, nameId)\n } else if (tag === TAG_HEAP_DUMP || tag === TAG_HEAP_DUMP_SEGMENT) {\n while (r.globalPos < recEnd) {\n const sub = await r.u1()\n const ev = await readSub(r, sub, idSize)\n if (ev) {\n if (ev.kind === 'class') {\n classInfo.set(ev.classObjId, ev.info)\n classCount++\n } else if (ev.kind === 'instance') {\n await r.skip(ev.numBytes) // Pass A never reads field data\n instanceCount++\n const shallow = ev.numBytes + idSize * 2\n heapBytes += shallow\n const e = perClass.get(ev.classObjId)\n if (e) {\n e.count++\n e.bytes += shallow\n } else {\n perClass.set(ev.classObjId, { count: 1, bytes: shallow })\n }\n } else if (ev.kind === 'objArray') {\n instanceCount++\n heapBytes += ev.shallow\n const e = objArrays.get(ev.elemClassId)\n if (e) {\n e.count++\n e.bytes += ev.shallow\n } else {\n objArrays.set(ev.elemClassId, { count: 1, bytes: ev.shallow })\n }\n } else {\n instanceCount++\n heapBytes += ev.shallow\n const e = primArrays.get(ev.elemType)\n if (e) {\n e.count++\n e.bytes += ev.shallow\n } else {\n primArrays.set(ev.elemType, { count: 1, bytes: ev.shallow })\n }\n }\n } else {\n gcRoots++\n }\n await tick()\n }\n } else {\n await r.skip(length) // unknown / uninteresting top-level record — self-describing length\n }\n\n // Guard: consume exactly to the record boundary so one mis-sized branch can't desync everything after it.\n if (r.globalPos < recEnd) await r.skip(recEnd - r.globalPos)\n else if (r.globalPos > recEnd) {\n throw new HprofParseError(\n '解析在标记 0x' +\n tag.toString(16) +\n ' 处越界(偏移 ' +\n r.globalPos +\n ',应止于 ' +\n recEnd +\n ')',\n )\n }\n await tick()\n }\n\n // Resolve class id → name now that every STRING / LOAD_CLASS has been seen (order isn't guaranteed).\n const classNames = new Map<string, string>()\n for (const [classObjId, nameId] of classNameStrId) {\n classNames.set(classObjId, strings.get(nameId) ?? '<class#' + classObjId + '>')\n }\n\n const rows: HprofClassRow[] = []\n for (const [classObjId, e] of perClass) {\n rows.push({\n name: classNames.get(classObjId) ?? '<class#' + classObjId + '>',\n count: e.count,\n bytes: e.bytes,\n target: { kind: 'class', classObjId },\n })\n }\n for (const [elemClassId, e] of objArrays) {\n rows.push({\n name: arrayClassDisplay(classNames.get(elemClassId)),\n count: e.count,\n bytes: e.bytes,\n target: { kind: 'objArray', elemClassId },\n })\n }\n for (const [elemType, e] of primArrays) {\n rows.push({\n name: primTypeName(elemType) + '[]',\n count: e.count,\n bytes: e.bytes,\n target: { kind: 'primArray', elemType },\n })\n }\n rows.sort((a, b) => b.bytes - a.bytes || b.count - a.count)\n\n onProgress?.(r.size, r.size)\n const summary: HprofSummary = {\n idSize,\n timestamp,\n fileSize: blob.size,\n recordCount,\n classCount,\n instanceCount,\n gcRoots,\n stringCount: strings.size,\n heapBytes,\n rows,\n }\n return new Hprof(blob, summary, idSize, classInfo, classNames, strings, new Map())\n }\n\n /**\n * Pass B: stream the file again and collect the objects of one drill-in target — a class (its instances), a\n * primitive-array type, or an object-array type. Decodes only matching objects (skipping everything else),\n * keeping at most `limit` rows; with `filter`, keeps only rows whose id / field value / array content contains\n * the (lower-cased) text — so a target that overflows the cap can still be searched across the WHOLE file.\n * `total` counts every matching object even beyond the cap.\n */\n async collect(target: CollectTarget, opts: CollectOptions = {}): Promise<HprofCollectResult> {\n const limit = opts.limit ?? MAX_COLLECT\n const needle = opts.filter?.trim().toLowerCase() ?? ''\n const idSize = this.idSize\n const layout = target.kind === 'class' ? this.resolveLayout(target.classObjId) : null\n\n const r = new ByteReader(this.blob)\n await readHeader(r)\n\n const rows: HprofInstance[] = []\n let total = 0\n let iter = 0\n const tick = async (): Promise<void> => {\n if (++iter % YIELD_EVERY === 0) {\n opts.onProgress?.(r.globalPos, r.size)\n await nextTick()\n }\n }\n // Keep a decoded row if it passes the filter and still fits the cap; count every match toward the total.\n const consider = (row: HprofInstance): void => {\n if (needle && !rowMatches(row, needle)) return\n total++\n if (rows.length < limit) rows.push(row)\n }\n\n while (r.globalPos < r.size) {\n const tag = await r.u1()\n await r.u4()\n const length = await r.u4()\n const recEnd = r.globalPos + length\n\n if (tag === TAG_HEAP_DUMP || tag === TAG_HEAP_DUMP_SEGMENT) {\n while (r.globalPos < recEnd) {\n const sub = await r.u1()\n if (target.kind === 'class' && sub === SUB_INSTANCE_DUMP) {\n const id = await r.id(idSize)\n await r.skip(4)\n const cls = await r.id(idSize)\n const numBytes = await r.u4()\n if (cls === target.classObjId) {\n const shallow = numBytes + idSize * 2\n // Decode only when the row can still matter (under cap, or filtering to find matches past it).\n if (needle || rows.length < limit) {\n const data = await r.bytes(numBytes)\n const fields = layout ? decodeFields(data, layout, idSize) : []\n consider({ id, size: shallow, fields })\n } else {\n await r.skip(numBytes)\n total++\n }\n } else {\n await r.skip(numBytes)\n }\n } else if (target.kind === 'primArray' && sub === SUB_PRIMITIVE_ARRAY_DUMP) {\n const id = await r.id(idSize)\n await r.skip(4)\n const num = await r.u4()\n const elemType = await r.u1()\n const nbytes = num * typeSize(elemType, idSize)\n if (elemType === target.elemType) {\n const shallow = nbytes + idSize * 2 + 4\n if (needle || rows.length < limit) {\n const take = Math.min(nbytes, MAX_DEREF_BYTES)\n const raw = await r.bytes(take)\n await r.skip(nbytes - take)\n consider({\n id,\n size: shallow,\n fields: [],\n array: buildPrimArrayPreview(elemType, raw, num),\n })\n } else {\n await r.skip(nbytes)\n total++\n }\n } else {\n await r.skip(nbytes)\n }\n } else if (target.kind === 'objArray' && sub === SUB_OBJECT_ARRAY_DUMP) {\n const id = await r.id(idSize)\n await r.skip(4)\n const num = await r.u4()\n const arrClassId = await r.id(idSize)\n if (arrClassId === target.elemClassId) {\n const shallow = num * idSize + idSize * 2 + 4\n if (needle || rows.length < limit) {\n const array = await this.readObjArrayPreview(r, num, arrClassId, idSize)\n consider({ id, size: shallow, fields: [], array })\n } else {\n await r.skip(num * idSize)\n total++\n }\n } else {\n await r.skip(num * idSize)\n }\n } else {\n // Not our target: consume for positioning. readSub fully skips arrays / classes / GC roots, but\n // leaves an INSTANCE_DUMP's field bytes for the caller — skip them so the sub is fully consumed.\n const ev = await readSub(r, sub, idSize)\n if (ev && ev.kind === 'instance') await r.skip(ev.numBytes)\n }\n await tick()\n }\n } else {\n await r.skip(length)\n }\n\n if (r.globalPos < recEnd) await r.skip(recEnd - r.globalPos)\n else if (r.globalPos > recEnd) {\n throw new HprofParseError('解析越界(偏移 ' + r.globalPos + ',应止于 ' + recEnd + ')')\n }\n await tick()\n }\n\n opts.onProgress?.(r.size, r.size)\n return { rows, total, truncated: total > rows.length }\n }\n\n /** Read a bounded element-id preview of an object array (cursor just past its array-class id). */\n private async readObjArrayPreview(\n r: ByteReader,\n num: number,\n arrClassId: string,\n idSize: number,\n ): Promise<HprofArrayPreview> {\n const take = Math.min(num, MAX_ARRAY_PREVIEW)\n const elements: HprofFieldValue[] = []\n for (let i = 0; i < take; i++) {\n const eid = await r.id(idSize)\n elements.push(\n eid === '0'\n ? { name: String(i), value: 'null', kind: 'null' }\n : { name: String(i), value: '#' + eid, kind: 'ref', refId: eid },\n )\n }\n await r.skip((num - take) * idSize)\n return {\n elemClassName: arrayElemDisplay(this.classNames.get(arrClassId)),\n length: num,\n elements,\n truncated: take < num,\n }\n }\n\n /**\n * Resolve a batch of object ids in ONE streaming sweep — the on-demand random access a preview needs to follow\n * a reference (jump to an object) or dereference a value (a String's backing `byte[]`/`char[]`). Class-object\n * ids resolve without scanning. Only ids actually found are returned (GC'd / unknown ids are absent). Bounded:\n * array content is capped (see {@link MAX_ARRAY_PREVIEW} / {@link MAX_DEREF_BYTES}), so memory stays ∝ the batch.\n */\n async resolveObjects(\n ids: Set<string>,\n onProgress?: HprofProgress,\n ): Promise<Map<string, HprofObjectView>> {\n const idSize = this.idSize\n const out = new Map<string, HprofObjectView>()\n let remaining = 0\n for (const id of ids) {\n const cn = this.classNames.get(id)\n if (cn) out.set(id, { id, kind: 'class', className: cn })\n else remaining++\n }\n if (remaining === 0) return out\n\n const r = new ByteReader(this.blob)\n await readHeader(r)\n let iter = 0\n const tick = async (): Promise<void> => {\n if (++iter % YIELD_EVERY === 0) {\n onProgress?.(r.globalPos, r.size)\n await nextTick()\n }\n }\n\n while (r.globalPos < r.size && remaining > 0) {\n const tag = await r.u1()\n await r.u4()\n const length = await r.u4()\n const recEnd = r.globalPos + length\n\n if (tag === TAG_HEAP_DUMP || tag === TAG_HEAP_DUMP_SEGMENT) {\n while (r.globalPos < recEnd && remaining > 0) {\n const sub = await r.u1()\n if (sub === SUB_INSTANCE_DUMP) {\n const id = await r.id(idSize)\n await r.skip(4)\n const cls = await r.id(idSize)\n const numBytes = await r.u4()\n if (ids.has(id) && !out.has(id)) {\n const data = await r.bytes(numBytes)\n const layout = this.resolveLayout(cls)\n out.set(id, {\n id,\n kind: 'instance',\n className: this.classNameOf(cls),\n size: numBytes + idSize * 2,\n fields: layout ? decodeFields(data, layout, idSize) : [],\n })\n remaining--\n } else {\n await r.skip(numBytes)\n }\n } else if (sub === SUB_PRIMITIVE_ARRAY_DUMP) {\n const id = await r.id(idSize)\n await r.skip(4)\n const num = await r.u4()\n const elemType = await r.u1()\n const nbytes = num * typeSize(elemType, idSize)\n if (ids.has(id) && !out.has(id)) {\n const take = Math.min(nbytes, MAX_DEREF_BYTES)\n const raw = await r.bytes(take)\n await r.skip(nbytes - take)\n out.set(id, {\n id,\n kind: 'primArray',\n className: primTypeName(elemType) + '[]',\n size: nbytes + idSize * 2 + 4,\n length: num,\n elemType,\n rawBytes: raw,\n array: buildPrimArrayPreview(elemType, raw, num),\n })\n remaining--\n } else {\n await r.skip(nbytes)\n }\n } else if (sub === SUB_OBJECT_ARRAY_DUMP) {\n const id = await r.id(idSize)\n await r.skip(4)\n const num = await r.u4()\n const arrClassId = await r.id(idSize)\n if (ids.has(id) && !out.has(id)) {\n const array = await this.readObjArrayPreview(r, num, arrClassId, idSize)\n out.set(id, {\n id,\n kind: 'objArray',\n className: arrayClassDisplay(this.classNames.get(arrClassId)),\n size: num * idSize + idSize * 2 + 4,\n length: num,\n array,\n })\n remaining--\n } else {\n await r.skip(num * idSize)\n }\n } else if (sub === SUB_CLASS_DUMP) {\n await readClassDump(r, idSize)\n } else {\n const rootExtra = GC_ROOT_EXTRA[sub]\n if (rootExtra) await r.skip(idSize + rootExtra(idSize))\n else\n throw new HprofParseError(\n '未知的堆子记录标记 0x' + sub.toString(16) + '(偏移 ' + r.globalPos + ')',\n )\n }\n await tick()\n }\n } else {\n await r.skip(length)\n }\n\n // Skip to the record boundary — also the fast path out when every id was found mid-segment.\n if (r.globalPos < recEnd) await r.skip(recEnd - r.globalPos)\n else if (r.globalPos > recEnd) {\n throw new HprofParseError('解析越界(偏移 ' + r.globalPos + ',应止于 ' + recEnd + ')')\n }\n await tick()\n }\n\n onProgress?.(r.size, r.size)\n return out\n }\n}\n\n/**\n * Case-insensitive match of a needle against a row's id, any field's `name=value` rendering, or its array\n * content (decoded text, hex, or element values) — the same text the preview shows, so `true`, `active`, and\n * `active=true` all match. `needle` is pre-lowercased.\n */\nfunction rowMatches(o: HprofInstance, needle: string): boolean {\n if (o.id.includes(needle)) return true\n for (const f of o.fields) {\n if ((f.name + '=' + f.value).toLowerCase().includes(needle)) return true\n }\n const a = o.array\n if (a) {\n if (a.text && a.text.toLowerCase().includes(needle)) return true\n if (a.hex && a.hex.includes(needle)) return true\n if (a.elements) {\n for (const e of a.elements) if (e.value.toLowerCase().includes(needle)) return true\n }\n }\n return false\n}\n"],"mappings":"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"}
package/dist/lib/ipynb.js CHANGED
@@ -128,3 +128,5 @@ function c(t) {
128
128
  }
129
129
  //#endregion
130
130
  export { c as parseNotebook };
131
+
132
+ //# sourceMappingURL=ipynb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipynb.js","names":[],"sources":["../../src/lib/ipynb.ts"],"sourcesContent":["/**\n * Hand-rolled, zero-dependency Jupyter Notebook (.ipynb) parser for the side viewer.\n *\n * A notebook is JSON: a list of cells (markdown / code / raw), each code cell carrying its outputs. This\n * flattens that into a render-ready shape the viewer can walk — markdown reuses the app's markdown engine,\n * code reuses highlight.js, and each output is reduced to one best-fit representation (richest mime wins,\n * mirroring Jupyter's own display priority). nbformat 4 is the target; v3 (worksheets + inline output keys)\n * is tolerated as a best-effort fallback.\n *\n * Rich HTML output is hostile markup (it comes from arbitrary kernels) — the viewer renders it in a fully\n * sandboxed, script-disabled iframe, so this parser only carries the raw string; it never trusts it.\n */\n\nexport type NbOutput =\n | { kind: 'stream'; text: string; isError: boolean }\n | { kind: 'text'; text: string }\n | { kind: 'json'; text: string }\n | { kind: 'markdown'; text: string }\n | { kind: 'html'; html: string }\n | { kind: 'image'; src: string }\n | { kind: 'error'; text: string }\n\nexport interface NbCell {\n type: 'markdown' | 'code' | 'raw'\n source: string\n executionCount: number | null\n outputs: NbOutput[]\n}\n\nexport interface ParsedNotebook {\n cells: NbCell[]\n language: string\n nbformat: number\n}\n\ntype Dict = Record<string, unknown>\n\n// nbformat stores multi-line strings as an array of lines (each keeping its trailing \\n) OR a plain string.\nfunction joinSource(src: unknown): string {\n if (Array.isArray(src)) return src.map((s) => (typeof s === 'string' ? s : '')).join('')\n return typeof src === 'string' ? src : ''\n}\n\nconst ESC = String.fromCharCode(27)\n\n// Strip ANSI/VT escape sequences (IPython colorizes tracebacks). Hand-scanned to avoid a control char in the\n// source: on each ESC, skip a `[ … <final letter>` CSI run. Leaves the plain, readable text.\nfunction stripAnsi(s: string): string {\n let out = ''\n for (let i = 0; i < s.length; i++) {\n if (s[i] !== ESC) {\n out += s[i]\n continue\n }\n i++ // past ESC\n if (s[i] === '[') {\n i++\n while (i < s.length && !/[A-Za-z]/.test(s[i])) i++ // params/intermediates, up to the final byte\n }\n }\n return out\n}\n\nfunction isDict(v: unknown): v is Dict {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n\n// The MIME bundle for a display_data / execute_result output, normalizing v3's inline keys (png/html/text…).\nfunction outputData(o: Dict): Dict {\n if (isDict(o.data)) return o.data\n const d: Dict = {}\n if (o.png) d['image/png'] = o.png\n if (o.jpeg) d['image/jpeg'] = o.jpeg\n if (o.gif) d['image/gif'] = o.gif\n if (o.svg) d['image/svg+xml'] = o.svg\n if (o.html) d['text/html'] = o.html\n if (o.latex) d['text/latex'] = o.latex\n if (o.text) d['text/plain'] = o.text\n return d\n}\n\n// Reduce a MIME bundle to one renderable output, richest representation first (Jupyter's display order).\nfunction pickRich(data: Dict): NbOutput {\n const has = (k: string) => data[k] != null\n const get = (k: string) => joinSource(data[k])\n if (has('text/html')) return { kind: 'html', html: get('text/html') }\n if (has('image/svg+xml')) {\n return { kind: 'image', src: `data:image/svg+xml,${encodeURIComponent(get('image/svg+xml'))}` }\n }\n for (const mime of ['image/png', 'image/jpeg', 'image/gif']) {\n if (has(mime))\n return { kind: 'image', src: `data:${mime};base64,${get(mime).replace(/\\s+/g, '')}` }\n }\n if (has('text/markdown')) return { kind: 'markdown', text: get('text/markdown') }\n if (has('text/latex')) return { kind: 'text', text: get('text/latex') }\n if (has('application/json')) {\n try {\n return { kind: 'json', text: JSON.stringify(data['application/json'], null, 2) }\n } catch {\n return { kind: 'text', text: get('application/json') }\n }\n }\n return { kind: 'text', text: get('text/plain') }\n}\n\nfunction parseOutput(o: Dict): NbOutput | null {\n // v3 uses pyout/pyerr; v4 execute_result/error. Normalize.\n const type = String(o.output_type ?? '')\n if (type === 'stream') {\n return { kind: 'stream', text: joinSource(o.text), isError: o.name === 'stderr' }\n }\n if (type === 'error' || type === 'pyerr') {\n const tb = Array.isArray(o.traceback) ? o.traceback.join('\\n') : ''\n const head = `${o.ename ?? 'Error'}: ${o.evalue ?? ''}`.trim()\n return { kind: 'error', text: stripAnsi(tb) || head }\n }\n if (type === 'execute_result' || type === 'display_data' || type === 'pyout') {\n return pickRich(outputData(o))\n }\n return null\n}\n\nfunction detectLanguage(meta: Dict): string {\n const info = isDict(meta.language_info) ? meta.language_info : {}\n const ks = isDict(meta.kernelspec) ? meta.kernelspec : {}\n const name = String(info.name ?? ks.language ?? '').toLowerCase()\n if (!name || name === 'ipython') return 'python'\n return name\n}\n\n/** Parse .ipynb source text into a flat, render-ready cell list. Throws on non-notebook JSON. */\nexport function parseNotebook(text: string): ParsedNotebook {\n const nb = JSON.parse(text) as Dict\n const meta = isDict(nb.metadata) ? nb.metadata : {}\n // v4: top-level cells. v3: cells nested under worksheets[].\n const rawCells: unknown[] = Array.isArray(nb.cells)\n ? nb.cells\n : Array.isArray(nb.worksheets)\n ? nb.worksheets.flatMap((w) => (isDict(w) && Array.isArray(w.cells) ? w.cells : []))\n : []\n if (!Array.isArray(nb.cells) && !Array.isArray(nb.worksheets)) {\n throw new Error('不是有效的 Jupyter Notebook(缺少 cells)')\n }\n\n const cells: NbCell[] = []\n for (const raw of rawCells) {\n if (!isDict(raw)) continue\n // v3 named code cells \"code\"; markdown/heading/raw otherwise.\n const ct = String(raw.cell_type ?? '')\n const source = joinSource(raw.source ?? raw.input)\n if (ct === 'code') {\n const outs = Array.isArray(raw.outputs) ? raw.outputs : []\n const outputs: NbOutput[] = []\n for (const o of outs) {\n if (!isDict(o)) continue\n const parsed = parseOutput(o)\n if (parsed) outputs.push(parsed)\n }\n const ec = raw.execution_count ?? raw.prompt_number\n cells.push({\n type: 'code',\n source,\n executionCount: typeof ec === 'number' ? ec : null,\n outputs,\n })\n } else if (ct === 'markdown' || ct === 'heading') {\n // v3 heading cells carry a level; render as a markdown heading.\n const level = typeof raw.level === 'number' ? '#'.repeat(Math.min(6, raw.level)) + ' ' : ''\n cells.push({ type: 'markdown', source: level + source, executionCount: null, outputs: [] })\n } else {\n cells.push({ type: 'raw', source, executionCount: null, outputs: [] })\n }\n }\n\n return {\n cells,\n language: detectLanguage(meta),\n nbformat: typeof nb.nbformat === 'number' ? nb.nbformat : 4,\n }\n}\n"],"mappings":"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"}
package/dist/lib/jks.js CHANGED
@@ -165,3 +165,5 @@ function _(i, a) {
165
165
  }
166
166
  //#endregion
167
167
  export { a as JCEKS_MAGIC, i as JKS_MAGIC, d as JksError, _ as decryptPrivateKey, h as readJks, g as verifyStorePassword };
168
+
169
+ //# sourceMappingURL=jks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jks.js","names":[],"sources":["../../src/lib/jks.ts"],"sourcesContent":["/**\n * Zero-dependency reader for Java keystores — JKS (`0xFEEDFEED`) and JCEKS (`0xCECECECE`) — for the keystore\n * viewer (JksViewer.vue). It parses the proprietary Sun on-disk format (magic / version / entry list / trailing\n * SHA-1 MAC) into an inventory of aliases, entry kinds, creation dates and certificate chains, and — given the\n * password — verifies store integrity and decrypts JKS private keys.\n *\n * What it can do, entirely in-browser and READ-ONLY:\n * - list every entry (private-key / trusted-cert), its alias + creation time, and each entry's X.509 chain\n * (certificates are stored UNENCRYPTED, so they always parse — see lib/x509.ts for the field extraction);\n * - verify the store password via the format's keyed MAC — SHA1(passwordUtf16BE ‖ \"Mighty Aphrodite\" ‖ body);\n * - decrypt a JKS private key with Sun's KeyProtector (OID 1.3.6.1.4.1.42.2.17.1.1): a SHA-1 keystream XOR\n * with a trailing SHA-1 check digest that doubles as the password check. On success the plaintext is a DER\n * PKCS#8 PrivateKeyInfo, from which we surface the key algorithm / size.\n *\n * Scope: JCEKS trusted certs + integrity parse the same way, but JCEKS private keys use PBEWithMD5AndTripleDES\n * (a different, heavier scheme) — reported as unsupported rather than decrypted. A JCEKS *secret-key* entry is a\n * Java-serialized object with no length prefix we can skip, so hitting one stops the entry walk (already-parsed\n * entries are kept, with a note). PKCS#12 keystores (`.p12`/`.pfx`) are a different format entirely — handled by\n * the certificate viewer, not here.\n */\n\nimport { decodeAsn1, oidToString } from './asn1'\nimport { describePrivateKey } from './x509'\nimport { Sha1 } from './sha1'\n\nexport const JKS_MAGIC = 0xfeedfeed\nexport const JCEKS_MAGIC = 0xcececece\n\n// Sun's proprietary \"key protector\" (JKS private-key encryption). JCEKS keys instead use the PBE OID below.\nconst KEY_PROTECTOR_OID = '1.3.6.1.4.1.42.2.17.1.1'\nconst JCEKS_PBE_OID = '1.3.6.1.4.1.42.2.19.1' // PBEWithMD5AndTripleDES\n\n// The fixed salt string mixed into the store-integrity MAC (sun.security.provider.JavaKeyStore).\nconst MAC_SALT = /* @__PURE__ */ new TextEncoder().encode('Mighty Aphrodite')\n\nconst SALT_LEN = 20\nconst DIGEST_LEN = 20\n\nexport type JksStoreType = 'jks' | 'jceks'\nexport type JksEntryType = 'privateKey' | 'trustedCert' | 'secretKey'\n\nexport interface JksCertRef {\n /** Certificate type as stored (almost always `X.509`). */\n type: string\n der: Uint8Array\n}\n\nexport interface JksEntry {\n type: JksEntryType\n alias: string\n /** Creation time (epoch ms); 0 when unknown. */\n createdMs: number\n /** Trusted-cert: one cert. Private-key: the (possibly empty) chain. Secret-key: none. */\n certs: JksCertRef[]\n /** Private-key entries only: the DER EncryptedPrivateKeyInfo (decrypt with {@link decryptPrivateKey}). */\n encryptedKey?: Uint8Array\n}\n\nexport interface JksStore {\n storeType: JksStoreType\n version: number\n entries: JksEntry[]\n /** Bytes covered by the integrity MAC — everything except the trailing 20-byte digest. */\n macData: Uint8Array\n /** The trailing 20-byte stored SHA-1 digest (or empty if the file is too short to hold one). */\n storedDigest: Uint8Array\n /** Set when the entry walk stopped early (e.g. an unskippable JCEKS secret-key entry). */\n truncatedNote?: string\n}\n\nexport class JksError extends Error {}\n\n/** Java DataInput.readUTF uses \"modified UTF-8\": NUL as C0 80, supplementary chars as CESU-8 surrogate pairs. */\nfunction readModifiedUtf8(bytes: Uint8Array, start: number, len: number): string {\n let out = ''\n let i = start\n const end = start + len\n while (i < end) {\n const a = bytes[i]\n if (a < 0x80 && a !== 0) {\n out += String.fromCharCode(a)\n i += 1\n } else if ((a & 0xe0) === 0xc0) {\n const b = bytes[i + 1] ?? 0\n out += String.fromCharCode(((a & 0x1f) << 6) | (b & 0x3f))\n i += 2\n } else if ((a & 0xf0) === 0xe0) {\n const b = bytes[i + 1] ?? 0\n const c = bytes[i + 2] ?? 0\n out += String.fromCharCode(((a & 0x0f) << 12) | ((b & 0x3f) << 6) | (c & 0x3f))\n i += 3\n } else {\n // Malformed lead byte — emit it raw and advance so we never spin.\n out += String.fromCharCode(a)\n i += 1\n }\n }\n return out\n}\n\n/** Password → UTF-16BE bytes, the form Sun feeds to both the store MAC and the KeyProtector. */\nfunction passwordToUtf16(password: string): Uint8Array {\n const out = new Uint8Array(password.length * 2)\n for (let i = 0; i < password.length; i++) {\n const c = password.charCodeAt(i)\n out[2 * i] = (c >>> 8) & 0xff\n out[2 * i + 1] = c & 0xff\n }\n return out\n}\n\nfunction bytesEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false\n return true\n}\n\n/**\n * Parse a JKS/JCEKS keystore from its raw bytes. Certificates and the entry inventory come out regardless of\n * any password (they're stored in the clear); use {@link verifyStorePassword} / {@link decryptPrivateKey} for\n * the password-gated parts. Throws {@link JksError} for a bad magic / version / truncated stream.\n */\nexport function readJks(buf: ArrayBuffer): JksStore {\n const bytes = new Uint8Array(buf)\n if (bytes.length < 8) throw new JksError('文件过小,不是有效的 keystore')\n const dv = new DataView(buf)\n let p = 0\n\n const magic = dv.getUint32(p)\n p += 4\n let storeType: JksStoreType\n if (magic === JKS_MAGIC) storeType = 'jks'\n else if (magic === JCEKS_MAGIC) storeType = 'jceks'\n else {\n throw new JksError(\n `文件头不匹配(magic=0x${magic.toString(16).padStart(8, '0')})—— 不是 JKS/JCEKS keystore` +\n '(PKCS#12 的 .p12/.pfx 请用证书查看器打开)',\n )\n }\n\n const version = dv.getUint32(p)\n p += 4\n if (version !== 1 && version !== 2) throw new JksError(`不支持的 keystore 版本 ${version}`)\n\n const count = dv.getUint32(p)\n p += 4\n if (count > 1_000_000) throw new JksError(`条目数异常(${count})`)\n\n const readUtf = (): string => {\n if (p + 2 > bytes.length) throw new JksError('数据被截断')\n const len = dv.getUint16(p)\n p += 2\n if (p + len > bytes.length) throw new JksError('数据被截断')\n const s = readModifiedUtf8(bytes, p, len)\n p += len\n return s\n }\n const readInt = (): number => {\n if (p + 4 > bytes.length) throw new JksError('数据被截断')\n const v = dv.getUint32(p)\n p += 4\n return v\n }\n const readLong = (): number => {\n if (p + 8 > bytes.length) throw new JksError('数据被截断')\n const v = Number(dv.getBigUint64(p))\n p += 8\n return v\n }\n // Copy out a slice so the returned bytes don't retain a view into the whole file buffer.\n const readBytes = (n: number): Uint8Array => {\n if (n < 0 || p + n > bytes.length) throw new JksError('数据被截断')\n const out = bytes.slice(p, p + n)\n p += n\n return out\n }\n\n const entries: JksEntry[] = []\n let truncatedNote: string | undefined\n\n for (let i = 0; i < count; i++) {\n const tag = readInt()\n if (tag === 1) {\n // Private-key entry: alias, date, EncryptedPrivateKeyInfo, then the certificate chain.\n const alias = readUtf()\n const createdMs = readLong()\n const keyLen = readInt()\n const encryptedKey = readBytes(keyLen)\n const chainLen = readInt()\n const certs: JksCertRef[] = []\n for (let j = 0; j < chainLen; j++) {\n const type = version === 2 ? readUtf() : 'X.509'\n const certLen = readInt()\n certs.push({ type, der: readBytes(certLen) })\n }\n entries.push({ type: 'privateKey', alias, createdMs, certs, encryptedKey })\n } else if (tag === 2) {\n // Trusted-certificate entry: alias, date, one certificate.\n const alias = readUtf()\n const createdMs = readLong()\n const type = version === 2 ? readUtf() : 'X.509'\n const certLen = readInt()\n const der = readBytes(certLen)\n entries.push({ type: 'trustedCert', alias, createdMs, certs: [{ type, der }] })\n } else if (tag === 3 && storeType === 'jceks') {\n // JCEKS secret-key entry: a Java-serialized SealedObject with no length prefix we can skip past — so we\n // record it and stop (the integrity MAC below is offset-independent, so it still works on the whole file).\n const alias = readUtf()\n entries.push({ type: 'secretKey', alias, createdMs: 0, certs: [] })\n truncatedNote =\n `含 JCEKS 密钥条目「${alias}」(Java 序列化对象,无法在浏览器内跳过其字节),` +\n '其后的条目未继续解析。'\n break\n } else {\n throw new JksError(`未知条目类型 tag=${tag}(第 ${i + 1} 项,偏移 ${p - 4})`)\n }\n }\n\n const n = bytes.length\n const hasDigest = n >= 20\n return {\n storeType,\n version,\n entries,\n macData: hasDigest ? bytes.slice(0, n - 20) : bytes.slice(),\n storedDigest: hasDigest ? bytes.slice(n - 20) : new Uint8Array(0),\n truncatedNote,\n }\n}\n\n/**\n * Verify the store-integrity MAC with a candidate password: SHA1(passwordUtf16BE ‖ \"Mighty Aphrodite\" ‖ body)\n * must equal the stored trailing digest. Also confirms the store password (keytool defaults it equal to each\n * key password). Returns false for an empty password or a store with no digest.\n */\nexport function verifyStorePassword(store: JksStore, password: string): boolean {\n if (!password || store.storedDigest.length !== DIGEST_LEN) return false\n const md = new Sha1()\n md.update(passwordToUtf16(password))\n md.update(MAC_SALT)\n md.update(store.macData)\n return bytesEqual(md.digest(), store.storedDigest)\n}\n\n/** Friendly description of a decrypted PKCS#8 private key. */\nexport interface KeyInfo {\n /** DER PKCS#8 PrivateKeyInfo (the decrypted plaintext). */\n pkcs8: Uint8Array\n algorithm: string\n bits?: number\n curve?: string\n}\n\nexport type KeyDecryptResult =\n | { ok: true; key: KeyInfo }\n | { ok: false; reason: 'wrong-password' | 'unsupported' | 'malformed'; detail?: string }\n\n/**\n * Decrypt a JKS private key (the DER EncryptedPrivateKeyInfo from {@link JksEntry.encryptedKey}) with Sun's\n * KeyProtector. The password is verified by the format's own trailing SHA-1 check digest, so a wrong password\n * yields `wrong-password` (never garbage). Non-JKS protection (e.g. JCEKS PBEWithMD5AndTripleDES) → `unsupported`.\n */\nexport function decryptPrivateKey(encryptedKey: Uint8Array, password: string): KeyDecryptResult {\n let algOid = ''\n let encrypted: Uint8Array | null = null\n try {\n // EncryptedPrivateKeyInfo ::= SEQUENCE { encryptionAlgorithm AlgorithmIdentifier, encryptedData OCTET STRING }\n const top = decodeAsn1(encryptedKey)[0]\n const algId = top?.children[0]\n const oidNode = algId?.children[0]\n algOid = oidNode ? oidToString(oidNode.content) : ''\n const octet = top?.children[1]\n if (octet) encrypted = octet.content\n } catch {\n return { ok: false, reason: 'malformed' }\n }\n if (!encrypted) return { ok: false, reason: 'malformed' }\n if (algOid !== KEY_PROTECTOR_OID) {\n return {\n ok: false,\n reason: 'unsupported',\n detail: algOid === JCEKS_PBE_OID ? 'PBEWithMD5AndTripleDES (JCEKS)' : algOid || '未知算法',\n }\n }\n if (encrypted.length < SALT_LEN + DIGEST_LEN) return { ok: false, reason: 'malformed' }\n\n const pwd = passwordToUtf16(password)\n const salt = encrypted.subarray(0, SALT_LEN)\n const encrKeyLen = encrypted.length - SALT_LEN - DIGEST_LEN\n const encrKey = encrypted.subarray(SALT_LEN, SALT_LEN + encrKeyLen)\n const check = encrypted.subarray(SALT_LEN + encrKeyLen)\n\n // Keystream: digest_0 = salt; digest_{i} = SHA1(password ‖ digest_{i-1}); concatenate 20 bytes per round.\n const xorKey = new Uint8Array(encrKeyLen)\n let digest = salt\n let off = 0\n const numRounds = Math.ceil(encrKeyLen / DIGEST_LEN)\n for (let i = 0; i < numRounds; i++) {\n const md = new Sha1()\n md.update(pwd)\n md.update(digest)\n digest = md.digest()\n xorKey.set(digest.subarray(0, Math.min(DIGEST_LEN, encrKeyLen - off)), off)\n off += DIGEST_LEN\n }\n const plain = new Uint8Array(encrKeyLen)\n for (let i = 0; i < encrKeyLen; i++) plain[i] = encrKey[i] ^ xorKey[i]\n\n // The format's integrity check IS the password check: SHA1(password ‖ plaintextKey) must match the trailer.\n const vmd = new Sha1()\n vmd.update(pwd)\n vmd.update(plain)\n if (!bytesEqual(vmd.digest(), check)) return { ok: false, reason: 'wrong-password' }\n\n return { ok: true, key: { pkcs8: plain, ...describePrivateKey(plain) } }\n}\n"],"mappings":"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"}
package/dist/lib/jsonl.js CHANGED
@@ -22,3 +22,5 @@ function e(e) {
22
22
  }
23
23
  //#endregion
24
24
  export { e as parseJsonl };
25
+
26
+ //# sourceMappingURL=jsonl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl.js","names":[],"sources":["../../src/lib/jsonl.ts"],"sourcesContent":["/**\n * JSON Lines / NDJSON (`.jsonl` / `.ndjson`) parser — one JSON value per physical line.\n *\n * Hand-rolled (no dependency, like the other in-browser parsers): split on newlines, skip blank lines, and\n * `JSON.parse` each remaining line independently. A line that isn't valid JSON is kept as an error record\n * (with its raw text) rather than aborting the whole file — JSONL is often produced incrementally / by logs,\n * so a single malformed line shouldn't blank the preview.\n *\n * Used by JsonlViewer (the side viewer's render mode): the record LIST shows a truncated one-line preview per\n * row, and a row expands to its pretty-printed value on demand — so a huge file stays responsive (the full\n * value of a record is only built when that row is opened).\n */\n\nexport interface JsonlRecord {\n /** 1-based physical line number in the file (blank lines are skipped, so numbers may have gaps). */\n line: number\n /** The raw line text (trailing CR stripped) — shown verbatim for error rows. */\n raw: string\n /** Parsed JSON value when the line is valid JSON; undefined when {@link error} is set. */\n value?: unknown\n /** Parse error message when the line isn't valid JSON. */\n error?: string\n}\n\nexport interface JsonlDoc {\n records: JsonlRecord[]\n /** How many records failed to parse (valid + invalid = records.length). */\n errorCount: number\n}\n\n/** Parse JSONL/NDJSON text into per-line records. Blank/whitespace-only lines are skipped (not recorded). */\nexport function parseJsonl(text: string): JsonlDoc {\n const records: JsonlRecord[] = []\n let errorCount = 0\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i].replace(/\\r$/, '')\n if (raw.trim() === '') continue\n const rec: JsonlRecord = { line: i + 1, raw }\n try {\n rec.value = JSON.parse(raw)\n } catch (e) {\n rec.error = e instanceof Error ? e.message : String(e)\n errorCount++\n }\n records.push(rec)\n }\n return { records, errorCount }\n}\n"],"mappings":";AA+BA,SAAgB,EAAW,GAAwB;CACjD,IAAM,IAAyB,CAAC,GAC5B,IAAa,GACX,IAAQ,EAAK,MAAM,IAAI;CAC7B,KAAK,IAAI,IAAI,GAAG,IAAI,EAAM,QAAQ,KAAK;EACrC,IAAM,IAAM,EAAM,EAAE,CAAC,QAAQ,OAAO,EAAE;EACtC,IAAI,EAAI,KAAK,MAAM,IAAI;EACvB,IAAM,IAAmB;GAAE,MAAM,IAAI;GAAG;EAAI;EAC5C,IAAI;GACF,EAAI,QAAQ,KAAK,MAAM,CAAG;EAC5B,SAAS,GAAG;GAEV,AADA,EAAI,QAAQ,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,GACrD;EACF;EACA,EAAQ,KAAK,CAAG;CAClB;CACA,OAAO;EAAE;EAAS;CAAW;AAC/B"}
package/dist/lib/lrc.js CHANGED
@@ -82,3 +82,5 @@ function i(e) {
82
82
  }
83
83
  //#endregion
84
84
  export { i as parseLrc };
85
+
86
+ //# sourceMappingURL=lrc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lrc.js","names":[],"sources":["../../src/lib/lrc.ts"],"sourcesContent":["/**\n * LRC 歌词解析(手写、零依赖)。\n *\n * LRC 是行式歌词格式:元信息标签 `[ti:标题] [ar:歌手] [al:专辑] [by:制作] [offset:毫秒]`,加上带时间戳的\n * 正文行 `[mm:ss.xx]歌词`。一行可带多个时间戳(`[t1][t2]同一句`),表示这句在多处重复出现。\n *\n * QQ 音乐导出的 .lrc 常见两个坑,这里都处理:\n * - 文本里混入 HTML 数字实体(如 `&#52572;` 表示某个 Unicode 码点),需要解码还原;\n * - 文件多为 **GBK** 编码(解码交由 {@link decodeTextSniff} 在读盘时完成,本模块只吃已解码的字符串)。\n *\n * 仅做解析,渲染在 LrcViewer.vue。无时间戳的纯文本歌词也能正常显示(hasTimings=false)。\n */\n\nexport interface LrcLine {\n /** 该行时间戳(毫秒),已叠加全局 offset;纯文本行为 null。 */\n timeMs: number | null\n text: string\n}\n\nexport interface ParsedLrc {\n tags: Record<string, string>\n title?: string\n artist?: string\n album?: string\n by?: string\n /** `[offset:n]` 毫秒(正值表示歌词提前),已并入每行 timeMs。 */\n offsetMs: number\n /** 按时间升序的歌词行(含解析出的纯文本行,timeMs=null 排在最前、保持原序)。 */\n lines: LrcLine[]\n /** 是否解析到任何带时间戳的行。 */\n hasTimings: boolean\n}\n\nconst NAMED_ENTITIES: Record<string, string> = {\n amp: '&',\n lt: '<',\n gt: '>',\n quot: '\"',\n apos: \"'\",\n nbsp: ' ',\n}\n\n/** 解码 HTML 实体:数字 `&#1234;` / 十六进制 `&#x4a;` / 常见命名实体。 */\nfunction decodeEntities(s: string): string {\n if (!s.includes('&')) return s\n return s.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z]+);/g, (m, body: string) => {\n if (body[0] === '#') {\n const code =\n body[1] === 'x' || body[1] === 'X'\n ? parseInt(body.slice(2), 16)\n : parseInt(body.slice(1), 10)\n if (Number.isFinite(code) && code >= 0 && code <= 0x10ffff) {\n try {\n return String.fromCodePoint(code)\n } catch {\n return m\n }\n }\n return m\n }\n return NAMED_ENTITIES[body.toLowerCase()] ?? m\n })\n}\n\n// 元信息标签里这些是「非时间」键。\nconst META_KEYS = new Set(['ti', 'ar', 'al', 'by', 'offset', 'length', 're', 've', 'au', 'la'])\n\n// 时间戳:[mm:ss]、[mm:ss.xx]、[mm:ss.xxx],分隔符 . 或 :。\nconst TIME_RE = /\\[(\\d{1,3}):(\\d{1,2})(?:[.:](\\d{1,3}))?\\]/g\n\n/** 解析 LRC 文本(已是正确编码的字符串)。 */\nexport function parseLrc(text: string): ParsedLrc {\n const tags: Record<string, string> = {}\n const timed: LrcLine[] = []\n const plain: LrcLine[] = []\n let offsetMs = 0\n\n for (const rawLine of text.split(/\\r\\n|\\r|\\n/)) {\n const line = rawLine\n // 先抽出行首的所有时间戳。\n TIME_RE.lastIndex = 0\n const stamps: number[] = []\n let lastEnd = 0\n let m: RegExpExecArray | null\n while ((m = TIME_RE.exec(line)) !== null) {\n // 仅接受连续位于行首/紧挨着的时间戳串(中间不夹其它字符)。\n if (m.index !== lastEnd) break\n const mm = parseInt(m[1], 10)\n const ss = parseInt(m[2], 10)\n const frac = m[3] ? m[3] : ''\n // 毫秒:两位当百分秒(*10),三位即毫秒,一位*100。\n let ms = 0\n if (frac.length === 1) ms = parseInt(frac, 10) * 100\n else if (frac.length === 2) ms = parseInt(frac, 10) * 10\n else if (frac.length >= 3) ms = parseInt(frac.slice(0, 3), 10)\n stamps.push(mm * 60000 + ss * 1000 + ms)\n lastEnd = m.index + m[0].length\n }\n\n if (stamps.length > 0) {\n const content = decodeEntities(line.slice(lastEnd).trim())\n for (const t of stamps) timed.push({ timeMs: t, text: content })\n continue\n }\n\n // 非时间戳行:可能是元信息标签 [key:value],或纯文本。\n const tag = /^\\[([a-zA-Z]+):(.*)\\]\\s*$/.exec(line.trim())\n if (tag && META_KEYS.has(tag[1].toLowerCase())) {\n const key = tag[1].toLowerCase()\n const val = decodeEntities(tag[2].trim())\n tags[key] = val\n if (key === 'offset') {\n const n = parseInt(val, 10)\n if (Number.isFinite(n)) offsetMs = n\n }\n continue\n }\n\n const txt = decodeEntities(line.trim())\n if (txt) plain.push({ timeMs: null, text: txt })\n }\n\n // offset 语义:正值表示歌词整体提前,故从时间里减去。\n if (offsetMs !== 0) for (const l of timed) if (l.timeMs != null) l.timeMs -= offsetMs\n\n timed.sort((a, b) => (a.timeMs ?? 0) - (b.timeMs ?? 0))\n\n const lines = timed.length > 0 ? timed : plain\n return {\n tags,\n title: tags.ti,\n artist: tags.ar,\n album: tags.al,\n by: tags.by,\n offsetMs,\n lines,\n hasTimings: timed.length > 0,\n }\n}\n"],"mappings":"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"}
package/dist/lib/lzma.js CHANGED
@@ -202,3 +202,5 @@ function E(e, t = 0) {
202
202
  }
203
203
  //#endregion
204
204
  export { E as bcjX86Decode, S as lzma2Decode, x as lzmaDecode };
205
+
206
+ //# sourceMappingURL=lzma.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lzma.js","names":[],"sources":["../../src/lib/lzma.ts"],"sourcesContent":["/**\n * Minimal in-browser LZMA / LZMA2 decoder — no dependency, no WASM.\n *\n * Browsers ship a native inflate (DecompressionStream) for ZIP's DEFLATE, but nothing for LZMA — the\n * codec 7z archives use. So unlike {@link lib/zip.ts}, the 7z reader ({@link lib/sevenZip.ts}) has to\n * carry its own decompressor. This is a straight port of Igor Pavlov's reference LZMA decoder (the one\n * in the LZMA SDK / the format spec): a range decoder, the bit-tree / length / distance sub-decoders,\n * and the literal/match main loop. It decodes into a caller-provided linear output buffer (the total\n * unpacked size is always known up front from the 7z folder metadata), which doubles as the LZ window.\n *\n * Three entry points, all synchronous (pure arithmetic, no async primitive needed):\n * - {@link lzmaDecode} raw LZMA1 stream (7z coder 03 01 01), 5-byte props.\n * - {@link lzma2Decode} LZMA2 chunk stream (7z coder 21), 1-byte props.\n * - {@link bcjX86Decode} the x86 BCJ branch filter's decode pass (7z coder 03 03 01 03).\n *\n * Encrypted / unusual coders are the 7z reader's concern; here we only fail (throw) on a malformed\n * stream or an unsupported LZMA2 control byte.\n */\n\nconst K_NUM_BIT_MODEL_TOTAL_BITS = 11\nconst K_BIT_MODEL_TOTAL = 1 << K_NUM_BIT_MODEL_TOTAL_BITS // 2048\nconst K_NUM_MOVE_BITS = 5\nconst PROB_INIT = K_BIT_MODEL_TOTAL >> 1 // 1024\nconst K_TOP_VALUE = 1 << 24\n\nconst K_NUM_POS_BITS_MAX = 4\nconst K_NUM_STATES = 12\nconst K_NUM_LEN_TO_POS_STATES = 4\nconst K_NUM_ALIGN_BITS = 4\nconst K_END_POS_MODEL_INDEX = 14\nconst K_NUM_FULL_DISTANCES = 1 << (K_END_POS_MODEL_INDEX >> 1) // 128\nconst K_MATCH_MIN_LEN = 2\n\n// Length-decoder array layout (one flat Uint16Array of 514 probs, reused for the match- and rep-length\n// coders): choice(1) + choice2(1) + low[16][8] + mid[16][8] + high[256].\nconst LEN_LOW = 2\nconst LEN_MID = LEN_LOW + (1 << K_NUM_POS_BITS_MAX) * 8 // 130\nconst LEN_HIGH = LEN_MID + (1 << K_NUM_POS_BITS_MAX) * 8 // 258\nconst LEN_SIZE = LEN_HIGH + 256 // 514\n\n/** A byte-at-a-time range decoder over a slice of the packed stream (reads past the end as zero). */\nclass RangeDecoder {\n private code = 0\n private range = 0xffffffff\n private pos: number\n constructor(\n private readonly buf: Uint8Array,\n start: number,\n ) {\n this.pos = start\n this.pos++ // first byte is always 0 (ignored)\n for (let i = 0; i < 4; i++) this.code = ((this.code << 8) | this.nextByte()) >>> 0\n }\n\n private nextByte(): number {\n return this.pos < this.buf.length ? this.buf[this.pos++] : (this.pos++, 0)\n }\n\n private normalize(): void {\n if (this.range >>> 0 < K_TOP_VALUE) {\n this.range = (this.range * 256) >>> 0\n this.code = (this.code * 256 + this.nextByte()) >>> 0\n }\n }\n\n /** Decode one bit under probability model `probs[i]`, adapting the model in place. */\n decodeBit(probs: Uint16Array, i: number): number {\n const prob = probs[i]\n const bound = (this.range >>> K_NUM_BIT_MODEL_TOTAL_BITS) * prob\n let symbol: number\n if (this.code >>> 0 < bound) {\n this.range = bound\n probs[i] = prob + ((K_BIT_MODEL_TOTAL - prob) >> K_NUM_MOVE_BITS)\n symbol = 0\n } else {\n this.range = (this.range - bound) >>> 0\n this.code = (this.code - bound) >>> 0\n probs[i] = prob - (prob >> K_NUM_MOVE_BITS)\n symbol = 1\n }\n this.normalize()\n return symbol\n }\n\n /** Decode `numBits` equiprobable bits (used for high distance bits). */\n decodeDirectBits(numBits: number): number {\n let result = 0\n do {\n this.range = this.range >>> 1\n this.code = (this.code - this.range) >>> 0\n const t = 0 - (this.code >>> 31) // 0 or -1\n this.code = (this.code + (this.range & t)) >>> 0\n this.normalize()\n result = result * 2 + (t + 1)\n } while (--numBits)\n return result\n }\n}\n\nfunction bitTreeDecode(\n rc: RangeDecoder,\n probs: Uint16Array,\n base: number,\n numBits: number,\n): number {\n let m = 1\n for (let i = 0; i < numBits; i++) m = (m << 1) + rc.decodeBit(probs, base + m)\n return m - (1 << numBits)\n}\n\nfunction bitTreeReverseDecode(\n rc: RangeDecoder,\n probs: Uint16Array,\n base: number,\n numBits: number,\n): number {\n let m = 1\n let sym = 0\n for (let i = 0; i < numBits; i++) {\n const bit = rc.decodeBit(probs, base + m)\n m = (m << 1) + bit\n sym |= bit << i\n }\n return sym\n}\n\nfunction decodeLen(rc: RangeDecoder, len: Uint16Array, posState: number): number {\n if (rc.decodeBit(len, 0) === 0) return bitTreeDecode(rc, len, LEN_LOW + posState * 8, 3)\n if (rc.decodeBit(len, 1) === 0) return 8 + bitTreeDecode(rc, len, LEN_MID + posState * 8, 3)\n return 16 + bitTreeDecode(rc, len, LEN_HIGH, 8)\n}\n\n/**\n * The LZMA decoder state. Holds the adaptive probability models, the `state` machine value and the four\n * recent match distances — all of which LZMA2 keeps alive (and selectively resets) across chunks, so this\n * is a reusable object rather than a one-shot function.\n */\nexport class LzmaState {\n lc = 0\n lp = 0\n pb = 0\n private literal = new Uint16Array(0)\n private readonly isMatch = new Uint16Array(K_NUM_STATES << K_NUM_POS_BITS_MAX)\n private readonly isRep = new Uint16Array(K_NUM_STATES)\n private readonly isRepG0 = new Uint16Array(K_NUM_STATES)\n private readonly isRepG1 = new Uint16Array(K_NUM_STATES)\n private readonly isRepG2 = new Uint16Array(K_NUM_STATES)\n private readonly isRep0Long = new Uint16Array(K_NUM_STATES << K_NUM_POS_BITS_MAX)\n private readonly posSlot = new Uint16Array(K_NUM_LEN_TO_POS_STATES << 6)\n private readonly specPos = new Uint16Array(K_NUM_FULL_DISTANCES - K_END_POS_MODEL_INDEX)\n private readonly align = new Uint16Array(1 << K_NUM_ALIGN_BITS)\n private readonly lenCoder = new Uint16Array(LEN_SIZE)\n private readonly repLenCoder = new Uint16Array(LEN_SIZE)\n\n state = 0\n rep0 = 0\n rep1 = 0\n rep2 = 0\n rep3 = 0\n\n /** Apply the lc/lp/pb properties byte (0..224) and size the literal table accordingly. */\n setProps(d: number): void {\n if (d >= 9 * 5 * 5) throw new Error('LZMA 属性非法')\n this.lc = d % 9\n d = (d / 9) | 0\n this.lp = d % 5\n this.pb = (d / 5) | 0\n const litSize = 0x300 << (this.lc + this.lp)\n if (this.literal.length !== litSize) this.literal = new Uint16Array(litSize)\n }\n\n /** Reset all probability models and the state machine (a \"reset state\" in LZMA2 terms). */\n resetState(): void {\n this.literal.fill(PROB_INIT)\n this.isMatch.fill(PROB_INIT)\n this.isRep.fill(PROB_INIT)\n this.isRepG0.fill(PROB_INIT)\n this.isRepG1.fill(PROB_INIT)\n this.isRepG2.fill(PROB_INIT)\n this.isRep0Long.fill(PROB_INIT)\n this.posSlot.fill(PROB_INIT)\n this.specPos.fill(PROB_INIT)\n this.align.fill(PROB_INIT)\n this.lenCoder.fill(PROB_INIT)\n this.repLenCoder.fill(PROB_INIT)\n this.state = 0\n this.rep0 = this.rep1 = this.rep2 = this.rep3 = 0\n }\n\n /**\n * Decode bytes into `out[outPos .. limit)` using `input` as the range-coded source. `dictStart` is the\n * output offset of the current dictionary's start (for LZMA1 it's `outPos`; for LZMA2 it moves on a dict\n * reset) — it anchors the position counter that drives posState and bounds back-references. Returns the\n * new output position (== limit on success).\n */\n decode(\n input: Uint8Array,\n inStart: number,\n out: Uint8Array,\n outPos: number,\n limit: number,\n dictStart: number,\n ): number {\n const rc = new RangeDecoder(input, inStart)\n const posMask = (1 << this.pb) - 1\n const litPosMask = (1 << this.lp) - 1\n const lc = this.lc\n let { state, rep0, rep1, rep2, rep3 } = this\n\n while (outPos < limit) {\n const processedPos = outPos - dictStart\n const posState = processedPos & posMask\n if (rc.decodeBit(this.isMatch, (state << K_NUM_POS_BITS_MAX) + posState) === 0) {\n // ── literal ──\n const prevByte = outPos > dictStart ? out[outPos - 1] : 0\n const litState = ((processedPos & litPosMask) << lc) + (prevByte >> (8 - lc))\n const probBase = 0x300 * litState\n let symbol = 1\n if (state >= 7) {\n let matchByte = out[outPos - rep0 - 1]\n do {\n const matchBit = (matchByte >> 7) & 1\n matchByte = (matchByte << 1) & 0xff\n const bit = rc.decodeBit(this.literal, probBase + ((1 + matchBit) << 8) + symbol)\n symbol = (symbol << 1) | bit\n if (matchBit !== bit) break\n } while (symbol < 0x100)\n }\n while (symbol < 0x100)\n symbol = (symbol << 1) | rc.decodeBit(this.literal, probBase + symbol)\n out[outPos++] = symbol & 0xff\n state = state < 4 ? 0 : state < 10 ? state - 3 : state - 6\n continue\n }\n\n // ── match ──\n let len: number\n if (rc.decodeBit(this.isRep, state) !== 0) {\n // rep match\n if (rc.decodeBit(this.isRepG0, state) === 0) {\n if (rc.decodeBit(this.isRep0Long, (state << K_NUM_POS_BITS_MAX) + posState) === 0) {\n // short rep: copy one byte at distance rep0\n state = state < 7 ? 9 : 11\n out[outPos] = out[outPos - rep0 - 1]\n outPos++\n continue\n }\n } else {\n let dist: number\n if (rc.decodeBit(this.isRepG1, state) === 0) {\n dist = rep1\n } else {\n if (rc.decodeBit(this.isRepG2, state) === 0) {\n dist = rep2\n } else {\n dist = rep3\n rep3 = rep2\n }\n rep2 = rep1\n }\n rep1 = rep0\n rep0 = dist\n }\n len = decodeLen(rc, this.repLenCoder, posState)\n state = state < 7 ? 8 : 11\n } else {\n // new match: shift the recent-distance history and decode a fresh distance\n rep3 = rep2\n rep2 = rep1\n rep1 = rep0\n len = decodeLen(rc, this.lenCoder, posState)\n state = state < 7 ? 7 : 10\n const lenToPosState = len < K_NUM_LEN_TO_POS_STATES ? len : K_NUM_LEN_TO_POS_STATES - 1\n const posSlot = bitTreeDecode(rc, this.posSlot, lenToPosState << 6, 6)\n if (posSlot < 4) {\n rep0 = posSlot\n } else {\n const numDirectBits = (posSlot >> 1) - 1\n rep0 = (2 | (posSlot & 1)) << numDirectBits\n if (posSlot < K_END_POS_MODEL_INDEX) {\n rep0 += bitTreeReverseDecode(rc, this.specPos, rep0 - posSlot - 1, numDirectBits)\n } else {\n rep0 += rc.decodeDirectBits(numDirectBits - K_NUM_ALIGN_BITS) * (1 << K_NUM_ALIGN_BITS)\n rep0 += bitTreeReverseDecode(rc, this.align, 0, K_NUM_ALIGN_BITS)\n if (rep0 >>> 0 === 0xffffffff) break // end-of-stream marker\n }\n }\n }\n\n // copy `len + K_MATCH_MIN_LEN` bytes from distance rep0\n len += K_MATCH_MIN_LEN\n let src = outPos - rep0 - 1\n for (let i = 0; i < len && outPos < limit; i++) out[outPos++] = out[src++]\n }\n\n this.state = state\n this.rep0 = rep0\n this.rep1 = rep1\n this.rep2 = rep2\n this.rep3 = rep3\n return outPos\n }\n}\n\n/**\n * Decode a raw LZMA1 stream (7z coder 03 01 01). `props` is the 5-byte property block (lc/lp/pb byte +\n * little-endian dict size, which we ignore — the linear output buffer is the window). Decodes exactly\n * `outSize` bytes.\n */\nexport function lzmaDecode(input: Uint8Array, props: Uint8Array, outSize: number): Uint8Array {\n if (props.length < 5) throw new Error('LZMA 属性长度不足')\n const st = new LzmaState()\n st.setProps(props[0])\n st.resetState()\n const out = new Uint8Array(outSize)\n st.decode(input, 0, out, 0, outSize, 0)\n return out\n}\n\n/**\n * Decode an LZMA2 stream (7z coder 21). LZMA2 frames a sequence of chunks — each either an uncompressed\n * block or an independently range-coded LZMA block — over a shared, selectively-reset dictionary and\n * decoder state. `props` (1 byte, dict-size code) is unused here. Decodes exactly `outSize` bytes.\n */\nexport function lzma2Decode(input: Uint8Array, _props: Uint8Array, outSize: number): Uint8Array {\n const out = new Uint8Array(outSize)\n const st = new LzmaState()\n let ip = 0\n let pos = 0\n let dictStart = 0\n let needProps = true\n\n while (ip < input.length) {\n const control = input[ip++]\n if (control === 0) break // end of LZMA2 stream\n\n if (control >= 0x80) {\n // LZMA chunk\n const unpackSize = ((control & 0x1f) << 16) + (input[ip] << 8) + input[ip + 1] + 1\n ip += 2\n const packSize = (input[ip] << 8) + input[ip + 1] + 1\n ip += 2\n const reset = (control >> 5) & 3 // 0 none · 1 state · 2 state+props · 3 state+props+dict\n if (reset >= 2) {\n st.setProps(input[ip++])\n needProps = false\n } else if (needProps) {\n throw new Error('LZMA2 缺少属性的块')\n }\n // reset ≥ 1 resets the adaptive state; reset 0 deliberately CONTINUES it from the previous chunk —\n // valid LZMA2, e.g. an LZMA chunk right after an uncompressed chunk that kept the dictionary. Don't\n // force a reset here: 7-Zip / xz only require a state reset after a *dictionary* reset (which is\n // gated below by needProps, since a dict reset re-sends props via a reset-2/3 chunk).\n if (reset >= 1) st.resetState()\n if (reset === 3) dictStart = pos\n st.decode(input, ip, out, pos, pos + unpackSize, dictStart)\n ip += packSize\n pos += unpackSize\n } else {\n // uncompressed chunk: 1 = reset dict, 2 = keep dict\n if (control > 2) throw new Error(`LZMA2 非法控制字节 0x${control.toString(16)}`)\n const size = (input[ip] << 8) + input[ip + 1] + 1\n ip += 2\n if (control === 1) {\n dictStart = pos\n needProps = true // a dict reset starts fresh → the next LZMA chunk must re-send props (reset 2/3)\n }\n out.set(input.subarray(ip, ip + size), pos)\n ip += size\n pos += size\n }\n if (pos >= outSize) break\n }\n return out\n}\n\n// The x86 BCJ filter rewrites the operands of E8/E9 (CALL/JMP rel32) instructions from absolute back to\n// relative form. Decode tables and algorithm follow the reference (xz / 7-Zip `x86_code`, encoding=false).\nconst MASK_TO_ALLOWED: ReadonlyArray<boolean> = [true, true, true, false, true, false, false, false]\nconst MASK_TO_BIT: ReadonlyArray<number> = [0, 1, 2, 2, 3, 3, 3, 3]\nconst test86 = (b: number): boolean => b === 0x00 || b === 0xff\n\n/** Apply the x86 BCJ decode pass in place (7z coder 03 03 01 03), with `ip` the stream start address (0). */\nexport function bcjX86Decode(data: Uint8Array, ip = 0): void {\n const size = data.length\n if (size < 5) return\n const limit = size - 5\n let prevMask = 0\n let prevPos = -1\n let i = 0\n while (i <= limit) {\n if ((data[i] & 0xfe) !== 0xe8) {\n i++\n continue\n }\n const off = i - prevPos\n prevPos = i\n if (off > 3) {\n prevMask = 0\n } else {\n prevMask = (prevMask << (off - 1)) & 7\n if (prevMask !== 0) {\n const b = data[i + 4 - MASK_TO_BIT[prevMask]]\n if (!MASK_TO_ALLOWED[prevMask] || test86(b)) {\n prevMask = ((prevMask << 1) & 7) | 1\n i++\n continue\n }\n }\n }\n if (test86(data[i + 4])) {\n let src = (data[i + 1] | (data[i + 2] << 8) | (data[i + 3] << 16) | (data[i + 4] << 24)) >>> 0\n let dest = 0\n for (;;) {\n dest = (src - (ip + i + 5)) >>> 0\n if (prevMask === 0) break\n const idx = MASK_TO_BIT[prevMask] * 8\n const b = (dest >>> (24 - idx)) & 0xff\n if (!test86(b)) break\n src = (dest ^ ((1 << (32 - idx)) - 1)) >>> 0\n }\n data[i + 4] = ~(((dest >>> 24) & 1) - 1) & 0xff\n data[i + 3] = (dest >>> 16) & 0xff\n data[i + 2] = (dest >>> 8) & 0xff\n data[i + 1] = dest & 0xff\n i += 5\n prevMask = 0\n } else {\n prevMask = ((prevMask << 1) & 7) | 1\n i++\n }\n }\n}\n"],"mappings":"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"}
@@ -219,3 +219,5 @@ function h(e, t) {
219
219
  }
220
220
  //#endregion
221
221
  export { h as md, m as mdNodes };
222
+
223
+ //# sourceMappingURL=blocks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blocks.js","names":[],"sources":["../../../src/lib/markdown/blocks.ts"],"sourcesContent":["import { h, type VNode } from 'vue'\nimport CodeBlock from '@/components/CodeBlock.vue'\nimport MarkdownTable from '@/components/MarkdownTable.vue'\nimport { inline } from './inline'\nimport { blockMath } from './math'\nimport {\n blockquoteStyle,\n headingStyle,\n hrStyle,\n listItemStyle,\n listStyle,\n paragraphStyle,\n taskCheckboxStyle,\n} from './styles'\n\n/** Convenience: render a fenced code block VNode. */\nfunction codeBlock(\n code: string,\n lang: string,\n key: string,\n opts?: { maxHeight?: string; margin?: string },\n): VNode {\n return h(CodeBlock, { key, code, lang, maxHeight: opts?.maxHeight, margin: opts?.margin })\n}\n\n/** Convenience: render a GFM table VNode. */\nfunction tableBlock(\n header: string[],\n aligns: (string | null)[],\n rows: string[][],\n key: string,\n): VNode {\n return h(MarkdownTable, { key, header, aligns, rows, keyPrefix: key })\n}\n\n/**\n * Block-level markdown → VNodes. Handles fenced code, ATX headings (## / ###),\n * GFM pipe tables, ordered/unordered lists (with nesting + fenced code inside\n * items), and paragraphs with hard line breaks. Faithful port of `mdNodes`.\n */\nexport function mdNodes(text: string, kp: string, depth: number): VNode[] {\n const lines = String(text).replace(/\\t/g, ' ').split('\\n')\n const out: VNode[] = []\n const pStyle = paragraphStyle(depth)\n let i = 0\n let bk = 0\n\n const indOf = (l: string) => l.match(/^(\\s*)/)![1].length\n\n // A thematic break: a whole line of 3+ of the same -, *, or _ (spaces allowed between).\n const isHr = (l: string) => /^ {0,3}([-*_])(?:[ \\t]*\\1){2,}[ \\t]*$/.test(l)\n\n // A GFM table delimiter row: contains a pipe and every cell is :?-+:?\n const isTableSep = (l: string): boolean => {\n if (l.indexOf('|') === -1) return false\n let s = l.trim()\n if (s.charAt(0) === '|') s = s.slice(1)\n if (s.charAt(s.length - 1) === '|') s = s.slice(0, -1)\n const cells = s.split('|')\n return cells.length > 0 && cells.every((c) => /^\\s*:?-+:?\\s*$/.test(c))\n }\n\n // Split one table row into trimmed cells, honoring `\\|` escapes and edge pipes.\n const splitRow = (l: string): string[] => {\n let s = l.trim()\n if (s.charAt(0) === '|') s = s.slice(1)\n if (s.charAt(s.length - 1) === '|') s = s.slice(0, -1)\n const cells: string[] = []\n let cur = ''\n for (let ci = 0; ci < s.length; ci++) {\n const ch = s.charAt(ci)\n if (ch === '\\\\' && s.charAt(ci + 1) === '|') {\n cur += '|'\n ci++\n continue\n }\n if (ch === '|') {\n cells.push(cur.trim())\n cur = ''\n continue\n }\n cur += ch\n }\n cells.push(cur.trim())\n return cells\n }\n\n while (i < lines.length) {\n const line = lines[i]\n if (line.trim() === '') {\n i++\n continue\n }\n const key = `${kp}-${bk++}`\n\n // fenced code (allowed at any indent — used inside list items)\n const fence = line.match(/^(\\s*)```+\\s*([^`]*)$/)\n if (fence) {\n const pad = fence[1].length\n const lang = fence[2]\n const body: string[] = []\n i++\n while (i < lines.length && !/^\\s*```+\\s*$/.test(lines[i])) {\n body.push(lines[i].slice(pad))\n i++\n }\n i++ // consume closing fence\n out.push(codeBlock(body.join('\\n'), lang, key))\n continue\n }\n\n // display math: `$$ … $$` or `\\[ … \\]` on its own line (may span multiple lines). Hand the TeX\n // to KaTeX (blockMath) — the hand-rolled engine doesn't typeset math. Detected here so the `$`/`\\`\n // internals never reach the paragraph/inline rules that would mangle them.\n const dmOpen = line.match(/^\\s*(\\$\\$|\\\\\\[)/)\n if (dmOpen) {\n const open = dmOpen[1]\n const close = open === '$$' ? '$$' : '\\\\]'\n const head = line.slice(line.indexOf(open) + open.length)\n const sameLineEnd = head.indexOf(close)\n let tex: string\n if (sameLineEnd !== -1) {\n tex = head.slice(0, sameLineEnd) // single line: $$ … $$\n i++\n } else {\n const buf = [head]\n i++\n while (i < lines.length) {\n const end = lines[i].indexOf(close)\n if (end !== -1) {\n buf.push(lines[i].slice(0, end))\n i++\n break\n }\n buf.push(lines[i])\n i++\n }\n tex = buf.join('\\n')\n }\n out.push(blockMath(tex.trim(), key))\n continue\n }\n\n // thematic break (--- / *** / ___) — before lists, since `* * *` looks like a bullet\n if (isHr(line)) {\n out.push(h('hr', { key, style: hrStyle }))\n i++\n continue\n }\n\n // blockquote (> …): gather the quoted lines, strip one `>` level, recurse (supports nesting)\n if (/^\\s*>/.test(line)) {\n const buf: string[] = []\n while (i < lines.length) {\n if (/^\\s*>/.test(lines[i])) {\n buf.push(lines[i].replace(/^\\s*>\\s?/, ''))\n i++\n } else if (lines[i].trim() === '') {\n // a blank line continues the quote only if another `>` line follows\n let j = i + 1\n while (j < lines.length && lines[j].trim() === '') j++\n if (j < lines.length && /^\\s*>/.test(lines[j])) {\n buf.push('')\n i = j\n continue\n }\n break\n } else break\n }\n out.push(\n h('blockquote', { key, style: blockquoteStyle }, mdNodes(buf.join('\\n'), key, depth)),\n )\n continue\n }\n\n // heading (# … ######)\n const hd = line.match(/^(#{1,6})\\s+(.*)$/)\n if (hd) {\n const lvl = hd[1].length\n const st = headingStyle(lvl, out.length === 0)\n out.push(h(`h${lvl}`, { key, style: st }, inline(hd[2], key)))\n i++\n continue\n }\n\n // table (GFM pipe table): header row immediately followed by a delimiter row\n if (line.indexOf('|') !== -1 && i + 1 < lines.length && isTableSep(lines[i + 1])) {\n const header = splitRow(line)\n const aligns = splitRow(lines[i + 1]).map((c) => {\n const L = c.charAt(0) === ':'\n const R = c.charAt(c.length - 1) === ':'\n return L && R ? 'center' : R ? 'right' : L ? 'left' : null\n })\n i += 2\n const rows: string[][] = []\n while (i < lines.length) {\n const r = lines[i]\n if (r.trim() === '' || r.indexOf('|') === -1 || /^\\s*```+/.test(r) || /^#{1,6}\\s/.test(r))\n break\n rows.push(splitRow(r))\n i++\n }\n out.push(tableBlock(header, aligns, rows, key))\n continue\n }\n\n // ordered / unordered list\n const om = line.match(/^(\\s*)(\\d+)\\.\\s+/)\n const um = line.match(/^(\\s*)([-*+•])\\s+/)\n if (om || um) {\n const ordered = !!om\n const baseIndent = (om || um)![1].length\n const markerRe = ordered ? /^(\\s*)(\\d+)\\.\\s+([\\s\\S]*)$/ : /^(\\s*)([-*+•])\\s+([\\s\\S]*)$/\n const items: string[][] = []\n let startNum: number | null = null\n while (i < lines.length) {\n const mm = lines[i].match(markerRe)\n // `* * *` / `- - -` match the bullet shape but are thematic breaks — let them end the list.\n if (mm && mm[1].length === baseIndent && !isHr(lines[i])) {\n if (ordered && startNum === null) startNum = parseInt(mm[2], 10)\n const itemLines = [mm[3]]\n i++\n while (i < lines.length) {\n if (lines[i].trim() === '') {\n itemLines.push('')\n i++\n continue\n }\n const ind = indOf(lines[i])\n const sm = lines[i].match(markerRe)\n if (ind > baseIndent && !(sm && sm[1].length === baseIndent)) {\n itemLines.push(lines[i])\n i++\n } else break\n }\n items.push(itemLines)\n } else if (lines[i].trim() === '') {\n // blank line: continue list only if a same-level item or indented child follows\n let j = i + 1\n while (j < lines.length && lines[j].trim() === '') j++\n if (j < lines.length) {\n const pk = lines[j].match(markerRe)\n if (\n (pk && pk[1].length === baseIndent && !isHr(lines[j])) ||\n indOf(lines[j]) > baseIndent\n ) {\n i = j\n continue\n }\n }\n break\n } else break\n }\n const lStyle = listStyle(depth, ordered)\n const liStyle = listItemStyle(depth)\n const children = items.map((raw, idx) => {\n let minInd = Infinity\n raw.slice(1).forEach((l) => {\n if (l.trim() !== '') minInd = Math.min(minInd, indOf(l))\n })\n if (!isFinite(minInd)) minInd = 0\n const dedented = [raw[0]].concat(\n raw.slice(1).map((l) => (l.trim() === '' ? '' : l.slice(minInd))),\n )\n const content = dedented.join('\\n').replace(/\\n+$/, '')\n // GFM task item: a leading `[ ]` / `[x]` turns the bullet into a checkbox\n const task = ordered ? null : /^\\[([ xX])\\]\\s+/.exec(content)\n const checked = !!task && task[1].toLowerCase() === 'x'\n const body = task ? content.slice(task[0].length) : content\n const innerNodes = mdNodes(body, `${key}-i${idx}`, depth + 1)\n // unwrap a lone paragraph so list markers hug their text\n const onlyP = innerNodes.length === 1 && innerNodes[0] && innerNodes[0].type === 'p'\n if (task) {\n const box = h(\n 'span',\n { key: 'cb', style: taskCheckboxStyle(checked), 'aria-hidden': 'true' },\n checked ? '✓' : '',\n )\n const inner = onlyP\n ? [box, ...((innerNodes[0].children as VNode[]) || [])]\n : [box, ...innerNodes]\n return h('li', { key: idx, style: { ...liStyle, listStyleType: 'none' } }, inner)\n }\n const kids = onlyP\n ? h(\n 'span',\n {\n style: {\n display: 'block',\n fontFamily: liStyle.fontFamily,\n fontSize: liStyle.fontSize,\n lineHeight: 1.72,\n },\n },\n innerNodes[0].children as VNode[],\n )\n : innerNodes\n return h('li', { key: idx, style: liStyle }, kids)\n })\n const olAttr = ordered && startNum && startNum !== 1 ? { start: startNum } : {}\n out.push(h(ordered ? 'ol' : 'ul', { key, style: lStyle, ...olAttr }, children))\n continue\n }\n\n // paragraph: gather until a blank line or a block-starting line\n const para = [line]\n i++\n while (i < lines.length) {\n const l = lines[i]\n if (l.trim() === '') break\n if (\n /^\\s*```+/.test(l) ||\n /^\\s*(\\$\\$|\\\\\\[)/.test(l) ||\n /^#{1,6}\\s/.test(l) ||\n /^\\s*>/.test(l) ||\n isHr(l) ||\n /^\\s*\\d+\\.\\s+/.test(l) ||\n /^\\s*[-*+•]\\s+/.test(l)\n )\n break\n if (l.indexOf('|') !== -1 && i + 1 < lines.length && isTableSep(lines[i + 1])) break\n para.push(l)\n i++\n }\n const nodes: (VNode | string)[] = []\n para.forEach((l, li) => {\n if (li > 0) nodes.push(h('br', { key: `br${li}` }))\n inline(l, `${key}-l${li}`).forEach((n) => nodes.push(n))\n })\n out.push(h('p', { key, style: pStyle }, nodes))\n }\n return out\n}\n\n/** Top-level markdown entry (depth 0). */\nexport function md(text: string, kp: string): VNode[] {\n return mdNodes(text, kp, 0)\n}\n"],"mappings":"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"}
@@ -82,3 +82,5 @@ function p(d, p) {
82
82
  }
83
83
  //#endregion
84
84
  export { p as inline, d as renderInline };
85
+
86
+ //# sourceMappingURL=inline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline.js","names":[],"sources":["../../../src/lib/markdown/inline.ts"],"sourcesContent":["import { h, type VNode } from 'vue'\nimport { useLightbox } from '@/composables/useLightbox'\nimport { inlineMath } from './math'\nimport { delStyle, emStyle, imgStyle, inlineCodeStyle, linkStyle, strongStyle } from './styles'\n\nexport type InlineNode = VNode | string\n\n/**\n * Resolve an inline citation token to its rendered chip(s), or null to strip it. Provider-specific (ChatGPT\n * supplies one via {@link renderInline}); the shared renderer just calls it for citation tokens it finds.\n */\nexport type CiteResolver = (token: string) => InlineNode[] | null\n\n/**\n * Resolve a markdown link to custom inline nodes, or null to render a normal anchor. Lets a provider turn\n * specific links into rich nodes — ChatGPT renders managed file-download links as file chips (preview/download)\n * via {@link renderInline}; everything else falls through to a plain `<a>`.\n */\nexport type LinkResolver = (text: string, href: string) => InlineNode[] | null\n\n// Active during a synchronous render pass only — set by renderInline around a (synchronous) md()/inline() call,\n// restored after. No await happens between set and restore, so this is safe under SSR (single-threaded, no\n// interleaving). Both default to null (Claude installs neither): citation tokens are then stripped and links\n// render as plain anchors.\nlet activeCite: CiteResolver | null = null\nlet activeLink: LinkResolver | null = null\n\n/** Inline resolvers a provider can install for one render pass. */\nexport interface InlineResolvers {\n cite?: CiteResolver\n link?: LinkResolver\n}\n\n/** Run [body] with the given inline [resolvers] active, restoring the previous ones afterwards. */\nexport function renderInline<T>(resolvers: InlineResolvers, body: () => T): T {\n const prevCite = activeCite\n const prevLink = activeLink\n activeCite = resolvers.cite ?? null\n activeLink = resolvers.link ?? null\n try {\n return body()\n } finally {\n activeCite = prevCite\n activeLink = prevLink\n }\n}\n\n// ChatGPT wraps inline-citation tokens in Private Use Area delimiters (U+E200…U+E201, separator U+E202) and uses\n// other PUA marks (e.g. U+E203 for hidden refs). Strip any stray ones from plain text so no garbage leaks through.\nconst PUA_RE = /[\\u{e200}-\\u{e20f}]/gu\n\n/**\n * Render inline markdown to an array of VNodes/strings.\n * Order matters: code first (nothing is parsed inside it), then math (`$…$` / `\\(…\\)`, pulled out\n * before emphasis so TeX internals like `_` `*` `\\` aren't mangled), image before link\n * (`![…](…)` contains `[…](…)`), bold (`**`/`__`) before italic (`*`/`_`).\n * Groups: 1 code, 2 math-`$`, 3 math-`\\(`, 4 img-alt, 5 img-url, 6 bold, 7 underscore-bold,\n * 8 strike, 9 link-text, 10 link-url, 11 italic, 12 underscore-italic, 13 citation (PUA-delimited),\n * 14 citation (`【n†…】`). The opening `$` is guarded against a following space/`$` and the closing\n * against a following word char, so prose prices like `$5` don't trigger math. Underscore emphasis is\n * guarded by alnum boundaries so `snake_case` stays intact.\n * Citation tokens resolve via the active {@link CiteResolver} (or are stripped when none is set).\n */\nexport function inline(s: string, kp: string): InlineNode[] {\n const parts: InlineNode[] = []\n // Push a plain-text run, stripping any stray citation PUA marks; skip if nothing is left.\n const pushText = (t: string): void => {\n const c = t.replace(PUA_RE, '')\n if (c) parts.push(c)\n }\n // Fresh regex per call so lastIndex never leaks between invocations.\n const re =\n /`([^`\\n]+?)`|\\$(?![ \\t$])((?:\\\\.|[^$\\n\\\\])+?)\\$(?![\\w$])|\\\\\\(([\\s\\S]+?)\\\\\\)|!\\[([^\\]\\n]*?)\\]\\(([^)\\s]+?)\\)|\\*\\*([\\s\\S]+?)\\*\\*|__([^_]+?)__|~~([\\s\\S]+?)~~|\\[([^\\]\\n]+?)\\]\\(([^)\\s]+?)\\)|\\*([^\\s*][^*]*?)\\*|(?<![A-Za-z0-9_])_([^_]+?)_(?![A-Za-z0-9_])|(\\u{e200}[\\s\\S]*?\\u{e201})|(【[^】\\n]*?†[^】\\n]*?】)/gu\n let last = 0\n let m: RegExpExecArray | null\n let k = 0\n while ((m = re.exec(s))) {\n if (m.index > last) pushText(s.slice(last, m.index))\n if (m[1] !== undefined) {\n parts.push(h('code', { key: `${kp}-c${k++}`, style: inlineCodeStyle }, m[1]))\n } else if (m[2] !== undefined) {\n parts.push(inlineMath(m[2], `${kp}-m${k++}`))\n } else if (m[3] !== undefined) {\n parts.push(inlineMath(m[3], `${kp}-m${k++}`))\n } else if (m[4] !== undefined) {\n const src = m[5]\n const alt = m[4]\n parts.push(\n h('img', {\n key: `${kp}-img${k++}`,\n src,\n alt,\n loading: 'lazy',\n style: { ...imgStyle, cursor: 'zoom-in' },\n // Click any inline image to enlarge it in the shared lightbox (same overlay as image thumbnails).\n onClick: () => useLightbox().open({ src, alt }),\n }),\n )\n } else if (m[6] !== undefined) {\n parts.push(h('strong', { key: `${kp}-s${k++}`, style: strongStyle }, m[6]))\n } else if (m[7] !== undefined) {\n parts.push(h('strong', { key: `${kp}-s${k++}`, style: strongStyle }, m[7]))\n } else if (m[8] !== undefined) {\n parts.push(h('del', { key: `${kp}-d${k++}`, style: delStyle }, m[8]))\n } else if (m[9] !== undefined) {\n const href = m[10] ?? ''\n const custom = activeLink ? activeLink(m[9], href) : null\n if (custom) {\n for (const n of custom) parts.push(n)\n } else {\n parts.push(\n h(\n 'a',\n {\n key: `${kp}-a${k++}`,\n href,\n target: '_blank',\n rel: 'noopener noreferrer',\n style: linkStyle,\n },\n m[9],\n ),\n )\n }\n } else if (m[11] !== undefined) {\n parts.push(h('em', { key: `${kp}-e${k++}`, style: emStyle }, m[11]))\n } else if (m[12] !== undefined) {\n parts.push(h('em', { key: `${kp}-e${k++}`, style: emStyle }, m[12]))\n } else {\n // citation token (m[13] PUA-delimited, or m[14] 【n†…】) — render via the active resolver, else strip\n const token = m[13] ?? m[14] ?? ''\n const rendered = activeCite ? activeCite(token) : null\n if (rendered) for (const n of rendered) parts.push(n)\n }\n last = re.lastIndex\n }\n if (last < s.length) pushText(s.slice(last))\n return parts\n}\n"],"mappings":"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"}
@@ -23,3 +23,5 @@ function i(t, r) {
23
23
  }
24
24
  //#endregion
25
25
  export { i as blockMath, r as inlineMath };
26
+
27
+ //# sourceMappingURL=math.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"math.js","names":[],"sources":["../../../src/lib/markdown/math.ts"],"sourcesContent":["import katex from 'katex'\nimport { h, type VNode } from 'vue'\n\n/**\n * TeX math → VNode, rendered by KaTeX. The hand-rolled markdown engine deliberately doesn't\n * typeset math (that's a full TeX layout problem, a different league from markdown) — so this is\n * the one place it delegates to a library, exactly like `highlight.js` for code.\n *\n * Why KaTeX fits this codebase:\n * - `renderToString` is *synchronous*, so it slots into the existing synchronous VNode pipeline\n * and the SSR smoke (`pnpm smoke`) with no async plumbing.\n * - It ships its own woff2 math fonts, bundled and self-hosted (no CDN) — see the css imports in\n * `main.ts` (`katex/dist/katex.min.css`) and the overrides in `assets/styles/katex.css`.\n * - `throwOnError: false` makes an invalid formula render as red source text instead of throwing\n * and blanking the message.\n *\n * The HTML KaTeX emits is its own trusted output, so feeding it through `innerHTML` is safe (same\n * pattern as WidgetBlock's static SVG). Never pass raw user text here — only KaTeX's result.\n */\nfunction render(tex: string, displayMode: boolean): string {\n return katex.renderToString(tex, { displayMode, throwOnError: false })\n}\n\n/** Inline formula (`$…$` / `\\(…\\)`) — flows within the surrounding line. */\nexport function inlineMath(tex: string, key: string): VNode {\n return h('span', { key, class: 'math-inline', innerHTML: render(tex, false) })\n}\n\n/** Display formula (`$$…$$` / `\\[…\\]`) — its own centered block, scrolls sideways if too wide. */\nexport function blockMath(tex: string, key: string): VNode {\n return h('div', { key, class: 'math-block', innerHTML: render(tex, true) })\n}\n"],"mappings":";;;AAmBA,SAAS,EAAO,GAAa,GAA8B;CACzD,OAAO,EAAM,eAAe,GAAK;EAAE;EAAa,cAAc;CAAM,CAAC;AACvE;AAGA,SAAgB,EAAW,GAAa,GAAoB;CAC1D,OAAO,EAAE,QAAQ;EAAE;EAAK,OAAO;EAAe,WAAW,EAAO,GAAK,EAAK;CAAE,CAAC;AAC/E;AAGA,SAAgB,EAAU,GAAa,GAAoB;CACzD,OAAO,EAAE,OAAO;EAAE;EAAK,OAAO;EAAc,WAAW,EAAO,GAAK,EAAI;CAAE,CAAC;AAC5E"}
@@ -26,3 +26,5 @@ function e(e) {
26
26
  }
27
27
  //#endregion
28
28
  export { e as segmentize };
29
+
30
+ //# sourceMappingURL=segmentize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segmentize.js","names":[],"sources":["../../../src/lib/markdown/segmentize.ts"],"sourcesContent":["export interface Segment {\n code: boolean\n text: string\n lang?: string\n}\n\n/**\n * Split markdown into ordered segments of prose and fenced code blocks.\n * Blank lines inside fences are preserved; blank lines around prose are trimmed.\n * Faithful port of the original `segmentize` (used for human messages).\n */\nexport function segmentize(text: string): Segment[] {\n const lines = String(text).split('\\n')\n const segs: Segment[] = []\n let buf: string[] = []\n let i = 0\n const flush = () => {\n if (buf.length) {\n const t = buf.join('\\n').replace(/^\\n+/, '').replace(/\\n+$/, '')\n if (t.trim()) segs.push({ code: false, text: t })\n buf = []\n }\n }\n while (i < lines.length) {\n const fence = lines[i].match(/^\\s*```+\\s*([^`]*)$/)\n if (fence) {\n flush()\n const lang = fence[1]\n const body: string[] = []\n i++\n while (i < lines.length && !/^\\s*```+\\s*$/.test(lines[i])) {\n body.push(lines[i])\n i++\n }\n i++ // consume closing fence\n segs.push({ code: true, lang, text: body.join('\\n') })\n } else {\n buf.push(lines[i])\n i++\n }\n }\n flush()\n return segs\n}\n"],"mappings":";AAWA,SAAgB,EAAW,GAAyB;CAClD,IAAM,IAAQ,OAAO,CAAI,CAAC,CAAC,MAAM,IAAI,GAC/B,IAAkB,CAAC,GACrB,IAAgB,CAAC,GACjB,IAAI,GACF,UAAc;EAClB,IAAI,EAAI,QAAQ;GACd,IAAM,IAAI,EAAI,KAAK,IAAI,CAAC,CAAC,QAAQ,QAAQ,EAAE,CAAC,CAAC,QAAQ,QAAQ,EAAE;GAE/D,AADI,EAAE,KAAK,KAAG,EAAK,KAAK;IAAE,MAAM;IAAO,MAAM;GAAE,CAAC,GAChD,IAAM,CAAC;EACT;CACF;CACA,OAAO,IAAI,EAAM,SAAQ;EACvB,IAAM,IAAQ,EAAM,EAAE,CAAC,MAAM,qBAAqB;EAClD,IAAI,GAAO;GACT,EAAM;GACN,IAAM,IAAO,EAAM,IACb,IAAiB,CAAC;GAExB,KADA,KACO,IAAI,EAAM,UAAU,CAAC,eAAe,KAAK,EAAM,EAAE,IAEtD,AADA,EAAK,KAAK,EAAM,EAAE,GAClB;GAGF,AADA,KACA,EAAK,KAAK;IAAE,MAAM;IAAM;IAAM,MAAM,EAAK,KAAK,IAAI;GAAE,CAAC;EACvD,OAEE,AADA,EAAI,KAAK,EAAM,EAAE,GACjB;CAEJ;CAEA,OADA,EAAM,GACC;AACT"}
@@ -133,3 +133,5 @@ function m(e) {
133
133
  }
134
134
  //#endregion
135
135
  export { p as blockquoteStyle, c as delStyle, l as emStyle, r as headingStyle, f as hrStyle, d as imgStyle, o as inlineCodeStyle, u as linkStyle, a as listItemStyle, i as listStyle, n as paragraphStyle, s as strongStyle, m as taskCheckboxStyle };
136
+
137
+ //# sourceMappingURL=styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.js","names":[],"sources":["../../../src/lib/markdown/styles.ts"],"sourcesContent":["import type { CSSProperties } from 'vue'\nimport { MONO, SERIF } from '@/lib/fonts'\n\n/**\n * Centralized typography for markdown-rendered nodes. The render functions build\n * raw VNodes (outside any SFC), so they can't use scoped CSS — keeping every\n * markdown style in this one file is the maintainable equivalent: tweak prose\n * sizing/spacing here and it applies everywhere markdown is rendered.\n *\n * `depth` mirrors the original: 0 = top level, >0 = nested inside a list item.\n */\n\nexport function paragraphStyle(depth: number): CSSProperties {\n return depth > 0\n ? {\n fontFamily: SERIF,\n fontSize: '16.5px',\n lineHeight: 1.7,\n margin: '0 0 8px',\n color: 'var(--text)',\n }\n : {\n fontFamily: SERIF,\n fontSize: '17px',\n lineHeight: 1.78,\n margin: '0 0 16px',\n color: 'var(--text)',\n }\n}\n\nexport function headingStyle(level: number, first: boolean): CSSProperties {\n const base: CSSProperties = { fontFamily: SERIF, fontWeight: 600, color: 'var(--text-strong)' }\n switch (level) {\n case 1:\n return {\n ...base,\n fontSize: '24px',\n margin: `${first ? '4px' : '32px'} 0 15px`,\n letterSpacing: '-0.02em',\n lineHeight: 1.3,\n }\n case 2:\n return {\n ...base,\n fontSize: '20px',\n margin: `${first ? '4px' : '30px'} 0 13px`,\n letterSpacing: '-0.01em',\n lineHeight: 1.35,\n }\n case 3:\n return { ...base, fontSize: '17px', margin: '22px 0 9px', lineHeight: 1.4 }\n case 4:\n return { ...base, fontSize: '15.5px', margin: '20px 0 8px', lineHeight: 1.45 }\n case 5:\n return { ...base, fontSize: '14px', margin: '18px 0 6px', lineHeight: 1.5 }\n default: // h6\n return {\n ...base,\n fontSize: '13px',\n margin: '18px 0 6px',\n letterSpacing: '0.01em',\n color: 'var(--muted)',\n lineHeight: 1.5,\n }\n }\n}\n\nexport function listStyle(depth: number, ordered: boolean): CSSProperties {\n return {\n margin: depth > 0 ? '8px 0 10px' : '4px 0 18px',\n paddingLeft: ordered ? '28px' : '24px',\n }\n}\n\nexport function listItemStyle(depth: number): CSSProperties {\n return {\n fontFamily: SERIF,\n fontSize: depth > 0 ? '16.5px' : '17px',\n lineHeight: 1.72,\n color: 'var(--text)',\n margin: '0 0 7px',\n paddingLeft: '3px',\n }\n}\n\nexport const inlineCodeStyle: CSSProperties = {\n fontFamily: MONO,\n fontSize: '0.86em',\n background: 'var(--code-bg)',\n border: '1px solid var(--code-border)',\n borderRadius: '5px',\n padding: '1.5px 5px',\n color: 'var(--accent)',\n overflowWrap: 'anywhere',\n}\n\nexport const strongStyle: CSSProperties = { fontWeight: 600, color: 'var(--text-strong)' }\nexport const delStyle: CSSProperties = { color: 'var(--muted)' }\nexport const emStyle: CSSProperties = { fontStyle: 'italic' }\nexport const linkStyle: CSSProperties = {\n color: 'var(--accent)',\n textDecoration: 'underline',\n textUnderlineOffset: '2px',\n textDecorationThickness: '1px',\n}\n\n/** Inline image (`![alt](url)`). Scales down to the column, never overflows. */\nexport const imgStyle: CSSProperties = {\n maxWidth: '100%',\n height: 'auto',\n borderRadius: '8px',\n margin: '6px 0',\n border: '1px solid var(--border)',\n}\n\n/** Thematic break (`---` / `***` / `___`). */\nexport const hrStyle: CSSProperties = {\n border: 'none',\n borderTop: '1px solid var(--border)',\n margin: '28px 0',\n}\n\n/** Blockquote (`> …`): left rule + softened text; nests via recursion. */\nexport const blockquoteStyle: CSSProperties = {\n margin: '0 0 16px',\n padding: '2px 0 2px 16px',\n borderLeft: '3px solid var(--border-2)',\n color: 'var(--muted)',\n}\n\n/** GFM task-list checkbox (`- [ ]` / `- [x]`) — a styled box, not a native input, for theme control. */\nexport function taskCheckboxStyle(checked: boolean): CSSProperties {\n return {\n display: 'inline-block',\n width: '15px',\n height: '15px',\n boxSizing: 'border-box',\n verticalAlign: '-2px',\n marginRight: '8px',\n borderRadius: '4px',\n border: `1.5px solid ${checked ? 'var(--accent)' : 'var(--border-2)'}`,\n background: checked ? 'var(--accent)' : 'transparent',\n color: '#fff',\n fontSize: '11px',\n lineHeight: '12px',\n textAlign: 'center',\n fontWeight: 700,\n }\n}\n"],"mappings":";;AAYA,SAAgB,EAAe,GAA8B;CAC3D,OAAO,IAAQ,IACX;EACE,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,QAAQ;EACR,OAAO;CACT,IACA;EACE,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,QAAQ;EACR,OAAO;CACT;AACN;AAEA,SAAgB,EAAa,GAAe,GAA+B;CACzE,IAAM,IAAsB;EAAE,YAAY;EAAO,YAAY;EAAK,OAAO;CAAqB;CAC9F,QAAQ,GAAR;EACE,KAAK,GACH,OAAO;GACL,GAAG;GACH,UAAU;GACV,QAAQ,GAAG,IAAQ,QAAQ,OAAO;GAClC,eAAe;GACf,YAAY;EACd;EACF,KAAK,GACH,OAAO;GACL,GAAG;GACH,UAAU;GACV,QAAQ,GAAG,IAAQ,QAAQ,OAAO;GAClC,eAAe;GACf,YAAY;EACd;EACF,KAAK,GACH,OAAO;GAAE,GAAG;GAAM,UAAU;GAAQ,QAAQ;GAAc,YAAY;EAAI;EAC5E,KAAK,GACH,OAAO;GAAE,GAAG;GAAM,UAAU;GAAU,QAAQ;GAAc,YAAY;EAAK;EAC/E,KAAK,GACH,OAAO;GAAE,GAAG;GAAM,UAAU;GAAQ,QAAQ;GAAc,YAAY;EAAI;EAC5E,SACE,OAAO;GACL,GAAG;GACH,UAAU;GACV,QAAQ;GACR,eAAe;GACf,OAAO;GACP,YAAY;EACd;CACJ;AACF;AAEA,SAAgB,EAAU,GAAe,GAAiC;CACxE,OAAO;EACL,QAAQ,IAAQ,IAAI,eAAe;EACnC,aAAa,IAAU,SAAS;CAClC;AACF;AAEA,SAAgB,EAAc,GAA8B;CAC1D,OAAO;EACL,YAAY;EACZ,UAAU,IAAQ,IAAI,WAAW;EACjC,YAAY;EACZ,OAAO;EACP,QAAQ;EACR,aAAa;CACf;AACF;AAEA,IAAa,IAAiC;CAC5C,YAAY;CACZ,UAAU;CACV,YAAY;CACZ,QAAQ;CACR,cAAc;CACd,SAAS;CACT,OAAO;CACP,cAAc;AAChB,GAEa,IAA6B;CAAE,YAAY;CAAK,OAAO;AAAqB,GAC5E,IAA0B,EAAE,OAAO,eAAe,GAClD,IAAyB,EAAE,WAAW,SAAS,GAC/C,IAA2B;CACtC,OAAO;CACP,gBAAgB;CAChB,qBAAqB;CACrB,yBAAyB;AAC3B,GAGa,IAA0B;CACrC,UAAU;CACV,QAAQ;CACR,cAAc;CACd,QAAQ;CACR,QAAQ;AACV,GAGa,IAAyB;CACpC,QAAQ;CACR,WAAW;CACX,QAAQ;AACV,GAGa,IAAiC;CAC5C,QAAQ;CACR,SAAS;CACT,YAAY;CACZ,OAAO;AACT;AAGA,SAAgB,EAAkB,GAAiC;CACjE,OAAO;EACL,SAAS;EACT,OAAO;EACP,QAAQ;EACR,WAAW;EACX,eAAe;EACf,aAAa;EACb,cAAc;EACd,QAAQ,eAAe,IAAU,kBAAkB;EACnD,YAAY,IAAU,kBAAkB;EACxC,OAAO;EACP,UAAU;EACV,YAAY;EACZ,WAAW;EACX,YAAY;CACd;AACF"}
package/dist/lib/mht.js CHANGED
@@ -120,3 +120,5 @@ function p(e, t) {
120
120
  }
121
121
  //#endregion
122
122
  export { d as parseMht, p as rewriteHtml };
123
+
124
+ //# sourceMappingURL=mht.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mht.js","names":[],"sources":["../../src/lib/mht.ts"],"sourcesContent":["/**\n * Hand-rolled MHT / MHTML (web archive, RFC 2557) parser — the archive-specific layer on top of the shared\n * MIME core (lib/mime.ts). An `.mht`/`.mhtml` is a `multipart/related` MIME container: a root HTML part plus\n * the page's resources (images / CSS / fonts), each part referenced from the HTML by its original URL via a\n * `Content-Location` header (vs. an email's `cid:` Content-ID).\n *\n * Two halves:\n * - {@link parseMht} (pure, unit-testable): parse the container, pick the root HTML part, and index every\n * other part by its absolute Content-Location (and Content-ID, for the rare `cid:` archive).\n * - {@link rewriteHtml} (browser-only, uses DOMParser): rewrite the HTML's resource references to caller-\n * supplied blob URLs, strip scripts, and inject a hardened CSP — so the archive renders offline inside a\n * sandboxed iframe without running upstream script or phoning home. See MhtViewer.vue.\n */\n\nimport {\n bytesToBinary,\n collectLeaves,\n decodeCharset,\n decodeWords,\n getHeader,\n parseEntity,\n parseHeaders,\n splitHeadersBody,\n type Entity,\n} from '@/lib/mime'\n\n/** A single archived page resource (image / stylesheet / font / …). */\nexport interface MhtResource {\n contentType: string\n /** Charset label from the part's Content-Type (for text resources like CSS); '' when none. */\n charset: string\n bytes: Uint8Array\n}\n\n/** Flattened, render-ready view of a parsed web archive. */\nexport interface ParsedMht {\n /** `Subject:` header — the saved page's title (browsers write the document title here). */\n title: string\n /** Original page URL (`Snapshot-Content-Location` or the root `Content-Location`), for display. */\n sourceUrl: string\n /** Raw `Date:` header value (the viewer formats it for display). */\n date: string\n /** Decoded root HTML (NOT yet resource-rewritten), or null when the archive has no HTML part. */\n html: string | null\n /** Base URL for resolving the root HTML's resource references (the root part's Content-Location). */\n rootBase: string\n /** Absolute Content-Location → resource. */\n byLocation: Map<string, MhtResource>\n /** Content-ID (no angle brackets) → resource. */\n byCid: Map<string, MhtResource>\n}\n\n/** The hardened CSP injected into the archive before it's handed to the sandboxed iframe. */\nexport const MHT_CSP =\n \"default-src 'none'; img-src blob: data:; media-src blob: data:; \" +\n \"style-src blob: data: 'unsafe-inline'; font-src blob: data:; \" +\n \"script-src 'none'; object-src 'none'; base-uri 'none'; form-action 'none'\"\n\n/** Resolve `ref` against `base` to an absolute URL; returns `ref` unchanged when it can't be resolved. */\nfunction absolutize(ref: string, base: string): string {\n try {\n return new URL(ref, base || undefined).href\n } catch {\n return ref\n }\n}\n\n/** Strip surrounding angle brackets from a Content-ID / `start` reference. */\nfunction unwrapId(id: string): string {\n return id.trim().replace(/^<|>$/g, '')\n}\n\n/** Parse raw `.mht`/`.mhtml` bytes into a flattened {@link ParsedMht}. */\nexport function parseMht(bytes: Uint8Array): ParsedMht {\n const bin = bytesToBinary(bytes)\n const root = parseEntity(bin)\n const headers = parseHeaders(splitHeadersBody(bin)[0])\n\n const leaves: Entity[] = []\n collectLeaves(root, leaves)\n\n // Pick the root HTML part: the multipart/related `start` (a Content-ID), else the first text/html leaf.\n const start = unwrapId(root.ctParams.start || '')\n let rootHtmlLeaf: Entity | undefined\n if (start) rootHtmlLeaf = leaves.find((l) => l.contentId === start)\n if (!rootHtmlLeaf) rootHtmlLeaf = leaves.find((l) => l.contentType === 'text/html')\n\n // Every other leaf is a page resource, keyed by its (absolute) Content-Location and/or Content-ID.\n const byLocation = new Map<string, MhtResource>()\n const byCid = new Map<string, MhtResource>()\n for (const lf of leaves) {\n if (lf === rootHtmlLeaf) continue\n const res: MhtResource = {\n contentType: lf.contentType,\n charset: lf.charset,\n bytes: lf.bodyBytes ?? new Uint8Array(),\n }\n if (lf.contentLocation) {\n byLocation.set(lf.contentLocation, res)\n const abs = absolutize(lf.contentLocation, lf.contentLocation)\n if (abs !== lf.contentLocation) byLocation.set(abs, res)\n }\n if (lf.contentId) byCid.set(lf.contentId, res)\n }\n\n const rootBase = rootHtmlLeaf?.contentLocation || getHeader(headers, 'content-location') || ''\n const html = rootHtmlLeaf\n ? decodeCharset(rootHtmlLeaf.bodyBytes ?? new Uint8Array(), rootHtmlLeaf.charset)\n : null\n\n return {\n title: decodeWords(getHeader(headers, 'subject')),\n sourceUrl:\n getHeader(headers, 'snapshot-content-location') ||\n getHeader(headers, 'content-location') ||\n rootBase,\n date: getHeader(headers, 'date'),\n html,\n rootBase,\n byLocation,\n byCid,\n }\n}\n\nconst XLINK_NS = 'http://www.w3.org/1999/xlink'\n\n/**\n * Rewrite the parsed archive's root HTML so every captured resource reference points at a caller-supplied\n * blob URL, strip scripts, and inject {@link MHT_CSP}. Returns a complete HTML document string for the\n * sandboxed iframe. Browser-only (uses DOMParser — which neither runs scripts nor fetches subresources).\n *\n * `makeUrl(bytes, contentType)` is the caller's blob-URL factory (it tracks the URLs for later revocation).\n * Resources we can't resolve are left with their original URL — the CSP then blocks the request, so they\n * show as a broken image rather than leaking to the network.\n */\nexport function rewriteHtml(\n parsed: ParsedMht,\n makeUrl: (bytes: Uint8Array, contentType: string) => string,\n): string {\n const doc = new DOMParser().parseFromString(parsed.html ?? '', 'text/html')\n\n // One blob URL per distinct resource (an image referenced N times → one URL).\n const urlCache = new Map<MhtResource, string>()\n const urlFor = (res: MhtResource): string => {\n let u = urlCache.get(res)\n if (!u) {\n u = makeUrl(res.bytes, res.contentType || 'application/octet-stream')\n urlCache.set(res, u)\n }\n return u\n }\n\n const lookup = (ref: string, base: string): MhtResource | undefined => {\n if (!ref) return undefined\n if (/^cid:/i.test(ref)) {\n const id = unwrapId(ref.slice(4))\n return parsed.byCid.get(id) ?? parsed.byCid.get(decodeURIComponent(id))\n }\n if (/^(data|blob|javascript|about):/i.test(ref)) return undefined\n const abs = absolutize(ref, base)\n return parsed.byLocation.get(abs) ?? parsed.byLocation.get(ref)\n }\n\n // Rewrite `url(...)` and `@import` targets inside a CSS string (inline <style>, style=\"\", or a stylesheet).\n const rewriteCss = (css: string, base: string): string => {\n let out = css.replace(/url\\(\\s*(['\"]?)([^'\")]+)\\1\\s*\\)/gi, (whole, _q: string, ref: string) => {\n const res = lookup(ref, base)\n return res ? `url(\"${urlFor(res)}\")` : whole\n })\n out = out.replace(/@import\\s+(['\"])([^'\"]+)\\1/gi, (whole, _q: string, ref: string) => {\n const res = lookup(ref, base)\n return res ? `@import \"${urlFor(res)}\"` : whole\n })\n return out\n }\n\n const setAttrUrl = (el: Element, attr: string): void => {\n const ref = el.getAttribute(attr)\n if (!ref) return\n const res = lookup(ref, parsed.rootBase)\n if (res) el.setAttribute(attr, urlFor(res))\n }\n\n // Drop scripts, <base> (would skew URL resolution), and any document-supplied CSP (ours must win).\n doc.querySelectorAll('script, base').forEach((el) => el.remove())\n doc.querySelectorAll('meta[http-equiv]').forEach((m) => {\n if ((m.getAttribute('http-equiv') || '').toLowerCase() === 'content-security-policy') m.remove()\n })\n\n // Linked stylesheets: rewrite the CSS body's url()s against the stylesheet's own base, then re-blob it.\n doc.querySelectorAll('link[rel~=\"stylesheet\"][href]').forEach((el) => {\n const ref = el.getAttribute('href')\n if (!ref) return\n const res = lookup(ref, parsed.rootBase)\n if (!res) return\n const cssBase = absolutize(ref, parsed.rootBase)\n const css = rewriteCss(decodeCharset(res.bytes, res.charset), cssBase)\n el.setAttribute('href', makeUrl(new TextEncoder().encode(css), 'text/css'))\n })\n\n // Plain single-URL resource attributes.\n const ATTRS: [string, string][] = [\n ['img', 'src'],\n ['input[type=\"image\"]', 'src'],\n ['source', 'src'],\n ['video', 'src'],\n ['video', 'poster'],\n ['audio', 'src'],\n ['track', 'src'],\n ['embed', 'src'],\n ['object', 'data'],\n ]\n for (const [sel, attr] of ATTRS) {\n doc.querySelectorAll(sel).forEach((el) => setAttrUrl(el, attr))\n }\n\n // SVG <image href> / xlink:href.\n doc.querySelectorAll('image').forEach((el) => {\n setAttrUrl(el, 'href')\n const xref = el.getAttributeNS(XLINK_NS, 'href')\n if (xref) {\n const res = lookup(xref, parsed.rootBase)\n if (res) el.setAttributeNS(XLINK_NS, 'href', urlFor(res))\n }\n })\n\n // srcset (img / source): a comma list of `url [descriptor]` candidates.\n doc.querySelectorAll('img[srcset], source[srcset]').forEach((el) => {\n const ss = el.getAttribute('srcset')\n if (!ss) return\n const out = ss\n .split(',')\n .map((part) => {\n const seg = part.trim()\n if (!seg) return seg\n const sp = seg.split(/\\s+/)\n const res = lookup(sp[0], parsed.rootBase)\n if (res) sp[0] = urlFor(res)\n return sp.join(' ')\n })\n .join(', ')\n el.setAttribute('srcset', out)\n })\n\n // Inline style=\"\" and <style> blocks.\n doc.querySelectorAll('[style]').forEach((el) => {\n const s = el.getAttribute('style')\n if (s && s.includes('url(')) el.setAttribute('style', rewriteCss(s, parsed.rootBase))\n })\n doc.querySelectorAll('style').forEach((el) => {\n el.textContent = rewriteCss(el.textContent ?? '', parsed.rootBase)\n })\n\n // Inject our hardened CSP as the first thing in <head> (intersects with — can't be loosened by — any other).\n const meta = doc.createElement('meta')\n meta.setAttribute('http-equiv', 'Content-Security-Policy')\n meta.setAttribute('content', MHT_CSP)\n doc.head.insertBefore(meta, doc.head.firstChild)\n\n return '<!doctype html>\\n' + doc.documentElement.outerHTML\n}\n"],"mappings":"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"}
package/dist/lib/midi.js CHANGED
@@ -82,3 +82,5 @@ function e(e) {
82
82
  }
83
83
  //#endregion
84
84
  export { e as parseMidi };
85
+
86
+ //# sourceMappingURL=midi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"midi.js","names":[],"sources":["../../src/lib/midi.ts"],"sourcesContent":["/**\n * Hand-rolled, zero-dependency Standard MIDI File (.mid/.midi) parser for the side viewer's best-effort\n * preview. The browser can't *play* MIDI (there's no built-in synthesizer and self-hosting a soundfont is out\n * of scope), so the viewer instead VISUALIZES the music as a piano roll. This extracts what that needs: the\n * note events (pitch / timing / track) plus header info and an approximate duration.\n *\n * Timing is approximate by design: it uses the first `set_tempo` it sees (or 120 BPM) for the whole file, so\n * songs with tempo changes will be slightly off — fine for a visual overview. SMPTE-division files fall back\n * to a nominal ticks-per-quarter. Note-ons with velocity 0 are treated as note-offs (the common shorthand).\n */\n\nexport interface MidiNote {\n track: number\n channel: number\n pitch: number // 0..127\n startTick: number\n endTick: number\n velocity: number // 1..127\n}\n\nexport interface ParsedMidi {\n format: number\n trackCount: number\n division: number // ticks per quarter note (or nominal fallback for SMPTE)\n notes: MidiNote[]\n totalTicks: number\n durationSec: number\n tempoBpm: number\n}\n\nexport function parseMidi(buf: ArrayBuffer): ParsedMidi {\n const dv = new DataView(buf)\n let p = 0\n const u8 = (): number => dv.getUint8(p++)\n const u16 = (): number => {\n const v = dv.getUint16(p)\n p += 2\n return v\n }\n const u32 = (): number => {\n const v = dv.getUint32(p)\n p += 4\n return v\n }\n const tag = (): string => String.fromCharCode(u8(), u8(), u8(), u8())\n // MIDI variable-length quantity.\n const varLen = (): number => {\n let value = 0\n for (let i = 0; i < 4; i++) {\n const b = u8()\n value = (value << 7) | (b & 0x7f)\n if (!(b & 0x80)) break\n }\n return value\n }\n\n if (buf.byteLength < 14 || tag() !== 'MThd') throw new Error('不是有效的 MIDI 文件')\n const headerLen = u32()\n const format = u16()\n const ntrks = u16()\n const rawDivision = u16()\n p = 8 + headerLen // skip to the first track (past any extra header bytes)\n\n const smpte = (rawDivision & 0x8000) !== 0\n const division = smpte ? 480 : rawDivision || 480\n\n const notes: MidiNote[] = []\n let tempoUs = 500000 // 120 BPM default\n let tempoSet = false\n let totalTicks = 0\n\n for (let t = 0; t < ntrks && p + 8 <= dv.byteLength; t++) {\n if (tag() !== 'MTrk') break\n const len = u32()\n const end = Math.min(p + len, dv.byteLength)\n let tick = 0\n let status = 0\n // key = (channel << 8) | pitch → the open note's start tick + velocity.\n const active = new Map<number, { startTick: number; velocity: number }>()\n const closeNote = (channel: number, pitch: number): void => {\n const key = (channel << 8) | pitch\n const a = active.get(key)\n if (a) {\n notes.push({\n track: t,\n channel,\n pitch,\n startTick: a.startTick,\n endTick: tick,\n velocity: a.velocity,\n })\n active.delete(key)\n if (tick > totalTicks) totalTicks = tick\n }\n }\n\n while (p < end) {\n tick += varLen()\n let b = u8()\n if (b & 0x80) {\n status = b\n } else {\n p-- // running status: reuse the previous status, `b` is the first data byte\n }\n if (status === 0xff) {\n // meta event\n const type = u8()\n const mlen = varLen()\n if (type === 0x51 && mlen === 3) {\n const us = (u8() << 16) | (u8() << 8) | u8()\n if (!tempoSet) {\n tempoUs = us\n tempoSet = true\n }\n } else {\n p += mlen\n }\n } else if (status === 0xf0 || status === 0xf7) {\n // sysex — skip\n p += varLen()\n } else {\n const hi = status & 0xf0\n const ch = status & 0x0f\n if (hi === 0x90) {\n const pitch = u8()\n const vel = u8()\n if (vel > 0) active.set((ch << 8) | pitch, { startTick: tick, velocity: vel })\n else closeNote(ch, pitch)\n } else if (hi === 0x80) {\n const pitch = u8()\n u8() // release velocity\n closeNote(ch, pitch)\n } else if (hi === 0xa0 || hi === 0xb0 || hi === 0xe0) {\n p += 2 // two data bytes\n } else if (hi === 0xc0 || hi === 0xd0) {\n p += 1 // one data byte\n } else {\n break // unknown status — bail out of this track\n }\n }\n }\n // Close any notes left hanging at the track's end.\n for (const [key, a] of active) {\n const pitch = key & 0xff\n const channel = key >> 8\n notes.push({\n track: t,\n channel,\n pitch,\n startTick: a.startTick,\n endTick: tick,\n velocity: a.velocity,\n })\n }\n if (tick > totalTicks) totalTicks = tick\n p = end // realign to the declared track length\n }\n\n const secPerTick = tempoUs / 1e6 / division\n return {\n format,\n trackCount: ntrks,\n division,\n notes,\n totalTicks,\n durationSec: totalTicks * secPerTick,\n tempoBpm: Math.round(60e6 / tempoUs),\n }\n}\n"],"mappings":"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"}
package/dist/lib/mime.js CHANGED
@@ -149,3 +149,5 @@ function v(e, t) {
149
149
  }
150
150
  //#endregion
151
151
  export { t as bytesToBinary, v as collectLeaves, i as decodeCharset, o as decodeWords, l as getHeader, _ as parseEntity, c as parseHeaders, s as splitHeadersBody };
152
+
153
+ //# sourceMappingURL=mime.js.map