@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
@@ -121,3 +121,5 @@ var d = { class: "tree" }, f = ["onClick"], p = {
121
121
  });
122
122
  //#endregion
123
123
  export { x as default };
124
+
125
+ //# sourceMappingURL=EplTree.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EplTree.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/epl/EplTree.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport type { EplProgram, EplClassKind } from '@/lib/epl'\nimport type { EplDocRef, EplDocKind } from './docTypes'\n\n/**\n * The 易语言 IDE「程序」tree: every 程序集 / 窗口程序集 / 类 at the top level (expandable to its 子程序), then\n * the project-level tables (全局变量 / 自定义数据类型 / Dll命令 / 常量表 / 资源表 / 模块引用表) — each shown\n * only when it has content. Clicking a node opens its document; clicking a method jumps to it inside the class\n * document.\n */\nconst props = defineProps<{ program: EplProgram; activeId: string }>()\nconst emit = defineEmits<{\n (e: 'select', ref: EplDocRef): void\n (e: 'selectMethod', payload: { classId: number; methodId: number }): void\n}>()\n\nconst expanded = ref<Set<number>>(new Set())\nfunction toggle(classId: number): void {\n const s = new Set(expanded.value)\n if (s.has(classId)) s.delete(classId)\n else s.add(classId)\n expanded.value = s\n}\n\nconst KIND_ICON: Record<EplClassKind, { ch: string; cls: string }> = {\n static: { ch: '集', cls: 'ico--static' },\n form: { ch: '窗', cls: 'ico--form' },\n class: { ch: '类', cls: 'ico--class' },\n}\n\ninterface TableNode {\n kind: EplDocKind\n title: string\n count: number\n}\nconst tableNodes = computed<TableNode[]>(() => {\n const p = props.program\n const all: TableNode[] = [\n { kind: 'globals', title: '全局变量', count: p.globals.length },\n { kind: 'structs', title: '自定义数据类型', count: p.structs.length },\n { kind: 'dll', title: 'Dll命令', count: p.dllDeclares.length },\n { kind: 'constants', title: '常量表', count: p.constants.length },\n { kind: 'resources', title: '图片/声音', count: p.resources.length },\n { kind: 'forms', title: '资源表', count: p.forms.length },\n { kind: 'libraries', title: '模块引用表', count: p.libraries.length },\n ]\n return all.filter((n) => n.count > 0)\n})\n\nfunction selectClass(classId: number, title: string): void {\n emit('select', { id: `class:${classId >>> 0}`, kind: 'class', classId, title })\n}\nfunction selectTable(n: TableNode): void {\n emit('select', { id: n.kind, kind: n.kind, title: n.title })\n}\n</script>\n\n<template>\n <div class=\"tree\">\n <div class=\"tree__root\">程序数据</div>\n\n <div v-for=\"c in program.classes\" :key=\"c.id\" class=\"tree__group\">\n <div class=\"tree__node\" :class=\"{ 'is-active': activeId === `class:${c.id >>> 0}` }\">\n <button\n v-if=\"c.methods.length\"\n type=\"button\"\n class=\"tree__caret\"\n :class=\"{ 'is-open': expanded.has(c.id) }\"\n @click=\"toggle(c.id)\"\n >\n ▶\n </button>\n <span v-else class=\"tree__caret tree__caret--empty\" />\n <button type=\"button\" class=\"tree__label\" @click=\"selectClass(c.id, c.name)\">\n <span class=\"ico\" :class=\"KIND_ICON[c.kind].cls\">{{ KIND_ICON[c.kind].ch }}</span>\n <span class=\"tree__name\">{{ c.name }}</span>\n </button>\n </div>\n <div v-if=\"expanded.has(c.id)\" class=\"tree__children\">\n <button\n v-for=\"m in c.methods\"\n :key=\"m.id\"\n type=\"button\"\n class=\"tree__method\"\n @click=\"emit('selectMethod', { classId: c.id, methodId: m.id })\"\n >\n <span class=\"ico ico--method\">子</span>\n <span class=\"tree__name\">{{ m.name }}</span>\n </button>\n </div>\n </div>\n\n <button\n v-for=\"n in tableNodes\"\n :key=\"n.kind\"\n type=\"button\"\n class=\"tree__node tree__label tree__table\"\n :class=\"{ 'is-active': activeId === n.kind }\"\n @click=\"selectTable(n)\"\n >\n <span class=\"ico ico--table\">表</span>\n <span class=\"tree__name\">{{ n.title }}</span>\n </button>\n </div>\n</template>\n\n<style scoped>\n.tree {\n font-size: 12.5px;\n padding: 6px 0;\n user-select: none;\n color: var(--epl-fg);\n}\n.tree__root {\n padding: 2px 10px 4px;\n font-weight: 600;\n color: var(--epl-th-fg);\n}\n.tree__node {\n display: flex;\n align-items: center;\n gap: 2px;\n width: 100%;\n}\n.tree__node.is-active,\n.tree__table.is-active {\n background: var(--epl-sel);\n}\n.tree__caret {\n flex: 0 0 auto;\n width: 16px;\n height: 18px;\n padding: 0;\n border: none;\n background: none;\n cursor: pointer;\n color: var(--epl-gutter);\n font-size: 8px;\n transition: transform 0.1s;\n}\n.tree__caret.is-open {\n transform: rotate(90deg);\n}\n.tree__caret--empty {\n cursor: default;\n}\n.tree__label {\n display: flex;\n align-items: center;\n gap: 6px;\n flex: 1 1 auto;\n min-width: 0;\n padding: 2px 10px 2px 0;\n border: none;\n background: none;\n cursor: pointer;\n text-align: left;\n color: inherit;\n font: inherit;\n}\n.tree__label:hover {\n color: var(--epl-ident);\n}\n.tree__table {\n padding-left: 18px;\n}\n.tree__children {\n display: flex;\n flex-direction: column;\n}\n.tree__method {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 1px 10px 1px 34px;\n border: none;\n background: none;\n cursor: pointer;\n text-align: left;\n color: inherit;\n font: inherit;\n}\n.tree__method:hover {\n color: var(--epl-ident);\n}\n.tree__name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.ico {\n flex: 0 0 auto;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 15px;\n height: 15px;\n border-radius: 3px;\n font-size: 10px;\n color: #fff;\n line-height: 1;\n}\n.ico--static {\n background: #5b8def;\n}\n.ico--form {\n background: #8a6fd0;\n}\n.ico--class {\n background: #2fa37a;\n}\n.ico--method {\n background: #c0894a;\n}\n.ico--table {\n background: #888;\n}\n</style>\n"],"mappings":"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"}
@@ -5,3 +5,5 @@ import t from "./EplVarTable.vue_vue_type_script_setup_true_lang.js";
5
5
  var n = /*#__PURE__*/ e(t, [["__scopeId", "data-v-eff7e67b"]]);
6
6
  //#endregion
7
7
  export { n as default };
8
+
9
+ //# sourceMappingURL=EplVarTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EplVarTable.js","names":[],"sources":["../../../src/components/epl/EplVarTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { EplVarRow } from '@/lib/epl'\n\n/**\n * The 易语言 IDE renders every definition (参数 / 局部变量 / 成员 / 全局变量 / DLL 参数) as a bordered table\n * with a pale header row. This is the shared table: the caller picks the columns (label + which {@link EplVarRow}\n * field each maps to), so one component covers all the variation between parameter / variable / member tables.\n * Boolean columns (公开 / 静态 / 传址 / 参考 / 可空 / 数组) render a centered ✓.\n */\nexport type EplColKey =\n | 'name'\n | 'type'\n | 'public'\n | 'static'\n | 'byAddress'\n | 'byReference'\n | 'nullable'\n | 'arrayBound'\n | 'arrayFlag'\n | 'comment'\n\nexport interface EplCol {\n key: EplColKey\n label: string\n}\n\n/** `nos` are the document-wide line numbers for each row (one per `rows` entry); the header row gets none. */\nconst props = defineProps<{ columns: EplCol[]; rows: EplVarRow[]; nos?: number[] }>()\n\nfunction rowNo(i: number): number {\n return props.nos?.[i] ?? i + 1\n}\n\nconst BOOL_KEYS = new Set<EplColKey>([\n 'public',\n 'static',\n 'byAddress',\n 'byReference',\n 'nullable',\n 'arrayFlag',\n])\n\nfunction isBool(key: EplColKey): boolean {\n return BOOL_KEYS.has(key)\n}\n\nfunction cell(row: EplVarRow, key: EplColKey): string {\n switch (key) {\n case 'name':\n return row.name\n case 'type':\n return row.type\n case 'public':\n return row.isPublic ? '✓' : ''\n case 'static':\n return row.isStatic ? '✓' : ''\n case 'byAddress':\n return row.byAddress ? '✓' : ''\n case 'byReference':\n return row.byReference ? '✓' : ''\n case 'nullable':\n return row.nullable ? '✓' : ''\n case 'arrayBound':\n return row.arrayBound\n case 'arrayFlag':\n return row.isArray ? '✓' : ''\n case 'comment':\n return row.comment\n }\n}\n\n/** Is this column an identifier-ish one (rendered in the IDE's blue link color)? */\nfunction isIdent(key: EplColKey): boolean {\n return key === 'name' || key === 'type'\n}\n</script>\n\n<template>\n <table class=\"vt\">\n <thead>\n <tr>\n <th class=\"vt__gut\" />\n <th\n v-for=\"col in columns\"\n :key=\"col.key\"\n :class=\"{ 'vt__th--bool': isBool(col.key), 'vt__th--cmt': col.key === 'comment' }\"\n >\n {{ col.label }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"(row, i) in rows\" :key=\"i\">\n <td class=\"vt__gut\">{{ rowNo(i) }}</td>\n <td\n v-for=\"col in columns\"\n :key=\"col.key\"\n :class=\"{\n 'vt__td--bool': isBool(col.key),\n 'vt__td--ident': isIdent(col.key),\n 'vt__td--cmt': col.key === 'comment',\n }\"\n >\n {{ cell(row, col.key) }}\n </td>\n </tr>\n </tbody>\n </table>\n</template>\n\n<style scoped>\n.vt {\n border-collapse: collapse;\n font-size: 12.5px;\n margin: 2px 0 0;\n background: var(--epl-bg);\n table-layout: auto;\n}\n.vt th,\n.vt td {\n border: 1px solid var(--epl-border);\n padding: 2px 8px;\n text-align: left;\n white-space: nowrap;\n color: var(--epl-fg);\n}\n.vt th {\n background: var(--epl-th-bg);\n color: var(--epl-th-fg);\n font-weight: 600;\n}\n.vt__th--bool,\n.vt__td--bool {\n text-align: center;\n min-width: 2.6em;\n}\n.vt__td--bool {\n color: var(--epl-check);\n font-weight: 700;\n}\n.vt__td--ident {\n color: var(--epl-ident);\n}\n.vt__th--cmt,\n.vt__td--cmt {\n white-space: normal;\n}\n.vt__td--cmt {\n color: var(--epl-comment);\n}\nth.vt__gut,\ntd.vt__gut {\n width: 3.4em;\n min-width: 3.4em;\n box-sizing: border-box;\n padding: 2px 10px 2px 0;\n text-align: right;\n border: none;\n background: var(--epl-gutter-bg);\n color: var(--epl-gutter);\n font-weight: normal;\n user-select: none;\n position: sticky;\n left: 0;\n z-index: 1;\n}\n</style>\n"],"mappings":""}
@@ -58,3 +58,5 @@ var c = { class: "vt" }, l = { class: "vt__gut" }, u = /*@__PURE__*/ r({
58
58
  });
59
59
  //#endregion
60
60
  export { u as default };
61
+
62
+ //# sourceMappingURL=EplVarTable.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EplVarTable.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/epl/EplVarTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { EplVarRow } from '@/lib/epl'\n\n/**\n * The 易语言 IDE renders every definition (参数 / 局部变量 / 成员 / 全局变量 / DLL 参数) as a bordered table\n * with a pale header row. This is the shared table: the caller picks the columns (label + which {@link EplVarRow}\n * field each maps to), so one component covers all the variation between parameter / variable / member tables.\n * Boolean columns (公开 / 静态 / 传址 / 参考 / 可空 / 数组) render a centered ✓.\n */\nexport type EplColKey =\n | 'name'\n | 'type'\n | 'public'\n | 'static'\n | 'byAddress'\n | 'byReference'\n | 'nullable'\n | 'arrayBound'\n | 'arrayFlag'\n | 'comment'\n\nexport interface EplCol {\n key: EplColKey\n label: string\n}\n\n/** `nos` are the document-wide line numbers for each row (one per `rows` entry); the header row gets none. */\nconst props = defineProps<{ columns: EplCol[]; rows: EplVarRow[]; nos?: number[] }>()\n\nfunction rowNo(i: number): number {\n return props.nos?.[i] ?? i + 1\n}\n\nconst BOOL_KEYS = new Set<EplColKey>([\n 'public',\n 'static',\n 'byAddress',\n 'byReference',\n 'nullable',\n 'arrayFlag',\n])\n\nfunction isBool(key: EplColKey): boolean {\n return BOOL_KEYS.has(key)\n}\n\nfunction cell(row: EplVarRow, key: EplColKey): string {\n switch (key) {\n case 'name':\n return row.name\n case 'type':\n return row.type\n case 'public':\n return row.isPublic ? '✓' : ''\n case 'static':\n return row.isStatic ? '✓' : ''\n case 'byAddress':\n return row.byAddress ? '✓' : ''\n case 'byReference':\n return row.byReference ? '✓' : ''\n case 'nullable':\n return row.nullable ? '✓' : ''\n case 'arrayBound':\n return row.arrayBound\n case 'arrayFlag':\n return row.isArray ? '✓' : ''\n case 'comment':\n return row.comment\n }\n}\n\n/** Is this column an identifier-ish one (rendered in the IDE's blue link color)? */\nfunction isIdent(key: EplColKey): boolean {\n return key === 'name' || key === 'type'\n}\n</script>\n\n<template>\n <table class=\"vt\">\n <thead>\n <tr>\n <th class=\"vt__gut\" />\n <th\n v-for=\"col in columns\"\n :key=\"col.key\"\n :class=\"{ 'vt__th--bool': isBool(col.key), 'vt__th--cmt': col.key === 'comment' }\"\n >\n {{ col.label }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"(row, i) in rows\" :key=\"i\">\n <td class=\"vt__gut\">{{ rowNo(i) }}</td>\n <td\n v-for=\"col in columns\"\n :key=\"col.key\"\n :class=\"{\n 'vt__td--bool': isBool(col.key),\n 'vt__td--ident': isIdent(col.key),\n 'vt__td--cmt': col.key === 'comment',\n }\"\n >\n {{ cell(row, col.key) }}\n </td>\n </tr>\n </tbody>\n </table>\n</template>\n\n<style scoped>\n.vt {\n border-collapse: collapse;\n font-size: 12.5px;\n margin: 2px 0 0;\n background: var(--epl-bg);\n table-layout: auto;\n}\n.vt th,\n.vt td {\n border: 1px solid var(--epl-border);\n padding: 2px 8px;\n text-align: left;\n white-space: nowrap;\n color: var(--epl-fg);\n}\n.vt th {\n background: var(--epl-th-bg);\n color: var(--epl-th-fg);\n font-weight: 600;\n}\n.vt__th--bool,\n.vt__td--bool {\n text-align: center;\n min-width: 2.6em;\n}\n.vt__td--bool {\n color: var(--epl-check);\n font-weight: 700;\n}\n.vt__td--ident {\n color: var(--epl-ident);\n}\n.vt__th--cmt,\n.vt__td--cmt {\n white-space: normal;\n}\n.vt__td--cmt {\n color: var(--epl-comment);\n}\nth.vt__gut,\ntd.vt__gut {\n width: 3.4em;\n min-width: 3.4em;\n box-sizing: border-box;\n padding: 2px 10px 2px 0;\n text-align: right;\n border: none;\n background: var(--epl-gutter-bg);\n color: var(--epl-gutter);\n font-weight: normal;\n user-select: none;\n position: sticky;\n left: 0;\n z-index: 1;\n}\n</style>\n"],"mappings":";;;;;;;;;;EA2BA,IAAM,IAAQ;EAEd,SAAS,EAAM,GAAmB;GAChC,OAAO,EAAM,MAAM,MAAM,IAAI;EAC/B;EAEA,IAAM,IAAY,IAAI,IAAe;GACnC;GACA;GACA;GACA;GACA;GACA;EACF,CAAC;EAED,SAAS,EAAO,GAAyB;GACvC,OAAO,EAAU,IAAI,CAAG;EAC1B;EAEA,SAAS,EAAK,GAAgB,GAAwB;GACpD,QAAQ,GAAR;IACE,KAAK,QACH,OAAO,EAAI;IACb,KAAK,QACH,OAAO,EAAI;IACb,KAAK,UACH,OAAO,EAAI,WAAW,MAAM;IAC9B,KAAK,UACH,OAAO,EAAI,WAAW,MAAM;IAC9B,KAAK,aACH,OAAO,EAAI,YAAY,MAAM;IAC/B,KAAK,eACH,OAAO,EAAI,cAAc,MAAM;IACjC,KAAK,YACH,OAAO,EAAI,WAAW,MAAM;IAC9B,KAAK,cACH,OAAO,EAAI;IACb,KAAK,aACH,OAAO,EAAI,UAAU,MAAM;IAC7B,KAAK,WACH,OAAO,EAAI;GACf;EACF;EAGA,SAAS,EAAQ,GAAyB;GACxC,OAAO,MAAQ,UAAU,MAAQ;EACnC;yBAIE,EA6BQ,SA7BR,GA6BQ,CA5BN,EAWQ,SAAA,MAAA,CAVN,EASK,MAAA,MAAA,CAAA,AAAA,EAAA,OARH,EAAsB,MAAA,EAAlB,OAAM,UAAS,GAAA,MAAA,EAAA,IAAA,EAAA,EAAA,GACnB,EAMK,GAAA,MAAA,EALW,EAAA,UAAP,YADT,EAMK,MAAA;GAJF,KAAK,EAAI;GACT,OAAK,EAAA;IAAA,gBAAoB,EAAO,EAAI,GAAG;IAAA,eAAkB,EAAI,QAAG;GAAA,CAAA;OAE9D,EAAI,KAAK,GAAA,CAAA,gBAIlB,EAeQ,SAAA,MAAA,EAAA,EAAA,EAAA,GAdN,EAaK,GAAA,MAAA,EAbkB,EAAA,OAAX,GAAK,YAAjB,EAaK,MAAA,EAbyB,KAAK,EAAC,GAAA,CAClC,EAAuC,MAAvC,GAAuC,EAAhB,EAAM,CAAC,CAAA,GAAA,CAAA,IAAA,EAAA,EAAA,GAC9B,EAUK,GAAA,MAAA,EATW,EAAA,UAAP,YADT,EAUK,MAAA;GARF,KAAK,EAAI;GACT,OAAK,EAAA;oBAAgC,EAAO,EAAI,GAAG;qBAAgC,EAAQ,EAAI,GAAG;mBAA8B,EAAI,QAAG;;OAMrI,EAAK,GAAK,EAAI,GAAG,CAAA,GAAA,CAAA"}
@@ -12,3 +12,5 @@ var e = class {
12
12
  };
