omni-viewer-core 0.16.0 → 0.17.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/README.md CHANGED
@@ -16,7 +16,8 @@ models, viewers mount into a DOM element, and everything host-specific
16
16
  legacy PPT), Markdown, LaTeX (structure and math preview, not typesetting)
17
17
  - **Data & spreadsheets** — Excel, CSV/TSV, JSON, JSONL/NDJSON, YAML, TOML,
18
18
  Parquet, Avro, HDF5, MATLAB MAT, NumPy (NPY/NPZ), Safetensors, GGUF, ONNX, TFLite/LiteRT,
19
- Keras (.keras and legacy .h5), Protocol Buffers, ReqIF, SQLite
19
+ Keras (.keras and legacy .h5), Core ML (.mlmodel and .mlpackage),
20
+ Protocol Buffers, ReqIF, SQLite
20
21
  - **Media & graphics** — audio (waveform/spectrogram), video, images,
21
22
  Photoshop PSD
22
23
  - **Engineering & automotive** — CAN DBC, AUTOSAR ARXML, ASAM A2L, Vector
@@ -172,6 +173,46 @@ contents distinguish a Keras model from any other HDF5 file; hosts that read the
172
173
  whole file can refine that with `looksLikeKerasHdf5` from
173
174
  `omni-viewer-core/parsers/keras` and mount the Keras viewer instead.
174
175
 
176
+ ### Core ML models
177
+
178
+ A `.mlmodel` is a serialized `CoreML.Specification.Model` protobuf, and an
179
+ `.mlpackage` is a bundle whose `Manifest.json` points at one such spec plus the
180
+ weight blobs its ML Program references. One entry point reads both — bytes that
181
+ open with a ZIP header are treated as a packaged bundle:
182
+
183
+ ```ts
184
+ import { mountCoremlViewer } from 'omni-viewer-core/viewers/coreml';
185
+
186
+ await mountCoremlViewer({ fileName: file.name, data: bytes }, container, ctx);
187
+ ```
188
+
189
+ Weight payloads are never decoded: blob references resolve to a file, an offset,
190
+ and a byte count, and inline weight tensors to their size and quantization, so a
191
+ multi-gigabyte model costs nothing to open. Package members are read in place,
192
+ and JSZip is only consulted for a bundle that was re-zipped with compression.
193
+
194
+ Two model families carry a graph, and the viewer reads them to different depths:
195
+
196
+ - An **ML Program** (Core ML 5 and newer) is self-describing — every operation
197
+ names its own inputs, so attributes are shown exactly as the producer wrote
198
+ them, with no schema knowledge involved.
199
+ - A **neural network** (the older encoding) stores each layer's parameters in a
200
+ distinct message per layer type. Layer types resolve for all of them, and
201
+ attributes are decoded for the common types; weights need no such table, since
202
+ `WeightParams` has one shape everywhere it appears and is found structurally.
203
+
204
+ The viewer provides a per-graph computation graph with operation, value, and
205
+ weight inspection, navigation into the blocks a control-flow operation
206
+ references, and searchable operation, input/output, weight, package, and
207
+ model-information panels. Custom layers, pipeline stages, unmapped layer types,
208
+ and weight files that are not present are surfaced as warnings.
209
+
210
+ Both extensions route by extension, and an extensionless zipped bundle is
211
+ resolved by `probeContainer` from its `Manifest.json` + `Data/com.apple.CoreML`
212
+ layout. A `.mlmodel` carries no leading magic, so hosts that can read a whole
213
+ extensionless file can refine routing with `looksLikeCoremlSpec` from
214
+ `omni-viewer-core/parsers/coreml`.
215
+
175
216
  ### Archive host integration
176
217
 
177
218
  Archive decompression remains adapter-owned: pass an `ArchiveDecoder` to
