omni-viewer-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (387) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +80 -0
  3. package/THIRD_PARTY_NOTICES.md +49 -0
  4. package/dist/assets/audio-engine/audio_engine.mjs +2 -0
  5. package/dist/assets/audio-engine/audio_engine.wasm +0 -0
  6. package/dist/assets/pdfjs/pdf.worker.min.mjs +21 -0
  7. package/dist/host/index.d.ts +133 -0
  8. package/dist/host/index.js +10 -0
  9. package/dist/i18n/catalog.en.d.ts +1 -0
  10. package/dist/i18n/catalog.en.js +411 -0
  11. package/dist/i18n/catalog.ko.d.ts +1 -0
  12. package/dist/i18n/catalog.ko.js +68 -0
  13. package/dist/i18n/index.d.ts +18 -0
  14. package/dist/i18n/index.js +41 -0
  15. package/dist/licenses/emscripten.txt +101 -0
  16. package/dist/licenses/kissfft.txt +28 -0
  17. package/dist/licenses/pdfjs-dist.txt +177 -0
  18. package/dist/parsers/a2l/index.d.ts +1 -0
  19. package/dist/parsers/a2l/index.js +1 -0
  20. package/dist/parsers/archive/index.d.ts +22 -0
  21. package/dist/parsers/archive/index.js +46 -0
  22. package/dist/parsers/archive/model.d.ts +29 -0
  23. package/dist/parsers/archive/model.js +1 -0
  24. package/dist/parsers/archive/worker.d.ts +21 -0
  25. package/dist/parsers/archive/worker.js +1 -0
  26. package/dist/parsers/arxml/index.d.ts +1 -0
  27. package/dist/parsers/arxml/index.js +1 -0
  28. package/dist/parsers/asc/index.d.ts +1 -0
  29. package/dist/parsers/asc/index.js +1 -0
  30. package/dist/parsers/audio/index.d.ts +9 -0
  31. package/dist/parsers/audio/index.js +46 -0
  32. package/dist/parsers/automotive/index.d.ts +33 -0
  33. package/dist/parsers/automotive/index.js +973 -0
  34. package/dist/parsers/blf/index.d.ts +1 -0
  35. package/dist/parsers/blf/index.js +1 -0
  36. package/dist/parsers/csv/delimiter.d.ts +31 -0
  37. package/dist/parsers/csv/delimiter.js +151 -0
  38. package/dist/parsers/csv/index.d.ts +30 -0
  39. package/dist/parsers/csv/index.js +108 -0
  40. package/dist/parsers/csv/parseText.d.ts +20 -0
  41. package/dist/parsers/csv/parseText.js +108 -0
  42. package/dist/parsers/csv/sort.d.ts +26 -0
  43. package/dist/parsers/csv/sort.js +224 -0
  44. package/dist/parsers/csv/statistics.d.ts +49 -0
  45. package/dist/parsers/csv/statistics.js +150 -0
  46. package/dist/parsers/dbc/index.d.ts +56 -0
  47. package/dist/parsers/dbc/index.js +94 -0
  48. package/dist/parsers/doc-binary/index.d.ts +35 -0
  49. package/dist/parsers/doc-binary/index.js +267 -0
  50. package/dist/parsers/doc-binary/vscode-parser.d.ts +142 -0
  51. package/dist/parsers/doc-binary/vscode-parser.js +3747 -0
  52. package/dist/parsers/excel/index.d.ts +17 -0
  53. package/dist/parsers/excel/index.js +406 -0
  54. package/dist/parsers/excel/model.d.ts +80 -0
  55. package/dist/parsers/excel/model.js +48 -0
  56. package/dist/parsers/excel/serialize.d.ts +3 -0
  57. package/dist/parsers/excel/serialize.js +78 -0
  58. package/dist/parsers/hdf5/index.d.ts +75 -0
  59. package/dist/parsers/hdf5/index.js +658 -0
  60. package/dist/parsers/hdf5/node.d.ts +21 -0
  61. package/dist/parsers/hdf5/node.js +95 -0
  62. package/dist/parsers/json/index.d.ts +15 -0
  63. package/dist/parsers/json/index.js +102 -0
  64. package/dist/parsers/json/model.d.ts +42 -0
  65. package/dist/parsers/json/model.js +140 -0
  66. package/dist/parsers/json/parse.d.ts +22 -0
  67. package/dist/parsers/json/parse.js +279 -0
  68. package/dist/parsers/json/tokenizer.d.ts +17 -0
  69. package/dist/parsers/json/tokenizer.js +175 -0
  70. package/dist/parsers/jsonl/index.d.ts +14 -0
  71. package/dist/parsers/jsonl/index.js +18 -0
  72. package/dist/parsers/jsonl/model.d.ts +23 -0
  73. package/dist/parsers/jsonl/model.js +1 -0
  74. package/dist/parsers/jsonl/parse.d.ts +7 -0
  75. package/dist/parsers/jsonl/parse.js +34 -0
  76. package/dist/parsers/markdown/index.d.ts +37 -0
  77. package/dist/parsers/markdown/index.js +59 -0
  78. package/dist/parsers/mat/index.d.ts +31 -0
  79. package/dist/parsers/mat/index.js +426 -0
  80. package/dist/parsers/mermaid/index.d.ts +5 -0
  81. package/dist/parsers/mermaid/index.js +3 -0
  82. package/dist/parsers/mf4/index.d.ts +1 -0
  83. package/dist/parsers/mf4/index.js +1 -0
  84. package/dist/parsers/parquet/index.d.ts +21 -0
  85. package/dist/parsers/parquet/index.js +68 -0
  86. package/dist/parsers/pcap/index.d.ts +1 -0
  87. package/dist/parsers/pcap/index.js +1 -0
  88. package/dist/parsers/pcapng/index.d.ts +1 -0
  89. package/dist/parsers/pcapng/index.js +1 -0
  90. package/dist/parsers/plantuml/index.d.ts +5 -0
  91. package/dist/parsers/plantuml/index.js +4 -0
  92. package/dist/parsers/ppt-binary/index.d.ts +5 -0
  93. package/dist/parsers/ppt-binary/index.js +62 -0
  94. package/dist/parsers/ppt-binary/pptBinaryBuildContext.d.ts +12 -0
  95. package/dist/parsers/ppt-binary/pptBinaryBuildContext.js +40 -0
  96. package/dist/parsers/ppt-binary/pptBinaryContainer.d.ts +4 -0
  97. package/dist/parsers/ppt-binary/pptBinaryContainer.js +174 -0
  98. package/dist/parsers/ppt-binary/pptBinaryTypes.d.ts +125 -0
  99. package/dist/parsers/ppt-binary/pptBinaryTypes.js +1 -0
  100. package/dist/parsers/ppt-binary/pptSlideLayouts.d.ts +9 -0
  101. package/dist/parsers/ppt-binary/pptSlideLayouts.js +510 -0
  102. package/dist/parsers/ppt-binary/vscode-parser.d.ts +116 -0
  103. package/dist/parsers/ppt-binary/vscode-parser.js +2853 -0
  104. package/dist/parsers/ppt-binary/vscode.d.ts +4 -0
  105. package/dist/parsers/ppt-binary/vscode.js +12 -0
  106. package/dist/parsers/pptx/index.d.ts +15 -0
  107. package/dist/parsers/pptx/index.js +88 -0
  108. package/dist/parsers/pptx/vscode-parser.d.ts +167 -0
  109. package/dist/parsers/pptx/vscode-parser.js +1503 -0
  110. package/dist/parsers/pptx/vscode.d.ts +4 -0
  111. package/dist/parsers/pptx/vscode.js +18 -0
  112. package/dist/parsers/pptx/zip-reader.d.ts +3 -0
  113. package/dist/parsers/pptx/zip-reader.js +20 -0
  114. package/dist/parsers/proto/index.d.ts +90 -0
  115. package/dist/parsers/proto/index.js +197 -0
  116. package/dist/parsers/psd/index.d.ts +16 -0
  117. package/dist/parsers/psd/index.js +10 -0
  118. package/dist/parsers/shapefile/dbf.d.ts +23 -0
  119. package/dist/parsers/shapefile/dbf.js +112 -0
  120. package/dist/parsers/shapefile/index.d.ts +44 -0
  121. package/dist/parsers/shapefile/index.js +119 -0
  122. package/dist/parsers/shapefile/reproject.d.ts +10 -0
  123. package/dist/parsers/shapefile/reproject.js +41 -0
  124. package/dist/parsers/slide-model.d.ts +106 -0
  125. package/dist/parsers/slide-model.js +1 -0
  126. package/dist/parsers/toml/index.d.ts +15 -0
  127. package/dist/parsers/toml/index.js +18 -0
  128. package/dist/parsers/toml/model.d.ts +15 -0
  129. package/dist/parsers/toml/model.js +1 -0
  130. package/dist/parsers/toml/parse.d.ts +16 -0
  131. package/dist/parsers/toml/parse.js +266 -0
  132. package/dist/parsers/types.d.ts +103 -0
  133. package/dist/parsers/types.js +106 -0
  134. package/dist/parsers/video/index.d.ts +6 -0
  135. package/dist/parsers/video/index.js +2 -0
  136. package/dist/parsers/yaml/index.d.ts +16 -0
  137. package/dist/parsers/yaml/index.js +58 -0
  138. package/dist/parsers/yaml/model.d.ts +22 -0
  139. package/dist/parsers/yaml/model.js +1 -0
  140. package/dist/parsers/yaml/self-loading.d.ts +3 -0
  141. package/dist/parsers/yaml/self-loading.js +19 -0
  142. package/dist/parsers/zip-scan.d.ts +8 -0
  143. package/dist/parsers/zip-scan.js +80 -0
  144. package/dist/registry/container.d.ts +17 -0
  145. package/dist/registry/container.js +49 -0
  146. package/dist/registry/index.d.ts +133 -0
  147. package/dist/registry/index.js +348 -0
  148. package/dist/registry/probe.d.ts +3 -0
  149. package/dist/registry/probe.js +177 -0
  150. package/dist/registry/sniff.d.ts +17 -0
  151. package/dist/registry/sniff.js +57 -0
  152. package/dist/styles/archive.css +10 -0
  153. package/dist/styles/audio.css +66 -0
  154. package/dist/styles/automotive.css +1 -0
  155. package/dist/styles/csv.css +262 -0
  156. package/dist/styles/excel.css +212 -0
  157. package/dist/styles/fallback.css +48 -0
  158. package/dist/styles/hdf5.css +3 -0
  159. package/dist/styles/hwp.css +12 -0
  160. package/dist/styles/image.css +115 -0
  161. package/dist/styles/json.css +342 -0
  162. package/dist/styles/jsonl.css +1 -0
  163. package/dist/styles/markdown.css +10 -0
  164. package/dist/styles/mat.css +2 -0
  165. package/dist/styles/mermaid.css +1 -0
  166. package/dist/styles/parquet.css +2 -0
  167. package/dist/styles/pdf.css +551 -0
  168. package/dist/styles/plantuml.css +1 -0
  169. package/dist/styles/ppt.css +1 -0
  170. package/dist/styles/proto.css +2 -0
  171. package/dist/styles/psd.css +1 -0
  172. package/dist/styles/shapefile.css +25 -0
  173. package/dist/styles/toml.css +1 -0
  174. package/dist/styles/video.css +74 -0
  175. package/dist/styles/word.css +685 -0
  176. package/dist/styles/yaml.css +1 -0
  177. package/dist/viewers/a2l/index.d.ts +15 -0
  178. package/dist/viewers/a2l/index.js +5 -0
  179. package/dist/viewers/archive/archive-preview-decoder.d.ts +4 -0
  180. package/dist/viewers/archive/archive-preview-decoder.js +223 -0
  181. package/dist/viewers/archive/controller.d.ts +24 -0
  182. package/dist/viewers/archive/controller.js +18 -0
  183. package/dist/viewers/archive/index.d.ts +25 -0
  184. package/dist/viewers/archive/index.js +230 -0
  185. package/dist/viewers/archive/preview.d.ts +2 -0
  186. package/dist/viewers/archive/preview.js +2 -0
  187. package/dist/viewers/archive/styles.d.ts +1 -0
  188. package/dist/viewers/archive/styles.js +11 -0
  189. package/dist/viewers/arxml/index.d.ts +15 -0
  190. package/dist/viewers/arxml/index.js +5 -0
  191. package/dist/viewers/asc/index.d.ts +15 -0
  192. package/dist/viewers/asc/index.js +5 -0
  193. package/dist/viewers/audio/controller.d.ts +33 -0
  194. package/dist/viewers/audio/controller.js +49 -0
  195. package/dist/viewers/audio/engine.d.ts +44 -0
  196. package/dist/viewers/audio/engine.js +108 -0
  197. package/dist/viewers/audio/index.d.ts +92 -0
  198. package/dist/viewers/audio/index.js +448 -0
  199. package/dist/viewers/audio/self-loading.d.ts +7 -0
  200. package/dist/viewers/audio/self-loading.js +42 -0
  201. package/dist/viewers/audio/styles.d.ts +1 -0
  202. package/dist/viewers/audio/styles.js +73 -0
  203. package/dist/viewers/automotive/index.d.ts +8 -0
  204. package/dist/viewers/automotive/index.js +152 -0
  205. package/dist/viewers/automotive/styles.d.ts +1 -0
  206. package/dist/viewers/automotive/styles.js +1 -0
  207. package/dist/viewers/avro/index.d.ts +15 -0
  208. package/dist/viewers/avro/index.js +5 -0
  209. package/dist/viewers/bag/index.d.ts +15 -0
  210. package/dist/viewers/bag/index.js +5 -0
  211. package/dist/viewers/blf/index.d.ts +15 -0
  212. package/dist/viewers/blf/index.js +5 -0
  213. package/dist/viewers/csv/controller.d.ts +126 -0
  214. package/dist/viewers/csv/controller.js +598 -0
  215. package/dist/viewers/csv/index.d.ts +48 -0
  216. package/dist/viewers/csv/index.js +846 -0
  217. package/dist/viewers/csv/styles.d.ts +1 -0
  218. package/dist/viewers/csv/styles.js +267 -0
  219. package/dist/viewers/db3/index.d.ts +15 -0
  220. package/dist/viewers/db3/index.js +5 -0
  221. package/dist/viewers/dbc/index.d.ts +15 -0
  222. package/dist/viewers/dbc/index.js +5 -0
  223. package/dist/viewers/diagram.d.ts +14 -0
  224. package/dist/viewers/diagram.js +95 -0
  225. package/dist/viewers/excel/controller.d.ts +108 -0
  226. package/dist/viewers/excel/controller.js +548 -0
  227. package/dist/viewers/excel/grid.d.ts +28 -0
  228. package/dist/viewers/excel/grid.js +99 -0
  229. package/dist/viewers/excel/index.d.ts +37 -0
  230. package/dist/viewers/excel/index.js +620 -0
  231. package/dist/viewers/excel/self-loading.d.ts +6 -0
  232. package/dist/viewers/excel/self-loading.js +13 -0
  233. package/dist/viewers/excel/styles.d.ts +1 -0
  234. package/dist/viewers/excel/styles.js +216 -0
  235. package/dist/viewers/fallback/index.d.ts +17 -0
  236. package/dist/viewers/fallback/index.js +130 -0
  237. package/dist/viewers/fallback/styles.d.ts +1 -0
  238. package/dist/viewers/fallback/styles.js +49 -0
  239. package/dist/viewers/hdf5/index.d.ts +19 -0
  240. package/dist/viewers/hdf5/index.js +170 -0
  241. package/dist/viewers/hdf5/styles.d.ts +1 -0
  242. package/dist/viewers/hdf5/styles.js +4 -0
  243. package/dist/viewers/hwp/controller.d.ts +19 -0
  244. package/dist/viewers/hwp/controller.js +22 -0
  245. package/dist/viewers/hwp/index.d.ts +39 -0
  246. package/dist/viewers/hwp/index.js +271 -0
  247. package/dist/viewers/hwp/self-loading.d.ts +2 -0
  248. package/dist/viewers/hwp/self-loading.js +6 -0
  249. package/dist/viewers/hwp/styles.d.ts +1 -0
  250. package/dist/viewers/hwp/styles.js +13 -0
  251. package/dist/viewers/image/controller.d.ts +210 -0
  252. package/dist/viewers/image/controller.js +336 -0
  253. package/dist/viewers/image/decode.d.ts +54 -0
  254. package/dist/viewers/image/decode.js +150 -0
  255. package/dist/viewers/image/index.d.ts +38 -0
  256. package/dist/viewers/image/index.js +749 -0
  257. package/dist/viewers/image/limits.d.ts +18 -0
  258. package/dist/viewers/image/limits.js +20 -0
  259. package/dist/viewers/image/styles.d.ts +1 -0
  260. package/dist/viewers/image/styles.js +119 -0
  261. package/dist/viewers/json/controller.d.ts +89 -0
  262. package/dist/viewers/json/controller.js +411 -0
  263. package/dist/viewers/json/index.d.ts +25 -0
  264. package/dist/viewers/json/index.js +503 -0
  265. package/dist/viewers/json/styles.d.ts +1 -0
  266. package/dist/viewers/json/styles.js +346 -0
  267. package/dist/viewers/json/transforms.d.ts +27 -0
  268. package/dist/viewers/json/transforms.js +253 -0
  269. package/dist/viewers/jsonl/controller.d.ts +48 -0
  270. package/dist/viewers/jsonl/controller.js +136 -0
  271. package/dist/viewers/jsonl/index.d.ts +22 -0
  272. package/dist/viewers/jsonl/index.js +184 -0
  273. package/dist/viewers/jsonl/styles.d.ts +1 -0
  274. package/dist/viewers/jsonl/styles.js +1 -0
  275. package/dist/viewers/markdown/controller.d.ts +50 -0
  276. package/dist/viewers/markdown/controller.js +62 -0
  277. package/dist/viewers/markdown/index.d.ts +64 -0
  278. package/dist/viewers/markdown/index.js +425 -0
  279. package/dist/viewers/markdown/math.d.ts +21 -0
  280. package/dist/viewers/markdown/math.js +100 -0
  281. package/dist/viewers/markdown/self-loading.d.ts +5 -0
  282. package/dist/viewers/markdown/self-loading.js +48 -0
  283. package/dist/viewers/markdown/styles.d.ts +1 -0
  284. package/dist/viewers/markdown/styles.js +11 -0
  285. package/dist/viewers/mat/index.d.ts +19 -0
  286. package/dist/viewers/mat/index.js +113 -0
  287. package/dist/viewers/mat/styles.d.ts +1 -0
  288. package/dist/viewers/mat/styles.js +3 -0
  289. package/dist/viewers/media.d.ts +9 -0
  290. package/dist/viewers/media.js +77 -0
  291. package/dist/viewers/mermaid/index.d.ts +17 -0
  292. package/dist/viewers/mermaid/index.js +6 -0
  293. package/dist/viewers/mermaid/self-loading.d.ts +2 -0
  294. package/dist/viewers/mermaid/self-loading.js +2 -0
  295. package/dist/viewers/mf4/index.d.ts +15 -0
  296. package/dist/viewers/mf4/index.js +5 -0
  297. package/dist/viewers/parquet/controller.d.ts +37 -0
  298. package/dist/viewers/parquet/controller.js +26 -0
  299. package/dist/viewers/parquet/index.d.ts +23 -0
  300. package/dist/viewers/parquet/index.js +134 -0
  301. package/dist/viewers/parquet/styles.d.ts +1 -0
  302. package/dist/viewers/parquet/styles.js +3 -0
  303. package/dist/viewers/pcap/index.d.ts +15 -0
  304. package/dist/viewers/pcap/index.js +5 -0
  305. package/dist/viewers/pcapng/index.d.ts +15 -0
  306. package/dist/viewers/pcapng/index.js +5 -0
  307. package/dist/viewers/pdf/controller.d.ts +120 -0
  308. package/dist/viewers/pdf/controller.js +191 -0
  309. package/dist/viewers/pdf/editing.d.ts +26 -0
  310. package/dist/viewers/pdf/editing.js +265 -0
  311. package/dist/viewers/pdf/index.d.ts +88 -0
  312. package/dist/viewers/pdf/index.js +1400 -0
  313. package/dist/viewers/pdf/self-loading.d.ts +6 -0
  314. package/dist/viewers/pdf/self-loading.js +14 -0
  315. package/dist/viewers/pdf/styles.d.ts +1 -0
  316. package/dist/viewers/pdf/styles.js +555 -0
  317. package/dist/viewers/plantuml/index.d.ts +17 -0
  318. package/dist/viewers/plantuml/index.js +6 -0
  319. package/dist/viewers/plantuml/self-loading.d.ts +2 -0
  320. package/dist/viewers/plantuml/self-loading.js +2 -0
  321. package/dist/viewers/ppt/chart.d.ts +8 -0
  322. package/dist/viewers/ppt/chart.js +83 -0
  323. package/dist/viewers/ppt/controller.d.ts +34 -0
  324. package/dist/viewers/ppt/controller.js +27 -0
  325. package/dist/viewers/ppt/index.d.ts +33 -0
  326. package/dist/viewers/ppt/index.js +101 -0
  327. package/dist/viewers/ppt/render.d.ts +5 -0
  328. package/dist/viewers/ppt/render.js +144 -0
  329. package/dist/viewers/ppt/self-loading.d.ts +9 -0
  330. package/dist/viewers/ppt/self-loading.js +4 -0
  331. package/dist/viewers/ppt/styles.d.ts +1 -0
  332. package/dist/viewers/ppt/styles.js +1 -0
  333. package/dist/viewers/proto/index.d.ts +17 -0
  334. package/dist/viewers/proto/index.js +170 -0
  335. package/dist/viewers/proto/styles.d.ts +1 -0
  336. package/dist/viewers/proto/styles.js +2 -0
  337. package/dist/viewers/psd/index.d.ts +27 -0
  338. package/dist/viewers/psd/index.js +39 -0
  339. package/dist/viewers/psd/self-loading.d.ts +10 -0
  340. package/dist/viewers/psd/self-loading.js +20 -0
  341. package/dist/viewers/psd/styles.d.ts +1 -0
  342. package/dist/viewers/psd/styles.js +1 -0
  343. package/dist/viewers/reqif/index.d.ts +15 -0
  344. package/dist/viewers/reqif/index.js +5 -0
  345. package/dist/viewers/shapefile/index.d.ts +35 -0
  346. package/dist/viewers/shapefile/index.js +336 -0
  347. package/dist/viewers/shapefile/self-loading.d.ts +7 -0
  348. package/dist/viewers/shapefile/self-loading.js +32 -0
  349. package/dist/viewers/shapefile/styles.d.ts +1 -0
  350. package/dist/viewers/shapefile/styles.js +28 -0
  351. package/dist/viewers/stp/index.d.ts +15 -0
  352. package/dist/viewers/stp/index.js +5 -0
  353. package/dist/viewers/structured-styles.d.ts +1 -0
  354. package/dist/viewers/structured-styles.js +1 -0
  355. package/dist/viewers/structured.d.ts +36 -0
  356. package/dist/viewers/structured.js +138 -0
  357. package/dist/viewers/toml/controller.d.ts +38 -0
  358. package/dist/viewers/toml/controller.js +61 -0
  359. package/dist/viewers/toml/index.d.ts +18 -0
  360. package/dist/viewers/toml/index.js +34 -0
  361. package/dist/viewers/types.d.ts +36 -0
  362. package/dist/viewers/types.js +9 -0
  363. package/dist/viewers/video/controller.d.ts +29 -0
  364. package/dist/viewers/video/controller.js +54 -0
  365. package/dist/viewers/video/index.d.ts +18 -0
  366. package/dist/viewers/video/index.js +305 -0
  367. package/dist/viewers/video/styles.d.ts +1 -0
  368. package/dist/viewers/video/styles.js +79 -0
  369. package/dist/viewers/word/controller.d.ts +19 -0
  370. package/dist/viewers/word/controller.js +22 -0
  371. package/dist/viewers/word/docx-preprocess.d.ts +63 -0
  372. package/dist/viewers/word/docx-preprocess.js +136 -0
  373. package/dist/viewers/word/index.d.ts +32 -0
  374. package/dist/viewers/word/index.js +187 -0
  375. package/dist/viewers/word/normalize-docx.d.ts +2 -0
  376. package/dist/viewers/word/normalize-docx.js +50 -0
  377. package/dist/viewers/word/paginate.d.ts +1 -0
  378. package/dist/viewers/word/paginate.js +1035 -0
  379. package/dist/viewers/word/self-loading.d.ts +2 -0
  380. package/dist/viewers/word/self-loading.js +7 -0
  381. package/dist/viewers/word/styles.d.ts +1 -0
  382. package/dist/viewers/word/styles.js +686 -0
  383. package/dist/viewers/yaml/controller.d.ts +42 -0
  384. package/dist/viewers/yaml/controller.js +41 -0
  385. package/dist/viewers/yaml/index.d.ts +21 -0
  386. package/dist/viewers/yaml/index.js +20 -0
  387. package/package.json +375 -0