13
13
  //#endregion
14
14
  export { e as LineCounter };
15
+
16
+ //# sourceMappingURL=numbering.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"numbering.js","names":[],"sources":["../../../src/components/epl/numbering.ts"],"sourcesContent":["/**\n * Document-wide line numbering for the IDE-style viewer. The 易语言 source view puts a single continuous\n * line-number gutter down the whole document: every *body* row (the 程序集/类 row, each 子程序 / 参数 / 局部 /\n * 成员 / 全局 row, and every code line — blanks included) takes the next number, while column-header rows do\n * not. So numbering can't live inside one table or one method; it threads through the active document here, and\n * the components just render the numbers they're handed.\n */\n\n/** Per-method numbers: the 子程序名 header row, then parameter / local-variable rows, then code lines.\n * A code entry is `null` for a row that takes no number (a hidden control-flow terminator). */\nexport interface MethodNos {\n head: number\n params: number[]\n locals: number[]\n code: (number | null)[]\n}\n\n/** A running 1-based counter that hands out single numbers or contiguous runs in document order. */\nexport class LineCounter {\n private n = 1\n next(): number {\n return this.n++\n }\n take(count: number): number[] {\n const out: number[] = []\n for (let i = 0; i < count; i++) out.push(this.n++)\n return out\n }\n}\n"],"mappings":";AAkBA,IAAa,IAAb,MAAyB;CACvB,IAAY;CACZ,OAAe;EACb,OAAO,KAAK;CACd;CACA,KAAK,GAAyB;EAC5B,IAAM,IAAgB,CAAC;EACvB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAO,KAAK,EAAI,KAAK,KAAK,GAAG;EACjD,OAAO;CACT;AACF"}
@@ -5,3 +5,5 @@ import t from "./Icon.vue_vue_type_script_setup_true_lang.js";
5
5
  var n = /*#__PURE__*/ e(t, [["__scopeId", "data-v-5d3b9e77"]]);
6
6
  //#endregion
7
7
  export { n as default };
8
+
9
+ //# sourceMappingURL=Icon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Icon.js","names":[],"sources":["../../../src/components/icons/Icon.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { STROKE_ICONS, type StrokeIconName } from './iconPaths'\n\n/** Outline icon (viewBox 24, stroke currentColor). Pass a known `name` or raw `path`. */\nconst props = withDefaults(\n defineProps<{\n name?: StrokeIconName\n path?: string\n size?: number\n strokeWidth?: number\n }>(),\n { size: 15, strokeWidth: 1.8 },\n)\n\nconst inner = computed(() => props.path ?? (props.name ? STROKE_ICONS[props.name] : ''))\n</script>\n\n<template>\n <span class=\"dc-icon\">\n <svg\n :width=\"size\"\n :height=\"size\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n :stroke-width=\"strokeWidth\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n v-html=\"inner\"\n />\n </span>\n</template>\n\n<style scoped>\n.dc-icon {\n display: inline-flex;\n line-height: 0;\n}\n</style>\n"],"mappings":""}
@@ -31,3 +31,5 @@ var a = { class: "dc-icon" }, o = [
31
31
  });
32
32
  //#endregion
33
33
  export { s as default };
34
+
35
+ //# sourceMappingURL=Icon.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Icon.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/icons/Icon.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { STROKE_ICONS, type StrokeIconName } from './iconPaths'\n\n/** Outline icon (viewBox 24, stroke currentColor). Pass a known `name` or raw `path`. */\nconst props = withDefaults(\n defineProps<{\n name?: StrokeIconName\n path?: string\n size?: number\n strokeWidth?: number\n }>(),\n { size: 15, strokeWidth: 1.8 },\n)\n\nconst inner = computed(() => props.path ?? (props.name ? STROKE_ICONS[props.name] : ''))\n</script>\n\n<template>\n <span class=\"dc-icon\">\n <svg\n :width=\"size\"\n :height=\"size\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n :stroke-width=\"strokeWidth\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n v-html=\"inner\"\n />\n </span>\n</template>\n\n<style scoped>\n.dc-icon {\n display: inline-flex;\n line-height: 0;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;EAKA,IAAM,IAAQ,GAUR,IAAQ,QAAe,EAAM,SAAS,EAAM,OAAO,EAAa,EAAM,QAAQ,GAAG;yBAIrF,EAYO,QAZP,GAYO,EAAA,EAAA,GAXL,EAUE,OAAA;GATC,OAAO,EAAA;GACP,QAAQ,EAAA;GACT,SAAQ;GACR,MAAK;GACL,QAAO;GACN,gBAAc,EAAA;GACf,kBAAe;GACf,mBAAgB;GAChB,WAAQ,EAAA"}
@@ -52,3 +52,5 @@ var e = {
52
52
  };
53
53
  //#endregion
54
54
  export { e as FILL_ICONS, t as STROKE_ICONS };
55
+
56
+ //# sourceMappingURL=iconPaths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iconPaths.js","names":[],"sources":["../../../src/components/icons/iconPaths.ts"],"sourcesContent":["/**\n * Centralized SVG path data, lifted from the inline SVGs scattered through the\n * original viewer. Two families:\n * - FILL_ICONS: filled glyphs, viewBox 0 0 20 20, fill currentColor (old icoF / ICONS)\n * - STROKE_ICONS: outline glyphs, viewBox 0 0 24 24, stroke currentColor (old ico)\n */\n\nexport const FILL_ICONS = {\n thinking:\n '<path d=\"M10.386 2.51A7.5 7.5 0 1 1 2.5 10a.5.5 0 0 1 1 0 6.5 6.5 0 1 0 6.835-6.491L10 3.5l-.1-.01a.5.5 0 0 1 .1-.99zM10 5.5a.5.5 0 0 1 .5.5v3.69l2.724 1.363a.5.5 0 0 1-.353.93l-.095-.036-3-1.5A.5.5 0 0 1 9.5 10V6a.5.5 0 0 1 .5-.5M3.662 6.941a.661.661 0 1 1 0 1.323.661.661 0 0 1 0-1.323m1.294-2.647a.662.662 0 1 1-.001 1.323.662.662 0 0 1 .001-1.323M7.603 3a.662.662 0 1 1-.001 1.325.662.662 0 0 1 0-1.325\"/>',\n bash: '<path fill-rule=\"evenodd\" d=\"M3.5 4A1.5 1.5 0 0 0 2 5.5v9A1.5 1.5 0 0 0 3.5 16h13a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 16.5 4zm0 1.2h13a.3.3 0 0 1 .3.3v9a.3.3 0 0 1-.3.3h-13a.3.3 0 0 1-.3-.3v-9a.3.3 0 0 1 .3-.3z\" clip-rule=\"evenodd\"/><path d=\"M5.3 7.2a.6.6 0 0 1 .85 0l2.1 2.1a.6.6 0 0 1 0 .85l-2.1 2.1a.6.6 0 1 1-.85-.85L6.99 9.7 5.3 8.05a.6.6 0 0 1 0-.85M9.6 11.6a.6.6 0 0 0 0 1.2h3.6a.6.6 0 0 0 0-1.2z\"/>',\n skill:\n '<path d=\"M13.04 7.304a.5.5 0 0 1 .92.392C13.665 8.386 13.089 9 12.3 9c-.487 0-.892-.234-1.2-.574-.309.34-.713.574-1.2.574-.486 0-.892-.234-1.2-.574-.31.34-.714.574-1.2.574a.5.5 0 0 1 0-1c.212 0 .52-.18.74-.696a.5.5 0 0 1 .92 0c.221.516.528.696.74.696.213 0 .52-.18.74-.696l.035-.067a.5.5 0 0 1 .885.067c.22.516.527.696.74.696s.519-.18.74-.696\"/><path fill-rule=\"evenodd\" d=\"M14 3a2 2 0 0 1 2 2v8h1.5a.5.5 0 0 1 .5.5V15a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V4H4a1 1 0 0 0-.745 1.667.5.5 0 0 1-.745.666A2 2 0 0 1 4 3zM6 15a1 1 0 1 0 2 0v-1.5a.5.5 0 0 1 .5-.5H15V5a1 1 0 0 0-1-1H6zm3 0c0 .365-.1.706-.27 1H16a1 1 0 0 0 1-1v-1H9z\" clip-rule=\"evenodd\"/>',\n edit: '<path d=\"M14.3 2.7a2.05 2.05 0 0 1 2.9 2.9l-.79.79-2.9-2.9zM12.79 4.21l2.9 2.9-7.86 7.86a1 1 0 0 1-.43.25l-3.2.9a.5.5 0 0 1-.62-.62l.9-3.2a1 1 0 0 1 .25-.43z\"/>',\n file: '<path fill-rule=\"evenodd\" d=\"M5.5 2.5A1.5 1.5 0 0 0 4 4v12a1.5 1.5 0 0 0 1.5 1.5h9A1.5 1.5 0 0 0 16 16V7.62a1.5 1.5 0 0 0-.44-1.06l-3.12-3.12a1.5 1.5 0 0 0-1.06-.44zm6 1.96 2.54 2.54H12a.5.5 0 0 1-.5-.5z\" clip-rule=\"evenodd\"/>',\n check:\n '<path d=\"M16.74 5.8a1 1 0 0 1 .04 1.41l-7.02 7.32a1 1 0 0 1-1.45.01l-3-3.13a1 1 0 1 1 1.44-1.38l2.28 2.37 6.3-6.56a1 1 0 0 1 1.41-.04z\"/>',\n tool: '<circle cx=\"10\" cy=\"10\" r=\"3\"/>',\n // \"Search past conversations\" (conversation_search / \"memory\"): a chat squiggle inside a refresh ring.\n // Used on the conversation_search timeline rail (see ChatSearchStep).\n conversation:\n '<path d=\"M13.29 8.804a.5.5 0 0 1 .92.392c-.36.84-1.046 1.554-1.96 1.554-.613 0-1.122-.321-1.5-.785-.378.464-.887.785-1.5.785s-1.122-.321-1.5-.785c-.378.464-.887.785-1.5.785a.5.5 0 0 1 0-1c.338 0 .755-.28 1.04-.946l.034-.067a.5.5 0 0 1 .886.067l.112.231c.276.5.632.715.928.715.338 0 .755-.28 1.04-.946l.034-.067a.5.5 0 0 1 .886.067l.112.231c.276.5.633.715.928.715.338 0 .755-.28 1.04-.946\"/><path d=\"M17.5 9.5A7.5 7.5 0 0 0 2.516 9c-.018.275.208.5.484.5a.53.53 0 0 0 .519-.5A6.5 6.5 0 1 1 10 16l-5.855.004.828-.834a.497.497 0 0 0-.706-.701l-1.576 1.584a.656.656 0 0 0 0 .926l1.542 1.55a.51.51 0 1 0 .722-.723l-.81-.802L10 17a7.5 7.5 0 0 0 7.5-7.5\"/>',\n // \"Open in new\" — a window with a diagonal arrow out the top-right. Used by web_fetch rich links.\n external:\n '<path d=\"M9.5 3a.5.5 0 0 1 0 1h-5a.5.5 0 0 0-.5.5v11a.5.5 0 0 0 .5.5h11a.5.5 0 0 0 .5-.5v-5a.5.5 0 0 1 1 0v5a1.5 1.5 0 0 1-1.5 1.5h-11A1.5 1.5 0 0 1 3 15.5v-11A1.5 1.5 0 0 1 4.5 3zm7 0a.5.5 0 0 1 .18.034l.021.01q.03.014.059.03l.023.014a.5.5 0 0 1 .07.058l.065.079q.015.025.026.052l.018.034a.5.5 0 0 1 .032.128Q17 3.47 17 3.5v4a.5.5 0 0 1-1 0V4.707l-4.146 4.147a.5.5 0 1 1-.707-.708L15.293 4H12.5a.5.5 0 0 1 0-1z\"/>',\n} as const\n\nexport type IconKey = keyof typeof FILL_ICONS\n\nexport const STROKE_ICONS = {\n copy: '<rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\"/><path d=\"M5 15V5a2 2 0 0 1 2-2h10\"/>',\n fileOutline:\n '<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"/><path d=\"M14 2v6h6\"/>',\n arrowLeft: '<path d=\"M19 12H5\"/><path d=\"M12 19l-7-7 7-7\"/>',\n logout:\n '<path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\"/><path d=\"M16 17l5-5-5-5\"/><path d=\"M21 12H9\"/>',\n download:\n '<path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><path d=\"M7 10l5 5 5-5\"/><path d=\"M12 15V3\"/>',\n close: '<path d=\"M18 6 6 18\"/><path d=\"M6 6l12 12\"/>',\n eye: '<path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"/><circle cx=\"12\" cy=\"12\" r=\"3.5\"/>',\n code: '<path d=\"M16 18l6-6-6-6\"/><path d=\"M8 6l-6 6 6 6\"/>',\n globe:\n '<circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M3 12h18M12 3c2.5 2.6 2.5 15.4 0 18M12 3c-2.5 2.6-2.5 15.4 0 18\"/>',\n link: '<path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/>',\n chevronRight: '<path d=\"M9 6l6 6-6 6\"/>',\n chevronLeft: '<path d=\"M15 6l-6 6 6 6\"/>',\n chevronDown: '<path d=\"M6 9l6 6 6-6\"/>',\n // Speech bubble — one past chat in a conversation_search result list (ChatSearchStep rows).\n chat: '<path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/>',\n folder:\n '<path d=\"M3 7a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.7.9l.8 1.1H19a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"/>',\n archive:\n '<rect x=\"3\" y=\"4\" width=\"18\" height=\"4\" rx=\"1\"/><path d=\"M5 8v11a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V8\"/><path d=\"M10 12h4\"/>',\n image:\n '<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><path d=\"M21 15l-5-5L5 21\"/>',\n play: '<circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M10 8.5l5 3.5-5 3.5z\"/>',\n music: '<path d=\"M9 18V5l12-2v13\"/><circle cx=\"6\" cy=\"18\" r=\"3\"/><circle cx=\"18\" cy=\"16\" r=\"3\"/>',\n arrowDown: '<path d=\"M12 5v14\"/><path d=\"M5 12l7 7 7-7\"/>',\n arrowUp: '<path d=\"M12 19V5\"/><path d=\"M5 12l7-7 7 7\"/>',\n chart:\n '<path d=\"M3 3v18h18\"/><rect x=\"7\" y=\"11\" width=\"3\" height=\"6\"/><rect x=\"13\" y=\"7\" width=\"3\" height=\"10\"/>',\n pot: '<path d=\"M2 12h20\"/><path d=\"M20 12v7a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-7\"/><path d=\"m4 8 16-4\"/><path d=\"m8.9 6.8-.5-1.8a2 2 0 0 1 1.5-2.4l1.9-.5a2 2 0 0 1 2.4 1.5l.5 1.8\"/>',\n clock: '<circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 7v5l3 2\"/>',\n info: '<circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M12 16v-4\"/><path d=\"M12 8h.01\"/>',\n retry: '<path d=\"M21 12a9 9 0 1 1-2.64-6.36M21 4v5h-5\"/>',\n thumb:\n '<path d=\"M7 10v11M7 10l4-7a2 2 0 0 1 2.6 2.6L12 10h5.6a2 2 0 0 1 2 2.4l-1.3 6A2 2 0 0 1 16.3 21H7\"/>',\n help: '<circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M9.1 9a3 3 0 0 1 5.8 1c0 2-3 3-3 3\"/><path d=\"M12 17h.01\"/>',\n key: '<circle cx=\"7.5\" cy=\"15.5\" r=\"5.5\"/><path d=\"m11.4 11.6 9.6-9.6\"/><path d=\"m15.5 7.5 3 3L22 7l-3-3\"/>',\n users:\n '<path d=\"M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\"/><circle cx=\"9\" cy=\"7\" r=\"4\"/><path d=\"M23 21v-2a4 4 0 0 0-3-3.87\"/><path d=\"M16 3.13a4 4 0 0 1 0 7.75\"/>',\n plus: '<path d=\"M12 5v14\"/><path d=\"M5 12h14\"/>',\n check: '<path d=\"M20 6 9 17l-5-5\"/>',\n trash:\n '<path d=\"M3 6h18\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/><path d=\"M10 11v6\"/><path d=\"M14 11v6\"/>',\n // Four corner brackets — \"expand to full screen\" (used by the HTML preview's in-app fullscreen overlay).\n maximize:\n '<path d=\"M8 3H5a2 2 0 0 0-2 2v3\"/><path d=\"M21 8V5a2 2 0 0 0-2-2h-3\"/><path d=\"M3 16v3a2 2 0 0 0 2 2h3\"/><path d=\"M16 21h3a2 2 0 0 0 2-2v-3\"/>',\n // Paperclip — \"this conversation has attached files\" (the listing's file marker).\n paperclip:\n '<path d=\"M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48\"/>',\n // Stacked documents — \"open this conversation's associated-file list\" (the detail page's top-right button).\n files:\n '<path d=\"M20 7h-3a2 2 0 0 1-2-2V2\"/><path d=\"M9 18a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h7l4 4v10a2 2 0 0 1-2 2Z\"/><path d=\"M3 7.6v12.8A1.6 1.6 0 0 0 4.6 22h9.8\"/>',\n // Target/crosshair — \"locate this file in the conversation\" (the file panel's jump cue).\n locate: '<circle cx=\"12\" cy=\"12\" r=\"3\"/><path d=\"M12 2v4M12 18v4M2 12h4M18 12h4\"/>',\n // Byte grid in a frame — \"view raw bytes / hex dump\" (the unpreviewable-file \"open with\" hex chooser).\n hex: '<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\"/><path d=\"M7 9h.01M11 9h.01M15 9h.01M7 13h.01M11 13h.01M15 13h.01\"/>',\n // Four tiles — \"open with / choose a viewer\" (the file panel's universal formatter menu trigger).\n apps: '<rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1.5\"/><rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" rx=\"1.5\"/><rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1.5\"/><rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" rx=\"1.5\"/>',\n} as const\n\nexport type StrokeIconName = keyof typeof STROKE_ICONS\n"],"mappings":";AAOA,IAAa,IAAa;CACxB,UACE;CACF,MAAM;CACN,OACE;CACF,MAAM;CACN,MAAM;CACN,OACE;CACF,MAAM;CAGN,cACE;CAEF,UACE;AACJ,GAIa,IAAe;CAC1B,MAAM;CACN,aACE;CACF,WAAW;CACX,QACE;CACF,UACE;CACF,OAAO;CACP,KAAK;CACL,MAAM;CACN,OACE;CACF,MAAM;CACN,cAAc;CACd,aAAa;CACb,aAAa;CAEb,MAAM;CACN,QACE;CACF,SACE;CACF,OACE;CACF,MAAM;CACN,OAAO;CACP,WAAW;CACX,SAAS;CACT,OACE;CACF,KAAK;CACL,OAAO;CACP,MAAM;CACN,OAAO;CACP,OACE;CACF,MAAM;CACN,KAAK;CACL,OACE;CACF,MAAM;CACN,OAAO;CACP,OACE;CAEF,UACE;CAEF,WACE;CAEF,OACE;CAEF,QAAQ;CAER,KAAK;CAEL,MAAM;AACR"}
@@ -35,3 +35,5 @@ function i(i, a, o) {
35
35
  }
