@l1yp/file-viewer 0.1.1 → 0.1.3

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 (440) hide show
  1. package/README.md +1 -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 +2 -0
  47. package/dist/components/DocxNavigationPane.js.map +1 -0
  48. package/dist/components/DocxNavigationPane.vue_vue_type_script_setup_true_lang.js +2 -0
  49. package/dist/components/DocxNavigationPane.vue_vue_type_script_setup_true_lang.js.map +1 -0
  50. package/dist/components/DocxViewer.js +2 -0
  51. package/dist/components/DocxViewer.js.map +1 -0
  52. package/dist/components/DocxViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  53. package/dist/components/DocxViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  54. package/dist/components/DrawioViewer.js +2 -0
  55. package/dist/components/DrawioViewer.js.map +1 -0
  56. package/dist/components/DrawioViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  57. package/dist/components/DrawioViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  58. package/dist/components/DxfViewer.js +2 -0
  59. package/dist/components/DxfViewer.js.map +1 -0
  60. package/dist/components/DxfViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  61. package/dist/components/DxfViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  62. package/dist/components/EbookViewer.js +2 -0
  63. package/dist/components/EbookViewer.js.map +1 -0
  64. package/dist/components/EbookViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  65. package/dist/components/EbookViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  66. package/dist/components/EmlViewer.js +2 -0
  67. package/dist/components/EmlViewer.js.map +1 -0
  68. package/dist/components/EmlViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  69. package/dist/components/EmlViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  70. package/dist/components/EplViewer.js +2 -0
  71. package/dist/components/EplViewer.js.map +1 -0
  72. package/dist/components/EplViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  73. package/dist/components/EplViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  74. package/dist/components/FileViewerBody.js +3 -1
  75. package/dist/components/FileViewerBody.js.map +1 -0
  76. package/dist/components/FileViewerBody.vue_vue_type_script_setup_true_lang.js +2 -0
  77. package/dist/components/FileViewerBody.vue_vue_type_script_setup_true_lang.js.map +1 -0
  78. package/dist/components/FileViewerPanel.js +2 -0
  79. package/dist/components/FileViewerPanel.js.map +1 -0
  80. package/dist/components/FileViewerPanel.vue_vue_type_script_setup_true_lang.js +2 -0
  81. package/dist/components/FileViewerPanel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  82. package/dist/components/FontViewer.js +2 -0
  83. package/dist/components/FontViewer.js.map +1 -0
  84. package/dist/components/FontViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  85. package/dist/components/FontViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  86. package/dist/components/FrontmatterCard.js +2 -0
  87. package/dist/components/FrontmatterCard.js.map +1 -0
  88. package/dist/components/FrontmatterCard.vue_vue_type_script_setup_true_lang.js +2 -0
  89. package/dist/components/FrontmatterCard.vue_vue_type_script_setup_true_lang.js.map +1 -0
  90. package/dist/components/GeoViewer.js +2 -0
  91. package/dist/components/GeoViewer.js.map +1 -0
  92. package/dist/components/GeoViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  93. package/dist/components/GeoViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  94. package/dist/components/HarViewer.js +2 -0
  95. package/dist/components/HarViewer.js.map +1 -0
  96. package/dist/components/HarViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  97. package/dist/components/HarViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  98. package/dist/components/HexViewer.js +2 -0
  99. package/dist/components/HexViewer.js.map +1 -0
  100. package/dist/components/HexViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  101. package/dist/components/HexViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  102. package/dist/components/HprofViewer.js +2 -0
  103. package/dist/components/HprofViewer.js.map +1 -0
  104. package/dist/components/HprofViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  105. package/dist/components/HprofViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  106. package/dist/components/ImageLightbox.js +2 -0
  107. package/dist/components/ImageLightbox.js.map +1 -0
  108. package/dist/components/ImageLightbox.vue_vue_type_script_setup_true_lang.js +2 -0
  109. package/dist/components/ImageLightbox.vue_vue_type_script_setup_true_lang.js.map +1 -0
  110. package/dist/components/InlineText.js +2 -0
  111. package/dist/components/InlineText.js.map +1 -0
  112. package/dist/components/JksViewer.js +2 -0
  113. package/dist/components/JksViewer.js.map +1 -0
  114. package/dist/components/JksViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  115. package/dist/components/JksViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  116. package/dist/components/JsonlViewer.js +3 -1
  117. package/dist/components/JsonlViewer.js.map +1 -0
  118. package/dist/components/JsonlViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  119. package/dist/components/JsonlViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  120. package/dist/components/LogViewer.js +2 -0
  121. package/dist/components/LogViewer.js.map +1 -0
  122. package/dist/components/LogViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  123. package/dist/components/LogViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  124. package/dist/components/LrcViewer.js +2 -0
  125. package/dist/components/LrcViewer.js.map +1 -0
  126. package/dist/components/LrcViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  127. package/dist/components/LrcViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  128. package/dist/components/MarkdownTable.js +2 -0
  129. package/dist/components/MarkdownTable.js.map +1 -0
  130. package/dist/components/MarkdownTable.vue_vue_type_script_setup_true_lang.js +2 -0
  131. package/dist/components/MarkdownTable.vue_vue_type_script_setup_true_lang.js.map +1 -0
  132. package/dist/components/MarkdownText.js +2 -0
  133. package/dist/components/MarkdownText.js.map +1 -0
  134. package/dist/components/MhtViewer.js +2 -0
  135. package/dist/components/MhtViewer.js.map +1 -0
  136. package/dist/components/MhtViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  137. package/dist/components/MhtViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  138. package/dist/components/MindMapView.js +2 -0
  139. package/dist/components/MindMapView.js.map +1 -0
  140. package/dist/components/MindMapView.vue_vue_type_script_setup_true_lang.js +2 -0
  141. package/dist/components/MindMapView.vue_vue_type_script_setup_true_lang.js.map +1 -0
  142. package/dist/components/MissingDependency.js +2 -0
  143. package/dist/components/MissingDependency.js.map +1 -0
  144. package/dist/components/MissingDependency.vue_vue_type_script_setup_true_lang.js +2 -0
  145. package/dist/components/MissingDependency.vue_vue_type_script_setup_true_lang.js.map +1 -0
  146. package/dist/components/ModelViewer.js +2 -0
  147. package/dist/components/ModelViewer.js.map +1 -0
  148. package/dist/components/ModelViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  149. package/dist/components/ModelViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  150. package/dist/components/MsiViewer.js +2 -0
  151. package/dist/components/MsiViewer.js.map +1 -0
  152. package/dist/components/MsiViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  153. package/dist/components/MsiViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  154. package/dist/components/NotebookViewer.js +2 -0
  155. package/dist/components/NotebookViewer.js.map +1 -0
  156. package/dist/components/NotebookViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  157. package/dist/components/NotebookViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  158. package/dist/components/PdfNavigationPane.js +9 -0
  159. package/dist/components/PdfNavigationPane.js.map +1 -0
  160. package/dist/components/PdfNavigationPane.vue.d.ts +24 -0
  161. package/dist/components/PdfNavigationPane.vue_vue_type_script_setup_true_lang.js +149 -0
  162. package/dist/components/PdfNavigationPane.vue_vue_type_script_setup_true_lang.js.map +1 -0
  163. package/dist/components/PdfViewer.js +3 -1
  164. package/dist/components/PdfViewer.js.map +1 -0
  165. package/dist/components/PdfViewer.vue.d.ts +0 -11
  166. package/dist/components/PdfViewer.vue_vue_type_script_setup_true_lang.js +133 -69
  167. package/dist/components/PdfViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  168. package/dist/components/PptxNavigationPane.js +2 -0
  169. package/dist/components/PptxNavigationPane.js.map +1 -0
  170. package/dist/components/PptxNavigationPane.vue_vue_type_script_setup_true_lang.js +2 -0
  171. package/dist/components/PptxNavigationPane.vue_vue_type_script_setup_true_lang.js.map +1 -0
  172. package/dist/components/PptxViewer.js +3 -1
  173. package/dist/components/PptxViewer.js.map +1 -0
  174. package/dist/components/PptxViewer.vue_vue_type_script_setup_true_lang.js +55 -49
  175. package/dist/components/PptxViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  176. package/dist/components/PsdViewer.js +2 -0
  177. package/dist/components/PsdViewer.js.map +1 -0
  178. package/dist/components/PsdViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  179. package/dist/components/PsdViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  180. package/dist/components/QmcAudioViewer.js +2 -0
  181. package/dist/components/QmcAudioViewer.js.map +1 -0
  182. package/dist/components/QmcAudioViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  183. package/dist/components/QmcAudioViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  184. package/dist/components/RasterViewer.js +2 -0
  185. package/dist/components/RasterViewer.js.map +1 -0
  186. package/dist/components/RasterViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  187. package/dist/components/RasterViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  188. package/dist/components/RtfViewer.js +2 -0
  189. package/dist/components/RtfViewer.js.map +1 -0
  190. package/dist/components/RtfViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  191. package/dist/components/RtfViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  192. package/dist/components/SevenZipBrowser.js +2 -0
  193. package/dist/components/SevenZipBrowser.js.map +1 -0
  194. package/dist/components/SevenZipBrowser.vue_vue_type_script_setup_true_lang.js +2 -0
  195. package/dist/components/SevenZipBrowser.vue_vue_type_script_setup_true_lang.js.map +1 -0
  196. package/dist/components/SqliteViewer.js +2 -0
  197. package/dist/components/SqliteViewer.js.map +1 -0
  198. package/dist/components/SqliteViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  199. package/dist/components/SqliteViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  200. package/dist/components/SubtitleViewer.js +2 -0
  201. package/dist/components/SubtitleViewer.js.map +1 -0
  202. package/dist/components/SubtitleViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  203. package/dist/components/SubtitleViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  204. package/dist/components/XlsxChart.js +2 -0
  205. package/dist/components/XlsxChart.js.map +1 -0
  206. package/dist/components/XlsxChart.vue_vue_type_script_setup_true_lang.js +2 -0
  207. package/dist/components/XlsxChart.vue_vue_type_script_setup_true_lang.js.map +1 -0
  208. package/dist/components/XlsxViewer.js +2 -0
  209. package/dist/components/XlsxViewer.js.map +1 -0
  210. package/dist/components/XlsxViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  211. package/dist/components/XlsxViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  212. package/dist/components/XmindViewer.js +2 -0
  213. package/dist/components/XmindViewer.js.map +1 -0
  214. package/dist/components/XmindViewer.vue_vue_type_script_setup_true_lang.js +2 -0
  215. package/dist/components/XmindViewer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  216. package/dist/components/ZipBrowser.js +2 -0
  217. package/dist/components/ZipBrowser.js.map +1 -0
  218. package/dist/components/ZipBrowser.vue_vue_type_script_setup_true_lang.js +2 -0
  219. package/dist/components/ZipBrowser.vue_vue_type_script_setup_true_lang.js.map +1 -0
  220. package/dist/components/ZoomImage.js +3 -1
  221. package/dist/components/ZoomImage.js.map +1 -0
  222. package/dist/components/ZoomImage.vue_vue_type_script_setup_true_lang.js +82 -80
  223. package/dist/components/ZoomImage.vue_vue_type_script_setup_true_lang.js.map +1 -0
  224. package/dist/components/epl/EplCodeBlock.js +2 -0
  225. package/dist/components/epl/EplCodeBlock.js.map +1 -0
  226. package/dist/components/epl/EplCodeBlock.vue_vue_type_script_setup_true_lang.js +2 -0
  227. package/dist/components/epl/EplCodeBlock.vue_vue_type_script_setup_true_lang.js.map +1 -0
  228. package/dist/components/epl/EplDoc.js +2 -0
  229. package/dist/components/epl/EplDoc.js.map +1 -0
  230. package/dist/components/epl/EplDoc.vue_vue_type_script_setup_true_lang.js +2 -0
  231. package/dist/components/epl/EplDoc.vue_vue_type_script_setup_true_lang.js.map +1 -0
  232. package/dist/components/epl/EplMethod.js +2 -0
  233. package/dist/components/epl/EplMethod.js.map +1 -0
  234. package/dist/components/epl/EplMethod.vue_vue_type_script_setup_true_lang.js +2 -0
  235. package/dist/components/epl/EplMethod.vue_vue_type_script_setup_true_lang.js.map +1 -0
  236. package/dist/components/epl/EplResource.js +2 -0
  237. package/dist/components/epl/EplResource.js.map +1 -0
  238. package/dist/components/epl/EplResource.vue_vue_type_script_setup_true_lang.js +2 -0
  239. package/dist/components/epl/EplResource.vue_vue_type_script_setup_true_lang.js.map +1 -0
  240. package/dist/components/epl/EplTree.js +2 -0
  241. package/dist/components/epl/EplTree.js.map +1 -0
  242. package/dist/components/epl/EplTree.vue_vue_type_script_setup_true_lang.js +2 -0
  243. package/dist/components/epl/EplTree.vue_vue_type_script_setup_true_lang.js.map +1 -0
  244. package/dist/components/epl/EplVarTable.js +2 -0
  245. package/dist/components/epl/EplVarTable.js.map +1 -0
  246. package/dist/components/epl/EplVarTable.vue_vue_type_script_setup_true_lang.js +2 -0
  247. package/dist/components/epl/EplVarTable.vue_vue_type_script_setup_true_lang.js.map +1 -0
  248. package/dist/components/epl/numbering.js +2 -0
  249. package/dist/components/epl/numbering.js.map +1 -0
  250. package/dist/components/icons/Icon.js +2 -0
  251. package/dist/components/icons/Icon.js.map +1 -0
  252. package/dist/components/icons/Icon.vue_vue_type_script_setup_true_lang.js +2 -0
  253. package/dist/components/icons/Icon.vue_vue_type_script_setup_true_lang.js.map +1 -0
  254. package/dist/components/icons/iconPaths.js +2 -0
  255. package/dist/components/icons/iconPaths.js.map +1 -0
  256. package/dist/components/optionalViewer.js +2 -0
  257. package/dist/components/optionalViewer.js.map +1 -0
  258. package/dist/components/ui/ClampBlock.js +2 -0
  259. package/dist/components/ui/ClampBlock.js.map +1 -0
  260. package/dist/composables/useElementNavigation.js +2 -0
  261. package/dist/composables/useElementNavigation.js.map +1 -0
  262. package/dist/composables/useFileViewer.js +2 -0
  263. package/dist/composables/useFileViewer.js.map +1 -0
  264. package/dist/composables/useLightbox.js +2 -0
  265. package/dist/composables/useLightbox.js.map +1 -0
  266. package/dist/composables/useLogRules.js +2 -0
  267. package/dist/composables/useLogRules.js.map +1 -0
  268. package/dist/lib/aes.js +2 -0
  269. package/dist/lib/aes.js.map +1 -0
  270. package/dist/lib/appx.js +2 -0
  271. package/dist/lib/appx.js.map +1 -0
  272. package/dist/lib/archiveHtml.js +2 -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.js +2 -0
  303. package/dist/lib/docxNavigation.js.map +1 -0
  304. package/dist/lib/dxf.js +2 -0
  305. package/dist/lib/dxf.js.map +1 -0
  306. package/dist/lib/eml.js +2 -0
  307. package/dist/lib/eml.js.map +1 -0
  308. package/dist/lib/encoding.js +2 -0
  309. package/dist/lib/encoding.js.map +1 -0
  310. package/dist/lib/epl/code/codeDataParser.js +2 -0
  311. package/dist/lib/epl/code/codeDataParser.js.map +1 -0
  312. package/dist/lib/epl/code/codeLines.js +2 -0
  313. package/dist/lib/epl/code/codeLines.js.map +1 -0
  314. package/dist/lib/epl/code/textCode.js +2 -0
  315. package/dist/lib/epl/code/textCode.js.map +1 -0
  316. package/dist/lib/epl/eplDocument.js +2 -0
  317. package/dist/lib/epl/eplDocument.js.map +1 -0
  318. package/dist/lib/epl/imageList.js +2 -0
  319. package/dist/lib/epl/imageList.js.map +1 -0
  320. package/dist/lib/epl/index.js +2 -0
  321. package/dist/lib/epl/index.js.map +1 -0
  322. package/dist/lib/epl/io/binaryReader.js +2 -0
  323. package/dist/lib/epl/io/binaryReader.js.map +1 -0
  324. package/dist/lib/epl/io/encoding.js +2 -0
  325. package/dist/lib/epl/io/encoding.js.map +1 -0
  326. package/dist/lib/epl/model/eplSystemId.js +2 -0
  327. package/dist/lib/epl/model/eplSystemId.js.map +1 -0
  328. package/dist/lib/epl/names/eplLibData.js +2 -0
  329. package/dist/lib/epl/names/eplLibData.js.map +1 -0
  330. package/dist/lib/epl/names/idToNameMap.js +2 -0
  331. package/dist/lib/epl/names/idToNameMap.js.map +1 -0
  332. package/dist/lib/epl/names/libNameProvider.js +2 -0
  333. package/dist/lib/epl/names/libNameProvider.js.map +1 -0
  334. package/dist/lib/epl/program.js +2 -0
  335. package/dist/lib/epl/program.js.map +1 -0
  336. package/dist/lib/epl/projectFileReader.js +2 -0
  337. package/dist/lib/epl/projectFileReader.js.map +1 -0
  338. package/dist/lib/fb2.js +2 -0
  339. package/dist/lib/fb2.js.map +1 -0
  340. package/dist/lib/fileType.js +2 -0
  341. package/dist/lib/fileType.js.map +1 -0
  342. package/dist/lib/fonts.js +2 -0
  343. package/dist/lib/fonts.js.map +1 -0
  344. package/dist/lib/format.js +2 -0
  345. package/dist/lib/format.js.map +1 -0
  346. package/dist/lib/frontmatter.js +2 -0
  347. package/dist/lib/frontmatter.js.map +1 -0
  348. package/dist/lib/geo.js +2 -0
  349. package/dist/lib/geo.js.map +1 -0
  350. package/dist/lib/har.js +2 -0
  351. package/dist/lib/har.js.map +1 -0
  352. package/dist/lib/highlight.js +2 -0
  353. package/dist/lib/highlight.js.map +1 -0
  354. package/dist/lib/highlightLangs.js +2 -0
  355. package/dist/lib/highlightLangs.js.map +1 -0
  356. package/dist/lib/hprof.js +2 -0
  357. package/dist/lib/hprof.js.map +1 -0
  358. package/dist/lib/ipynb.js +2 -0
  359. package/dist/lib/ipynb.js.map +1 -0
  360. package/dist/lib/jks.js +2 -0
  361. package/dist/lib/jks.js.map +1 -0
  362. package/dist/lib/jsonl.js +2 -0
  363. package/dist/lib/jsonl.js.map +1 -0
  364. package/dist/lib/lrc.js +2 -0
  365. package/dist/lib/lrc.js.map +1 -0
  366. package/dist/lib/lzma.js +2 -0
  367. package/dist/lib/lzma.js.map +1 -0
  368. package/dist/lib/markdown/blocks.js +2 -0
  369. package/dist/lib/markdown/blocks.js.map +1 -0
  370. package/dist/lib/markdown/inline.js +2 -0
  371. package/dist/lib/markdown/inline.js.map +1 -0
  372. package/dist/lib/markdown/math.js +2 -0
  373. package/dist/lib/markdown/math.js.map +1 -0
  374. package/dist/lib/markdown/segmentize.js +2 -0
  375. package/dist/lib/markdown/segmentize.js.map +1 -0
  376. package/dist/lib/markdown/styles.js +2 -0
  377. package/dist/lib/markdown/styles.js.map +1 -0
  378. package/dist/lib/mht.js +2 -0
  379. package/dist/lib/mht.js.map +1 -0
  380. package/dist/lib/midi.js +2 -0
  381. package/dist/lib/midi.js.map +1 -0
  382. package/dist/lib/mime.js +2 -0
  383. package/dist/lib/mime.js.map +1 -0
  384. package/dist/lib/mindmap.js +2 -0
  385. package/dist/lib/mindmap.js.map +1 -0
  386. package/dist/lib/mobi.js +2 -0
  387. package/dist/lib/mobi.js.map +1 -0
  388. package/dist/lib/msi.js +2 -0
  389. package/dist/lib/msi.js.map +1 -0
  390. package/dist/lib/optionalDep.js +2 -0
  391. package/dist/lib/optionalDep.js.map +1 -0
  392. package/dist/lib/pdfNavigation.d.ts +11 -0
  393. package/dist/lib/pdfNavigation.js +32 -0
  394. package/dist/lib/pdfNavigation.js.map +1 -0
  395. package/dist/lib/pkcs12.js +2 -0
  396. package/dist/lib/pkcs12.js.map +1 -0
  397. package/dist/lib/pptxNavigation.js +2 -0
  398. package/dist/lib/pptxNavigation.js.map +1 -0
  399. package/dist/lib/qmc.js +2 -0
  400. package/dist/lib/qmc.js.map +1 -0
  401. package/dist/lib/rar.js +2 -0
  402. package/dist/lib/rar.js.map +1 -0
  403. package/dist/lib/rawPreview.js +2 -0
  404. package/dist/lib/rawPreview.js.map +1 -0
  405. package/dist/lib/rc2.js +2 -0
  406. package/dist/lib/rc2.js.map +1 -0
  407. package/dist/lib/resolveInput.js +2 -0
  408. package/dist/lib/resolveInput.js.map +1 -0
  409. package/dist/lib/rtf.js +2 -0
  410. package/dist/lib/rtf.js.map +1 -0
  411. package/dist/lib/sevenZip.js +2 -0
  412. package/dist/lib/sevenZip.js.map +1 -0
  413. package/dist/lib/sha1.js +2 -0
  414. package/dist/lib/sha1.js.map +1 -0
  415. package/dist/lib/sha256.js +2 -0
  416. package/dist/lib/sha256.js.map +1 -0
  417. package/dist/lib/speechAudio.js +2 -0
  418. package/dist/lib/speechAudio.js.map +1 -0
  419. package/dist/lib/sqlite.js +2 -0
  420. package/dist/lib/sqlite.js.map +1 -0
  421. package/dist/lib/subtitle.js +2 -0
  422. package/dist/lib/subtitle.js.map +1 -0
  423. package/dist/lib/tarball.js +2 -0
  424. package/dist/lib/tarball.js.map +1 -0
  425. package/dist/lib/viewerFormats.js +2 -0
  426. package/dist/lib/viewerFormats.js.map +1 -0
  427. package/dist/lib/viewerKind.js +2 -0
  428. package/dist/lib/viewerKind.js.map +1 -0
  429. package/dist/lib/x509.js +2 -0
  430. package/dist/lib/x509.js.map +1 -0
  431. package/dist/lib/xlsx.js +2 -0
  432. package/dist/lib/xlsx.js.map +1 -0
  433. package/dist/lib/xlsxCharts.js +2 -0
  434. package/dist/lib/xlsxCharts.js.map +1 -0
  435. package/dist/lib/xmind.js +2 -0
  436. package/dist/lib/xmind.js.map +1 -0
  437. package/dist/lib/zip.js +2 -0
  438. package/dist/lib/zip.js.map +1 -0
  439. package/dist/style.css +1 -1
  440. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binobj.js","names":[],"sources":["../../src/lib/binobj.ts"],"sourcesContent":["/**\n * Minimal in-browser ELF / PE symbol reader — no dependency, no WASM.\n *\n * Parses just enough of the container to list its *function symbols* — name, virtual address, and\n * (when the table records it) size. Mirrors {@link lib/zip.ts}: hand-rolled structural parsing over a\n * DataView, decoding only what conversation artifacts actually ship — `.so` shared objects (ELF) and\n * `.dll` libraries (PE). It deliberately does NOT disassemble: turning machine code into mnemonics\n * needs a real engine (Capstone/WASM), which is out of scope for this \"what functions are in here?\" view.\n *\n * - ELF: walks the section table and reads `.symtab` (full symbols) or, when stripped, `.dynsym`\n * (dynamic/exported symbols only), keeping the `STT_FUNC`/`STT_GNU_IFUNC` entries that are\n * defined in this object (not undefined imports).\n * - PE: reads the export directory — the only symbols a DLL normally carries without a separate PDB.\n *\n * Beyond symbols it also lifts human-facing METADATA (see {@link BinMeta}):\n * - ELF: header type/ABI/entry, the program interpreter (PT_INTERP), and the dynamic section's SONAME /\n * NEEDED libraries / RPATH-RUNPATH, plus the GNU build-id note.\n * - PE: the COFF/optional-header subsystem + kind + link time, and — parsed from the resource directory —\n * the VS_VERSIONINFO strings (company / product / version / copyright …) and the embedded ICON, which\n * is repackaged into a tiny .ico and surfaced as a data URL for inline display.\n *\n * Used by BinObjBrowser (the side viewer's binary-object mode): the bytes come from the same download\n * endpoint as any other file, are parsed entirely client-side, and never leave the browser.\n */\n\nexport type BinObjFormat = 'elf' | 'pe'\n\n/** A human-facing metadata row (label + value) shown above the symbol list. */\nexport interface BinMeta {\n label: string\n value: string\n}\n\nexport interface BinSymbol {\n /** Symbol name as stored — NOT demangled (C++ names stay mangled, e.g. `_ZN3foo3barEv`). */\n name: string\n /** Virtual address (ELF `st_value`) or RVA (PE export). For a PIC `.so` this is a load-base offset. */\n address: number\n /** Size in bytes when the table records it (ELF `st_size`); undefined for PE exports. */\n size?: number\n /** Symbol kind: ELF type lowercased (`func` / `ifunc`), or `export` for PE. */\n kind: string\n /** ELF binding (`local` / `global` / `weak`); undefined for PE. */\n bind?: string\n /** Where it came from: `.symtab` / `.dynsym` (ELF) or `export` (PE). */\n source: string\n /** PE export ordinal (Base + index), when applicable. */\n ordinal?: number\n}\n\nexport interface BinObjInfo {\n format: BinObjFormat\n /** Human architecture label, e.g. `x86-64`, `aarch64`, `i386`, `arm`. */\n arch: string\n bits: 32 | 64\n endian: 'le' | 'be'\n /** True when no full symbol table was available (ELF: only `.dynsym`; PE: always — exports only). */\n stripped: boolean\n /** Defined function symbols, sorted by address. */\n symbols: BinSymbol[]\n /** Human note explaining an empty/partial list (e.g. fully stripped, or a PE with no exports). */\n note?: string\n /** Human-facing metadata rows (ELF header/dynamic, PE version-info), shown as a card above the symbols. */\n meta: BinMeta[]\n /** PE icon repackaged as a tiny .ico and encoded as a data URL, when an icon resource was decoded. */\n iconDataUrl?: string\n}\n\n/** Thrown when the bytes aren't a recognized ELF or PE container. */\nexport class UnsupportedBinaryError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'UnsupportedBinaryError'\n }\n}\n\n// ── ELF constants ───────────────────────────────────────────────────────────────────────────────\nconst SHT_SYMTAB = 2\nconst SHT_DYNSYM = 11\nconst STT_FUNC = 2\nconst STT_GNU_IFUNC = 10\nconst SHN_UNDEF = 0\n\n// e_machine → label (only the families likely to show up as conversation artifacts; others fall back).\nconst ELF_MACHINE: Record<number, string> = {\n 0x02: 'sparc',\n 0x03: 'i386',\n 0x08: 'mips',\n 0x14: 'ppc',\n 0x15: 'ppc64',\n 0x16: 's390',\n 0x28: 'arm',\n 0x2a: 'sh',\n 0x32: 'ia-64',\n 0x3e: 'x86-64',\n 0xb7: 'aarch64',\n 0xf3: 'riscv',\n}\n\n// PE Machine → label.\nconst PE_MACHINE: Record<number, string> = {\n 0x014c: 'i386',\n 0x0166: 'mips',\n 0x01c0: 'arm',\n 0x01c4: 'arm-thumb2',\n 0x0200: 'ia-64',\n 0x5064: 'riscv64',\n 0x8664: 'x86-64',\n 0xaa64: 'aarch64',\n}\n\nconst ELF_BIND: Record<number, string> = { 0: 'local', 1: 'global', 2: 'weak' }\nconst ELF_TYPE: Record<number, string> = { [STT_FUNC]: 'func', [STT_GNU_IFUNC]: 'ifunc' }\n\n// ELF metadata constants.\nconst SHT_DYNAMIC = 6\nconst PT_INTERP = 3\nconst PT_NOTE = 4\nconst DT_NULL = 0\nconst DT_NEEDED = 1\nconst DT_SONAME = 14\nconst DT_RPATH = 15\nconst DT_RUNPATH = 29\nconst NT_GNU_BUILD_ID = 3\nconst ELF_ET: Record<number, string> = {\n 1: '可重定位 (REL)',\n 2: '可执行 (EXEC)',\n 3: '共享对象 (DYN/PIE)',\n 4: '核心转储 (CORE)',\n}\nconst ELF_OSABI: Record<number, string> = {\n 0: 'System V',\n 1: 'HP-UX',\n 2: 'NetBSD',\n 3: 'Linux',\n 6: 'Solaris',\n 7: 'AIX',\n 9: 'FreeBSD',\n 12: 'OpenBSD',\n}\n\n// PE metadata constants.\nconst PE_SUBSYSTEM: Record<number, string> = {\n 1: 'Native',\n 2: 'Windows GUI',\n 3: 'Windows 控制台',\n 5: 'OS/2 控制台',\n 7: 'POSIX 控制台',\n 9: 'Windows CE GUI',\n 10: 'EFI 应用',\n 11: 'EFI 启动驱动',\n 12: 'EFI 运行时驱动',\n 13: 'EFI ROM',\n 14: 'Xbox',\n}\nconst RT_ICON = 3\nconst RT_GROUP_ICON = 14\nconst RT_VERSION = 16\n// VS_VERSIONINFO string keys → Chinese labels (unknown keys are shown verbatim).\nconst PE_VERSION_LABELS: Record<string, string> = {\n CompanyName: '公司',\n FileDescription: '描述',\n FileVersion: '文件版本',\n InternalName: '内部名称',\n LegalCopyright: '版权',\n OriginalFilename: '原始文件名',\n ProductName: '产品',\n ProductVersion: '产品版本',\n Comments: '备注',\n LegalTrademarks: '商标',\n}\n\n/**\n * Bounds-checked little/big-endian reader over the file bytes. Reads that fall outside the buffer throw\n * (DataView's own RangeError) and are caught by the caller — a truncated/corrupt file surfaces as an\n * error rather than silently mis-parsed garbage. 64-bit fields are returned as Number (addresses/offsets\n * in real shared libraries sit far below 2^53; precision loss isn't a practical concern here).\n */\nclass Reader {\n private dv: DataView\n constructor(\n readonly buf: ArrayBuffer,\n readonly le: boolean,\n ) {\n this.dv = new DataView(buf)\n }\n get length(): number {\n return this.dv.byteLength\n }\n u8(off: number): number {\n return this.dv.getUint8(off)\n }\n u16(off: number): number {\n return this.dv.getUint16(off, this.le)\n }\n u32(off: number): number {\n return this.dv.getUint32(off, this.le)\n }\n u64(off: number): number {\n return Number(this.dv.getBigUint64(off, this.le))\n }\n /** NUL-terminated UTF-8 string at an absolute file offset (empty if the offset is out of range). */\n str(off: number): string {\n if (off < 0 || off >= this.length) return ''\n let end = off\n while (end < this.length && this.dv.getUint8(end) !== 0) end++\n return new TextDecoder('utf-8').decode(new Uint8Array(this.buf, off, end - off))\n }\n /** Copy `len` bytes at `off` into a fresh Uint8Array (clamped to the buffer; empty if out of range). */\n slice(off: number, len: number): Uint8Array {\n if (off < 0 || off >= this.length || len <= 0) return new Uint8Array(0)\n const end = Math.min(this.length, off + len)\n return new Uint8Array(this.buf.slice(off, end))\n }\n /** NUL-terminated UTF-16LE string starting at `off`, reading at most `maxBytes` (for PE resource keys). */\n utf16(off: number, maxBytes: number): string {\n const end = Math.min(this.length, off + maxBytes)\n let s = ''\n for (let p = off; p + 1 < end; p += 2) {\n const c = this.dv.getUint16(p, true)\n if (c === 0) break\n s += String.fromCharCode(c)\n }\n return s\n }\n}\n\n/** Recognize the container by magic and dispatch. Throws {@link UnsupportedBinaryError} otherwise. */\nexport function parseBinObj(buf: ArrayBuffer): BinObjInfo {\n if (buf.byteLength < 64) throw new UnsupportedBinaryError('文件过小,不是有效的 ELF/PE')\n const dv = new DataView(buf)\n // ELF: 0x7F 'E' 'L' 'F'\n if (dv.getUint32(0, false) === 0x7f454c46) return parseElf(buf)\n // PE: starts with DOS 'MZ' (0x4D 0x5A), real header at e_lfanew.\n if (dv.getUint8(0) === 0x4d && dv.getUint8(1) === 0x5a) return parsePe(buf)\n throw new UnsupportedBinaryError('无法识别的二进制格式(既不是 ELF 也不是 PE)')\n}\n\n// ── ELF ───────────────────────────────────────────────────────────────────────────────────────\nfunction parseElf(buf: ArrayBuffer): BinObjInfo {\n const ident = new DataView(buf)\n const eiClass = ident.getUint8(4) // 1 = 32-bit, 2 = 64-bit\n const eiData = ident.getUint8(5) // 1 = little-endian, 2 = big-endian\n if (eiClass !== 1 && eiClass !== 2) throw new UnsupportedBinaryError('未知 ELF 位宽')\n const bits: 32 | 64 = eiClass === 2 ? 64 : 32\n const le = eiData !== 2\n const r = new Reader(buf, le)\n\n const machine = r.u16(18)\n const arch = ELF_MACHINE[machine] ?? `0x${machine.toString(16)}`\n\n // Section header table location (offsets differ by class).\n const shoff = bits === 64 ? r.u64(40) : r.u32(32)\n const shentsize = r.u16(bits === 64 ? 58 : 46)\n const shnum = r.u16(bits === 64 ? 60 : 48)\n\n const base = (i: number) => shoff + i * shentsize\n interface Section {\n type: number\n offset: number\n size: number\n link: number\n entsize: number\n }\n const sections: Section[] = []\n for (let i = 0; i < shnum; i++) {\n const o = base(i)\n sections.push({\n type: r.u32(o + 4),\n offset: bits === 64 ? r.u64(o + 24) : r.u32(o + 16),\n size: bits === 64 ? r.u64(o + 32) : r.u32(o + 20),\n link: r.u32(o + (bits === 64 ? 40 : 24)),\n entsize: bits === 64 ? r.u64(o + 56) : r.u32(o + 36),\n })\n }\n\n // Prefer the full .symtab; fall back to .dynsym (exports only) — that fallback means \"stripped\".\n const symtab = sections.find((s) => s.type === SHT_SYMTAB)\n const dynsym = sections.find((s) => s.type === SHT_DYNSYM)\n const table = symtab ?? dynsym\n const stripped = !symtab\n // Metadata is best-effort: never let a malformed header/dynamic section abort the symbol listing.\n let meta: BinMeta[] = []\n try {\n meta = elfMeta(r, bits, sections)\n } catch {\n /* metadata unavailable — keep the symbols */\n }\n const info: BinObjInfo = {\n format: 'elf',\n arch,\n bits,\n endian: le ? 'le' : 'be',\n stripped,\n symbols: [],\n meta,\n }\n if (!table) {\n info.note = '未找到符号表(.symtab/.dynsym 均缺失,文件被完全剥离)'\n return info\n }\n const strtab = sections[table.link]\n if (!strtab) {\n info.note = '符号表缺少关联的字符串表'\n return info\n }\n\n const symSize = table.entsize || (bits === 64 ? 24 : 16)\n const count = Math.floor(table.size / symSize)\n const symbols: BinSymbol[] = []\n for (let i = 0; i < count; i++) {\n const o = table.offset + i * symSize\n let stName: number, stInfo: number, stShndx: number, stValue: number, stSize: number\n if (bits === 64) {\n stName = r.u32(o)\n stInfo = r.u8(o + 4)\n stShndx = r.u16(o + 6)\n stValue = r.u64(o + 8)\n stSize = r.u64(o + 16)\n } else {\n stName = r.u32(o)\n stValue = r.u32(o + 4)\n stSize = r.u32(o + 8)\n stInfo = r.u8(o + 12)\n stShndx = r.u16(o + 14)\n }\n const type = stInfo & 0xf\n if (type !== STT_FUNC && type !== STT_GNU_IFUNC) continue\n if (stShndx === SHN_UNDEF) continue // undefined import, not defined in this object\n if (stName === 0) continue\n const name = r.str(strtab.offset + stName)\n if (!name) continue\n symbols.push({\n name,\n address: stValue,\n size: stSize || undefined,\n kind: ELF_TYPE[type] ?? 'func',\n bind: ELF_BIND[stInfo >> 4],\n source: symtab ? '.symtab' : '.dynsym',\n })\n }\n symbols.sort((a, b) => a.address - b.address || a.name.localeCompare(b.name))\n info.symbols = symbols\n if (!symbols.length) info.note = stripped ? '动态符号表中没有已定义的函数' : '未找到函数符号'\n return info\n}\n\n// ── ELF metadata (header / interpreter / dynamic / build-id) ─────────────────────────────────────\ninterface ElfSectionRef {\n type: number\n offset: number\n size: number\n link: number\n entsize: number\n}\nconst align4 = (n: number): number => (n + 3) & ~3\n\nfunction elfMeta(r: Reader, bits: 32 | 64, sections: ElfSectionRef[]): BinMeta[] {\n const eType = r.u16(16)\n const osabi = r.u8(7)\n const entry = bits === 64 ? r.u64(24) : r.u32(24)\n\n // Program headers → PT_INTERP (the dynamic linker) and PT_NOTE (the GNU build-id).\n const phoff = bits === 64 ? r.u64(32) : r.u32(28)\n const phentsize = r.u16(bits === 64 ? 54 : 42)\n const phnum = r.u16(bits === 64 ? 56 : 44)\n let interp = ''\n let buildId = ''\n if (phoff && phnum && phentsize >= (bits === 64 ? 56 : 32)) {\n for (let i = 0; i < phnum; i++) {\n const o = phoff + i * phentsize\n const pType = r.u32(o)\n const pOff = bits === 64 ? r.u64(o + 8) : r.u32(o + 4)\n if (pType === PT_INTERP) {\n interp = r.str(pOff).trim()\n } else if (pType === PT_NOTE && !buildId) {\n const pSz = bits === 64 ? r.u64(o + 32) : r.u32(o + 16)\n buildId = elfBuildId(r, pOff, pSz)\n }\n }\n }\n\n // Dynamic section → SONAME / NEEDED / RPATH (names live in the linked .dynstr string table).\n let soname = ''\n let rpath = ''\n const needed: string[] = []\n const dyn = sections.find((s) => s.type === SHT_DYNAMIC)\n if (dyn) {\n const dynstr = sections[dyn.link]\n const strBase = dynstr ? dynstr.offset : 0\n const esz = dyn.entsize || (bits === 64 ? 16 : 8)\n const count = Math.floor(dyn.size / esz)\n for (let i = 0; i < count; i++) {\n const o = dyn.offset + i * esz\n const tag = bits === 64 ? r.u64(o) : r.u32(o)\n const val = bits === 64 ? r.u64(o + 8) : r.u32(o + 4)\n if (tag === DT_NULL) break\n if (tag === DT_NEEDED) {\n const n = r.str(strBase + val)\n if (n) needed.push(n)\n } else if (tag === DT_SONAME) {\n soname = r.str(strBase + val)\n } else if (tag === DT_RPATH || tag === DT_RUNPATH) {\n rpath = r.str(strBase + val)\n }\n }\n }\n\n const meta: BinMeta[] = [\n { label: '类型', value: ELF_ET[eType] ?? `0x${eType.toString(16)}` },\n { label: 'ABI', value: ELF_OSABI[osabi] ?? `0x${osabi.toString(16)}` },\n { label: '入口', value: `0x${entry.toString(16)}` },\n ]\n if (interp) meta.push({ label: '解释器', value: interp })\n if (soname) meta.push({ label: 'SONAME', value: soname })\n if (needed.length) meta.push({ label: `依赖 (${needed.length})`, value: needed.join(', ') })\n if (rpath) meta.push({ label: 'RPATH', value: rpath })\n if (buildId) meta.push({ label: '构建 ID', value: buildId })\n return meta\n}\n\n// Scan a PT_NOTE segment for the NT_GNU_BUILD_ID note (owner \"GNU\"); returns its hex digest or ''.\nfunction elfBuildId(r: Reader, off: number, size: number): string {\n let p = off\n const end = off + size\n while (p + 12 <= end) {\n const namesz = r.u32(p)\n const descsz = r.u32(p + 4)\n const ntype = r.u32(p + 8)\n const name = namesz ? r.str(p + 12) : ''\n const descOff = p + 12 + align4(namesz)\n if (ntype === NT_GNU_BUILD_ID && name === 'GNU' && descsz > 0) {\n return Array.from(r.slice(descOff, descsz))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n }\n const next = descOff + align4(descsz)\n if (next <= p) break\n p = next\n }\n return ''\n}\n\n// ── PE ──────────────────────────────────────────────────────────────────────────────────────────\nfunction parsePe(buf: ArrayBuffer): BinObjInfo {\n const r = new Reader(buf, true) // PE is always little-endian\n const peOff = r.u32(0x3c) // e_lfanew\n if (r.u32(peOff) !== 0x00004550) throw new UnsupportedBinaryError('缺少 PE 签名') // 'PE\\0\\0'\n\n const coff = peOff + 4\n const machine = r.u16(coff)\n const arch = PE_MACHINE[machine] ?? `0x${machine.toString(16)}`\n const numSections = r.u16(coff + 2)\n const timeStamp = r.u32(coff + 8)\n const characteristics = r.u16(coff + 18)\n const optSize = r.u16(coff + 16)\n const opt = coff + 20\n\n const magic = r.u16(opt) // 0x10b = PE32, 0x20b = PE32+\n const bits: 32 | 64 = magic === 0x20b ? 64 : 32\n const info: BinObjInfo = {\n format: 'pe',\n arch,\n bits,\n endian: 'le',\n stripped: true, // a PE without a PDB exposes only its export table\n symbols: [],\n meta: [],\n }\n if (optSize === 0) {\n info.note = '该 PE 无可选头'\n return info\n }\n\n // Section table → RVA-to-file-offset map (shared by the resource + export parsers below).\n const secs: { va: number; vsize: number; raw: number; rawSize: number }[] = []\n const secBase = opt + optSize\n for (let i = 0; i < numSections; i++) {\n const o = secBase + i * 40\n secs.push({\n vsize: r.u32(o + 8),\n va: r.u32(o + 12),\n rawSize: r.u32(o + 16),\n raw: r.u32(o + 20),\n })\n }\n const toOffset = (rva: number): number | null => {\n for (const s of secs) {\n const span = Math.max(s.vsize, s.rawSize)\n if (rva >= s.va && rva < s.va + span) return rva - s.va + s.raw\n }\n return null\n }\n\n // ── header metadata ──\n info.meta.push({\n label: '类型',\n value: characteristics & 0x2000 ? '动态链接库 (DLL)' : '可执行文件 (EXE)',\n })\n const subsystem = r.u16(opt + 68) // same offset for PE32 / PE32+ (fields align after SectionAlignment@32)\n info.meta.push({\n label: '子系统',\n value: PE_SUBSYSTEM[subsystem] ?? `0x${subsystem.toString(16)}`,\n })\n info.meta.push({ label: '入口', value: `0x${r.u32(opt + 16).toString(16)}` })\n const imageBase = bits === 64 ? r.u64(opt + 24) : r.u32(opt + 28)\n info.meta.push({ label: '镜像基址', value: `0x${imageBase.toString(16)}` })\n if (timeStamp > 0 && timeStamp < 0xffffffff) {\n info.meta.push({ label: '链接时间', value: peTime(timeStamp) })\n }\n\n // ── version-info + icon (from the resource directory = data directory[2]) ──\n const dataDir = opt + (bits === 64 ? 112 : 96)\n const resBase = (() => {\n const rva = r.u32(dataDir + 16)\n return rva ? toOffset(rva) : null\n })()\n if (resBase != null) {\n try {\n for (const [k, v] of peVersionInfo(r, resBase, toOffset)) {\n info.meta.push({ label: PE_VERSION_LABELS[k] ?? k, value: v })\n }\n } catch {\n /* malformed version resource — skip */\n }\n try {\n const icon = peIcon(r, resBase, toOffset)\n if (icon) info.iconDataUrl = icon\n } catch {\n /* malformed icon resource — skip */\n }\n }\n\n // ── exports (data directory[0]) ──\n const exportRva = r.u32(dataDir)\n if (!exportRva) {\n info.note = '该 PE 没有导出表(无导出函数)'\n return info\n }\n const expOff = toOffset(exportRva)\n if (expOff == null) {\n info.note = '导出表 RVA 无法定位'\n return info\n }\n const ordinalBase = r.u32(expOff + 16)\n const numNames = r.u32(expOff + 24)\n const addrFuncs = toOffset(r.u32(expOff + 28))\n const addrNames = toOffset(r.u32(expOff + 32))\n const addrOrdinals = toOffset(r.u32(expOff + 36))\n if (addrFuncs == null || addrNames == null || addrOrdinals == null) {\n info.note = '导出表结构无法定位'\n return info\n }\n\n const symbols: BinSymbol[] = []\n for (let i = 0; i < numNames; i++) {\n const nameRva = r.u32(addrNames + i * 4)\n const nameOff = toOffset(nameRva)\n const name = nameOff != null ? r.str(nameOff) : ''\n if (!name) continue\n const idx = r.u16(addrOrdinals + i * 2) // unbiased index into the EAT\n const funcRva = r.u32(addrFuncs + idx * 4)\n symbols.push({\n name,\n address: funcRva,\n kind: 'export',\n source: 'export',\n ordinal: ordinalBase + idx,\n })\n }\n symbols.sort((a, b) => a.address - b.address || a.name.localeCompare(b.name))\n info.symbols = symbols\n if (!symbols.length && !info.note) info.note = '导出表中没有具名函数'\n return info\n}\n\n// PE TimeDateStamp (epoch seconds) → \"YYYY-MM-DD\" UTC. (Reproducible builds may store a hash, not a date.)\nfunction peTime(ts: number): string {\n return new Date(ts * 1000).toISOString().slice(0, 10)\n}\n\ntype ToOffset = (rva: number) => number | null\ninterface ResEntry {\n id: number\n named: boolean\n isDir: boolean\n offset: number // relative to the resource section base\n}\n// Entries of one IMAGE_RESOURCE_DIRECTORY at `dirOff` (absolute file offset).\nfunction resEntries(r: Reader, dirOff: number): ResEntry[] {\n const named = r.u16(dirOff + 12)\n const ids = r.u16(dirOff + 14)\n const out: ResEntry[] = []\n for (let i = 0; i < named + ids; i++) {\n const e = dirOff + 16 + i * 8\n const nameField = r.u32(e)\n const offField = r.u32(e + 4)\n out.push({\n id: nameField & 0x7fffffff,\n named: (nameField & 0x80000000) !== 0,\n isDir: (offField & 0x80000000) !== 0,\n offset: offField & 0x7fffffff,\n })\n }\n return out\n}\n// Read an IMAGE_RESOURCE_DATA_ENTRY (OffsetToData is an RVA) → its file offset + size.\nfunction resData(\n r: Reader,\n entryOff: number,\n toOffset: ToOffset,\n): { off: number; size: number } | null {\n const fo = toOffset(r.u32(entryOff))\n if (fo == null) return null\n return { off: fo, size: r.u32(entryOff + 4) }\n}\n// Walk Type → (matching id, or first) → first language → data entry, for a resource type.\nfunction findResource(\n r: Reader,\n resBase: number,\n typeId: number,\n wantId: number | null,\n toOffset: ToOffset,\n): { off: number; size: number } | null {\n const t = resEntries(r, resBase).find((e) => !e.named && e.id === typeId && e.isDir)\n if (!t) return null\n const names = resEntries(r, resBase + t.offset)\n const n = wantId == null ? names[0] : names.find((e) => !e.named && e.id === wantId)\n if (!n) return null\n let dataEntryOff = resBase + n.offset\n if (n.isDir) {\n const lang = resEntries(r, resBase + n.offset)[0]\n if (!lang || lang.isDir) return null\n dataEntryOff = resBase + lang.offset\n }\n return resData(r, dataEntryOff, toOffset)\n}\n\n// VS_VERSIONINFO string table → [key, value] pairs (CompanyName, ProductName, FileVersion, …).\nfunction peVersionInfo(r: Reader, resBase: number, toOffset: ToOffset): [string, string][] {\n const data = findResource(r, resBase, RT_VERSION, null, toOffset)\n if (!data) return []\n return parseVersionInfo(r, data.off, data.size)\n}\n\n// Read one VS_VERSIONINFO node header at `p`: key, value span, and where its children begin.\nfunction versionNode(\n r: Reader,\n p: number,\n): {\n key: string\n length: number\n valOff: number\n valLen: number\n wType: number\n childOff: number\n} {\n const length = r.u16(p)\n const valueLen = r.u16(p + 2)\n const wType = r.u16(p + 4)\n const key = r.utf16(p + 6, 512)\n const valOff = align4(p + 6 + (key.length + 1) * 2)\n const valLen = wType === 1 ? valueLen * 2 : valueLen // text values count WCHARs, binary counts bytes\n return { key, length, valOff, valLen, wType, childOff: align4(valOff + valLen) }\n}\n\nfunction parseVersionInfo(r: Reader, base: number, size: number): [string, string][] {\n const out: [string, string][] = []\n const end = base + size\n const root = versionNode(r, base)\n if (root.key !== 'VS_VERSION_INFO' || root.length === 0) return out\n const rootEnd = Math.min(end, base + root.length)\n let c = root.childOff\n while (c + 6 <= rootEnd) {\n const block = versionNode(r, c)\n if (block.length === 0) break\n if (block.key === 'StringFileInfo') {\n const sfiEnd = Math.min(rootEnd, c + block.length)\n let st = block.childOff\n while (st + 6 <= sfiEnd) {\n const table = versionNode(r, st)\n if (table.length === 0) break\n const tEnd = Math.min(sfiEnd, st + table.length)\n let s = table.childOff\n while (s + 6 <= tEnd) {\n const str = versionNode(r, s)\n if (str.length === 0) break\n const value = str.wType === 1 ? r.utf16(str.valOff, str.valLen + 2).trim() : ''\n if (str.key && value) out.push([str.key, value])\n s = align4(s + str.length)\n }\n st = align4(st + table.length)\n }\n break // the first StringFileInfo (one language) is enough for a summary\n }\n c = align4(c + block.length)\n }\n return out\n}\n\n// Decode the embedded application icon: pick the best entry from the RT_GROUP_ICON directory, find its RT_ICON\n// image, and repackage it as a one-image .ico (the RT_ICON payload — PNG or DIB — drops straight into the .ico\n// image slot), returned as a data URL for inline <img> display.\nfunction peIcon(r: Reader, resBase: number, toOffset: ToOffset): string | null {\n const group = findResource(r, resBase, RT_GROUP_ICON, null, toOffset)\n if (!group) return null\n const count = r.u16(group.off + 4)\n if (!count) return null\n let bestEntry = -1\n let bestScore = -1\n for (let i = 0; i < count; i++) {\n const e = group.off + 6 + i * 14\n const w = r.u8(e) || 256\n const h = r.u8(e + 1) || 256\n const score = w * h * 1000 + r.u16(e + 6) // area, tie-broken by bit depth\n if (score > bestScore) {\n bestScore = score\n bestEntry = i\n }\n }\n if (bestEntry < 0) return null\n const be = group.off + 6 + bestEntry * 14\n const entry = {\n w: r.u8(be),\n h: r.u8(be + 1),\n colorCount: r.u8(be + 2),\n planes: r.u16(be + 4),\n bitCount: r.u16(be + 6),\n bytesInRes: r.u32(be + 8),\n iconId: r.u16(be + 12),\n }\n const iconData = findResource(r, resBase, RT_ICON, entry.iconId, toOffset)\n if (!iconData) return null\n const img = r.slice(iconData.off, Math.min(iconData.size, entry.bytesInRes || iconData.size))\n if (!img.length) return null\n // A modern RT_ICON payload is often a PNG (esp. for 256px+ icons). The .ico container's width/height\n // fields are single bytes (max 256), so a 512×512 PNG wrapped in an .ico renders BLANK in browsers\n // (Chrome rejects PNG-in-.ico above 256px). Serve a PNG payload directly as a raw PNG data URL — no\n // size limit, decoded natively. Only the legacy DIB payloads need the .ico wrapper to be interpretable.\n const isPng =\n img.length > 8 && img[0] === 0x89 && img[1] === 0x50 && img[2] === 0x4e && img[3] === 0x47\n if (isPng) return `data:image/png;base64,${bytesToBase64(img)}`\n return `data:image/x-icon;base64,${bytesToBase64(buildIco(entry, img))}`\n}\n\n// Wrap a single icon image (RT_ICON payload) in a minimal .ico container.\nfunction buildIco(\n e: { w: number; h: number; colorCount: number; planes: number; bitCount: number },\n img: Uint8Array,\n): Uint8Array {\n const header = 6 + 16\n const out = new Uint8Array(header + img.length)\n const dv = new DataView(out.buffer)\n dv.setUint16(2, 1, true) // type = icon\n dv.setUint16(4, 1, true) // one image\n out[6] = e.w & 0xff\n out[7] = e.h & 0xff\n out[8] = e.colorCount & 0xff\n dv.setUint16(10, e.planes, true)\n dv.setUint16(12, e.bitCount, true)\n dv.setUint32(14, img.length, true)\n dv.setUint32(18, header, true)\n out.set(img, header)\n return out\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n let bin = ''\n const CHUNK = 0x8000\n for (let i = 0; i < bytes.length; i += CHUNK) {\n bin += String.fromCharCode(...bytes.subarray(i, i + CHUNK))\n }\n return btoa(bin)\n}\n"],"mappings":"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"}
