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.
- package/LICENSE +21 -0
- package/README.md +80 -0
- package/THIRD_PARTY_NOTICES.md +49 -0
- package/dist/assets/audio-engine/audio_engine.mjs +2 -0
- package/dist/assets/audio-engine/audio_engine.wasm +0 -0
- package/dist/assets/pdfjs/pdf.worker.min.mjs +21 -0
- package/dist/host/index.d.ts +133 -0
- package/dist/host/index.js +10 -0
- package/dist/i18n/catalog.en.d.ts +1 -0
- package/dist/i18n/catalog.en.js +411 -0
- package/dist/i18n/catalog.ko.d.ts +1 -0
- package/dist/i18n/catalog.ko.js +68 -0
- package/dist/i18n/index.d.ts +18 -0
- package/dist/i18n/index.js +41 -0
- package/dist/licenses/emscripten.txt +101 -0
- package/dist/licenses/kissfft.txt +28 -0
- package/dist/licenses/pdfjs-dist.txt +177 -0
- package/dist/parsers/a2l/index.d.ts +1 -0
- package/dist/parsers/a2l/index.js +1 -0
- package/dist/parsers/archive/index.d.ts +22 -0
- package/dist/parsers/archive/index.js +46 -0
- package/dist/parsers/archive/model.d.ts +29 -0
- package/dist/parsers/archive/model.js +1 -0
- package/dist/parsers/archive/worker.d.ts +21 -0
- package/dist/parsers/archive/worker.js +1 -0
- package/dist/parsers/arxml/index.d.ts +1 -0
- package/dist/parsers/arxml/index.js +1 -0
- package/dist/parsers/asc/index.d.ts +1 -0
- package/dist/parsers/asc/index.js +1 -0
- package/dist/parsers/audio/index.d.ts +9 -0
- package/dist/parsers/audio/index.js +46 -0
- package/dist/parsers/automotive/index.d.ts +33 -0
- package/dist/parsers/automotive/index.js +973 -0
- package/dist/parsers/blf/index.d.ts +1 -0
- package/dist/parsers/blf/index.js +1 -0
- package/dist/parsers/csv/delimiter.d.ts +31 -0
- package/dist/parsers/csv/delimiter.js +151 -0
- package/dist/parsers/csv/index.d.ts +30 -0
- package/dist/parsers/csv/index.js +108 -0
- package/dist/parsers/csv/parseText.d.ts +20 -0
- package/dist/parsers/csv/parseText.js +108 -0
- package/dist/parsers/csv/sort.d.ts +26 -0
- package/dist/parsers/csv/sort.js +224 -0
- package/dist/parsers/csv/statistics.d.ts +49 -0
- package/dist/parsers/csv/statistics.js +150 -0
- package/dist/parsers/dbc/index.d.ts +56 -0
- package/dist/parsers/dbc/index.js +94 -0
- package/dist/parsers/doc-binary/index.d.ts +35 -0
- package/dist/parsers/doc-binary/index.js +267 -0
- package/dist/parsers/doc-binary/vscode-parser.d.ts +142 -0
- package/dist/parsers/doc-binary/vscode-parser.js +3747 -0
- package/dist/parsers/excel/index.d.ts +17 -0
- package/dist/parsers/excel/index.js +406 -0
- package/dist/parsers/excel/model.d.ts +80 -0
- package/dist/parsers/excel/model.js +48 -0
- package/dist/parsers/excel/serialize.d.ts +3 -0
- package/dist/parsers/excel/serialize.js +78 -0
- package/dist/parsers/hdf5/index.d.ts +75 -0
- package/dist/parsers/hdf5/index.js +658 -0
- package/dist/parsers/hdf5/node.d.ts +21 -0
- package/dist/parsers/hdf5/node.js +95 -0
- package/dist/parsers/json/index.d.ts +15 -0
- package/dist/parsers/json/index.js +102 -0
- package/dist/parsers/json/model.d.ts +42 -0
- package/dist/parsers/json/model.js +140 -0
- package/dist/parsers/json/parse.d.ts +22 -0
- package/dist/parsers/json/parse.js +279 -0
- package/dist/parsers/json/tokenizer.d.ts +17 -0
- package/dist/parsers/json/tokenizer.js +175 -0
- package/dist/parsers/jsonl/index.d.ts +14 -0
- package/dist/parsers/jsonl/index.js +18 -0
- package/dist/parsers/jsonl/model.d.ts +23 -0
- package/dist/parsers/jsonl/model.js +1 -0
- package/dist/parsers/jsonl/parse.d.ts +7 -0
- package/dist/parsers/jsonl/parse.js +34 -0
- package/dist/parsers/markdown/index.d.ts +37 -0
- package/dist/parsers/markdown/index.js +59 -0
- package/dist/parsers/mat/index.d.ts +31 -0
- package/dist/parsers/mat/index.js +426 -0
- package/dist/parsers/mermaid/index.d.ts +5 -0
- package/dist/parsers/mermaid/index.js +3 -0
- package/dist/parsers/mf4/index.d.ts +1 -0
- package/dist/parsers/mf4/index.js +1 -0
- package/dist/parsers/parquet/index.d.ts +21 -0
- package/dist/parsers/parquet/index.js +68 -0
- package/dist/parsers/pcap/index.d.ts +1 -0
- package/dist/parsers/pcap/index.js +1 -0
- package/dist/parsers/pcapng/index.d.ts +1 -0
- package/dist/parsers/pcapng/index.js +1 -0
- package/dist/parsers/plantuml/index.d.ts +5 -0
- package/dist/parsers/plantuml/index.js +4 -0
- package/dist/parsers/ppt-binary/index.d.ts +5 -0
- package/dist/parsers/ppt-binary/index.js +62 -0
- package/dist/parsers/ppt-binary/pptBinaryBuildContext.d.ts +12 -0
- package/dist/parsers/ppt-binary/pptBinaryBuildContext.js +40 -0
- package/dist/parsers/ppt-binary/pptBinaryContainer.d.ts +4 -0
- package/dist/parsers/ppt-binary/pptBinaryContainer.js +174 -0
- package/dist/parsers/ppt-binary/pptBinaryTypes.d.ts +125 -0
- package/dist/parsers/ppt-binary/pptBinaryTypes.js +1 -0
- package/dist/parsers/ppt-binary/pptSlideLayouts.d.ts +9 -0
- package/dist/parsers/ppt-binary/pptSlideLayouts.js +510 -0
- package/dist/parsers/ppt-binary/vscode-parser.d.ts +116 -0
- package/dist/parsers/ppt-binary/vscode-parser.js +2853 -0
- package/dist/parsers/ppt-binary/vscode.d.ts +4 -0
- package/dist/parsers/ppt-binary/vscode.js +12 -0
- package/dist/parsers/pptx/index.d.ts +15 -0
- package/dist/parsers/pptx/index.js +88 -0
- package/dist/parsers/pptx/vscode-parser.d.ts +167 -0
- package/dist/parsers/pptx/vscode-parser.js +1503 -0
- package/dist/parsers/pptx/vscode.d.ts +4 -0
- package/dist/parsers/pptx/vscode.js +18 -0
- package/dist/parsers/pptx/zip-reader.d.ts +3 -0
- package/dist/parsers/pptx/zip-reader.js +20 -0
- package/dist/parsers/proto/index.d.ts +90 -0
- package/dist/parsers/proto/index.js +197 -0
- package/dist/parsers/psd/index.d.ts +16 -0
- package/dist/parsers/psd/index.js +10 -0
- package/dist/parsers/shapefile/dbf.d.ts +23 -0
- package/dist/parsers/shapefile/dbf.js +112 -0
- package/dist/parsers/shapefile/index.d.ts +44 -0
- package/dist/parsers/shapefile/index.js +119 -0
- package/dist/parsers/shapefile/reproject.d.ts +10 -0
- package/dist/parsers/shapefile/reproject.js +41 -0
- package/dist/parsers/slide-model.d.ts +106 -0
- package/dist/parsers/slide-model.js +1 -0
- package/dist/parsers/toml/index.d.ts +15 -0
- package/dist/parsers/toml/index.js +18 -0
- package/dist/parsers/toml/model.d.ts +15 -0
- package/dist/parsers/toml/model.js +1 -0
- package/dist/parsers/toml/parse.d.ts +16 -0
- package/dist/parsers/toml/parse.js +266 -0
- package/dist/parsers/types.d.ts +103 -0
- package/dist/parsers/types.js +106 -0
- package/dist/parsers/video/index.d.ts +6 -0
- package/dist/parsers/video/index.js +2 -0
- package/dist/parsers/yaml/index.d.ts +16 -0
- package/dist/parsers/yaml/index.js +58 -0
- package/dist/parsers/yaml/model.d.ts +22 -0
- package/dist/parsers/yaml/model.js +1 -0
- package/dist/parsers/yaml/self-loading.d.ts +3 -0
- package/dist/parsers/yaml/self-loading.js +19 -0
- package/dist/parsers/zip-scan.d.ts +8 -0
- package/dist/parsers/zip-scan.js +80 -0
- package/dist/registry/container.d.ts +17 -0
- package/dist/registry/container.js +49 -0
- package/dist/registry/index.d.ts +133 -0
- package/dist/registry/index.js +348 -0
- package/dist/registry/probe.d.ts +3 -0
- package/dist/registry/probe.js +177 -0
- package/dist/registry/sniff.d.ts +17 -0
- package/dist/registry/sniff.js +57 -0
- package/dist/styles/archive.css +10 -0
- package/dist/styles/audio.css +66 -0
- package/dist/styles/automotive.css +1 -0
- package/dist/styles/csv.css +262 -0
- package/dist/styles/excel.css +212 -0
- package/dist/styles/fallback.css +48 -0
- package/dist/styles/hdf5.css +3 -0
- package/dist/styles/hwp.css +12 -0
- package/dist/styles/image.css +115 -0
- package/dist/styles/json.css +342 -0
- package/dist/styles/jsonl.css +1 -0
- package/dist/styles/markdown.css +10 -0
- package/dist/styles/mat.css +2 -0
- package/dist/styles/mermaid.css +1 -0
- package/dist/styles/parquet.css +2 -0
- package/dist/styles/pdf.css +551 -0
- package/dist/styles/plantuml.css +1 -0
- package/dist/styles/ppt.css +1 -0
- package/dist/styles/proto.css +2 -0
- package/dist/styles/psd.css +1 -0
- package/dist/styles/shapefile.css +25 -0
- package/dist/styles/toml.css +1 -0
- package/dist/styles/video.css +74 -0
- package/dist/styles/word.css +685 -0
- package/dist/styles/yaml.css +1 -0
- package/dist/viewers/a2l/index.d.ts +15 -0
- package/dist/viewers/a2l/index.js +5 -0
- package/dist/viewers/archive/archive-preview-decoder.d.ts +4 -0
- package/dist/viewers/archive/archive-preview-decoder.js +223 -0
- package/dist/viewers/archive/controller.d.ts +24 -0
- package/dist/viewers/archive/controller.js +18 -0
- package/dist/viewers/archive/index.d.ts +25 -0
- package/dist/viewers/archive/index.js +230 -0
- package/dist/viewers/archive/preview.d.ts +2 -0
- package/dist/viewers/archive/preview.js +2 -0
- package/dist/viewers/archive/styles.d.ts +1 -0
- package/dist/viewers/archive/styles.js +11 -0
- package/dist/viewers/arxml/index.d.ts +15 -0
- package/dist/viewers/arxml/index.js +5 -0
- package/dist/viewers/asc/index.d.ts +15 -0
- package/dist/viewers/asc/index.js +5 -0
- package/dist/viewers/audio/controller.d.ts +33 -0
- package/dist/viewers/audio/controller.js +49 -0
- package/dist/viewers/audio/engine.d.ts +44 -0
- package/dist/viewers/audio/engine.js +108 -0
- package/dist/viewers/audio/index.d.ts +92 -0
- package/dist/viewers/audio/index.js +448 -0
- package/dist/viewers/audio/self-loading.d.ts +7 -0
- package/dist/viewers/audio/self-loading.js +42 -0
- package/dist/viewers/audio/styles.d.ts +1 -0
- package/dist/viewers/audio/styles.js +73 -0
- package/dist/viewers/automotive/index.d.ts +8 -0
- package/dist/viewers/automotive/index.js +152 -0
- package/dist/viewers/automotive/styles.d.ts +1 -0
- package/dist/viewers/automotive/styles.js +1 -0
- package/dist/viewers/avro/index.d.ts +15 -0
- package/dist/viewers/avro/index.js +5 -0
- package/dist/viewers/bag/index.d.ts +15 -0
- package/dist/viewers/bag/index.js +5 -0
- package/dist/viewers/blf/index.d.ts +15 -0
- package/dist/viewers/blf/index.js +5 -0
- package/dist/viewers/csv/controller.d.ts +126 -0
- package/dist/viewers/csv/controller.js +598 -0
- package/dist/viewers/csv/index.d.ts +48 -0
- package/dist/viewers/csv/index.js +846 -0
- package/dist/viewers/csv/styles.d.ts +1 -0
- package/dist/viewers/csv/styles.js +267 -0
- package/dist/viewers/db3/index.d.ts +15 -0
- package/dist/viewers/db3/index.js +5 -0
- package/dist/viewers/dbc/index.d.ts +15 -0
- package/dist/viewers/dbc/index.js +5 -0
- package/dist/viewers/diagram.d.ts +14 -0
- package/dist/viewers/diagram.js +95 -0
- package/dist/viewers/excel/controller.d.ts +108 -0
- package/dist/viewers/excel/controller.js +548 -0
- package/dist/viewers/excel/grid.d.ts +28 -0
- package/dist/viewers/excel/grid.js +99 -0
- package/dist/viewers/excel/index.d.ts +37 -0
- package/dist/viewers/excel/index.js +620 -0
- package/dist/viewers/excel/self-loading.d.ts +6 -0
- package/dist/viewers/excel/self-loading.js +13 -0
- package/dist/viewers/excel/styles.d.ts +1 -0
- package/dist/viewers/excel/styles.js +216 -0
- package/dist/viewers/fallback/index.d.ts +17 -0
- package/dist/viewers/fallback/index.js +130 -0
- package/dist/viewers/fallback/styles.d.ts +1 -0
- package/dist/viewers/fallback/styles.js +49 -0
- package/dist/viewers/hdf5/index.d.ts +19 -0
- package/dist/viewers/hdf5/index.js +170 -0
- package/dist/viewers/hdf5/styles.d.ts +1 -0
- package/dist/viewers/hdf5/styles.js +4 -0
- package/dist/viewers/hwp/controller.d.ts +19 -0
- package/dist/viewers/hwp/controller.js +22 -0
- package/dist/viewers/hwp/index.d.ts +39 -0
- package/dist/viewers/hwp/index.js +271 -0
- package/dist/viewers/hwp/self-loading.d.ts +2 -0
- package/dist/viewers/hwp/self-loading.js +6 -0
- package/dist/viewers/hwp/styles.d.ts +1 -0
- package/dist/viewers/hwp/styles.js +13 -0
- package/dist/viewers/image/controller.d.ts +210 -0
- package/dist/viewers/image/controller.js +336 -0
- package/dist/viewers/image/decode.d.ts +54 -0
- package/dist/viewers/image/decode.js +150 -0
- package/dist/viewers/image/index.d.ts +38 -0
- package/dist/viewers/image/index.js +749 -0
- package/dist/viewers/image/limits.d.ts +18 -0
- package/dist/viewers/image/limits.js +20 -0
- package/dist/viewers/image/styles.d.ts +1 -0
- package/dist/viewers/image/styles.js +119 -0
- package/dist/viewers/json/controller.d.ts +89 -0
- package/dist/viewers/json/controller.js +411 -0
- package/dist/viewers/json/index.d.ts +25 -0
- package/dist/viewers/json/index.js +503 -0
- package/dist/viewers/json/styles.d.ts +1 -0
- package/dist/viewers/json/styles.js +346 -0
- package/dist/viewers/json/transforms.d.ts +27 -0
- package/dist/viewers/json/transforms.js +253 -0
- package/dist/viewers/jsonl/controller.d.ts +48 -0
- package/dist/viewers/jsonl/controller.js +136 -0
- package/dist/viewers/jsonl/index.d.ts +22 -0
- package/dist/viewers/jsonl/index.js +184 -0
- package/dist/viewers/jsonl/styles.d.ts +1 -0
- package/dist/viewers/jsonl/styles.js +1 -0
- package/dist/viewers/markdown/controller.d.ts +50 -0
- package/dist/viewers/markdown/controller.js +62 -0
- package/dist/viewers/markdown/index.d.ts +64 -0
- package/dist/viewers/markdown/index.js +425 -0
- package/dist/viewers/markdown/math.d.ts +21 -0
- package/dist/viewers/markdown/math.js +100 -0
- package/dist/viewers/markdown/self-loading.d.ts +5 -0
- package/dist/viewers/markdown/self-loading.js +48 -0
- package/dist/viewers/markdown/styles.d.ts +1 -0
- package/dist/viewers/markdown/styles.js +11 -0
- package/dist/viewers/mat/index.d.ts +19 -0
- package/dist/viewers/mat/index.js +113 -0
- package/dist/viewers/mat/styles.d.ts +1 -0
- package/dist/viewers/mat/styles.js +3 -0
- package/dist/viewers/media.d.ts +9 -0
- package/dist/viewers/media.js +77 -0
- package/dist/viewers/mermaid/index.d.ts +17 -0
- package/dist/viewers/mermaid/index.js +6 -0
- package/dist/viewers/mermaid/self-loading.d.ts +2 -0
- package/dist/viewers/mermaid/self-loading.js +2 -0
- package/dist/viewers/mf4/index.d.ts +15 -0
- package/dist/viewers/mf4/index.js +5 -0
- package/dist/viewers/parquet/controller.d.ts +37 -0
- package/dist/viewers/parquet/controller.js +26 -0
- package/dist/viewers/parquet/index.d.ts +23 -0
- package/dist/viewers/parquet/index.js +134 -0
- package/dist/viewers/parquet/styles.d.ts +1 -0
- package/dist/viewers/parquet/styles.js +3 -0
- package/dist/viewers/pcap/index.d.ts +15 -0
- package/dist/viewers/pcap/index.js +5 -0
- package/dist/viewers/pcapng/index.d.ts +15 -0
- package/dist/viewers/pcapng/index.js +5 -0
- package/dist/viewers/pdf/controller.d.ts +120 -0
- package/dist/viewers/pdf/controller.js +191 -0
- package/dist/viewers/pdf/editing.d.ts +26 -0
- package/dist/viewers/pdf/editing.js +265 -0
- package/dist/viewers/pdf/index.d.ts +88 -0
- package/dist/viewers/pdf/index.js +1400 -0
- package/dist/viewers/pdf/self-loading.d.ts +6 -0
- package/dist/viewers/pdf/self-loading.js +14 -0
- package/dist/viewers/pdf/styles.d.ts +1 -0
- package/dist/viewers/pdf/styles.js +555 -0
- package/dist/viewers/plantuml/index.d.ts +17 -0
- package/dist/viewers/plantuml/index.js +6 -0
- package/dist/viewers/plantuml/self-loading.d.ts +2 -0
- package/dist/viewers/plantuml/self-loading.js +2 -0
- package/dist/viewers/ppt/chart.d.ts +8 -0
- package/dist/viewers/ppt/chart.js +83 -0
- package/dist/viewers/ppt/controller.d.ts +34 -0
- package/dist/viewers/ppt/controller.js +27 -0
- package/dist/viewers/ppt/index.d.ts +33 -0
- package/dist/viewers/ppt/index.js +101 -0
- package/dist/viewers/ppt/render.d.ts +5 -0
- package/dist/viewers/ppt/render.js +144 -0
- package/dist/viewers/ppt/self-loading.d.ts +9 -0
- package/dist/viewers/ppt/self-loading.js +4 -0
- package/dist/viewers/ppt/styles.d.ts +1 -0
- package/dist/viewers/ppt/styles.js +1 -0
- package/dist/viewers/proto/index.d.ts +17 -0
- package/dist/viewers/proto/index.js +170 -0
- package/dist/viewers/proto/styles.d.ts +1 -0
- package/dist/viewers/proto/styles.js +2 -0
- package/dist/viewers/psd/index.d.ts +27 -0
- package/dist/viewers/psd/index.js +39 -0
- package/dist/viewers/psd/self-loading.d.ts +10 -0
- package/dist/viewers/psd/self-loading.js +20 -0
- package/dist/viewers/psd/styles.d.ts +1 -0
- package/dist/viewers/psd/styles.js +1 -0
- package/dist/viewers/reqif/index.d.ts +15 -0
- package/dist/viewers/reqif/index.js +5 -0
- package/dist/viewers/shapefile/index.d.ts +35 -0
- package/dist/viewers/shapefile/index.js +336 -0
- package/dist/viewers/shapefile/self-loading.d.ts +7 -0
- package/dist/viewers/shapefile/self-loading.js +32 -0
- package/dist/viewers/shapefile/styles.d.ts +1 -0
- package/dist/viewers/shapefile/styles.js +28 -0
- package/dist/viewers/stp/index.d.ts +15 -0
- package/dist/viewers/stp/index.js +5 -0
- package/dist/viewers/structured-styles.d.ts +1 -0
- package/dist/viewers/structured-styles.js +1 -0
- package/dist/viewers/structured.d.ts +36 -0
- package/dist/viewers/structured.js +138 -0
- package/dist/viewers/toml/controller.d.ts +38 -0
- package/dist/viewers/toml/controller.js +61 -0
- package/dist/viewers/toml/index.d.ts +18 -0
- package/dist/viewers/toml/index.js +34 -0
- package/dist/viewers/types.d.ts +36 -0
- package/dist/viewers/types.js +9 -0
- package/dist/viewers/video/controller.d.ts +29 -0
- package/dist/viewers/video/controller.js +54 -0
- package/dist/viewers/video/index.d.ts +18 -0
- package/dist/viewers/video/index.js +305 -0
- package/dist/viewers/video/styles.d.ts +1 -0
- package/dist/viewers/video/styles.js +79 -0
- package/dist/viewers/word/controller.d.ts +19 -0
- package/dist/viewers/word/controller.js +22 -0
- package/dist/viewers/word/docx-preprocess.d.ts +63 -0
- package/dist/viewers/word/docx-preprocess.js +136 -0
- package/dist/viewers/word/index.d.ts +32 -0
- package/dist/viewers/word/index.js +187 -0
- package/dist/viewers/word/normalize-docx.d.ts +2 -0
- package/dist/viewers/word/normalize-docx.js +50 -0
- package/dist/viewers/word/paginate.d.ts +1 -0
- package/dist/viewers/word/paginate.js +1035 -0
- package/dist/viewers/word/self-loading.d.ts +2 -0
- package/dist/viewers/word/self-loading.js +7 -0
- package/dist/viewers/word/styles.d.ts +1 -0
- package/dist/viewers/word/styles.js +686 -0
- package/dist/viewers/yaml/controller.d.ts +42 -0
- package/dist/viewers/yaml/controller.js +41 -0
- package/dist/viewers/yaml/index.d.ts +21 -0
- package/dist/viewers/yaml/index.js +20 -0
- package/package.json +375 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface MatVariable {
|
|
2
|
+
name: string;
|
|
3
|
+
className: string;
|
|
4
|
+
dimensions: number[];
|
|
5
|
+
dataType: string;
|
|
6
|
+
bytes: number;
|
|
7
|
+
preview: string;
|
|
8
|
+
attributes: string[];
|
|
9
|
+
}
|
|
10
|
+
export interface MatSummaryItem {
|
|
11
|
+
label: string;
|
|
12
|
+
value: string | number;
|
|
13
|
+
}
|
|
14
|
+
export interface MatTable {
|
|
15
|
+
title: string;
|
|
16
|
+
headers: string[];
|
|
17
|
+
rows: Array<Array<string | number>>;
|
|
18
|
+
}
|
|
19
|
+
export interface MatDocument {
|
|
20
|
+
format: 'MAT v4' | 'MAT v5/v6/v7' | 'MAT v7.3';
|
|
21
|
+
title: string;
|
|
22
|
+
fileSize: string;
|
|
23
|
+
summary: MatSummaryItem[];
|
|
24
|
+
tables: MatTable[];
|
|
25
|
+
variables: MatVariable[];
|
|
26
|
+
rawPreview?: string | undefined;
|
|
27
|
+
warnings: string[];
|
|
28
|
+
}
|
|
29
|
+
/** Parse MATLAB Level 4, Level 5 (v5/v6/v7), and HDF5-backed v7.3 files. */
|
|
30
|
+
export declare function parseMat(data: Uint8Array, fileSize?: string): Promise<MatDocument>;
|
|
31
|
+
export declare function isMatLevel5(data: Uint8Array): boolean;
|
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
import { Hdf5Parser } from '../hdf5/index.js';
|
|
2
|
+
const HDF5_SIGNATURE = [0x89, 0x48, 0x44, 0x46, 0x0d, 0x0a, 0x1a, 0x0a];
|
|
3
|
+
const MAT_V5_HEADER_BYTES = 128;
|
|
4
|
+
const MAX_VARIABLES = 5000;
|
|
5
|
+
const MAX_PREVIEW_VALUES = 24;
|
|
6
|
+
const MAX_DECOMPRESSED_BLOCK_BYTES = 256 * 1024 * 1024;
|
|
7
|
+
const MI_INT8 = 1;
|
|
8
|
+
const MI_UINT8 = 2;
|
|
9
|
+
const MI_INT16 = 3;
|
|
10
|
+
const MI_UINT16 = 4;
|
|
11
|
+
const MI_INT32 = 5;
|
|
12
|
+
const MI_UINT32 = 6;
|
|
13
|
+
const MI_SINGLE = 7;
|
|
14
|
+
const MI_DOUBLE = 9;
|
|
15
|
+
const MI_INT64 = 12;
|
|
16
|
+
const MI_UINT64 = 13;
|
|
17
|
+
const MI_MATRIX = 14;
|
|
18
|
+
const MI_COMPRESSED = 15;
|
|
19
|
+
const MI_UTF8 = 16;
|
|
20
|
+
const MI_UTF16 = 17;
|
|
21
|
+
const MI_UTF32 = 18;
|
|
22
|
+
const MX_CLASSES = {
|
|
23
|
+
1: 'cell', 2: 'struct', 3: 'object', 4: 'char', 5: 'sparse',
|
|
24
|
+
6: 'double', 7: 'single', 8: 'int8', 9: 'uint8', 10: 'int16',
|
|
25
|
+
11: 'uint16', 12: 'int32', 13: 'uint32', 14: 'int64', 15: 'uint64'
|
|
26
|
+
};
|
|
27
|
+
const MI_TYPES = {
|
|
28
|
+
[MI_INT8]: 'miINT8', [MI_UINT8]: 'miUINT8', [MI_INT16]: 'miINT16',
|
|
29
|
+
[MI_UINT16]: 'miUINT16', [MI_INT32]: 'miINT32', [MI_UINT32]: 'miUINT32',
|
|
30
|
+
[MI_SINGLE]: 'miSINGLE', [MI_DOUBLE]: 'miDOUBLE', [MI_INT64]: 'miINT64',
|
|
31
|
+
[MI_UINT64]: 'miUINT64', [MI_MATRIX]: 'miMATRIX', [MI_COMPRESSED]: 'miCOMPRESSED',
|
|
32
|
+
[MI_UTF8]: 'miUTF8', [MI_UTF16]: 'miUTF16', [MI_UTF32]: 'miUTF32'
|
|
33
|
+
};
|
|
34
|
+
/** Parse MATLAB Level 4, Level 5 (v5/v6/v7), and HDF5-backed v7.3 files. */
|
|
35
|
+
export async function parseMat(data, fileSize = formatFileSize(data.byteLength)) {
|
|
36
|
+
if (findHdf5SignatureOffset(data) >= 0)
|
|
37
|
+
return parseHdf5Mat(data, fileSize);
|
|
38
|
+
if (isLevel5(data))
|
|
39
|
+
return parseLevel5(data, fileSize);
|
|
40
|
+
return parseLevel4(data, fileSize);
|
|
41
|
+
}
|
|
42
|
+
export function isMatLevel5(data) {
|
|
43
|
+
return isLevel5(data);
|
|
44
|
+
}
|
|
45
|
+
function parseHdf5Mat(data, fileSize) {
|
|
46
|
+
const hdf5 = Hdf5Parser.parse(data, fileSize);
|
|
47
|
+
return {
|
|
48
|
+
format: 'MAT v7.3',
|
|
49
|
+
title: 'MATLAB MAT-file (HDF5)',
|
|
50
|
+
fileSize,
|
|
51
|
+
summary: [
|
|
52
|
+
{ label: 'MAT version', value: '7.3' },
|
|
53
|
+
...hdf5.summary.filter(item => item.label !== 'Format')
|
|
54
|
+
],
|
|
55
|
+
tables: hdf5.tables,
|
|
56
|
+
variables: [],
|
|
57
|
+
rawPreview: hdf5.rawPreview,
|
|
58
|
+
warnings: [
|
|
59
|
+
...hdf5.warnings,
|
|
60
|
+
'MAT v7.3 files are HDF5 containers. Variables are shown from HDF5 metadata; large dataset payloads are not loaded.'
|
|
61
|
+
]
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
async function parseLevel5(data, fileSize) {
|
|
65
|
+
const endian = ascii(data, 126, 128) === 'IM' ? 'LE' : 'BE';
|
|
66
|
+
const headerText = cleanText(latin1(data.subarray(0, 116)));
|
|
67
|
+
const version = readUInt16(data, 124, endian);
|
|
68
|
+
const variables = [];
|
|
69
|
+
const warnings = [];
|
|
70
|
+
const stats = { skipped: 0, compressed: 0 };
|
|
71
|
+
await parseLevel5Elements(data, MAT_V5_HEADER_BYTES, data.length, endian, variables, warnings, stats);
|
|
72
|
+
if (variables.length >= MAX_VARIABLES)
|
|
73
|
+
warnings.push(`Variable table is limited to the first ${MAX_VARIABLES} entries.`);
|
|
74
|
+
if (stats.skipped > 0)
|
|
75
|
+
warnings.push(`${stats.skipped} non-matrix top-level data element(s) were skipped.`);
|
|
76
|
+
return makeClassicDocument('MAT v5/v6/v7', 'MATLAB MAT-file', fileSize, variables, [
|
|
77
|
+
{ label: 'MAT version', value: versionLabel(headerText) },
|
|
78
|
+
{ label: 'Header version', value: version },
|
|
79
|
+
{ label: 'Endian', value: endian === 'LE' ? 'little' : 'big' },
|
|
80
|
+
{ label: 'Variables', value: variables.length }
|
|
81
|
+
], headerText, data, warnings);
|
|
82
|
+
}
|
|
83
|
+
async function parseLevel5Elements(data, start, end, endian, variables, warnings, stats) {
|
|
84
|
+
let offset = start;
|
|
85
|
+
while (offset + 8 <= end && variables.length < MAX_VARIABLES) {
|
|
86
|
+
const element = readElement(data, offset, endian);
|
|
87
|
+
if (!element || element.nextOffset <= offset || element.dataOffset + element.size > end) {
|
|
88
|
+
warnings.push(`Stopped at byte ${offset}: invalid data element tag.`);
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
if (element.type === MI_MATRIX) {
|
|
92
|
+
try {
|
|
93
|
+
variables.push(parseMatrix(data, element, endian));
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
warnings.push(`Unable to decode matrix at byte ${offset}: ${error instanceof Error ? error.message : 'unknown error'}.`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else if (element.type === MI_COMPRESSED) {
|
|
100
|
+
stats.compressed++;
|
|
101
|
+
try {
|
|
102
|
+
const inflated = await inflateZlib(data.subarray(element.dataOffset, element.dataOffset + element.size));
|
|
103
|
+
await parseLevel5Elements(inflated, 0, inflated.length, endian, variables, warnings, stats);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
warnings.push(`Unable to expand compressed data element at byte ${offset}: ${error instanceof Error ? error.message : 'unknown error'}.`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else if (element.type !== 0 || element.size !== 0) {
|
|
110
|
+
stats.skipped++;
|
|
111
|
+
}
|
|
112
|
+
offset = element.nextOffset;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function parseMatrix(data, element, endian) {
|
|
116
|
+
let cursor = element.dataOffset;
|
|
117
|
+
const end = Math.min(element.dataOffset + element.size, data.length);
|
|
118
|
+
const flags = nextElement(data, cursor, endian, end);
|
|
119
|
+
if (!flags)
|
|
120
|
+
throw new Error('missing array flags');
|
|
121
|
+
cursor = flags.nextOffset;
|
|
122
|
+
const flagValue = flags.size >= 4 ? readUInt32(data, flags.dataOffset, endian) : 0;
|
|
123
|
+
const classId = flagValue & 0xff;
|
|
124
|
+
const dimensionsElement = nextElement(data, cursor, endian, end);
|
|
125
|
+
if (!dimensionsElement)
|
|
126
|
+
throw new Error('missing dimensions');
|
|
127
|
+
cursor = dimensionsElement.nextOffset;
|
|
128
|
+
const dimensions = [];
|
|
129
|
+
for (let i = 0; i + 4 <= dimensionsElement.size; i += 4)
|
|
130
|
+
dimensions.push(readInt32(data, dimensionsElement.dataOffset + i, endian));
|
|
131
|
+
const nameElement = nextElement(data, cursor, endian, end);
|
|
132
|
+
if (!nameElement)
|
|
133
|
+
throw new Error('missing variable name');
|
|
134
|
+
cursor = nameElement.nextOffset;
|
|
135
|
+
const name = decodeElementText(data, nameElement, endian);
|
|
136
|
+
const valueElement = nextElement(data, cursor, endian, end);
|
|
137
|
+
return {
|
|
138
|
+
name,
|
|
139
|
+
className: MX_CLASSES[classId] || `mxCLASS${classId}`,
|
|
140
|
+
dimensions,
|
|
141
|
+
dataType: valueElement ? MI_TYPES[valueElement.type] || `miTYPE${valueElement.type}` : '-',
|
|
142
|
+
bytes: element.size,
|
|
143
|
+
preview: valueElement ? previewElement(data, valueElement, endian, classId, dimensions) : '',
|
|
144
|
+
attributes: matrixAttributes(flagValue)
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
function parseLevel4(data, fileSize) {
|
|
148
|
+
const variants = ['LE', 'BE'].map(endian => {
|
|
149
|
+
const result = tryParseLevel4(data, endian);
|
|
150
|
+
return { ...result, endian, score: result.variables.length * 100 - result.warnings.length * 10 };
|
|
151
|
+
});
|
|
152
|
+
const best = variants.sort((a, b) => b.score - a.score)[0];
|
|
153
|
+
const warnings = [...best.warnings];
|
|
154
|
+
if (best.variables.length === 0)
|
|
155
|
+
warnings.push('No MAT v4 matrix records were decoded. The file may be corrupt or use an unsupported private extension.');
|
|
156
|
+
return makeClassicDocument('MAT v4', 'MATLAB Level 4 MAT-file', fileSize, best.variables, [
|
|
157
|
+
{ label: 'MAT version', value: '4' },
|
|
158
|
+
{ label: 'Endian', value: best.endian === 'LE' ? 'little' : 'big' },
|
|
159
|
+
{ label: 'Variables', value: best.variables.length }
|
|
160
|
+
], hexPreview(data), data, warnings);
|
|
161
|
+
}
|
|
162
|
+
function tryParseLevel4(data, endian) {
|
|
163
|
+
const variables = [];
|
|
164
|
+
const warnings = [];
|
|
165
|
+
let offset = 0;
|
|
166
|
+
while (offset + 20 <= data.length && variables.length < MAX_VARIABLES) {
|
|
167
|
+
const type = readInt32(data, offset, endian);
|
|
168
|
+
const rows = readInt32(data, offset + 4, endian);
|
|
169
|
+
const cols = readInt32(data, offset + 8, endian);
|
|
170
|
+
const imagf = readInt32(data, offset + 12, endian);
|
|
171
|
+
const nameLength = readInt32(data, offset + 16, endian);
|
|
172
|
+
if (rows < 0 || cols < 0 || nameLength <= 0 || nameLength > 4096 || imagf < 0 || imagf > 1) {
|
|
173
|
+
if (offset === 0)
|
|
174
|
+
warnings.push('Header values did not look like MAT v4 records.');
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
const nameOffset = offset + 20;
|
|
178
|
+
const dataOffset = nameOffset + nameLength;
|
|
179
|
+
if (dataOffset > data.length) {
|
|
180
|
+
warnings.push(`Stopped at byte ${offset}: variable name extends beyond the file.`);
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
const name = latin1(data.subarray(nameOffset, dataOffset)).replace(/\0+$/g, '');
|
|
184
|
+
const numericType = ((type % 10) + 10) % 10;
|
|
185
|
+
const width = level4BytesPerValue(numericType);
|
|
186
|
+
const valueCount = rows * cols * (imagf ? 2 : 1);
|
|
187
|
+
const dataBytes = valueCount * width;
|
|
188
|
+
const nextOffset = dataOffset + dataBytes;
|
|
189
|
+
if (!Number.isSafeInteger(valueCount) || valueCount < 0 || nextOffset > data.length) {
|
|
190
|
+
warnings.push(`Stopped at byte ${offset}: matrix payload extends beyond the file.`);
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
variables.push({
|
|
194
|
+
name,
|
|
195
|
+
className: level4ClassName(numericType),
|
|
196
|
+
dimensions: [rows, cols],
|
|
197
|
+
dataType: `MOPT ${type}`,
|
|
198
|
+
bytes: 20 + nameLength + dataBytes,
|
|
199
|
+
attributes: imagf ? ['complex'] : [],
|
|
200
|
+
preview: previewLevel4(data, dataOffset, Math.min(rows * cols, MAX_PREVIEW_VALUES), numericType, endian)
|
|
201
|
+
});
|
|
202
|
+
offset = nextOffset;
|
|
203
|
+
}
|
|
204
|
+
return { variables, warnings };
|
|
205
|
+
}
|
|
206
|
+
function makeClassicDocument(format, title, fileSize, variables, summary, rawPreview, data, warnings) {
|
|
207
|
+
return {
|
|
208
|
+
format, title, fileSize, summary, variables, rawPreview, warnings,
|
|
209
|
+
tables: [
|
|
210
|
+
{
|
|
211
|
+
title: `Variables (${variables.length})`,
|
|
212
|
+
headers: ['Name', 'Class', 'Size', 'Storage', 'Bytes', 'Attributes', 'Preview'],
|
|
213
|
+
rows: variables.map(variable => [variable.name || '<unnamed>', variable.className, formatDimensions(variable.dimensions), variable.dataType, variable.bytes, variable.attributes.join(', ') || '-', variable.preview || '-'])
|
|
214
|
+
},
|
|
215
|
+
{ title: 'Header preview', headers: ['Offset', 'Hex', 'ASCII'], rows: hexRows(data.subarray(0, Math.min(data.length, 256))) }
|
|
216
|
+
]
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
function isLevel5(data) {
|
|
220
|
+
if (data.length < MAT_V5_HEADER_BYTES)
|
|
221
|
+
return false;
|
|
222
|
+
const header = latin1(data.subarray(0, 116));
|
|
223
|
+
const endian = ascii(data, 126, 128);
|
|
224
|
+
return /^MATLAB\s+(?:5\.0|7\.)\s+MAT-file/i.test(header) || endian === 'IM' || endian === 'MI';
|
|
225
|
+
}
|
|
226
|
+
function readElement(data, offset, endian) {
|
|
227
|
+
if (offset + 4 > data.length)
|
|
228
|
+
return null;
|
|
229
|
+
const raw = readUInt32(data, offset, endian);
|
|
230
|
+
const smallType = readUInt16(data, offset, endian);
|
|
231
|
+
const smallSize = readUInt16(data, offset + 2, endian);
|
|
232
|
+
if (smallSize > 0 && smallSize <= 4 && offset + 8 <= data.length)
|
|
233
|
+
return { type: smallType, size: smallSize, dataOffset: offset + 4, nextOffset: offset + 8 };
|
|
234
|
+
if (offset + 8 > data.length)
|
|
235
|
+
return null;
|
|
236
|
+
const size = readUInt32(data, offset + 4, endian);
|
|
237
|
+
// miCOMPRESSED payloads are not required to carry the usual 64-bit
|
|
238
|
+
// padding; real MATLAB v7 files commonly place the next tag immediately.
|
|
239
|
+
const nextOffset = raw === MI_COMPRESSED ? offset + 8 + size : align8(offset + 8 + size);
|
|
240
|
+
if (!Number.isSafeInteger(nextOffset))
|
|
241
|
+
return null;
|
|
242
|
+
return { type: raw, size, dataOffset: offset + 8, nextOffset };
|
|
243
|
+
}
|
|
244
|
+
function nextElement(data, offset, endian, end) {
|
|
245
|
+
const element = readElement(data, offset, endian);
|
|
246
|
+
if (!element || element.dataOffset + element.size > data.length || element.dataOffset > end)
|
|
247
|
+
return null;
|
|
248
|
+
return element.nextOffset <= end + 8 ? element : null;
|
|
249
|
+
}
|
|
250
|
+
function previewElement(data, element, endian, classId, dimensions) {
|
|
251
|
+
if (classId === 4)
|
|
252
|
+
return quotePreview(decodeElementText(data, element, endian));
|
|
253
|
+
if (classId === 1 || classId === 2 || classId === 3)
|
|
254
|
+
return `${formatDimensions(dimensions)} ${MX_CLASSES[classId]}`;
|
|
255
|
+
if (classId === 5)
|
|
256
|
+
return 'sparse matrix';
|
|
257
|
+
const values = previewNumericValues(data, element, endian);
|
|
258
|
+
return values.length ? values.join(', ') : `${element.size} bytes`;
|
|
259
|
+
}
|
|
260
|
+
function previewNumericValues(data, element, endian) {
|
|
261
|
+
const values = [];
|
|
262
|
+
const end = Math.min(element.dataOffset + element.size, data.length);
|
|
263
|
+
const width = bytesPerMiType(element.type);
|
|
264
|
+
if (width <= 0)
|
|
265
|
+
return values;
|
|
266
|
+
for (let offset = element.dataOffset; offset + width <= end && values.length < MAX_PREVIEW_VALUES; offset += width)
|
|
267
|
+
values.push(readNumeric(data, offset, element.type, endian));
|
|
268
|
+
if ((end - element.dataOffset) / width > values.length)
|
|
269
|
+
values.push('...');
|
|
270
|
+
return values;
|
|
271
|
+
}
|
|
272
|
+
function decodeElementText(data, element, endian) {
|
|
273
|
+
const bytes = data.subarray(element.dataOffset, Math.min(element.dataOffset + element.size, data.length));
|
|
274
|
+
if (element.type === MI_UTF16 || element.type === MI_UINT16)
|
|
275
|
+
return cleanText(decodeUtf16(bytes, endian));
|
|
276
|
+
if (element.type === MI_UTF32) {
|
|
277
|
+
const chars = [];
|
|
278
|
+
for (let offset = 0; offset + 4 <= bytes.length; offset += 4) {
|
|
279
|
+
const codePoint = readUInt32(bytes, offset, endian);
|
|
280
|
+
if (codePoint > 0 && codePoint <= 0x10ffff && !(codePoint >= 0xd800 && codePoint <= 0xdfff))
|
|
281
|
+
chars.push(String.fromCodePoint(codePoint));
|
|
282
|
+
}
|
|
283
|
+
return cleanText(chars.join(''));
|
|
284
|
+
}
|
|
285
|
+
return cleanText(element.type === MI_UTF8 ? new TextDecoder().decode(bytes) : latin1(bytes));
|
|
286
|
+
}
|
|
287
|
+
function matrixAttributes(flags) {
|
|
288
|
+
const attributes = [];
|
|
289
|
+
if (flags & 0x0800)
|
|
290
|
+
attributes.push('complex');
|
|
291
|
+
if (flags & 0x0400)
|
|
292
|
+
attributes.push('global');
|
|
293
|
+
if (flags & 0x0200)
|
|
294
|
+
attributes.push('logical');
|
|
295
|
+
return attributes;
|
|
296
|
+
}
|
|
297
|
+
function level4BytesPerValue(type) { return [8, 4, 4, 2, 2, 1][type] ?? 8; }
|
|
298
|
+
function level4ClassName(type) { return ['double', 'single', 'int32', 'int16', 'uint16', 'uint8'][type] ?? `type ${type}`; }
|
|
299
|
+
function previewLevel4(data, offset, count, type, endian) {
|
|
300
|
+
const values = [];
|
|
301
|
+
const width = level4BytesPerValue(type);
|
|
302
|
+
for (let i = 0; i < count && offset + width <= data.length; i++)
|
|
303
|
+
values.push(readLevel4Numeric(data, offset + i * width, type, endian));
|
|
304
|
+
if (count >= MAX_PREVIEW_VALUES)
|
|
305
|
+
values.push('...');
|
|
306
|
+
return values.join(', ');
|
|
307
|
+
}
|
|
308
|
+
function readLevel4Numeric(data, offset, type, endian) {
|
|
309
|
+
const view = viewAt(data, offset);
|
|
310
|
+
const le = endian === 'LE';
|
|
311
|
+
switch (type) {
|
|
312
|
+
case 0: return formatNumber(view.getFloat64(0, le));
|
|
313
|
+
case 1: return formatNumber(view.getFloat32(0, le));
|
|
314
|
+
case 2: return String(view.getInt32(0, le));
|
|
315
|
+
case 3: return String(view.getInt16(0, le));
|
|
316
|
+
case 4: return String(view.getUint16(0, le));
|
|
317
|
+
case 5: return String(view.getUint8(0));
|
|
318
|
+
default: return '?';
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
function readNumeric(data, offset, type, endian) {
|
|
322
|
+
const view = viewAt(data, offset);
|
|
323
|
+
const le = endian === 'LE';
|
|
324
|
+
switch (type) {
|
|
325
|
+
case MI_INT8: return String(view.getInt8(0));
|
|
326
|
+
case MI_UINT8: return String(view.getUint8(0));
|
|
327
|
+
case MI_INT16: return String(view.getInt16(0, le));
|
|
328
|
+
case MI_UINT16: return String(view.getUint16(0, le));
|
|
329
|
+
case MI_INT32: return String(view.getInt32(0, le));
|
|
330
|
+
case MI_UINT32: return String(view.getUint32(0, le));
|
|
331
|
+
case MI_SINGLE: return formatNumber(view.getFloat32(0, le));
|
|
332
|
+
case MI_DOUBLE: return formatNumber(view.getFloat64(0, le));
|
|
333
|
+
case MI_INT64: return String(view.getBigInt64(0, le));
|
|
334
|
+
case MI_UINT64: return String(view.getBigUint64(0, le));
|
|
335
|
+
default: return '?';
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
function bytesPerMiType(type) {
|
|
339
|
+
if (type === MI_INT8 || type === MI_UINT8 || type === MI_UTF8)
|
|
340
|
+
return 1;
|
|
341
|
+
if (type === MI_INT16 || type === MI_UINT16 || type === MI_UTF16)
|
|
342
|
+
return 2;
|
|
343
|
+
if (type === MI_INT32 || type === MI_UINT32 || type === MI_SINGLE || type === MI_UTF32)
|
|
344
|
+
return 4;
|
|
345
|
+
if (type === MI_DOUBLE || type === MI_INT64 || type === MI_UINT64)
|
|
346
|
+
return 8;
|
|
347
|
+
return 0;
|
|
348
|
+
}
|
|
349
|
+
function viewAt(data, offset) { return new DataView(data.buffer, data.byteOffset + offset, data.byteLength - offset); }
|
|
350
|
+
function readUInt16(data, offset, endian) { return viewAt(data, offset).getUint16(0, endian === 'LE'); }
|
|
351
|
+
function readInt32(data, offset, endian) { return viewAt(data, offset).getInt32(0, endian === 'LE'); }
|
|
352
|
+
function readUInt32(data, offset, endian) { return viewAt(data, offset).getUint32(0, endian === 'LE'); }
|
|
353
|
+
function align8(value) { return Math.ceil(value / 8) * 8; }
|
|
354
|
+
function formatDimensions(dimensions) { return dimensions.length ? dimensions.join(' × ') : 'scalar'; }
|
|
355
|
+
function formatNumber(value) { return Number.isFinite(value) ? Number(value.toPrecision(8)).toString() : String(value); }
|
|
356
|
+
function cleanText(value) { return value.replace(/\0+$/g, '').trim(); }
|
|
357
|
+
function quotePreview(value) { const single = value.replace(/\s+/g, ' ').trim(); return single ? `"${single.length > 120 ? `${single.slice(0, 120)}...` : single}"` : ''; }
|
|
358
|
+
function matchesBytes(data, signature) { return data.length >= signature.length && signature.every((byte, index) => data[index] === byte); }
|
|
359
|
+
function findHdf5SignatureOffset(data) {
|
|
360
|
+
let offset = 0;
|
|
361
|
+
while (offset + HDF5_SIGNATURE.length <= data.length) {
|
|
362
|
+
if (matchesBytes(data.subarray(offset), HDF5_SIGNATURE))
|
|
363
|
+
return offset;
|
|
364
|
+
offset = offset === 0 ? 512 : offset * 2;
|
|
365
|
+
}
|
|
366
|
+
return -1;
|
|
367
|
+
}
|
|
368
|
+
async function inflateZlib(compressed) {
|
|
369
|
+
if (typeof DecompressionStream === 'undefined')
|
|
370
|
+
throw new Error('zlib decompression is unavailable in this environment');
|
|
371
|
+
const stream = new Blob([compressed.slice()]).stream().pipeThrough(new DecompressionStream('deflate'));
|
|
372
|
+
const reader = stream.getReader();
|
|
373
|
+
const chunks = [];
|
|
374
|
+
let total = 0;
|
|
375
|
+
try {
|
|
376
|
+
while (true) {
|
|
377
|
+
const { done, value } = await reader.read();
|
|
378
|
+
if (done)
|
|
379
|
+
break;
|
|
380
|
+
total += value.byteLength;
|
|
381
|
+
if (total > MAX_DECOMPRESSED_BLOCK_BYTES)
|
|
382
|
+
throw new Error(`decompressed block exceeds ${MAX_DECOMPRESSED_BLOCK_BYTES} bytes`);
|
|
383
|
+
chunks.push(value);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
catch (error) {
|
|
387
|
+
await reader.cancel(error).catch(() => undefined);
|
|
388
|
+
throw error;
|
|
389
|
+
}
|
|
390
|
+
const result = new Uint8Array(total);
|
|
391
|
+
let offset = 0;
|
|
392
|
+
for (const chunk of chunks) {
|
|
393
|
+
result.set(chunk, offset);
|
|
394
|
+
offset += chunk.byteLength;
|
|
395
|
+
}
|
|
396
|
+
return result;
|
|
397
|
+
}
|
|
398
|
+
function ascii(data, start, end) { return String.fromCharCode(...data.subarray(start, end)); }
|
|
399
|
+
function latin1(data) { return new TextDecoder('latin1').decode(data); }
|
|
400
|
+
function decodeUtf16(data, endian) {
|
|
401
|
+
if (endian === 'LE')
|
|
402
|
+
return new TextDecoder('utf-16le').decode(data);
|
|
403
|
+
const swapped = new Uint8Array(data.length);
|
|
404
|
+
for (let i = 0; i + 1 < data.length; i += 2) {
|
|
405
|
+
swapped[i] = data[i + 1];
|
|
406
|
+
swapped[i + 1] = data[i];
|
|
407
|
+
}
|
|
408
|
+
return new TextDecoder('utf-16le').decode(swapped);
|
|
409
|
+
}
|
|
410
|
+
function versionLabel(header) { const match = header.match(/MATLAB\s+([0-9.]+)\s+MAT-file/i); return match ? (match[1].startsWith('7') ? match[1].replace(/\.0$/, '') : match[1]) : '5/6/7'; }
|
|
411
|
+
function formatFileSize(bytes) { if (bytes < 1024)
|
|
412
|
+
return `${bytes} bytes`; const units = ['KB', 'MB', 'GB', 'TB']; let value = bytes; let unit = -1; do {
|
|
413
|
+
value /= 1024;
|
|
414
|
+
unit++;
|
|
415
|
+
} while (value >= 1024 && unit < units.length - 1); return `${value.toFixed(value >= 10 ? 1 : 2)} ${units[unit]}`; }
|
|
416
|
+
function hexPreview(data) { return hexRows(data.subarray(0, Math.min(data.length, 256))).map(row => `${row[0]} ${row[1]} ${row[2]}`).join('\n'); }
|
|
417
|
+
function hexRows(data) {
|
|
418
|
+
const rows = [];
|
|
419
|
+
for (let offset = 0; offset < data.length; offset += 16) {
|
|
420
|
+
const slice = data.subarray(offset, Math.min(offset + 16, data.length));
|
|
421
|
+
const hex = Array.from(slice, byte => byte.toString(16).padStart(2, '0')).join(' ');
|
|
422
|
+
const printable = Array.from(slice, byte => byte >= 32 && byte <= 126 ? String.fromCharCode(byte) : '.').join('');
|
|
423
|
+
rows.push([`0x${offset.toString(16).padStart(4, '0')}`, hex, printable]);
|
|
424
|
+
}
|
|
425
|
+
return rows;
|
|
426
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export function parseMermaid(data, maxBytes = 200_000) { const source = new TextDecoder().decode(data.subarray(0, maxBytes)); const warnings = []; if (data.byteLength > maxBytes)
|
|
2
|
+
warnings.push(`Diagram source is limited to ${maxBytes.toLocaleString()} bytes.`); if (!/^\s*(?:---[\s\S]*?---\s*)?(?:graph|flowchart|sequenceDiagram|classDiagram|stateDiagram|erDiagram|journey|gantt|pie|gitGraph|mindmap|timeline|quadrantChart|xychart|block|packet|architecture|kanban|sankey)/i.test(source))
|
|
3
|
+
warnings.push('The file does not begin with a recognized Mermaid diagram declaration.'); return { source, warnings }; }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { parseMf4 } from '../automotive/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { parseMf4 } from '../automotive/index.js';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare const PARQUET_PREVIEW_BYTES: number;
|
|
2
|
+
export declare const PARQUET_PREVIEW_ROWS = 10000;
|
|
3
|
+
export type ParquetCell = null | boolean | number | string | ParquetCell[] | {
|
|
4
|
+
[key: string]: ParquetCell;
|
|
5
|
+
};
|
|
6
|
+
export interface ParquetDocument {
|
|
7
|
+
headers: string[];
|
|
8
|
+
rows: ParquetCell[][];
|
|
9
|
+
schema: ParquetCell;
|
|
10
|
+
totalRows: number;
|
|
11
|
+
loadedRows: number;
|
|
12
|
+
fileSizeBytes: number;
|
|
13
|
+
isLimited: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface ParquetParseOptions {
|
|
16
|
+
maxPreviewBytes?: number;
|
|
17
|
+
previewRows?: number;
|
|
18
|
+
rowStart?: number;
|
|
19
|
+
signal?: AbortSignal;
|
|
20
|
+
}
|
|
21
|
+
export declare function parseParquet(data: Uint8Array, options?: ParquetParseOptions): Promise<ParquetDocument>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { parquetMetadataAsync, parquetReadObjects, parquetSchema } from 'hyparquet';
|
|
2
|
+
import { compressors } from 'hyparquet-compressors';
|
|
3
|
+
export const PARQUET_PREVIEW_BYTES = 50 * 1024 * 1024;
|
|
4
|
+
export const PARQUET_PREVIEW_ROWS = 10_000;
|
|
5
|
+
export async function parseParquet(data, options = {}) {
|
|
6
|
+
if (options.signal?.aborted)
|
|
7
|
+
throw new DOMException('Parsing was cancelled.', 'AbortError');
|
|
8
|
+
const file = {
|
|
9
|
+
byteLength: data.byteLength,
|
|
10
|
+
async slice(start, end) {
|
|
11
|
+
if (options.signal?.aborted)
|
|
12
|
+
throw new DOMException('Parsing was cancelled.', 'AbortError');
|
|
13
|
+
const part = data.subarray(start, end);
|
|
14
|
+
return part.buffer.slice(part.byteOffset, part.byteOffset + part.byteLength);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
const metadata = await parquetMetadataAsync(file);
|
|
18
|
+
const schema = parquetSchema(metadata);
|
|
19
|
+
const totalRows = Number(metadata.num_rows ?? 0);
|
|
20
|
+
const rowStart = Math.max(0, options.rowStart ?? 0);
|
|
21
|
+
const shouldChunk = data.byteLength >= (options.maxPreviewBytes ?? PARQUET_PREVIEW_BYTES);
|
|
22
|
+
const readOptions = { file, metadata, compressors };
|
|
23
|
+
if (shouldChunk) {
|
|
24
|
+
readOptions.rowStart = rowStart;
|
|
25
|
+
readOptions.rowEnd = rowStart + (options.previewRows ?? PARQUET_PREVIEW_ROWS);
|
|
26
|
+
}
|
|
27
|
+
const objects = await parquetReadObjects(readOptions);
|
|
28
|
+
if (options.signal?.aborted)
|
|
29
|
+
throw new DOMException('Parsing was cancelled.', 'AbortError');
|
|
30
|
+
const headers = objects[0] ? Object.keys(objects[0]) : extractColumnNames(schema);
|
|
31
|
+
if (headers.length === 0)
|
|
32
|
+
throw new Error('Could not extract column names from Parquet file.');
|
|
33
|
+
const types = collectColumnTypes(schema);
|
|
34
|
+
const rows = objects.map((row) => headers.map((header) => convertValue(row[header], types.get(header))));
|
|
35
|
+
return { headers, rows, schema: convertValue(schema), totalRows, loadedRows: rows.length,
|
|
36
|
+
fileSizeBytes: data.byteLength, isLimited: shouldChunk && rowStart + rows.length < totalRows };
|
|
37
|
+
}
|
|
38
|
+
function convertValue(value, type) {
|
|
39
|
+
if (value == null || typeof value === 'string' || typeof value === 'boolean' || typeof value === 'number')
|
|
40
|
+
return value;
|
|
41
|
+
if (typeof value === 'bigint')
|
|
42
|
+
return value.toString();
|
|
43
|
+
if (value instanceof Date)
|
|
44
|
+
return type?.logicalType === 'DATE' || type?.convertedType === 'DATE'
|
|
45
|
+
? value.toISOString().slice(0, 10) : value.toISOString();
|
|
46
|
+
if (value instanceof Uint8Array)
|
|
47
|
+
return Array.from(value);
|
|
48
|
+
if (Array.isArray(value))
|
|
49
|
+
return value.map((item) => convertValue(item));
|
|
50
|
+
if (typeof value === 'object')
|
|
51
|
+
return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, convertValue(v)]));
|
|
52
|
+
return String(value);
|
|
53
|
+
}
|
|
54
|
+
function extractColumnNames(node) {
|
|
55
|
+
if (!node)
|
|
56
|
+
return [];
|
|
57
|
+
const children = Array.isArray(node.children) ? node.children : [];
|
|
58
|
+
if (!children.length && node.element?.name)
|
|
59
|
+
return [node.path?.length ? node.path.join('.') : node.element.name];
|
|
60
|
+
return children.flatMap(extractColumnNames);
|
|
61
|
+
}
|
|
62
|
+
function collectColumnTypes(node, out = new Map()) {
|
|
63
|
+
const children = Array.isArray(node?.children) ? node.children : [];
|
|
64
|
+
if (!children.length && node?.element?.name)
|
|
65
|
+
out.set(node.path?.length ? node.path.join('.') : node.element.name, { logicalType: node.element.logical_type?.type, convertedType: node.element.converted_type });
|
|
66
|
+
children.forEach((child) => collectColumnTypes(child, out));
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { parsePcap } from '../automotive/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { parsePcap } from '../automotive/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { parsePcapng } from '../automotive/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { parsePcapng } from '../automotive/index.js';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export function parsePlantUml(data, maxBytes = 200_000) { const source = new TextDecoder().decode(data.subarray(0, maxBytes)); const warnings = []; if (data.byteLength > maxBytes)
|
|
2
|
+
warnings.push(`Diagram source is limited to ${maxBytes.toLocaleString()} bytes.`); if (!/^\s*@start(?:uml|mindmap|wbs|gantt|json|yaml|ditaa|jcckit|salt|creole)/i.test(source))
|
|
3
|
+
warnings.push('The file does not begin with a recognized PlantUML @start directive.'); if (!/@end(?:uml|mindmap|wbs|gantt|json|yaml|ditaa|jcckit|salt|creole)\s*$/i.test(source))
|
|
4
|
+
warnings.push('The PlantUML source appears truncated or is missing an @end directive.'); return { source, warnings }; }
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { parsePptBinaryVscode } from './vscode.js';
|
|
2
|
+
import type { ParseOptions, ParseOutcome } from '../types.js';
|
|
3
|
+
import type { SlideDeck } from '../slide-model.js';
|
|
4
|
+
export * from '../slide-model.js';
|
|
5
|
+
export declare function parsePptBinary(input: Uint8Array, options?: ParseOptions): Promise<ParseOutcome<SlideDeck>>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// @ts-nocheck -- compact binary reader; public return contract remains typed.
|
|
2
|
+
export { parsePptBinaryVscode } from './vscode.js';
|
|
3
|
+
export * from '../slide-model.js';
|
|
4
|
+
const END = 0xfffffffe, FREE = 0xffffffff;
|
|
5
|
+
function cfbStream(input, wanted) { if (input.length < 512)
|
|
6
|
+
return; const v = new DataView(input.buffer, input.byteOffset, input.byteLength), shift = v.getUint16(30, true), ss = 1 << shift; if (ss !== 512 && ss !== 4096)
|
|
7
|
+
return; const sector = (id) => (id + 1) * ss; const fat = []; for (let i = 0; i < Math.min(v.getUint32(44, true), 109); i++) {
|
|
8
|
+
const id = v.getUint32(76 + i * 4, true);
|
|
9
|
+
if (id === FREE || id === END)
|
|
10
|
+
continue;
|
|
11
|
+
const off = sector(id);
|
|
12
|
+
if (off + ss > input.length)
|
|
13
|
+
break;
|
|
14
|
+
for (let p = 0; p < ss; p += 4)
|
|
15
|
+
fat.push(v.getUint32(off + p, true));
|
|
16
|
+
} const readChain = (start, size = Infinity) => { const parts = []; let id = start, remaining = size; const seen = new Set(); while (id !== END && id !== FREE && id < fat.length && !seen.has(id) && remaining > 0) {
|
|
17
|
+
seen.add(id);
|
|
18
|
+
const off = sector(id), n = Math.min(ss, remaining, input.length - off);
|
|
19
|
+
for (let i = 0; i < n; i++)
|
|
20
|
+
parts.push(input[off + i]);
|
|
21
|
+
remaining -= n;
|
|
22
|
+
id = fat[id] ?? END;
|
|
23
|
+
} return new Uint8Array(parts); }; const dir = readChain(v.getUint32(48, true)); const dv = new DataView(dir.buffer, dir.byteOffset, dir.byteLength); const entries = []; for (let off = 0; off + 128 <= dir.length; off += 128) {
|
|
24
|
+
const len = dv.getUint16(off + 64, true), type = dv.getUint8(off + 66);
|
|
25
|
+
if (len < 2 || len > 64)
|
|
26
|
+
continue;
|
|
27
|
+
entries.push({ name: new TextDecoder('utf-16le').decode(dir.subarray(off, off + len - 2)), type, start: dv.getUint32(off + 116, true), size: dv.getUint32(off + 120, true) });
|
|
28
|
+
} const e = entries.find(x => x.type === 2 && x.name === wanted); if (!e)
|
|
29
|
+
return; return readChain(e.start, e.size); }
|
|
30
|
+
function strings(bytes) { const out = []; for (let p = 0; p + 8 < bytes.length;) {
|
|
31
|
+
let end = p;
|
|
32
|
+
while (end + 1 < bytes.length) {
|
|
33
|
+
const code = bytes[end] | (bytes[end + 1] << 8);
|
|
34
|
+
if (code === 0)
|
|
35
|
+
break;
|
|
36
|
+
if (code < 9 || (code > 13 && code < 32))
|
|
37
|
+
break;
|
|
38
|
+
end += 2;
|
|
39
|
+
}
|
|
40
|
+
if (end - p >= 8) {
|
|
41
|
+
const text = new TextDecoder('utf-16le').decode(bytes.subarray(p, end)).trim();
|
|
42
|
+
if (text.length >= 2 && !out.includes(text))
|
|
43
|
+
out.push(text);
|
|
44
|
+
p = end + 2;
|
|
45
|
+
}
|
|
46
|
+
else
|
|
47
|
+
p += 2;
|
|
48
|
+
} return out; }
|
|
49
|
+
export async function parsePptBinary(input, options = {}) { const started = Date.now(), diagnostics = []; if (options.signal?.aborted)
|
|
50
|
+
return { result: { status: 'failed', failure: { code: 'aborted', retryable: true, messageKey: 'diag.aborted' }, diagnostics }, execution: { workerUsed: false, hardLimitEnforced: false, elapsedMillis: 0 } }; try {
|
|
51
|
+
const stream = cfbStream(input, 'PowerPoint Document');
|
|
52
|
+
if (!stream)
|
|
53
|
+
throw new Error();
|
|
54
|
+
const texts = strings(stream).slice(0, Math.min(options.limits?.maxEntries ?? 1000, 1000));
|
|
55
|
+
const widthPx = 960, heightPx = 720;
|
|
56
|
+
const slides = texts.length ? [{ slideNumber: 1, widthPx, heightPx, backgroundColor: '#ffffff', elements: texts.map((text, i) => ({ type: 'text', x: 72, y: 70 + i * 34, width: 816, height: 30, zIndex: i, isTitle: i === 0, paragraphs: [{ text, level: 0, bullet: i > 0 }] })) }] : [];
|
|
57
|
+
const deck = { slides, totalSlides: slides.length, slideSize: { widthPx, heightPx } };
|
|
58
|
+
return { result: { status: 'ok', document: deck, diagnostics }, execution: { workerUsed: false, hardLimitEnforced: false, elapsedMillis: Date.now() - started } };
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return { result: { status: 'failed', failure: { code: 'invalid-format', retryable: false, messageKey: 'diag.ppt.invalid-format' }, diagnostics }, execution: { workerUsed: false, hardLimitEnforced: false, elapsedMillis: Date.now() - started } };
|
|
62
|
+
} }
|