36
36
  //#endregion
37
37
  export { i as optionalViewer };
38
+
39
+ //# sourceMappingURL=optionalViewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"optionalViewer.js","names":[],"sources":["../../src/components/optionalViewer.ts"],"sourcesContent":["import { defineAsyncComponent, defineComponent, h, type Component } from 'vue'\nimport MissingDependency from '@/components/MissingDependency.vue'\n\n/**\n * Wrap a heavy viewer's async loader so that, when its OPTIONAL peer dependency isn't installed in the\n * consumer's app, the chunk-load failure shows a {@link MissingDependency} card (\"npm i <pkg>\") instead of a\n * blank error (see docs/file-viewer-package-design.md §4). The dep is `external` in the library build, so a\n * viewer that statically imports it fails to evaluate its chunk when the dep is absent — which lands here.\n *\n * The error component receives the SAME props the viewer was given (`url`/`name`/`size`), so the card can keep\n * the file downloadable. Only for viewers whose dep is imported STATICALLY (pdf/docx/xlsx/pptx/sqlite/model/\n * dicom); viewers that import their engine dynamically at runtime (geo/raster/ebook) handle absence themselves.\n */\nexport function optionalViewer(\n loader: () => Promise<Component | { default: Component }>,\n deps: string | string[],\n label: string,\n): Component {\n const pkg = Array.isArray(deps) ? deps : [deps]\n return defineAsyncComponent({\n loader: loader as () => Promise<Component>,\n errorComponent: defineComponent({\n name: 'ViewerDependencyMissing',\n props: {\n url: { type: String, default: '' },\n name: { type: String, default: '' },\n size: { type: Number, default: undefined },\n },\n setup: (props) => () =>\n h(MissingDependency, {\n pkg,\n label,\n downloadUrl: props.url,\n downloadName: props.name,\n }),\n }),\n // Any failure to load this viewer's chunk → show the \"install <pkg>\" card (the dominant cause for a\n // published package is a missing optional dep). Don't retry.\n onError(_error, _retry, fail) {\n fail()\n },\n })\n}\n"],"mappings":";;;AAaA,SAAgB,EACd,GACA,GACA,GACW;CACX,IAAM,IAAM,MAAM,QAAQ,CAAI,IAAI,IAAO,CAAC,CAAI;CAC9C,OAAO,EAAqB;EAClB;EACR,gBAAgB,EAAgB;GAC9B,MAAM;GACN,OAAO;IACL,KAAK;KAAE,MAAM;KAAQ,SAAS;IAAG;IACjC,MAAM;KAAE,MAAM;KAAQ,SAAS;IAAG;IAClC,MAAM;KAAE,MAAM;KAAQ,SAAS,KAAA;IAAU;GAC3C;GACA,QAAQ,YACN,EAAE,GAAmB;IACnB;IACA;IACA,aAAa,EAAM;IACnB,cAAc,EAAM;GACtB,CAAC;EACL,CAAC;EAGD,QAAQ,GAAQ,GAAQ,GAAM;GAC5B,EAAK;EACP;CACF,CAAC;AACH"}
@@ -61,3 +61,5 @@ var o = t({
61
61
  });
62
62
  //#endregion
63
63
  export { o as default };
64
+
65
+ //# sourceMappingURL=ClampBlock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClampBlock.js","names":[],"sources":["../../../src/components/ui/ClampBlock.ts"],"sourcesContent":["import { computed, defineComponent, h, onBeforeUnmount, onMounted, ref, type VNode } from 'vue'\n\n/**\n * Clamp tall content to a collapsed height with a Show more / Show less toggle —\n * claude.ai's long-block behavior. When collapsed and overflowing, the bottom\n * fades into `fade` (a soft shadow cue that more lies below). The toggle is a\n * plain-text link hidden until you hover the block (the fade), brightening when\n * you hover the text itself. Content that fits renders untouched: no clip, no\n * fade, no toggle.\n *\n * A render function (not an SFC) on purpose: a compiled `<slot/>` trips the\n * server renderer in the SSR smoke harness (renderSlot → null instance), so we\n * invoke the slot directly. Styling lives in assets/styles/clamp.css.\n */\nexport default defineComponent({\n name: 'ClampBlock',\n props: {\n /** Collapsed height cap, in px. */\n maxHeight: { type: Number, default: 360 },\n /** Color the bottom gradient fades to — match the content's own background. */\n fade: { type: String, default: 'var(--bg)' },\n /** Px of overflow tolerated before the toggle appears (avoids clamping near-fits). */\n slack: { type: Number, default: 28 },\n /** Left inset of the toggle, in px — align it with padded content (e.g. a code block). */\n inset: { type: Number, default: 0 },\n moreLabel: { type: String, default: 'Show more' },\n lessLabel: { type: String, default: 'Show less' },\n },\n setup(props, { slots }) {\n const open = ref(false)\n const overflowing = ref(false)\n const content = ref<HTMLElement | null>(null)\n let ro: ResizeObserver | undefined\n\n const measure = () => {\n const el = content.value\n if (el) overflowing.value = el.scrollHeight > props.maxHeight + props.slack\n }\n\n onMounted(() => {\n measure()\n // Re-measure as fonts/highlighting/images settle or the pane is resized.\n if (typeof ResizeObserver !== 'undefined') {\n ro = new ResizeObserver(measure)\n if (content.value) ro.observe(content.value)\n }\n })\n onBeforeUnmount(() => ro?.disconnect())\n\n const collapsed = computed(() => overflowing.value && !open.value)\n\n return () => {\n const kids: VNode[] = [\n h(\n 'div',\n {\n ref: content,\n class: ['clamp__content', { 'clamp__content--clip': collapsed.value }],\n style: collapsed.value ? { maxHeight: props.maxHeight + 'px' } : undefined,\n },\n slots.default?.(),\n ),\n ]\n\n if (collapsed.value) {\n kids.push(\n h('div', {\n class: 'clamp__fade',\n 'aria-hidden': 'true',\n style: { backgroundImage: `linear-gradient(to bottom, transparent, ${props.fade})` },\n }),\n )\n }\n\n if (overflowing.value) {\n kids.push(\n h(\n 'div',\n {\n class: ['clamp__toggle', { 'clamp__toggle--float': collapsed.value }],\n style: props.inset ? { paddingLeft: props.inset + 'px' } : undefined,\n },\n h(\n 'button',\n {\n type: 'button',\n class: 'clamp__btn',\n 'aria-expanded': open.value,\n onClick: () => (open.value = !open.value),\n },\n open.value ? props.lessLabel : props.moreLabel,\n ),\n ),\n )\n }\n\n return h('div', { class: 'clamp' }, kids)\n }\n },\n})\n"],"mappings":";;AAcA,IAAA,IAAe,EAAgB;CAC7B,MAAM;CACN,OAAO;EAEL,WAAW;GAAE,MAAM;GAAQ,SAAS;EAAI;EAExC,MAAM;GAAE,MAAM;GAAQ,SAAS;EAAY;EAE3C,OAAO;GAAE,MAAM;GAAQ,SAAS;EAAG;EAEnC,OAAO;GAAE,MAAM;GAAQ,SAAS;EAAE;EAClC,WAAW;GAAE,MAAM;GAAQ,SAAS;EAAY;EAChD,WAAW;GAAE,MAAM;GAAQ,SAAS;EAAY;CAClD;CACA,MAAM,GAAO,EAAE,YAAS;EACtB,IAAM,IAAO,EAAI,EAAK,GAChB,IAAc,EAAI,EAAK,GACvB,IAAU,EAAwB,IAAI,GACxC,GAEE,UAAgB;GACpB,IAAM,IAAK,EAAQ;GACnB,AAAI,MAAI,EAAY,QAAQ,EAAG,eAAe,EAAM,YAAY,EAAM;EACxE;EAUA,AARA,QAAgB;GAGd,AAFA,EAAQ,GAEJ,OAAO,iBAAmB,QAC5B,IAAK,IAAI,eAAe,CAAO,GAC3B,EAAQ,SAAO,EAAG,QAAQ,EAAQ,KAAK;EAE/C,CAAC,GACD,QAAsB,GAAI,WAAW,CAAC;EAEtC,IAAM,IAAY,QAAe,EAAY,SAAS,CAAC,EAAK,KAAK;EAEjE,aAAa;GACX,IAAM,IAAgB,CACpB,EACE,OACA;IACE,KAAK;IACL,OAAO,CAAC,kBAAkB,EAAE,wBAAwB,EAAU,MAAM,CAAC;IACrE,OAAO,EAAU,QAAQ,EAAE,WAAW,EAAM,YAAY,KAAK,IAAI,KAAA;GACnE,GACA,EAAM,UAAU,CAClB,CACF;GAkCA,OAhCI,EAAU,SACZ,EAAK,KACH,EAAE,OAAO;IACP,OAAO;IACP,eAAe;IACf,OAAO,EAAE,iBAAiB,2CAA2C,EAAM,KAAK,GAAG;GACrF,CAAC,CACH,GAGE,EAAY,SACd,EAAK,KACH,EACE,OACA;IACE,OAAO,CAAC,iBAAiB,EAAE,wBAAwB,EAAU,MAAM,CAAC;IACpE,OAAO,EAAM,QAAQ,EAAE,aAAa,EAAM,QAAQ,KAAK,IAAI,KAAA;GAC7D,GACA,EACE,UACA;IACE,MAAM;IACN,OAAO;IACP,iBAAiB,EAAK;IACtB,eAAgB,EAAK,QAAQ,CAAC,EAAK;GACrC,GACA,EAAK,QAAQ,EAAM,YAAY,EAAM,SACvC,CACF,CACF,GAGK,EAAE,OAAO,EAAE,OAAO,QAAQ,GAAG,CAAI;EAC1C;CACF;AACF,CAAC"}
@@ -59,3 +59,5 @@ function r(r) {
59
59
  }
60
60
  //#endregion
61
61
  export { r as useElementNavigation };