@@ -14,3 +14,5 @@ async function a(e) {
14
14
  }
15
15
  //#endregion
16
16
  export { a as brotliDecode };
17
+
18
+ //# sourceMappingURL=brotli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brotli.js","names":[],"sources":["../../src/lib/brotli.ts"],"sourcesContent":["/**\n * In-browser Brotli decompression, wrapping the WASM decoder (brotli-dec-wasm).\n *\n * Browsers ship native gzip/deflate (DecompressionStream) but NOT Brotli, and a faithful Brotli decoder is\n * far too large to hand-roll (it carries a ~120KB static dictionary plus context modeling). So — like rar —\n * this leans on a compiled WASM decoder: brotli-dec-wasm's `web` (wasm-bindgen) build, decode-only, ~250KB.\n * The wasm is fetched as a same-origin asset (Vite emits it via the `?url` import) and instantiated from the\n * fetched bytes (no streaming, so the server's wasm MIME type is irrelevant). Pulled in lazily by\n * {@link lib/tarball} only when a `.br` / `.tar.br` is actually opened.\n *\n * Brotli is a raw stream with no magic bytes, so callers route to it by extension, not by sniffing.\n */\n\nimport init, { decompress } from 'brotli-dec-wasm/web'\n// Vite emits the decoder wasm as a hashed, same-origin asset and gives us its URL.\nimport brotliWasmUrl from 'brotli-dec-wasm/web/bg.wasm?url'\n\nlet ready: Promise<unknown> | null = null\n\n/** Fetch + instantiate the wasm once (cached across calls). */\nfunction ensureReady(): Promise<unknown> {\n if (!ready) {\n ready = (async () => {\n const res = await fetch(brotliWasmUrl)\n if (!res.ok) throw new Error(`无法加载 brotli wasm(HTTP ${res.status})`)\n await init({ module_or_path: await res.arrayBuffer() })\n })()\n }\n return ready\n}\n\n/** Decompress a complete Brotli stream into its raw bytes. */\nexport async function brotliDecode(data: Uint8Array): Promise<Uint8Array> {\n await ensureReady()\n return decompress(data)\n}\n"],"mappings":";;;AAiBA,IAAI,IAAiC;AAGrC,SAAS,IAAgC;CAQvC,OAPA,AACE,OAAS,YAAY;EACnB,IAAM,IAAM,MAAM,MAAM,CAAa;EACrC,IAAI,CAAC,EAAI,IAAI,MAAU,MAAM,yBAAyB,EAAI,OAAO,EAAE;EACnE,MAAM,EAAK,EAAE,gBAAgB,MAAM,EAAI,YAAY,EAAE,CAAC;CACxD,EAAA,CAAG,GAEE;AACT;AAGA,eAAsB,EAAa,GAAuC;CAExE,OADA,MAAM,EAAY,GACX,EAAW,CAAI;AACxB"}
package/dist/lib/bzip2.js CHANGED
@@ -159,3 +159,5 @@ function d(i) {
159
159
  }