@@ -210,6 +210,67 @@ export const CATALOG_EN = {
210
210
  'tflite.inspector.inputs': 'Inputs', 'tflite.inspector.outputs': 'Outputs',
211
211
  'tflite.inspector.intermediates': 'Intermediates', 'tflite.inspector.options': 'Options',
212
212
  'tflite.inspector.customOptions': 'Custom options', 'tflite.inspector.subgraphs': 'Referenced subgraphs',
213
+ 'coreml.title': 'Core ML model', 'coreml.search': 'Search operations, operands, and weights…',
214
+ 'coreml.copyJson': 'Copy JSON', 'coreml.graph': 'Graph', 'coreml.unnamed': 'unnamed',
215
+ 'coreml.operations': 'Operations', 'coreml.io': 'Inputs & Outputs', 'coreml.weights': 'Weights',
216
+ 'coreml.packageContents': 'Package', 'coreml.modelInfo': 'Model Info',
217
+ 'coreml.package': 'Package', 'coreml.updatable': 'Updatable',
218
+ 'coreml.specVersion': 'specification v{version}',
219
+ 'coreml.rows': '{shown} / {total} rows shown', 'coreml.noMatches': 'No rows match the current search.',
220
+ 'coreml.selectNode': 'Select an operation or value to inspect it.',
221
+ 'coreml.graphLimited': 'Graph preview shows {shown} of {total} items.',
222
+ 'coreml.graphEdgesLimited': 'Only the first {count} connections are shown.',
223
+ 'coreml.moreItems': '{count} more…', 'coreml.optional': 'Optional', 'coreml.default': 'default',
224
+ 'coreml.unknown': 'unknown', 'coreml.external': 'from enclosing scope',
225
+ 'coreml.yes': 'Yes', 'coreml.no': 'No', 'coreml.rootItem': 'root model',
226
+ 'coreml.blobPresent': '{count} tensor(s), {referenced} referenced of {size} in the package',
227
+ 'coreml.blobAbsent': '{count} tensor(s), {referenced} referenced — the file is not available here',
228
+ 'coreml.weightFiles': 'Weight files',
229
+ 'coreml.summary.operations': 'Operations', 'coreml.summary.graphs': 'Graphs',
230
+ 'coreml.summary.inputs': 'Inputs', 'coreml.summary.outputs': 'Outputs',
231
+ 'coreml.summary.functions': 'Functions', 'coreml.summary.specVersion': 'Spec version',
232
+ 'coreml.kind.operation': 'Operation', 'coreml.kind.layer': 'Layer', 'coreml.kind.stage': 'Pipeline stage',
233
+ 'coreml.kind.input': 'Input', 'coreml.kind.output': 'Output', 'coreml.kind.state': 'State',
234
+ 'coreml.kind.trainingInput': 'Training input', 'coreml.kind.manifestItem': 'Manifest item',
235
+ 'coreml.kind.archiveMember': 'Archive member',
236
+ 'coreml.storage.blob': 'Weight file', 'coreml.storage.inline': 'Inline',
237
+ 'coreml.column.index': '#', 'coreml.column.name': 'Name', 'coreml.column.type': 'Type',
238
+ 'coreml.column.kind': 'Kind', 'coreml.column.inputs': 'Inputs', 'coreml.column.outputs': 'Outputs',
239
+ 'coreml.column.attributes': 'Attributes', 'coreml.column.weights': 'Weights',
240
+ 'coreml.column.function': 'Function', 'coreml.column.typeShape': 'Type / Shape',
241
+ 'coreml.column.flexibility': 'Flexibility', 'coreml.column.optional': 'Optional',
242
+ 'coreml.column.description': 'Description', 'coreml.column.graph': 'Graph', 'coreml.column.node': 'Operation',
243
+ 'coreml.column.parameter': 'Parameter', 'coreml.column.shape': 'Shape', 'coreml.column.elements': 'Elements',
244
+ 'coreml.column.dataSize': 'Data size', 'coreml.column.storage': 'Storage',
245
+ 'coreml.column.location': 'Location', 'coreml.column.path': 'Path',
246
+ 'coreml.info.modelType': 'Model type', 'coreml.info.specVersion': 'Specification version',
247
+ 'coreml.info.availability': 'OS availability', 'coreml.info.description': 'Description',
248
+ 'coreml.info.author': 'Author', 'coreml.info.license': 'License', 'coreml.info.version': 'Version',
249
+ 'coreml.info.updatable': 'On-device update', 'coreml.info.fileSize': 'File size',
250
+ 'coreml.info.functions': 'Functions', 'coreml.info.defaultFunction': 'Default function',
251
+ 'coreml.info.graphs': 'Graphs', 'coreml.info.classLabels': 'Class labels',
252
+ 'coreml.info.packageVersion': 'Package format', 'coreml.info.modelPath': 'Model path',
253
+ 'coreml.inspector.inputs': 'Inputs', 'coreml.inspector.outputs': 'Outputs',
254
+ 'coreml.inspector.attributes': 'Attributes', 'coreml.inspector.weights': 'Weights',
255
+ 'coreml.inspector.graphs': 'Referenced graphs',
256
+ 'coreml.warning.specVersion': 'The model declares specification version {version}, which this viewer does not have an OS mapping for.',
257
+ 'coreml.warning.noModelType': 'The model declares no model type.',
258
+ 'coreml.warning.emptyGraph': 'The model contains no operations.',
259
+ 'coreml.warning.emptyProgram': 'The ML Program declares no functions.',
260
+ 'coreml.warning.programVersion': 'The ML Program declares version {version}; this viewer targets version 1.',
261
+ 'coreml.warning.emptyPipeline': 'The pipeline contains no stages.',
262
+ 'coreml.warning.pipelineDepth': 'Pipeline nesting deeper than {limit} levels was not read.',
263
+ 'coreml.warning.unknownLayer': 'Layer {name} declares no recognized layer type.',
264
+ 'coreml.warning.customLayers': '{count} custom layer(s) require a matching runtime registration: {names}',
265
+ 'coreml.warning.blobMissing': '{count} weight file(s) the model references are not in this package: {names}',
266
+ 'coreml.warning.blobUnavailable': '{count} weight file(s) live beside this specification and were not read: {names}',
267
+ 'coreml.warning.manifestMissing': 'The package has no Manifest.json; the model was located by its conventional path.',
268
+ 'coreml.warning.manifestInvalid': 'The package Manifest.json could not be read.',
269
+ 'coreml.warning.manifestUnreadable': 'The package Manifest.json could not be extracted, so the package contents are not described.',
270
+ 'coreml.warning.textTruncated': 'Some text fields were longer than this viewer displays and were cut short.',
271
+ 'coreml.warning.archiveEntryLimit': 'Only the first {limit} archive entries were read.',
272
+ 'coreml.warning.serializedModel': 'This is a private serialized model; Apple documents no schema for its contents.',
273
+ 'coreml.warning.linkedModel': 'This model links to a separate model file that this viewer does not read.',
213
274
  'keras.title': 'Keras model', 'keras.document.v3': 'Keras v3 archive', 'keras.document.hdf5': 'Keras HDF5 model',
214
275
  'keras.version': 'Keras {version}', 'keras.search': 'Search layers, weights, and configuration…',
215
276
  'keras.copyJson': 'Copy JSON', 'keras.invalid': 'invalid',
@@ -449,6 +510,7 @@ export const CATALOG_EN = {
449
510
  'common.copied': 'Copied to clipboard',
450
511
  'common.noClipboard': 'Copy is unavailable on this platform',
451
512
  'common.copyTooLarge': 'Too large to copy to the clipboard ({size} bytes). Use file export instead.',
513
+ 'common.copyTooLargeNoExport': 'Too large to copy to the clipboard ({size} bytes).',
452
514
  'common.noFileSave': 'Saving files is unavailable on this platform',
453
515
  'common.saved': 'Saved {name}',
454
516
  'common.savedToOriginal': 'Saved',
@@ -206,6 +206,67 @@ export const CATALOG_JA = {
206
206
  'tflite.inspector.inputs': '入力', 'tflite.inspector.outputs': '出力',
207
207
  'tflite.inspector.intermediates': '中間テンソル', 'tflite.inspector.options': 'オプション',
208
208
  'tflite.inspector.customOptions': 'カスタムオプション', 'tflite.inspector.subgraphs': '参照サブグラフ',
209
+ 'coreml.title': 'Core MLモデル', 'coreml.search': '演算・オペランド・重みを検索…',
210
+ 'coreml.copyJson': 'JSONをコピー', 'coreml.graph': 'グラフ', 'coreml.unnamed': '名前なし',
211
+ 'coreml.operations': '演算', 'coreml.io': '入力と出力', 'coreml.weights': '重み',
212
+ 'coreml.packageContents': 'パッケージ', 'coreml.modelInfo': 'モデル情報',
213
+ 'coreml.package': 'パッケージ', 'coreml.updatable': '更新可能',
214
+ 'coreml.specVersion': '仕様 v{version}',
215
+ 'coreml.rows': '{total}行中{shown}行を表示', 'coreml.noMatches': '現在の検索に一致する行はありません。',
216
+ 'coreml.selectNode': '演算または値を選択すると詳細が表示されます。',
217
+ 'coreml.graphLimited': 'グラフプレビューは{total}件中{shown}件を表示しています。',
218
+ 'coreml.graphEdgesLimited': '最初の{count}本の接続のみ表示しています。',
219
+ 'coreml.moreItems': '他{count}件…', 'coreml.optional': '省略可', 'coreml.default': '既定',
220
+ 'coreml.unknown': '不明', 'coreml.external': '外側のスコープから',
221
+ 'coreml.yes': 'はい', 'coreml.no': 'いいえ', 'coreml.rootItem': 'ルートモデル',
222
+ 'coreml.blobPresent': 'テンソル{count}件、パッケージ内{size}のうち{referenced}を参照',
223
+ 'coreml.blobAbsent': 'テンソル{count}件、{referenced}を参照 — このファイルはここにありません',
224
+ 'coreml.weightFiles': '重みファイル',
225
+ 'coreml.summary.operations': '演算', 'coreml.summary.graphs': 'グラフ',
226
+ 'coreml.summary.inputs': '入力', 'coreml.summary.outputs': '出力',
227
+ 'coreml.summary.functions': '関数', 'coreml.summary.specVersion': '仕様バージョン',
228
+ 'coreml.kind.operation': '演算', 'coreml.kind.layer': 'レイヤー', 'coreml.kind.stage': 'パイプライン段',
229
+ 'coreml.kind.input': '入力', 'coreml.kind.output': '出力', 'coreml.kind.state': '状態',
230
+ 'coreml.kind.trainingInput': '学習入力', 'coreml.kind.manifestItem': 'マニフェスト項目',
231
+ 'coreml.kind.archiveMember': 'アーカイブメンバー',
232
+ 'coreml.storage.blob': '重みファイル', 'coreml.storage.inline': '埋め込み',
233
+ 'coreml.column.index': '#', 'coreml.column.name': '名前', 'coreml.column.type': '種別',
234
+ 'coreml.column.kind': '分類', 'coreml.column.inputs': '入力', 'coreml.column.outputs': '出力',
235
+ 'coreml.column.attributes': '属性', 'coreml.column.weights': '重み',
236
+ 'coreml.column.function': '関数', 'coreml.column.typeShape': '型 / 形状',
237
+ 'coreml.column.flexibility': '可変性', 'coreml.column.optional': '省略可',
238
+ 'coreml.column.description': '説明', 'coreml.column.graph': 'グラフ', 'coreml.column.node': '演算',
239
+ 'coreml.column.parameter': 'パラメータ', 'coreml.column.shape': '形状', 'coreml.column.elements': '要素数',
240
+ 'coreml.column.dataSize': 'データサイズ', 'coreml.column.storage': '格納先',
241
+ 'coreml.column.location': '位置', 'coreml.column.path': 'パス',
242
+ 'coreml.info.modelType': 'モデル種別', 'coreml.info.specVersion': '仕様バージョン',
243
+ 'coreml.info.availability': '対応OS', 'coreml.info.description': '説明',
244
+ 'coreml.info.author': '作成者', 'coreml.info.license': 'ライセンス', 'coreml.info.version': 'バージョン',
245
+ 'coreml.info.updatable': 'オンデバイス更新', 'coreml.info.fileSize': 'ファイルサイズ',
246
+ 'coreml.info.functions': '関数', 'coreml.info.defaultFunction': '既定の関数',
247
+ 'coreml.info.graphs': 'グラフ', 'coreml.info.classLabels': 'クラスラベル',
248
+ 'coreml.info.packageVersion': 'パッケージ形式', 'coreml.info.modelPath': 'モデルパス',
249
+ 'coreml.inspector.inputs': '入力', 'coreml.inspector.outputs': '出力',
250
+ 'coreml.inspector.attributes': '属性', 'coreml.inspector.weights': '重み',
251
+ 'coreml.inspector.graphs': '参照グラフ',
252
+ 'coreml.warning.specVersion': 'モデルは仕様バージョン{version}を宣言していますが、このビューアーに対応OSの情報がありません。',
253
+ 'coreml.warning.noModelType': 'モデルにモデル種別が宣言されていません。',
254
+ 'coreml.warning.emptyGraph': 'モデルに演算がありません。',
255
+ 'coreml.warning.emptyProgram': 'ML Programに関数が宣言されていません。',
256
+ 'coreml.warning.programVersion': 'ML Programはバージョン{version}を宣言しています。このビューアーはバージョン1を対象としています。',
257
+ 'coreml.warning.emptyPipeline': 'パイプラインに段がありません。',
258
+ 'coreml.warning.pipelineDepth': '{limit}段より深いパイプラインのネストは読み取っていません。',
259
+ 'coreml.warning.unknownLayer': 'レイヤー{name}に認識可能なレイヤー種別がありません。',
260
+ 'coreml.warning.customLayers': 'カスタムレイヤー{count}件はランタイムへの登録が必要です: {names}',
261
+ 'coreml.warning.blobMissing': 'モデルが参照する重みファイル{count}件がこのパッケージにありません: {names}',
262
+ 'coreml.warning.blobUnavailable': '重みファイル{count}件はこの仕様ファイルと同じ場所にあり、読み取っていません: {names}',
263
+ 'coreml.warning.manifestMissing': 'パッケージにManifest.jsonがないため、慣例のパスからモデルを見つけました。',
264
+ 'coreml.warning.manifestInvalid': 'パッケージのManifest.jsonを読み取れませんでした。',
265
+ 'coreml.warning.manifestUnreadable': 'パッケージのManifest.jsonを展開できなかったため、パッケージ構成を表示できません。',
266
+ 'coreml.warning.textTruncated': '一部のテキストフィールドが表示上限を超えたため切り詰められました。',
267
+ 'coreml.warning.archiveEntryLimit': 'アーカイブ項目のうち最初の{limit}件のみ読み取りました。',
268
+ 'coreml.warning.serializedModel': '非公開のシリアライズ済みモデルです。Appleは内容のスキーマを公開していません。',
269
+ 'coreml.warning.linkedModel': 'このモデルは別のモデルファイルを参照しており、ビューアーはそのファイルを読み取りません。',
209
270
  'keras.title': 'Kerasモデル', 'keras.document.v3': 'Keras v3アーカイブ', 'keras.document.hdf5': 'Keras HDF5モデル',
210
271
  'keras.version': 'Keras {version}', 'keras.search': 'レイヤー、重み、設定を検索…',
211
272
  'keras.copyJson': 'JSONをコピー', 'keras.invalid': '無効',
@@ -445,6 +506,7 @@ export const CATALOG_JA = {
445
506
  'common.rowsMatched': '{total}行中{matched}行が一致', 'common.copied': 'クリップボードにコピーしました',
446
507
  'common.noClipboard': 'この環境ではコピーを利用できません',
447
508
  'common.copyTooLarge': 'クリップボードにコピーするには大きすぎます({size}バイト)。代わりにファイルへエクスポートしてください。',
509
+ 'common.copyTooLargeNoExport': 'クリップボードにコピーするには大きすぎます({size}バイト)。',
448
510
  'common.noFileSave': 'この環境ではファイルを保存できません', 'common.saved': '{name}を保存しました',
449
511
  'common.savedToOriginal': '保存しました', 'common.saveFailed': '保存に失敗しました',
450
512
  'common.unsaved': '未保存の変更', 'common.noWriteback': '元のファイルには保存できません。ファイルのエクスポートを使用してください。',
@@ -208,6 +208,67 @@ export const CATALOG_KO = {
208
208
  'tflite.inspector.inputs': '입력', 'tflite.inspector.outputs': '출력',
209
209
  'tflite.inspector.intermediates': '중간 텐서', 'tflite.inspector.options': '옵션',
210
210
  'tflite.inspector.customOptions': '커스텀 옵션', 'tflite.inspector.subgraphs': '참조 서브그래프',
211
+ 'coreml.title': 'Core ML 모델', 'coreml.search': '연산·피연산자·가중치 검색…',
212
+ 'coreml.copyJson': 'JSON 복사', 'coreml.graph': '그래프', 'coreml.unnamed': '이름 없음',
213
+ 'coreml.operations': '연산', 'coreml.io': '입력 및 출력', 'coreml.weights': '가중치',
214
+ 'coreml.packageContents': '패키지', 'coreml.modelInfo': '모델 정보',
215
+ 'coreml.package': '패키지', 'coreml.updatable': '업데이트 가능',
216
+ 'coreml.specVersion': '사양 v{version}',
217
+ 'coreml.rows': '{total}행 중 {shown}행 표시', 'coreml.noMatches': '현재 검색과 일치하는 행이 없습니다.',
218
+ 'coreml.selectNode': '연산이나 값을 선택하면 상세 정보가 표시됩니다.',
219
+ 'coreml.graphLimited': '그래프 미리보기에 {total}개 중 {shown}개를 표시합니다.',
220
+ 'coreml.graphEdgesLimited': '처음 {count}개의 연결만 표시합니다.',
221
+ 'coreml.moreItems': '{count}개 더…', 'coreml.optional': '선택 사항', 'coreml.default': '기본',
222
+ 'coreml.unknown': '알 수 없음', 'coreml.external': '상위 범위에서 전달',
223
+ 'coreml.yes': '예', 'coreml.no': '아니요', 'coreml.rootItem': '루트 모델',
224
+ 'coreml.blobPresent': '텐서 {count}개, 패키지 내 {size} 중 {referenced} 참조',
225
+ 'coreml.blobAbsent': '텐서 {count}개, {referenced} 참조 — 이 파일은 여기에 없습니다',
226
+ 'coreml.weightFiles': '가중치 파일',
227
+ 'coreml.summary.operations': '연산', 'coreml.summary.graphs': '그래프',
228
+ 'coreml.summary.inputs': '입력', 'coreml.summary.outputs': '출력',
229
+ 'coreml.summary.functions': '함수', 'coreml.summary.specVersion': '사양 버전',
230
+ 'coreml.kind.operation': '연산', 'coreml.kind.layer': '레이어', 'coreml.kind.stage': '파이프라인 단계',
231
+ 'coreml.kind.input': '입력', 'coreml.kind.output': '출력', 'coreml.kind.state': '상태',
232
+ 'coreml.kind.trainingInput': '학습 입력', 'coreml.kind.manifestItem': '매니페스트 항목',
233
+ 'coreml.kind.archiveMember': '아카이브 멤버',
234
+ 'coreml.storage.blob': '가중치 파일', 'coreml.storage.inline': '내장',
235
+ 'coreml.column.index': '#', 'coreml.column.name': '이름', 'coreml.column.type': '유형',
236
+ 'coreml.column.kind': '종류', 'coreml.column.inputs': '입력', 'coreml.column.outputs': '출력',
237
+ 'coreml.column.attributes': '속성', 'coreml.column.weights': '가중치',
238
+ 'coreml.column.function': '함수', 'coreml.column.typeShape': '유형 / 형태',
239
+ 'coreml.column.flexibility': '가변성', 'coreml.column.optional': '선택 사항',
240
+ 'coreml.column.description': '설명', 'coreml.column.graph': '그래프', 'coreml.column.node': '연산',
241
+ 'coreml.column.parameter': '매개변수', 'coreml.column.shape': '형태', 'coreml.column.elements': '요소 수',
242
+ 'coreml.column.dataSize': '데이터 크기', 'coreml.column.storage': '저장 위치',
243
+ 'coreml.column.location': '위치', 'coreml.column.path': '경로',
244
+ 'coreml.info.modelType': '모델 유형', 'coreml.info.specVersion': '사양 버전',
245
+ 'coreml.info.availability': 'OS 지원', 'coreml.info.description': '설명',
246
+ 'coreml.info.author': '작성자', 'coreml.info.license': '라이선스', 'coreml.info.version': '버전',
247
+ 'coreml.info.updatable': '온디바이스 업데이트', 'coreml.info.fileSize': '파일 크기',
248
+ 'coreml.info.functions': '함수', 'coreml.info.defaultFunction': '기본 함수',
249
+ 'coreml.info.graphs': '그래프', 'coreml.info.classLabels': '클래스 레이블',
250
+ 'coreml.info.packageVersion': '패키지 형식', 'coreml.info.modelPath': '모델 경로',
251
+ 'coreml.inspector.inputs': '입력', 'coreml.inspector.outputs': '출력',
252
+ 'coreml.inspector.attributes': '속성', 'coreml.inspector.weights': '가중치',
253
+ 'coreml.inspector.graphs': '참조 그래프',
254
+ 'coreml.warning.specVersion': '모델이 사양 버전 {version}을(를) 선언했지만 이 뷰어에는 해당 OS 정보가 없습니다.',
255
+ 'coreml.warning.noModelType': '모델에 모델 유형이 선언되어 있지 않습니다.',
256
+ 'coreml.warning.emptyGraph': '모델에 연산이 없습니다.',
257
+ 'coreml.warning.emptyProgram': 'ML Program에 함수가 선언되어 있지 않습니다.',
258
+ 'coreml.warning.programVersion': 'ML Program이 버전 {version}을(를) 선언했습니다. 이 뷰어는 버전 1을 기준으로 합니다.',
259
+ 'coreml.warning.emptyPipeline': '파이프라인에 단계가 없습니다.',
260
+ 'coreml.warning.pipelineDepth': '{limit}단계보다 깊은 파이프라인 중첩은 읽지 않았습니다.',
261
+ 'coreml.warning.unknownLayer': '{name} 레이어에 인식 가능한 레이어 유형이 없습니다.',
262
+ 'coreml.warning.customLayers': '커스텀 레이어 {count}개는 런타임에 등록이 필요합니다: {names}',
263
+ 'coreml.warning.blobMissing': '모델이 참조하는 가중치 파일 {count}개가 이 패키지에 없습니다: {names}',
264
+ 'coreml.warning.blobUnavailable': '가중치 파일 {count}개는 이 사양 파일 옆에 있으며 읽지 않았습니다: {names}',
265
+ 'coreml.warning.manifestMissing': '패키지에 Manifest.json이 없어 관례적인 경로로 모델을 찾았습니다.',
266
+ 'coreml.warning.manifestInvalid': '패키지의 Manifest.json을 읽을 수 없습니다.',
267
+ 'coreml.warning.manifestUnreadable': '패키지의 Manifest.json을 추출할 수 없어 패키지 구성 정보를 표시하지 못했습니다.',
268
+ 'coreml.warning.textTruncated': '일부 텍스트 필드가 표시 한도를 넘어 잘렸습니다.',
269
+ 'coreml.warning.archiveEntryLimit': '아카이브 항목 중 처음 {limit}개만 읽었습니다.',
270
+ 'coreml.warning.serializedModel': '비공개 직렬화 모델입니다. Apple이 내용에 대한 스키마를 공개하지 않았습니다.',
271
+ 'coreml.warning.linkedModel': '이 모델은 별도의 모델 파일을 참조하며 뷰어는 해당 파일을 읽지 않습니다.',
211
272
  'keras.title': 'Keras 모델', 'keras.document.v3': 'Keras v3 아카이브', 'keras.document.hdf5': 'Keras HDF5 모델',
212
273
  'keras.version': 'Keras {version}', 'keras.search': '레이어, 가중치, 설정 검색…',
213
274
  'keras.copyJson': 'JSON 복사', 'keras.invalid': '유효하지 않음',
@@ -449,6 +510,7 @@ export const CATALOG_KO = {
449
510
  'common.copied': '클립보드에 복사됨',
450
511
  'common.noClipboard': '이 플랫폼에서는 복사를 사용할 수 없습니다',
451
512
  'common.copyTooLarge': '너무 커서 클립보드에 복사할 수 없습니다({size}바이트). 대신 파일 내보내기를 사용하세요.',
513
+ 'common.copyTooLargeNoExport': '너무 커서 클립보드에 복사할 수 없습니다({size}바이트).',
452
514
  'common.noFileSave': '이 플랫폼에서는 파일 저장을 사용할 수 없습니다',
453
515
  'common.saved': '{name} 저장됨',
454
516
  'common.savedToOriginal': '저장됨',
@@ -197,6 +197,67 @@ export const CATALOG_ZH_CN = {
197
197
  'tflite.inspector.inputs': '输入', 'tflite.inspector.outputs': '输出',
198
198
  'tflite.inspector.intermediates': '中间张量', 'tflite.inspector.options': '选项',
199
199
  'tflite.inspector.customOptions': '自定义选项', 'tflite.inspector.subgraphs': '引用的子图',
200
+ 'coreml.title': 'Core ML 模型', 'coreml.search': '搜索算子、操作数和权重…',
201
+ 'coreml.copyJson': '复制 JSON', 'coreml.graph': '图', 'coreml.unnamed': '未命名',
202
+ 'coreml.operations': '算子', 'coreml.io': '输入与输出', 'coreml.weights': '权重',
203
+ 'coreml.packageContents': '软件包', 'coreml.modelInfo': '模型信息',
204
+ 'coreml.package': '软件包', 'coreml.updatable': '可更新',
205
+ 'coreml.specVersion': '规范 v{version}',
206
+ 'coreml.rows': '显示 {total} 行中的 {shown} 行', 'coreml.noMatches': '没有与当前搜索匹配的行。',
207
+ 'coreml.selectNode': '选择一个算子或值以查看详情。',
208
+ 'coreml.graphLimited': '图预览显示 {total} 项中的 {shown} 项。',
209
+ 'coreml.graphEdgesLimited': '仅显示前 {count} 条连接。',
210
+ 'coreml.moreItems': '另有 {count} 项…', 'coreml.optional': '可选', 'coreml.default': '默认',
211
+ 'coreml.unknown': '未知', 'coreml.external': '来自外层作用域',
212
+ 'coreml.yes': '是', 'coreml.no': '否', 'coreml.rootItem': '根模型',
213
+ 'coreml.blobPresent': '{count} 个张量,引用软件包内 {size} 中的 {referenced}',
214
+ 'coreml.blobAbsent': '{count} 个张量,引用 {referenced} — 此处没有该文件',
215
+ 'coreml.weightFiles': '权重文件',
216
+ 'coreml.summary.operations': '算子', 'coreml.summary.graphs': '图',
217
+ 'coreml.summary.inputs': '输入', 'coreml.summary.outputs': '输出',
218
+ 'coreml.summary.functions': '函数', 'coreml.summary.specVersion': '规范版本',
219
+ 'coreml.kind.operation': '算子', 'coreml.kind.layer': '层', 'coreml.kind.stage': '流水线阶段',
220
+ 'coreml.kind.input': '输入', 'coreml.kind.output': '输出', 'coreml.kind.state': '状态',
221
+ 'coreml.kind.trainingInput': '训练输入', 'coreml.kind.manifestItem': '清单条目',
222
+ 'coreml.kind.archiveMember': '压缩包成员',
223
+ 'coreml.storage.blob': '权重文件', 'coreml.storage.inline': '内嵌',
224
+ 'coreml.column.index': '#', 'coreml.column.name': '名称', 'coreml.column.type': '类型',
225
+ 'coreml.column.kind': '种类', 'coreml.column.inputs': '输入', 'coreml.column.outputs': '输出',
226
+ 'coreml.column.attributes': '属性', 'coreml.column.weights': '权重',
227
+ 'coreml.column.function': '函数', 'coreml.column.typeShape': '类型 / 形状',
228
+ 'coreml.column.flexibility': '可变性', 'coreml.column.optional': '可选',
229
+ 'coreml.column.description': '描述', 'coreml.column.graph': '图', 'coreml.column.node': '算子',
230
+ 'coreml.column.parameter': '参数', 'coreml.column.shape': '形状', 'coreml.column.elements': '元素数',
231
+ 'coreml.column.dataSize': '数据大小', 'coreml.column.storage': '存储',
232
+ 'coreml.column.location': '位置', 'coreml.column.path': '路径',
233
+ 'coreml.info.modelType': '模型类型', 'coreml.info.specVersion': '规范版本',
234
+ 'coreml.info.availability': '系统支持', 'coreml.info.description': '描述',
235
+ 'coreml.info.author': '作者', 'coreml.info.license': '许可', 'coreml.info.version': '版本',
236
+ 'coreml.info.updatable': '设备端更新', 'coreml.info.fileSize': '文件大小',
237
+ 'coreml.info.functions': '函数', 'coreml.info.defaultFunction': '默认函数',
238
+ 'coreml.info.graphs': '图', 'coreml.info.classLabels': '类别标签',
239
+ 'coreml.info.packageVersion': '软件包格式', 'coreml.info.modelPath': '模型路径',
240
+ 'coreml.inspector.inputs': '输入', 'coreml.inspector.outputs': '输出',
241
+ 'coreml.inspector.attributes': '属性', 'coreml.inspector.weights': '权重',
242
+ 'coreml.inspector.graphs': '引用的图',
243
+ 'coreml.warning.specVersion': '模型声明规范版本 {version},该查看器没有对应的系统版本信息。',
244
+ 'coreml.warning.noModelType': '模型未声明模型类型。',
245
+ 'coreml.warning.emptyGraph': '模型中没有算子。',
246
+ 'coreml.warning.emptyProgram': 'ML Program 未声明任何函数。',
247
+ 'coreml.warning.programVersion': 'ML Program 声明版本 {version};该查看器针对版本 1。',
248
+ 'coreml.warning.emptyPipeline': '流水线中没有阶段。',
249
+ 'coreml.warning.pipelineDepth': '未读取嵌套超过 {limit} 层的流水线。',
250
+ 'coreml.warning.unknownLayer': '层 {name} 没有可识别的层类型。',
251
+ 'coreml.warning.customLayers': '{count} 个自定义层需要在运行时注册:{names}',
252
+ 'coreml.warning.blobMissing': '模型引用的 {count} 个权重文件不在此软件包中:{names}',
253
+ 'coreml.warning.blobUnavailable': '{count} 个权重文件位于该规范文件旁,未被读取:{names}',
254
+ 'coreml.warning.manifestMissing': '软件包中没有 Manifest.json,已按约定路径定位模型。',
255
+ 'coreml.warning.manifestInvalid': '无法读取软件包中的 Manifest.json。',
256
+ 'coreml.warning.manifestUnreadable': '无法解压软件包中的 Manifest.json,因此未能显示软件包内容。',
257
+ 'coreml.warning.textTruncated': '部分文本字段超过显示上限,已被截断。',
258
+ 'coreml.warning.archiveEntryLimit': '仅读取了压缩包中的前 {limit} 个条目。',
259
+ 'coreml.warning.serializedModel': '这是私有的序列化模型;Apple 未公开其内容的格式。',
260
+ 'coreml.warning.linkedModel': '该模型链接到另一个模型文件,此查看器不会读取该文件。',
200
261
  'keras.title': 'Keras 模型', 'keras.document.v3': 'Keras v3 压缩包', 'keras.document.hdf5': 'Keras HDF5 模型',
201
262
  'keras.version': 'Keras {version}', 'keras.search': '搜索层、权重和配置…',
202
263
  'keras.copyJson': '复制 JSON', 'keras.invalid': '无效',
@@ -430,6 +491,7 @@ export const CATALOG_ZH_CN = {
430
491
  'common.rowsMatched': '匹配 {matched} / {total} 行', 'common.copied': '已复制到剪贴板',
431
492
  'common.noClipboard': '此平台无法复制',
432
493
  'common.copyTooLarge': '内容过大,无法复制到剪贴板({size} 字节)。请改用文件导出。',
494
+ 'common.copyTooLargeNoExport': '内容过大,无法复制到剪贴板({size} 字节)。',
433
495
  'common.noFileSave': '此平台无法保存文件', 'common.saved': '已保存 {name}',
434
496
  'common.savedToOriginal': '已保存', 'common.saveFailed': '保存失败',
435
497
  'common.unsaved': '未保存的更改', 'common.noWriteback': '此处无法保存到原文件,请使用“导出文件”。',
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Dependency-free Core ML reader for `.mlmodel` specifications and `.mlpackage`
3
+ * archives.
4
+ *
5
+ * A `.mlmodel` file is a serialized `CoreML.Specification.Model` protobuf, and
6
+ * an `.mlpackage` is a bundle whose `Manifest.json` points at one such spec plus
7
+ * the weight blobs its ML Program references. Field numbers follow the normative
8
+ * schemas published with coremltools (`Model.proto`, `FeatureTypes.proto`,
9
+ * `MIL.proto`, `NeuralNetwork.proto`).
10
+ *
11
+ * Weight payloads are never decoded. The viewer needs graph topology, feature
12
+ * types, operator attributes, and storage metadata — so blob references are
13
+ * resolved to a file, an offset, and a byte count, and inline weight tensors to
14
+ * their size and quantization, without materializing a single parameter.
15
+ *
16
+ * Two model families carry a graph, and they answer questions very differently:
17
+ *
18
+ * - An **ML Program** (`mlProgram`, Core ML 5 and newer) is self-describing, so
19
+ * operands and attributes are read exactly as the producer wrote them with no
20
+ * schema knowledge at all. An operation states its payload in two places and
21
+ * both matter: named operands under `Operation.inputs`, and an
22
+ * `Operation.attributes` map that a `const` uses for its *entire* value —
23
+ * which is where every weight an ML Program owns actually lives.
24
+ * - A **neural network** (the pre-Core ML 5 encoding) puts each layer's
25
+ * parameters in a distinct message per layer type. Layer *types* are resolved
26
+ * for all of them from the `oneof layer` field numbers, and attributes are
27
+ * decoded for the common types listed in `LAYER_SCHEMAS`. Weights need no
28
+ * such table: `WeightParams` has one shape everywhere it appears, so a
29
+ * structural scan finds them under any layer, known or not.
30
+ */
31
+ export interface CoremlEntry {
32
+ key: string;
33
+ value: string;
34
+ }
35
+ export interface CoremlWarning {
36
+ key: string;
37
+ args?: Record<string, string | number>;
38
+ }
39
+ export interface CoremlSummaryItem {
40
+ labelKey: string;
41
+ value: string | number;
42
+ }
43
+ /** A named model input, output, state, or training input. */
44
+ export interface CoremlFeature {
45
+ name: string;
46
+ /** 'image' | 'multiArray' | 'dictionary' | 'sequence' | 'int64' | 'double' |
47
+ * 'string' | 'state' | 'unknown' — the `FeatureType` oneof arm. */
48
+ typeKind: string;
49
+ /** Rendered type, e.g. `image 224 × 224 RGB` or `multiArray FLOAT32[1, 3, 224, 224]`. */
50
+ type: string;
51
+ /** Rendered size/shape flexibility, empty when the feature is fixed. */
52
+ flexibility: string;
53
+ optional: boolean;
54
+ description: string;
55
+ details: CoremlEntry[];
56
+ }
57
+ /** One prediction interface. Models before Core ML 8 declare exactly one. */
58
+ export interface CoremlFunction {
59
+ name: string;
60
+ isDefault: boolean;
61
+ inputs: CoremlFeature[];
62
+ outputs: CoremlFeature[];
63
+ state: CoremlFeature[];
64
+ trainingInputs: CoremlFeature[];
65
+ predictedFeatureName: string;
66
+ predictedProbabilitiesName: string;
67
+ }
68
+ /** A tensor a node reads from a weight blob or holds inline. */
69
+ export interface CoremlWeight {
70
+ /** Parameter name (`weight`, `bias`) or `field {n}` for an unmapped one. */
71
+ name: string;
72
+ dataType: string;
73
+ shape: string[];
74
+ elementCount: string;
75
+ byteLength: string;
76
+ /** 'blob' lives in a weight file; 'inline' is embedded in the spec. */
77
+ storage: 'blob' | 'inline';
78
+ file: string;
79
+ offset: string;
80
+ quantization: string;
81
+ updatable: boolean;
82
+ }
83
+ /** A named value: a graph input, a block argument, or an operation output. */
84
+ export interface CoremlValue {
85
+ name: string;
86
+ type: string;
87
+ }
88
+ /**
89
+ * One thing an operand is bound to. Whether that is a reference to another
90
+ * value or an inline constant is recorded here rather than inferred from the
91
+ * text later: a neural network names its operands with unconstrained strings,
92
+ * so a name like `123` — what an ONNX conversion produces — is indistinguishable
93
+ * from a numeric literal once the two are flattened together.
94
+ */
95
+ export interface CoremlBinding {
96
+ /** A variable name, or a rendered literal value. */
97
+ text: string;
98
+ /** True when `text` names a value some node produces or the graph declares. */
99
+ variable: boolean;
100
+ }
101
+ /** One operand slot. ML Program operands are named; layer operands are ordered. */
102
+ export interface CoremlPort {
103
+ /** Parameter name (`x`, `weight`) — empty for a positional layer operand. */
104
+ name: string;
105
+ values: CoremlBinding[];
106
+ }
107
+ export interface CoremlNode {
108
+ id: string;
109
+ graphId: string;
110
+ name: string;
111
+ type: string;
112
+ /** 'operation' (ML Program), 'layer' (neural network), 'stage' (pipeline). */
113
+ kind: 'operation' | 'layer' | 'stage';
114
+ /** True for an ML Program `const`, which is how a program holds a constant. */
115
+ constant: boolean;
116
+ /**
117
+ * True when the operation needs a class registered with the runtime. The
118
+ * two encodings spell this differently — a neural network has a `custom`
119
+ * layer, while an ML Program rewrites the op type to `custom_layer` — so
120
+ * the distinction is resolved here rather than by every consumer.
121
+ */
122
+ custom: boolean;
123
+ inputs: CoremlPort[];
124
+ outputs: CoremlValue[];
125
+ attributes: CoremlEntry[];
126
+ weights: CoremlWeight[];
127
+ /** Graph ids this node transfers control into (blocks, branches, stages). */
128
+ graphs: string[];
129
+ updatable: boolean;
130
+ description: string;
131
+ }
132
+ export type CoremlGraphKind = 'program' | 'block' | 'network' | 'pipeline';
133
+ export interface CoremlGraph {
134
+ id: string;
135
+ name: string;
136
+ kind: CoremlGraphKind;
137
+ /** MIL opset (`CoreML7`) or the neural network's shape-mapping mode. */
138
+ opset: string;
139
+ parentId: string;
140
+ /** Nesting level, so a picker can indent a block under its function. */
141
+ depth: number;
142
+ inputs: CoremlValue[];
143
+ outputs: string[];
144
+ nodes: CoremlNode[];
145
+ description: string;
146
+ }
147
+ /** One `Manifest.json` item of an `.mlpackage`. */
148
+ export interface CoremlPackageItem {
149
+ identifier: string;
150
+ name: string;
151
+ path: string;
152
+ author: string;
153
+ description: string;
154
+ /** Bytes the archive holds for this item; a directory sums its members. */
155
+ byteLength: string;
156
+ isRoot: boolean;
157
+ }
158
+ export interface CoremlPackage {
159
+ formatVersion: string;
160
+ rootIdentifier: string;
161
+ /** Archive path of the spec that was parsed. */
162
+ modelPath: string;
163
+ items: CoremlPackageItem[];
164
+ files: Array<{
165
+ name: string;
166
+ byteLength: string;
167
+ method: string;
168
+ }>;
169
+ }
170
+ /** A weight blob an ML Program reads its constants from. */
171
+ export interface CoremlWeightFile {
172
+ /** Name as the program spells it, e.g. `@model_path/weights/weight.bin`. */
173
+ name: string;
174
+ referenceCount: number;
175
+ /** Sum of the referenced tensors' byte lengths. */
176
+ referencedBytes: string;
177
+ /** Archive size when the package carries the file; empty when it does not. */
178
+ byteLength: string;
179
+ present: boolean;
180
+ }
181
+ export interface CoremlDocument {
182
+ format: 'coreml';
183
+ /** Model-level short description, or the model type when it has none. */
184
+ title: string;
185
+ fileSize: string;
186
+ /** True when the spec was read out of an `.mlpackage` archive. */
187
+ packaged: boolean;
188
+ specificationVersion: number;
189
+ /** `iOS 17 · macOS 14 (Core ML 7)`, or an empty string for a future version. */
190
+ availability: string;
191
+ /** The `oneof Type` arm, e.g. `mlProgram`. */
192
+ modelType: string;
193
+ isUpdatable: boolean;
194
+ shortDescription: string;
195
+ versionString: string;
196
+ author: string;
197
+ license: string;
198
+ userDefined: CoremlEntry[];
199
+ functions: CoremlFunction[];
200
+ defaultFunctionName: string;
201
+ graphs: CoremlGraph[];
202
+ classLabels: {
203
+ kind: 'string' | 'int64' | '';
204
+ values: string[];
205
+ total: number;
206
+ };
207
+ weightFiles: CoremlWeightFile[];
208
+ package?: CoremlPackage;
209
+ summary: CoremlSummaryItem[];
210
+ warnings: CoremlWarning[];
211
+ }
212
+ export declare class CoremlParseError extends Error {
213
+ readonly name = "CoremlParseError";
214
+ }
215
+ export interface CoremlParseOptions {
216
+ signal?: AbortSignal;
217
+ }
218
+ /**
219
+ * Reads a Core ML model from either encoding. `.mlpackage` bytes are recognized
220
+ * by their ZIP header, so a caller never has to say which one it holds.
221
+ */
222
+ export declare function parseCoreml(data: Uint8Array, options?: CoremlParseOptions): Promise<CoremlDocument>;
223
+ /** Reads a bare `.mlmodel` specification. */
224
+ export declare function parseCoremlSpec(data: Uint8Array): CoremlDocument;
225
+ /**
226
+ * True when the bytes open with a Core ML specification. Used for content
227
+ * routing where the extension is absent, so it stays deliberately strict: a
228
+ * `specificationVersion` in the published range plus a description or a model
229
+ * type, read without trusting anything past the fields it checks.
230
+ */
231
+ export declare function looksLikeCoremlSpec(data: Uint8Array): boolean;
232
+ export declare function formatFileSize(bytes: number | bigint): string;