62
+
63
+ //# sourceMappingURL=useElementNavigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useElementNavigation.js","names":[],"sources":["../../src/composables/useElementNavigation.ts"],"sourcesContent":["import { onBeforeUnmount, shallowRef, watch, type ShallowRef } from 'vue'\n\nexport interface ElementNavigationItem {\n id: string\n title: string\n level: number\n target: HTMLElement\n}\n\n/**\n * Scroll-spy + in-container navigation for DOM-backed document viewers.\n *\n * The rendered document remains the only source of scroll state. Navigation entries retain their target\n * elements, while this composable exposes readonly-by-convention refs and explicit mutation actions.\n */\nexport function useElementNavigation(scrollRoot: Readonly<ShallowRef<HTMLElement | null>>) {\n const outlineItems = shallowRef<ElementNavigationItem[]>([])\n const pageItems = shallowRef<ElementNavigationItem[]>([])\n const activeOutlineId = shallowRef('')\n const activePageId = shallowRef('')\n\n let frame = 0\n let listeningRoot: HTMLElement | null = null\n\n function activeItem(items: readonly ElementNavigationItem[], line: number) {\n if (!items.length) return undefined\n let active = items[0]\n for (const item of items) {\n if (item.target.getBoundingClientRect().top > line) break\n active = item\n }\n return active\n }\n\n function refreshActive(): void {\n frame = 0\n const root = scrollRoot.value\n if (!root) return\n const line = root.getBoundingClientRect().top + 32\n activeOutlineId.value = activeItem(outlineItems.value, line)?.id ?? ''\n activePageId.value = activeItem(pageItems.value, line)?.id ?? ''\n }\n\n function queueRefresh(): void {\n if (frame) return\n if (typeof requestAnimationFrame === 'undefined') {\n refreshActive()\n return\n }\n frame = requestAnimationFrame(refreshActive)\n }\n\n function bindRoot(root: HTMLElement | null): void {\n listeningRoot?.removeEventListener('scroll', queueRefresh)\n listeningRoot = root\n listeningRoot?.addEventListener('scroll', queueRefresh, { passive: true })\n queueRefresh()\n }\n\n const stopRootWatch = watch(scrollRoot, bindRoot, { immediate: true, flush: 'post' })\n\n function setItems(\n outline: readonly ElementNavigationItem[],\n pages: readonly ElementNavigationItem[],\n ): void {\n outlineItems.value = [...outline]\n pageItems.value = [...pages]\n activeOutlineId.value = outline[0]?.id ?? ''\n activePageId.value = pages[0]?.id ?? ''\n queueRefresh()\n }\n\n function navigate(item: ElementNavigationItem): void {\n const root = scrollRoot.value\n if (!root) return\n const rootTop = root.getBoundingClientRect().top\n const targetTop = item.target.getBoundingClientRect().top\n root.scrollTo({ top: root.scrollTop + targetTop - rootTop - 18, behavior: 'smooth' })\n }\n\n onBeforeUnmount(() => {\n stopRootWatch()\n listeningRoot?.removeEventListener('scroll', queueRefresh)\n if (frame && typeof cancelAnimationFrame !== 'undefined') cancelAnimationFrame(frame)\n })\n\n return {\n outlineItems,\n pageItems,\n activeOutlineId,\n activePageId,\n setItems,\n navigate,\n }\n}\n"],"mappings":";;AAeA,SAAgB,EAAqB,GAAsD;CACzF,IAAM,IAAe,EAAoC,CAAC,CAAC,GACrD,IAAY,EAAoC,CAAC,CAAC,GAClD,IAAkB,EAAW,EAAE,GAC/B,IAAe,EAAW,EAAE,GAE9B,IAAQ,GACR,IAAoC;CAExC,SAAS,EAAW,GAAyC,GAAc;EACzE,IAAI,CAAC,EAAM,QAAQ;EACnB,IAAI,IAAS,EAAM;EACnB,KAAK,IAAM,KAAQ,GAAO;GACxB,IAAI,EAAK,OAAO,sBAAsB,CAAC,CAAC,MAAM,GAAM;GACpD,IAAS;EACX;EACA,OAAO;CACT;CAEA,SAAS,IAAsB;EAC7B,IAAQ;EACR,IAAM,IAAO,EAAW;EACxB,IAAI,CAAC,GAAM;EACX,IAAM,IAAO,EAAK,sBAAsB,CAAC,CAAC,MAAM;EAEhD,AADA,EAAgB,QAAQ,EAAW,EAAa,OAAO,CAAI,CAAC,EAAE,MAAM,IACpE,EAAa,QAAQ,EAAW,EAAU,OAAO,CAAI,CAAC,EAAE,MAAM;CAChE;CAEA,SAAS,IAAqB;EACxB,QACJ;OAAI,OAAO,wBAA0B,KAAa;IAChD,EAAc;IACd;GACF;GACA,IAAQ,sBAAsB,CAAa;EAD3C;CAEF;CAEA,SAAS,EAAS,GAAgC;EAIhD,AAHA,GAAe,oBAAoB,UAAU,CAAY,GACzD,IAAgB,GAChB,GAAe,iBAAiB,UAAU,GAAc,EAAE,SAAS,GAAK,CAAC,GACzE,EAAa;CACf;CAEA,IAAM,IAAgB,EAAM,GAAY,GAAU;EAAE,WAAW;EAAM,OAAO;CAAO,CAAC;CAEpF,SAAS,EACP,GACA,GACM;EAKN,AAJA,EAAa,QAAQ,CAAC,GAAG,CAAO,GAChC,EAAU,QAAQ,CAAC,GAAG,CAAK,GAC3B,EAAgB,QAAQ,EAAQ,EAAE,EAAE,MAAM,IAC1C,EAAa,QAAQ,EAAM,EAAE,EAAE,MAAM,IACrC,EAAa;CACf;CAEA,SAAS,EAAS,GAAmC;EACnD,IAAM,IAAO,EAAW;EACxB,IAAI,CAAC,GAAM;EACX,IAAM,IAAU,EAAK,sBAAsB,CAAC,CAAC,KACvC,IAAY,EAAK,OAAO,sBAAsB,CAAC,CAAC;EACtD,EAAK,SAAS;GAAE,KAAK,EAAK,YAAY,IAAY,IAAU;GAAI,UAAU;EAAS,CAAC;CACtF;CAQA,OANA,QAAsB;EAGpB,AAFA,EAAc,GACd,GAAe,oBAAoB,UAAU,CAAY,GACrD,KAAS,OAAO,uBAAyB,OAAa,qBAAqB,CAAK;CACtF,CAAC,GAEM;EACL;EACA;EACA;EACA;EACA;EACA;CACF;AACF"}
@@ -25,3 +25,5 @@ function c() {
25
25
  }
26
26
  //#endregion
27
27
  export { c as useFileViewer };
28
+
29
+ //# sourceMappingURL=useFileViewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFileViewer.js","names":[],"sources":["../../src/composables/useFileViewer.ts"],"sourcesContent":["import { computed, ref } from 'vue'\n\n/** A file opened in the side viewer: its display name, fetch/download URL, and highlight language. */\nexport interface ViewerFile {\n name: string\n /** Download endpoint URL — fetched as text and reused by the download button. Omit when `content` is set. */\n url?: string\n /** highlight.js language id, '' for plain text, or 'markdown' (the panel renders markdown instead of highlighting). */\n lang: string\n /** HTML document: the panel offers a render/source toggle, rendering the markup in a sandboxed iframe. */\n html?: boolean\n /** SVG document: the panel offers a render/source toggle — render shows the picture, source the XML. */\n svg?: boolean\n /** ZIP archive: the panel fetches the bytes and hands them to the in-browser archive browser. */\n zip?: boolean\n /** 7z archive: the panel fetches the bytes and hands them to the in-browser 7z browser. */\n sevenZip?: boolean\n /**\n * tar-family ('tar': tar/gz/tgz/xz/txz/bz2/tbz2) or rar ('rar') archive: the panel hands the URL + this\n * kind to the generic in-browser ArchiveBrowser, which decompresses the bytes and browses the entries.\n */\n archive?: 'tar' | 'rar'\n /** Native binary object (.so/.dll): the panel hands the URL to the in-browser symbol browser. */\n binobj?: boolean\n /** E-language (.e/.ec) project: the panel hands the URL to the in-browser EPL viewer (parse + decompile). */\n epl?: boolean\n /** DICOM (.dcm) medical image: the panel hands the URL to the in-browser DICOM viewer. */\n dicom?: boolean\n /** Word (.docx) document: the panel hands the URL to the in-browser Word viewer (docx-preview). */\n docx?: boolean\n /** Excel (.xlsx/.xlsm) workbook: the panel hands the URL to the in-browser spreadsheet viewer (exceljs). */\n xlsx?: boolean\n /** PowerPoint (.pptx/.pptm/.ppsx) deck: the panel hands the URL to the in-browser slide viewer (pptx-renderer). */\n pptx?: boolean\n /** Rich Text (.rtf) document: the panel hands the URL to the in-browser rich-text viewer (hand-rolled RTF parser). */\n rtf?: boolean\n /** PDF (.pdf) document: the panel hands the URL to the in-browser PDF viewer (pdfjs-dist). */\n pdf?: boolean\n /** OPML / FreeMind (.opml/.mm) outline: the panel fetches the text and renders it as an interactive mind map. */\n mindmap?: boolean\n /** XMind workbook (.xmind): the panel hands the URL to the in-browser XMind viewer (unzip → mind-map tree). */\n xmind?: boolean\n /** Email (.eml) message: the panel hands the URL to the in-browser email viewer (MIME parser). */\n eml?: boolean\n /** Web archive (.mht/.mhtml): the panel hands the URL to the in-browser web-archive viewer (MIME parser). */\n mht?: boolean\n /** HAR (.har) capture: the panel hands the URL to the in-browser HAR viewer (hand-rolled JSON parser). */\n har?: boolean\n /** SQLite database (.sqlite/.db/…): the panel hands the URL to the in-browser SQLite viewer (sql.js). */\n sqlite?: boolean\n /** Certificate / key (.pem/.crt/.der/.csr/.p12/…): the panel hands the URL to the in-browser cert viewer (ASN.1/X.509). */\n cert?: boolean\n /** Keystore (.jks/.keystore/.jceks + PKCS#12 .p12/.pfx): the panel hands the URL to the in-browser keystore viewer (sniffs format, parse + password decrypt). */\n jks?: boolean\n /** Subtitle (.srt/.vtt/.ass/.ssa): the panel renders the fetched text as a parsed cue list (render/source toggle). */\n subtitle?: boolean\n /** CSV / TSV (.csv/.tsv): the panel renders the fetched text as a parsed table (render/source toggle). */\n csv?: boolean\n /** JSON Lines (.jsonl/.ndjson): the panel renders the fetched text as a record list — truncated rows, click to expand (render/source toggle). */\n jsonl?: boolean\n /** Java bytecode (.class): the panel hands the URL to the in-browser class viewer (parse structure → fields/methods). */\n javaClass?: boolean\n /** JVM heap dump (.hprof): the panel hands the URL to the in-browser HPROF viewer (stream-parse → class histogram + per-class object drill-in). */\n hprof?: boolean\n /** Windows Installer (.msi/.msp/.msm): the panel hands the URL to the in-browser MSI viewer (OLE compound file → product identity + summary). */\n msi?: boolean\n /** Windows app package (.appx/.msix/.appxbundle/.msixbundle): the panel hands the URL to the in-browser APPX viewer (unzip manifest → identity/deps/capabilities). */\n appx?: boolean\n /** Font (.ttf/.otf/.woff/.woff2): the panel hands the URL to the in-browser font specimen (FontFace API). */\n font?: boolean\n /** Jupyter Notebook (.ipynb): the panel hands the URL to the in-browser notebook viewer (hand-rolled JSON parser). */\n ipynb?: boolean\n /** Geodata (.geojson/.kml/.gpx): the panel renders the fetched text as an offline SVG map (render/source toggle). */\n geo?: boolean\n /** Audio (mp3/wav/flac/ogg/m4a/aac/opus, or .mid): the panel hands the URL to the in-browser audio player. */\n audio?: boolean\n /** QQ Music encrypted audio (.mflac/.mgg/…): the panel hands the URL to the QMC player (decrypts in-browser, then plays). */\n qmc?: boolean\n /** LRC lyrics (.lrc): the panel hands the URL to the lyrics viewer (self-fetches + sniffs GBK, then renders synced lines). */\n lrc?: boolean\n /** Large text / `.log`: the panel hands the URL to the in-browser streaming log viewer (virtual-scrolled). */\n log?: boolean\n /** 3D model (.stl/.obj/.ply/.glb/.gltf): the panel hands the URL to the in-browser three.js model viewer. */\n model?: boolean\n /** Decoding image (TIFF/PSD/HEIC/RAW): the panel hands the URL + kind to the in-browser raster viewer. */\n raster?: 'tiff' | 'psd' | 'heic' | 'raw'\n /** E-book (EPUB/FB2/MOBI/DjVu): the panel hands the URL + kind to the in-browser e-book reader. */\n ebook?: 'epub' | 'fb2' | 'mobi' | 'djvu'\n /** Diagram (.drawio/.excalidraw): the panel renders the fetched text as an SVG (render/source toggle). */\n diagram?: 'drawio' | 'excalidraw'\n /** DXF (.dxf) CAD drawing: the panel hands the URL to the in-browser DXF viewer (parse → SVG, pan/zoom/layers). */\n dxf?: boolean\n /**\n * Raster image (png/jpg/…/svg-as-picture): rendered inline as a zoomable picture. The main FileChip flow\n * routes images to the LIGHTBOX, so this is set only for archive entries (browsed inside the side viewer,\n * where there is no lightbox) — see classifyViewerFile.\n */\n image?: boolean\n /** Video (mp4/webm/…): rendered inline with a native <video> player. Like {@link image}, set only for archive entries. */\n video?: boolean\n /** Unpreviewable binary: the body shows a \"can't preview — download\" card. Set only for archive entries with no matching viewer. */\n binary?: boolean\n /**\n * Hex dump: the panel hands the URL to the in-browser hex viewer (offset + raw bytes + ASCII gutter). Never\n * auto-detected — set only when the user picks \"十六进制\" from the unpreviewable-binary card's \"open with\"\n * chooser (any bytes can be inspected this way), see FileViewerBody.\n */\n hex?: boolean\n /** File size in bytes (from the manifest) when known — drives the symbol browser's large-file gate. */\n size?: number\n /** Inline text to render directly (e.g. a loaded skill's SKILL.md) — when set, the panel skips fetching. */\n content?: string\n}\n\n// Module-level singleton: a file chip (deep in the message tree) opens the viewer, and the panel\n// (mounted by DetailView) reads the same ref. The detail view closes it on navigation/unmount.\nconst current = ref<ViewerFile | null>(null)\n\n// Shared panel width (px), driven by the drag splitter. DetailView feeds it into `--fv-width` so the\n// conversation column reflows and the panel resizes together; the panel reads it for the drag baseline.\nconst MIN_WIDTH = 360\nconst MAX_WIDTH = 760\n\n// Open at the viewer's original responsive width — clamp(360, 42vw, 760) — so it starts wide; the\n// drag splitter adjusts from there. (No window under SSR: fall back to a sensible fixed default.)\nfunction defaultWidth(): number {\n if (typeof window === 'undefined') return 680\n return Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, Math.round(window.innerWidth * 0.42)))\n}\nconst width = ref(defaultWidth())\n\n/** Clamp to a sane range: never narrower than MIN_WIDTH, and always leave ~320px for the conversation. */\nfunction setWidth(px: number): void {\n const max = typeof window !== 'undefined' ? Math.max(MIN_WIDTH, window.innerWidth - 320) : 900\n width.value = Math.min(max, Math.max(MIN_WIDTH, Math.round(px)))\n}\n\nexport function useFileViewer() {\n return {\n current,\n width,\n setWidth,\n isOpen: computed(() => current.value !== null),\n open(file: ViewerFile): void {\n current.value = file\n },\n close(): void {\n current.value = null\n },\n }\n}\n"],"mappings":";;AAoHA,IAAM,IAAU,EAAuB,IAAI,GAIrC,IAAY,KACZ,IAAY;AAIlB,SAAS,IAAuB;CAE9B,OADI,OAAO,SAAW,MAAoB,MACnC,KAAK,IAAI,GAAW,KAAK,IAAI,GAAW,KAAK,MAAM,OAAO,aAAa,GAAI,CAAC,CAAC;AACtF;AACA,IAAM,IAAQ,EAAI,EAAa,CAAC;AAGhC,SAAS,EAAS,GAAkB;CAClC,IAAM,IAAM,OAAO,SAAW,MAAc,KAAK,IAAI,GAAW,OAAO,aAAa,GAAG,IAAI;CAC3F,EAAM,QAAQ,KAAK,IAAI,GAAK,KAAK,IAAI,GAAW,KAAK,MAAM,CAAE,CAAC,CAAC;AACjE;AAEA,SAAgB,IAAgB;CAC9B,OAAO;EACL;EACA;EACA;EACA,QAAQ,QAAe,EAAQ,UAAU,IAAI;EAC7C,KAAK,GAAwB;GAC3B,EAAQ,QAAQ;EAClB;EACA,QAAc;GACZ,EAAQ,QAAQ;EAClB;CACF;AACF"}
@@ -15,3 +15,5 @@ function r() {
15
15
  }
16
16
  //#endregion
17
17
  export { r as useLightbox };