160
160
  //#endregion
161
161
  export { d as bzip2Decode };
162
+
163
+ //# sourceMappingURL=bzip2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bzip2.js","names":[],"sources":["../../src/lib/bzip2.ts"],"sourcesContent":["/**\n * Minimal in-browser bzip2 decoder — no dependency, no WASM.\n *\n * Browsers ship a native gzip/deflate inflate (DecompressionStream) but nothing for bzip2's Burrows–Wheeler\n * pipeline, so — like {@link lib/lzma} does for 7z — the tar-family reader ({@link lib/tarball}) carries its\n * own. This is a from-scratch port of the bzip2 block format (the algorithm Julian Seward's reference\n * `bzip2`/libbzip2 implements): a bit reader, canonical-Huffman group tables, the MTF + RLE2 symbol decode,\n * the inverse Burrows–Wheeler transform, and the final RLE1 run expansion.\n *\n * One synchronous entry point, {@link bzip2Decode}, returns the full decompressed bytes. Randomized blocks\n * (a pre-0.9.5 quirk modern bzip2 never emits) and malformed streams are surfaced as errors.\n */\n\nconst BLOCK_MAGIC_HI = 0x314159 // 0x314159265359 (\"pi\"), split into two 24-bit halves for the bit reader\nconst BLOCK_MAGIC_LO = 0x265359\nconst EOS_MAGIC_HI = 0x177245 // 0x177245385090 (\"sqrt pi\") — end of stream\nconst EOS_MAGIC_LO = 0x385090\n\nconst RUNA = 0\nconst RUNB = 1\n\n/** MSB-first bit reader over the packed stream (reads past the end as zero). */\nclass BitReader {\n private pos = 0\n private buf = 0\n private count = 0\n constructor(private readonly data: Uint8Array) {}\n\n bit(): number {\n if (this.count === 0) {\n this.buf = this.pos < this.data.length ? this.data[this.pos++] : 0\n this.count = 8\n }\n this.count--\n return (this.buf >> this.count) & 1\n }\n\n /** Read `n` bits (n ≤ 24 stays within 2^31; callers split wider reads into halves). */\n bits(n: number): number {\n let v = 0\n for (let i = 0; i < n; i++) v = (v << 1) | this.bit()\n return v\n }\n}\n\n// Per-group canonical Huffman decode tables (libbzip2's limit/base/perm scheme).\ninterface HuffTable {\n minLen: number\n maxLen: number\n limit: Int32Array\n base: Int32Array\n perm: Int32Array\n}\n\nfunction buildHuffTable(lengths: Uint8Array, alphaSize: number): HuffTable {\n let minLen = 32\n let maxLen = 0\n for (let i = 0; i < alphaSize; i++) {\n if (lengths[i] > maxLen) maxLen = lengths[i]\n if (lengths[i] < minLen) minLen = lengths[i]\n }\n const perm = new Int32Array(alphaSize)\n let pp = 0\n for (let len = minLen; len <= maxLen; len++) {\n for (let sym = 0; sym < alphaSize; sym++) if (lengths[sym] === len) perm[pp++] = sym\n }\n const base = new Int32Array(maxLen + 2)\n for (let i = 0; i < alphaSize; i++) base[lengths[i] + 1]++\n for (let i = 1; i < base.length; i++) base[i] += base[i - 1]\n const limit = new Int32Array(maxLen + 2)\n let vec = 0\n for (let len = minLen; len <= maxLen; len++) {\n vec += base[len + 1] - base[len]\n limit[len] = vec - 1\n vec <<= 1\n }\n for (let len = minLen + 1; len <= maxLen; len++) {\n base[len] = ((limit[len - 1] + 1) << 1) - base[len]\n }\n return { minLen, maxLen, limit, base, perm }\n}\n\nfunction decodeSym(br: BitReader, t: HuffTable): number {\n let len = t.minLen\n let vec = br.bits(len)\n while (len <= t.maxLen && vec > t.limit[len]) {\n len++\n vec = (vec << 1) | br.bit()\n }\n return t.perm[vec - t.base[len]]\n}\n\n/** Decode one bzip2 block's bytes (after the block magic has been consumed). */\nfunction decodeBlock(br: BitReader, blockSize: number): Uint8Array {\n br.bits(16) // block CRC (high), discarded — we don't verify\n br.bits(16) // block CRC (low)\n if (br.bit() !== 0) throw new Error('不支持随机化的 bzip2 块')\n const origPtr = br.bits(24)\n\n // ── symbol map: which byte values occur in this block ──\n const used16 = br.bits(16)\n const symMap: number[] = []\n for (let i = 0; i < 16; i++) {\n if ((used16 & (0x8000 >> i)) !== 0) {\n const bits16 = br.bits(16)\n for (let j = 0; j < 16; j++) {\n if ((bits16 & (0x8000 >> j)) !== 0) symMap.push(i * 16 + j)\n }\n }\n }\n const numSyms = symMap.length\n if (numSyms === 0) throw new Error('bzip2 块符号表为空')\n const alphaSize = numSyms + 2 // RUNA, RUNB, …syms…, EOB\n const eob = alphaSize - 1\n\n // ── Huffman group selectors (MTF-encoded over group indices) ──\n const numGroups = br.bits(3)\n if (numGroups < 2 || numGroups > 6) throw new Error('bzip2 Huffman 组数非法')\n const numSelectors = br.bits(15)\n const groupPos = new Int32Array(numGroups)\n for (let i = 0; i < numGroups; i++) groupPos[i] = i\n const selectors = new Uint8Array(numSelectors)\n for (let i = 0; i < numSelectors; i++) {\n let j = 0\n while (br.bit() === 1) {\n j++\n if (j >= numGroups) throw new Error('bzip2 选择器越界')\n }\n // move group j to front of the MTF list\n const v = groupPos[j]\n for (let k = j; k > 0; k--) groupPos[k] = groupPos[k - 1]\n groupPos[0] = v\n selectors[i] = v\n }\n\n // ── per-group Huffman code lengths (5-bit start + delta unary) ──\n const tables: HuffTable[] = []\n for (let g = 0; g < numGroups; g++) {\n const lengths = new Uint8Array(alphaSize)\n let len = br.bits(5)\n for (let s = 0; s < alphaSize; s++) {\n for (;;) {\n if (len < 1 || len > 20) throw new Error('bzip2 码长非法')\n if (br.bit() === 0) break\n if (br.bit() === 0) len++\n else len--\n }\n lengths[s] = len\n }\n tables.push(buildHuffTable(lengths, alphaSize))\n }\n\n // ── MTF + RLE2 decode → BWT last column (bytes stored in tt's low 8 bits) ──\n const tt = new Uint32Array(blockSize)\n const unzftab = new Int32Array(256)\n const mtf = symMap.slice() // MTF list of byte values, front = index 0\n let nblock = 0\n let groupNo = -1\n let groupCount = 0\n let table: HuffTable = tables[0]\n const nextSym = (): number => {\n if (groupCount === 0) {\n groupNo++\n if (groupNo >= numSelectors) throw new Error('bzip2 选择器不足')\n groupCount = 50\n table = tables[selectors[groupNo]]\n }\n groupCount--\n return decodeSym(br, table)\n }\n\n let sym = nextSym()\n while (sym !== eob) {\n if (sym === RUNA || sym === RUNB) {\n // run-length of the byte currently at the MTF front, in bijective base-2\n let es = -1\n let N = 1\n do {\n if (sym === RUNA) es += N\n else es += N << 1\n N <<= 1\n sym = nextSym()\n } while (sym === RUNA || sym === RUNB)\n es++\n const b = mtf[0]\n unzftab[b] += es\n if (nblock + es > blockSize) throw new Error('bzip2 块溢出')\n while (es-- > 0) tt[nblock++] = b\n continue\n }\n // sym in 2..eob-1: MTF index (sym-1); fetch that byte value and move it to front\n const idx = sym - 1\n const b = mtf[idx]\n for (let k = idx; k > 0; k--) mtf[k] = mtf[k - 1]\n mtf[0] = b\n unzftab[b]++\n if (nblock >= blockSize) throw new Error('bzip2 块溢出')\n tt[nblock++] = b\n sym = nextSym()\n }\n if (origPtr >= nblock) throw new Error('bzip2 origPtr 越界')\n\n // ── inverse Burrows–Wheeler transform (libbzip2's tt[] pointer walk) ──\n const cftab = new Int32Array(257)\n for (let i = 0; i < 256; i++) cftab[i + 1] = unzftab[i]\n for (let i = 1; i <= 256; i++) cftab[i] += cftab[i - 1]\n for (let i = 0; i < nblock; i++) {\n const b = tt[i] & 0xff\n tt[cftab[b]] |= i << 8\n cftab[b]++\n }\n let tPos = tt[origPtr] >>> 8\n const bwt = new Uint8Array(nblock)\n for (let i = 0; i < nblock; i++) {\n tPos = tt[tPos]\n bwt[i] = tPos & 0xff\n tPos >>>= 8\n }\n\n // ── final RLE1: 4 equal bytes are followed by a count byte of extra repeats ──\n const out = new GrowBuffer(nblock)\n let i = 0\n while (i < nblock) {\n const b = bwt[i]\n let run = 1\n while (i + run < nblock && run < 4 && bwt[i + run] === b) run++\n out.pushRepeat(b, run)\n i += run\n if (run === 4) {\n const extra = bwt[i]\n out.pushRepeat(b, extra)\n i++\n }\n }\n return out.slice()\n}\n\n/** A Uint8Array that doubles its backing store on demand (RLE1 can expand a block beyond its size). */\nclass GrowBuffer {\n private buf: Uint8Array\n private len = 0\n constructor(hint: number) {\n this.buf = new Uint8Array(Math.max(64, hint))\n }\n private ensure(extra: number): void {\n const need = this.len + extra\n if (need <= this.buf.length) return\n let cap = this.buf.length * 2\n while (cap < need) cap *= 2\n const next = new Uint8Array(cap)\n next.set(this.buf.subarray(0, this.len))\n this.buf = next\n }\n pushRepeat(byte: number, count: number): void {\n if (count <= 0) return\n this.ensure(count)\n this.buf.fill(byte, this.len, this.len + count)\n this.len += count\n }\n slice(): Uint8Array {\n return this.buf.slice(0, this.len)\n }\n}\n\n/** Decode a complete bzip2 stream (\"BZh\" + level + one or more blocks) into its raw bytes. */\nexport function bzip2Decode(data: Uint8Array): Uint8Array {\n if (data.length < 4 || data[0] !== 0x42 || data[1] !== 0x5a || data[2] !== 0x68) {\n throw new Error('不是有效的 bzip2 文件')\n }\n const level = data[3] - 0x30\n if (level < 1 || level > 9) throw new Error('bzip2 块大小非法')\n const blockSize = level * 100000\n const br = new BitReader(data.subarray(4))\n\n const blocks: Uint8Array[] = []\n for (;;) {\n const hi = br.bits(24)\n const lo = br.bits(24)\n if (hi === EOS_MAGIC_HI && lo === EOS_MAGIC_LO) break\n if (hi !== BLOCK_MAGIC_HI || lo !== BLOCK_MAGIC_LO) throw new Error('bzip2 块标记损坏')\n blocks.push(decodeBlock(br, blockSize + 10)) // +10: BWT may overshoot the nominal block size slightly\n }\n\n let total = 0\n for (const b of blocks) total += b.length\n const out = new Uint8Array(total)\n let off = 0\n for (const b of blocks) {\n out.set(b, off)\n off += b.length\n }\n return out\n}\n"],"mappings":"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"}
@@ -208,3 +208,5 @@ function r(r) {
208
208
  }