@@ -0,0 +1,223 @@
1
+ const RES_XML_TYPE = 0x0003;
2
+ const RES_STRING_POOL_TYPE = 0x0001;
3
+ const RES_XML_START_NAMESPACE_TYPE = 0x0100;
4
+ const RES_XML_END_NAMESPACE_TYPE = 0x0101;
5
+ const RES_XML_START_ELEMENT_TYPE = 0x0102;
6
+ const RES_XML_END_ELEMENT_TYPE = 0x0103;
7
+ const NO_INDEX = 0xffffffff;
8
+ class Reader {
9
+ bytes;
10
+ view;
11
+ constructor(bytes) {
12
+ this.bytes = bytes;
13
+ this.view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
14
+ }
15
+ u8(offset) { return offset < this.bytes.length ? this.view.getUint8(offset) : undefined; }
16
+ u16(offset) { return offset + 2 <= this.bytes.length ? this.view.getUint16(offset, true) : undefined; }
17
+ u32(offset) { return offset + 4 <= this.bytes.length ? this.view.getUint32(offset, true) : undefined; }
18
+ }
19
+ export function tryDecodeArchiveEntryPreview(entryPath, bytes) {
20
+ if (!entryPath.toLocaleLowerCase().endsWith('.xml'))
21
+ return null;
22
+ const reader = new Reader(bytes);
23
+ const xml = readChunkHeader(reader, 0);
24
+ if (!xml || xml.type !== RES_XML_TYPE || xml.headerSize < 8 || xml.size > bytes.length || readChunkHeader(reader, xml.headerSize)?.type !== RES_STRING_POOL_TYPE)
25
+ return null;
26
+ const stringPool = parseStringPool(reader);
27
+ if (!stringPool)
28
+ return null;
29
+ const namespaceStack = new Map();
30
+ const prefixByUri = new Map();
31
+ const pendingNamespaces = new Map();
32
+ const elements = [];
33
+ const lines = ['<?xml version="1.0" encoding="utf-8"?>'];
34
+ let offset = xml.headerSize;
35
+ while (offset + 8 <= bytes.length) {
36
+ const chunk = readChunkHeader(reader, offset);
37
+ if (!chunk || chunk.size <= 0 || offset + chunk.size > bytes.length)
38
+ return null;
39
+ if (chunk.type === RES_XML_START_NAMESPACE_TYPE || chunk.type === RES_XML_END_NAMESPACE_TYPE) {
40
+ if (!parseNamespace(reader, offset, stringPool, namespaceStack, prefixByUri, pendingNamespaces, chunk.type === RES_XML_START_NAMESPACE_TYPE))
41
+ return null;
42
+ }
43
+ else if (chunk.type === RES_XML_START_ELEMENT_TYPE) {
44
+ const element = parseStartElement(reader, offset, chunk, stringPool);
45
+ if (!element)
46
+ return null;
47
+ const parts = [qualifyName(element.namespaceUri, element.name, prefixByUri)];
48
+ const declarations = [...pendingNamespaces].map(([uri, prefix]) => prefix ? `xmlns:${prefix}="${escapeXml(uri)}"` : `xmlns="${escapeXml(uri)}"`);
49
+ pendingNamespaces.clear();
50
+ parts.push(...declarations, ...element.attributes.map(attribute => `${qualifyName(attribute.namespaceUri, attribute.name, prefixByUri)}="${escapeXml(attribute.value)}"`));
51
+ lines.push(`${' '.repeat(elements.length)}<${parts.join(' ')}>`);
52
+ elements.push(element);
53
+ }
54
+ else if (chunk.type === RES_XML_END_ELEMENT_TYPE) {
55
+ const element = parseEndElement(reader, offset, stringPool);
56
+ if (!element)
57
+ return null;
58
+ const current = elements.pop();
59
+ if (current && (current.name !== element.name || current.namespaceUri !== element.namespaceUri))
60
+ return null;
61
+ lines.push(`${' '.repeat(elements.length)}</${qualifyName(element.namespaceUri, element.name, prefixByUri)}>`);
62
+ }
63
+ offset += chunk.size;
64
+ }
65
+ return lines.length > 1 ? { content: lines.join('\n') } : null;
66
+ }
67
+ function parseStringPool(reader) {
68
+ const start = 8;
69
+ const header = readChunkHeader(reader, start);
70
+ if (!header || header.type !== RES_STRING_POOL_TYPE || header.headerSize < 28 || start + header.size > reader.bytes.length)
71
+ return null;
72
+ const count = reader.u32(start + 8);
73
+ const flags = reader.u32(start + 16);
74
+ const stringsStart = reader.u32(start + 20);
75
+ if (count === undefined || flags === undefined || stringsStart === undefined || count > (header.size - header.headerSize) / 4)
76
+ return null;
77
+ const utf8 = (flags & 0x100) !== 0;
78
+ const strings = [];
79
+ for (let index = 0; index < count; index++) {
80
+ const relative = reader.u32(start + header.headerSize + index * 4);
81
+ if (relative === undefined)
82
+ return null;
83
+ const absolute = start + stringsStart + relative;
84
+ if (absolute >= start + header.size)
85
+ return null;
86
+ const value = utf8 ? readUtf8String(reader, absolute, start + header.size) : readUtf16String(reader, absolute, start + header.size);
87
+ if (value === null)
88
+ return null;
89
+ strings.push(value);
90
+ }
91
+ return { strings };
92
+ }
93
+ function readUtf8String(reader, offset, limit) {
94
+ const chars = readLength8(reader, offset);
95
+ if (!chars)
96
+ return null;
97
+ const bytes = readLength8(reader, offset + chars[1]);
98
+ if (!bytes)
99
+ return null;
100
+ const start = offset + chars[1] + bytes[1];
101
+ const end = start + bytes[0];
102
+ return end <= limit ? new TextDecoder().decode(reader.bytes.subarray(start, end)) : null;
103
+ }
104
+ function readUtf16String(reader, offset, limit) {
105
+ const length = readLength16(reader, offset);
106
+ if (!length)
107
+ return null;
108
+ const start = offset + length[1];
109
+ const end = start + length[0] * 2;
110
+ return end <= limit ? new TextDecoder('utf-16le').decode(reader.bytes.subarray(start, end)) : null;
111
+ }
112
+ function readLength8(reader, offset) {
113
+ const first = reader.u8(offset);
114
+ if (first === undefined)
115
+ return null;
116
+ if ((first & 0x80) === 0)
117
+ return [first, 1];
118
+ const second = reader.u8(offset + 1);
119
+ return second === undefined ? null : [((first & 0x7f) << 8) | second, 2];
120
+ }
121
+ function readLength16(reader, offset) {
122
+ const first = reader.u16(offset);
123
+ if (first === undefined)
124
+ return null;
125
+ if ((first & 0x8000) === 0)
126
+ return [first, 2];
127
+ const second = reader.u16(offset + 2);
128
+ return second === undefined ? null : [((first & 0x7fff) << 16) | second, 4];
129
+ }
130
+ function parseNamespace(reader, offset, pool, stack, prefixes, pending, start) {
131
+ const prefixIndex = reader.u32(offset + 16);
132
+ const uriIndex = reader.u32(offset + 20);
133
+ if (prefixIndex === undefined || uriIndex === undefined)
134
+ return false;
135
+ const prefix = getString(pool, prefixIndex) ?? '';
136
+ const uri = getString(pool, uriIndex);
137
+ if (!uri)
138
+ return true;
139
+ if (start) {
140
+ const values = stack.get(uri) ?? [];
141
+ values.push(prefix);
142
+ stack.set(uri, values);
143
+ prefixes.set(uri, prefix);
144
+ pending.set(uri, prefix);
145
+ }
146
+ else {
147
+ const values = stack.get(uri);
148
+ values?.pop();
149
+ if (!values?.length) {
150
+ stack.delete(uri);
151
+ prefixes.delete(uri);
152
+ pending.delete(uri);
153
+ }
154
+ else
155
+ prefixes.set(uri, values[values.length - 1]);
156
+ }
157
+ return true;
158
+ }
159
+ function parseStartElement(reader, offset, header, pool) {
160
+ const namespaceIndex = reader.u32(offset + 16);
161
+ const nameIndex = reader.u32(offset + 20);
162
+ const attributeStart = reader.u16(offset + 24);
163
+ const attributeSize = reader.u16(offset + 26);
164
+ const count = reader.u16(offset + 28);
165
+ if (header.headerSize < 16 || namespaceIndex === undefined || nameIndex === undefined || attributeStart === undefined || attributeSize === undefined || count === undefined || attributeSize < 20)
166
+ return null;
167
+ const name = getString(pool, nameIndex);
168
+ if (!name)
169
+ return null;
170
+ const attributes = [];
171
+ let position = offset + 16 + attributeStart;
172
+ for (let index = 0; index < count; index++, position += attributeSize) {
173
+ if (position + attributeSize > offset + header.size)
174
+ return null;
175
+ const namespace = reader.u32(position);
176
+ const attributeName = reader.u32(position + 4);
177
+ const raw = reader.u32(position + 8);
178
+ const type = reader.u8(position + 15);
179
+ const data = reader.u32(position + 16);
180
+ if (namespace === undefined || attributeName === undefined || raw === undefined || type === undefined || data === undefined)
181
+ return null;
182
+ const resolvedName = getString(pool, attributeName);
183
+ if (!resolvedName)
184
+ return null;
185
+ attributes.push({ namespaceUri: getString(pool, namespace), name: resolvedName, value: formatTypedValue(type, data, getString(pool, raw), pool) });
186
+ }
187
+ return { namespaceUri: getString(pool, namespaceIndex), name, attributes };
188
+ }
189
+ function parseEndElement(reader, offset, pool) {
190
+ const namespace = reader.u32(offset + 16);
191
+ const nameIndex = reader.u32(offset + 20);
192
+ if (namespace === undefined || nameIndex === undefined)
193
+ return null;
194
+ const name = getString(pool, nameIndex);
195
+ return name ? { namespaceUri: getString(pool, namespace), name, attributes: [] } : null;
196
+ }
197
+ function formatTypedValue(type, data, raw, pool) {
198
+ if (raw)
199
+ return raw;
200
+ switch (type) {
201
+ case 0x00: return '';
202
+ case 0x01: return `@0x${data.toString(16).padStart(8, '0')}`;
203
+ case 0x02: return `?0x${data.toString(16).padStart(8, '0')}`;
204
+ case 0x03: return getString(pool, data) ?? '';
205
+ case 0x04: return String(bitsToFloat(data));
206
+ case 0x05: return formatComplex(data, ['px', 'dp', 'sp', 'pt', 'in', 'mm']);
207
+ case 0x06: return formatComplex(data, ['%', '%p']);
208
+ case 0x10: return String(data | 0);
209
+ case 0x11: return `0x${data.toString(16)}`;
210
+ case 0x12: return data ? 'true' : 'false';
211
+ case 0x1c:
212
+ case 0x1d:
213
+ case 0x1e:
214
+ case 0x1f: return `#${data.toString(16).padStart(8, '0')}`;
215
+ default: return `0x${data.toString(16)}`;
216
+ }
217
+ }
218
+ function bitsToFloat(data) { const view = new DataView(new ArrayBuffer(4)); view.setUint32(0, data, true); return view.getFloat32(0, true); }
219
+ function formatComplex(data, units) { const mantissa = (data & 0xffffff00) >> 8; const radix = (data >> 4) & 3; return `${mantissa * ([1 / 2 ** 23, 1 / 2 ** 15, 1 / 2 ** 7, 1][radix] ?? 1)}${units[data & 0xf] ?? ''}`; }
220
+ function qualifyName(uri, name, prefixes) { const prefix = uri ? prefixes.get(uri) : undefined; return prefix ? `${prefix}:${name}` : name; }
221
+ function getString(pool, index) { return index === NO_INDEX ? null : pool.strings[index] ?? null; }
222
+ function readChunkHeader(reader, offset) { const type = reader.u16(offset); const headerSize = reader.u16(offset + 2); const size = reader.u32(offset + 4); return type === undefined || headerSize === undefined || size === undefined ? null : { type, headerSize, size }; }
223
+ function escapeXml(value) { return value.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/'/g, '&apos;'); }
@@ -0,0 +1,24 @@
1
+ import type { ArchiveEntry } from '../../parsers/archive/index.js';
2
+ export interface ArchiveViewState {
3
+ query: string;
4
+ selectedId?: number;
5
+ expanded: ReadonlySet<string>;
6
+ entries: readonly ArchiveEntry[];
7
+ }
8
+ export type ArchiveAction = {
9
+ type: 'set-search';
10
+ query: string;
11
+ } | {
12
+ type: 'select';
13
+ entryId: number;
14
+ } | {
15
+ type: 'toggle-directory';
16
+ path: string;
17
+ };
18
+ export interface ArchiveController {
19
+ readonly state: ArchiveViewState;
20
+ dispatch(action: ArchiveAction): void;
21
+ visibleEntries(): readonly ArchiveEntry[];
22
+ subscribe(listener: () => void): () => void;
23
+ }
24
+ export declare function createArchiveController(entries: readonly ArchiveEntry[]): ArchiveController;
@@ -0,0 +1,18 @@
1
+ const parent = (path) => path.replace(/\/?[^/]+\/?$/, '');
2
+ export function createArchiveController(entries) {
3
+ let state = { query: '', expanded: new Set(entries.filter(x => x.isDirectory).map(x => x.path)), entries };
4
+ const listeners = new Set();
5
+ const emit = () => listeners.forEach(x => x());
6
+ return { get state() { return state; }, dispatch(action) { if (action.type === 'set-search')
7
+ state = { ...state, query: action.query };
8
+ else if (action.type === 'select')
9
+ state = { ...state, selectedId: action.entryId };
10
+ else {
11
+ const expanded = new Set(state.expanded);
12
+ expanded.has(action.path) ? expanded.delete(action.path) : expanded.add(action.path);
13
+ state = { ...state, expanded };
14
+ } emit(); }, visibleEntries() { const q = state.query.toLocaleLowerCase(); return state.entries.filter(entry => { if (q)
15
+ return entry.path.toLocaleLowerCase().includes(q) || state.entries.some(x => x.path.startsWith(`${entry.path.replace(/\/$/, '')}/`) && x.path.toLocaleLowerCase().includes(q)); for (let p = parent(entry.path); p; p = parent(p))
16
+ if (!state.expanded.has(p) && !state.expanded.has(`${p}/`))
17
+ return false; return true; }); }, subscribe(listener) { listeners.add(listener); return () => listeners.delete(listener); } };
18
+ }
@@ -0,0 +1,25 @@
1
+ import type { FileSaveService, HostContext } from '../../host/index.js';
2
+ import { type ArchiveDecoder } from '../../parsers/archive/index.js';
3
+ import type { ResourceLimits } from '../../parsers/types.js';
4
+ import { type MountOptions, type ViewerHandle, type ViewerInput } from '../types.js';
5
+ export * from '../../parsers/archive/index.js';
6
+ export { createArchiveController } from './controller.js';
7
+ export { archiveViewerCss } from './styles.js';
8
+ export declare const ARCHIVE_VIEWER_META: {
9
+ id: string;
10
+ displayNameKey: string;
11
+ extensions: string[];
12
+ priority: number;
13
+ requiredServices: readonly [];
14
+ optionalServices: readonly ["save"];
15
+ inputOwnership: "consumes";
16
+ };
17
+ export interface ArchiveViewerDeps extends ArchiveDecoder {
18
+ }
19
+ export type ArchiveViewerContext = HostContext & {
20
+ save?: FileSaveService;
21
+ };
22
+ export interface ArchiveMountOptions extends MountOptions {
23
+ limits?: ResourceLimits;
24
+ }
25
+ export declare function mountArchiveViewer(input: ViewerInput, container: HTMLElement, ctx: ArchiveViewerContext, deps: ArchiveViewerDeps, options?: ArchiveMountOptions): Promise<ViewerHandle>;
@@ -0,0 +1,230 @@
1
+ import { ARCHIVE_DEFAULT_LIMITS, ArchiveError, parseArchive } from '../../parsers/archive/index.js';
2
+ import { MountAbortedError, VIEWER_ROOT_CLASS } from '../types.js';
3
+ import { createArchiveController } from './controller.js';
4
+ import { tryDecodeArchiveEntryPreview } from './archive-preview-decoder.js';
5
+ import { hexPreview, isText } from './preview.js';
6
+ import { archiveViewerCss } from './styles.js';
7
+ export * from '../../parsers/archive/index.js';
8
+ export { createArchiveController } from './controller.js';
9
+ export { archiveViewerCss } from './styles.js';
10
+ export const ARCHIVE_VIEWER_META = { id: 'archive', displayNameKey: 'archive.title', extensions: ['zip', 'jar', 'apk', 'tar', 'tgz', 'tar.gz', 'tbz', 'tbz2', 'tar.bz2', 'txz', 'tar.xz', 'gz', 'bz2', 'xz', '7z', 'rar', 'dmg'], priority: 5, requiredServices: [], optionalServices: ['save'], inputOwnership: 'consumes' };
11
+ const element = (tag, className, text) => {
12
+ const node = document.createElement(tag);
13
+ if (className)
14
+ node.className = className;
15
+ if (text !== undefined)
16
+ node.textContent = text;
17
+ return node;
18
+ };
19
+ const formatSize = (value) => {
20
+ if (value === undefined || !Number.isFinite(value))
21
+ return '—';
22
+ const units = ['B', 'KB', 'MB', 'GB', 'TB'];
23
+ let size = value;
24
+ let unit = 0;
25
+ while (size >= 1024 && unit < units.length - 1) {
26
+ size /= 1024;
27
+ unit++;
28
+ }
29
+ const precision = size >= 100 || unit === 0 ? 0 : size >= 10 ? 1 : 2;
30
+ return `${size.toFixed(precision)} ${units[unit]}`;
31
+ };
32
+ const formatDate = (value) => {
33
+ if (value === undefined)
34
+ return '—';
35
+ const date = value instanceof Date ? value : new Date(value);
36
+ return Number.isNaN(date.getTime()) ? '—' : new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(date);
37
+ };
38
+ const archiveFormat = (name) => {
39
+ const lower = name.toLocaleLowerCase();
40
+ return ['tar.gz', 'tar.bz2', 'tar.xz'].find(ext => lower.endsWith(`.${ext}`))?.toUpperCase() ?? (lower.split('.').pop()?.toUpperCase() || 'ARCHIVE');
41
+ };
42
+ export async function mountArchiveViewer(input, container, ctx, deps, options = {}) {
43
+ if (options.signal?.aborted)
44
+ throw new MountAbortedError();
45
+ const parsed = await parseArchive(input.data, deps, { fileName: input.fileName, ...(options.signal ? { signal: options.signal } : {}), ...(options.limits ? { limits: options.limits } : {}) });
46
+ if (parsed.outcome.result.status === 'failed')
47
+ throw new Error(parsed.outcome.result.failure.messageKey);
48
+ if (options.signal?.aborted) {
49
+ await parsed.handle?.close();
50
+ throw new MountAbortedError();
51
+ }
52
+ let handle = parsed.handle;
53
+ const root = options.styleIsolation !== 'scoped' && typeof container.attachShadow === 'function' ? (container.shadowRoot ?? container.attachShadow({ mode: 'open' })) : container;
54
+ if (root === container)
55
+ container.classList.add(VIEWER_ROOT_CLASS, 'omni-viewer--archive');
56
+ else {
57
+ const style = element('style');
58
+ style.textContent = archiveViewerCss;
59
+ root.append(style);
60
+ }
61
+ const t = (key, args) => ctx.i18n.t(key, args);
62
+ const entries = parsed.outcome.result.document.entries;
63
+ const controller = createArchiveController(entries);
64
+ const wrap = element('section', `${VIEWER_ROOT_CLASS} omni-viewer--archive`);
65
+ const hero = element('header', 'omni-archive__hero');
66
+ const heading = element('div');
67
+ heading.append(element('div', 'omni-archive__eyebrow', t('archive.preview')), element('h1', '', input.fileName), element('p', 'omni-archive__subtitle', t('archive.summary')));
68
+ const pills = element('div', 'omni-archive__pills');
69
+ pills.append(element('span', 'omni-archive__pill', archiveFormat(input.fileName)), element('span', 'omni-archive__pill', t('archive.entries', { count: entries.length })), element('span', 'omni-archive__pill', formatSize(input.data.byteLength)));
70
+ hero.append(heading, pills);
71
+ const controls = element('section', 'omni-archive__controls');
72
+ const label = element('label', 'omni-archive__search-label', t('archive.filter'));
73
+ const search = element('input', 'omni-archive__search');
74
+ search.type = 'search';
75
+ search.placeholder = t('archive.search');
76
+ label.append(search);
77
+ controls.append(label);
78
+ const stats = element('section', 'omni-archive__stats');
79
+ const files = entries.filter(entry => !entry.isDirectory).length;
80
+ const statValues = [['archive.entries', entries.length], ['archive.files', files], ['archive.directories', entries.length - files], ['archive.visible', entries.length]];
81
+ const visibleStat = statValues[3];
82
+ for (const [key, value] of statValues) {
83
+ const card = element('article', 'omni-archive__stat');
84
+ card.append(element('div', 'omni-archive__stat-label', key === 'archive.entries' ? t('archive.title') : t(key)), element('div', 'omni-archive__stat-value', value.toLocaleString()));
85
+ stats.append(card);
86
+ }
87
+ const workspace = element('section', 'omni-archive__workspace');
88
+ const tableWrap = element('div', 'omni-archive__table-wrap');
89
+ const table = element('table', 'omni-archive__table');
90
+ const thead = element('thead');
91
+ const headerRow = element('tr');
92
+ for (const key of ['archive.path', 'archive.type', 'archive.compressedSize', 'archive.originalSize', 'archive.modified'])
93
+ headerRow.append(element('th', '', t(key)));
94
+ thead.append(headerRow);
95
+ const tbody = element('tbody');
96
+ table.append(thead, tbody);
97
+ const empty = element('div', 'omni-archive__empty', t('archive.noMatches'));
98
+ empty.hidden = true;
99
+ tableWrap.append(table, empty);
100
+ const previewPanel = element('aside', 'omni-archive__preview-panel');
101
+ const previewHeader = element('div', 'omni-archive__preview-header');
102
+ const previewHeading = element('div');
103
+ const previewTitle = element('h2', '', t('archive.chooseFile'));
104
+ previewHeading.append(element('div', 'omni-archive__preview-kicker', t('archive.entryPreview')), previewTitle);
105
+ const previewStatus = element('span', 'omni-archive__preview-badge', t('archive.idle'));
106
+ previewHeader.append(previewHeading, previewStatus);
107
+ const previewMeta = element('p', 'omni-archive__preview-meta', t('archive.selectHint'));
108
+ const preview = element('pre', 'omni-archive__preview', t('archive.noSelection'));
109
+ preview.setAttribute('aria-live', 'polite');
110
+ const saveButton = element('button', 'omni-archive__save', t('archive.saveEntry'));
111
+ saveButton.type = 'button';
112
+ saveButton.hidden = !ctx.save;
113
+ saveButton.disabled = true;
114
+ previewPanel.append(previewHeader, previewMeta, preview, saveButton);
115
+ workspace.append(tableWrap, previewPanel);
116
+ wrap.append(hero, controls, stats, workspace);
117
+ root.append(wrap);
118
+ let ticket = 0;
119
+ let extraction;
120
+ let saveExtraction;
121
+ let selectedEntry;
122
+ const setPreview = (entry, status, meta, content) => { previewTitle.textContent = entry?.path ?? t('archive.chooseFile'); previewStatus.textContent = status; previewMeta.textContent = meta; preview.textContent = content; };
123
+ const select = async (entry) => {
124
+ extraction?.abort();
125
+ extraction = undefined;
126
+ const local = ++ticket;
127
+ selectedEntry = entry;
128
+ saveButton.disabled = entry.isDirectory;
129
+ if (entry.isDirectory)
130
+ controller.dispatch({ type: 'toggle-directory', path: entry.path });
131
+ controller.dispatch({ type: 'select', entryId: entry.entryId });
132
+ if (entry.isDirectory) {
133
+ setPreview(entry, t('archive.directory'), t('archive.directoryHint'), t('archive.directoryContent'));
134
+ return;
135
+ }
136
+ if (!handle)
137
+ return;
138
+ extraction = new AbortController();
139
+ const request = extraction;
140
+ setPreview(entry, t('archive.loading'), t('archive.loadingHint'), t('archive.loadingContent'));
141
+ const maxPreview = ARCHIVE_DEFAULT_LIMITS.maxPreviewBytes;
142
+ if (entry.uncompressedSize !== undefined && entry.uncompressedSize > maxPreview) {
143
+ setPreview(entry, t('archive.previewUnavailable'), t('diag.archive.limit-exceeded'), t('archive.previewUnavailable'));
144
+ return;
145
+ }
146
+ try {
147
+ const data = await handle.extract(entry.entryId, { signal: request.signal, maxBytes: maxPreview });
148
+ if (local !== ticket)
149
+ return;
150
+ const decoded = tryDecodeArchiveEntryPreview(entry.path, data);
151
+ const text = isText(data);
152
+ setPreview(entry, t('archive.ready'), t(decoded ? 'archive.androidBinaryXmlReady' : text ? 'archive.textReady' : 'archive.binaryReady'), decoded?.content ?? (text ? new TextDecoder().decode(data) : hexPreview(data)));
153
+ }
154
+ catch (error) {
155
+ if (local === ticket && !request.signal.aborted)
156
+ setPreview(entry, t('archive.previewUnavailable'), t(error instanceof ArchiveError && error.code === 'limit-exceeded' ? 'diag.archive.limit-exceeded' : 'archive.previewUnavailable'), t('archive.previewUnavailable'));
157
+ }
158
+ };
159
+ saveButton.addEventListener('click', async () => {
160
+ const entry = selectedEntry;
161
+ const save = ctx.save;
162
+ if (!entry || entry.isDirectory || !save || !handle)
163
+ return;
164
+ saveExtraction?.abort();
165
+ saveExtraction = new AbortController();
166
+ const request = saveExtraction;
167
+ saveButton.disabled = true;
168
+ saveButton.textContent = t('archive.savingEntry');
169
+ try {
170
+ const configuredLimit = options.limits?.maxDecompressedBytes ?? ARCHIVE_DEFAULT_LIMITS.maxDecompressedBytes;
171
+ const maxBytes = Math.max(1, Math.min(entry.uncompressedSize ?? configuredLimit, configuredLimit));
172
+ const data = await handle.extract(entry.entryId, { signal: request.signal, maxBytes });
173
+ if (request.signal.aborted)
174
+ return;
175
+ const suggestedName = entry.path.split('/').filter(Boolean).pop() ?? 'archive-entry';
176
+ await save.saveFile(suggestedName, data, entry.mimeType ?? 'application/octet-stream');
177
+ if (!request.signal.aborted)
178
+ previewMeta.textContent = t('common.saved', { name: suggestedName });
179
+ }
180
+ catch {
181
+ if (!request.signal.aborted)
182
+ previewMeta.textContent = t('archive.saveFailed');
183
+ }
184
+ finally {
185
+ if (!request.signal.aborted) {
186
+ saveButton.disabled = false;
187
+ saveButton.textContent = t('archive.saveEntry');
188
+ }
189
+ }
190
+ });
191
+ const ROW_HEIGHT = 43;
192
+ const OVERSCAN = 8;
193
+ const FALLBACK_VIEWPORT_HEIGHT = 600;
194
+ const render = () => {
195
+ const visible = controller.visibleEntries();
196
+ visibleStat[1] = visible.length;
197
+ stats.querySelectorAll('.omni-archive__stat-value')[3].textContent = visible.length.toLocaleString();
198
+ tbody.replaceChildren();
199
+ empty.hidden = visible.length !== 0;
200
+ table.hidden = visible.length === 0;
201
+ const viewportHeight = tableWrap.clientHeight || FALLBACK_VIEWPORT_HEIGHT;
202
+ const start = Math.max(0, Math.floor(tableWrap.scrollTop / ROW_HEIGHT) - OVERSCAN);
203
+ const count = Math.ceil(viewportHeight / ROW_HEIGHT) + OVERSCAN * 2;
204
+ const end = Math.min(visible.length, start + count);
205
+ const spacer = (height) => { const row = element('tr', 'omni-archive__spacer'); const cell = element('td'); cell.colSpan = 5; cell.style.height = `${height}px`; row.append(cell); return row; };
206
+ if (start > 0)
207
+ tbody.append(spacer(start * ROW_HEIGHT));
208
+ for (const entry of visible.slice(start, end)) {
209
+ const row = element('tr', `omni-archive__entry${controller.state.selectedId === entry.entryId ? ' is-selected' : ''}`);
210
+ row.tabIndex = 0;
211
+ row.dataset.entryId = String(entry.entryId);
212
+ const path = element('td', 'omni-archive__path', `${entry.isDirectory ? (controller.state.expanded.has(entry.path) ? '▾ ' : '▸ ') : ''}${entry.path}`);
213
+ path.style.paddingInlineStart = `${Math.max(0, entry.path.split('/').filter(Boolean).length - 1) * 12 + 14}px`;
214
+ row.append(path, element('td', '', t(entry.isDirectory ? 'archive.directory' : 'archive.file')), element('td', '', formatSize(entry.compressedSize)), element('td', '', formatSize(entry.uncompressedSize)), element('td', '', formatDate(entry.modifiedAt)));
215
+ row.addEventListener('click', () => void select(entry));
216
+ row.addEventListener('keydown', event => { if (event.key === 'Enter' || event.key === ' ') {
217
+ event.preventDefault();
218
+ void select(entry);
219
+ } });
220
+ tbody.append(row);
221
+ }
222
+ if (end < visible.length)
223
+ tbody.append(spacer((visible.length - end) * ROW_HEIGHT));
224
+ };
225
+ tableWrap.addEventListener('scroll', render, { passive: true });
226
+ search.addEventListener('input', () => { tableWrap.scrollTop = 0; controller.dispatch({ type: 'set-search', query: search.value }); });
227
+ const unsubscribe = controller.subscribe(render);
228
+ render();
229
+ return { dispose() { ticket++; extraction?.abort(); saveExtraction?.abort(); unsubscribe(); wrap.remove(); void handle?.close(); handle = undefined; } };
230
+ }
@@ -0,0 +1,2 @@
1
+ export declare function isText(data: Uint8Array): boolean;
2
+ export declare function hexPreview(data: Uint8Array, max?: number): string;
@@ -0,0 +1,2 @@
1
+ export function isText(data) { return !data.some(x => x === 0 || (x < 9) || (x > 13 && x < 32)); }
2
+ export function hexPreview(data, max = 4096) { return Array.from(data.subarray(0, max), x => x.toString(16).padStart(2, '0')).join(' ') + (data.length > max ? ' …' : ''); }
@@ -0,0 +1 @@
1
+ export declare const archiveViewerCss = "\n.omni-viewer--archive{all:initial}.omni-viewer--archive :where(header,section,aside,div,h1,h2,p,span,label,input,table,thead,tbody,tr,th,td,pre){all:revert}\n:host,.omni-viewer--archive{display:block;min-height:100%;box-sizing:border-box;color:var(--omni-fg,#d4d4d4);background:radial-gradient(circle at top left,color-mix(in srgb,var(--omni-accent,#d97706) 14%,transparent),transparent 28%),var(--omni-bg,#1e1e1e);font:13px var(--omni-font,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif)}\n.omni-viewer--archive *{box-sizing:border-box}.omni-viewer--archive{padding:28px 20px 40px}.omni-archive__hero,.omni-archive__controls,.omni-archive__stats,.omni-archive__table-wrap,.omni-archive__preview-panel{background:var(--omni-bg-secondary,#252526);border:1px solid var(--omni-border,#3c3c3c);border-radius:18px;box-shadow:0 20px 40px rgba(0,0,0,.12)}\n.omni-archive__hero{display:flex;justify-content:space-between;gap:16px;padding:24px;align-items:flex-start}.omni-archive__eyebrow{font-size:12px;letter-spacing:.18em;text-transform:uppercase;color:var(--omni-accent,#d97706);font-weight:700}.omni-archive__hero h1{margin:8px 0 6px;font-size:clamp(26px,4vw,40px);line-height:1.1}.omni-archive__subtitle,.omni-archive__preview-meta{color:var(--omni-muted-fg,#9d9d9d);line-height:1.5}.omni-archive__pills{display:flex;gap:10px;flex-wrap:wrap;justify-content:flex-end}.omni-archive__pill{padding:10px 14px;border-radius:999px;background:color-mix(in srgb,var(--omni-accent,#d97706) 16%,transparent);border:1px solid color-mix(in srgb,var(--omni-accent,#d97706) 35%,transparent);font-weight:600;white-space:nowrap}\n.omni-archive__controls,.omni-archive__stats,.omni-archive__workspace{margin-top:16px}.omni-archive__controls{padding:16px}.omni-archive__search-label{display:block;font-weight:600}.omni-archive__search{display:block;width:100%;margin-top:8px;padding:12px 14px;border-radius:12px;border:1px solid var(--omni-border,#3c3c3c);background:var(--omni-input-bg,#3c3c3c);color:var(--omni-fg,#d4d4d4);font:inherit}.omni-archive__stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px;padding:16px}.omni-archive__stat{padding:14px;border-radius:14px;background:color-mix(in srgb,var(--omni-bg-secondary,#252526) 76%,#000);border:1px solid var(--omni-border,#3c3c3c)}.omni-archive__stat-label{font-size:12px;text-transform:uppercase;letter-spacing:.08em;color:var(--omni-muted-fg,#9d9d9d);margin-bottom:6px}.omni-archive__stat-value{font-size:24px;font-weight:700}\n.omni-archive__workspace{display:grid;grid-template-columns:minmax(0,1.7fr) minmax(320px,.95fr);gap:16px;align-items:start}.omni-archive__table-wrap{overflow:auto;min-width:0;max-height:70vh}.omni-archive__table{width:100%;table-layout:fixed;border-collapse:collapse}.omni-archive__table th,.omni-archive__table td{padding:12px 14px;border-bottom:1px solid var(--omni-border,#3c3c3c);text-align:left;vertical-align:top;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.omni-archive__table th:first-child{width:42%}.omni-archive__table th{position:sticky;top:0;font-size:12px;text-transform:uppercase;letter-spacing:.08em;color:var(--omni-muted-fg,#9d9d9d);background:var(--omni-bg-secondary,#252526);z-index:1}.omni-archive__path{font-family:var(--omni-mono-font,\"SFMono-Regular\",Consolas,monospace)}.omni-archive__entry{height:43px;cursor:pointer;transition:background-color 120ms ease}.omni-archive__entry:hover{background:color-mix(in srgb,var(--omni-accent,#d97706) 8%,transparent)}.omni-archive__entry:focus-visible{outline:2px solid var(--omni-accent,#d97706);outline-offset:-2px}.omni-archive__entry.is-selected{background:color-mix(in srgb,var(--omni-accent,#d97706) 16%,transparent)}.omni-archive__empty{padding:26px 18px;text-align:center;color:var(--omni-muted-fg,#9d9d9d)}\n.omni-archive__preview-panel{padding:18px;min-height:420px;display:flex;flex-direction:column;gap:14px}.omni-archive__preview-header{display:flex;justify-content:space-between;gap:12px;align-items:flex-start}.omni-archive__preview-kicker{font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--omni-muted-fg,#9d9d9d);margin-bottom:6px}.omni-archive__preview-header h2{margin:0;font-size:18px;line-height:1.35;word-break:break-word}.omni-archive__preview-badge{border-radius:999px;padding:8px 12px;font-size:12px;font-weight:700;background:var(--omni-badge-bg,#3a3d41);white-space:nowrap}.omni-archive__preview-meta{margin:0}.omni-archive__preview{margin:0;flex:1;overflow:auto;white-space:pre-wrap;word-break:break-word;border-radius:14px;border:1px solid var(--omni-border,#3c3c3c);background:var(--omni-code-bg,#181818);padding:14px;color:var(--omni-fg,#d4d4d4);font:12px/1.55 var(--omni-mono-font,\"SFMono-Regular\",Consolas,monospace)}\n.omni-archive__save{align-self:flex-start;padding:8px 12px;border:1px solid var(--omni-border,#3c3c3c);border-radius:6px;background:var(--omni-button-bg,#3a3d41);color:var(--omni-fg,#d4d4d4);font:inherit;cursor:pointer}.omni-archive__save:hover:not(:disabled){background:var(--omni-button-hover-bg,#45494e)}.omni-archive__save:disabled{opacity:.55;cursor:not-allowed}.omni-archive__spacer td{padding:0!important;border:0!important}\n@media(max-width:720px){.omni-viewer--archive{padding:16px 10px 24px}.omni-archive__hero{flex-direction:column}.omni-archive__pills{justify-content:flex-start}.omni-archive__table th:nth-child(n+3),.omni-archive__table td:nth-child(n+3){display:none}.omni-archive__workspace{grid-template-columns:1fr}.omni-archive__preview-panel{min-height:280px}}\n";
@@ -0,0 +1,11 @@
1
+ export const archiveViewerCss = `
2
+ .omni-viewer--archive{all:initial}.omni-viewer--archive :where(header,section,aside,div,h1,h2,p,span,label,input,table,thead,tbody,tr,th,td,pre){all:revert}
3
+ :host,.omni-viewer--archive{display:block;min-height:100%;box-sizing:border-box;color:var(--omni-fg,#d4d4d4);background:radial-gradient(circle at top left,color-mix(in srgb,var(--omni-accent,#d97706) 14%,transparent),transparent 28%),var(--omni-bg,#1e1e1e);font:13px var(--omni-font,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif)}
4
+ .omni-viewer--archive *{box-sizing:border-box}.omni-viewer--archive{padding:28px 20px 40px}.omni-archive__hero,.omni-archive__controls,.omni-archive__stats,.omni-archive__table-wrap,.omni-archive__preview-panel{background:var(--omni-bg-secondary,#252526);border:1px solid var(--omni-border,#3c3c3c);border-radius:18px;box-shadow:0 20px 40px rgba(0,0,0,.12)}
5
+ .omni-archive__hero{display:flex;justify-content:space-between;gap:16px;padding:24px;align-items:flex-start}.omni-archive__eyebrow{font-size:12px;letter-spacing:.18em;text-transform:uppercase;color:var(--omni-accent,#d97706);font-weight:700}.omni-archive__hero h1{margin:8px 0 6px;font-size:clamp(26px,4vw,40px);line-height:1.1}.omni-archive__subtitle,.omni-archive__preview-meta{color:var(--omni-muted-fg,#9d9d9d);line-height:1.5}.omni-archive__pills{display:flex;gap:10px;flex-wrap:wrap;justify-content:flex-end}.omni-archive__pill{padding:10px 14px;border-radius:999px;background:color-mix(in srgb,var(--omni-accent,#d97706) 16%,transparent);border:1px solid color-mix(in srgb,var(--omni-accent,#d97706) 35%,transparent);font-weight:600;white-space:nowrap}
6
+ .omni-archive__controls,.omni-archive__stats,.omni-archive__workspace{margin-top:16px}.omni-archive__controls{padding:16px}.omni-archive__search-label{display:block;font-weight:600}.omni-archive__search{display:block;width:100%;margin-top:8px;padding:12px 14px;border-radius:12px;border:1px solid var(--omni-border,#3c3c3c);background:var(--omni-input-bg,#3c3c3c);color:var(--omni-fg,#d4d4d4);font:inherit}.omni-archive__stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px;padding:16px}.omni-archive__stat{padding:14px;border-radius:14px;background:color-mix(in srgb,var(--omni-bg-secondary,#252526) 76%,#000);border:1px solid var(--omni-border,#3c3c3c)}.omni-archive__stat-label{font-size:12px;text-transform:uppercase;letter-spacing:.08em;color:var(--omni-muted-fg,#9d9d9d);margin-bottom:6px}.omni-archive__stat-value{font-size:24px;font-weight:700}
7
+ .omni-archive__workspace{display:grid;grid-template-columns:minmax(0,1.7fr) minmax(320px,.95fr);gap:16px;align-items:start}.omni-archive__table-wrap{overflow:auto;min-width:0;max-height:70vh}.omni-archive__table{width:100%;table-layout:fixed;border-collapse:collapse}.omni-archive__table th,.omni-archive__table td{padding:12px 14px;border-bottom:1px solid var(--omni-border,#3c3c3c);text-align:left;vertical-align:top;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.omni-archive__table th:first-child{width:42%}.omni-archive__table th{position:sticky;top:0;font-size:12px;text-transform:uppercase;letter-spacing:.08em;color:var(--omni-muted-fg,#9d9d9d);background:var(--omni-bg-secondary,#252526);z-index:1}.omni-archive__path{font-family:var(--omni-mono-font,"SFMono-Regular",Consolas,monospace)}.omni-archive__entry{height:43px;cursor:pointer;transition:background-color 120ms ease}.omni-archive__entry:hover{background:color-mix(in srgb,var(--omni-accent,#d97706) 8%,transparent)}.omni-archive__entry:focus-visible{outline:2px solid var(--omni-accent,#d97706);outline-offset:-2px}.omni-archive__entry.is-selected{background:color-mix(in srgb,var(--omni-accent,#d97706) 16%,transparent)}.omni-archive__empty{padding:26px 18px;text-align:center;color:var(--omni-muted-fg,#9d9d9d)}
8
+ .omni-archive__preview-panel{padding:18px;min-height:420px;display:flex;flex-direction:column;gap:14px}.omni-archive__preview-header{display:flex;justify-content:space-between;gap:12px;align-items:flex-start}.omni-archive__preview-kicker{font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--omni-muted-fg,#9d9d9d);margin-bottom:6px}.omni-archive__preview-header h2{margin:0;font-size:18px;line-height:1.35;word-break:break-word}.omni-archive__preview-badge{border-radius:999px;padding:8px 12px;font-size:12px;font-weight:700;background:var(--omni-badge-bg,#3a3d41);white-space:nowrap}.omni-archive__preview-meta{margin:0}.omni-archive__preview{margin:0;flex:1;overflow:auto;white-space:pre-wrap;word-break:break-word;border-radius:14px;border:1px solid var(--omni-border,#3c3c3c);background:var(--omni-code-bg,#181818);padding:14px;color:var(--omni-fg,#d4d4d4);font:12px/1.55 var(--omni-mono-font,"SFMono-Regular",Consolas,monospace)}
9
+ .omni-archive__save{align-self:flex-start;padding:8px 12px;border:1px solid var(--omni-border,#3c3c3c);border-radius:6px;background:var(--omni-button-bg,#3a3d41);color:var(--omni-fg,#d4d4d4);font:inherit;cursor:pointer}.omni-archive__save:hover:not(:disabled){background:var(--omni-button-hover-bg,#45494e)}.omni-archive__save:disabled{opacity:.55;cursor:not-allowed}.omni-archive__spacer td{padding:0!important;border:0!important}
10
+ @media(max-width:720px){.omni-viewer--archive{padding:16px 10px 24px}.omni-archive__hero{flex-direction:column}.omni-archive__pills{justify-content:flex-start}.omni-archive__table th:nth-child(n+3),.omni-archive__table td:nth-child(n+3){display:none}.omni-archive__workspace{grid-template-columns:1fr}.omni-archive__preview-panel{min-height:280px}}
11
+ `;
@@ -0,0 +1,15 @@
1
+ import type { AutomotiveViewerContext } from '../automotive/index.js';
2
+ import type { MountOptions, ViewerHandle, ViewerInput } from '../types.js';
3
+ export { parseArxml } from '../../parsers/arxml/index.js';
4
+ export { automotiveViewerCss as arxmlViewerCss } from '../automotive/styles.js';
5
+ export type ArxmlViewerContext = AutomotiveViewerContext;
6
+ export declare const ARXML_VIEWER_META: {
7
+ id: string;
8
+ displayNameKey: string;
9
+ extensions: string[];
10
+ priority: number;
11
+ requiredServices: readonly [];
12
+ optionalServices: readonly ["clipboard"];
13
+ inputOwnership: "borrows";
14
+ };
15
+ export declare const mountArxmlViewer: (input: ViewerInput, container: HTMLElement, ctx: ArxmlViewerContext, options?: MountOptions) => Promise<ViewerHandle>;
@@ -0,0 +1,5 @@
1
+ import { mountAutomotiveViewer } from '../automotive/index.js';
2
+ export { parseArxml } from '../../parsers/arxml/index.js';
3
+ export { automotiveViewerCss as arxmlViewerCss } from '../automotive/styles.js';
4
+ export const ARXML_VIEWER_META = { id: 'arxml', displayNameKey: 'arxml.title', extensions: ['arxml'], priority: 20, requiredServices: [], optionalServices: ['clipboard'], inputOwnership: 'borrows' };
5
+ export const mountArxmlViewer = (input, container, ctx, options = {}) => mountAutomotiveViewer('arxml', input, container, ctx, options);
@@ -0,0 +1,15 @@
1
+ import type { AutomotiveViewerContext } from '../automotive/index.js';
2
+ import type { MountOptions, ViewerHandle, ViewerInput } from '../types.js';
3
+ export { parseAsc } from '../../parsers/asc/index.js';
4
+ export { automotiveViewerCss as ascViewerCss } from '../automotive/styles.js';
5
+ export type AscViewerContext = AutomotiveViewerContext;
6
+ export declare const ASC_VIEWER_META: {
7
+ id: string;
8
+ displayNameKey: string;
9
+ extensions: string[];
10
+ priority: number;
11
+ requiredServices: readonly [];
12
+ optionalServices: readonly ["clipboard"];
13
+ inputOwnership: "borrows";
14
+ };
15
+ export declare const mountAscViewer: (input: ViewerInput, container: HTMLElement, ctx: AscViewerContext, options?: MountOptions) => Promise<ViewerHandle>;
@@ -0,0 +1,5 @@
1
+ import { mountAutomotiveViewer } from '../automotive/index.js';
2
+ export { parseAsc } from '../../parsers/asc/index.js';
3
+ export { automotiveViewerCss as ascViewerCss } from '../automotive/styles.js';
4
+ export const ASC_VIEWER_META = { id: 'asc', displayNameKey: 'asc.title', extensions: ['asc'], priority: 20, requiredServices: [], optionalServices: ['clipboard'], inputOwnership: 'borrows' };
5
+ export const mountAscViewer = (input, container, ctx, options = {}) => mountAutomotiveViewer('asc', input, container, ctx, options);
@@ -0,0 +1,33 @@
1
+ export declare const AUDIO_MIN_ZOOM = 1;
2
+ export declare const AUDIO_MAX_ZOOM = 32;
3
+ export declare const AUDIO_VOLUME_STEPS = 100;
4
+ export type AudioVisualization = 'waveform' | 'spectrogram';
5
+ export interface AudioViewState {
6
+ /** Horizontal zoom multiplier over the fit-to-width pixel density. */
7
+ zoom: number;
8
+ /** 0..1 */
9
+ volume: number;
10
+ loop: boolean;
11
+ visualization: AudioVisualization;
12
+ }
13
+ export type AudioAction = {
14
+ type: 'zoom-in';
15
+ } | {
16
+ type: 'zoom-out';
17
+ } | {
18
+ type: 'zoom-fit';
19
+ } | {
20
+ type: 'set-volume';
21
+ volume: number;
22
+ } | {
23
+ type: 'toggle-loop';
24
+ } | {
25
+ type: 'set-visualization';
26
+ visualization: AudioVisualization;
27
+ };
28
+ export interface AudioController {
29
+ readonly state: AudioViewState;
30
+ dispatch(action: AudioAction): void;
31
+ subscribe(listener: (state: AudioViewState) => void): () => void;
32
+ }
33
+ export declare function createAudioController(): AudioController;