18
+
19
+ //# sourceMappingURL=useLightbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLightbox.js","names":[],"sources":["../../src/composables/useLightbox.ts"],"sourcesContent":["import { computed, ref } from 'vue'\n\n/** Media shown full-screen in the lightbox: its source URL, an alt/title, and the kind to render. */\nexport interface LightboxImage {\n src: string\n alt?: string\n /** 'video' fetches the source and plays it in a <video> (blob-backed); default 'image' shows an <img>. */\n kind?: 'image' | 'video'\n /** A \"long image\" (tall screenshot): show it at a readable width inside a vertical-scroll frame, not letterboxed. */\n long?: boolean\n}\n\n// Module-level singleton: a thumbnail anywhere in the message tree opens the lightbox, and the single\n// ImageLightbox overlay (mounted in App.vue) reads the same ref. Mirrors useFileViewer's pattern.\nconst current = ref<LightboxImage | null>(null)\n\nexport function useLightbox() {\n return {\n current,\n isOpen: computed(() => current.value !== null),\n open(img: LightboxImage): void {\n if (img.src) current.value = img\n },\n close(): void {\n current.value = null\n },\n }\n}\n"],"mappings":";;AAcA,IAAM,IAAU,EAA0B,IAAI;AAE9C,SAAgB,IAAc;CAC5B,OAAO;EACL;EACA,QAAQ,QAAe,EAAQ,UAAU,IAAI;EAC7C,KAAK,GAA0B;GAC7B,AAAI,EAAI,QAAK,EAAQ,QAAQ;EAC/B;EACA,QAAc;GACZ,EAAQ,QAAQ;EAClB;CACF;AACF"}
@@ -72,3 +72,5 @@ function c() {
72
72
  }
73
73
  //#endregion
74
74
  export { c as useLogRules };
75
+
76
+ //# sourceMappingURL=useLogRules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLogRules.js","names":[],"sources":["../../src/composables/useLogRules.ts"],"sourcesContent":["import { ref, watch } from 'vue'\n\n/**\n * A single line-coloring rule for the log viewer: match lines by substring or regex, then paint their\n * background and/or text. Rules apply top-to-bottom, first match wins (see LogViewer's `styleFor`).\n */\nexport interface ColorRule {\n id: string\n pattern: string\n regex: boolean // treat `pattern` as a RegExp instead of a plain substring\n caseSensitive: boolean\n bgOn: boolean\n bg: string // hex background color, applied when bgOn\n fgOn: boolean\n fg: string // hex text color, applied when fgOn\n enabled: boolean\n}\n\nconst STORAGE_KEY = 'viewer-log-color-rules'\n\nfunction newId(): string {\n try {\n return crypto.randomUUID()\n } catch {\n // Non-secure contexts / very old engines lack randomUUID — a timestamp-ish id is unique enough for a\n // local, per-browser preference list.\n return 'r' + Date.now().toString(36) + Math.floor(Math.random() * 1e9).toString(36)\n }\n}\n\nexport function defaultRule(): ColorRule {\n return {\n id: newId(),\n pattern: '',\n regex: false,\n caseSensitive: false,\n bgOn: true,\n bg: '#fde68a',\n fgOn: false,\n fg: '#111827',\n enabled: true,\n }\n}\n\n// Tolerate absent / partial / garbled persisted entries by filling each field from a default.\nfunction sanitize(x: unknown): ColorRule | null {\n if (!x || typeof x !== 'object') return null\n const o = x as Record<string, unknown>\n const d = defaultRule()\n return {\n id: typeof o.id === 'string' ? o.id : d.id,\n pattern: typeof o.pattern === 'string' ? o.pattern : '',\n regex: !!o.regex,\n caseSensitive: !!o.caseSensitive,\n bgOn: o.bgOn !== false,\n bg: typeof o.bg === 'string' ? o.bg : d.bg,\n fgOn: !!o.fgOn,\n fg: typeof o.fg === 'string' ? o.fg : d.fg,\n enabled: o.enabled !== false,\n }\n}\n\nfunction readInitial(): ColorRule[] {\n if (typeof localStorage !== 'undefined') {\n try {\n const raw = localStorage.getItem(STORAGE_KEY)\n if (raw) {\n const arr = JSON.parse(raw)\n if (Array.isArray(arr)) {\n return arr.map(sanitize).filter((r): r is ColorRule => r !== null)\n }\n }\n } catch {\n // Malformed JSON — ignore and start empty.\n }\n }\n return []\n}\n\n// Module-level singleton so rules persist across files, viewer re-mounts, and reloads.\nconst rules = ref<ColorRule[]>(readInitial())\nwatch(\n rules,\n (v) => {\n if (typeof localStorage !== 'undefined') {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(v))\n } catch {\n // Storage full / disabled — the rules still work for this session.\n }\n }\n },\n { deep: true },\n)\n\n/**\n * Persisted, browser-global line-coloring rules for the log viewer. A singleton (like {@link useListPrefs})\n * so the set sticks across navigation and reloads; every mutation reassigns/deep-touches `rules` so the\n * watcher writes through to localStorage.\n */\nexport function useLogRules() {\n function add(): void {\n rules.value = [...rules.value, defaultRule()]\n }\n function remove(id: string): void {\n rules.value = rules.value.filter((r) => r.id !== id)\n }\n // Reorder (first-match precedence): swap a rule with its neighbor.\n function move(id: string, dir: -1 | 1): void {\n const arr = [...rules.value]\n const i = arr.findIndex((r) => r.id === id)\n const j = i + dir\n if (i < 0 || j < 0 || j >= arr.length) return\n ;[arr[i], arr[j]] = [arr[j], arr[i]]\n rules.value = arr\n }\n return { rules, add, remove, move }\n}\n"],"mappings":";;AAkBA,IAAM,IAAc;AAEpB,SAAS,IAAgB;CACvB,IAAI;EACF,OAAO,OAAO,WAAW;CAC3B,QAAQ;EAGN,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,SAAS,EAAE,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE;CACpF;AACF;AAEA,SAAgB,IAAyB;CACvC,OAAO;EACL,IAAI,EAAM;EACV,SAAS;EACT,OAAO;EACP,eAAe;EACf,MAAM;EACN,IAAI;EACJ,MAAM;EACN,IAAI;EACJ,SAAS;CACX;AACF;AAGA,SAAS,EAAS,GAA8B;CAC9C,IAAI,CAAC,KAAK,OAAO,KAAM,UAAU,OAAO;CACxC,IAAM,IAAI,GACJ,IAAI,EAAY;CACtB,OAAO;EACL,IAAI,OAAO,EAAE,MAAO,WAAW,EAAE,KAAK,EAAE;EACxC,SAAS,OAAO,EAAE,WAAY,WAAW,EAAE,UAAU;EACrD,OAAO,CAAC,CAAC,EAAE;EACX,eAAe,CAAC,CAAC,EAAE;EACnB,MAAM,EAAE,SAAS;EACjB,IAAI,OAAO,EAAE,MAAO,WAAW,EAAE,KAAK,EAAE;EACxC,MAAM,CAAC,CAAC,EAAE;EACV,IAAI,OAAO,EAAE,MAAO,WAAW,EAAE,KAAK,EAAE;EACxC,SAAS,EAAE,YAAY;CACzB;AACF;AAEA,SAAS,IAA2B;CAClC,IAAI,OAAO,eAAiB,KAC1B,IAAI;EACF,IAAM,IAAM,aAAa,QAAQ,CAAW;EAC5C,IAAI,GAAK;GACP,IAAM,IAAM,KAAK,MAAM,CAAG;GAC1B,IAAI,MAAM,QAAQ,CAAG,GACnB,OAAO,EAAI,IAAI,CAAQ,CAAC,CAAC,QAAQ,MAAsB,MAAM,IAAI;EAErE;CACF,QAAQ,CAER;CAEF,OAAO,CAAC;AACV;AAGA,IAAM,IAAQ,EAAiB,EAAY,CAAC;AAC5C,EACE,IACC,MAAM;CACL,IAAI,OAAO,eAAiB,KAC1B,IAAI;EACF,aAAa,QAAQ,GAAa,KAAK,UAAU,CAAC,CAAC;CACrD,QAAQ,CAER;AAEJ,GACA,EAAE,MAAM,GAAK,CACf;AAOA,SAAgB,IAAc;CAC5B,SAAS,IAAY;EACnB,EAAM,QAAQ,CAAC,GAAG,EAAM,OAAO,EAAY,CAAC;CAC9C;CACA,SAAS,EAAO,GAAkB;EAChC,EAAM,QAAQ,EAAM,MAAM,QAAQ,MAAM,EAAE,OAAO,CAAE;CACrD;CAEA,SAAS,EAAK,GAAY,GAAmB;EAC3C,IAAM,IAAM,CAAC,GAAG,EAAM,KAAK,GACrB,IAAI,EAAI,WAAW,MAAM,EAAE,OAAO,CAAE,GACpC,IAAI,IAAI;EACV,IAAI,KAAK,IAAI,KAAK,KAAK,EAAI,WAC9B,CAAC,EAAI,IAAI,EAAI,MAAM,CAAC,EAAI,IAAI,EAAI,EAAE,GACnC,EAAM,QAAQ;CAChB;CACA,OAAO;EAAE;EAAO;EAAK;EAAQ;CAAK;AACpC"}
package/dist/lib/aes.js CHANGED
@@ -97,3 +97,5 @@ function u(e, t, n) {
97
97
  }
98
98
  //#endregion
99
99
  export { u as aesCbcDecrypt, l as aesCtrXor };
100
+
101
+ //# sourceMappingURL=aes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aes.js","names":[],"sources":["../../src/lib/aes.ts"],"sourcesContent":["/**\n * Compact AES shared by the in-browser archive viewers — no dependency, no WASM.\n *\n * The FORWARD cipher drives CTR mode (WinZip-AES ZIP extraction, see {@link lib/zip.ts}); the INVERSE\n * cipher drives CBC decryption (AES-256 encrypted 7z extraction, see {@link lib/sevenZip.ts}). The S-box is\n * generated from the GF(2^8) affine transform (not tabled); the inverse S-box and the GF multiplies for\n * InvMixColumns are derived from it. Key derivation (PBKDF2 / SHA-256) stays in each caller via WebCrypto —\n * this module is pure block/mode math and stays synchronous.\n *\n * State layout is column-major: byte `s[4*col + row]`, matching the AES spec's column words. Encrypt and\n * decrypt share the key schedule and AddRoundKey; only Sub/Shift/Mix differ (forward vs inverse).\n */\n\n// S-box generated from the affine transform over GF(2^8).\nconst SBOX = /* @__PURE__ */ (() => {\n const sbox = new Uint8Array(256)\n const rotl8 = (x: number, s: number): number => ((x << s) | (x >> (8 - s))) & 0xff\n let p = 1\n let q = 1\n do {\n p = (p ^ (p << 1) ^ (p & 0x80 ? 0x11b : 0)) & 0xff\n q ^= q << 1\n q ^= q << 2\n q ^= q << 4\n q &= 0xff\n if (q & 0x80) q ^= 0x09\n q &= 0xff\n sbox[p] = (q ^ rotl8(q, 1) ^ rotl8(q, 2) ^ rotl8(q, 3) ^ rotl8(q, 4) ^ 0x63) & 0xff\n } while (p !== 1)\n sbox[0] = 0x63\n return sbox\n})()\n// Inverse S-box: INV_SBOX[SBOX[i]] = i.\nconst INV_SBOX = /* @__PURE__ */ (() => {\n const inv = new Uint8Array(256)\n for (let i = 0; i < 256; i++) inv[SBOX[i]] = i\n return inv\n})()\nconst RCON = new Uint8Array([0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c])\nconst xtime = (a: number): number => ((a << 1) ^ (a & 0x80 ? 0x11b : 0)) & 0xff\n// GF(2^8) multiply (peasant) — only InvMixColumns needs the {09,0b,0d,0e} multiplies.\nfunction gmul(a: number, b: number): number {\n let p = 0\n for (let i = 0; i < 8 && b; i++) {\n if (b & 1) p ^= a\n const hi = a & 0x80\n a = (a << 1) & 0xff\n if (hi) a ^= 0x1b\n b >>= 1\n }\n return p & 0xff\n}\n\n/** Expand a 16/24/32-byte key into the round-key word schedule. */\nexport function aesKeySchedule(key: Uint8Array): Uint32Array {\n const Nk = key.length / 4\n const Nr = Nk + 6\n const w = new Uint32Array(4 * (Nr + 1))\n for (let i = 0; i < Nk; i++) {\n w[i] =\n ((key[4 * i] << 24) | (key[4 * i + 1] << 16) | (key[4 * i + 2] << 8) | key[4 * i + 3]) >>> 0\n }\n const sub = (x: number): number =>\n ((SBOX[(x >>> 24) & 0xff] << 24) |\n (SBOX[(x >>> 16) & 0xff] << 16) |\n (SBOX[(x >>> 8) & 0xff] << 8) |\n SBOX[x & 0xff]) >>>\n 0\n const rot = (x: number): number => ((x << 8) | (x >>> 24)) >>> 0\n for (let i = Nk; i < w.length; i++) {\n let t = w[i - 1]\n if (i % Nk === 0) t = (sub(rot(t)) ^ (RCON[i / Nk - 1] << 24)) >>> 0\n else if (Nk > 6 && i % Nk === 4) t = sub(t)\n w[i] = (w[i - Nk] ^ t) >>> 0\n }\n return w\n}\n\nfunction addRoundKey(s: Uint8Array, w: Uint32Array, round: number): void {\n for (let c = 0; c < 4; c++) {\n const k = w[round * 4 + c]\n s[4 * c] ^= (k >>> 24) & 0xff\n s[4 * c + 1] ^= (k >>> 16) & 0xff\n s[4 * c + 2] ^= (k >>> 8) & 0xff\n s[4 * c + 3] ^= k & 0xff\n }\n}\n\n/** Encrypt one 16-byte block in place into `out` (forward cipher). */\nexport function aesEncryptBlock(w: Uint32Array, block: Uint8Array, out: Uint8Array): void {\n const Nr = w.length / 4 - 1\n const s = out\n s.set(block)\n addRoundKey(s, w, 0)\n for (let round = 1; round <= Nr; round++) {\n for (let i = 0; i < 16; i++) s[i] = SBOX[s[i]]\n // ShiftRows (row r rotates LEFT by r)\n let tmp = s[1]\n s[1] = s[5]\n s[5] = s[9]\n s[9] = s[13]\n s[13] = tmp\n tmp = s[2]\n s[2] = s[10]\n s[10] = tmp\n tmp = s[6]\n s[6] = s[14]\n s[14] = tmp\n tmp = s[15]\n s[15] = s[11]\n s[11] = s[7]\n s[7] = s[3]\n s[3] = tmp\n if (round < Nr) {\n for (let c = 0; c < 4; c++) {\n const i = 4 * c\n const a0 = s[i]\n const a1 = s[i + 1]\n const a2 = s[i + 2]\n const a3 = s[i + 3]\n const t = a0 ^ a1 ^ a2 ^ a3\n s[i] ^= t ^ xtime(a0 ^ a1)\n s[i + 1] ^= t ^ xtime(a1 ^ a2)\n s[i + 2] ^= t ^ xtime(a2 ^ a3)\n s[i + 3] ^= t ^ xtime(a3 ^ a0)\n }\n }\n addRoundKey(s, w, round)\n }\n}\n\n/** Decrypt one 16-byte block in place into `out` (inverse cipher). */\nexport function aesDecryptBlock(w: Uint32Array, block: Uint8Array, out: Uint8Array): void {\n const Nr = w.length / 4 - 1\n const s = out\n s.set(block)\n addRoundKey(s, w, Nr)\n for (let round = Nr - 1; round >= 0; round--) {\n // InvShiftRows (row r rotates RIGHT by r)\n let tmp = s[13]\n s[13] = s[9]\n s[9] = s[5]\n s[5] = s[1]\n s[1] = tmp\n tmp = s[2]\n s[2] = s[10]\n s[10] = tmp\n tmp = s[6]\n s[6] = s[14]\n s[14] = tmp\n tmp = s[3]\n s[3] = s[7]\n s[7] = s[11]\n s[11] = s[15]\n s[15] = tmp\n for (let i = 0; i < 16; i++) s[i] = INV_SBOX[s[i]]\n addRoundKey(s, w, round)\n if (round > 0) {\n for (let c = 0; c < 4; c++) {\n const i = 4 * c\n const a0 = s[i]\n const a1 = s[i + 1]\n const a2 = s[i + 2]\n const a3 = s[i + 3]\n s[i] = gmul(a0, 14) ^ gmul(a1, 11) ^ gmul(a2, 13) ^ gmul(a3, 9)\n s[i + 1] = gmul(a0, 9) ^ gmul(a1, 14) ^ gmul(a2, 11) ^ gmul(a3, 13)\n s[i + 2] = gmul(a0, 13) ^ gmul(a1, 9) ^ gmul(a2, 14) ^ gmul(a3, 11)\n s[i + 3] = gmul(a0, 11) ^ gmul(a1, 13) ^ gmul(a2, 9) ^ gmul(a3, 14)\n }\n }\n }\n}\n\n/** WinZip AES-CTR keystream (counter is a 16-byte LITTLE-endian integer starting at 1) XORed over `data`. */\nexport function aesCtrXor(key: Uint8Array, data: Uint8Array): Uint8Array {\n const w = aesKeySchedule(key)\n const out = new Uint8Array(data.length)\n const counter = new Uint8Array(16)\n const ks = new Uint8Array(16)\n let block = 1\n for (let off = 0; off < data.length; off += 16) {\n let v = block++\n for (let i = 0; i < 8; i++) {\n counter[i] = v & 0xff\n v = Math.floor(v / 256)\n }\n aesEncryptBlock(w, counter, ks)\n const n = Math.min(16, data.length - off)\n for (let i = 0; i < n; i++) out[off + i] = data[off + i] ^ ks[i]\n }\n return out\n}\n\n/**\n * AES-CBC decrypt (no padding removal — 7z stores the real output length separately and its ciphertext is a\n * whole number of blocks). `iv` is 16 bytes; only full 16-byte blocks of `data` are processed.\n */\nexport function aesCbcDecrypt(key: Uint8Array, iv: Uint8Array, data: Uint8Array): Uint8Array {\n const w = aesKeySchedule(key)\n const n = data.length - (data.length % 16)\n const out = new Uint8Array(n)\n const dec = new Uint8Array(16)\n const prev = new Uint8Array(16)\n prev.set(iv.subarray(0, 16))\n for (let off = 0; off < n; off += 16) {\n const block = data.subarray(off, off + 16)\n aesDecryptBlock(w, block, dec)\n for (let i = 0; i < 16; i++) out[off + i] = dec[i] ^ prev[i]\n prev.set(block)\n }\n return out\n}\n"],"mappings":"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"}
package/dist/lib/appx.js CHANGED
@@ -110,3 +110,5 @@ function l(e, t) {
110
110
  }