209
209
  //#endregion
210
210
  export { e as NotClassFileError, r as parseClass };
211
+
212
+ //# sourceMappingURL=classfile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classfile.js","names":[],"sources":["../../src/lib/classfile.ts"],"sourcesContent":["/**\n * Minimal in-browser Java `.class` STRUCTURE reader — no dependency, no decompilation.\n *\n * Mirrors {@link lib/binobj.ts}: hand-rolled big-endian parsing over a DataView, reading only the structural\n * tables a `javap`-style listing needs — the constant pool, the field table, and the method table. It does\n * NOT reconstruct method bodies (that's a real decompiler — control-flow recovery, expression rebuilding,\n * out of scope). The whole thing is \"read a few length-prefixed tables and translate type descriptors\".\n *\n * What it surfaces (see {@link ClassInfo}): the class signature (modifiers + kind + this/super/interfaces),\n * the bytecode version, every field (modifiers + type + name), and every method (modifiers + return + params),\n * plus — when the class was compiled with `javac -g` — each method's local variables (from the Code attribute's\n * LocalVariableTable). Faithfully ported from the project's verified reference parser (docs/java class\n * decompile.md), validated byte-for-byte against an OpenJDK 21 compiled class.\n *\n * Used by ClassViewer (the side viewer's `.class` mode): bytes come from the same download endpoint as any\n * other file, are parsed entirely client-side, and never leave the browser.\n */\n\nexport interface ClassField {\n name: string\n /** Human type from the field descriptor (`Ljava/lang/String;` → `String`, `[I` → `int[]`). Generics erased. */\n type: string\n /** Access modifiers in source order: `public`/`private`/`protected`/`static`/`final`/`volatile`/`transient`. */\n flags: string[]\n}\n\nexport interface ClassLocal {\n name: string\n type: string\n /** Local-variable slot index (slot 0 of an instance method is `this`). */\n slot: number\n}\n\nexport interface ClassMethod {\n /** Method name; `<init>` is the constructor, `<clinit>` the static initializer. */\n name: string\n /** Parameter types (descriptor-decoded, generics erased). */\n params: string[]\n /** Return type. */\n ret: string\n flags: string[]\n /** Local variables (from Code/LocalVariableTable, `javac -g` only); null when the table is absent. */\n locals: ClassLocal[] | null\n}\n\nexport type ClassKind = 'class' | 'interface' | 'enum' | '@interface'\n\nexport interface ClassInfo {\n majorVersion: number\n minorVersion: number\n /** `\"major.minor\"` raw bytecode version (e.g. `\"65.0\"`). */\n version: string\n /** Friendly platform label derived from the major version (e.g. `\"Java 21\"`). */\n javaLabel: string\n /** Whether it's a class / interface / enum / annotation (`@interface`). */\n kind: ClassKind\n /** Class-level modifiers that aren't implied by {@link kind} (e.g. `[\"public\", \"final\"]`). */\n modifiers: string[]\n /** Fully-qualified name of this class (`demo.Sample`). */\n thisClass: string | null\n /** Fully-qualified superclass (`java.lang.Object`); null only for `java.lang.Object` itself. */\n superClass: string | null\n /** Fully-qualified implemented interfaces (for an interface: its extended interfaces). */\n interfaces: string[]\n fields: ClassField[]\n methods: ClassMethod[]\n}\n\n/** Thrown when the bytes aren't a Java class file (magic mismatch). */\nexport class NotClassFileError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'NotClassFileError'\n }\n}\n\n// One constant-pool entry. Only Utf8 (`str`) and Class (`nameIndex`) are needed to list fields/methods, but\n// EVERY tag must still be read so the cursor stays aligned (Long/Double notoriously occupy two slots).\ninterface CpEntry {\n tag: number\n str?: string\n nameIndex?: number\n}\n\nconst PRIM: Record<string, string> = {\n B: 'byte',\n C: 'char',\n D: 'double',\n F: 'float',\n I: 'int',\n J: 'long',\n S: 'short',\n Z: 'boolean',\n V: 'void',\n}\n\n// Major bytecode version → platform label. 49+ map linearly (49 = Java 5 … 65 = Java 21); 45-48 are the\n// pre-1.5 `1.x` line. Unknown/future majors fall back to the raw number.\nfunction javaLabel(major: number): string {\n if (major >= 49) return `Java ${major - 44}`\n const legacy: Record<number, string> = {\n 45: 'Java 1.1',\n 46: 'Java 1.2',\n 47: 'Java 1.3',\n 48: 'Java 1.4',\n }\n return legacy[major] ?? `主版本 ${major}`\n}\n\n/**\n * Parse a `.class` file's structure. Input is an ArrayBuffer/Uint8Array of the file bytes. Throws\n * {@link NotClassFileError} on a magic mismatch; a truncated/corrupt file surfaces as a generic RangeError\n * (DataView bounds) for the caller to report.\n */\nexport function parseClass(input: ArrayBuffer | Uint8Array): ClassInfo {\n const u8 = input instanceof Uint8Array ? input : new Uint8Array(input)\n const dv = new DataView(u8.buffer, u8.byteOffset, u8.byteLength)\n let p = 0\n const u1 = (): number => dv.getUint8(p++)\n const u2 = (): number => {\n const v = dv.getUint16(p)\n p += 2\n return v\n }\n const u4 = (): number => {\n const v = dv.getUint32(p)\n p += 4\n return v\n }\n\n if (u8.byteLength < 10 || dv.getUint32(0) !== 0xcafebabe) {\n throw new NotClassFileError('不是有效的 .class 文件(magic 不匹配 0xCAFEBABE)')\n }\n p = 4\n const minor = u2()\n const major = u2()\n\n // ---- Constant pool (1-indexed; count-1 real entries) ----\n const cpCount = u2()\n const cp: (CpEntry | undefined)[] = [] // 1-indexed, sparse (assigned by slot below)\n const dec = new TextDecoder('utf-8')\n for (let i = 1; i < cpCount; i++) {\n const tag = u1()\n switch (tag) {\n case 1: {\n // Utf8\n const len = u2()\n const b = u8.subarray(p, p + len)\n p += len\n cp[i] = { tag, str: dec.decode(b) }\n break\n }\n case 7: // Class → name_index (the only ref we resolve)\n cp[i] = { tag, nameIndex: u2() }\n break\n case 8: // String\n case 16: // MethodType\n case 19: // Module\n case 20: // Package\n cp[i] = { tag }\n u2()\n break\n case 9: // Fieldref\n case 10: // Methodref\n case 11: // InterfaceMethodref\n case 12: // NameAndType\n case 17: // Dynamic\n case 18: // InvokeDynamic\n cp[i] = { tag }\n u2()\n u2()\n break\n case 3: // Integer\n case 4: // Float\n cp[i] = { tag }\n u4()\n break\n case 5: // Long — occupies TWO pool slots\n case 6: // Double — occupies TWO pool slots\n cp[i] = { tag }\n u4()\n u4()\n i++\n break\n case 15: // MethodHandle: u1 kind + u2 index\n cp[i] = { tag }\n u1()\n u2()\n break\n default:\n throw new NotClassFileError(`未知常量池标签 ${tag} @${i}`)\n }\n }\n\n const utf8 = (i: number): string => cp[i]?.str ?? ''\n const className = (i: number): string | null =>\n i === 0 ? null : utf8(cp[i]?.nameIndex ?? 0).replace(/\\//g, '.')\n\n // ---- Type-descriptor decoding ----\n function readType(d: string, pos: number): { type: string; next: number } {\n let arr = 0\n while (d[pos] === '[') {\n arr++\n pos++\n }\n const c = d[pos++] ?? ''\n let base: string\n if (PRIM[c]) {\n base = PRIM[c]\n } else if (c === 'L') {\n let n = ''\n while (pos < d.length && d[pos] !== ';') n += d[pos++]\n pos++ // consume ';'\n base = n.replace(/\\//g, '.').replace(/^java\\.lang\\./, '')\n } else {\n base = c\n }\n return { type: base + '[]'.repeat(arr), next: pos }\n }\n const fieldType = (d: string): string => readType(d, 0).type\n function methodSig(d: string): { params: string[]; ret: string } {\n let pos = 1 // skip '('\n const params: string[] = []\n while (pos < d.length && d[pos] !== ')') {\n const r = readType(d, pos)\n params.push(r.type)\n pos = r.next\n }\n return { params, ret: readType(d, pos + 1).type }\n }\n\n // ---- Access flags (same bit, different meaning on field vs method) ----\n const memberFlags = (f: number, kind: 'field' | 'method'): string[] => {\n const M: [number, string][] = [\n [0x0001, 'public'],\n [0x0002, 'private'],\n [0x0004, 'protected'],\n [0x0008, 'static'],\n [0x0010, 'final'],\n [0x0040, kind === 'field' ? 'volatile' : 'bridge'],\n [0x0080, kind === 'field' ? 'transient' : 'varargs'],\n [0x0100, 'native'],\n [0x0400, 'abstract'],\n [0x0800, 'strictfp'],\n ]\n return M.filter(([b]) => (f & b) !== 0).map(([, n]) => n)\n }\n\n // ---- Class header ----\n const accessFlags = u2()\n const thisClass = className(u2())\n const superClass = className(u2())\n const ifaceCount = u2()\n const interfaces: string[] = []\n for (let i = 0; i < ifaceCount; i++) {\n const n = className(u2())\n if (n) interfaces.push(n)\n }\n\n // Generic attribute skip — record name + body position, advance by the declared length. Unknown attributes\n // are skipped wholesale (this is what makes the parser forward-compatible).\n interface AttrRef {\n name: string\n start: number\n len: number\n }\n const readAttributes = (): AttrRef[] => {\n const n = u2()\n const out: AttrRef[] = []\n for (let i = 0; i < n; i++) {\n const nameIdx = u2()\n const len = u4()\n out.push({ name: utf8(nameIdx), start: p, len })\n p += len\n }\n return out\n }\n\n // ---- Fields ----\n const fieldCount = u2()\n const fields: ClassField[] = []\n for (let i = 0; i < fieldCount; i++) {\n const flags = u2()\n const nameIdx = u2()\n const descIdx = u2()\n readAttributes()\n fields.push({\n name: utf8(nameIdx),\n type: fieldType(utf8(descIdx)),\n flags: memberFlags(flags, 'field'),\n })\n }\n\n // ---- Methods (also lifting local-variable names out of the Code attribute) ----\n const methodCount = u2()\n const methods: ClassMethod[] = []\n for (let i = 0; i < methodCount; i++) {\n const flags = u2()\n const nameIdx = u2()\n const descIdx = u2()\n const attrs = readAttributes()\n const sig = methodSig(utf8(descIdx))\n let locals: ClassLocal[] | null = null\n const code = attrs.find((a) => a.name === 'Code')\n if (code) {\n // Code: max_stack u2, max_locals u2, code_length u4, code[], exception_table_length u2,\n // exceptions[8*n], attributes_count u2, attributes...\n let q = code.start\n const r2 = (): number => {\n const v = dv.getUint16(q)\n q += 2\n return v\n }\n const r4 = (): number => {\n const v = dv.getUint32(q)\n q += 4\n return v\n }\n r2() // max_stack\n r2() // max_locals\n const codeLen = r4()\n q += codeLen\n const excLen = r2()\n q += excLen * 8\n const nAttr = r2()\n for (let k = 0; k < nAttr; k++) {\n const an = utf8(r2())\n const al = r4()\n const aStart = q\n if (an === 'LocalVariableTable') {\n // Each entry: start_pc u2, length u2, name_index u2, descriptor_index u2, index u2.\n const cnt = dv.getUint16(q)\n let qq = q + 2\n locals = []\n for (let v = 0; v < cnt; v++) {\n qq += 4 // skip start_pc, length\n const nm = dv.getUint16(qq)\n qq += 2\n const ds = dv.getUint16(qq)\n qq += 2\n const sl = dv.getUint16(qq)\n qq += 2\n locals.push({ name: utf8(nm), type: fieldType(utf8(ds)), slot: sl })\n }\n }\n q = aStart + al\n }\n }\n methods.push({\n name: utf8(nameIdx),\n params: sig.params,\n ret: sig.ret,\n flags: memberFlags(flags, 'method'),\n locals,\n })\n }\n\n // ---- Class kind + class-level modifiers (from access_flags) ----\n const ACC_FINAL = 0x0010\n const ACC_INTERFACE = 0x0200\n const ACC_ABSTRACT = 0x0400\n const ACC_ANNOTATION = 0x2000\n const ACC_ENUM = 0x4000\n let kind: ClassKind = 'class'\n if (accessFlags & ACC_ANNOTATION) kind = '@interface'\n else if (accessFlags & ACC_INTERFACE) kind = 'interface'\n else if (accessFlags & ACC_ENUM) kind = 'enum'\n const modifiers: string[] = []\n if (accessFlags & 0x0001) modifiers.push('public')\n // `final`/`abstract` are only meaningful (and non-redundant) on a plain class.\n if (kind === 'class' && accessFlags & ACC_FINAL) modifiers.push('final')\n if (kind === 'class' && accessFlags & ACC_ABSTRACT) modifiers.push('abstract')\n\n return {\n majorVersion: major,\n minorVersion: minor,\n version: `${major}.${minor}`,\n javaLabel: javaLabel(major),\n kind,\n modifiers,\n thisClass,\n superClass,\n interfaces,\n fields,\n methods,\n }\n}\n"],"mappings":"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"}
@@ -25,3 +25,5 @@ function n(n) {
25
25
  }
26
26
  //#endregion
27
27
  export { n as codePreview };
28
+
29
+ //# sourceMappingURL=codePreview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codePreview.js","names":[],"sources":["../../src/lib/codePreview.ts"],"sourcesContent":["import type { ViewerFile } from '@/composables/useFileViewer'\n\n/**\n * Live-preview support for fenced code blocks. A markdown/html/svg fence can be \"run\" in the side\n * viewer (FileViewerPanel) with the code itself as inline content — no file, no fetch. This is the\n * code-block twin of fileType.ts's {@link isHtmlFile}/{@link isSvgFile}: same render modes, but the\n * input is a fence info-string language token (` ```html `) rather than a filename + mime.\n */\nexport interface CodePreview {\n /** Synthesized extension for the viewer header (also a sensible name for its download/copy label). */\n ext: string\n /** ViewerFile fields that pick the render mode: `lang` (source-view highlighting) + html/svg flags. */\n fields: Pick<ViewerFile, 'lang' | 'html' | 'svg'>\n}\n\nconst HTML_LANGS = new Set(['html', 'htm', 'xhtml'])\nconst MARKDOWN_LANGS = new Set(['markdown', 'md'])\n\n/**\n * Map a fenced code block's language to a side-viewer preview, or null when it has no live preview\n * (most languages — no Run button). Mirrors FileViewerPanel's render modes:\n * - html/htm/xhtml → sandboxed iframe (lang 'xml' so the source toggle still highlights);\n * - svg → picture (data-URL <img>, scripts never run) (lang 'xml' for source);\n * - markdown/md → rendered document.\n * Only the first info-string token matters, so ` ```html linenums ` still previews as HTML.\n */\nexport function codePreview(lang: string | undefined): CodePreview | null {\n const l = (lang || '').trim().toLowerCase().split(/\\s+/)[0]\n if (HTML_LANGS.has(l)) return { ext: 'html', fields: { lang: 'xml', html: true } }\n if (l === 'svg') return { ext: 'svg', fields: { lang: 'xml', svg: true } }\n if (MARKDOWN_LANGS.has(l)) return { ext: 'md', fields: { lang: 'markdown' } }\n return null\n}\n"],"mappings":";AAeA,IAAM,IAAa,IAAI,IAAI;CAAC;CAAQ;CAAO;AAAO,CAAC,GAC7C,IAAiB,IAAI,IAAI,CAAC,YAAY,IAAI,CAAC;AAUjD,SAAgB,EAAY,GAA8C;CACxE,IAAM,KAAK,KAAQ,GAAA,CAAI,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;CAIzD,OAHI,EAAW,IAAI,CAAC,IAAU;EAAE,KAAK;EAAQ,QAAQ;GAAE,MAAM;GAAO,MAAM;EAAK;CAAE,IAC7E,MAAM,QAAc;EAAE,KAAK;EAAO,QAAQ;GAAE,MAAM;GAAO,KAAK;EAAK;CAAE,IACrE,EAAe,IAAI,CAAC,IAAU;EAAE,KAAK;EAAM,QAAQ,EAAE,MAAM,WAAW;CAAE,IACrE;AACT"}
@@ -28,3 +28,5 @@ function t(e, t) {
28
28
  }
29
29
  //#endregion
30
30
  export { e as computeFoldRegions };
31
+
32
+ //# sourceMappingURL=codefold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codefold.js","names":[],"sources":["../../src/lib/codefold.ts"],"sourcesContent":["/**\n * Indentation-based code folding for the source viewer (CodeView.vue).\n *\n * Deliberately language-AGNOSTIC: a foldable region is a header line followed by a run of more-deeply-indented\n * lines (blank lines inside the run don't break it). This covers the requested languages — yaml / json / xml /\n * html / java / kotlin / python / ts / js — because their block structure is mirrored in indentation, with no\n * per-language parser or wasm grammar to ship (the codebase's hand-rolled, zero-dependency house style; a\n * tree-sitter approach would mean bundling a runtime + a grammar per language). Minified or single-line files\n * simply have nothing to fold.\n *\n * Returns a map of header line index (0-based) → the LAST line index belonging to its block, so folding the\n * header hides lines header+1 … end (inclusive). Tabs are expanded to `tabSize` columns for the comparison.\n */\nexport function computeFoldRegions(code: string, tabSize = 2): Map<number, number> {\n const lines = code.split('\\n')\n const indent = lines.map((l) => indentOf(l, tabSize)) // -1 for a blank / whitespace-only line\n const regions = new Map<number, number>()\n for (let i = 0; i < lines.length; i++) {\n if (indent[i] < 0) continue\n let end = i\n let j = i + 1\n while (j < lines.length) {\n if (indent[j] < 0) {\n j++ // blank line: part of the block only if a deeper line follows — keep scanning, don't extend `end`\n continue\n }\n if (indent[j] > indent[i]) {\n end = j\n j++\n } else {\n break\n }\n }\n if (end > i) regions.set(i, end)\n }\n return regions\n}\n\n// Leading-whitespace width in columns (tabs → next multiple of tabSize), or -1 for a blank line.\nfunction indentOf(line: string, tabSize: number): number {\n let col = 0\n for (let i = 0; i < line.length; i++) {\n const c = line[i]\n if (c === ' ') col++\n else if (c === '\\t') col += tabSize - (col % tabSize)\n else return col\n }\n return -1\n}\n"],"mappings":";AAaA,SAAgB,EAAmB,GAAc,IAAU,GAAwB;CACjF,IAAM,IAAQ,EAAK,MAAM,IAAI,GACvB,IAAS,EAAM,KAAK,MAAM,EAAS,GAAG,CAAO,CAAC,GAC9C,oBAAU,IAAI,IAAoB;CACxC,KAAK,IAAI,IAAI,GAAG,IAAI,EAAM,QAAQ,KAAK;EACrC,IAAI,EAAO,KAAK,GAAG;EACnB,IAAI,IAAM,GACN,IAAI,IAAI;EACZ,OAAO,IAAI,EAAM,SAAQ;GACvB,IAAI,EAAO,KAAK,GAAG;IACjB;IACA;GACF;GACA,IAAI,EAAO,KAAK,EAAO,IAErB,AADA,IAAM,GACN;QAEA;EAEJ;EACA,AAAI,IAAM,KAAG,EAAQ,IAAI,GAAG,CAAG;CACjC;CACA,OAAO;AACT;AAGA,SAAS,EAAS,GAAc,GAAyB;CACvD,IAAI,IAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK;EACpC,IAAM,IAAI,EAAK;EACf,IAAI,MAAM,KAAK;OACV,IAAI,MAAM,KAAM,KAAO,IAAW,IAAM;OACxC,OAAO;CACd;CACA,OAAO;AACT"}
@@ -128,3 +128,5 @@ async function c(e, t) {
128
128
  }
129
129
  //#endregion
130
130
  export { o as canFormat, c as formatCode };
