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,973 @@
1
+ import { parseDbc } from '../dbc/index.js';
2
+ const SQLITE_HEADER = 'SQLite format 3\0';
3
+ const utf8 = new TextDecoder();
4
+ const latin1 = new TextDecoder('latin1');
5
+ const TEXT_SCAN_LIMIT = 4 * 1024 * 1024;
6
+ const BINARY_SCAN_LIMIT = 8 * 1024 * 1024;
7
+ const ROW_LIMIT = 5_000;
8
+ export function parseAutomotive(format, data) {
9
+ switch (format) {
10
+ case 'avro': return parseAvro(data);
11
+ case 'bag': return parseBag(data);
12
+ case 'stp': return parseStp(data);
13
+ case 'db3': return parseDb3(data);
14
+ case 'reqif': return parseReqif(data);
15
+ case 'dbc': return parseDbcAutomotive(data);
16
+ case 'arxml': return parseArxml(data);
17
+ case 'a2l': return parseA2l(data);
18
+ case 'asc': return parseAsc(data);
19
+ case 'blf': return parseBlf(data);
20
+ case 'mf4': return parseMf4(data);
21
+ case 'pcap': return parsePcap(data);
22
+ case 'pcapng': return parsePcapng(data);
23
+ }
24
+ }
25
+ function parseDbcAutomotive(data) {
26
+ const model = parseDbc(data);
27
+ const messages = model.messages.slice(0, 2_000);
28
+ const signals = messages.flatMap(message => message.signals.map(signal => [message.idHex, message.name, signal.name, signal.startBit, signal.length, signal.byteOrder, signal.valueType, signal.factor, signal.offset, signal.unit, signal.receivers.join(', ')]));
29
+ return {
30
+ format: 'DBC', title: 'CAN database', fileSizeBytes: data.byteLength,
31
+ summary: [{ label: 'Version', value: model.version || '-' }, { label: 'Messages', value: model.stats.messageCount }, { label: 'Signals', value: model.stats.signalCount }, { label: 'Nodes', value: model.stats.nodeCount }],
32
+ tables: [
33
+ { title: 'Messages', headers: ['ID', 'Name', 'DLC', 'Transmitter', 'Signals', 'Comment'], rows: messages.map(x => [x.idHex, x.name, x.dlc, x.transmitter, x.signals.length, x.comment ?? '-']) },
34
+ { title: 'Signals', headers: ['Message ID', 'Message', 'Signal', 'Start bit', 'Length', 'Byte order', 'Sign', 'Factor', 'Offset', 'Unit', 'Receivers'], rows: signals.slice(0, 20_000) },
35
+ { title: 'Nodes', headers: ['#', 'Name'], rows: model.nodes.map((name, index) => [index + 1, name]) }
36
+ ], rawPreview: preview(new TextDecoder().decode(data.subarray(0, TEXT_SCAN_LIMIT))), warnings: model.warnings
37
+ };
38
+ }
39
+ export function parseAvro(data) {
40
+ const isObjectContainer = matchesBytes(data, 0, [0x4f, 0x62, 0x6a, 0x01]);
41
+ const metadata = isObjectContainer ? readAvroMetadata(data) : [];
42
+ const schema = metadata.find(row => row[0] === 'avro.schema')?.[1];
43
+ const codec = metadata.find(row => row[0] === 'avro.codec')?.[1];
44
+ const syncMarker = data.length >= 16 ? toHex(data.subarray(data.length - 16)) : '-';
45
+ return {
46
+ format: 'AVRO',
47
+ title: 'Apache Avro object container',
48
+ fileSizeBytes: data.byteLength,
49
+ summary: [
50
+ { label: 'Magic', value: isObjectContainer ? 'Obj\\x01' : '-' },
51
+ { label: 'Metadata entries', value: metadata.length },
52
+ { label: 'Codec', value: codec || 'null' },
53
+ { label: 'Sync marker hint', value: syncMarker }
54
+ ],
55
+ tables: [
56
+ {
57
+ title: 'Metadata',
58
+ headers: ['Key', 'Value'],
59
+ rows: metadata.length ? metadata : [['-', 'No Avro metadata map could be decoded from the header.']]
60
+ },
61
+ { title: 'Header preview', headers: ['Offset', 'Hex', 'ASCII'], rows: hexRows(data, 0, Math.min(data.length, 256)) }
62
+ ],
63
+ ...(schema ? { rawPreview: prettyJson(String(schema)) } : {}),
64
+ warnings: isObjectContainer ? [] : ['The file does not start with the expected Avro object container magic bytes.']
65
+ };
66
+ }
67
+ export function parseBag(data) {
68
+ const headerLine = firstAsciiLine(data);
69
+ const isRosBag = headerLine.startsWith('#ROSBAG V2.');
70
+ const scan = data.subarray(0, BINARY_SCAN_LIMIT);
71
+ const counts = countBagOperations(scan);
72
+ const operationRows = [
73
+ ['Bag header', counts.bagHeader], ['Connection', counts.connection], ['Chunk', counts.chunk],
74
+ ['Index data', counts.indexData], ['Chunk info', counts.chunkInfo], ['Message data', counts.messageData]
75
+ ].filter(row => Number(row[1]) > 0);
76
+ return {
77
+ format: 'BAG',
78
+ title: 'ROS bag',
79
+ fileSizeBytes: data.byteLength,
80
+ summary: [
81
+ { label: 'Header', value: headerLine || '-' },
82
+ { label: 'Connection records', value: counts.connection },
83
+ { label: 'Chunk records', value: counts.chunk },
84
+ { label: 'Message data records', value: counts.messageData }
85
+ ],
86
+ tables: [
87
+ { title: 'Record op hints', headers: ['Record type', 'Count'], rows: operationRows },
88
+ { title: 'Header preview', headers: ['Offset', 'Hex', 'ASCII'], rows: hexRows(data, 0, Math.min(data.length, 256)) }
89
+ ],
90
+ warnings: [
91
+ ...(isRosBag ? [] : ['The file does not start with the expected ROS bag header.']),
92
+ ...(data.length > scan.length ? ['ROS bag record scan is limited to the first 8 MiB.'] : [])
93
+ ]
94
+ };
95
+ }
96
+ export function parseStp(data) {
97
+ const { source, truncated } = boundedText(data);
98
+ const header = extractStepHeader(source);
99
+ const entities = collectStepEntities(source);
100
+ const counts = new Map();
101
+ entities.forEach(entity => counts.set(entity.type, (counts.get(entity.type) ?? 0) + 1));
102
+ return {
103
+ format: 'STP',
104
+ title: 'ISO 10303 STEP model',
105
+ fileSizeBytes: data.byteLength,
106
+ summary: [
107
+ { label: 'Schema', value: header.schema || '-' }, { label: 'Name', value: header.name || '-' },
108
+ { label: 'Entity lines', value: entities.length }, { label: 'Entity types', value: counts.size }
109
+ ],
110
+ tables: [
111
+ {
112
+ title: 'Header', headers: ['Field', 'Value'], rows: [
113
+ ['Name', header.name || '-'], ['Timestamp', header.timestamp || '-'], ['Author', header.author || '-'],
114
+ ['Organization', header.organization || '-'], ['Preprocessor', header.preprocessor || '-'],
115
+ ['Originating system', header.originatingSystem || '-'], ['Authorization', header.authorization || '-'],
116
+ ['Schema', header.schema || '-']
117
+ ]
118
+ },
119
+ {
120
+ title: 'Top entity types', headers: ['Entity', 'Count'],
121
+ rows: [...counts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 100)
122
+ },
123
+ { title: 'Entity preview', headers: ['ID', 'Type', 'Line'], rows: entities.slice(0, 1000).map(item => [item.id, item.type, item.line]) }
124
+ ],
125
+ rawPreview: preview(source),
126
+ warnings: [
127
+ ...limitWarning(truncated, 'STEP text scan'),
128
+ ...(entities.length > 1000 ? ['Large STEP file: entity preview is limited to the first 1,000 entities.'] : [])
129
+ ]
130
+ };
131
+ }
132
+ export function parseDb3(data) {
133
+ const isSqlite = ascii(data.subarray(0, SQLITE_HEADER.length)) === SQLITE_HEADER;
134
+ const pageSize = data.length >= 18 ? readSqlitePageSize(data) : 0;
135
+ const pageCount = data.length >= 32 ? readU32BE(data, 28) : 0;
136
+ const sqlite = isSqlite && pageSize > 0
137
+ ? parseSqliteDatabase(data, pageSize)
138
+ : { schema: [], previews: [], warnings: [] };
139
+ const schemaRows = sqlite.schema.length
140
+ ? sqlite.schema.map(entry => [entry.type, entry.name, entry.tableName, entry.rootPage, entry.sql])
141
+ : extractSqliteSchemaHints(data).map((sql, index) => ['hint', `schema-${index + 1}`, '-', '-', sql]);
142
+ const userTables = sqlite.schema.filter(entry => entry.type === 'table' && !entry.name.startsWith('sqlite_'));
143
+ const ros2Tables = ['topics', 'messages', 'schemas', 'metadata'].filter(name => userTables.some(entry => entry.name === name));
144
+ return {
145
+ format: 'DB3',
146
+ title: 'SQLite 3 database',
147
+ fileSizeBytes: data.byteLength,
148
+ summary: [
149
+ { label: 'Signature', value: isSqlite ? 'SQLite format 3' : '-' }, { label: 'Page size', value: pageSize || '-' },
150
+ { label: 'Page count hint', value: pageCount || '-' }, { label: 'Tables', value: userTables.length }
151
+ ],
152
+ tables: [
153
+ {
154
+ title: 'Database header', headers: ['Field', 'Value'], rows: [
155
+ ['Page size', pageSize || '-'], ['Page count hint', pageCount || '-'], ['Schema entries', sqlite.schema.length],
156
+ ['ROS2 tables detected', ros2Tables.length ? ros2Tables.join(', ') : '-']
157
+ ]
158
+ },
159
+ {
160
+ title: 'Schema', headers: ['Type', 'Name', 'Table', 'Root page', 'SQL'],
161
+ rows: schemaRows.length ? schemaRows : [['-', '-', '-', '-', 'No sqlite_master schema rows could be decoded.']]
162
+ },
163
+ ...sqlite.previews.map(table => ({
164
+ title: `Rows: ${table.tableName}`,
165
+ headers: ['rowid', ...table.columns],
166
+ rows: table.rows.map(row => [row.rowid, ...row.values])
167
+ })),
168
+ { title: 'Header preview', headers: ['Offset', 'Hex', 'ASCII'], rows: hexRows(data, 0, Math.min(data.length, 256)) }
169
+ ],
170
+ warnings: isSqlite ? sqlite.warnings : ['The file does not start with the expected SQLite 3 database header.']
171
+ };
172
+ }
173
+ export function parseReqif(data) {
174
+ const { source, truncated } = boundedText(data);
175
+ const header = extractReqifHeader(source);
176
+ const specObjects = collectReqifElements(source, 'SPEC-OBJECT');
177
+ const specifications = collectReqifElements(source, 'SPECIFICATION');
178
+ const relations = collectReqifElements(source, 'SPEC-RELATION');
179
+ const datatypes = collectReqifElements(source, 'DATATYPE-DEFINITION-[A-Z-]+');
180
+ const specTypes = collectReqifElements(source, 'SPEC-[A-Z-]*TYPE');
181
+ return {
182
+ format: 'REQIF',
183
+ title: 'Requirements Interchange Format',
184
+ fileSizeBytes: data.byteLength,
185
+ summary: [
186
+ { label: 'Title', value: header.title || '-' }, { label: 'Spec objects', value: specObjects.length },
187
+ { label: 'Specifications', value: specifications.length }, { label: 'Spec relations', value: relations.length }
188
+ ],
189
+ tables: [
190
+ {
191
+ title: 'Header', headers: ['Field', 'Value'], rows: [
192
+ ['Title', header.title || '-'], ['Identifier', header.identifier || '-'],
193
+ ['Source tool ID', header.sourceToolId || '-'], ['ReqIF tool ID', header.reqifToolId || '-'],
194
+ ['Creation time', header.creationTime || '-'], ['Comment', header.comment || '-']
195
+ ]
196
+ },
197
+ { title: 'Specifications', headers: ['Identifier', 'Long name', 'Type'], rows: reqifRows(specifications, 1000) },
198
+ { title: 'Spec objects', headers: ['Identifier', 'Long name', 'Type'], rows: reqifRows(specObjects, 1000) },
199
+ { title: 'Spec relations', headers: ['Identifier', 'Long name', 'Type'], rows: reqifRows(relations, 1000) },
200
+ {
201
+ title: 'Definitions', headers: ['Kind', 'Identifier', 'Long name'], rows: [
202
+ ...datatypes.slice(0, 500).map(item => [item.type, item.identifier, item.longName]),
203
+ ...specTypes.slice(0, 500).map(item => [item.type, item.identifier, item.longName])
204
+ ]
205
+ }
206
+ ],
207
+ rawPreview: preview(source),
208
+ warnings: [
209
+ ...limitWarning(truncated, 'ReqIF XML scan'),
210
+ ...(specObjects.length > 1000 || specifications.length > 1000 || relations.length > 1000
211
+ ? ['Large ReqIF file: object, specification, and relation tables are limited to the first 1,000 entries.']
212
+ : [])
213
+ ]
214
+ };
215
+ }
216
+ function boundedText(data) {
217
+ const truncated = data.byteLength > TEXT_SCAN_LIMIT;
218
+ return { source: utf8.decode(data.subarray(0, TEXT_SCAN_LIMIT)), truncated };
219
+ }
220
+ function limitWarning(truncated, kind = 'text scan') {
221
+ return truncated ? [`Large input: ${kind} is limited to the first ${TEXT_SCAN_LIMIT.toLocaleString()} bytes.`] : [];
222
+ }
223
+ export function parseArxml(data) {
224
+ const { source, truncated } = boundedText(data);
225
+ const valid = /<AUTOSAR(?:\s|>)/i.test(source);
226
+ const complete = /<\/AUTOSAR\s*>/i.test(source);
227
+ const packageNames = collectXmlChildText(source, 'AR-PACKAGE', 'SHORT-NAME', 1_000);
228
+ const tags = ['CAN-CLUSTER', 'CAN-PHYSICAL-CHANNEL', 'CAN-FRAME-TRIGGERING', 'FRAME', 'I-SIGNAL', 'I-PDU', 'SIGNAL-I-PDU', 'ECU-INSTANCE'];
229
+ const elements = [];
230
+ for (const tag of tags) {
231
+ const re = new RegExp(`<${tag}\\b[^>]*>[\\s\\S]*?<SHORT-NAME\\b[^>]*>([\\s\\S]*?)<\\/SHORT-NAME>`, 'gi');
232
+ let match;
233
+ while (elements.length < 1_000 && (match = re.exec(source)))
234
+ elements.push([tag, cleanXmlText(match[1] ?? '')]);
235
+ }
236
+ const refs = [];
237
+ const refRe = /<([A-Z0-9-]*REF)\b([^>]*)>([^<]{0,4096})<\/\1>/gi;
238
+ let ref;
239
+ while (refs.length < 1_000 && (ref = refRe.exec(source)))
240
+ refs.push([ref[1] ?? '', /\bDEST\s*=\s*["']([^"']*)/i.exec(ref[2] ?? '')?.[1] ?? '-', cleanXmlText(ref[3] ?? '')]);
241
+ const namespace = /<AUTOSAR\b[^>]*\bxmlns\s*=\s*["']([^"']+)/i.exec(source)?.[1] ?? '-';
242
+ return {
243
+ format: 'ARXML', title: 'AUTOSAR XML', fileSizeBytes: data.byteLength,
244
+ summary: [{ label: 'Packages', value: packageNames.length }, { label: 'Named elements', value: elements.length }, { label: 'References', value: refs.length }, { label: 'XML namespace', value: namespace }],
245
+ tables: [
246
+ { title: 'Packages', headers: ['#', 'Short name'], rows: packageNames.map((name, i) => [i + 1, name]) },
247
+ { title: 'Named elements', headers: ['Type', 'Short name'], rows: elements },
248
+ { title: 'References', headers: ['Tag', 'Dest', 'Target'], rows: refs }
249
+ ], rawPreview: preview(source),
250
+ warnings: [...(!valid ? ['The input does not contain an AUTOSAR root element.'] : []), ...(valid && !complete ? ['The AUTOSAR XML document appears truncated or is missing its closing root element.'] : []), ...limitWarning(truncated, 'XML scan'), ...(elements.length >= 1_000 || refs.length >= 1_000 ? ['ARXML tables are limited to 1,000 rows.'] : [])]
251
+ };
252
+ }
253
+ export function parseA2l(data) {
254
+ const { source, truncated } = boundedText(data);
255
+ const blocks = [];
256
+ const counts = new Map();
257
+ source.split(/\r?\n/).forEach((line, index) => {
258
+ const match = /^\s*\/begin\s+([A-Z0-9_]+)(?:\s+([^\s/]+))?/i.exec(line);
259
+ if (!match?.[1])
260
+ return;
261
+ const type = match[1].toUpperCase();
262
+ counts.set(type, (counts.get(type) ?? 0) + 1);
263
+ if (blocks.length < 1_000)
264
+ blocks.push({ type, name: (match[2] ?? '-').replace(/^"|"$/g, ''), line: index + 1 });
265
+ });
266
+ const total = [...counts.values()].reduce((a, b) => a + b, 0);
267
+ return {
268
+ format: 'A2L', title: 'ASAM MCD-2 MC / ASAP2', fileSizeBytes: data.byteLength,
269
+ summary: [{ label: 'Blocks', value: total }, { label: 'Measurements', value: counts.get('MEASUREMENT') ?? 0 }, { label: 'Characteristics', value: counts.get('CHARACTERISTIC') ?? 0 }, { label: 'IF_DATA', value: counts.get('IF_DATA') ?? 0 }],
270
+ tables: [
271
+ { title: 'Important blocks', headers: ['Type', 'Name', 'Line'], rows: blocks.map(x => [x.type, x.name, x.line]) },
272
+ { title: 'Block counts', headers: ['Type', 'Count'], rows: [...counts].sort((a, b) => b[1] - a[1]) }
273
+ ], rawPreview: preview(source), warnings: [...(total === 0 ? ['No A2L /begin blocks were found.'] : []), ...(total > (source.match(/^\s*\/end\b/gim)?.length ?? 0) ? ['The A2L document appears truncated: one or more /begin blocks have no /end.'] : []), ...limitWarning(truncated), ...(total > blocks.length ? ['A2L block preview is limited to 1,000 rows.'] : [])]
274
+ };
275
+ }
276
+ export function parseAsc(data) {
277
+ const { source, truncated } = boundedText(data);
278
+ const headers = [];
279
+ const events = [];
280
+ let total = 0;
281
+ let fd = 0;
282
+ source.split(/\r?\n/).forEach((line, index) => {
283
+ const trimmed = line.trim();
284
+ if (!trimmed)
285
+ return;
286
+ if (!/^\d+(?:\.\d+)?\s+/.test(trimmed)) {
287
+ if (headers.length < 20)
288
+ headers.push([headers.length + 1, trimmed]);
289
+ return;
290
+ }
291
+ const event = parseAscEvent(trimmed, index + 1);
292
+ if (!event)
293
+ return;
294
+ total++;
295
+ if (event.type === 'CANFD')
296
+ fd++;
297
+ if (events.length < ROW_LIMIT)
298
+ events.push([event.time, event.type, event.channel, event.direction, event.id, event.dlc, event.data, event.line]);
299
+ });
300
+ return {
301
+ format: 'ASC', title: 'Vector ASCII CAN log', fileSizeBytes: data.byteLength,
302
+ summary: [{ label: 'Parsed events', value: total }, { label: 'CAN FD events', value: fd }, { label: 'Classic CAN events', value: total - fd }, { label: 'Header lines', value: headers.length }],
303
+ tables: [{ title: 'Header', headers: ['#', 'Line'], rows: headers }, { title: 'CAN events', headers: ['Time', 'Type', 'Channel', 'Dir', 'ID', 'DLC', 'Data', 'Line'], rows: events }],
304
+ rawPreview: preview(source), warnings: [...(total === 0 ? ['No timestamped ASC events were found.'] : []), ...limitWarning(truncated), ...(total > events.length ? [`ASC event preview is limited to ${ROW_LIMIT.toLocaleString()} rows.`] : [])]
305
+ };
306
+ }
307
+ function parseAscEvent(line, lineNumber) {
308
+ const canFd = /^(\d+(?:\.\d+)?)\s+CANFD\s+(\S+)\s+(Rx|Tx)\s+((?:0x)?[0-9A-Fa-f]+x?)\s+(.+)$/i.exec(line);
309
+ if (canFd) {
310
+ const fields = (canFd[5] ?? '').trim().split(/\s+/);
311
+ // Vector CAN FD ASC rows contain an optional symbolic name before
312
+ // BRS, ESI, DLC and DataLength. Like python-can, a numeric first
313
+ // field identifies the no-symbol variant.
314
+ const flagsOffset = /^\d+$/.test(fields[0] ?? '') ? 0 : 1;
315
+ const brs = fields[flagsOffset];
316
+ const esi = fields[flagsOffset + 1];
317
+ const dlc = fields[flagsOffset + 2];
318
+ const dataLengthText = fields[flagsOffset + 3];
319
+ const dataLength = /^\d+$/.test(dataLengthText ?? '') ? Number(dataLengthText) : -1;
320
+ if (/^[01]$/.test(brs ?? '') && /^[01]$/.test(esi ?? '') && /^[0-9A-Fa-f]+$/.test(dlc ?? '') && dataLength >= 0 && dataLength <= 64) {
321
+ const dataStart = flagsOffset + 4;
322
+ return {
323
+ time: canFd[1] ?? '-', type: 'CANFD', channel: canFd[2] ?? '-', direction: canFd[3] ?? '-',
324
+ id: canFd[4] ?? '-', dlc: dlc ?? '-', data: fields.slice(dataStart, dataStart + dataLength).join(' '), line: lineNumber
325
+ };
326
+ }
327
+ }
328
+ const classic = /^(\d+(?:\.\d+)?)\s+(\S+)\s+((?:0x)?[0-9A-Fa-f]+x?)\s+(Rx|Tx)\s+d\s+(\d+)\s*(.*)$/i.exec(line);
329
+ return classic ? {
330
+ time: classic[1] ?? '-', type: 'CAN', channel: classic[2] ?? '-', direction: classic[4] ?? '-',
331
+ id: classic[3] ?? '-', dlc: classic[5] ?? '-', data: classic[6]?.trim() ?? '', line: lineNumber
332
+ } : null;
333
+ }
334
+ export function parseBlf(data) {
335
+ const signature = ascii(data.subarray(0, 4));
336
+ const headerSize = data.length >= 8 ? view(data).getUint32(4, true) : 0;
337
+ const applicationId = data.length >= 9 ? data[8] ?? 0 : 0;
338
+ const objectCount = data.length >= 36 ? view(data).getUint32(32, true) : 0;
339
+ return { format: 'BLF', title: 'Vector Binary Logging Format', fileSizeBytes: data.byteLength,
340
+ summary: [{ label: 'Signature', value: signature || '-' }, { label: 'Header size', value: headerSize }, { label: 'Application ID', value: applicationId }, { label: 'Object count hint', value: objectCount || '-' }],
341
+ tables: [{ title: 'Header preview', headers: ['Offset', 'Hex', 'ASCII'], rows: hexRows(data, 0, Math.min(data.length, 256)) }],
342
+ warnings: [...(signature === 'LOGG' ? [] : ['The file does not start with the expected BLF LOGG signature.']), ...(signature === 'LOGG' && data.length < 144 ? ['The BLF file header is truncated.'] : [])] };
343
+ }
344
+ export function parseMf4(data) {
345
+ const magic = ascii(data.subarray(0, 8)).replace(/\0/g, '').trim();
346
+ const version = ascii(data.subarray(8, 16)).replace(/\0/g, '').trim();
347
+ const program = ascii(data.subarray(16, 24)).replace(/\0/g, '').trim();
348
+ const scan = data.subarray(0, BINARY_SCAN_LIMIT);
349
+ const markers = ['##HD', '##DG', '##CG', '##CN', '##CC', '##DT', '##DZ', '##TX', '##MD'];
350
+ const rows = markers.map(marker => [marker, countBytes(scan, [...marker].map(c => c.charCodeAt(0)))]).filter(row => Number(row[1]) > 0);
351
+ return { format: 'MF4', title: 'ASAM MDF 4 measurement data', fileSizeBytes: data.byteLength,
352
+ summary: [{ label: 'Magic', value: magic || '-' }, { label: 'Version', value: version || '-' }, { label: 'Program ID', value: program || '-' }, { label: 'Known block markers', value: rows.reduce((n, r) => n + Number(r[1]), 0) }],
353
+ tables: [{ title: 'MDF block markers', headers: ['Block', 'Count'], rows }, { title: 'Header preview', headers: ['Offset', 'Hex', 'ASCII'], rows: hexRows(data, 0, Math.min(data.length, 256)) }],
354
+ warnings: [...(!/^MDF/i.test(magic) ? ['The file does not start with an MDF identification block.'] : []), ...(/^MDF/i.test(magic) && data.length < 64 ? ['The MDF identification/header block is truncated.'] : []), ...(data.length > scan.length ? ['MDF marker scan is limited to the first 8 MiB.'] : [])] };
355
+ }
356
+ export function parsePcap(data) {
357
+ const magic = data.length >= 4 ? view(data).getUint32(0, false) : 0;
358
+ const little = magic === 0xd4c3b2a1 || magic === 0x4d3cb2a1;
359
+ const valid = little || magic === 0xa1b2c3d4 || magic === 0xa1b23c4d;
360
+ const nanos = magic === 0x4d3cb2a1 || magic === 0xa1b23c4d;
361
+ const linkType = data.length >= 24 ? view(data).getUint32(20, little) : 0;
362
+ const rows = [];
363
+ let offset = 24;
364
+ let total = 0;
365
+ let malformed = valid && data.length < 24;
366
+ while (valid && offset + 16 <= data.length && total < ROW_LIMIT) {
367
+ const seconds = view(data).getUint32(offset, little);
368
+ const fraction = view(data).getUint32(offset + 4, little);
369
+ const captured = view(data).getUint32(offset + 8, little);
370
+ const original = view(data).getUint32(offset + 12, little);
371
+ if (captured > 64 * 1024 * 1024 || offset + 16 + captured > data.length) {
372
+ malformed = true;
373
+ break;
374
+ }
375
+ rows.push([total + 1, `${seconds}.${String(fraction).padStart(nanos ? 9 : 6, '0')}`, captured, original, packetPreview(data.subarray(offset + 16, offset + 16 + captured))]);
376
+ total++;
377
+ offset += 16 + captured;
378
+ }
379
+ return packetModel('PCAP', 'PCAP packet capture', data, valid, linkType, rows, malformed, total >= ROW_LIMIT);
380
+ }
381
+ export function parsePcapng(data) {
382
+ const valid = matchesBytes(data, 0, [0x0a, 0x0d, 0x0d, 0x0a]);
383
+ let little = true;
384
+ let offset = 0;
385
+ let total = 0;
386
+ let malformed = valid && data.length < 12;
387
+ const blocks = new Map();
388
+ const packets = [];
389
+ while (valid && offset + 12 <= data.length && total < ROW_LIMIT) {
390
+ // The SHB type is byte-order invariant. Its BOM selects the byte order
391
+ // for that section, including the SHB length itself. A later SHB may
392
+ // switch byte order again within the same file.
393
+ if (view(data).getUint32(offset, false) === 0x0a0d0d0a) {
394
+ const bom = view(data).getUint32(offset + 8, false);
395
+ if (bom === 0x1a2b3c4d)
396
+ little = false;
397
+ else if (bom === 0x4d3c2b1a)
398
+ little = true;
399
+ else {
400
+ malformed = true;
401
+ break;
402
+ }
403
+ }
404
+ const type = view(data).getUint32(offset, little);
405
+ const length = view(data).getUint32(offset + 4, little);
406
+ if (length < 12 || length % 4 !== 0 || offset + length > data.length) {
407
+ malformed = true;
408
+ break;
409
+ }
410
+ blocks.set(type, (blocks.get(type) ?? 0) + 1);
411
+ if (type === 6 && length >= 32) {
412
+ const captured = view(data).getUint32(offset + 20, little);
413
+ const original = view(data).getUint32(offset + 24, little);
414
+ const payloadStart = offset + 28;
415
+ packets.push([packets.length + 1, view(data).getUint32(offset + 8, little), captured, original, packetPreview(data.subarray(payloadStart, Math.min(payloadStart + captured, offset + length - 4)))]);
416
+ }
417
+ total++;
418
+ offset += length;
419
+ }
420
+ const model = packetModel('PCAPNG', 'PCAP Next Generation capture', data, valid, 0, packets, malformed, total >= ROW_LIMIT);
421
+ model.tables.unshift({ title: 'Block counts', headers: ['Block type', 'Count'], rows: [...blocks].map(([type, count]) => [`0x${type.toString(16).padStart(8, '0')}`, count]) });
422
+ return model;
423
+ }
424
+ function packetModel(format, title, data, valid, linkType, rows, malformed, limited) {
425
+ return { format, title, fileSizeBytes: data.byteLength,
426
+ summary: [{ label: 'Signature', value: valid ? format : '-' }, { label: 'Packets previewed', value: rows.length }, { label: 'Link type', value: linkType || '-' }, { label: 'Bytes', value: data.byteLength }],
427
+ tables: [{ title: 'Packets', headers: ['#', 'Timestamp / interface', 'Captured', 'Original', 'Payload preview'], rows }],
428
+ warnings: [...(!valid ? [`The file does not start with a valid ${format} signature.`] : []), ...(malformed ? ['Parsing stopped at a truncated or invalid block.'] : []), ...(limited ? [`Preview is limited to ${ROW_LIMIT.toLocaleString()} packets or blocks.`] : [])] };
429
+ }
430
+ function collectXmlChildText(source, parent, child, limit) {
431
+ const result = [];
432
+ const re = new RegExp(`<${parent}\\b[^>]*>[\\s\\S]*?<${child}\\b[^>]*>([\\s\\S]*?)<\\/${child}>`, 'gi');
433
+ let match;
434
+ while (result.length < limit && (match = re.exec(source)))
435
+ result.push(cleanXmlText(match[1] ?? ''));
436
+ return result;
437
+ }
438
+ function cleanXmlText(value) { return decodeXml(value.replace(/<[^>]*>/g, '').trim()); }
439
+ function packetPreview(data) { return [...data.subarray(0, 32)].map(x => x.toString(16).padStart(2, '0')).join(' '); }
440
+ function readAvroMetadata(data) {
441
+ const rows = [];
442
+ let offset = 4;
443
+ const maxOffset = Math.min(data.length, 64 * 1024);
444
+ try {
445
+ while (offset < maxOffset) {
446
+ const countResult = readAvroLong(data, offset);
447
+ offset = countResult.offset;
448
+ let count = countResult.value;
449
+ if (count === 0n)
450
+ break;
451
+ if (count < 0n) {
452
+ offset = readAvroLong(data, offset).offset;
453
+ count = -count;
454
+ }
455
+ if (count > 64n)
456
+ break;
457
+ for (let index = 0n; index < count && offset < maxOffset; index++) {
458
+ const key = readAvroBytes(data, offset);
459
+ offset = key.offset;
460
+ const value = readAvroBytes(data, offset);
461
+ offset = value.offset;
462
+ const keyText = utf8.decode(key.bytes);
463
+ rows.push([keyText, printableMetadataValue(keyText, value.bytes)]);
464
+ }
465
+ }
466
+ }
467
+ catch {
468
+ return rows;
469
+ }
470
+ return rows;
471
+ }
472
+ function readAvroLong(data, offset) {
473
+ let result = 0n;
474
+ let shift = 0n;
475
+ let cursor = offset;
476
+ while (cursor < data.length) {
477
+ const byte = data[cursor++];
478
+ if (byte === undefined)
479
+ break;
480
+ result |= BigInt(byte & 0x7f) << shift;
481
+ if ((byte & 0x80) === 0)
482
+ return { value: (result >> 1n) ^ -(result & 1n), offset: cursor };
483
+ shift += 7n;
484
+ if (shift > 63n)
485
+ break;
486
+ }
487
+ throw new Error('Invalid Avro long value.');
488
+ }
489
+ function readAvroBytes(data, offset) {
490
+ const lengthResult = readAvroLong(data, offset);
491
+ const length = Number(lengthResult.value);
492
+ if (!Number.isSafeInteger(length) || length < 0 || lengthResult.offset + length > data.length) {
493
+ throw new Error('Invalid Avro bytes value.');
494
+ }
495
+ return { bytes: data.subarray(lengthResult.offset, lengthResult.offset + length), offset: lengthResult.offset + length };
496
+ }
497
+ function printableMetadataValue(key, value) {
498
+ const text = utf8.decode(value);
499
+ if (key === 'avro.schema')
500
+ return compactJson(text);
501
+ return value.every(byte => (byte >= 32 && byte <= 126) || byte === 9 || byte === 10 || byte === 13) ? text : toHex(value);
502
+ }
503
+ function extractStepHeader(source) {
504
+ const description = matchStepHeaderValue(source, 'FILE_DESCRIPTION');
505
+ const nameFields = splitStepArguments(matchStepHeaderValue(source, 'FILE_NAME'));
506
+ return {
507
+ name: nameFields[0] ?? '', timestamp: nameFields[1] ?? '', author: nameFields[2] ?? '',
508
+ organization: nameFields[3] ?? '', preprocessor: nameFields[4] ?? '', originatingSystem: nameFields[5] ?? '',
509
+ authorization: nameFields[6] ?? description, schema: splitStepArguments(matchStepHeaderValue(source, 'FILE_SCHEMA')).join(', ')
510
+ };
511
+ }
512
+ function matchStepHeaderValue(source, keyword) {
513
+ return new RegExp(`${keyword}\\s*\\(([^;]*)\\);`, 'i').exec(source)?.[1]?.trim() ?? '';
514
+ }
515
+ function splitStepArguments(value) {
516
+ const args = [];
517
+ let current = '';
518
+ let inString = false;
519
+ let depth = 0;
520
+ for (const char of value) {
521
+ if (char === "'") {
522
+ inString = !inString;
523
+ continue;
524
+ }
525
+ if (!inString && char === '(') {
526
+ depth++;
527
+ continue;
528
+ }
529
+ if (!inString && char === ')') {
530
+ depth = Math.max(0, depth - 1);
531
+ continue;
532
+ }
533
+ if (!inString && depth === 0 && char === ',') {
534
+ args.push(cleanStepValue(current));
535
+ current = '';
536
+ continue;
537
+ }
538
+ current += char;
539
+ }
540
+ if (current.trim())
541
+ args.push(cleanStepValue(current));
542
+ return args;
543
+ }
544
+ function cleanStepValue(value) {
545
+ return value.replace(/^\s*\$?\s*|\s*$/g, '').replace(/^'(.*)'$/s, '$1').trim();
546
+ }
547
+ function collectStepEntities(source) {
548
+ const entities = [];
549
+ source.split(/\r?\n/).forEach((line, index) => {
550
+ const match = /^\s*#(\d+)\s*=\s*([A-Z0-9_]+)\s*\(/i.exec(line);
551
+ if (match?.[1] && match[2])
552
+ entities.push({ id: `#${match[1]}`, type: match[2].toUpperCase(), line: index + 1 });
553
+ });
554
+ return entities;
555
+ }
556
+ function extractReqifHeader(source) {
557
+ const match = /<REQ-IF-HEADER\b[^>]*>([\s\S]*?)<\/REQ-IF-HEADER>/i.exec(source);
558
+ const header = match?.[1] ?? '';
559
+ return {
560
+ title: extractFirstTagText(header, 'TITLE'), identifier: extractAttribute(match?.[0] ?? '', 'IDENTIFIER'),
561
+ sourceToolId: extractFirstTagText(header, 'SOURCE-TOOL-ID'), reqifToolId: extractFirstTagText(header, 'REQ-IF-TOOL-ID'),
562
+ creationTime: extractFirstTagText(header, 'CREATION-TIME'), comment: extractFirstTagText(header, 'COMMENT')
563
+ };
564
+ }
565
+ function collectReqifElements(source, tagPattern) {
566
+ const elements = [];
567
+ const pattern = new RegExp(`<(${tagPattern})(?!-)\\b([^>]*)>`, 'gi');
568
+ let match;
569
+ while ((match = pattern.exec(source))) {
570
+ elements.push({
571
+ type: match[1]?.toUpperCase() ?? '',
572
+ identifier: extractAttribute(match[2] ?? '', 'IDENTIFIER') || '-',
573
+ longName: decodeXml(extractAttribute(match[2] ?? '', 'LONG-NAME') || '-')
574
+ });
575
+ }
576
+ return elements;
577
+ }
578
+ function reqifRows(items, limit) {
579
+ return items.slice(0, limit).map(item => [item.identifier, item.longName, item.type]);
580
+ }
581
+ function extractFirstTagText(source, tagName) {
582
+ const value = new RegExp(`<${tagName}\\b[^>]*>([\\s\\S]*?)<\\/${tagName}>`, 'i').exec(source)?.[1];
583
+ return value ? decodeXml(value.trim()) : '';
584
+ }
585
+ function extractAttribute(source, name) {
586
+ return new RegExp(`\\b${name}="([^"]*)"`, 'i').exec(source)?.[1] ?? '';
587
+ }
588
+ function parseSqliteDatabase(data, pageSize) {
589
+ const warnings = [];
590
+ const schemaRecords = readSqliteTableRecords(data, pageSize, 1, 500, warnings);
591
+ const schema = schemaRecords.map(toSqliteSchemaEntry).filter((entry) => entry !== null);
592
+ const previews = schema
593
+ .filter(entry => entry.type === 'table' && entry.rootPage > 0 && !entry.name.startsWith('sqlite_'))
594
+ .slice(0, 12)
595
+ .map(entry => {
596
+ const columns = extractSqliteColumnNames(entry.sql);
597
+ const rows = readSqliteTableRecords(data, pageSize, entry.rootPage, 100, warnings);
598
+ return {
599
+ tableName: entry.name, columns,
600
+ rows: rows.map(row => ({ rowid: row.rowid, values: alignSqliteRowValues(columns, row) })),
601
+ truncated: rows.length >= 100
602
+ };
603
+ });
604
+ if (!schemaRecords.length)
605
+ warnings.push('Could not decode sqlite_master rows from page 1.');
606
+ previews.filter(item => item.truncated).forEach(item => warnings.push(`Table ${item.tableName} preview is limited to the first 100 rows.`));
607
+ return { schema, previews, warnings: [...new Set(warnings)] };
608
+ }
609
+ function toSqliteSchemaEntry(record) {
610
+ if (record.values.length < 5)
611
+ return null;
612
+ return {
613
+ type: String(record.values[0] ?? ''), name: String(record.values[1] ?? ''), tableName: String(record.values[2] ?? ''),
614
+ rootPage: Number(record.values[3]) || 0, sql: String(record.values[4] ?? '')
615
+ };
616
+ }
617
+ function readSqliteTableRecords(data, pageSize, rootPage, limit, warnings, visited = new Set()) {
618
+ if (rootPage <= 0 || visited.has(rootPage) || visited.size > 512)
619
+ return [];
620
+ visited.add(rootPage);
621
+ const page = getSqlitePage(data, pageSize, rootPage);
622
+ if (!page) {
623
+ warnings.push(`Could not read SQLite page ${rootPage}.`);
624
+ return [];
625
+ }
626
+ const headerOffset = rootPage === 1 ? 100 : 0;
627
+ if (page.length < headerOffset + 8) {
628
+ warnings.push(`SQLite page ${rootPage} is too small to contain a b-tree header.`);
629
+ return [];
630
+ }
631
+ const pageType = page[headerOffset];
632
+ const cellCount = readU16BE(page, headerOffset + 3);
633
+ const records = [];
634
+ if (pageType === 0x0d) {
635
+ for (let index = 0; index < cellCount && records.length < limit; index++) {
636
+ const pointerOffset = headerOffset + 8 + index * 2;
637
+ if (pointerOffset + 2 > page.length)
638
+ break;
639
+ const record = readSqliteTableLeafCell(data, page, pageSize, readU16BE(page, pointerOffset), rootPage, warnings);
640
+ if (record)
641
+ records.push(record);
642
+ }
643
+ return records;
644
+ }
645
+ if (pageType === 0x05) {
646
+ for (let index = 0; index < cellCount && records.length < limit; index++) {
647
+ const pointerOffset = headerOffset + 12 + index * 2;
648
+ if (pointerOffset + 2 > page.length)
649
+ break;
650
+ const cellOffset = readU16BE(page, pointerOffset);
651
+ if (cellOffset + 4 <= page.length) {
652
+ records.push(...readSqliteTableRecords(data, pageSize, readU32BE(page, cellOffset), limit - records.length, warnings, visited));
653
+ }
654
+ }
655
+ if (records.length < limit && headerOffset + 12 <= page.length) {
656
+ records.push(...readSqliteTableRecords(data, pageSize, readU32BE(page, headerOffset + 8), limit - records.length, warnings, visited));
657
+ }
658
+ return records;
659
+ }
660
+ warnings.push(`SQLite page ${rootPage} has unsupported b-tree page type 0x${(pageType ?? 0).toString(16)}.`);
661
+ return [];
662
+ }
663
+ function readSqliteTableLeafCell(data, page, pageSize, cellOffset, pageNumber, warnings) {
664
+ if (cellOffset <= 0 || cellOffset >= page.length)
665
+ return null;
666
+ try {
667
+ const payloadSize = readSqliteVarint(page, cellOffset);
668
+ const rowid = readSqliteVarint(page, payloadSize.offset);
669
+ const payload = readSqlitePayload(data, page, pageSize, rowid.offset, Number(payloadSize.value), warnings);
670
+ return { rowid: displaySqliteInteger(rowid.value), values: decodeSqliteRecord(payload) };
671
+ }
672
+ catch {
673
+ warnings.push(`Could not decode SQLite table cell on page ${pageNumber} at offset 0x${cellOffset.toString(16)}.`);
674
+ return null;
675
+ }
676
+ }
677
+ function readSqlitePayload(data, page, pageSize, payloadStart, payloadSize, warnings) {
678
+ if (payloadSize <= 0)
679
+ return new Uint8Array();
680
+ const maxLocal = pageSize - 35;
681
+ let localSize = payloadSize;
682
+ let overflowPointerOffset = -1;
683
+ if (payloadSize > maxLocal) {
684
+ const minLocal = Math.floor((pageSize - 12) * 32 / 255) - 23;
685
+ localSize = minLocal + (payloadSize - minLocal) % (pageSize - 4);
686
+ if (localSize > maxLocal)
687
+ localSize = minLocal;
688
+ overflowPointerOffset = payloadStart + localSize;
689
+ }
690
+ const chunks = [page.subarray(payloadStart, Math.min(payloadStart + localSize, page.length))];
691
+ if (overflowPointerOffset >= 0 && overflowPointerOffset + 4 <= page.length) {
692
+ let nextPage = readU32BE(page, overflowPointerOffset);
693
+ let remaining = payloadSize - localSize;
694
+ let guard = 0;
695
+ while (nextPage > 0 && remaining > 0 && guard++ < 256) {
696
+ const overflow = getSqlitePage(data, pageSize, nextPage);
697
+ if (!overflow || overflow.length < 4) {
698
+ warnings.push(`SQLite overflow page ${nextPage} could not be read.`);
699
+ break;
700
+ }
701
+ nextPage = readU32BE(overflow, 0);
702
+ const chunk = overflow.subarray(4, Math.min(4 + remaining, overflow.length));
703
+ chunks.push(chunk);
704
+ remaining -= chunk.length;
705
+ }
706
+ if (remaining > 0)
707
+ warnings.push('A SQLite record uses overflow pages that could not be fully reconstructed.');
708
+ }
709
+ return concatBytes(chunks, payloadSize);
710
+ }
711
+ function decodeSqliteRecord(payload) {
712
+ if (!payload.length)
713
+ return [];
714
+ const header = readSqliteVarint(payload, 0);
715
+ const headerSize = Number(header.value);
716
+ const serialTypes = [];
717
+ let cursor = header.offset;
718
+ while (cursor < headerSize && cursor < payload.length) {
719
+ const serial = readSqliteVarint(payload, cursor);
720
+ serialTypes.push(serial.value);
721
+ cursor = serial.offset;
722
+ }
723
+ let bodyOffset = headerSize;
724
+ return serialTypes.map(serialType => {
725
+ const decoded = decodeSqliteValue(payload, bodyOffset, serialType);
726
+ bodyOffset += decoded.bytesRead;
727
+ return decoded.value;
728
+ });
729
+ }
730
+ function decodeSqliteValue(payload, offset, serialType) {
731
+ const type = Number(serialType);
732
+ const requireBytes = (count) => { if (offset < 0 || offset + count > payload.length)
733
+ throw new Error('SQLite value exceeds payload.'); };
734
+ switch (type) {
735
+ case 0: return { value: 'NULL', bytesRead: 0 };
736
+ case 1:
737
+ requireBytes(1);
738
+ return { value: view(payload).getInt8(offset), bytesRead: 1 };
739
+ case 2:
740
+ requireBytes(2);
741
+ return { value: view(payload).getInt16(offset), bytesRead: 2 };
742
+ case 3:
743
+ requireBytes(3);
744
+ return { value: readSignedInteger(payload, offset, 3), bytesRead: 3 };
745
+ case 4:
746
+ requireBytes(4);
747
+ return { value: view(payload).getInt32(offset), bytesRead: 4 };
748
+ case 5:
749
+ requireBytes(6);
750
+ return { value: readSignedInteger(payload, offset, 6), bytesRead: 6 };
751
+ case 6:
752
+ requireBytes(8);
753
+ return { value: displaySqliteInteger(view(payload).getBigInt64(offset)), bytesRead: 8 };
754
+ case 7:
755
+ requireBytes(8);
756
+ return { value: view(payload).getFloat64(offset), bytesRead: 8 };
757
+ case 8: return { value: 0, bytesRead: 0 };
758
+ case 9: return { value: 1, bytesRead: 0 };
759
+ default: {
760
+ if (type < 12)
761
+ return { value: `reserved(${type})`, bytesRead: 0 };
762
+ const length = type % 2 === 0 ? (type - 12) / 2 : (type - 13) / 2;
763
+ requireBytes(length);
764
+ const bytes = payload.subarray(offset, offset + length);
765
+ return type % 2 === 0
766
+ ? { value: `BLOB(${length} bytes) ${toHex(bytes.subarray(0, 24))}${length > 24 ? '...' : ''}`, bytesRead: length }
767
+ : { value: utf8.decode(bytes), bytesRead: length };
768
+ }
769
+ }
770
+ }
771
+ function readSqliteVarint(data, offset) {
772
+ let value = 0n;
773
+ for (let index = 0; index < 9; index++) {
774
+ const byte = data[offset + index];
775
+ if (byte === undefined)
776
+ throw new Error('SQLite varint exceeds buffer bounds.');
777
+ if (index === 8)
778
+ return { value: (value << 8n) | BigInt(byte), offset: offset + 9 };
779
+ value = (value << 7n) | BigInt(byte & 0x7f);
780
+ if ((byte & 0x80) === 0)
781
+ return { value, offset: offset + index + 1 };
782
+ }
783
+ throw new Error('Invalid SQLite varint.');
784
+ }
785
+ function readSignedInteger(data, offset, byteLength) {
786
+ let value = 0n;
787
+ for (let index = 0; index < byteLength; index++)
788
+ value = (value << 8n) | BigInt(data[offset + index] ?? 0);
789
+ const signBit = 1n << BigInt(byteLength * 8 - 1);
790
+ if ((value & signBit) !== 0n)
791
+ value -= 1n << BigInt(byteLength * 8);
792
+ return Number(value);
793
+ }
794
+ function displaySqliteInteger(value) {
795
+ return value > BigInt(Number.MAX_SAFE_INTEGER) || value < BigInt(Number.MIN_SAFE_INTEGER) ? value.toString() : Number(value);
796
+ }
797
+ function extractSqliteColumnNames(sql) {
798
+ const open = sql.indexOf('(');
799
+ const close = sql.lastIndexOf(')');
800
+ if (open < 0 || close <= open)
801
+ return [];
802
+ return splitSqliteDefinitions(sql.slice(open + 1, close)).map(extractSqliteColumnName).filter((name) => Boolean(name));
803
+ }
804
+ function splitSqliteDefinitions(source) {
805
+ const values = [];
806
+ let current = '';
807
+ let depth = 0;
808
+ let quote = null;
809
+ for (const char of source) {
810
+ if (quote) {
811
+ current += char;
812
+ if (char === quote)
813
+ quote = null;
814
+ continue;
815
+ }
816
+ if (char === "'" || char === '"' || char === '`' || char === '[') {
817
+ quote = char === '[' ? ']' : char;
818
+ current += char;
819
+ continue;
820
+ }
821
+ if (char === '(')
822
+ depth++;
823
+ else if (char === ')')
824
+ depth = Math.max(0, depth - 1);
825
+ else if (char === ',' && depth === 0) {
826
+ values.push(current.trim());
827
+ current = '';
828
+ continue;
829
+ }
830
+ current += char;
831
+ }
832
+ if (current.trim())
833
+ values.push(current.trim());
834
+ return values;
835
+ }
836
+ function extractSqliteColumnName(definition) {
837
+ const trimmed = definition.trim();
838
+ if (!trimmed || /^(CONSTRAINT|PRIMARY|FOREIGN|UNIQUE|CHECK|KEY)\b/i.test(trimmed))
839
+ return null;
840
+ const quoted = /^"([^"]+)"|^`([^`]+)`|^\[([^\]]+)\]|^'([^']+)'/.exec(trimmed);
841
+ return quoted ? quoted[1] ?? quoted[2] ?? quoted[3] ?? quoted[4] ?? null : /^([^\s,]+)/.exec(trimmed)?.[1] ?? null;
842
+ }
843
+ function alignSqliteRowValues(columns, row) {
844
+ const values = [...row.values];
845
+ if (values.length < columns.length)
846
+ values.push(...Array(columns.length - values.length).fill(''));
847
+ return values.slice(0, Math.max(columns.length, values.length));
848
+ }
849
+ function readSqlitePageSize(data) {
850
+ const size = readU16BE(data, 16);
851
+ return size === 1 ? 65_536 : size;
852
+ }
853
+ function extractSqliteSchemaHints(data) {
854
+ const text = latin1.decode(data.subarray(0, Math.min(data.length, 1024 * 1024)));
855
+ return (text.match(/CREATE\s+(?:TABLE|INDEX|VIEW|TRIGGER)[\s\S]{0,400}?(?=\0|$)/gi) ?? [])
856
+ .map(value => value.replace(/[^\x20-\x7e]+/g, ' ').replace(/\s+/g, ' ').trim()).filter(Boolean).slice(0, 100);
857
+ }
858
+ function getSqlitePage(data, pageSize, pageNumber) {
859
+ const offset = (pageNumber - 1) * pageSize;
860
+ return pageNumber > 0 && offset >= 0 && offset < data.length ? data.subarray(offset, Math.min(offset + pageSize, data.length)) : null;
861
+ }
862
+ function view(data) {
863
+ return new DataView(data.buffer, data.byteOffset, data.byteLength);
864
+ }
865
+ function readU16BE(data, offset) {
866
+ if (offset < 0 || offset + 2 > data.length)
867
+ throw new Error('Read exceeds buffer bounds.');
868
+ return view(data).getUint16(offset);
869
+ }
870
+ function readU32BE(data, offset) {
871
+ if (offset < 0 || offset + 4 > data.length)
872
+ throw new Error('Read exceeds buffer bounds.');
873
+ return view(data).getUint32(offset);
874
+ }
875
+ function concatBytes(chunks, limit) {
876
+ const length = Math.min(limit, chunks.reduce((sum, chunk) => sum + chunk.length, 0));
877
+ const result = new Uint8Array(length);
878
+ let offset = 0;
879
+ for (const chunk of chunks) {
880
+ const next = chunk.subarray(0, Math.min(chunk.length, length - offset));
881
+ result.set(next, offset);
882
+ offset += next.length;
883
+ if (offset >= length)
884
+ break;
885
+ }
886
+ return result;
887
+ }
888
+ function hexRows(data, start, end) {
889
+ const rows = [];
890
+ for (let offset = start; offset < end; offset += 16) {
891
+ const bytes = data.subarray(offset, Math.min(offset + 16, end));
892
+ rows.push([
893
+ `0x${offset.toString(16).padStart(8, '0')}`,
894
+ [...bytes].map(byte => byte.toString(16).padStart(2, '0')).join(' '),
895
+ [...bytes].map(byte => byte >= 32 && byte <= 126 ? String.fromCharCode(byte) : '.').join('')
896
+ ]);
897
+ }
898
+ return rows;
899
+ }
900
+ function firstAsciiLine(data) {
901
+ const newline = data.indexOf(0x0a);
902
+ return ascii(data.subarray(0, newline < 0 ? Math.min(data.length, 256) : newline)).trim();
903
+ }
904
+ function countBagOperations(data) {
905
+ const counts = { bagHeader: 0, chunk: 0, connection: 0, indexData: 0, chunkInfo: 0, messageData: 0 };
906
+ for (let offset = 0; offset + 3 < data.length; offset++) {
907
+ if (data[offset] !== 0x6f || data[offset + 1] !== 0x70 || data[offset + 2] !== 0x3d)
908
+ continue;
909
+ switch (data[offset + 3]) {
910
+ case 0x02:
911
+ counts.messageData++;
912
+ break;
913
+ case 0x03:
914
+ counts.bagHeader++;
915
+ break;
916
+ case 0x04:
917
+ counts.indexData++;
918
+ break;
919
+ case 0x05:
920
+ counts.chunk++;
921
+ break;
922
+ case 0x06:
923
+ counts.chunkInfo++;
924
+ break;
925
+ case 0x07:
926
+ counts.connection++;
927
+ break;
928
+ }
929
+ offset += 3;
930
+ }
931
+ return counts;
932
+ }
933
+ function countBytes(data, needle) {
934
+ let count = 0;
935
+ for (let offset = 0; offset <= data.length - needle.length; offset++) {
936
+ if (matchesBytes(data, offset, needle)) {
937
+ count++;
938
+ offset += needle.length - 1;
939
+ }
940
+ }
941
+ return count;
942
+ }
943
+ function matchesBytes(data, offset, expected) {
944
+ return offset >= 0 && offset + expected.length <= data.length && expected.every((byte, index) => data[offset + index] === byte);
945
+ }
946
+ function ascii(data) {
947
+ return [...data].map(byte => String.fromCharCode(byte)).join('');
948
+ }
949
+ function toHex(data) {
950
+ return [...data].map(byte => byte.toString(16).padStart(2, '0')).join('');
951
+ }
952
+ function compactJson(value) {
953
+ try {
954
+ return JSON.stringify(JSON.parse(value));
955
+ }
956
+ catch {
957
+ return value;
958
+ }
959
+ }
960
+ function prettyJson(value) {
961
+ try {
962
+ return JSON.stringify(JSON.parse(value), null, 2);
963
+ }
964
+ catch {
965
+ return value;
966
+ }
967
+ }
968
+ function preview(source) {
969
+ return source.length > 200_000 ? `${source.slice(0, 200_000)}\n\n[Preview truncated]` : source;
970
+ }
971
+ function decodeXml(value) {
972
+ return value.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&amp;/g, '&');
973
+ }