111
111
  //#endregion
112
112
  export { n as NotAppxError, r as parseAppx };
113
+
114
+ //# sourceMappingURL=appx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appx.js","names":[],"sources":["../../src/lib/appx.ts"],"sourcesContent":["/**\n * In-browser APPX / MSIX package reader — no dependency beyond the project's own ZIP reader.\n *\n * An `.appx`/`.msix` (and `.appxbundle`/`.msixbundle`) is NOT a PE and NOT an OLE compound file — it's an\n * **OPC ZIP archive** (the same container `.docx`/`.jar` use). Its metadata lives in an XML manifest inside:\n * - a single package: `AppxManifest.xml` — `<Identity>` (name/version/arch/publisher), `<Properties>`\n * (display + publisher names), `<Dependencies>` (target OS + package deps), `<Capabilities>`,\n * `<Applications>`, and the declared `<Resources>` languages.\n * - a bundle: `AppxMetadata/AppxBundleManifest.xml` — `<Identity>` + the list of contained `<Package>`s.\n *\n * We decompress just the manifest with the project's ZIP reader (lib/zip.ts — browser-native DEFLATE) and\n * read the fields with the DOM (namespace-agnostic local-name matching, since real manifests sprinkle uap/\n * rescap/wincap prefixes). The manifest structure was checked against a real Microsoft Store `.appx`.\n *\n * Used by AppxViewer (the side viewer's APPX mode): the bytes come from the same download endpoint as any\n * other file, are unzipped + parsed entirely client-side, and never leave the browser.\n */\n\nimport { readZip, extractZipEntry, type ZipEntry } from '@/lib/zip'\n\nexport interface AppxVersionRef {\n name: string\n minVersion?: string\n maxVersionTested?: string\n publisher?: string\n}\nexport interface AppxApp {\n id: string\n displayName?: string\n description?: string\n}\nexport interface AppxBundlePackage {\n type?: string\n architecture?: string\n version?: string\n fileName?: string\n}\n\nexport interface AppxInfo {\n kind: 'package' | 'bundle'\n /** Identity (`<Identity>`): the package family identity. */\n name?: string\n version?: string\n architecture?: string\n /** Raw publisher distinguished name, e.g. \"CN=Microsoft Corporation, …\". */\n publisher?: string\n /** `<Properties>` display fields (DisplayName may be an `ms-resource:…` reference we can't resolve here). */\n displayName?: string\n publisherDisplayName?: string\n description?: string\n /** `<Dependencies>`: target OS families + package dependencies. */\n targetDeviceFamilies: AppxVersionRef[]\n packageDependencies: AppxVersionRef[]\n /** `<Capabilities>` declared capability names (restricted/device ones included). */\n capabilities: string[]\n /** `<Applications>` entry points. */\n applications: AppxApp[]\n /** Declared resource languages (`<Resources><Resource Language=…>`). */\n languages: string[]\n /** For a bundle: the contained packages. */\n bundlePackages: AppxBundlePackage[]\n /** Number of files in the archive. */\n fileCount: number\n notes: string[]\n}\n\n/** Thrown when the bytes aren't an APPX/MSIX (not a zip, or no manifest inside). */\nexport class NotAppxError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'NotAppxError'\n }\n}\n\nexport async function parseAppx(buf: ArrayBuffer): Promise<AppxInfo> {\n let entries: ZipEntry[]\n try {\n entries = readZip(buf)\n } catch {\n throw new NotAppxError('不是有效的 APPX/MSIX(无法读取 ZIP 容器)')\n }\n const find = (path: string): ZipEntry | undefined =>\n entries.find((e) => e.path.toLowerCase() === path.toLowerCase())\n const pkgEntry = find('AppxManifest.xml')\n const bundleEntry = find('AppxMetadata/AppxBundleManifest.xml') ?? find('AppxBundleManifest.xml')\n const manifestEntry = pkgEntry ?? bundleEntry\n if (!manifestEntry) {\n throw new NotAppxError('未找到 AppxManifest.xml(不是 APPX/MSIX 包)')\n }\n\n const bytes = await extractZipEntry(buf, manifestEntry)\n const xml = new TextDecoder('utf-8').decode(bytes)\n const doc = new DOMParser().parseFromString(xml, 'application/xml')\n if (doc.getElementsByTagName('parsererror').length > 0) {\n throw new NotAppxError('AppxManifest.xml 解析失败(XML 无效)')\n }\n const fileCount = entries.filter((e) => !e.isDir).length\n return pkgEntry ? parsePackage(doc, fileCount) : parseBundle(doc, fileCount)\n}\n\n// ── DOM helpers (namespace-agnostic: match by localName, since prefixes vary uap/uap4/rescap/wincap/…) ──\nfunction byLocal(root: Element | Document, local: string): Element[] {\n const all = root.getElementsByTagName('*')\n const out: Element[] = []\n for (let i = 0; i < all.length; i++) if (all[i].localName === local) out.push(all[i])\n return out\n}\nfunction firstLocal(root: Element | Document | null, local: string): Element | null {\n if (!root) return null\n const all = root.getElementsByTagName('*')\n for (let i = 0; i < all.length; i++) if (all[i].localName === local) return all[i]\n return null\n}\nfunction attr(el: Element | null, name: string): string | undefined {\n const v = el?.getAttribute(name)\n return v == null || v === '' ? undefined : v\n}\nfunction textOf(root: Element | null, local: string): string | undefined {\n const t = firstLocal(root, local)?.textContent?.trim()\n return t ? t : undefined\n}\n\nfunction parsePackage(doc: Document, fileCount: number): AppxInfo {\n const identity = firstLocal(doc, 'Identity')\n const props = firstLocal(doc, 'Properties')\n\n const targetDeviceFamilies = byLocal(doc, 'TargetDeviceFamily').map((e) => ({\n name: attr(e, 'Name') ?? '',\n minVersion: attr(e, 'MinVersion'),\n maxVersionTested: attr(e, 'MaxVersionTested'),\n }))\n const packageDependencies = byLocal(doc, 'PackageDependency').map((e) => ({\n name: attr(e, 'Name') ?? '',\n minVersion: attr(e, 'MinVersion'),\n publisher: attr(e, 'Publisher'),\n }))\n\n // Capabilities: any child of <Capabilities> carrying a Name (Capability / rescap:Capability / DeviceCapability…).\n const capabilities: string[] = []\n const capsRoot = firstLocal(doc, 'Capabilities')\n if (capsRoot) {\n const kids = capsRoot.getElementsByTagName('*')\n for (let i = 0; i < kids.length; i++) {\n const n = attr(kids[i], 'Name')\n if (n && !capabilities.includes(n)) capabilities.push(n)\n }\n }\n\n const applications = byLocal(doc, 'Application').map((a) => {\n const ve = firstLocal(a, 'VisualElements')\n return {\n id: attr(a, 'Id') ?? '',\n displayName: attr(ve, 'DisplayName'),\n description: attr(ve, 'Description'),\n }\n })\n\n const languages: string[] = []\n for (const r of byLocal(doc, 'Resource')) {\n const l = attr(r, 'Language')\n if (l && !languages.includes(l)) languages.push(l)\n }\n\n return {\n kind: 'package',\n name: attr(identity, 'Name'),\n version: attr(identity, 'Version'),\n architecture: attr(identity, 'ProcessorArchitecture'),\n publisher: attr(identity, 'Publisher'),\n displayName: textOf(props, 'DisplayName'),\n publisherDisplayName: textOf(props, 'PublisherDisplayName'),\n description: textOf(props, 'Description'),\n targetDeviceFamilies,\n packageDependencies,\n capabilities,\n applications,\n languages,\n bundlePackages: [],\n fileCount,\n notes: [],\n }\n}\n\nfunction parseBundle(doc: Document, fileCount: number): AppxInfo {\n const identity = firstLocal(doc, 'Identity')\n // A bundle manifest lists its contained packages; skip the <Resources> (per-package language slivers).\n const bundlePackages = byLocal(doc, 'Package').map((p) => ({\n type: attr(p, 'Type'),\n architecture: attr(p, 'Architecture'),\n version: attr(p, 'Version'),\n fileName: attr(p, 'FileName'),\n }))\n return {\n kind: 'bundle',\n name: attr(identity, 'Name'),\n version: attr(identity, 'Version'),\n architecture: undefined,\n publisher: attr(identity, 'Publisher'),\n targetDeviceFamilies: [],\n packageDependencies: [],\n capabilities: [],\n applications: [],\n languages: [],\n bundlePackages,\n fileCount,\n notes: [],\n }\n}\n"],"mappings":";;AAmEA,IAAa,IAAb,cAAkC,MAAM;CACtC,YAAY,GAAiB;EAE3B,AADA,MAAM,CAAO,GACb,KAAK,OAAO;CACd;AACF;AAEA,eAAsB,EAAU,GAAqC;CACnE,IAAI;CACJ,IAAI;EACF,IAAU,EAAQ,CAAG;CACvB,QAAQ;EACN,MAAM,IAAI,EAAa,8BAA8B;CACvD;CACA,IAAM,KAAQ,MACZ,EAAQ,MAAM,MAAM,EAAE,KAAK,YAAY,MAAM,EAAK,YAAY,CAAC,GAC3D,IAAW,EAAK,kBAAkB,GAClC,IAAc,EAAK,qCAAqC,KAAK,EAAK,wBAAwB,GAC1F,IAAgB,KAAY;CAClC,IAAI,CAAC,GACH,MAAM,IAAI,EAAa,sCAAsC;CAG/D,IAAM,IAAQ,MAAM,EAAgB,GAAK,CAAa,GAChD,IAAM,IAAI,YAAY,OAAO,CAAC,CAAC,OAAO,CAAK,GAC3C,IAAM,IAAI,UAAU,CAAC,CAAC,gBAAgB,GAAK,iBAAiB;CAClE,IAAI,EAAI,qBAAqB,aAAa,CAAC,CAAC,SAAS,GACnD,MAAM,IAAI,EAAa,+BAA+B;CAExD,IAAM,IAAY,EAAQ,QAAQ,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;CAClD,OAAO,IAAW,EAAa,GAAK,CAAS,IAAI,EAAY,GAAK,CAAS;AAC7E;AAGA,SAAS,EAAQ,GAA0B,GAA0B;CACnE,IAAM,IAAM,EAAK,qBAAqB,GAAG,GACnC,IAAiB,CAAC;CACxB,KAAK,IAAI,IAAI,GAAG,IAAI,EAAI,QAAQ,KAAK,AAAI,EAAI,EAAE,CAAC,cAAc,KAAO,EAAI,KAAK,EAAI,EAAE;CACpF,OAAO;AACT;AACA,SAAS,EAAW,GAAiC,GAA+B;CAClF,IAAI,CAAC,GAAM,OAAO;CAClB,IAAM,IAAM,EAAK,qBAAqB,GAAG;CACzC,KAAK,IAAI,IAAI,GAAG,IAAI,EAAI,QAAQ,KAAK,IAAI,EAAI,EAAE,CAAC,cAAc,GAAO,OAAO,EAAI;CAChF,OAAO;AACT;AACA,SAAS,EAAK,GAAoB,GAAkC;CAClE,IAAM,IAAI,GAAI,aAAa,CAAI;CAC/B,OAAO,KAAK,QAAQ,MAAM,KAAK,KAAA,IAAY;AAC7C;AACA,SAAS,EAAO,GAAsB,GAAmC;CAEvE,OADU,EAAW,GAAM,CAAK,CAAC,EAAE,aAAa,KAAK,KACtC,KAAA;AACjB;AAEA,SAAS,EAAa,GAAe,GAA6B;CAChE,IAAM,IAAW,EAAW,GAAK,UAAU,GACrC,IAAQ,EAAW,GAAK,YAAY,GAEpC,IAAuB,EAAQ,GAAK,oBAAoB,CAAC,CAAC,KAAK,OAAO;EAC1E,MAAM,EAAK,GAAG,MAAM,KAAK;EACzB,YAAY,EAAK,GAAG,YAAY;EAChC,kBAAkB,EAAK,GAAG,kBAAkB;CAC9C,EAAE,GACI,IAAsB,EAAQ,GAAK,mBAAmB,CAAC,CAAC,KAAK,OAAO;EACxE,MAAM,EAAK,GAAG,MAAM,KAAK;EACzB,YAAY,EAAK,GAAG,YAAY;EAChC,WAAW,EAAK,GAAG,WAAW;CAChC,EAAE,GAGI,IAAyB,CAAC,GAC1B,IAAW,EAAW,GAAK,cAAc;CAC/C,IAAI,GAAU;EACZ,IAAM,IAAO,EAAS,qBAAqB,GAAG;EAC9C,KAAK,IAAI,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK;GACpC,IAAM,IAAI,EAAK,EAAK,IAAI,MAAM;GAC9B,AAAI,KAAK,CAAC,EAAa,SAAS,CAAC,KAAG,EAAa,KAAK,CAAC;EACzD;CACF;CAEA,IAAM,IAAe,EAAQ,GAAK,aAAa,CAAC,CAAC,KAAK,MAAM;EAC1D,IAAM,IAAK,EAAW,GAAG,gBAAgB;EACzC,OAAO;GACL,IAAI,EAAK,GAAG,IAAI,KAAK;GACrB,aAAa,EAAK,GAAI,aAAa;GACnC,aAAa,EAAK,GAAI,aAAa;EACrC;CACF,CAAC,GAEK,IAAsB,CAAC;CAC7B,KAAK,IAAM,KAAK,EAAQ,GAAK,UAAU,GAAG;EACxC,IAAM,IAAI,EAAK,GAAG,UAAU;EAC5B,AAAI,KAAK,CAAC,EAAU,SAAS,CAAC,KAAG,EAAU,KAAK,CAAC;CACnD;CAEA,OAAO;EACL,MAAM;EACN,MAAM,EAAK,GAAU,MAAM;EAC3B,SAAS,EAAK,GAAU,SAAS;EACjC,cAAc,EAAK,GAAU,uBAAuB;EACpD,WAAW,EAAK,GAAU,WAAW;EACrC,aAAa,EAAO,GAAO,aAAa;EACxC,sBAAsB,EAAO,GAAO,sBAAsB;EAC1D,aAAa,EAAO,GAAO,aAAa;EACxC;EACA;EACA;EACA;EACA;EACA,gBAAgB,CAAC;EACjB;EACA,OAAO,CAAC;CACV;AACF;AAEA,SAAS,EAAY,GAAe,GAA6B;CAC/D,IAAM,IAAW,EAAW,GAAK,UAAU,GAErC,IAAiB,EAAQ,GAAK,SAAS,CAAC,CAAC,KAAK,OAAO;EACzD,MAAM,EAAK,GAAG,MAAM;EACpB,cAAc,EAAK,GAAG,cAAc;EACpC,SAAS,EAAK,GAAG,SAAS;EAC1B,UAAU,EAAK,GAAG,UAAU;CAC9B,EAAE;CACF,OAAO;EACL,MAAM;EACN,MAAM,EAAK,GAAU,MAAM;EAC3B,SAAS,EAAK,GAAU,SAAS;EACjC,cAAc,KAAA;EACd,WAAW,EAAK,GAAU,WAAW;EACrC,sBAAsB,CAAC;EACvB,qBAAqB,CAAC;EACtB,cAAc,CAAC;EACf,cAAc,CAAC;EACf,WAAW,CAAC;EACZ;EACA;EACA,OAAO,CAAC;CACV;AACF"}
@@ -373,3 +373,5 @@ async function C(e) {
373
373
  }