131
+
132
+ //# sourceMappingURL=codeformat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codeformat.js","names":[],"sources":["../../src/lib/codeformat.ts"],"sourcesContent":["/**\n * On-demand code formatting for the source viewer (CodeView), powered by Prettier — loaded LAZILY: the library\n * and the one language plugin needed are dynamic-imported only when the user clicks 格式化, so they never weigh\n * on the main bundle. Covers the languages Prettier can parse in the browser: js/jsx, ts/tsx, json/json5,\n * css/scss/less, html/vue, xml/svg (via @prettier/plugin-xml), yaml, markdown, graphql. Other languages\n * (python/java/kotlin/go/…) have no in-browser Prettier parser, so {@link canFormat} returns false and the\n * button is hidden — consistent with the codebase's \"be honest about what's supported\" stance.\n *\n * The parser is chosen from the file EXTENSION first (precise — .html, .vue and .xml all collapse to hljs lang\n * 'xml'), falling back to the hljs language id when no filename is available.\n */\n\ntype PluginId =\n | 'babel'\n | 'estree'\n | 'typescript'\n | 'postcss'\n | 'html'\n | 'yaml'\n | 'markdown'\n | 'graphql'\n | 'xml'\n\ninterface Spec {\n parser: string\n plugins: PluginId[]\n}\n\n// estree is Prettier's shared printer for the babel/typescript ASTs (json reuses the babel parser).\nconst JS: Spec = { parser: 'babel', plugins: ['babel', 'estree'] }\nconst TS: Spec = { parser: 'typescript', plugins: ['typescript', 'estree'] }\nconst JSON_SPEC: Spec = { parser: 'json', plugins: ['babel', 'estree'] }\n\n// Extension → spec (preferred — most precise).\nconst BY_EXT: Record<string, Spec> = {\n js: JS,\n mjs: JS,\n cjs: JS,\n jsx: JS,\n ts: TS,\n mts: TS,\n cts: TS,\n tsx: TS,\n json: JSON_SPEC,\n jsonc: JSON_SPEC,\n json5: { parser: 'json5', plugins: ['babel', 'estree'] },\n css: { parser: 'css', plugins: ['postcss'] },\n scss: { parser: 'scss', plugins: ['postcss'] },\n sass: { parser: 'scss', plugins: ['postcss'] },\n less: { parser: 'less', plugins: ['postcss'] },\n html: { parser: 'html', plugins: ['html'] },\n htm: { parser: 'html', plugins: ['html'] },\n vue: { parser: 'vue', plugins: ['html'] },\n xml: { parser: 'xml', plugins: ['xml'] },\n svg: { parser: 'xml', plugins: ['xml'] },\n yaml: { parser: 'yaml', plugins: ['yaml'] },\n yml: { parser: 'yaml', plugins: ['yaml'] },\n md: { parser: 'markdown', plugins: ['markdown'] },\n markdown: { parser: 'markdown', plugins: ['markdown'] },\n graphql: { parser: 'graphql', plugins: ['graphql'] },\n gql: { parser: 'graphql', plugins: ['graphql'] },\n}\n\n// hljs language id → spec (fallback when there's no filename). 'xml' defaults to the xml parser, which is safe\n// for any markup; a precise .html/.vue file matches by extension above before this is consulted.\nconst BY_LANG: Record<string, Spec> = {\n javascript: JS,\n typescript: TS,\n json: JSON_SPEC,\n css: BY_EXT.css,\n scss: BY_EXT.scss,\n less: BY_EXT.less,\n yaml: BY_EXT.yaml,\n markdown: BY_EXT.md,\n graphql: BY_EXT.graphql,\n xml: BY_EXT.xml,\n}\n\nfunction specFor(ext: string, lang: string): Spec | null {\n return BY_EXT[ext] ?? BY_LANG[lang] ?? null\n}\n\n/** Whether the source viewer should offer a 格式化 button for this file (Prettier can parse it in-browser). */\nexport function canFormat(ext: string, lang: string): boolean {\n return specFor(ext, lang) != null\n}\n\nfunction loadPlugin(id: PluginId): Promise<unknown> {\n switch (id) {\n case 'babel':\n return import('prettier/plugins/babel')\n case 'estree':\n return import('prettier/plugins/estree')\n case 'typescript':\n return import('prettier/plugins/typescript')\n case 'postcss':\n return import('prettier/plugins/postcss')\n case 'html':\n return import('prettier/plugins/html')\n case 'yaml':\n return import('prettier/plugins/yaml')\n case 'markdown':\n return import('prettier/plugins/markdown')\n case 'graphql':\n return import('prettier/plugins/graphql')\n case 'xml':\n return import('@prettier/plugin-xml')\n }\n}\n\n/**\n * Format `code` with Prettier, picking the parser by extension (preferred) or hljs lang. Throws if the type is\n * unsupported or the source doesn't parse (the caller surfaces a brief \"格式化失败\" and keeps the original).\n */\nexport async function formatCode(\n code: string,\n opts: { ext: string; lang: string },\n): Promise<string> {\n const spec = specFor(opts.ext, opts.lang)\n if (!spec) throw new Error('该类型暂不支持格式化')\n const [standalone, ...mods] = await Promise.all([\n import('prettier/standalone'),\n ...spec.plugins.map(loadPlugin),\n ])\n // Core plugins are used as the imported namespace; @prettier/plugin-xml exposes the plugin as a default export.\n const plugins = mods.map((m) => (m as { default?: unknown }).default ?? m)\n // `xmlWhitespaceSensitivity` is an @prettier/plugin-xml option (not in Prettier's core Options type, hence the\n // cast); it relaxes the plugin's default strict mode so xml/svg actually re-indent. Ignored by other parsers.\n const options = {\n parser: spec.parser,\n plugins,\n printWidth: 100,\n tabWidth: 2,\n xmlWhitespaceSensitivity: 'ignore',\n } as Parameters<typeof standalone.format>[1]\n return standalone.format(code, options)\n}\n"],"mappings":";AA6BA,IAAM,IAAW;CAAE,QAAQ;CAAS,SAAS,CAAC,SAAS,QAAQ;AAAE,GAC3D,IAAW;CAAE,QAAQ;CAAc,SAAS,CAAC,cAAc,QAAQ;AAAE,GACrE,IAAkB;CAAE,QAAQ;CAAQ,SAAS,CAAC,SAAS,QAAQ;AAAE,GAGjE,IAA+B;CACnC,IAAI;CACJ,KAAK;CACL,KAAK;CACL,KAAK;CACL,IAAI;CACJ,KAAK;CACL,KAAK;CACL,KAAK;CACL,MAAM;CACN,OAAO;CACP,OAAO;EAAE,QAAQ;EAAS,SAAS,CAAC,SAAS,QAAQ;CAAE;CACvD,KAAK;EAAE,QAAQ;EAAO,SAAS,CAAC,SAAS;CAAE;CAC3C,MAAM;EAAE,QAAQ;EAAQ,SAAS,CAAC,SAAS;CAAE;CAC7C,MAAM;EAAE,QAAQ;EAAQ,SAAS,CAAC,SAAS;CAAE;CAC7C,MAAM;EAAE,QAAQ;EAAQ,SAAS,CAAC,SAAS;CAAE;CAC7C,MAAM;EAAE,QAAQ;EAAQ,SAAS,CAAC,MAAM;CAAE;CAC1C,KAAK;EAAE,QAAQ;EAAQ,SAAS,CAAC,MAAM;CAAE;CACzC,KAAK;EAAE,QAAQ;EAAO,SAAS,CAAC,MAAM;CAAE;CACxC,KAAK;EAAE,QAAQ;EAAO,SAAS,CAAC,KAAK;CAAE;CACvC,KAAK;EAAE,QAAQ;EAAO,SAAS,CAAC,KAAK;CAAE;CACvC,MAAM;EAAE,QAAQ;EAAQ,SAAS,CAAC,MAAM;CAAE;CAC1C,KAAK;EAAE,QAAQ;EAAQ,SAAS,CAAC,MAAM;CAAE;CACzC,IAAI;EAAE,QAAQ;EAAY,SAAS,CAAC,UAAU;CAAE;CAChD,UAAU;EAAE,QAAQ;EAAY,SAAS,CAAC,UAAU;CAAE;CACtD,SAAS;EAAE,QAAQ;EAAW,SAAS,CAAC,SAAS;CAAE;CACnD,KAAK;EAAE,QAAQ;EAAW,SAAS,CAAC,SAAS;CAAE;AACjD,GAIM,IAAgC;CACpC,YAAY;CACZ,YAAY;CACZ,MAAM;CACN,KAAK,EAAO;CACZ,MAAM,EAAO;CACb,MAAM,EAAO;CACb,MAAM,EAAO;CACb,UAAU,EAAO;CACjB,SAAS,EAAO;CAChB,KAAK,EAAO;AACd;AAEA,SAAS,EAAQ,GAAa,GAA2B;CACvD,OAAO,EAAO,MAAQ,EAAQ,MAAS;AACzC;AAGA,SAAgB,EAAU,GAAa,GAAuB;CAC5D,OAAO,EAAQ,GAAK,CAAI,KAAK;AAC/B;AAEA,SAAS,EAAW,GAAgC;CAClD,QAAQ,GAAR;EACE,KAAK,SACH,OAAO,OAAO;EAChB,KAAK,UACH,OAAO,OAAO;EAChB,KAAK,cACH,OAAO,OAAO;EAChB,KAAK,WACH,OAAO,OAAO;EAChB,KAAK,QACH,OAAO,OAAO;EAChB,KAAK,QACH,OAAO,OAAO;EAChB,KAAK,YACH,OAAO,OAAO;EAChB,KAAK,WACH,OAAO,OAAO;EAChB,KAAK,OACH,OAAO,OAAO;CAClB;AACF;AAMA,eAAsB,EACpB,GACA,GACiB;CACjB,IAAM,IAAO,EAAQ,EAAK,KAAK,EAAK,IAAI;CACxC,IAAI,CAAC,GAAM,MAAU,MAAM,YAAY;CACvC,IAAM,CAAC,GAAY,GAAG,KAAQ,MAAM,QAAQ,IAAI,CAC9C,OAAO,wBACP,GAAG,EAAK,QAAQ,IAAI,CAAU,CAChC,CAAC,GAEK,IAAU,EAAK,KAAK,MAAO,EAA4B,WAAW,CAAC,GAGnE,IAAU;EACd,QAAQ,EAAK;EACb;EACA,YAAY;EACZ,UAAU;EACV,0BAA0B;CAC5B;CACA,OAAO,EAAW,OAAO,GAAM,CAAO;AACxC"}
package/dist/lib/csv.js CHANGED
@@ -72,3 +72,5 @@ function r(e, t) {
72
72
  }
73
73
  //#endregion
74
74
  export { r as parseCsv };
75
+
76
+ //# sourceMappingURL=csv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv.js","names":[],"sources":["../../src/lib/csv.ts"],"sourcesContent":["/**\n * Hand-rolled, zero-dependency CSV / TSV parser for the side viewer's table preview.\n *\n * Implements RFC 4180 quoting: a field may be wrapped in double quotes; a literal quote inside such a field is\n * written doubled (`\"\"` → `\"`); a quoted field may contain the delimiter, CR, and LF. Outside quotes, fields\n * split on the delimiter and rows on CRLF / LF / lone CR. The delimiter is the tab for `.tsv`, otherwise sniffed\n * (comma / semicolon / tab / pipe — whichever occurs most on the first line, counted OUTSIDE quotes), so\n * European `;`-separated files and tab files both render correctly. A leading UTF-8 BOM is stripped.\n *\n * The viewer (CsvViewer.vue) renders the rows as a table; cell text is escaped by Vue on render, so embedded\n * markup is inert. We never trust the stored content_type — detection is extension-driven (see isCsvFile).\n */\n\nexport interface ParsedCsv {\n rows: string[][]\n delimiter: string\n /** Widest row's column count (shorter rows are padded with empty cells when rendered). */\n cols: number\n}\n\nconst DELIMS = [',', ';', '\\t', '|']\n\n// Count a candidate delimiter on a line, ignoring occurrences inside quoted fields (and doubled quotes).\nfunction countOutsideQuotes(line: string, delim: string): number {\n let n = 0\n let inQuotes = false\n for (let i = 0; i < line.length; i++) {\n const c = line[i]\n if (c === '\"') {\n if (inQuotes && line[i + 1] === '\"') {\n i++ // doubled quote inside a quoted field — skip both\n continue\n }\n inQuotes = !inQuotes\n } else if (c === delim && !inQuotes) {\n n++\n }\n }\n return n\n}\n\nfunction pickDelimiter(text: string, ext?: string): string {\n if (ext === 'tsv' || ext === 'tab') return '\\t'\n const nl = text.indexOf('\\n')\n const firstLine = (nl >= 0 ? text.slice(0, nl) : text).slice(0, 4096)\n let best = ','\n let bestCount = -1\n for (const d of DELIMS) {\n const c = countOutsideQuotes(firstLine, d)\n if (c > bestCount) {\n bestCount = c\n best = d\n }\n }\n return best\n}\n\nexport function parseCsv(text: string, ext?: string): ParsedCsv {\n const src = text.charCodeAt(0) === 0xfeff ? text.slice(1) : text\n const delimiter = pickDelimiter(src, ext)\n const rows: string[][] = []\n let row: string[] = []\n let field = ''\n let inQuotes = false\n let started = false // saw any char on the current row? (so a final row break doesn't add a blank row)\n const n = src.length\n let i = 0\n\n const endRow = (): void => {\n row.push(field)\n rows.push(row)\n row = []\n field = ''\n started = false\n }\n\n while (i < n) {\n const c = src[i]\n if (inQuotes) {\n if (c === '\"') {\n if (src[i + 1] === '\"') {\n field += '\"' // escaped quote\n i += 2\n continue\n }\n inQuotes = false\n i++\n continue\n }\n field += c\n i++\n continue\n }\n if (c === '\"' && field === '') {\n // A quote only opens a quoted field at field start; a mid-field quote is treated as a literal char.\n inQuotes = true\n started = true\n i++\n continue\n }\n if (c === delimiter) {\n row.push(field)\n field = ''\n started = true\n i++\n continue\n }\n if (c === '\\n') {\n endRow()\n i++\n continue\n }\n if (c === '\\r') {\n endRow()\n if (src[i + 1] === '\\n') i += 2\n else i++\n continue\n }\n field += c\n started = true\n i++\n }\n // Flush the trailing field/row — unless the input ended exactly on a row break (nothing pending).\n if (started || field !== '' || row.length > 0) {\n row.push(field)\n rows.push(row)\n }\n\n const cols = rows.reduce((m, r) => Math.max(m, r.length), 0)\n return { rows, delimiter, cols }\n}\n"],"mappings":";AAoBA,IAAM,IAAS;CAAC;CAAK;CAAK;CAAM;AAAG;AAGnC,SAAS,EAAmB,GAAc,GAAuB;CAC/D,IAAI,IAAI,GACJ,IAAW;CACf,KAAK,IAAI,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK;EACpC,IAAM,IAAI,EAAK;EACf,IAAI,MAAM,MAAK;GACb,IAAI,KAAY,EAAK,IAAI,OAAO,MAAK;IACnC;IACA;GACF;GACA,IAAW,CAAC;EACd,OAAO,AAAI,MAAM,KAAS,CAAC,KACzB;CAEJ;CACA,OAAO;AACT;AAEA,SAAS,EAAc,GAAc,GAAsB;CACzD,IAAI,MAAQ,SAAS,MAAQ,OAAO,OAAO;CAC3C,IAAM,IAAK,EAAK,QAAQ,IAAI,GACtB,KAAa,KAAM,IAAI,EAAK,MAAM,GAAG,CAAE,IAAI,EAAA,CAAM,MAAM,GAAG,IAAI,GAChE,IAAO,KACP,IAAY;CAChB,KAAK,IAAM,KAAK,GAAQ;EACtB,IAAM,IAAI,EAAmB,GAAW,CAAC;EACzC,AAAI,IAAI,MACN,IAAY,GACZ,IAAO;CAEX;CACA,OAAO;AACT;AAEA,SAAgB,EAAS,GAAc,GAAyB;CAC9D,IAAM,IAAM,EAAK,WAAW,CAAC,MAAM,QAAS,EAAK,MAAM,CAAC,IAAI,GACtD,IAAY,EAAc,GAAK,CAAG,GAClC,IAAmB,CAAC,GACtB,IAAgB,CAAC,GACjB,IAAQ,IACR,IAAW,IACX,IAAU,IACR,IAAI,EAAI,QACV,IAAI,GAEF,UAAqB;EAKzB,AAJA,EAAI,KAAK,CAAK,GACd,EAAK,KAAK,CAAG,GACb,IAAM,CAAC,GACP,IAAQ,IACR,IAAU;CACZ;CAEA,OAAO,IAAI,IAAG;EACZ,IAAM,IAAI,EAAI;EACd,IAAI,GAAU;GACZ,IAAI,MAAM,MAAK;IACb,IAAI,EAAI,IAAI,OAAO,MAAK;KAEtB,AADA,KAAS,MACT,KAAK;KACL;IACF;IAEA,AADA,IAAW,IACX;IACA;GACF;GAEA,AADA,KAAS,GACT;GACA;EACF;EACA,IAAI,MAAM,QAAO,MAAU,IAAI;GAI7B,AAFA,IAAW,IACX,IAAU,IACV;GACA;EACF;EACA,IAAI,MAAM,GAAW;GAInB,AAHA,EAAI,KAAK,CAAK,GACd,IAAQ,IACR,IAAU,IACV;GACA;EACF;EACA,IAAI,MAAM,MAAM;GAEd,AADA,EAAO,GACP;GACA;EACF;EACA,IAAI,MAAM,MAAM;GAEd,AADA,EAAO,GACH,EAAI,IAAI,OAAO,OAAM,KAAK,IACzB;GACL;EACF;EAGA,AAFA,KAAS,GACT,IAAU,IACV;CACF;CAQA,QANI,KAAW,MAAU,MAAM,EAAI,SAAS,OAC1C,EAAI,KAAK,CAAK,GACd,EAAK,KAAK,CAAG,IAIR;EAAE;EAAM;EAAW,MADb,EAAK,QAAQ,GAAG,MAAM,KAAK,IAAI,GAAG,EAAE,MAAM,GAAG,CAChC;CAAK;AACjC"}
package/dist/lib/des.js CHANGED
@@ -926,3 +926,5 @@ function h(e, t, n) {
926
926
  }
927
927
  //#endregion
928
928
  export { h as tripleDesCbcDecrypt };
929
+
930
+ //# sourceMappingURL=des.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"des.js","names":[],"sources":["../../src/lib/des.ts"],"sourcesContent":["/**\n * Compact DES / Triple-DES (FIPS 46-3) — no dependency, no WASM.\n *\n * Needed for legacy PKCS#12 keystores (see lib/pkcs12.ts): the private key is stored in a\n * pkcs8ShroudedKeyBag encrypted with `pbeWithSHA1And3-KeyTripleDES-CBC`, and WebCrypto ships no DES. This is\n * decrypt-oriented (that's all the viewer needs) but the block cipher is symmetric, so an encrypt helper is\n * exposed too (Triple-DES EDE needs a middle DES *encrypt* during decryption). DES is long obsolete — used\n * here ONLY to read existing keystores, never for new encryption.\n *\n * Implementation is the textbook bit-permutation form (clear + obviously correct); keystores are a few KB, so\n * the per-block array churn is irrelevant.\n */\n\n// ── FIPS 46-3 permutation tables (1-indexed positions) ────────────────────────────────────────────\n// prettier-ignore\nconst IP = [\n 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,\n 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,\n 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,\n 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7,\n]\n// prettier-ignore\nconst FP = [\n 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,\n 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,\n 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,\n 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25,\n]\n// prettier-ignore\nconst E = [\n 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,\n 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1,\n]\n// prettier-ignore\nconst P = [\n 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,\n 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25,\n]\n// prettier-ignore\nconst PC1 = [\n 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3,\n 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37,\n 29, 21, 13, 5, 28, 20, 12, 4,\n]\n// prettier-ignore\nconst PC2 = [\n 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,\n 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32,\n]\nconst SHIFTS = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]\n// prettier-ignore\nconst SBOX: number[][] = [\n [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,\n 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13],\n [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,\n 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9],\n [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,\n 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12],\n [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,\n 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14],\n [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,\n 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3],\n [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,\n 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13],\n [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,\n 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12],\n [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,\n 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11],\n]\n\ntype Bits = number[]\n\nfunction bytesToBits(bytes: Uint8Array): Bits {\n const bits: Bits = []\n for (const b of bytes) for (let i = 7; i >= 0; i--) bits.push((b >> i) & 1)\n return bits\n}\nfunction bitsToBytes(bits: Bits): Uint8Array {\n const out = new Uint8Array(bits.length >> 3)\n for (let i = 0; i < out.length; i++) {\n let v = 0\n for (let j = 0; j < 8; j++) v = (v << 1) | bits[i * 8 + j]\n out[i] = v\n }\n return out\n}\nfunction permute(input: Bits, table: number[]): Bits {\n return table.map((pos) => input[pos - 1])\n}\n\n/** 16 round subkeys (each 48 bits) from an 8-byte DES key. */\nfunction desSubkeys(key8: Uint8Array): Bits[] {\n const cd = permute(bytesToBits(key8), PC1) // 56 bits\n let c = cd.slice(0, 28)\n let d = cd.slice(28, 56)\n const keys: Bits[] = []\n for (let i = 0; i < 16; i++) {\n const s = SHIFTS[i]\n c = c.slice(s).concat(c.slice(0, s))\n d = d.slice(s).concat(d.slice(0, s))\n keys.push(permute(c.concat(d), PC2))\n }\n return keys\n}\n\nfunction feistel(r: Bits, k: Bits): Bits {\n const x = permute(r, E) // 48 bits\n for (let i = 0; i < 48; i++) x[i] ^= k[i]\n const out: Bits = []\n for (let i = 0; i < 8; i++) {\n const o = i * 6\n const row = (x[o] << 1) | x[o + 5]\n const col = (x[o + 1] << 3) | (x[o + 2] << 2) | (x[o + 3] << 1) | x[o + 4]\n const val = SBOX[i][row * 16 + col]\n out.push((val >> 3) & 1, (val >> 2) & 1, (val >> 1) & 1, val & 1)\n }\n return permute(out, P)\n}\n\n/** One 8-byte DES block through `subkeys` (already in application order — reverse them for decryption). */\nfunction desBlock(block8: Uint8Array, subkeys: Bits[]): Uint8Array {\n const bits = permute(bytesToBits(block8), IP)\n let l = bits.slice(0, 32)\n let r = bits.slice(32, 64)\n for (let i = 0; i < 16; i++) {\n const f = feistel(r, subkeys[i])\n const nr = l.map((b, j) => b ^ f[j])\n l = r\n r = nr\n }\n return bitsToBytes(permute(r.concat(l), FP)) // preoutput is R16 ‖ L16 (swapped)\n}\n\n/** A prepared DES key: forward (encrypt) and reversed (decrypt) subkey orders. */\ninterface DesKey {\n enc: Bits[]\n dec: Bits[]\n}\nfunction prepare(key8: Uint8Array): DesKey {\n const sk = desSubkeys(key8)\n return { enc: sk, dec: sk.slice().reverse() }\n}\n\n/**\n * Triple-DES (EDE) CBC decrypt, no padding removal (the caller strips PKCS#7). `key` is 24 bytes\n * (K1‖K2‖K3) or 16 bytes (2-key: K3=K1); `iv` is 8 bytes; `data` must be a whole number of 8-byte blocks.\n */\nexport function tripleDesCbcDecrypt(key: Uint8Array, iv: Uint8Array, data: Uint8Array): Uint8Array {\n const k1 = prepare(key.subarray(0, 8))\n const k2 = prepare(key.subarray(8, 16))\n const k3 = key.length >= 24 ? prepare(key.subarray(16, 24)) : k1\n const n = data.length - (data.length % 8)\n const out = new Uint8Array(n)\n const prev = new Uint8Array(8)\n prev.set(iv.subarray(0, 8))\n for (let off = 0; off < n; off += 8) {\n const block = data.subarray(off, off + 8)\n // EDE decrypt: P = D_K1(E_K2(D_K3(C)))\n const x = desBlock(desBlock(desBlock(block, k3.dec), k2.enc), k1.dec)\n for (let i = 0; i < 8; i++) out[off + i] = x[i] ^ prev[i]\n prev.set(block)\n }\n return out\n}\n"],"mappings":";AAeA,IAAM,IAAK;CACT;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAC3D;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAC3D;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAG;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAC1D;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;AAC7D,GAEM,IAAK;CACT;CAAI;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAC1D;CAAI;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAC1D;CAAI;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAC1D;CAAI;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAG;CAAI;CAAG;CAAI;CAAI;CAAI;AAC3D,GAEM,IAAI;CACR;CAAI;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAC/E;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;AAC9F,GAEM,IAAI;CACR;CAAI;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAG;CAAI;CAAI;CAAI;CAAG;CAAI;CAAI;CACzD;CAAG;CAAG;CAAI;CAAI;CAAI;CAAI;CAAG;CAAG;CAAI;CAAI;CAAI;CAAG;CAAI;CAAI;CAAG;AACxD,GAEM,IAAM;CACV;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAG;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CACzF;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAG;CAAI;CAAI;CAAI;CAC1F;CAAI;CAAI;CAAI;CAAG;CAAI;CAAI;CAAI;AAC7B,GAEM,IAAM;CACV;CAAI;CAAI;CAAI;CAAI;CAAG;CAAG;CAAG;CAAI;CAAI;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAG;CAAI;CAAG;CAAI;CAAG;CAAI;CAAI;CAAI;CACrF;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;AAC9F,GACM,IAAS;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;CAAG;AAAC,GAExD,IAAmB;CACvB;EAAC;EAAI;EAAG;EAAI;EAAG;EAAG;EAAI;EAAI;EAAG;EAAG;EAAI;EAAG;EAAI;EAAG;EAAG;EAAG;EAAG;EAAG;EAAI;EAAG;EAAG;EAAI;EAAG;EAAI;EAAG;EAAI;EAAG;EAAI;EAAI;EAAG;EAAG;EAAG;EACzG;EAAG;EAAG;EAAI;EAAG;EAAI;EAAG;EAAG;EAAI;EAAI;EAAI;EAAG;EAAG;EAAG;EAAI;EAAG;EAAG;EAAI;EAAI;EAAG;EAAG;EAAG;EAAG;EAAG;EAAG;EAAG;EAAI;EAAG;EAAI;EAAI;EAAG;EAAG;CAAE;CAC3G;EAAC;EAAI;EAAG;EAAG;EAAI;EAAG;EAAI;EAAG;EAAG;EAAG;EAAG;EAAG;EAAI;EAAI;EAAG;EAAG;EAAI;EAAG;EAAI;EAAG;EAAG;EAAI;EAAG;EAAG;EAAI;EAAI;EAAG;EAAG;EAAI;EAAG;EAAG;EAAI;EACzG;EAAG;EAAI;EAAG;EAAI;EAAI;EAAG;EAAI;EAAG;EAAG;EAAG;EAAI;EAAG;EAAG;EAAG;EAAG;EAAI;EAAI;EAAG;EAAI;EAAG;EAAG;EAAI;EAAG;EAAG;EAAI;EAAG;EAAG;EAAI;EAAG;EAAG;EAAI;CAAC;CAC3G;EAAC;EAAI;EAAG;EAAG;EAAI;EAAG;EAAG;EAAI;EAAG;EAAG;EAAI;EAAI;EAAG;EAAI;EAAG;EAAG;EAAG;EAAI;EAAG;EAAG;EAAG;EAAG;EAAG;EAAG;EAAI;EAAG;EAAG;EAAG;EAAI;EAAI;EAAI;EAAI;EACzG;EAAI;EAAG;EAAG;EAAG;EAAG;EAAI;EAAG;EAAG;EAAI;EAAG;EAAG;EAAI;EAAG;EAAI;EAAI;EAAG;EAAG;EAAI;EAAI;EAAG;EAAG;EAAG;EAAG;EAAG;EAAG;EAAI;EAAI;EAAG;EAAI;EAAG;EAAG;CAAE;CAC3G;EAAC;EAAG;EAAI;EAAI;EAAG;EAAG;EAAG;EAAG;EAAI;EAAG;EAAG;EAAG;EAAG;EAAI;EAAI;EAAG;EAAI;EAAI;EAAG;EAAI;EAAG;EAAG;EAAI;EAAG;EAAG;EAAG;EAAG;EAAG;EAAI;EAAG;EAAI;EAAI;EACzG;EAAI;EAAG;EAAG;EAAG;EAAI;EAAI;EAAG;EAAI;EAAI;EAAG;EAAG;EAAI;EAAG;EAAG;EAAG;EAAG;EAAG;EAAI;EAAG;EAAG;EAAI;EAAG;EAAI;EAAG;EAAG;EAAG;EAAG;EAAI;EAAI;EAAG;EAAG;CAAE;CAC3G;EAAC;EAAG;EAAI;EAAG;EAAG;EAAG;EAAI;EAAI;EAAG;EAAG;EAAG;EAAG;EAAI;EAAI;EAAG;EAAI;EAAG;EAAI;EAAI;EAAG;EAAI;EAAG;EAAG;EAAI;EAAG;EAAG;EAAG;EAAI;EAAI;EAAG;EAAG;EAAG;EACzG;EAAG;EAAG;EAAG;EAAI;EAAI;EAAI;EAAG;EAAG;EAAI;EAAG;EAAI;EAAG;EAAG;EAAG;EAAG;EAAI;EAAI;EAAG;EAAI;EAAG;EAAG;EAAI;EAAG;EAAI;EAAG;EAAI;EAAG;EAAG;EAAI;EAAG;EAAG;CAAC;CAC3G;EAAC;EAAI;EAAG;EAAI;EAAI;EAAG;EAAG;EAAG;EAAG;EAAG;EAAI;EAAG;EAAG;EAAI;EAAG;EAAG;EAAI;EAAI;EAAI;EAAG;EAAG;EAAG;EAAI;EAAG;EAAG;EAAG;EAAG;EAAI;EAAI;EAAG;EAAI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"}
@@ -477,3 +477,5 @@ function J(e, t, n, r, a) {
477
477
  }
478
478
  //#endregion
479
479
  export { t as isDiagramFile, n as renderDiagram };
480
+
481
+ //# sourceMappingURL=diagram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagram.js","names":[],"sources":["../../src/lib/diagram.ts"],"sourcesContent":["/**\n * Best-effort, zero-dependency diagram rendering for the file viewer — draws .drawio (mxGraph) and .excalidraw\n * scenes to a self-contained SVG string. In the codebase's hand-rolled house style (like lib/geo.ts's offline\n * map): no mxGraph / excalidraw runtime, no CDN. It covers the COMMON cases — flowchart shapes (rect / rounded /\n * ellipse / diamond / text label), edges with the right arrowheads (classic vs none), exit/entry connection\n * points, orthogonal routing + waypoints, and edge labels — and degrades gracefully on exotic shape libraries\n * (a shape it doesn't special-case falls back to a plain rectangle). For anything it can't render faithfully,\n * the viewer's source toggle still shows the raw XML/JSON, and the file remains downloadable.\n *\n * - .drawio: an <mxfile> whose <diagram> body is either inline <mxGraphModel> XML or, more often, a\n * base64 + raw-DEFLATE + URI-encoded blob (decoded here via DecompressionStream — hence the async API).\n * - .excalidraw: a JSON scene { elements: [...] } — parsed and mapped element-by-element.\n *\n * The produced SVG is OUR markup (built from the parsed geometry, never raw upstream HTML), so the viewer can\n * inline it with v-html safely; element text is escaped.\n */\nimport { fileExt } from '@/lib/fileType'\n\nexport type DiagramKind = 'drawio' | 'excalidraw'\n\n/** Which diagram renderer (if any) handles this file — extension-driven, with the registered mimes as a hint. */\nexport function isDiagramFile(name: string, mime?: string | null): DiagramKind | null {\n const ext = fileExt(name)\n if (ext === 'drawio' || ext === 'dio') return 'drawio'\n if (ext === 'excalidraw') return 'excalidraw'\n const m = (mime || '').toLowerCase().trim()\n if (m === 'application/vnd.jgraph.mxfile') return 'drawio'\n if (m === 'application/vnd.excalidraw+json') return 'excalidraw'\n return null\n}\n\n/** Render a diagram's text to a standalone SVG string. Async because drawio diagrams are usually DEFLATE'd. */\nexport async function renderDiagram(text: string, kind: DiagramKind): Promise<string> {\n return kind === 'excalidraw' ? excalidrawToSvg(text) : drawioToSvg(text)\n}\n\n// ── shared helpers ────────────────────────────────────────────────────────────────────────────────\nconst FONT = 'Helvetica, Arial, \"PingFang SC\", \"Microsoft YaHei\", sans-serif'\n\nfunction esc(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n}\nfunction num(v: string | null | undefined, fallback = 0): number {\n const n = Number(v)\n return Number.isFinite(n) ? n : fallback\n}\n// Trim coordinate noise (perimeter / midpoint math produces long decimals) without losing visible precision.\nconst rnd = (n: number): number => Math.round(n * 100) / 100\nconst clamp = (v: number, lo: number, hi: number): number => Math.max(lo, Math.min(hi, v))\n\nfunction svgWrap(viewBox: string, w: number, h: number, bg: string, body: string): string {\n // `auto-start-reverse` lets the one marker serve both marker-start and marker-end (start gets flipped).\n const marker =\n `<defs><marker id=\"dg-arrow\" markerWidth=\"10\" markerHeight=\"8\" refX=\"8\" refY=\"3\" ` +\n `orient=\"auto-start-reverse\" markerUnits=\"strokeWidth\"><path d=\"M0,0 L9,3 L0,6 z\" fill=\"context-stroke\"/></marker></defs>`\n // The background must cover the ENTIRE viewBox. Percentage sizing (width/height=\"100%\") gives the rect the\n // viewport's size but keeps it anchored at user-space (0,0), so on any diagram whose content is offset from\n // the origin (the common case — minX/minY ≠ 0) the white rect drifts off and leaves shapes near the far\n // edges uncovered (a tall flowchart's bottom node fell BELOW the white background). Anchor the rect to the\n // viewBox's own x/y/w/h so it always lines up exactly.\n const [vx, vy, vw, vh] = viewBox.split(/\\s+/).map(Number)\n const back =\n bg && bg !== 'transparent'\n ? `<rect x=\"${rnd(vx)}\" y=\"${rnd(vy)}\" width=\"${rnd(vw)}\" height=\"${rnd(vh)}\" fill=\"${bg}\"/>`\n : ''\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"${viewBox}\" width=\"${w}\" height=\"${h}\" ` +\n `font-family='${FONT}'>${marker}${back}${body}</svg>`\n )\n}\n\n// ── drawio (mxGraph) ────────────────────────────────────────────────────────────────────────────\nasync function drawioToSvg(text: string): Promise<string> {\n const model = await extractMxGraphModel(text)\n if (!model) throw new Error('无法解析该 drawio 文件(未找到 mxGraphModel)')\n return mxModelToSvg(model)\n}\n\nconst firstTag = (el: Document | Element, tag: string): Element | null =>\n el.getElementsByTagName(tag)[0] ?? null\n\n// Resolve to the <mxGraphModel> element, inflating a compressed first <diagram> page if needed. Uses only\n// getElementsByTagName (portable across DOM implementations — no querySelector/.children).\nasync function extractMxGraphModel(text: string): Promise<Element | null> {\n const parser = new DOMParser()\n const doc = parser.parseFromString(text, 'text/xml')\n if (firstTag(doc, 'parsererror')) return firstTag(doc, 'mxGraphModel')\n const root = doc.documentElement\n if (!root) return null\n if (root.nodeName === 'mxGraphModel') return root\n if (root.nodeName === 'mxfile') {\n const diagram = firstTag(root, 'diagram')\n if (!diagram) return firstTag(root, 'mxGraphModel')\n const childModel = firstTag(diagram, 'mxGraphModel')\n if (childModel) return childModel // uncompressed, stored as a child element\n const inner = (diagram.textContent || '').trim()\n if (!inner) return null\n const xml = inner.startsWith('<') ? inner : await inflateRaw(inner)\n return firstTag(parser.parseFromString(xml, 'text/xml'), 'mxGraphModel')\n }\n return firstTag(doc, 'mxGraphModel')\n}\n\n// base64 → raw-DEFLATE inflate → URI-decode (drawio's diagram compression).\nasync function inflateRaw(b64: string): Promise<string> {\n const bin = atob(b64.replace(/\\s+/g, ''))\n const bytes = new Uint8Array(bin.length)\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i)\n const stream = new Blob([bytes]).stream().pipeThrough(new DecompressionStream('deflate-raw'))\n const out = await new Response(stream).arrayBuffer()\n return decodeURIComponent(new TextDecoder().decode(out))\n}\n\ninterface Pt {\n x: number\n y: number\n}\ninterface Box {\n x: number\n y: number\n w: number\n h: number\n}\ntype Side = 'L' | 'R' | 'T' | 'B'\n\ninterface MxCell {\n id: string\n value: string\n style: Record<string, string>\n vertex: boolean\n edge: boolean\n source: string\n target: string\n parent: string\n geom?: { x: number; y: number; w: number; h: number; relative: boolean }\n points?: Pt[]\n srcPoint?: Pt\n tgtPoint?: Pt\n offset?: Pt\n}\n\n// \"rounded=1;fillColor=#dae8fc;ellipse\" → { rounded:'1', fillColor:'#dae8fc', ellipse:'' }\nfunction parseStyle(s: string): Record<string, string> {\n const out: Record<string, string> = {}\n for (const part of s.split(';')) {\n if (!part) continue\n const eq = part.indexOf('=')\n if (eq < 0) out[part.trim()] = ''\n else out[part.slice(0, eq).trim()] = part.slice(eq + 1).trim()\n }\n return out\n}\n\n// Decode the handful of HTML entities drawio labels actually use (&amp; resolved last to avoid double-decoding).\nfunction decodeEntities(s: string): string {\n return s\n .replace(/&#x([0-9a-f]+);/gi, (_, h) => String.fromCodePoint(Number.parseInt(h, 16)))\n .replace(/&#(\\d+);/g, (_, d) => String.fromCodePoint(Number(d)))\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&apos;|&#39;/g, \"'\")\n .replace(/&nbsp;/g, ' ')\n .replace(/&amp;/g, '&')\n}\n// drawio labels are HTML when html=1 — turn block/breaks into newlines, strip tags, decode entities.\nfunction stripHtml(s: string): string {\n if (!s) return ''\n const t = s\n .replace(/<br\\s*\\/?>/gi, '\\n')\n .replace(/<\\/(div|p|li|tr|h[1-6])>/gi, '\\n')\n .replace(/<[^>]+>/g, '')\n return decodeEntities(t)\n .replace(/ /g, ' ')\n .replace(/\\n{2,}/g, '\\n')\n .trim()\n}\n\nfunction parseCells(model: Element): { cells: MxCell[]; byId: Map<string, MxCell> } {\n const byId = new Map<string, MxCell>()\n const cells: MxCell[] = []\n for (const el of Array.from(model.getElementsByTagName('mxCell'))) {\n const c: MxCell = {\n id: el.getAttribute('id') || '',\n value: stripHtml(el.getAttribute('value') || ''),\n style: parseStyle(el.getAttribute('style') || ''),\n vertex: el.getAttribute('vertex') === '1',\n edge: el.getAttribute('edge') === '1',\n source: el.getAttribute('source') || '',\n target: el.getAttribute('target') || '',\n parent: el.getAttribute('parent') || '',\n }\n const g = el.getElementsByTagName('mxGeometry')[0]\n if (g) {\n c.geom = {\n x: num(g.getAttribute('x')),\n y: num(g.getAttribute('y')),\n w: num(g.getAttribute('width')),\n h: num(g.getAttribute('height')),\n relative: g.getAttribute('relative') === '1',\n }\n for (const pe of Array.from(g.getElementsByTagName('mxPoint'))) {\n const p = { x: num(pe.getAttribute('x')), y: num(pe.getAttribute('y')) }\n const as = pe.getAttribute('as')\n if (as === 'sourcePoint') c.srcPoint = p\n else if (as === 'targetPoint') c.tgtPoint = p\n else if (as === 'offset') c.offset = p\n }\n const arr = Array.from(g.getElementsByTagName('Array')).find(\n (a) => a.getAttribute('as') === 'points',\n )\n if (arr) {\n c.points = Array.from(arr.getElementsByTagName('mxPoint')).map((pe) => ({\n x: num(pe.getAttribute('x')),\n y: num(pe.getAttribute('y')),\n }))\n }\n }\n byId.set(c.id, c)\n cells.push(c)\n }\n return { cells, byId }\n}\n\n// A cell's geometry is relative to its parent vertex (a container/group). Walk up summing ancestor offsets to\n// get the absolute box. Stops at the root layer (parent \"0\"/\"1\", which has no geometry) or an edge parent.\nfunction absBox(c: MxCell, byId: Map<string, MxCell>): Box {\n const g = c.geom as { x: number; y: number; w: number; h: number }\n let x = g.x\n let y = g.y\n let p = byId.get(c.parent)\n while (p && p.geom && p.vertex && !p.edge) {\n x += p.geom.x\n y += p.geom.y\n p = byId.get(p.parent)\n }\n return { x, y, w: g.w, h: g.h }\n}\n\nconst boxCenter = (b: Box): Pt => ({ x: b.x + b.w / 2, y: b.y + b.h / 2 })\n\n// Fixed connection point from drawio's exitX/exitY (or entryX/entryY): a fraction of the node's box.\nfunction fixedPoint(b: Box, fx?: string, fy?: string): Pt | null {\n if (fx == null || fy == null) return null\n return { x: b.x + num(fx) * b.w, y: b.y + num(fy) * b.h }\n}\nfunction sideOfFixed(fx?: string, fy?: string): Side | null {\n if (fx == null || fy == null) return null\n const x = num(fx)\n const y = num(fy)\n if (x === 0) return 'L'\n if (x === 1) return 'R'\n if (y === 0) return 'T'\n if (y === 1) return 'B'\n return null\n}\n// Where a line from the box centre toward `toward` crosses the box's rectangular boundary.\nfunction rectPerim(b: Box, toward: Pt): Pt {\n const c = boxCenter(b)\n const dx = toward.x - c.x\n const dy = toward.y - c.y\n if (!dx && !dy) return c\n const sx = dx ? b.w / 2 / Math.abs(dx) : Infinity\n const sy = dy ? b.h / 2 / Math.abs(dy) : Infinity\n const s = Math.min(sx, sy)\n return { x: c.x + dx * s, y: c.y + dy * s }\n}\n// Same, for an ellipse node.\nfunction ellipsePerim(b: Box, toward: Pt): Pt {\n const c = boxCenter(b)\n const dx = toward.x - c.x\n const dy = toward.y - c.y\n if (!dx && !dy) return c\n const rx = b.w / 2 || 1\n const ry = b.h / 2 || 1\n const t = 1 / Math.sqrt((dx / rx) ** 2 + (dy / ry) ** 2)\n return { x: c.x + dx * t, y: c.y + dy * t }\n}\n\n// One end of an edge: a fixed exit/entry point if the style names one, else the node's perimeter toward `toward`.\nfunction endAt(\n node: MxCell,\n box: Box,\n fx: string | undefined,\n fy: string | undefined,\n toward: Pt,\n): { pt: Pt; side: Side | null } {\n const fixed = fixedPoint(box, fx, fy)\n if (fixed) return { pt: fixed, side: sideOfFixed(fx, fy) }\n const pt = 'ellipse' in node.style ? ellipsePerim(box, toward) : rectPerim(box, toward)\n return { pt, side: null }\n}\n\n// A simple orthogonal connector between two endpoints, using their box sides when known (else inferred from the\n// dominant axis). Good enough for drawio's orthogonalEdgeStyle when no explicit waypoints are given.\nfunction orthRoute(a: Pt, sa: Side | null, b: Pt, sb: Side | null): Pt[] {\n const dom = Math.abs(b.x - a.x) >= Math.abs(b.y - a.y)\n const ha = sa ? sa === 'L' || sa === 'R' : dom\n const hb = sb ? sb === 'L' || sb === 'R' : dom\n if (ha && hb) {\n const mx = (a.x + b.x) / 2\n return [a, { x: mx, y: a.y }, { x: mx, y: b.y }, b]\n }\n if (!ha && !hb) {\n const my = (a.y + b.y) / 2\n return [a, { x: a.x, y: my }, { x: b.x, y: my }, b]\n }\n if (ha && !hb) return [a, { x: b.x, y: a.y }, b]\n return [a, { x: a.x, y: b.y }, b]\n}\n\nconst hasBox = (c: MxCell | undefined): c is MxCell => !!c && !!c.geom && c.geom.w > 0\n\n// The full point list an edge is drawn through: resolved source end → waypoints → resolved target end.\nfunction edgePolyline(c: MxCell, byId: Map<string, MxCell>): Pt[] {\n const src = c.source ? byId.get(c.source) : undefined\n const tgt = c.target ? byId.get(c.target) : undefined\n const srcBox = hasBox(src) ? absBox(src, byId) : null\n const tgtBox = hasBox(tgt) ? absBox(tgt, byId) : null\n const wpts = c.points ?? []\n\n const exitFixed = srcBox ? fixedPoint(srcBox, c.style.exitX, c.style.exitY) : null\n const entryFixed = tgtBox ? fixedPoint(tgtBox, c.style.entryX, c.style.entryY) : null\n const srcRef = exitFixed ?? (srcBox ? boxCenter(srcBox) : c.srcPoint) ?? { x: 0, y: 0 }\n const tgtRef = entryFixed ?? (tgtBox ? boxCenter(tgtBox) : c.tgtPoint) ?? { x: 0, y: 0 }\n\n let a: Pt | undefined\n let sa: Side | null = null\n if (src && srcBox) {\n const r = endAt(src, srcBox, c.style.exitX, c.style.exitY, wpts[0] ?? tgtRef)\n a = r.pt\n sa = r.side\n } else a = c.srcPoint\n\n let b: Pt | undefined\n let sb: Side | null = null\n if (tgt && tgtBox) {\n const r = endAt(tgt, tgtBox, c.style.entryX, c.style.entryY, wpts[wpts.length - 1] ?? srcRef)\n b = r.pt\n sb = r.side\n } else b = c.tgtPoint\n\n if (!a || !b) return []\n if (wpts.length) return [a, ...wpts, b]\n if ((c.style.edgeStyle || '').toLowerCase().includes('orthogonal')) return orthRoute(a, sa, b, sb)\n return [a, b]\n}\n\nfunction colorOf(v: string | undefined, fallback: string): string {\n // Distinguish \"not set\" (use the fallback) from an explicit \"none\" (no paint).\n if (v === 'none') return 'none'\n if (!v) return fallback\n return v\n}\n\n// ── line jumps (jumpStyle) ──────────────────────────────────────────────────────────────────────\n// drawio draws a little hop where one connector crosses another (style `jumpStyle=arc`). Without it, crossing\n// lines look connected. We compute pairwise segment intersections between jump-enabled edges and give each\n// crossing to ONE edge (the more-horizontal segment hops over the more-vertical one — drawio's usual look).\nconst JUMP_R = 6 // hop radius, in diagram units\n\ninterface Jump {\n seg: number // segment index within the edge polyline\n t: number // param along that segment (0..1)\n}\n\nfunction jumpEnabled(c: MxCell): boolean {\n const js = (c.style.jumpStyle || '').toLowerCase()\n return js !== '' && js !== 'none' && c.style.noJump !== '1'\n}\n\n// Intersection of segments a→b and c→d, as {t,u} params, or null (parallel / not within both segments).\nfunction segIntersect(a: Pt, b: Pt, c: Pt, d: Pt): { t: number; u: number } | null {\n const rx = b.x - a.x\n const ry = b.y - a.y\n const sx = d.x - c.x\n const sy = d.y - c.y\n const denom = rx * sy - ry * sx\n if (Math.abs(denom) < 1e-9) return null\n const t = ((c.x - a.x) * sy - (c.y - a.y) * sx) / denom\n const u = ((c.x - a.x) * ry - (c.y - a.y) * rx) / denom\n if (t <= 0 || t >= 1 || u <= 0 || u >= 1) return null\n return { t, u }\n}\n\nfunction addJump(m: Map<string, Jump[]>, id: string, seg: number, t: number): void {\n const arr = m.get(id)\n if (arr) arr.push({ seg, t })\n else m.set(id, [{ seg, t }])\n}\n\nfunction computeJumps(edges: MxCell[], polys: Map<string, Pt[]>): Map<string, Jump[]> {\n const list = edges.filter((c) => jumpEnabled(c) && (polys.get(c.id)?.length ?? 0) >= 2)\n const out = new Map<string, Jump[]>()\n const near = (p: Pt, q: Pt, t: number): boolean => {\n const len = Math.hypot(q.x - p.x, q.y - p.y)\n return t * len < JUMP_R * 1.5 || (1 - t) * len < JUMP_R * 1.5\n }\n for (let i = 0; i < list.length; i++) {\n const A = polys.get(list[i].id) as Pt[]\n for (let j = i + 1; j < list.length; j++) {\n const B = polys.get(list[j].id) as Pt[]\n for (let ai = 0; ai + 1 < A.length; ai++) {\n for (let bi = 0; bi + 1 < B.length; bi++) {\n const hit = segIntersect(A[ai], A[ai + 1], B[bi], B[bi + 1])\n if (!hit) continue\n // skip crossings that are really a shared endpoint (edges meeting at the same node)\n if (near(A[ai], A[ai + 1], hit.t) || near(B[bi], B[bi + 1], hit.u)) continue\n const aHoriz = Math.abs(A[ai + 1].x - A[ai].x) >= Math.abs(A[ai + 1].y - A[ai].y)\n const bHoriz = Math.abs(B[bi + 1].x - B[bi].x) >= Math.abs(B[bi + 1].y - B[bi].y)\n // the more-horizontal segment hops; ties → the later-listed edge\n if (aHoriz && !bHoriz) addJump(out, list[i].id, ai, hit.t)\n else addJump(out, list[j].id, bi, hit.u)\n }\n }\n }\n }\n return out\n}\n\n// Build the edge path `d`, inserting a semicircular hop at each jump point on its way along the polyline.\nfunction edgePathD(poly: Pt[], jumps: Jump[] | undefined): string {\n const bySeg = new Map<number, number[]>()\n if (jumps) {\n for (const j of jumps) {\n const arr = bySeg.get(j.seg)\n if (arr) arr.push(j.t)\n else bySeg.set(j.seg, [j.t])\n }\n }\n let d = `M ${rnd(poly[0].x)} ${rnd(poly[0].y)}`\n for (let i = 0; i + 1 < poly.length; i++) {\n const p = poly[i]\n const q = poly[i + 1]\n const ts = bySeg.get(i)\n if (ts && ts.length) {\n ts.sort((m, n) => m - n)\n const len = Math.hypot(q.x - p.x, q.y - p.y) || 1\n const ux = (q.x - p.x) / len\n const uy = (q.y - p.y) / len\n for (const t of ts) {\n const jx = p.x + (q.x - p.x) * t\n const jy = p.y + (q.y - p.y) * t\n d += ` L ${rnd(jx - ux * JUMP_R)} ${rnd(jy - uy * JUMP_R)}`\n d += ` A ${JUMP_R} ${JUMP_R} 0 0 1 ${rnd(jx + ux * JUMP_R)} ${rnd(jy + uy * JUMP_R)}`\n }\n }\n d += ` L ${rnd(q.x)} ${rnd(q.y)}`\n }\n return d\n}\n\nfunction edgeSvg(c: MxCell, poly: Pt[], jumps?: Jump[]): string {\n if (poly.length < 2) return ''\n const stroke = colorOf(c.style.strokeColor, '#333333')\n const d = edgePathD(poly, jumps)\n const sw = num(c.style.strokeWidth, 1.4)\n const dash = c.style.dashed === '1' ? ' stroke-dasharray=\"6 4\"' : ''\n // drawio defaults: end arrow = classic, start arrow = none.\n const me = (c.style.endArrow ?? 'classic') !== 'none' ? ' marker-end=\"url(#dg-arrow)\"' : ''\n const ms = (c.style.startArrow ?? 'none') !== 'none' ? ' marker-start=\"url(#dg-arrow)\"' : ''\n return `<path d=\"${d}\" fill=\"none\" stroke=\"${stroke === 'none' ? '#333333' : stroke}\" stroke-width=\"${sw}\" stroke-linejoin=\"round\"${dash}${me}${ms}/>`\n}\n\ntype HAlign = 'left' | 'center' | 'right'\ntype VAlign = 'top' | 'middle' | 'bottom'\n\n// Rough per-character advance (no font metrics here): CJK / full-width glyphs ≈ 1em, latin ≈ 0.58em. Only used\n// to WRAP labels to their box width and to size the diagram's bounding box — approximate is fine.\nfunction charW(ch: string, fs: number): number {\n const c = ch.codePointAt(0) ?? 0\n const wide =\n c >= 0x1100 &&\n (c <= 0x115f || // Hangul Jamo\n (c >= 0x2e80 && c <= 0xa4cf) || // CJK radicals … Yi\n (c >= 0xac00 && c <= 0xd7a3) || // Hangul syllables\n (c >= 0xf900 && c <= 0xfaff) || // CJK compatibility ideographs\n (c >= 0xfe30 && c <= 0xfe4f) || // CJK compatibility forms\n (c >= 0xff00 && c <= 0xff60) || // full-width forms\n (c >= 0xffe0 && c <= 0xffe6) ||\n (c >= 0x20000 && c <= 0x3fffd)) // CJK extension B+\n return (wide ? 1 : 0.58) * fs\n}\nfunction textW(s: string, fs: number): number {\n let w = 0\n for (const ch of s) w += charW(ch, fs)\n return w\n}\n// Word-wrap a logical line to fit `maxW` (latin by word; long tokens / CJK runs hard-break by character).\nfunction wrapLine(line: string, fs: number, maxW: number): string[] {\n if (maxW <= 4 || textW(line, fs) <= maxW) return [line]\n const out: string[] = []\n let cur = ''\n for (const word of line.split(/\\s+/).filter((w) => w !== '')) {\n if (!cur) cur = word\n else if (textW(`${cur} ${word}`, fs) <= maxW) cur = `${cur} ${word}`\n else {\n out.push(cur)\n cur = word\n }\n // hard-break the current run when a single token still overflows (covers space-less CJK text)\n while (textW(cur, fs) > maxW) {\n let piece = ''\n let rest = ''\n let broke = false\n for (const ch of cur) {\n if (!broke && piece && textW(piece + ch, fs) > maxW) broke = true\n if (broke) rest += ch\n else piece += ch\n }\n if (!piece) break\n out.push(piece)\n cur = rest\n }\n }\n if (cur) out.push(cur)\n return out.length ? out : [line]\n}\n\ninterface LabelLayout {\n lines: string[]\n anchor: 'start' | 'middle' | 'end'\n tx: number\n firstCenter: number // y-centre of the first line\n lh: number\n fontSize: number\n bits: number\n color: string\n bbox: Box // rendered extent, so the diagram bounds can include out-of-box labels\n}\n\nconst LBL_GAP = 3 // gap between an out-of-box label and the shape edge\n\n// Lay out a cell label. Unlike a naive \"centre in the box\", this honours drawio's labelPosition /\n// verticalLabelPosition (which push the label OUTSIDE the shape — the DFD data-store labels sit above / below /\n// to the right of their tiny box), and wraps `whiteSpace=wrap` text to the box width so long labels don't spill\n// out of their shape. align / verticalAlign then place the text within its region.\nfunction labelLayout(value: string, box: Box, style: Record<string, string>): LabelLayout {\n const fontSize = num(style.fontSize, 12)\n const color = colorOf(style.fontColor, '#1a1a1a')\n const bits = num(style.fontStyle, 0)\n const align = (style.align as HAlign) || 'center'\n const valign = (style.verticalAlign as VAlign) || 'middle'\n const labelPos = style.labelPosition || 'center' // horizontal position of the label vs the cell\n const vLabelPos = style.verticalLabelPosition || 'middle'\n const wrap = style.whiteSpace === 'wrap'\n const lh = fontSize * 1.25\n\n // Horizontal placement + the width text may wrap to (only labels INSIDE the box wrap).\n let anchor: 'start' | 'middle' | 'end'\n let tx: number\n let maxW = Infinity\n if (labelPos === 'left') {\n anchor = 'end'\n tx = box.x - LBL_GAP\n } else if (labelPos === 'right') {\n anchor = 'start'\n tx = box.x + box.w + LBL_GAP\n } else if (align === 'left') {\n anchor = 'start'\n tx = box.x + 6\n if (wrap && vLabelPos === 'middle') maxW = box.w - 8\n } else if (align === 'right') {\n anchor = 'end'\n tx = box.x + box.w - 6\n if (wrap && vLabelPos === 'middle') maxW = box.w - 8\n } else {\n anchor = 'middle'\n tx = box.x + box.w / 2\n if (wrap && vLabelPos === 'middle') maxW = box.w - 8\n }\n\n const lines: string[] = []\n for (const ln of value.split('\\n')) {\n if (Number.isFinite(maxW)) lines.push(...wrapLine(ln, fontSize, maxW))\n else lines.push(ln)\n }\n const n = lines.length || 1\n\n // Vertical placement: firstCenter = y-centre of the first line.\n let firstCenter: number\n if (vLabelPos === 'top') firstCenter = box.y - LBL_GAP - (n - 1) * lh - lh / 2\n else if (vLabelPos === 'bottom') firstCenter = box.y + box.h + LBL_GAP + lh / 2\n else if (valign === 'top') firstCenter = box.y + lh / 2 + 2\n else if (valign === 'bottom') firstCenter = box.y + box.h - (n - 1) * lh - lh / 2 - 2\n else firstCenter = box.y + box.h / 2 - ((n - 1) * lh) / 2\n\n let tw = 0\n for (const ln of lines) tw = Math.max(tw, textW(ln, fontSize))\n const bx0 = anchor === 'start' ? tx : anchor === 'end' ? tx - tw : tx - tw / 2\n const by0 = firstCenter - lh / 2\n const bbox: Box = { x: bx0, y: by0, w: tw, h: n * lh }\n\n return { lines, anchor, tx, firstCenter, lh, fontSize, bits, color, bbox }\n}\n\n// Render a laid-out label to an SVG <text> (honours fontStyle bold/italic/underline).\nfunction labelSvg(value: string, box: Box, style: Record<string, string>): string {\n if (!value) return ''\n const l = labelLayout(value, box, style)\n const weight = l.bits & 1 ? ' font-weight=\"700\"' : ''\n const fstyle = l.bits & 2 ? ' font-style=\"italic\"' : ''\n const deco = l.bits & 4 ? ' text-decoration=\"underline\"' : ''\n const tspans = l.lines\n .map(\n (ln, i) => `<tspan x=\"${rnd(l.tx)}\" y=\"${rnd(l.firstCenter + i * l.lh)}\">${esc(ln)}</tspan>`,\n )\n .join('')\n return `<text text-anchor=\"${l.anchor}\" dominant-baseline=\"central\" font-size=\"${l.fontSize}\" fill=\"${l.color === 'none' ? '#1a1a1a' : l.color}\"${weight}${fstyle}${deco}>${tspans}</text>`\n}\n\nfunction vertexSvg(c: MxCell, box: Box): string {\n const style = c.style\n const fill = colorOf(style.fillColor, '#ffffff')\n const stroke = colorOf(style.strokeColor, '#333333')\n\n // A bare text label (style \"text\" with no fill/stroke): render the text only, no box — matches the many\n // borderless captions in drawio diagrams (group titles like 弱电箱 / 电视柜, free labels like 入户光纤).\n if ('text' in style && fill === 'none' && stroke === 'none') {\n return c.value ? labelSvg(c.value, box, style) : ''\n }\n\n const { x, y, w, h } = box\n const sw = num(style.strokeWidth, 1.2)\n const dash = style.dashed === '1' ? ' stroke-dasharray=\"4 3\"' : ''\n const common = `fill=\"${fill}\" stroke=\"${stroke}\" stroke-width=\"${sw}\"${dash}`\n const shapeName = (style.shape || '').toLowerCase()\n let shape: string\n if ('ellipse' in style) {\n shape = `<ellipse cx=\"${rnd(x + w / 2)}\" cy=\"${rnd(y + h / 2)}\" rx=\"${rnd(w / 2)}\" ry=\"${rnd(h / 2)}\" ${common}/>`\n } else if ('rhombus' in style) {\n const pts = `${rnd(x + w / 2)},${rnd(y)} ${rnd(x + w)},${rnd(y + h / 2)} ${rnd(x + w / 2)},${rnd(y + h)} ${rnd(x)},${rnd(y + h / 2)}`\n shape = `<polygon points=\"${pts}\" ${common}/>`\n } else if (shapeName.includes('datastore')) {\n // DFD data store (Gane–Sarson): a rectangle open on the right, with a left \"ID\" divider. Fill first, then\n // the open outline + divider on top.\n const d = Math.min(w * 0.2, 20)\n shape =\n `<rect x=\"${rnd(x)}\" y=\"${rnd(y)}\" width=\"${rnd(w)}\" height=\"${rnd(h)}\" fill=\"${fill}\" stroke=\"none\"/>` +\n `<path d=\"M ${rnd(x + w)} ${rnd(y)} L ${rnd(x)} ${rnd(y)} L ${rnd(x)} ${rnd(y + h)} L ${rnd(x + w)} ${rnd(y + h)}\" fill=\"none\" stroke=\"${stroke}\" stroke-width=\"${sw}\"${dash}/>` +\n `<line x1=\"${rnd(x + d)}\" y1=\"${rnd(y)}\" x2=\"${rnd(x + d)}\" y2=\"${rnd(y + h)}\" stroke=\"${stroke}\" stroke-width=\"${sw}\"/>`\n } else {\n const rad = style.rounded === '1' ? Math.min(12, w / 4, h / 4) : 0\n shape = `<rect x=\"${rnd(x)}\" y=\"${rnd(y)}\" width=\"${rnd(w)}\" height=\"${rnd(h)}\" rx=\"${rad}\" ry=\"${rad}\" ${common}/>`\n }\n return shape + (c.value ? labelSvg(c.value, box, style) : '')\n}\n\n// Position along a polyline by arc-length fraction (0 = start, 1 = end).\nfunction pointAtFraction(poly: Pt[], t: number): Pt {\n if (poly.length === 1) return poly[0]\n const segs: number[] = []\n let total = 0\n for (let i = 1; i < poly.length; i++) {\n const d = Math.hypot(poly[i].x - poly[i - 1].x, poly[i].y - poly[i - 1].y)\n segs.push(d)\n total += d\n }\n if (total === 0) return poly[0]\n let want = t * total\n for (let i = 0; i < segs.length; i++) {\n if (want <= segs[i] || i === segs.length - 1) {\n const f = segs[i] ? want / segs[i] : 0\n return {\n x: poly[i].x + (poly[i + 1].x - poly[i].x) * f,\n y: poly[i].y + (poly[i + 1].y - poly[i].y) * f,\n }\n }\n want -= segs[i]\n }\n return poly[poly.length - 1]\n}\n\n// An edge label (a child cell of an edge): drawio stores its position as a fraction along the edge (geometry x,\n// -1..1) plus a pixel offset. White-backed so it stays legible over the line.\n// The white-backed box an edge label occupies (positioned by its fraction along the edge + pixel offset).\nfunction edgeLabelBox(c: MxCell, poly: Pt[]): Box | null {\n if (!c.value || poly.length < 2) return null\n const t = clamp(((c.geom?.x ?? 0) + 1) / 2, 0, 1)\n const base = pointAtFraction(poly, t)\n const off = c.offset ?? { x: 0, y: 0 }\n const cx = base.x + off.x\n const cy = base.y + off.y\n const fontSize = num(c.style.fontSize, 11)\n const lines = c.value.split('\\n')\n let tw = 0\n for (const l of lines) tw = Math.max(tw, textW(l, fontSize))\n tw += 8\n const th = lines.length * fontSize * 1.25 + 4\n return { x: cx - tw / 2, y: cy - th / 2, w: tw, h: th }\n}\n\nfunction edgeLabelSvg(c: MxCell, poly: Pt[]): string {\n const box = edgeLabelBox(c, poly)\n if (!box) return ''\n return (\n `<rect x=\"${rnd(box.x)}\" y=\"${rnd(box.y)}\" width=\"${rnd(box.w)}\" height=\"${rnd(box.h)}\" fill=\"#ffffff\" opacity=\"0.82\" rx=\"3\"/>` +\n labelSvg(c.value, box, c.style)\n )\n}\n\nfunction mxModelToSvg(model: Element): string {\n const { cells, byId } = parseCells(model)\n\n // Precompute every edge's polyline once (edges draw it; their labels position along it).\n const edgePaths = new Map<string, Pt[]>()\n for (const c of cells) if (c.edge) edgePaths.set(c.id, edgePolyline(c, byId))\n\n const isEdgeLabel = (c: MxCell): boolean => c.vertex && (byId.get(c.parent)?.edge ?? false)\n const drawableVertex = (c: MxCell): boolean =>\n c.vertex && !isEdgeLabel(c) && !!c.geom && c.geom.w > 0 && c.geom.h > 0\n\n // Bounding box over node boxes + every edge point.\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n const grow = (x: number, y: number): void => {\n minX = Math.min(minX, x)\n minY = Math.min(minY, y)\n maxX = Math.max(maxX, x)\n maxY = Math.max(maxY, y)\n }\n for (const c of cells) {\n if (drawableVertex(c)) {\n const b = absBox(c, byId)\n grow(b.x, b.y)\n grow(b.x + b.w, b.y + b.h)\n // Include the label's rendered extent — drawio labels can sit OUTSIDE the shape (e.g. the DFD data-store\n // labels above / below / right of their box), which would otherwise be clipped by the viewBox.\n if (c.value) {\n const lb = labelLayout(c.value, b, c.style).bbox\n grow(lb.x, lb.y)\n grow(lb.x + lb.w, lb.y + lb.h)\n }\n } else if (isEdgeLabel(c)) {\n const lb = edgeLabelBox(c, edgePaths.get(c.parent) ?? [])\n if (lb) {\n grow(lb.x, lb.y)\n grow(lb.x + lb.w, lb.y + lb.h)\n }\n }\n }\n for (const poly of edgePaths.values()) for (const p of poly) grow(p.x, p.y)\n if (!Number.isFinite(minX)) throw new Error('该 drawio 文件没有可绘制的图形')\n\n // Precompute the crossing hops (jumpStyle) once, keyed by edge id.\n const jumps = computeJumps(\n cells.filter((c) => c.edge),\n edgePaths,\n )\n\n // Render in DOCUMENT ORDER so a container box defined before an edge sits BEHIND it (and inner nodes defined\n // after the edge sit on top) — this matches drawio's z-order and is what makes an edge cross INTO a group box\n // to reach an inner node, instead of the white container painting over the line.\n const out: string[] = []\n for (const c of cells) {\n if (c.edge) out.push(edgeSvg(c, edgePaths.get(c.id) ?? [], jumps.get(c.id)))\n else if (isEdgeLabel(c)) out.push(edgeLabelSvg(c, edgePaths.get(c.parent) ?? []))\n else if (drawableVertex(c)) out.push(vertexSvg(c, absBox(c, byId)))\n }\n\n const pad = 24\n const w = maxX - minX + pad * 2\n const h = maxY - minY + pad * 2\n const vb = `${rnd(minX - pad)} ${rnd(minY - pad)} ${rnd(w)} ${rnd(h)}`\n return svgWrap(vb, rnd(w), rnd(h), '#ffffff', out.join(''))\n}\n\n// ── excalidraw ────────────────────────────────────────────────────────────────────────────────\ninterface ExEl {\n type: string\n x: number\n y: number\n width: number\n height: number\n angle?: number\n strokeColor?: string\n backgroundColor?: string\n strokeWidth?: number\n opacity?: number\n roundness?: unknown\n points?: [number, number][]\n text?: string\n fontSize?: number\n isDeleted?: boolean\n}\n\nfunction excalidrawToSvg(text: string): string {\n const data = JSON.parse(text) as {\n elements?: ExEl[]\n appState?: { viewBackgroundColor?: string }\n }\n const els = (data.elements ?? []).filter((e) => e && !e.isDeleted)\n if (!els.length) throw new Error('该 excalidraw 场景没有元素')\n\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n for (const e of els) {\n const xs = [e.x, e.x + (e.width || 0)]\n const ys = [e.y, e.y + (e.height || 0)]\n for (const p of e.points ?? []) {\n xs.push(e.x + p[0])\n ys.push(e.y + p[1])\n }\n minX = Math.min(minX, ...xs)\n maxX = Math.max(maxX, ...xs)\n minY = Math.min(minY, ...ys)\n maxY = Math.max(maxY, ...ys)\n }\n if (!Number.isFinite(minX)) throw new Error('该 excalidraw 场景没有可绘制的元素')\n\n const body = els.map(excalidrawEl).join('')\n const pad = 16\n const w = maxX - minX + pad * 2\n const h = maxY - minY + pad * 2\n const vb = `${minX - pad} ${minY - pad} ${w} ${h}`\n return svgWrap(vb, w, h, data.appState?.viewBackgroundColor || '#ffffff', body)\n}\n\nfunction excalidrawEl(e: ExEl): string {\n const stroke = e.strokeColor && e.strokeColor !== 'transparent' ? e.strokeColor : '#1e1e1e'\n const fill = e.backgroundColor && e.backgroundColor !== 'transparent' ? e.backgroundColor : 'none'\n const sw = e.strokeWidth ?? 1.5\n const op = e.opacity != null ? e.opacity / 100 : 1\n const cx = e.x + (e.width || 0) / 2\n const cy = e.y + (e.height || 0) / 2\n const rot = e.angle ? ` transform=\"rotate(${(e.angle * 180) / Math.PI} ${cx} ${cy})\"` : ''\n const g = (inner: string): string => `<g opacity=\"${op}\"${rot}>${inner}</g>`\n\n switch (e.type) {\n case 'rectangle': {\n const r = e.roundness ? Math.min(32, (e.width || 0) / 4, (e.height || 0) / 4) : 0\n return g(\n `<rect x=\"${e.x}\" y=\"${e.y}\" width=\"${e.width}\" height=\"${e.height}\" rx=\"${r}\" ry=\"${r}\" fill=\"${fill}\" stroke=\"${stroke}\" stroke-width=\"${sw}\"/>`,\n )\n }\n case 'ellipse':\n return g(\n `<ellipse cx=\"${cx}\" cy=\"${cy}\" rx=\"${(e.width || 0) / 2}\" ry=\"${(e.height || 0) / 2}\" fill=\"${fill}\" stroke=\"${stroke}\" stroke-width=\"${sw}\"/>`,\n )\n case 'diamond': {\n const pts = `${cx},${e.y} ${e.x + (e.width || 0)},${cy} ${cx},${e.y + (e.height || 0)} ${e.x},${cy}`\n return g(`<polygon points=\"${pts}\" fill=\"${fill}\" stroke=\"${stroke}\" stroke-width=\"${sw}\"/>`)\n }\n case 'text':\n return g(\n textLeft(\n e.text || '',\n e.x,\n e.y,\n e.fontSize ?? 16,\n e.strokeColor && e.strokeColor !== 'transparent' ? e.strokeColor : '#1e1e1e',\n ),\n )\n case 'arrow':\n case 'line':\n case 'draw':\n case 'freedraw': {\n const pts = (e.points ?? []).map((p) => `${e.x + p[0]},${e.y + p[1]}`).join(' ')\n if (!pts) return ''\n const arrow = e.type === 'arrow' ? ' marker-end=\"url(#dg-arrow)\"' : ''\n return g(\n `<polyline points=\"${pts}\" fill=\"none\" stroke=\"${stroke}\" stroke-width=\"${sw}\"${arrow}/>`,\n )\n }\n default:\n // Unknown element (image / frame / embeddable …): a faint placeholder box keeps the layout honest.\n if (e.width && e.height) {\n return g(\n `<rect x=\"${e.x}\" y=\"${e.y}\" width=\"${e.width}\" height=\"${e.height}\" fill=\"none\" stroke=\"#bbbbbb\" stroke-width=\"1\" stroke-dasharray=\"4 4\"/>`,\n )\n }\n return ''\n }\n}\n\n// Left-anchored, top-based multi-line text (excalidraw text origin is the top-left).\nfunction textLeft(text: string, x: number, y: number, fontSize: number, color: string): string {\n const lh = fontSize * 1.25\n const tspans = text\n .split('\\n')\n .map((ln, i) => `<tspan x=\"${x}\" y=\"${y + fontSize + i * lh}\">${esc(ln)}</tspan>`)\n .join('')\n return `<text font-size=\"${fontSize}\" fill=\"${color}\">${tspans}</text>`\n}\n"],"mappings":"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"}
package/dist/lib/dicom.js CHANGED
@@ -440,3 +440,5 @@ function h(l) {
440
440
  }