374
374
  //#endregion
375
375
  export { C as buildArchiveHtmlPreview };
376
+
377
+ //# sourceMappingURL=archiveHtml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archiveHtml.js","names":[],"sources":["../../src/lib/archiveHtml.ts"],"sourcesContent":["/**\n * Build a renderable HTML document from one entry inside an archive.\n *\n * A selected ZIP entry normally gets a single `blob:` URL. That is enough for the HTML bytes themselves, but\n * relative references such as `./assets/app.js` and `./styles/site.css` have nowhere to resolve: blob URLs have\n * no archive directory behind them. This module treats the archive's flat entry list as a tiny read-only web\n * root, extracts only resources referenced by the selected document, and rewrites those references to `data:`\n * URLs before the document reaches FileViewerBody's sandboxed iframe.\n *\n * `data:` is deliberate rather than `blob:`. FileViewerBody's opt-in interactive iframe uses `allow-scripts`\n * WITHOUT `allow-same-origin`, giving it an opaque origin. Chromium correctly refuses subresource blob URLs\n * minted by the parent from that opaque frame, while data URLs remain loadable. Scripts therefore still run\n * only after the existing explicit opt-in, but both inert CSS/image preview and interactive JS work reliably.\n */\n\nimport { decodeTextSniff } from '@/lib/encoding'\nimport { fileExt } from '@/lib/fileType'\nimport { bytesToBinary } from '@/lib/mime'\n\nexport interface ArchiveHtmlEntry {\n path: string\n name: string\n size: number\n isDir: boolean\n}\n\nexport interface ArchiveHtmlPreviewOptions<T extends ArchiveHtmlEntry> {\n html: string\n documentPath: string\n entries: readonly T[]\n loadEntry: (entry: T) => Uint8Array | Promise<Uint8Array>\n /** Maximum number of distinct dependency entries automatically extracted. */\n maxResources?: number\n /** Maximum declared/decoded bytes across automatically extracted dependencies. */\n maxTotalBytes?: number\n /** Maximum declared/decoded bytes for one dependency. */\n maxEntryBytes?: number\n}\n\nexport interface ArchiveHtmlPreview {\n html: string\n loadedResources: number\n skippedResources: number\n}\n\ntype ResourceKind = 'raw' | 'css' | 'module' | 'html'\n\nconst DEFAULT_MAX_RESOURCES = 512\nconst DEFAULT_MAX_TOTAL_BYTES = 64 * 1024 * 1024\nconst DEFAULT_MAX_ENTRY_BYTES = 32 * 1024 * 1024\n\nconst MIME_BY_EXT: Record<string, string> = {\n css: 'text/css',\n js: 'text/javascript',\n mjs: 'text/javascript',\n cjs: 'text/javascript',\n json: 'application/json',\n map: 'application/json',\n wasm: 'application/wasm',\n html: 'text/html',\n htm: 'text/html',\n xhtml: 'application/xhtml+xml',\n xml: 'application/xml',\n svg: 'image/svg+xml',\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n webp: 'image/webp',\n bmp: 'image/bmp',\n ico: 'image/x-icon',\n avif: 'image/avif',\n mp3: 'audio/mpeg',\n wav: 'audio/wav',\n ogg: 'audio/ogg',\n opus: 'audio/opus',\n flac: 'audio/flac',\n mp4: 'video/mp4',\n webm: 'video/webm',\n mov: 'video/quicktime',\n woff: 'font/woff',\n woff2: 'font/woff2',\n ttf: 'font/ttf',\n otf: 'font/otf',\n eot: 'application/vnd.ms-fontobject',\n txt: 'text/plain',\n}\n\nfunction mimeForName(name: string): string {\n return MIME_BY_EXT[fileExt(name)] ?? 'application/octet-stream'\n}\n\nfunction dataUrl(bytes: Uint8Array, contentType: string): string {\n return `data:${contentType};base64,${btoa(bytesToBinary(bytes))}`\n}\n\nfunction stripQueryAndHash(ref: string): string {\n const end = ref.search(/[?#]/)\n return end < 0 ? ref : ref.slice(0, end)\n}\n\nfunction decodePath(path: string): string {\n try {\n return decodeURIComponent(path)\n } catch {\n return path\n }\n}\n\nfunction normalizePath(path: string): string | null {\n const out: string[] = []\n for (const part of decodePath(path).replace(/\\\\/g, '/').split('/')) {\n if (!part || part === '.') continue\n if (part === '..') {\n if (!out.length) return null\n out.pop()\n continue\n }\n out.push(part)\n }\n return out.join('/')\n}\n\nfunction dirOf(path: string): string {\n const i = path.lastIndexOf('/')\n return i < 0 ? '' : path.slice(0, i)\n}\n\nfunction isExternalOrInlineReference(ref: string): boolean {\n const s = ref.trim()\n return (\n !s ||\n s.startsWith('#') ||\n s.startsWith('?') ||\n s.startsWith('//') ||\n /^[a-z][a-z\\d+.-]*:/i.test(s)\n )\n}\n\n/**\n * Index archive entries and resolve an HTML/CSS/JS reference against the entry containing it.\n *\n * Root-relative references first target the real archive root, then the selected document's top-level wrapper\n * directory (the usual `site/index.html` ZIP layout). A case-insensitive fallback handles archives produced on\n * Windows without changing the exact-match preference of case-sensitive ZIP paths.\n */\nfunction archiveReferenceCandidates(ref: string, basePath: string): string[] {\n if (isExternalOrInlineReference(ref)) return []\n const bare = stripQueryAndHash(ref.trim())\n if (!bare) return []\n const cleanBase = normalizePath(basePath) ?? ''\n const baseDir = dirOf(cleanBase)\n const raw = bare.replace(/\\\\/g, '/')\n const candidates: string[] = []\n\n if (raw.startsWith('/')) {\n const rootPath = normalizePath(raw.slice(1))\n if (rootPath) candidates.push(rootPath)\n const wrapper = cleanBase.split('/')[0]\n if (wrapper && cleanBase.includes('/') && rootPath) {\n const wrapped = normalizePath(`${wrapper}/${rootPath}`)\n if (wrapped) candidates.push(wrapped)\n }\n if (baseDir && rootPath) {\n const local = normalizePath(`${baseDir}/${rootPath}`)\n if (local) candidates.push(local)\n }\n } else {\n const relative = normalizePath(baseDir ? `${baseDir}/${raw}` : raw)\n if (relative) candidates.push(relative)\n }\n return candidates\n}\n\nexport function createArchiveEntryResolver<T extends ArchiveHtmlEntry>(entries: readonly T[]) {\n const exact = new Map<string, T>()\n const folded = new Map<string, T | null>()\n for (const entry of entries) {\n if (entry.isDir) continue\n const path = normalizePath(entry.path)\n if (!path) continue\n exact.set(path, entry)\n const key = path.toLocaleLowerCase()\n if (!folded.has(key)) folded.set(key, entry)\n else folded.set(key, null)\n }\n\n const lookup = (path: string): T | undefined => {\n const hit = exact.get(path)\n if (hit) return hit\n return folded.get(path.toLocaleLowerCase()) ?? undefined\n }\n\n return (ref: string, basePath: string): T | undefined => {\n for (const candidate of archiveReferenceCandidates(ref, basePath)) {\n const hit = lookup(candidate)\n if (hit) return hit\n }\n return undefined\n }\n}\n\nasync function replaceAsync(\n input: string,\n pattern: RegExp,\n replacement: (match: RegExpExecArray) => string | Promise<string>,\n): Promise<string> {\n const flags = pattern.flags.includes('g') ? pattern.flags : pattern.flags + 'g'\n const re = new RegExp(pattern.source, flags)\n let out = ''\n let cursor = 0\n let match: RegExpExecArray | null\n while ((match = re.exec(input)) !== null) {\n out += input.slice(cursor, match.index)\n out += await replacement(match)\n cursor = match.index + match[0].length\n if (match[0].length === 0) re.lastIndex++\n }\n return out + input.slice(cursor)\n}\n\n/** Rewrite CSS `@import` and `url(...)` references through an async archive resource resolver. */\nexport async function rewriteArchiveCssReferences(\n css: string,\n resolve: (ref: string, kind: 'css' | 'raw') => string | null | Promise<string | null>,\n): Promise<string> {\n let out = await replaceAsync(\n css,\n /@import\\s+(?:url\\(\\s*)?(['\"]?)([^'\"\\s)]+)\\1\\s*\\)?/gi,\n async (match) => {\n const url = await resolve(match[2], 'css')\n return url ? `@import url(\"${url}\")` : match[0]\n },\n )\n out = await replaceAsync(out, /url\\(\\s*(['\"]?)([^'\")]+)\\1\\s*\\)/gi, async (match) => {\n const url = await resolve(match[2].trim(), 'raw')\n return url ? `url(\"${url}\")` : match[0]\n })\n return out\n}\n\n/** Best-effort rewrite for static/dynamic ESM imports and `new URL(x, import.meta.url)` assets. */\nexport async function rewriteArchiveModuleReferences(\n source: string,\n resolve: (ref: string, kind: 'module' | 'raw') => string | null | Promise<string | null>,\n): Promise<string> {\n // Bundler output is commonly whitespace-free (`import{a}from\"./chunk.js\"`, `export*from\"./chunk.js\"`).\n // Keep `from` declarations and side-effect imports as separate passes: this covers both authored and minified\n // ESM without confusing dynamic `import(...)` / `import.meta` with a quoted static specifier.\n let out = await replaceAsync(\n source,\n /\\b((?:import|export)[^'\";]*?\\bfrom\\s*)(['\"])([^'\"]+)\\2/g,\n async (match) => {\n const url = await resolve(match[3], 'module')\n return url ? `${match[1]}${match[2]}${url}${match[2]}` : match[0]\n },\n )\n out = await replaceAsync(out, /\\b(import\\s*)(['\"])([^'\"]+)\\2/g, async (match) => {\n const url = await resolve(match[3], 'module')\n return url ? `${match[1]}${match[2]}${url}${match[2]}` : match[0]\n })\n out = await replaceAsync(out, /\\b(import\\s*\\(\\s*)(['\"])([^'\"]+)\\2(\\s*\\))/g, async (match) => {\n const url = await resolve(match[3], 'module')\n return url ? `${match[1]}${match[2]}${url}${match[2]}${match[4]}` : match[0]\n })\n out = await replaceAsync(\n out,\n /\\bnew\\s+URL\\(\\s*(['\"])([^'\"]+)\\1\\s*,\\s*import\\.meta\\.url\\s*\\)/g,\n async (match) => {\n const url = await resolve(match[2], 'raw')\n return url ? `new URL(${JSON.stringify(url)})` : match[0]\n },\n )\n return out\n}\n\ntype ImportMapAddress = string | null\ntype ImportMapEntries = Record<string, ImportMapAddress>\n\ninterface ParsedArchiveImportMap {\n imports: ImportMapEntries\n scopes: Record<string, ImportMapEntries>\n}\n\ninterface ArchiveImportMapContext {\n id: number\n documentPath: string\n resolve: ReturnType<typeof createArchiveImportMapResolver>\n}\n\nfunction parseArchiveImportMaps(sources: readonly string[]): ParsedArchiveImportMap {\n const imports: ImportMapEntries = {}\n const scopes: Record<string, ImportMapEntries> = {}\n for (const source of sources) {\n try {\n const value: unknown = JSON.parse(source)\n if (!value || typeof value !== 'object' || Array.isArray(value)) continue\n const map = value as Record<string, unknown>\n if (map.imports && typeof map.imports === 'object' && !Array.isArray(map.imports)) {\n for (const [key, address] of Object.entries(map.imports)) {\n if (!(key in imports) && (typeof address === 'string' || address === null)) {\n imports[key] = address\n }\n }\n }\n if (map.scopes && typeof map.scopes === 'object' && !Array.isArray(map.scopes)) {\n for (const [scope, rawEntries] of Object.entries(map.scopes)) {\n if (!rawEntries || typeof rawEntries !== 'object' || Array.isArray(rawEntries)) continue\n const entries = (scopes[scope] ??= {})\n for (const [key, address] of Object.entries(rawEntries)) {\n if (!(key in entries) && (typeof address === 'string' || address === null)) {\n entries[key] = address\n }\n }\n }\n }\n } catch {\n // The browser will report malformed import maps; leave them untouched and continue the HTML preview.\n }\n }\n return { imports, scopes }\n}\n\nfunction mappedAddress(entries: ImportMapEntries, specifier: string): string | null | undefined {\n if (Object.prototype.hasOwnProperty.call(entries, specifier)) return entries[specifier]\n let best = ''\n for (const key of Object.keys(entries)) {\n if (key.endsWith('/') && specifier.startsWith(key) && key.length > best.length) best = key\n }\n if (!best) return undefined\n const address = entries[best]\n if (address === null || !address.endsWith('/')) return null\n return address + specifier.slice(best.length)\n}\n\n/** Resolve bare ESM specifiers against inline import maps while paths still refer to archive entries. */\nexport function createArchiveImportMapResolver(sources: readonly string[], documentPath: string) {\n const map = parseArchiveImportMaps(sources)\n return (specifier: string, referrerPath: string): string | null | undefined => {\n let scoped: { prefix: string; entries: ImportMapEntries } | undefined\n for (const [scope, entries] of Object.entries(map.scopes)) {\n for (const prefix of archiveReferenceCandidates(scope, documentPath)) {\n const normalized = prefix.replace(/\\/$/, '')\n if (\n (referrerPath === normalized || referrerPath.startsWith(`${normalized}/`)) &&\n (!scoped || normalized.length > scoped.prefix.length)\n ) {\n scoped = { prefix: normalized, entries }\n }\n }\n }\n const scopedAddress = scoped ? mappedAddress(scoped.entries, specifier) : undefined\n return scopedAddress !== undefined ? scopedAddress : mappedAddress(map.imports, specifier)\n }\n}\n\nfunction kindForReference(entry: ArchiveHtmlEntry, requested: ResourceKind): ResourceKind {\n if (requested !== 'module') return requested\n const ext = fileExt(entry.name)\n if (ext === 'css') return 'css'\n if (ext === 'html' || ext === 'htm' || ext === 'xhtml') return 'html'\n return ext === 'js' || ext === 'mjs' || ext === 'cjs' ? 'module' : 'raw'\n}\n\n/**\n * Resolve one archive HTML entry plus its reachable dependencies into a complete iframe document.\n * Browser-only: DOMParser parses inertly; it neither executes scripts nor fetches the original references.\n */\nexport async function buildArchiveHtmlPreview<T extends ArchiveHtmlEntry>(\n options: ArchiveHtmlPreviewOptions<T>,\n): Promise<ArchiveHtmlPreview> {\n const resolveEntry = createArchiveEntryResolver(options.entries)\n const maxResources = options.maxResources ?? DEFAULT_MAX_RESOURCES\n const maxTotalBytes = options.maxTotalBytes ?? DEFAULT_MAX_TOTAL_BYTES\n const maxEntryBytes = options.maxEntryBytes ?? DEFAULT_MAX_ENTRY_BYTES\n const byteCache = new Map<T, Promise<Uint8Array | null>>()\n const urlCache = new Map<string, Promise<string | null>>()\n const building = new Set<string>()\n let importMapContextId = 0\n let claimedBytes = 0\n let loadedResources = 0\n let skippedResources = 0\n\n const loadBytes = (entry: T): Promise<Uint8Array | null> => {\n const cached = byteCache.get(entry)\n if (cached) return cached\n const work = (async (): Promise<Uint8Array | null> => {\n if (\n byteCache.size >= maxResources ||\n entry.size > maxEntryBytes ||\n claimedBytes + entry.size > maxTotalBytes\n ) {\n skippedResources++\n return null\n }\n claimedBytes += entry.size\n try {\n const bytes = await options.loadEntry(entry)\n if (\n bytes.byteLength > maxEntryBytes ||\n claimedBytes - entry.size + bytes.byteLength > maxTotalBytes\n ) {\n skippedResources++\n return null\n }\n claimedBytes += bytes.byteLength - entry.size\n loadedResources++\n return bytes\n } catch {\n skippedResources++\n return null\n }\n })()\n byteCache.set(entry, work)\n return work\n }\n\n const resourceUrl = async (\n entry: T,\n requested: ResourceKind,\n importMap?: ArchiveImportMapContext,\n ): Promise<string | null> => {\n const kind = kindForReference(entry, requested)\n const key = `${entry.path}\\u0000${kind}\\u0000${kind === 'module' ? (importMap?.id ?? '') : ''}`\n if (building.has(key)) return null // cyclic CSS/module imports keep that edge unchanged instead of deadlocking\n const cached = urlCache.get(key)\n if (cached) return cached\n building.add(key)\n const work = (async (): Promise<string | null> => {\n const bytes = await loadBytes(entry)\n if (!bytes) return null\n if (kind === 'css') {\n const css = await rewriteArchiveCssReferences(\n decodeTextSniff(bytes),\n async (ref, refKind) => {\n const dependency = resolveEntry(ref, entry.path)\n return dependency ? resourceUrl(dependency, refKind, importMap) : null\n },\n )\n return dataUrl(new TextEncoder().encode(css), 'text/css')\n }\n if (kind === 'module') {\n const js = await rewriteArchiveModuleReferences(\n decodeTextSniff(bytes),\n async (ref, refKind) => urlForReference(ref, entry.path, refKind, importMap),\n )\n return dataUrl(new TextEncoder().encode(js), 'text/javascript')\n }\n if (kind === 'html') {\n const html = await rewriteDocument(decodeTextSniff(bytes), entry.path)\n return dataUrl(new TextEncoder().encode(html), 'text/html')\n }\n return dataUrl(bytes, mimeForName(entry.name))\n })().finally(() => building.delete(key))\n urlCache.set(key, work)\n return work\n }\n\n const urlForReference = async (\n ref: string,\n basePath: string,\n kind: ResourceKind,\n importMap?: ArchiveImportMapContext,\n ): Promise<string | null> => {\n let address = ref\n let addressBase = basePath\n if (kind === 'module' && importMap) {\n const mapped = importMap.resolve(ref, basePath)\n if (mapped === null) return null\n if (mapped !== undefined) {\n address = mapped\n addressBase = importMap.documentPath\n if (isExternalOrInlineReference(address)) return address\n }\n }\n const entry = resolveEntry(address, addressBase)\n if (!entry) return null\n const url = await resourceUrl(entry, kind, importMap)\n if (!url) return null\n const hash = address.indexOf('#')\n return hash < 0 ? url : url + address.slice(hash)\n }\n\n const rewriteSrcset = async (srcset: string, basePath: string): Promise<string> => {\n const parts = srcset.split(',')\n const rewritten: string[] = []\n for (const part of parts) {\n const segment = part.trim()\n if (!segment) continue\n const fields = segment.split(/\\s+/)\n const url = await urlForReference(fields[0], basePath, 'raw')\n if (url) fields[0] = url\n rewritten.push(fields.join(' '))\n }\n return rewritten.join(', ')\n }\n\n const rewriteDocument = async (html: string, documentPath: string): Promise<string> => {\n const doc = new DOMParser().parseFromString(html, 'text/html')\n const importMapElements = Array.from(\n doc.querySelectorAll<HTMLScriptElement>('script[type=\"importmap\"]:not([src])'),\n )\n const importMap: ArchiveImportMapContext = {\n id: ++importMapContextId,\n documentPath,\n resolve: createArchiveImportMapResolver(\n importMapElements.map((element) => element.textContent ?? ''),\n documentPath,\n ),\n }\n\n // The selected archive directory is the base. A document-supplied base would point outside that virtual\n // tree, and a supplied CSP could block the safe data URLs; FileViewerBody injects the authoritative CSP.\n doc.querySelectorAll('base').forEach((element) => element.remove())\n doc.querySelectorAll('meta[http-equiv]').forEach((element) => {\n const directive = (element.getAttribute('http-equiv') ?? '').toLocaleLowerCase()\n if (directive === 'content-security-policy' || directive === 'refresh') element.remove()\n })\n\n for (const element of Array.from(doc.querySelectorAll('link[href]'))) {\n const ref = element.getAttribute('href')\n if (!ref) continue\n const rel = (element.getAttribute('rel') ?? '').toLocaleLowerCase().split(/\\s+/)\n const kind: ResourceKind = rel.includes('stylesheet')\n ? 'css'\n : rel.includes('modulepreload')\n ? 'module'\n : 'raw'\n const url = await urlForReference(ref, documentPath, kind, importMap)\n if (url) {\n element.setAttribute('href', url)\n if (kind === 'css' || kind === 'module') element.removeAttribute('integrity')\n }\n }\n\n for (const element of Array.from(doc.querySelectorAll('script[src]'))) {\n const ref = element.getAttribute('src')\n if (!ref) continue\n const kind =\n (element.getAttribute('type') ?? '').toLocaleLowerCase() === 'module' ? 'module' : 'raw'\n const url = await urlForReference(ref, documentPath, kind, importMap)\n if (url) {\n element.setAttribute('src', url)\n if (kind === 'module') element.removeAttribute('integrity')\n }\n }\n for (const element of Array.from(doc.querySelectorAll('script[type=\"module\"]:not([src])'))) {\n element.textContent = await rewriteArchiveModuleReferences(\n element.textContent ?? '',\n async (ref, kind) => urlForReference(ref, documentPath, kind, importMap),\n )\n }\n // A blob-backed preview has no hierarchical base, so relative import-map addresses are normalized to null\n // by the browser. All literal imports have already been resolved through this map and rewritten above;\n // remove the now-redundant maps instead of letting those null entries block bare module specifiers.\n importMapElements.forEach((element) => element.remove())\n\n const attributes: Array<[string, string, ResourceKind]> = [\n ['img[src]', 'src', 'raw'],\n ['input[type=\"image\"][src]', 'src', 'raw'],\n ['source[src]', 'src', 'raw'],\n ['video[src]', 'src', 'raw'],\n ['video[poster]', 'poster', 'raw'],\n ['audio[src]', 'src', 'raw'],\n ['track[src]', 'src', 'raw'],\n ['embed[src]', 'src', 'raw'],\n ['object[data]', 'data', 'raw'],\n ['iframe[src]', 'src', 'html'],\n ['image[href]', 'href', 'raw'],\n ['use[href]', 'href', 'raw'],\n ]\n for (const [selector, attribute, kind] of attributes) {\n for (const element of Array.from(doc.querySelectorAll(selector))) {\n const ref = element.getAttribute(attribute)\n if (!ref) continue\n const url = await urlForReference(ref, documentPath, kind)\n if (url) element.setAttribute(attribute, url)\n }\n }\n for (const element of Array.from(doc.querySelectorAll('image, use'))) {\n const ref = element.getAttribute('xlink:href')\n if (!ref) continue\n const url = await urlForReference(ref, documentPath, 'raw')\n if (url) element.setAttribute('xlink:href', url)\n }\n\n for (const element of Array.from(doc.querySelectorAll('img[srcset], source[srcset]'))) {\n const srcset = element.getAttribute('srcset')\n if (srcset) element.setAttribute('srcset', await rewriteSrcset(srcset, documentPath))\n }\n for (const element of Array.from(doc.querySelectorAll('[style]'))) {\n const style = element.getAttribute('style')\n if (!style) continue\n element.setAttribute(\n 'style',\n await rewriteArchiveCssReferences(style, async (ref, kind) =>\n urlForReference(ref, documentPath, kind),\n ),\n )\n }\n for (const element of Array.from(doc.querySelectorAll('style'))) {\n element.textContent = await rewriteArchiveCssReferences(\n element.textContent ?? '',\n async (ref, kind) => urlForReference(ref, documentPath, kind),\n )\n }\n\n return '<!doctype html>\\n' + doc.documentElement.outerHTML\n }\n\n return {\n html: await rewriteDocument(options.html, options.documentPath),\n loadedResources,\n skippedResources,\n }\n}\n"],"mappings":"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"}
package/dist/lib/asn1.js CHANGED
@@ -120,3 +120,5 @@ function l(t) {
120
120
  }