441
441
  //#endregion
442
442
  export { n as DicomError, h as readDicom };
443
+
444
+ //# sourceMappingURL=dicom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dicom.js","names":[],"sources":["../../src/lib/dicom.ts"],"sourcesContent":["/**\n * DICOM (.dcm) container parsing for the side-viewer image preview.\n *\n * We use `dicom-parser` (zero-dependency, MIT) ONLY to walk the DICOM Part-10 byte stream and pull out the\n * header attributes + the Pixel Data element. Everything visual — decoding compressed pixel data, the\n * modality/VOI LUTs, windowing, photometric interpretation — is done by us (see lib/dicomCodecs.ts and\n * lib/dicomRender.ts), the same hand-rolled philosophy as the zip/7z/binobj viewers.\n *\n * A DICOM image is a grid of stored pixel samples plus the metadata needed to turn them into something a\n * screen can show: how many bits, signed or not, grayscale vs colour, how to rescale to real units, and a\n * default window (brightness/contrast). This module extracts that metadata and hands raw per-frame bytes to\n * the codec/render layers; it deliberately does no rendering itself.\n */\nimport dicomParser, { type DataSet, type Element } from 'dicom-parser'\n\n/** Tags we read, as dicom-parser's lowercase `xggggeeee` keys. */\nconst TAG = {\n transferSyntax: 'x00020010',\n samplesPerPixel: 'x00280002',\n photometric: 'x00280004',\n planarConfiguration: 'x00280006',\n numberOfFrames: 'x00280008',\n rows: 'x00280010',\n columns: 'x00280011',\n bitsAllocated: 'x00280100',\n bitsStored: 'x00280101',\n highBit: 'x00280102',\n pixelRepresentation: 'x00280103',\n windowCenter: 'x00281050',\n windowWidth: 'x00281051',\n rescaleIntercept: 'x00281052',\n rescaleSlope: 'x00281053',\n // Palette colour LUTs\n redDescriptor: 'x00281101',\n greenDescriptor: 'x00281102',\n blueDescriptor: 'x00281103',\n redData: 'x00281201',\n greenData: 'x00281202',\n blueData: 'x00281203',\n // Descriptive (for the info strip; no patient identifiers are surfaced)\n modality: 'x00080060',\n studyDescription: 'x00081030',\n seriesDescription: 'x0008103e',\n bodyPart: 'x00180015',\n pixelData: 'x7fe00010',\n} as const\n\nexport interface DicomPalette {\n r: Uint8ClampedArray\n g: Uint8ClampedArray\n b: Uint8ClampedArray\n}\n\nexport interface DicomMeta {\n transferSyntaxUid: string\n rows: number\n columns: number\n samplesPerPixel: number\n photometric: string\n bitsAllocated: number\n bitsStored: number\n highBit: number\n /** 0 = unsigned, 1 = two's-complement signed stored values. */\n pixelRepresentation: number\n /** 0 = colour-by-pixel (interleaved RGB), 1 = colour-by-plane (RRR…GGG…BBB). */\n planarConfiguration: number\n numberOfFrames: number\n /** Default VOI window from the file, or null when absent (then we auto-compute one from the pixels). */\n windowCenter: number | null\n windowWidth: number | null\n rescaleSlope: number\n rescaleIntercept: number\n palette: DicomPalette | null\n modality: string\n studyDescription: string\n seriesDescription: string\n bodyPart: string\n}\n\n/** One label→value metadata row (a single DICOM attribute, formatted for display). */\nexport interface DicomTagRow {\n label: string\n value: string\n}\n\n/** A titled group of metadata rows (Patient / Study / Series / …), for the viewer's info panel. */\nexport interface DicomTagGroup {\n title: string\n rows: DicomTagRow[]\n}\n\n/**\n * One slice of a series-stack: an independent DICOM *file* (its own Part-10 header), lazily fetched. The\n * DICOM viewer can browse a list of these as a single scrollable series — the classic hospital export shape\n * where one folder = one series and every file is a single-frame slice. `load()` returns the file's bytes\n * on demand (decoded/cached by the viewer), so hundreds of slices cost nothing until scrolled to.\n */\nexport interface DicomSlice {\n name: string\n size?: number\n load: () => Promise<ArrayBuffer>\n}\n\nexport interface ParsedDicom {\n meta: DicomMeta\n /** Whether the Pixel Data is encapsulated (any compressed transfer syntax). */\n encapsulated: boolean\n /** Curated, human-labelled metadata (present attributes only), grouped for the on-demand info panel. */\n tags: DicomTagGroup[]\n /** Pull the raw bytes for frame `i` — encoded bytes when compressed, raw samples when uncompressed. */\n frameBytes(i: number): Uint8Array\n}\n\nexport class DicomError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'DicomError'\n }\n}\n\nfunction num(ds: DataSet, tag: string, fallback: number): number {\n const v = ds.uint16(tag)\n return typeof v === 'number' && Number.isFinite(v) ? v : fallback\n}\n\nfunction float(ds: DataSet, tag: string, fallback: number): number {\n const v = ds.floatString(tag, 0)\n return typeof v === 'number' && Number.isFinite(v) ? v : fallback\n}\n\nfunction floatOrNull(ds: DataSet, tag: string): number | null {\n const v = ds.floatString(tag, 0)\n return typeof v === 'number' && Number.isFinite(v) ? v : null\n}\n\nfunction str(ds: DataSet, tag: string): string {\n return (ds.string(tag) ?? '').trim()\n}\n\n// A palette-colour LUT element: a 3-value descriptor (entry count, first mapped value, bits/entry) plus the\n// LUT data. 16-bit LUTs are common; we down-sample them to 8-bit per channel for canvas output.\nfunction readPalette(ds: DataSet): DicomPalette | null {\n const rd = ds.elements[TAG.redData]\n const gd = ds.elements[TAG.greenData]\n const bd = ds.elements[TAG.blueData]\n const desc = ds.elements[TAG.redDescriptor]\n if (!rd || !gd || !bd || !desc) return null\n // Descriptor: [numberOfEntries, firstValueMapped, bitsPerEntry]; numberOfEntries 0 means 65536.\n let entries = ds.uint16(TAG.redDescriptor, 0) ?? 0\n if (entries === 0) entries = 65536\n const bits = ds.uint16(TAG.redDescriptor, 2) ?? 8\n const channel = (el: Element): Uint8ClampedArray => {\n const out = new Uint8ClampedArray(entries)\n const bytes = ds.byteArray\n if (bits === 16) {\n // 16-bit LUT, little-endian; take the high byte as the 8-bit value.\n for (let i = 0; i < entries; i++) {\n const off = el.dataOffset + i * 2\n out[i] = off + 1 < bytes.length ? bytes[off + 1] : 0\n }\n } else {\n for (let i = 0; i < entries; i++) {\n const off = el.dataOffset + i\n out[i] = off < bytes.length ? bytes[off] : 0\n }\n }\n return out\n }\n return { r: channel(rd), g: channel(gd), b: channel(bd) }\n}\n\nconst UNCOMPRESSED = new Set([\n '1.2.840.10008.1.2', // Implicit VR Little Endian\n '1.2.840.10008.1.2.1', // Explicit VR Little Endian\n '1.2.840.10008.1.2.2', // Explicit VR Big Endian (handled via byte-swap in the render layer)\n])\n\n// --- Metadata table ---------------------------------------------------------------------------------------\n//\n// A curated, labelled subset of DICOM attributes for the viewer's on-demand info panel. We don't ship a full\n// data dictionary (dicom-parser has none), so we read a hand-picked set of common, useful tags by their known\n// keys + VR kind. `kind` picks the reader/formatter: 'us' is a binary unsigned-short; everything else is a\n// string VR read via dataSet.string(), with date/time/name reformatted for humans.\n\ntype TagKind = 'text' | 'name' | 'date' | 'time' | 'us'\ninterface TagSpec {\n tag: string\n label: string\n kind?: TagKind\n}\ninterface TagGroupSpec {\n title: string\n specs: TagSpec[]\n}\n\nconst TAG_GROUPS: TagGroupSpec[] = [\n {\n title: '患者',\n specs: [\n { tag: 'x00100010', label: '姓名', kind: 'name' },\n { tag: 'x00100020', label: 'ID' },\n { tag: 'x00100030', label: '出生日期', kind: 'date' },\n { tag: 'x00100040', label: '性别' },\n { tag: 'x00101010', label: '年龄' },\n { tag: 'x00101030', label: '体重 (kg)' },\n { tag: 'x00101020', label: '身高 (m)' },\n ],\n },\n {\n title: '检查 (Study)',\n specs: [\n { tag: 'x00080020', label: '检查日期', kind: 'date' },\n { tag: 'x00080030', label: '检查时间', kind: 'time' },\n { tag: 'x00081030', label: '检查描述' },\n { tag: 'x00080050', label: '登记号' },\n { tag: 'x00200010', label: 'Study ID' },\n { tag: 'x00080090', label: '申请医师', kind: 'name' },\n { tag: 'x0020000d', label: 'Study UID' },\n ],\n },\n {\n title: '序列 (Series)',\n specs: [\n { tag: 'x00080060', label: '设备类型' },\n { tag: 'x0008103e', label: '序列描述' },\n { tag: 'x00200011', label: '序列号' },\n { tag: 'x00180015', label: '检查部位' },\n { tag: 'x00185100', label: '患者体位' },\n { tag: 'x00080021', label: '序列日期', kind: 'date' },\n { tag: 'x00080031', label: '序列时间', kind: 'time' },\n { tag: 'x0020000e', label: 'Series UID' },\n ],\n },\n {\n title: '设备',\n specs: [\n { tag: 'x00080070', label: '厂商' },\n { tag: 'x00081090', label: '型号' },\n { tag: 'x00080080', label: '机构' },\n { tag: 'x00081010', label: '工作站' },\n { tag: 'x00181020', label: '软件版本' },\n { tag: 'x00080008', label: '图像类型' },\n ],\n },\n {\n title: '采集参数',\n specs: [\n { tag: 'x00181030', label: '协议名' },\n { tag: 'x00180050', label: '层厚 (mm)' },\n { tag: 'x00180088', label: '层间距 (mm)' },\n { tag: 'x00201041', label: '层位置' },\n { tag: 'x00180060', label: 'KVP' },\n { tag: 'x00181151', label: '管电流 (mA)' },\n { tag: 'x00181150', label: '曝光时间 (ms)' },\n { tag: 'x00181152', label: '曝光量 (mAs)' },\n { tag: 'x00181210', label: '卷积核' },\n { tag: 'x00180080', label: '重复时间 TR (ms)' },\n { tag: 'x00180081', label: '回波时间 TE (ms)' },\n { tag: 'x00180087', label: '磁场强度 (T)' },\n { tag: 'x00181314', label: '翻转角 (°)' },\n ],\n },\n {\n title: '图像',\n specs: [\n { tag: 'x00200013', label: '实例号' },\n { tag: 'x00280008', label: '帧数' },\n { tag: 'x00280010', label: '行 (Rows)', kind: 'us' },\n { tag: 'x00280011', label: '列 (Columns)', kind: 'us' },\n { tag: 'x00280100', label: 'Bits Allocated', kind: 'us' },\n { tag: 'x00280101', label: 'Bits Stored', kind: 'us' },\n { tag: 'x00280002', label: 'Samples/Pixel', kind: 'us' },\n { tag: 'x00280004', label: '光度' },\n { tag: 'x00280030', label: '像素间距' },\n { tag: 'x00281050', label: '窗位' },\n { tag: 'x00281051', label: '窗宽' },\n { tag: 'x00281052', label: '截距' },\n { tag: 'x00281053', label: '斜率' },\n ],\n },\n]\n\nfunction fmtDate(s: string): string {\n const m = /^(\\d{4})(\\d{2})(\\d{2})/.exec(s)\n return m ? `${m[1]}-${m[2]}-${m[3]}` : s\n}\nfunction fmtTime(s: string): string {\n const m = /^(\\d{2})(\\d{2})(\\d{2})/.exec(s)\n return m ? `${m[1]}:${m[2]}:${m[3]}` : s\n}\nfunction fmtPersonName(s: string): string {\n // DICOM PN is caret-delimited (Family^Given^Middle^Prefix^Suffix); show as spaced words.\n return s.replace(/\\^+/g, ' ').replace(/\\s+/g, ' ').trim()\n}\n\nfunction readTagValue(ds: DataSet, spec: TagSpec): string {\n if (spec.kind === 'us') {\n const v = ds.uint16(spec.tag)\n return typeof v === 'number' && Number.isFinite(v) ? String(v) : ''\n }\n const raw = (ds.string(spec.tag) ?? '').trim()\n if (!raw) return ''\n if (spec.kind === 'date') return fmtDate(raw)\n if (spec.kind === 'time') return fmtTime(raw)\n if (spec.kind === 'name') return fmtPersonName(raw)\n // Multi-valued attributes are backslash-delimited; show them comfortably.\n return raw.replace(/\\\\/g, ' / ')\n}\n\n/** Build the curated metadata table, keeping only present (non-empty) attributes and non-empty groups. */\nfunction readTagGroups(ds: DataSet): DicomTagGroup[] {\n const groups: DicomTagGroup[] = []\n for (const g of TAG_GROUPS) {\n const rows: DicomTagRow[] = []\n for (const spec of g.specs) {\n const value = readTagValue(ds, spec)\n if (value) rows.push({ label: spec.label, value })\n }\n if (rows.length > 0) groups.push({ title: g.title, rows })\n }\n return groups\n}\n\n/**\n * Parse a DICOM file. Throws {@link DicomError} when it isn't DICOM, has no image, or uses an unsupported\n * image layout (e.g. 1-bit bitmaps). Compressed pixel data is left encoded — the codec layer decodes it\n * lazily per frame; this just locates the bytes.\n */\nexport function readDicom(buf: ArrayBuffer): ParsedDicom {\n const byteArray = new Uint8Array(buf)\n // DICOM Part-10: 128-byte preamble + \"DICM\" magic. dicom-parser also accepts headerless streams, but we\n // require the magic so we don't misread an arbitrary binary as DICOM.\n if (\n byteArray.length < 132 ||\n byteArray[128] !== 0x44 ||\n byteArray[129] !== 0x49 ||\n byteArray[130] !== 0x43 ||\n byteArray[131] !== 0x4d\n ) {\n throw new DicomError('不是有效的 DICOM 文件(缺少 DICM 标识)')\n }\n\n let ds: DataSet\n try {\n ds = dicomParser.parseDicom(byteArray)\n } catch (e) {\n throw new DicomError(`DICOM 解析失败:${e instanceof Error ? e.message : String(e)}`)\n }\n\n const pixelData = ds.elements[TAG.pixelData]\n if (!pixelData) throw new DicomError('该 DICOM 不含像素数据(可能仅为结构化报告/元数据)')\n\n const rows = num(ds, TAG.rows, 0)\n const columns = num(ds, TAG.columns, 0)\n if (rows < 1 || columns < 1) throw new DicomError('像素尺寸无效')\n\n const bitsAllocated = num(ds, TAG.bitsAllocated, 8)\n if (bitsAllocated !== 8 && bitsAllocated !== 16) {\n throw new DicomError(`暂不支持 ${bitsAllocated}-bit 像素(仅支持 8/16-bit)`)\n }\n\n const meta: DicomMeta = {\n transferSyntaxUid: str(ds, TAG.transferSyntax) || '1.2.840.10008.1.2',\n rows,\n columns,\n samplesPerPixel: num(ds, TAG.samplesPerPixel, 1),\n photometric: str(ds, TAG.photometric) || 'MONOCHROME2',\n bitsAllocated,\n bitsStored: num(ds, TAG.bitsStored, bitsAllocated),\n highBit: num(ds, TAG.highBit, bitsAllocated - 1),\n pixelRepresentation: num(ds, TAG.pixelRepresentation, 0),\n planarConfiguration: num(ds, TAG.planarConfiguration, 0),\n numberOfFrames: Math.max(1, ds.intString(TAG.numberOfFrames) ?? 1),\n windowCenter: floatOrNull(ds, TAG.windowCenter),\n windowWidth: floatOrNull(ds, TAG.windowWidth),\n rescaleSlope: float(ds, TAG.rescaleSlope, 1),\n rescaleIntercept: float(ds, TAG.rescaleIntercept, 0),\n palette: null,\n modality: str(ds, TAG.modality),\n studyDescription: str(ds, TAG.studyDescription),\n seriesDescription: str(ds, TAG.seriesDescription),\n bodyPart: str(ds, TAG.bodyPart),\n }\n if (meta.photometric === 'PALETTE COLOR') meta.palette = readPalette(ds)\n\n const tags = readTagGroups(ds)\n const encapsulated = !UNCOMPRESSED.has(meta.transferSyntaxUid)\n const isRle = meta.transferSyntaxUid === '1.2.840.10008.1.2.5'\n\n // Uncompressed: frames are contiguous, fixed stride. Compressed: pull encoded bytes per frame via the\n // basic offset table / fragments.\n const frameSize = rows * columns * meta.samplesPerPixel * (bitsAllocated / 8)\n const totalFrames = meta.numberOfFrames\n\n function frameBytes(i: number): Uint8Array {\n const frame = Math.min(Math.max(i, 0), totalFrames - 1)\n if (!encapsulated) {\n const start = pixelData.dataOffset + frame * frameSize\n return byteArray.subarray(start, start + frameSize)\n }\n try {\n // RLE: the spec mandates exactly one fragment per frame, so fragment index == frame index.\n if (isRle) {\n return dicomParser.readEncapsulatedPixelDataFromFragments(ds, pixelData, frame)\n }\n // JPEG / JPEG-LS / JPEG2000: a frame may span multiple fragments. Prefer the file's basic offset\n // table; when absent, rebuild one by scanning codestream markers (handles multi-fragment frames like\n // some J2K ultrasound) so readEncapsulatedImageFrame concatenates each frame's fragments correctly.\n let bot = pixelData.basicOffsetTable\n if (!bot || bot.length === 0) {\n try {\n bot = dicomParser.createJPEGBasicOffsetTable(ds, pixelData)\n } catch {\n bot = []\n }\n }\n if (bot && bot.length > 0) {\n return dicomParser.readEncapsulatedImageFrame(ds, pixelData, frame, bot)\n }\n // Still no offset table: a lone frame uses all fragments; otherwise assume one fragment per frame.\n const fragmentCount = pixelData.fragments?.length ?? 1\n if (totalFrames <= 1) {\n return dicomParser.readEncapsulatedPixelDataFromFragments(ds, pixelData, 0, fragmentCount)\n }\n return dicomParser.readEncapsulatedPixelDataFromFragments(ds, pixelData, frame)\n } catch (e) {\n throw new DicomError(\n `读取第 ${frame + 1} 帧像素失败:${e instanceof Error ? e.message : String(e)}`,\n )\n }\n }\n\n return { meta, encapsulated, tags, frameBytes }\n}\n"],"mappings":"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"}
@@ -154,3 +154,5 @@ function g(e, t) {
154
154
  }
155
155
  //#endregion
156
156
  export { i as UnsupportedTransferSyntaxError, m as decodeDicomFrame, r as transferSyntaxName };
157
+
158
+ //# sourceMappingURL=dicomCodecs.js.map