121
121
  //#endregion
122
122
  export { e as TAG, s as asn1String, l as asn1Time, o as bytesToHex, t as decodeAsn1, a as oidToString, i as tagName };
123
+
124
+ //# sourceMappingURL=asn1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asn1.js","names":[],"sources":["../../src/lib/asn1.ts"],"sourcesContent":["/**\n * Minimal, zero-dependency ASN.1 DER decoder for the certificate viewer (lib/x509.ts + CertViewer.vue).\n *\n * Decodes the tag/length/value tree; constructed types recurse. Enough to walk X.509 / PKCS#10 / PKCS#7 /\n * PKCS#12 structures and render a generic, collapsible structure tree. It is NOT a validator — it tolerates\n * and surfaces partial / malformed input (bailing on no-progress) rather than throwing, so a weird file shows\n * what could be decoded instead of a blank error.\n */\n\nexport interface Asn1Node {\n tagClass: number // 0 universal, 1 application, 2 context-specific, 3 private\n constructed: boolean\n tagNumber: number // tag number (universal types: 2=INTEGER, 6=OID, 16=SEQUENCE, …)\n start: number // offset of this TLV's first byte within the buffer\n headerLen: number // bytes of tag + length\n length: number // content length in bytes\n content: Uint8Array // the V (content) bytes\n children: Asn1Node[] // decoded sub-nodes (constructed types only)\n}\n\nexport const TAG = {\n BOOLEAN: 1,\n INTEGER: 2,\n BIT_STRING: 3,\n OCTET_STRING: 4,\n NULL: 5,\n OID: 6,\n UTF8String: 12,\n SEQUENCE: 16,\n SET: 17,\n PrintableString: 19,\n IA5String: 22,\n UTCTime: 23,\n GeneralizedTime: 24,\n} as const\n\n/** Decode every TLV in [start, end) into a forest of nodes. */\nexport function decodeAsn1(buf: Uint8Array, start = 0, end = buf.length): Asn1Node[] {\n const out: Asn1Node[] = []\n let i = start\n while (i < end) {\n const node = decodeOne(buf, i, end)\n if (!node) break\n out.push(node)\n const next = node.start + node.headerLen + node.length\n if (next <= i) break // no progress on malformed input — stop rather than spin\n i = next\n }\n return out\n}\n\nfunction decodeOne(buf: Uint8Array, start: number, end: number): Asn1Node | null {\n let i = start\n if (i >= end) return null\n const first = buf[i++]\n const tagClass = first >> 6\n const constructed = (first & 0x20) !== 0\n let tagNumber = first & 0x1f\n if (tagNumber === 0x1f) {\n // high-tag-number form: base-128 continuation bytes\n tagNumber = 0\n while (i < end) {\n const b = buf[i++]\n tagNumber = (tagNumber << 7) | (b & 0x7f)\n if ((b & 0x80) === 0) break\n }\n }\n if (i >= end) return null\n let len = buf[i++]\n if (len & 0x80) {\n const numBytes = len & 0x7f\n if (numBytes === 0 || numBytes > 4 || i + numBytes > end) {\n // indefinite or oversized length — not valid DER; take the rest as content\n len = end - i\n } else {\n len = 0\n for (let k = 0; k < numBytes; k++) len = len * 256 + buf[i++]\n }\n }\n const contentStart = i\n const contentEnd = Math.min(end, contentStart + len)\n const node: Asn1Node = {\n tagClass,\n constructed,\n tagNumber,\n start,\n headerLen: contentStart - start,\n length: contentEnd - contentStart,\n content: buf.subarray(contentStart, contentEnd),\n children: [],\n }\n if (constructed) node.children = decodeAsn1(buf, contentStart, contentEnd)\n return node\n}\n\nconst UNIVERSAL_NAMES: Record<number, string> = {\n 1: 'BOOLEAN',\n 2: 'INTEGER',\n 3: 'BIT STRING',\n 4: 'OCTET STRING',\n 5: 'NULL',\n 6: 'OBJECT IDENTIFIER',\n 10: 'ENUMERATED',\n 12: 'UTF8String',\n 13: 'RELATIVE-OID',\n 16: 'SEQUENCE',\n 17: 'SET',\n 18: 'NumericString',\n 19: 'PrintableString',\n 20: 'TeletexString',\n 22: 'IA5String',\n 23: 'UTCTime',\n 24: 'GeneralizedTime',\n 26: 'VisibleString',\n 27: 'GeneralString',\n 28: 'UniversalString',\n 30: 'BMPString',\n}\n\n/** Display name for a node's tag (universal type name, or `[n]` for context-specific). */\nexport function tagName(node: Asn1Node): string {\n if (node.tagClass === 2) return `[${node.tagNumber}]`\n if (node.tagClass === 1) return `APPLICATION ${node.tagNumber}`\n if (node.tagClass === 3) return `PRIVATE ${node.tagNumber}`\n return UNIVERSAL_NAMES[node.tagNumber] ?? `TAG ${node.tagNumber}`\n}\n\n/** Decode OID content bytes → dotted-decimal string. */\nexport function oidToString(bytes: Uint8Array): string {\n if (!bytes.length) return ''\n const parts: number[] = [Math.floor(bytes[0] / 40), bytes[0] % 40]\n let val = 0\n for (let i = 1; i < bytes.length; i++) {\n val = val * 128 + (bytes[i] & 0x7f)\n if ((bytes[i] & 0x80) === 0) {\n parts.push(val)\n val = 0\n }\n }\n return parts.join('.')\n}\n\nexport function bytesToHex(bytes: Uint8Array, sep = ''): string {\n let s = ''\n for (let i = 0; i < bytes.length; i++) {\n s += bytes[i].toString(16).padStart(2, '0')\n if (sep && i < bytes.length - 1) s += sep\n }\n return s\n}\n\n/** Decode a string-typed node's content as UTF-8 text (falls back to hex for odd bytes). */\nexport function asn1String(node: Asn1Node): string {\n try {\n return new TextDecoder('utf-8').decode(node.content)\n } catch {\n return bytesToHex(node.content)\n }\n}\n\nfunction buildTime(\n year: number,\n mo: string,\n d: string,\n h: string,\n mi: string,\n s?: string,\n): { text: string; ms: number } {\n const ms = Date.UTC(\n year,\n parseInt(mo, 10) - 1,\n parseInt(d, 10),\n parseInt(h, 10),\n parseInt(mi, 10),\n s ? parseInt(s, 10) : 0,\n )\n return { text: `${year}-${mo}-${d} ${h}:${mi}:${s ?? '00'} UTC`, ms }\n}\n\n/** Decode a UTCTime / GeneralizedTime node → human text + epoch ms, or null if unparseable. */\nexport function asn1Time(node: Asn1Node): { text: string; ms: number } | null {\n const s = new TextDecoder('latin1').decode(node.content).trim()\n if (node.tagNumber === TAG.UTCTime) {\n const m = s.match(/^(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})?/)\n if (!m) return null\n const yy = parseInt(m[1], 10)\n return buildTime(yy < 50 ? 2000 + yy : 1900 + yy, m[2], m[3], m[4], m[5], m[6])\n }\n const m = s.match(/^(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})?/)\n if (!m) return null\n return buildTime(parseInt(m[1], 10), m[2], m[3], m[4], m[5], m[6])\n}\n"],"mappings":"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"}
@@ -428,3 +428,5 @@ function H(e) {
428
428
  }
429
429
  //#endregion
430
430
  export { e as UnsupportedBinaryError, D as parseBinObj };
431
+
432
+ //# sourceMappingURL=binobj.js.map