tempest-react-sdk 0.69.0 → 0.70.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 (77) hide show
  1. package/README.md +1 -1
  2. package/dist/vision/core/canvas.cjs +1 -1
  3. package/dist/vision/core/canvas.cjs.map +1 -1
  4. package/dist/vision/core/canvas.js +37 -13
  5. package/dist/vision/core/canvas.js.map +1 -1
  6. package/dist/vision/core/dtypes.cjs +2 -0
  7. package/dist/vision/core/dtypes.cjs.map +1 -0
  8. package/dist/vision/core/dtypes.js +33 -0
  9. package/dist/vision/core/dtypes.js.map +1 -0
  10. package/dist/vision/core/graph.cjs +1 -1
  11. package/dist/vision/core/graph.cjs.map +1 -1
  12. package/dist/vision/core/graph.js +10 -2
  13. package/dist/vision/core/graph.js.map +1 -1
  14. package/dist/vision/core/metadata.cjs +2 -2
  15. package/dist/vision/core/metadata.cjs.map +1 -1
  16. package/dist/vision/core/metadata.js +103 -13
  17. package/dist/vision/core/metadata.js.map +1 -1
  18. package/dist/vision/core/providers.cjs +1 -1
  19. package/dist/vision/core/providers.cjs.map +1 -1
  20. package/dist/vision/core/providers.js +9 -6
  21. package/dist/vision/core/providers.js.map +1 -1
  22. package/dist/vision/core/session.cjs +1 -1
  23. package/dist/vision/core/session.cjs.map +1 -1
  24. package/dist/vision/core/session.js +115 -27
  25. package/dist/vision/core/session.js.map +1 -1
  26. package/dist/vision/fusion.cjs +1 -1
  27. package/dist/vision/fusion.cjs.map +1 -1
  28. package/dist/vision/fusion.js +28 -23
  29. package/dist/vision/fusion.js.map +1 -1
  30. package/dist/vision/index.cjs +1 -1
  31. package/dist/vision/index.cjs.map +1 -1
  32. package/dist/vision/index.js +20 -19
  33. package/dist/vision/index.js.map +1 -1
  34. package/dist/vision/io/image.cjs +1 -1
  35. package/dist/vision/io/image.cjs.map +1 -1
  36. package/dist/vision/io/image.js +55 -20
  37. package/dist/vision/io/image.js.map +1 -1
  38. package/dist/vision/postprocess/detection.cjs +1 -1
  39. package/dist/vision/postprocess/detection.cjs.map +1 -1
  40. package/dist/vision/postprocess/detection.js +42 -51
  41. package/dist/vision/postprocess/detection.js.map +1 -1
  42. package/dist/vision/postprocess/segmentation.cjs +1 -1
  43. package/dist/vision/postprocess/segmentation.cjs.map +1 -1
  44. package/dist/vision/postprocess/segmentation.js +45 -31
  45. package/dist/vision/postprocess/segmentation.js.map +1 -1
  46. package/dist/vision/preprocess/pipeline.cjs +1 -1
  47. package/dist/vision/preprocess/pipeline.cjs.map +1 -1
  48. package/dist/vision/preprocess/pipeline.js +24 -25
  49. package/dist/vision/preprocess/pipeline.js.map +1 -1
  50. package/dist/vision/tasks/base.cjs +1 -1
  51. package/dist/vision/tasks/base.cjs.map +1 -1
  52. package/dist/vision/tasks/base.js +22 -7
  53. package/dist/vision/tasks/base.js.map +1 -1
  54. package/dist/vision/tasks/classifier.cjs +1 -1
  55. package/dist/vision/tasks/classifier.cjs.map +1 -1
  56. package/dist/vision/tasks/classifier.js +64 -55
  57. package/dist/vision/tasks/classifier.js.map +1 -1
  58. package/dist/vision/tasks/detectClassify.cjs +1 -1
  59. package/dist/vision/tasks/detectClassify.cjs.map +1 -1
  60. package/dist/vision/tasks/detectClassify.js +80 -69
  61. package/dist/vision/tasks/detectClassify.js.map +1 -1
  62. package/dist/vision/tasks/detector.cjs +1 -1
  63. package/dist/vision/tasks/detector.cjs.map +1 -1
  64. package/dist/vision/tasks/detector.js +74 -68
  65. package/dist/vision/tasks/detector.js.map +1 -1
  66. package/dist/vision/tasks/segmenter.cjs +1 -1
  67. package/dist/vision/tasks/segmenter.cjs.map +1 -1
  68. package/dist/vision/tasks/segmenter.js +85 -62
  69. package/dist/vision/tasks/segmenter.js.map +1 -1
  70. package/dist/vision/types.cjs +1 -1
  71. package/dist/vision/types.cjs.map +1 -1
  72. package/dist/vision/types.js +24 -4
  73. package/dist/vision/types.js.map +1 -1
  74. package/dist/vision.cjs +1 -1
  75. package/dist/vision.d.ts +1153 -777
  76. package/dist/vision.js +22 -21
  77. package/package.json +1 -1
package/README.md CHANGED
@@ -320,7 +320,7 @@ Every module is re-exported from the package root — `import { Button, useDebou
320
320
  | `push` | `WebPushClient`, `WebPushUnsupportedError`, `WebPushPermissionDeniedError`, `usePushSubscription`, `urlBase64ToUint8Array`, `isPushSupported` |
321
321
  | `sw` _(also subpath `tempest-react-sdk/sw`)_ | `registerServiceWorker` (opt-in `autoUpdate` poll + reload, no `vite-plugin-pwa`), `skipWaiting`, `unregisterAllServiceWorkers`, `installPushHandler`, `installNotificationClickHandler`, `installSkipWaitingListener`, `installPrecache` (app-shell offline + Navigation Preload), `installRuntimeCache` (per-route caching, incl. `rangeRequests`), `createPartialResponse` (206 range slicing), `installBackgroundSync` (offline mutation queue + `periodicsync`), `registerPeriodicSync` (main-thread periodic sync), `inspectCaches`/`clearCaches` (cache observability) — the React-free `tempest-react-sdk/sw` subpath is ideal for bundling into your own `sw.ts` |
322
322
  | `editor` _(subpath `tempest-react-sdk/editor`, opt. peers `@tiptap/react`+`@tiptap/starter-kit`)_ | `RichTextEditor` — themed tiptap v3 rich-text editor with toolbar (tiptap externalized; install it only if you use the editor) |
323
- | `vision` _(subpath `tempest-react-sdk/vision`, opt. peer `onnxruntime-web`)_ | `Classifier`, `Detector`, `Segmenter`, `DetectClassify` (fused detect→classify pipeline) + `warmup()`, `raiseOnEmpty`/`NoDetectionsError`, `LetterboxPipeline`, `readFusionSpec` and results/labels/preprocess — on-device ONNX vision inference, vendored from `@mauriciobenjamin700/ort-vision-sdk-web` (onnxruntime-web externalized; install it only if you use vision). Plus browser capture primitives: `useCameraStream` (rear-camera `getUserMedia` + classified errors + `retry()`), `computeImageLuminance`/`isLuminanceAcceptable`/`LowLuminanceError`/`LUMINANCE_SAMPLE_MAX_EDGE` (BT.709 brightness), `useLiveLuminance` (live rAF sampling) |
323
+ | `vision` _(subpath `tempest-react-sdk/vision`, opt. peer `onnxruntime-web`)_ | `Classifier`, `Detector`, `Segmenter`, `DetectClassify` (fused detect→classify pipeline, optionally with a segmentation stage) + `warmup()`, FP16 models, `cache` (Cache Storage), video/`VideoFrame` inputs, `raiseOnEmpty`/`NoDetectionsError`, `LetterboxPipeline`, `readFusionSpec` and results/labels/preprocess — on-device ONNX vision inference, vendored from `@mauriciobenjamin700/ort-vision-sdk-web` (onnxruntime-web externalized; install it only if you use vision). Plus browser capture primitives: `useCameraStream` (rear-camera `getUserMedia` + classified errors + `retry()`), `computeImageLuminance`/`isLuminanceAcceptable`/`LowLuminanceError`/`LUMINANCE_SAMPLE_MAX_EDGE` (BT.709 brightness), `useLiveLuminance` (live rAF sampling) |
324
324
  | `tabular` _(subpath `tempest-react-sdk/tabular`, opt. peer `onnxruntime-web`)_ | `TabularPredictor`, `useTabularPredictor` — scikit-learn models exported by `tempest-fastapi-sdk`'s `export_sklearn_to_onnx`, running in the browser with no inference server. Offline by design: `fetchModelBytes`/`isModelCached`/`cacheModelBytes`/`clearModelCache` (Cache Storage, cache-first) plus `configureOrtAssets`/`ortAssetUrls`/`ORT_WASM_ASSETS` for the runtime's WebAssembly binaries, which ONNX Runtime Web fetches at session creation. Import the default `onnxruntime-web` entry — the WebGPU build has no `ai.onnx.ml` kernels |
325
325
  | `imaging` _(subpath `tempest-react-sdk/imaging`, no deps)_ | `resizeImage`, `cropImage`, `rotateImage`, `flipImage`, `compressToTarget` (binary-searches quality into a byte budget), `createThumbnails` (several sizes from one decode), `captureFrame` (one frame out of a `<video>`, at the instant you ask for), `decodeImage`/`readImageInfo`, `encodeImage`, `supportsImageType`/`bestSupportedType`, plus `useImagePreview`/`useImageProcessing`. Canvas only — decodes with EXIF orientation applied (phone photos arrive upright), reports the format actually produced (asking for AVIF where there is no encoder silently returns PNG), and re-encoding drops EXIF, which is the privacy step as much as the bandwidth one. `captureFrame` is the one with teeth: `seeked` does not mean the new frame is readable, so the naive seek-then-draw returns the neighbouring frame with no error — and a `MediaRecorder` blob reports no duration until it is probed for one, which it does for you |
326
326
  | `audio` | `createAudioPlayer`, `playAudio`, `stopAudio`, `useAudio`, `createAudioBus` / `useAudioBus` (gain above 100%, post-mix limiter, `setSinkId` routing), `DEFAULT_MAX_GAIN` |
@@ -1,2 +1,2 @@
1
- const e=require("./exceptions.cjs"),t=require("../types.cjs");function n(t,n){if(typeof OffscreenCanvas<`u`)return new OffscreenCanvas(t,n);if(typeof document<`u`){let e=document.createElement(`canvas`);return e.width=t,e.height=n,e}throw new e.ImageLoadError(`No canvas implementation available in this environment.`)}function r(t,n={}){let r=t.getContext(`2d`,n);if(r===null)throw new e.ImageLoadError(`Failed to obtain 2D rendering context.`);return r}function i(n){let{data:r,width:i,height:a}=n;if(r.length!==i*a*4)throw new e.ImageLoadError(`Unexpected ImageData length ${r.length} for ${i}x${a} (expected ${i*a*4}).`);let o=new Uint8Array(i*a*3);for(let e=0,t=0;e<r.length;e+=4,t+=3)o[t]=r[e],o[t+1]=r[e+1],o[t+2]=r[e+2];return new t.RGBImage(o,i,a)}function a(e){let t=new Uint8ClampedArray(e.width*e.height*4);for(let n=0,r=0;n<e.data.length;n+=3,r+=4)t[r]=e.data[n],t[r+1]=e.data[n+1],t[r+2]=e.data[n+2],t[r+3]=255;return new ImageData(t,e.width,e.height)}exports.createCanvas=n,exports.get2DContext=r,exports.imageDataToRGB=i,exports.rgbToImageData=a;
1
+ const e=require("./exceptions.cjs"),t=require("../types.cjs");var n=new Uint8Array(new Uint32Array([1]).buffer)[0]===1;function r(t,n){if(typeof OffscreenCanvas<`u`)return new OffscreenCanvas(t,n);if(typeof document<`u`){let e=document.createElement(`canvas`);return e.width=t,e.height=n,e}throw new e.ImageLoadError(`No canvas implementation available in this environment.`)}function i(t,n={}){let r=t.getContext(`2d`,n);if(r===null)throw new e.ImageLoadError(`Failed to obtain 2D rendering context.`);return r}function a(e){return o(e).image}function o(r){let{data:i,width:a,height:o}=r;if(i.length!==a*o*4)throw new e.ImageLoadError(`Unexpected ImageData length ${i.length} for ${a}x${o} (expected ${a*o*4}).`);let s=a*o,c=new Uint8Array(s*3);if(n&&i.byteOffset%4==0){let e=new Uint32Array(i.buffer,i.byteOffset,s),n=-1;for(let t=0,r=0;t<s;t++,r+=3){let i=e[t];c[r]=i,c[r+1]=i>>>8,c[r+2]=i>>>16,n&=i}return{image:new t.RGBImage(c,a,o),opaque:n>>>24==255}}let l=255;for(let e=0,t=0;e<i.length;e+=4,t+=3)c[t]=i[e],c[t+1]=i[e+1],c[t+2]=i[e+2],l&=i[e+3];return{image:new t.RGBImage(c,a,o),opaque:l===255}}function s(e){let t=e.width*e.height,r=new Uint8ClampedArray(t*4),i=e.data;if(n){let n=new Uint32Array(r.buffer);for(let e=0,r=0;e<t;e++,r+=3)n[e]=(i[r]|i[r+1]<<8|i[r+2]<<16|4278190080)>>>0;return new ImageData(r,e.width,e.height)}for(let t=0,n=0;t<e.data.length;t+=3,n+=4)r[n]=e.data[t],r[n+1]=e.data[t+1],r[n+2]=e.data[t+2],r[n+3]=255;return new ImageData(r,e.width,e.height)}exports.createCanvas=r,exports.get2DContext=i,exports.imageDataToRGB=a,exports.imageDataToRGBChecked=o,exports.rgbToImageData=s;
2
2
  //# sourceMappingURL=canvas.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"canvas.cjs","names":[],"sources":["../../../src/vision/core/canvas.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Canvas plumbing shared by `io/image.ts` and `preprocess/image.ts`.\n *\n * Browsers and workers expose two canvas types (`HTMLCanvasElement` and\n * `OffscreenCanvas`) with slightly different surfaces. These helpers pick the\n * right one for the current environment, return a unified 2D context, and\n * convert between RGBA `ImageData` and the SDK's canonical HWC RGB\n * `RGBImage`.\n */\n\nimport { ImageLoadError } from \"./exceptions\";\nimport { RGBImage } from \"../types\";\n\nexport type Canvas2D = HTMLCanvasElement | OffscreenCanvas;\nexport type Context2D = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n\n/** Allocate a `Canvas2D`, preferring `OffscreenCanvas` when available. */\nexport function createCanvas(width: number, height: number): Canvas2D {\n if (typeof OffscreenCanvas !== \"undefined\") {\n return new OffscreenCanvas(width, height);\n }\n if (typeof document !== \"undefined\") {\n const c = document.createElement(\"canvas\");\n c.width = width;\n c.height = height;\n return c;\n }\n throw new ImageLoadError(\"No canvas implementation available in this environment.\");\n}\n\n/**\n * Get a 2D context from a canvas, throwing a typed error if the browser refuses.\n *\n * @param canvas The canvas to obtain a context for.\n * @param options Context attributes, forwarded verbatim. `willReadFrequently`\n * tells the browser the canvas is read back with `getImageData` repeatedly,\n * which moves the backing store to software: faster readback, slower\n * compositing. Whether it pays depends on the surface, so it is the caller's\n * call rather than a default here.\n */\nexport function get2DContext(\n canvas: Canvas2D,\n options: CanvasRenderingContext2DSettings = {},\n): Context2D {\n const ctx = canvas.getContext(\"2d\", options) as Context2D | null;\n if (ctx === null) {\n throw new ImageLoadError(\"Failed to obtain 2D rendering context.\");\n }\n return ctx;\n}\n\n/** Convert RGBA `ImageData` into the canonical HWC RGB `RGBImage`. */\nexport function imageDataToRGB(imageData: ImageData): RGBImage {\n const { data, width, height } = imageData;\n if (data.length !== width * height * 4) {\n throw new ImageLoadError(\n `Unexpected ImageData length ${data.length} for ${width}x${height} (expected ${\n width * height * 4\n }).`,\n );\n }\n const rgb = new Uint8Array(width * height * 3);\n for (let i = 0, j = 0; i < data.length; i += 4, j += 3) {\n rgb[j] = data[i] as number;\n rgb[j + 1] = data[i + 1] as number;\n rgb[j + 2] = data[i + 2] as number;\n }\n return new RGBImage(rgb, width, height);\n}\n\n/** Convert an `RGBImage` into RGBA `ImageData` (alpha forced to 255). */\nexport function rgbToImageData(image: RGBImage): ImageData {\n const data = new Uint8ClampedArray(image.width * image.height * 4);\n for (let i = 0, j = 0; i < image.data.length; i += 3, j += 4) {\n data[j] = image.data[i] as number;\n data[j + 1] = image.data[i + 1] as number;\n data[j + 2] = image.data[i + 2] as number;\n data[j + 3] = 255;\n }\n return new ImageData(data, image.width, image.height);\n}\n"],"mappings":"8DAkBA,SAAgB,EAAa,EAAe,EAA0B,CAClE,GAAI,OAAO,gBAAoB,IAC3B,OAAO,IAAI,gBAAgB,EAAO,CAAM,EAE5C,GAAI,OAAO,SAAa,IAAa,CACjC,IAAM,EAAI,SAAS,cAAc,QAAQ,EAGzC,MAFA,GAAE,MAAQ,EACV,EAAE,OAAS,EACJ,CACX,CACA,MAAM,IAAI,EAAA,eAAe,yDAAyD,CACtF,CAYA,SAAgB,EACZ,EACA,EAA4C,CAAC,EACpC,CACT,IAAM,EAAM,EAAO,WAAW,KAAM,CAAO,EAC3C,GAAI,IAAQ,KACR,MAAM,IAAI,EAAA,eAAe,wCAAwC,EAErE,OAAO,CACX,CAGA,SAAgB,EAAe,EAAgC,CAC3D,GAAM,CAAE,OAAM,QAAO,UAAW,EAChC,GAAI,EAAK,SAAW,EAAQ,EAAS,EACjC,MAAM,IAAI,EAAA,eACN,+BAA+B,EAAK,OAAO,OAAO,EAAM,GAAG,EAAO,aAC9D,EAAQ,EAAS,EACpB,GACL,EAEJ,IAAM,EAAM,IAAI,WAAW,EAAQ,EAAS,CAAC,EAC7C,IAAK,IAAI,EAAI,EAAG,EAAI,EAAG,EAAI,EAAK,OAAQ,GAAK,EAAG,GAAK,EACjD,EAAI,GAAK,EAAK,GACd,EAAI,EAAI,GAAK,EAAK,EAAI,GACtB,EAAI,EAAI,GAAK,EAAK,EAAI,GAE1B,OAAO,IAAI,EAAA,SAAS,EAAK,EAAO,CAAM,CAC1C,CAGA,SAAgB,EAAe,EAA4B,CACvD,IAAM,EAAO,IAAI,kBAAkB,EAAM,MAAQ,EAAM,OAAS,CAAC,EACjE,IAAK,IAAI,EAAI,EAAG,EAAI,EAAG,EAAI,EAAM,KAAK,OAAQ,GAAK,EAAG,GAAK,EACvD,EAAK,GAAK,EAAM,KAAK,GACrB,EAAK,EAAI,GAAK,EAAM,KAAK,EAAI,GAC7B,EAAK,EAAI,GAAK,EAAM,KAAK,EAAI,GAC7B,EAAK,EAAI,GAAK,IAElB,OAAO,IAAI,UAAU,EAAM,EAAM,MAAO,EAAM,MAAM,CACxD"}
1
+ {"version":3,"file":"canvas.cjs","names":[],"sources":["../../../src/vision/core/canvas.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Canvas plumbing shared by `io/image.ts` and `preprocess/image.ts`.\n *\n * Browsers and workers expose two canvas types (`HTMLCanvasElement` and\n * `OffscreenCanvas`) with slightly different surfaces. These helpers pick the\n * right one for the current environment, return a unified 2D context, and\n * convert between RGBA `ImageData` and the SDK's canonical HWC RGB\n * `RGBImage`.\n */\n\nimport { ImageLoadError } from \"./exceptions\";\nimport { RGBImage } from \"../types\";\n\nexport type Canvas2D = HTMLCanvasElement | OffscreenCanvas;\n\n/**\n * Whether typed-array words are stored least-significant byte first.\n *\n * The pixel conversions below move one RGBA pixel as one `Uint32` — about a\n * quarter fewer milliseconds per 1080p frame than four byte accesses — which\n * only maps `R` to the low byte on a little-endian platform. Every browser\n * engine in use is little-endian; the byte-wise loops stay as the fallback so\n * correctness never rests on that.\n */\nconst LITTLE_ENDIAN = new Uint8Array(new Uint32Array([1]).buffer)[0] === 1;\nexport type Context2D = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n\n/** Allocate a `Canvas2D`, preferring `OffscreenCanvas` when available. */\nexport function createCanvas(width: number, height: number): Canvas2D {\n if (typeof OffscreenCanvas !== \"undefined\") {\n return new OffscreenCanvas(width, height);\n }\n if (typeof document !== \"undefined\") {\n const c = document.createElement(\"canvas\");\n c.width = width;\n c.height = height;\n return c;\n }\n throw new ImageLoadError(\"No canvas implementation available in this environment.\");\n}\n\n/**\n * Get a 2D context from a canvas, throwing a typed error if the browser refuses.\n *\n * @param canvas The canvas to obtain a context for.\n * @param options Context attributes, forwarded verbatim. `willReadFrequently`\n * tells the browser the canvas is read back with `getImageData` repeatedly,\n * which moves the backing store to software: faster readback, slower\n * compositing. Whether it pays depends on the surface, so it is the caller's\n * call rather than a default here.\n */\nexport function get2DContext(\n canvas: Canvas2D,\n options: CanvasRenderingContext2DSettings = {},\n): Context2D {\n const ctx = canvas.getContext(\"2d\", options) as Context2D | null;\n if (ctx === null) {\n throw new ImageLoadError(\"Failed to obtain 2D rendering context.\");\n }\n return ctx;\n}\n\n/** Convert RGBA `ImageData` into the canonical HWC RGB `RGBImage`. */\nexport function imageDataToRGB(imageData: ImageData): RGBImage {\n return imageDataToRGBChecked(imageData).image;\n}\n\n/** An {@link RGBImage} plus whether the RGBA it came from was fully opaque. */\nexport interface CheckedRGB {\n readonly image: RGBImage;\n /** `true` when every source pixel had alpha 255. */\n readonly opaque: boolean;\n}\n\n/**\n * Convert RGBA `ImageData` into an `RGBImage`, noting whether alpha was all 255.\n *\n * Dropping alpha is lossy only when some pixel was translucent: the RGB kept is\n * the un-premultiplied colour, which {@link rgbToImageData} later paints back as\n * fully opaque. A canvas still holding the original RGBA composites that pixel\n * differently, so it can stand in for the `RGBImage` only when nothing was\n * translucent — which is what `opaque` reports. The check rides the copy loop\n * that already reads every alpha byte, so it costs one AND per pixel. The loop\n * reads a whole pixel as one `Uint32` where {@link LITTLE_ENDIAN} allows.\n *\n * @param imageData Source pixels.\n * @returns The packed RGB image and the opacity verdict.\n * @throws {@link ImageLoadError} if the buffer length does not match the size.\n */\nexport function imageDataToRGBChecked(imageData: ImageData): CheckedRGB {\n const { data, width, height } = imageData;\n if (data.length !== width * height * 4) {\n throw new ImageLoadError(\n `Unexpected ImageData length ${data.length} for ${width}x${height} (expected ${\n width * height * 4\n }).`,\n );\n }\n const pixels = width * height;\n const rgb = new Uint8Array(pixels * 3);\n if (LITTLE_ENDIAN && data.byteOffset % 4 === 0) {\n const words = new Uint32Array(data.buffer, data.byteOffset, pixels);\n let alpha = -1;\n for (let p = 0, j = 0; p < pixels; p++, j += 3) {\n const word = words[p] as number;\n rgb[j] = word;\n rgb[j + 1] = word >>> 8;\n rgb[j + 2] = word >>> 16;\n alpha &= word;\n }\n return { image: new RGBImage(rgb, width, height), opaque: alpha >>> 24 === 255 };\n }\n let alpha = 255;\n for (let i = 0, j = 0; i < data.length; i += 4, j += 3) {\n rgb[j] = data[i] as number;\n rgb[j + 1] = data[i + 1] as number;\n rgb[j + 2] = data[i + 2] as number;\n alpha &= data[i + 3] as number;\n }\n return { image: new RGBImage(rgb, width, height), opaque: alpha === 255 };\n}\n\n/**\n * Convert an `RGBImage` into RGBA `ImageData` (alpha forced to 255).\n *\n * Writes one 32-bit word per pixel where the platform allows — see\n * {@link LITTLE_ENDIAN} — instead of four separate byte stores.\n */\nexport function rgbToImageData(image: RGBImage): ImageData {\n const pixels = image.width * image.height;\n const data = new Uint8ClampedArray(pixels * 4);\n const src = image.data;\n if (LITTLE_ENDIAN) {\n const words = new Uint32Array(data.buffer);\n for (let p = 0, i = 0; p < pixels; p++, i += 3) {\n words[p] =\n ((src[i] as number) |\n ((src[i + 1] as number) << 8) |\n ((src[i + 2] as number) << 16) |\n 0xff000000) >>>\n 0;\n }\n return new ImageData(data, image.width, image.height);\n }\n for (let i = 0, j = 0; i < image.data.length; i += 3, j += 4) {\n data[j] = image.data[i] as number;\n data[j + 1] = image.data[i + 1] as number;\n data[j + 2] = image.data[i + 2] as number;\n data[j + 3] = 255;\n }\n return new ImageData(data, image.width, image.height);\n}\n"],"mappings":"8DAyBA,IAAM,EAAgB,IAAI,WAAW,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAO,EAIzE,SAAgB,EAAa,EAAe,EAA0B,CAClE,GAAI,OAAO,gBAAoB,IAC3B,OAAO,IAAI,gBAAgB,EAAO,CAAM,EAE5C,GAAI,OAAO,SAAa,IAAa,CACjC,IAAM,EAAI,SAAS,cAAc,QAAQ,EAGzC,MAFA,GAAE,MAAQ,EACV,EAAE,OAAS,EACJ,CACX,CACA,MAAM,IAAI,EAAA,eAAe,yDAAyD,CACtF,CAYA,SAAgB,EACZ,EACA,EAA4C,CAAC,EACpC,CACT,IAAM,EAAM,EAAO,WAAW,KAAM,CAAO,EAC3C,GAAI,IAAQ,KACR,MAAM,IAAI,EAAA,eAAe,wCAAwC,EAErE,OAAO,CACX,CAGA,SAAgB,EAAe,EAAgC,CAC3D,OAAO,EAAsB,CAAS,CAAC,CAAC,KAC5C,CAwBA,SAAgB,EAAsB,EAAkC,CACpE,GAAM,CAAE,OAAM,QAAO,UAAW,EAChC,GAAI,EAAK,SAAW,EAAQ,EAAS,EACjC,MAAM,IAAI,EAAA,eACN,+BAA+B,EAAK,OAAO,OAAO,EAAM,GAAG,EAAO,aAC9D,EAAQ,EAAS,EACpB,GACL,EAEJ,IAAM,EAAS,EAAQ,EACjB,EAAM,IAAI,WAAW,EAAS,CAAC,EACrC,GAAI,GAAiB,EAAK,WAAa,GAAM,EAAG,CAC5C,IAAM,EAAQ,IAAI,YAAY,EAAK,OAAQ,EAAK,WAAY,CAAM,EAC9D,EAAQ,GACZ,IAAK,IAAI,EAAI,EAAG,EAAI,EAAG,EAAI,EAAQ,IAAK,GAAK,EAAG,CAC5C,IAAM,EAAO,EAAM,GACnB,EAAI,GAAK,EACT,EAAI,EAAI,GAAK,IAAS,EACtB,EAAI,EAAI,GAAK,IAAS,GACtB,GAAS,CACb,CACA,MAAO,CAAE,MAAO,IAAI,EAAA,SAAS,EAAK,EAAO,CAAM,EAAG,OAAQ,IAAU,IAAO,GAAI,CACnF,CACA,IAAI,EAAQ,IACZ,IAAK,IAAI,EAAI,EAAG,EAAI,EAAG,EAAI,EAAK,OAAQ,GAAK,EAAG,GAAK,EACjD,EAAI,GAAK,EAAK,GACd,EAAI,EAAI,GAAK,EAAK,EAAI,GACtB,EAAI,EAAI,GAAK,EAAK,EAAI,GACtB,GAAS,EAAK,EAAI,GAEtB,MAAO,CAAE,MAAO,IAAI,EAAA,SAAS,EAAK,EAAO,CAAM,EAAG,OAAQ,IAAU,GAAI,CAC5E,CAQA,SAAgB,EAAe,EAA4B,CACvD,IAAM,EAAS,EAAM,MAAQ,EAAM,OAC7B,EAAO,IAAI,kBAAkB,EAAS,CAAC,EACvC,EAAM,EAAM,KAClB,GAAI,EAAe,CACf,IAAM,EAAQ,IAAI,YAAY,EAAK,MAAM,EACzC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAG,EAAI,EAAQ,IAAK,GAAK,EACzC,EAAM,IACA,EAAI,GACA,EAAI,EAAI,IAAiB,EACzB,EAAI,EAAI,IAAiB,GAC3B,cACJ,EAER,OAAO,IAAI,UAAU,EAAM,EAAM,MAAO,EAAM,MAAM,CACxD,CACA,IAAK,IAAI,EAAI,EAAG,EAAI,EAAG,EAAI,EAAM,KAAK,OAAQ,GAAK,EAAG,GAAK,EACvD,EAAK,GAAK,EAAM,KAAK,GACrB,EAAK,EAAI,GAAK,EAAM,KAAK,EAAI,GAC7B,EAAK,EAAI,GAAK,EAAM,KAAK,EAAI,GAC7B,EAAK,EAAI,GAAK,IAElB,OAAO,IAAI,UAAU,EAAM,EAAM,MAAO,EAAM,MAAM,CACxD"}
@@ -1,7 +1,8 @@
1
1
  import { ImageLoadError as e } from "./exceptions.js";
2
2
  import { RGBImage as t } from "../types.js";
3
3
  //#region src/vision/core/canvas.ts
4
- function n(t, n) {
4
+ var n = new Uint8Array(new Uint32Array([1]).buffer)[0] === 1;
5
+ function r(t, n) {
5
6
  if (typeof OffscreenCanvas < "u") return new OffscreenCanvas(t, n);
6
7
  if (typeof document < "u") {
7
8
  let e = document.createElement("canvas");
@@ -9,24 +10,47 @@ function n(t, n) {
9
10
  }
10
11
  throw new e("No canvas implementation available in this environment.");
11
12
  }
12
- function r(t, n = {}) {
13
+ function i(t, n = {}) {
13
14
  let r = t.getContext("2d", n);
14
15
  if (r === null) throw new e("Failed to obtain 2D rendering context.");
15
16
  return r;
16
17
  }
17
- function i(n) {
18
- let { data: r, width: i, height: a } = n;
19
- if (r.length !== i * a * 4) throw new e(`Unexpected ImageData length ${r.length} for ${i}x${a} (expected ${i * a * 4}).`);
20
- let o = new Uint8Array(i * a * 3);
21
- for (let e = 0, t = 0; e < r.length; e += 4, t += 3) o[t] = r[e], o[t + 1] = r[e + 1], o[t + 2] = r[e + 2];
22
- return new t(o, i, a);
23
- }
24
18
  function a(e) {
25
- let t = new Uint8ClampedArray(e.width * e.height * 4);
26
- for (let n = 0, r = 0; n < e.data.length; n += 3, r += 4) t[r] = e.data[n], t[r + 1] = e.data[n + 1], t[r + 2] = e.data[n + 2], t[r + 3] = 255;
27
- return new ImageData(t, e.width, e.height);
19
+ return o(e).image;
20
+ }
21
+ function o(r) {
22
+ let { data: i, width: a, height: o } = r;
23
+ if (i.length !== a * o * 4) throw new e(`Unexpected ImageData length ${i.length} for ${a}x${o} (expected ${a * o * 4}).`);
24
+ let s = a * o, c = new Uint8Array(s * 3);
25
+ if (n && i.byteOffset % 4 == 0) {
26
+ let e = new Uint32Array(i.buffer, i.byteOffset, s), n = -1;
27
+ for (let t = 0, r = 0; t < s; t++, r += 3) {
28
+ let i = e[t];
29
+ c[r] = i, c[r + 1] = i >>> 8, c[r + 2] = i >>> 16, n &= i;
30
+ }
31
+ return {
32
+ image: new t(c, a, o),
33
+ opaque: n >>> 24 == 255
34
+ };
35
+ }
36
+ let l = 255;
37
+ for (let e = 0, t = 0; e < i.length; e += 4, t += 3) c[t] = i[e], c[t + 1] = i[e + 1], c[t + 2] = i[e + 2], l &= i[e + 3];
38
+ return {
39
+ image: new t(c, a, o),
40
+ opaque: l === 255
41
+ };
42
+ }
43
+ function s(e) {
44
+ let t = e.width * e.height, r = new Uint8ClampedArray(t * 4), i = e.data;
45
+ if (n) {
46
+ let n = new Uint32Array(r.buffer);
47
+ for (let e = 0, r = 0; e < t; e++, r += 3) n[e] = (i[r] | i[r + 1] << 8 | i[r + 2] << 16 | 4278190080) >>> 0;
48
+ return new ImageData(r, e.width, e.height);
49
+ }
50
+ for (let t = 0, n = 0; t < e.data.length; t += 3, n += 4) r[n] = e.data[t], r[n + 1] = e.data[t + 1], r[n + 2] = e.data[t + 2], r[n + 3] = 255;
51
+ return new ImageData(r, e.width, e.height);
28
52
  }
29
53
  //#endregion
30
- export { n as createCanvas, r as get2DContext, i as imageDataToRGB, a as rgbToImageData };
54
+ export { r as createCanvas, i as get2DContext, a as imageDataToRGB, o as imageDataToRGBChecked, s as rgbToImageData };
31
55
 
32
56
  //# sourceMappingURL=canvas.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"canvas.js","names":[],"sources":["../../../src/vision/core/canvas.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Canvas plumbing shared by `io/image.ts` and `preprocess/image.ts`.\n *\n * Browsers and workers expose two canvas types (`HTMLCanvasElement` and\n * `OffscreenCanvas`) with slightly different surfaces. These helpers pick the\n * right one for the current environment, return a unified 2D context, and\n * convert between RGBA `ImageData` and the SDK's canonical HWC RGB\n * `RGBImage`.\n */\n\nimport { ImageLoadError } from \"./exceptions\";\nimport { RGBImage } from \"../types\";\n\nexport type Canvas2D = HTMLCanvasElement | OffscreenCanvas;\nexport type Context2D = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n\n/** Allocate a `Canvas2D`, preferring `OffscreenCanvas` when available. */\nexport function createCanvas(width: number, height: number): Canvas2D {\n if (typeof OffscreenCanvas !== \"undefined\") {\n return new OffscreenCanvas(width, height);\n }\n if (typeof document !== \"undefined\") {\n const c = document.createElement(\"canvas\");\n c.width = width;\n c.height = height;\n return c;\n }\n throw new ImageLoadError(\"No canvas implementation available in this environment.\");\n}\n\n/**\n * Get a 2D context from a canvas, throwing a typed error if the browser refuses.\n *\n * @param canvas The canvas to obtain a context for.\n * @param options Context attributes, forwarded verbatim. `willReadFrequently`\n * tells the browser the canvas is read back with `getImageData` repeatedly,\n * which moves the backing store to software: faster readback, slower\n * compositing. Whether it pays depends on the surface, so it is the caller's\n * call rather than a default here.\n */\nexport function get2DContext(\n canvas: Canvas2D,\n options: CanvasRenderingContext2DSettings = {},\n): Context2D {\n const ctx = canvas.getContext(\"2d\", options) as Context2D | null;\n if (ctx === null) {\n throw new ImageLoadError(\"Failed to obtain 2D rendering context.\");\n }\n return ctx;\n}\n\n/** Convert RGBA `ImageData` into the canonical HWC RGB `RGBImage`. */\nexport function imageDataToRGB(imageData: ImageData): RGBImage {\n const { data, width, height } = imageData;\n if (data.length !== width * height * 4) {\n throw new ImageLoadError(\n `Unexpected ImageData length ${data.length} for ${width}x${height} (expected ${\n width * height * 4\n }).`,\n );\n }\n const rgb = new Uint8Array(width * height * 3);\n for (let i = 0, j = 0; i < data.length; i += 4, j += 3) {\n rgb[j] = data[i] as number;\n rgb[j + 1] = data[i + 1] as number;\n rgb[j + 2] = data[i + 2] as number;\n }\n return new RGBImage(rgb, width, height);\n}\n\n/** Convert an `RGBImage` into RGBA `ImageData` (alpha forced to 255). */\nexport function rgbToImageData(image: RGBImage): ImageData {\n const data = new Uint8ClampedArray(image.width * image.height * 4);\n for (let i = 0, j = 0; i < image.data.length; i += 3, j += 4) {\n data[j] = image.data[i] as number;\n data[j + 1] = image.data[i + 1] as number;\n data[j + 2] = image.data[i + 2] as number;\n data[j + 3] = 255;\n }\n return new ImageData(data, image.width, image.height);\n}\n"],"mappings":";;;AAkBA,SAAgB,EAAa,GAAe,GAA0B;CAClE,IAAI,OAAO,kBAAoB,KAC3B,OAAO,IAAI,gBAAgB,GAAO,CAAM;CAE5C,IAAI,OAAO,WAAa,KAAa;EACjC,IAAM,IAAI,SAAS,cAAc,QAAQ;EAGzC,OAFA,EAAE,QAAQ,GACV,EAAE,SAAS,GACJ;CACX;CACA,MAAM,IAAI,EAAe,yDAAyD;AACtF;AAYA,SAAgB,EACZ,GACA,IAA4C,CAAC,GACpC;CACT,IAAM,IAAM,EAAO,WAAW,MAAM,CAAO;CAC3C,IAAI,MAAQ,MACR,MAAM,IAAI,EAAe,wCAAwC;CAErE,OAAO;AACX;AAGA,SAAgB,EAAe,GAAgC;CAC3D,IAAM,EAAE,SAAM,UAAO,cAAW;CAChC,IAAI,EAAK,WAAW,IAAQ,IAAS,GACjC,MAAM,IAAI,EACN,+BAA+B,EAAK,OAAO,OAAO,EAAM,GAAG,EAAO,aAC9D,IAAQ,IAAS,EACpB,GACL;CAEJ,IAAM,IAAM,IAAI,WAAW,IAAQ,IAAS,CAAC;CAC7C,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK,GAAG,KAAK,GAGjD,AAFA,EAAI,KAAK,EAAK,IACd,EAAI,IAAI,KAAK,EAAK,IAAI,IACtB,EAAI,IAAI,KAAK,EAAK,IAAI;CAE1B,OAAO,IAAI,EAAS,GAAK,GAAO,CAAM;AAC1C;AAGA,SAAgB,EAAe,GAA4B;CACvD,IAAM,IAAO,IAAI,kBAAkB,EAAM,QAAQ,EAAM,SAAS,CAAC;CACjE,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,EAAM,KAAK,QAAQ,KAAK,GAAG,KAAK,GAIvD,AAHA,EAAK,KAAK,EAAM,KAAK,IACrB,EAAK,IAAI,KAAK,EAAM,KAAK,IAAI,IAC7B,EAAK,IAAI,KAAK,EAAM,KAAK,IAAI,IAC7B,EAAK,IAAI,KAAK;CAElB,OAAO,IAAI,UAAU,GAAM,EAAM,OAAO,EAAM,MAAM;AACxD"}
1
+ {"version":3,"file":"canvas.js","names":[],"sources":["../../../src/vision/core/canvas.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Canvas plumbing shared by `io/image.ts` and `preprocess/image.ts`.\n *\n * Browsers and workers expose two canvas types (`HTMLCanvasElement` and\n * `OffscreenCanvas`) with slightly different surfaces. These helpers pick the\n * right one for the current environment, return a unified 2D context, and\n * convert between RGBA `ImageData` and the SDK's canonical HWC RGB\n * `RGBImage`.\n */\n\nimport { ImageLoadError } from \"./exceptions\";\nimport { RGBImage } from \"../types\";\n\nexport type Canvas2D = HTMLCanvasElement | OffscreenCanvas;\n\n/**\n * Whether typed-array words are stored least-significant byte first.\n *\n * The pixel conversions below move one RGBA pixel as one `Uint32` — about a\n * quarter fewer milliseconds per 1080p frame than four byte accesses — which\n * only maps `R` to the low byte on a little-endian platform. Every browser\n * engine in use is little-endian; the byte-wise loops stay as the fallback so\n * correctness never rests on that.\n */\nconst LITTLE_ENDIAN = new Uint8Array(new Uint32Array([1]).buffer)[0] === 1;\nexport type Context2D = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n\n/** Allocate a `Canvas2D`, preferring `OffscreenCanvas` when available. */\nexport function createCanvas(width: number, height: number): Canvas2D {\n if (typeof OffscreenCanvas !== \"undefined\") {\n return new OffscreenCanvas(width, height);\n }\n if (typeof document !== \"undefined\") {\n const c = document.createElement(\"canvas\");\n c.width = width;\n c.height = height;\n return c;\n }\n throw new ImageLoadError(\"No canvas implementation available in this environment.\");\n}\n\n/**\n * Get a 2D context from a canvas, throwing a typed error if the browser refuses.\n *\n * @param canvas The canvas to obtain a context for.\n * @param options Context attributes, forwarded verbatim. `willReadFrequently`\n * tells the browser the canvas is read back with `getImageData` repeatedly,\n * which moves the backing store to software: faster readback, slower\n * compositing. Whether it pays depends on the surface, so it is the caller's\n * call rather than a default here.\n */\nexport function get2DContext(\n canvas: Canvas2D,\n options: CanvasRenderingContext2DSettings = {},\n): Context2D {\n const ctx = canvas.getContext(\"2d\", options) as Context2D | null;\n if (ctx === null) {\n throw new ImageLoadError(\"Failed to obtain 2D rendering context.\");\n }\n return ctx;\n}\n\n/** Convert RGBA `ImageData` into the canonical HWC RGB `RGBImage`. */\nexport function imageDataToRGB(imageData: ImageData): RGBImage {\n return imageDataToRGBChecked(imageData).image;\n}\n\n/** An {@link RGBImage} plus whether the RGBA it came from was fully opaque. */\nexport interface CheckedRGB {\n readonly image: RGBImage;\n /** `true` when every source pixel had alpha 255. */\n readonly opaque: boolean;\n}\n\n/**\n * Convert RGBA `ImageData` into an `RGBImage`, noting whether alpha was all 255.\n *\n * Dropping alpha is lossy only when some pixel was translucent: the RGB kept is\n * the un-premultiplied colour, which {@link rgbToImageData} later paints back as\n * fully opaque. A canvas still holding the original RGBA composites that pixel\n * differently, so it can stand in for the `RGBImage` only when nothing was\n * translucent — which is what `opaque` reports. The check rides the copy loop\n * that already reads every alpha byte, so it costs one AND per pixel. The loop\n * reads a whole pixel as one `Uint32` where {@link LITTLE_ENDIAN} allows.\n *\n * @param imageData Source pixels.\n * @returns The packed RGB image and the opacity verdict.\n * @throws {@link ImageLoadError} if the buffer length does not match the size.\n */\nexport function imageDataToRGBChecked(imageData: ImageData): CheckedRGB {\n const { data, width, height } = imageData;\n if (data.length !== width * height * 4) {\n throw new ImageLoadError(\n `Unexpected ImageData length ${data.length} for ${width}x${height} (expected ${\n width * height * 4\n }).`,\n );\n }\n const pixels = width * height;\n const rgb = new Uint8Array(pixels * 3);\n if (LITTLE_ENDIAN && data.byteOffset % 4 === 0) {\n const words = new Uint32Array(data.buffer, data.byteOffset, pixels);\n let alpha = -1;\n for (let p = 0, j = 0; p < pixels; p++, j += 3) {\n const word = words[p] as number;\n rgb[j] = word;\n rgb[j + 1] = word >>> 8;\n rgb[j + 2] = word >>> 16;\n alpha &= word;\n }\n return { image: new RGBImage(rgb, width, height), opaque: alpha >>> 24 === 255 };\n }\n let alpha = 255;\n for (let i = 0, j = 0; i < data.length; i += 4, j += 3) {\n rgb[j] = data[i] as number;\n rgb[j + 1] = data[i + 1] as number;\n rgb[j + 2] = data[i + 2] as number;\n alpha &= data[i + 3] as number;\n }\n return { image: new RGBImage(rgb, width, height), opaque: alpha === 255 };\n}\n\n/**\n * Convert an `RGBImage` into RGBA `ImageData` (alpha forced to 255).\n *\n * Writes one 32-bit word per pixel where the platform allows — see\n * {@link LITTLE_ENDIAN} — instead of four separate byte stores.\n */\nexport function rgbToImageData(image: RGBImage): ImageData {\n const pixels = image.width * image.height;\n const data = new Uint8ClampedArray(pixels * 4);\n const src = image.data;\n if (LITTLE_ENDIAN) {\n const words = new Uint32Array(data.buffer);\n for (let p = 0, i = 0; p < pixels; p++, i += 3) {\n words[p] =\n ((src[i] as number) |\n ((src[i + 1] as number) << 8) |\n ((src[i + 2] as number) << 16) |\n 0xff000000) >>>\n 0;\n }\n return new ImageData(data, image.width, image.height);\n }\n for (let i = 0, j = 0; i < image.data.length; i += 3, j += 4) {\n data[j] = image.data[i] as number;\n data[j + 1] = image.data[i + 1] as number;\n data[j + 2] = image.data[i + 2] as number;\n data[j + 3] = 255;\n }\n return new ImageData(data, image.width, image.height);\n}\n"],"mappings":";;;AAyBA,IAAM,IAAgB,IAAI,WAAW,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO;AAIzE,SAAgB,EAAa,GAAe,GAA0B;CAClE,IAAI,OAAO,kBAAoB,KAC3B,OAAO,IAAI,gBAAgB,GAAO,CAAM;CAE5C,IAAI,OAAO,WAAa,KAAa;EACjC,IAAM,IAAI,SAAS,cAAc,QAAQ;EAGzC,OAFA,EAAE,QAAQ,GACV,EAAE,SAAS,GACJ;CACX;CACA,MAAM,IAAI,EAAe,yDAAyD;AACtF;AAYA,SAAgB,EACZ,GACA,IAA4C,CAAC,GACpC;CACT,IAAM,IAAM,EAAO,WAAW,MAAM,CAAO;CAC3C,IAAI,MAAQ,MACR,MAAM,IAAI,EAAe,wCAAwC;CAErE,OAAO;AACX;AAGA,SAAgB,EAAe,GAAgC;CAC3D,OAAO,EAAsB,CAAS,CAAC,CAAC;AAC5C;AAwBA,SAAgB,EAAsB,GAAkC;CACpE,IAAM,EAAE,SAAM,UAAO,cAAW;CAChC,IAAI,EAAK,WAAW,IAAQ,IAAS,GACjC,MAAM,IAAI,EACN,+BAA+B,EAAK,OAAO,OAAO,EAAM,GAAG,EAAO,aAC9D,IAAQ,IAAS,EACpB,GACL;CAEJ,IAAM,IAAS,IAAQ,GACjB,IAAM,IAAI,WAAW,IAAS,CAAC;CACrC,IAAI,KAAiB,EAAK,aAAa,KAAM,GAAG;EAC5C,IAAM,IAAQ,IAAI,YAAY,EAAK,QAAQ,EAAK,YAAY,CAAM,GAC9D,IAAQ;EACZ,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,GAAQ,KAAK,KAAK,GAAG;GAC5C,IAAM,IAAO,EAAM;GAInB,AAHA,EAAI,KAAK,GACT,EAAI,IAAI,KAAK,MAAS,GACtB,EAAI,IAAI,KAAK,MAAS,IACtB,KAAS;EACb;EACA,OAAO;GAAE,OAAO,IAAI,EAAS,GAAK,GAAO,CAAM;GAAG,QAAQ,MAAU,MAAO;EAAI;CACnF;CACA,IAAI,IAAQ;CACZ,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK,GAAG,KAAK,GAIjD,AAHA,EAAI,KAAK,EAAK,IACd,EAAI,IAAI,KAAK,EAAK,IAAI,IACtB,EAAI,IAAI,KAAK,EAAK,IAAI,IACtB,KAAS,EAAK,IAAI;CAEtB,OAAO;EAAE,OAAO,IAAI,EAAS,GAAK,GAAO,CAAM;EAAG,QAAQ,MAAU;CAAI;AAC5E;AAQA,SAAgB,EAAe,GAA4B;CACvD,IAAM,IAAS,EAAM,QAAQ,EAAM,QAC7B,IAAO,IAAI,kBAAkB,IAAS,CAAC,GACvC,IAAM,EAAM;CAClB,IAAI,GAAe;EACf,IAAM,IAAQ,IAAI,YAAY,EAAK,MAAM;EACzC,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,GAAQ,KAAK,KAAK,GACzC,EAAM,MACA,EAAI,KACA,EAAI,IAAI,MAAiB,IACzB,EAAI,IAAI,MAAiB,KAC3B,gBACJ;EAER,OAAO,IAAI,UAAU,GAAM,EAAM,OAAO,EAAM,MAAM;CACxD;CACA,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,EAAM,KAAK,QAAQ,KAAK,GAAG,KAAK,GAIvD,AAHA,EAAK,KAAK,EAAM,KAAK,IACrB,EAAK,IAAI,KAAK,EAAM,KAAK,IAAI,IAC7B,EAAK,IAAI,KAAK,EAAM,KAAK,IAAI,IAC7B,EAAK,IAAI,KAAK;CAElB,OAAO,IAAI,UAAU,GAAM,EAAM,OAAO,EAAM,MAAM;AACxD"}
@@ -0,0 +1,2 @@
1
+ var e={1:`float32`,2:`uint8`,3:`int8`,4:`uint16`,5:`int16`,6:`int32`,7:`int64`,9:`bool`,10:`float16`,11:`float64`,12:`uint32`,13:`uint64`},t=`float32`,n=globalThis.Float16Array;function r(){return n!==void 0}function i(n){return n===void 0?t:e[n]??`float32`}function a(e,t){if(t!==`float16`)return e;if(n===void 0)throw RangeError(`This model declares a float16 input, but this environment has no Float16Array.`);return new n(e)}function o(e){return e instanceof Float32Array?e:Float32Array.from(e)}exports.DEFAULT_TENSOR_TYPE=t,exports.asFloat32Array=o,exports.hasFloat16Array=r,exports.tensorTypeFor=i,exports.toFeedData=a;
2
+ //# sourceMappingURL=dtypes.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dtypes.cjs","names":[],"sources":["../../../src/vision/core/dtypes.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * What element type the graph declares, and what typed array that means.\n *\n * A model exported with `half=True` declares its input as `float16`, and ONNX\n * Runtime refuses a float32 feed against it:\n *\n * ```text\n * Unexpected input data type. Actual: (tensor(float)) , expected: (tensor(float16))\n * ```\n *\n * The session opens without complaint, so the failure lands on the caller's\n * first `predict()` rather than on `create()`. Preprocessing stays in\n * `Float32Array` because that is where the normalization arithmetic belongs —\n * `(value / 255 - mean) / std` in half precision loses exactly the small\n * differences normalization exists to preserve — and the conversion happens\n * once, at the feed boundary.\n *\n * Outputs travel the other way. Float16 carries 11 bits of mantissa, so at\n * pixel scale its neighbouring values are 0.5 apart around coordinate 640 and\n * 1.0 apart around 1280: decoding boxes in that type quantises every coordinate\n * before NMS and the scale-back to original-image pixels ever run. {@link\n * asFloat32Array} widens a half-precision output before the decoders touch it.\n *\n * `Float16Array` is what ORT requires for a half tensor — a `Uint16Array` of\n * the same bits is rejected — and it is not in every browser yet, so\n * {@link hasFloat16Array} exists to refuse at session creation instead of on\n * the first frame.\n */\n\n/** ONNX `TensorProto.DataType` values this SDK can name. */\nconst ELEM_TYPE_TO_TENSOR_TYPE: Readonly<Record<number, string>> = {\n 1: \"float32\",\n 2: \"uint8\",\n 3: \"int8\",\n 4: \"uint16\",\n 5: \"int16\",\n 6: \"int32\",\n 7: \"int64\",\n 9: \"bool\",\n 10: \"float16\",\n 11: \"float64\",\n 12: \"uint32\",\n 13: \"uint64\",\n};\n\n/** The element type every task preprocesses to, and the fallback when unknown. */\nexport const DEFAULT_TENSOR_TYPE = \"float32\";\n\n/**\n * The structural surface of `Float16Array` this module needs.\n *\n * Declared here rather than pulled from `lib.es2025`: the package targets\n * ES2022 so it builds for consumers on older TypeScript, and the only thing\n * needed is \"an array-like of numbers ORT recognises as half precision\".\n */\nexport interface Float16ArrayLike {\n readonly length: number;\n readonly buffer: ArrayBufferLike;\n [index: number]: number;\n}\n\ninterface Float16ArrayConstructor {\n new (input: ArrayLike<number> | number): Float16ArrayLike;\n}\n\nconst FLOAT16_ARRAY = (globalThis as { Float16Array?: Float16ArrayConstructor }).Float16Array;\n\n/**\n * Whether this environment can build a half-precision tensor at all.\n *\n * @returns `true` when the runtime exposes `Float16Array`. ORT rejects any\n * other typed array for a `float16` tensor, so a `false` here means half\n * precision is unreachable in this browser no matter what the model declares.\n */\nexport function hasFloat16Array(): boolean {\n return FLOAT16_ARRAY !== undefined;\n}\n\n/**\n * Name the tensor type an ONNX element type maps to.\n *\n * @param elemType A `TensorProto.DataType` value read off the graph.\n * @returns The ORT tensor type name, or `\"float32\"` for anything unrecognised —\n * which is what every task produces anyway, so an unknown type surfaces as\n * ORT's own type error against the real graph rather than as a lookup miss.\n */\nexport function tensorTypeFor(elemType: number | undefined): string {\n if (elemType === undefined) return DEFAULT_TENSOR_TYPE;\n return ELEM_TYPE_TO_TENSOR_TYPE[elemType] ?? DEFAULT_TENSOR_TYPE;\n}\n\n/**\n * Convert a preprocessed float32 buffer to the type a feed must carry.\n *\n * @param data The preprocessed planar buffer.\n * @param tensorType The tensor type the input declares, from\n * {@link tensorTypeFor}.\n * @returns `data` itself for a float32 input, or a `Float16Array` holding the\n * same values for a half-precision one.\n * @throws {RangeError} If half precision is asked for and the runtime has no\n * `Float16Array`. Callers convert this into a `ModelLoadError` at session\n * creation, so it never reaches a `predict()`.\n */\nexport function toFeedData(\n data: Float32Array,\n tensorType: string,\n): Float32Array | Float16ArrayLike {\n if (tensorType !== \"float16\") return data;\n if (FLOAT16_ARRAY === undefined) {\n throw new RangeError(\n \"This model declares a float16 input, but this environment has no Float16Array.\",\n );\n }\n return new FLOAT16_ARRAY(data);\n}\n\n/**\n * Widen a model output to `Float32Array`, without copying when it already is.\n *\n * @param data A tensor's `data`, as ORT returned it.\n * @returns The same values as a `Float32Array`. A float32 output is passed\n * through untouched; anything else is copied once.\n */\nexport function asFloat32Array(data: unknown): Float32Array {\n if (data instanceof Float32Array) return data;\n return Float32Array.from(data as ArrayLike<number>);\n}\n"],"mappings":"AA+BA,IAAM,EAA6D,CAC/D,EAAG,UACH,EAAG,QACH,EAAG,OACH,EAAG,SACH,EAAG,QACH,EAAG,QACH,EAAG,QACH,EAAG,OACH,GAAI,UACJ,GAAI,UACJ,GAAI,SACJ,GAAI,QACR,EAGa,EAAsB,UAmB7B,EAAiB,WAA0D,aASjF,SAAgB,GAA2B,CACvC,OAAO,IAAkB,IAAA,EAC7B,CAUA,SAAgB,EAAc,EAAsC,CAEhE,OADI,IAAa,IAAA,GAAkB,EAC5B,EAAyB,IAAA,SACpC,CAcA,SAAgB,EACZ,EACA,EAC+B,CAC/B,GAAI,IAAe,UAAW,OAAO,EACrC,GAAI,IAAkB,IAAA,GAClB,MAAU,WACN,gFACJ,EAEJ,OAAO,IAAI,EAAc,CAAI,CACjC,CASA,SAAgB,EAAe,EAA6B,CAExD,OADI,aAAgB,aAAqB,EAClC,aAAa,KAAK,CAAyB,CACtD"}
@@ -0,0 +1,33 @@
1
+ //#region src/vision/core/dtypes.ts
2
+ var e = {
3
+ 1: "float32",
4
+ 2: "uint8",
5
+ 3: "int8",
6
+ 4: "uint16",
7
+ 5: "int16",
8
+ 6: "int32",
9
+ 7: "int64",
10
+ 9: "bool",
11
+ 10: "float16",
12
+ 11: "float64",
13
+ 12: "uint32",
14
+ 13: "uint64"
15
+ }, t = "float32", n = globalThis.Float16Array;
16
+ function r() {
17
+ return n !== void 0;
18
+ }
19
+ function i(n) {
20
+ return n === void 0 ? t : e[n] ?? "float32";
21
+ }
22
+ function a(e, t) {
23
+ if (t !== "float16") return e;
24
+ if (n === void 0) throw RangeError("This model declares a float16 input, but this environment has no Float16Array.");
25
+ return new n(e);
26
+ }
27
+ function o(e) {
28
+ return e instanceof Float32Array ? e : Float32Array.from(e);
29
+ }
30
+ //#endregion
31
+ export { t as DEFAULT_TENSOR_TYPE, o as asFloat32Array, r as hasFloat16Array, i as tensorTypeFor, a as toFeedData };
32
+
33
+ //# sourceMappingURL=dtypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dtypes.js","names":[],"sources":["../../../src/vision/core/dtypes.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * What element type the graph declares, and what typed array that means.\n *\n * A model exported with `half=True` declares its input as `float16`, and ONNX\n * Runtime refuses a float32 feed against it:\n *\n * ```text\n * Unexpected input data type. Actual: (tensor(float)) , expected: (tensor(float16))\n * ```\n *\n * The session opens without complaint, so the failure lands on the caller's\n * first `predict()` rather than on `create()`. Preprocessing stays in\n * `Float32Array` because that is where the normalization arithmetic belongs —\n * `(value / 255 - mean) / std` in half precision loses exactly the small\n * differences normalization exists to preserve — and the conversion happens\n * once, at the feed boundary.\n *\n * Outputs travel the other way. Float16 carries 11 bits of mantissa, so at\n * pixel scale its neighbouring values are 0.5 apart around coordinate 640 and\n * 1.0 apart around 1280: decoding boxes in that type quantises every coordinate\n * before NMS and the scale-back to original-image pixels ever run. {@link\n * asFloat32Array} widens a half-precision output before the decoders touch it.\n *\n * `Float16Array` is what ORT requires for a half tensor — a `Uint16Array` of\n * the same bits is rejected — and it is not in every browser yet, so\n * {@link hasFloat16Array} exists to refuse at session creation instead of on\n * the first frame.\n */\n\n/** ONNX `TensorProto.DataType` values this SDK can name. */\nconst ELEM_TYPE_TO_TENSOR_TYPE: Readonly<Record<number, string>> = {\n 1: \"float32\",\n 2: \"uint8\",\n 3: \"int8\",\n 4: \"uint16\",\n 5: \"int16\",\n 6: \"int32\",\n 7: \"int64\",\n 9: \"bool\",\n 10: \"float16\",\n 11: \"float64\",\n 12: \"uint32\",\n 13: \"uint64\",\n};\n\n/** The element type every task preprocesses to, and the fallback when unknown. */\nexport const DEFAULT_TENSOR_TYPE = \"float32\";\n\n/**\n * The structural surface of `Float16Array` this module needs.\n *\n * Declared here rather than pulled from `lib.es2025`: the package targets\n * ES2022 so it builds for consumers on older TypeScript, and the only thing\n * needed is \"an array-like of numbers ORT recognises as half precision\".\n */\nexport interface Float16ArrayLike {\n readonly length: number;\n readonly buffer: ArrayBufferLike;\n [index: number]: number;\n}\n\ninterface Float16ArrayConstructor {\n new (input: ArrayLike<number> | number): Float16ArrayLike;\n}\n\nconst FLOAT16_ARRAY = (globalThis as { Float16Array?: Float16ArrayConstructor }).Float16Array;\n\n/**\n * Whether this environment can build a half-precision tensor at all.\n *\n * @returns `true` when the runtime exposes `Float16Array`. ORT rejects any\n * other typed array for a `float16` tensor, so a `false` here means half\n * precision is unreachable in this browser no matter what the model declares.\n */\nexport function hasFloat16Array(): boolean {\n return FLOAT16_ARRAY !== undefined;\n}\n\n/**\n * Name the tensor type an ONNX element type maps to.\n *\n * @param elemType A `TensorProto.DataType` value read off the graph.\n * @returns The ORT tensor type name, or `\"float32\"` for anything unrecognised —\n * which is what every task produces anyway, so an unknown type surfaces as\n * ORT's own type error against the real graph rather than as a lookup miss.\n */\nexport function tensorTypeFor(elemType: number | undefined): string {\n if (elemType === undefined) return DEFAULT_TENSOR_TYPE;\n return ELEM_TYPE_TO_TENSOR_TYPE[elemType] ?? DEFAULT_TENSOR_TYPE;\n}\n\n/**\n * Convert a preprocessed float32 buffer to the type a feed must carry.\n *\n * @param data The preprocessed planar buffer.\n * @param tensorType The tensor type the input declares, from\n * {@link tensorTypeFor}.\n * @returns `data` itself for a float32 input, or a `Float16Array` holding the\n * same values for a half-precision one.\n * @throws {RangeError} If half precision is asked for and the runtime has no\n * `Float16Array`. Callers convert this into a `ModelLoadError` at session\n * creation, so it never reaches a `predict()`.\n */\nexport function toFeedData(\n data: Float32Array,\n tensorType: string,\n): Float32Array | Float16ArrayLike {\n if (tensorType !== \"float16\") return data;\n if (FLOAT16_ARRAY === undefined) {\n throw new RangeError(\n \"This model declares a float16 input, but this environment has no Float16Array.\",\n );\n }\n return new FLOAT16_ARRAY(data);\n}\n\n/**\n * Widen a model output to `Float32Array`, without copying when it already is.\n *\n * @param data A tensor's `data`, as ORT returned it.\n * @returns The same values as a `Float32Array`. A float32 output is passed\n * through untouched; anything else is copied once.\n */\nexport function asFloat32Array(data: unknown): Float32Array {\n if (data instanceof Float32Array) return data;\n return Float32Array.from(data as ArrayLike<number>);\n}\n"],"mappings":";AA+BA,IAAM,IAA6D;CAC/D,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACR,GAGa,IAAsB,WAmB7B,IAAiB,WAA0D;AASjF,SAAgB,IAA2B;CACvC,OAAO,MAAkB,KAAA;AAC7B;AAUA,SAAgB,EAAc,GAAsC;CAEhE,OADI,MAAa,KAAA,IAAkB,IAC5B,EAAyB,MAAA;AACpC;AAcA,SAAgB,EACZ,GACA,GAC+B;CAC/B,IAAI,MAAe,WAAW,OAAO;CACrC,IAAI,MAAkB,KAAA,GAClB,MAAU,WACN,gFACJ;CAEJ,OAAO,IAAI,EAAc,CAAI;AACjC;AASA,SAAgB,EAAe,GAA6B;CAExD,OADI,aAAgB,eAAqB,IAClC,aAAa,KAAK,CAAyB;AACtD"}
@@ -1,2 +1,2 @@
1
- function e(e){return e===void 0?[]:e.map(e=>e.isTensor?e.shape.map(e=>typeof e==`number`&&Number.isInteger(e)&&e>0?e:null):[])}function t(e){if(e.length!==4)return null;let t=e[2],n=e[3];return t==null||n==null?null:[n,t]}function n(e){let t=e.filter(e=>e!==null&&e>1);if(t.length===0)return null;let n=Math.min(...t);return n<5?null:n-4}function r(e){let t=e[e.length-1];return t==null||t<1?null:t}function i(e){let n=e.graphShape===void 0?null:t(e.graphShape),r=e.requested;return n===null?r??e.fallback:(r!==void 0&&(r[0]!==n[0]||r[1]!==n[1])&&console.warn(`[ort-vision-sdk] The model declares a ${n[0]}x${n[1]} input; ignoring the requested ${r[0]}x${r[1]}, which ONNX Runtime would reject.`),n)}exports.classificationNumClasses=r,exports.declaredShapesFrom=e,exports.detectionNumClasses=n,exports.resolveInputSize=i,exports.spatialInputSize=t;
1
+ function e(e){return e===void 0?[]:e.map(e=>e.isTensor?e.shape.map(e=>typeof e==`number`&&Number.isInteger(e)&&e>0?e:null):[])}function t(e){if(e.length!==4)return null;let t=e[2],n=e[3];return t==null||n==null?null:[n,t]}function n(e){let t=e.filter(e=>e!==null&&e>1);if(t.length===0)return null;let n=Math.min(...t);return n<5?null:n-4}function r(e){let t=e.find(e=>e.length===3);if(t===void 0)return null;let n=t.filter(e=>e!==null&&e>1);if(n.length===0)return null;let r=Math.min(...n),i=e.find(e=>e.length===4)?.[1],a=typeof i==`number`&&i>0?i:32,o=r-4-a;return o>0?o:null}function i(e){let t=e[e.length-1];return t==null||t<1?null:t}function a(e){let n=e.graphShape===void 0?null:t(e.graphShape),r=e.requested;return n===null?r??e.fallback:(r!==void 0&&(r[0]!==n[0]||r[1]!==n[1])&&console.warn(`[ort-vision-sdk] The model declares a ${n[0]}x${n[1]} input; ignoring the requested ${r[0]}x${r[1]}, which ONNX Runtime would reject.`),n)}exports.classificationNumClasses=i,exports.declaredShapesFrom=e,exports.detectionNumClasses=n,exports.resolveInputSize=a,exports.segmentationNumClasses=r,exports.spatialInputSize=t;
2
2
  //# sourceMappingURL=graph.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"graph.cjs","names":[],"sources":["../../../src/vision/core/graph.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * What the ONNX graph itself says about its inputs.\n *\n * The resolution a session must be fed at is a property of the exported model,\n * not of the configuration around it. Feeding a 640x640 tensor to a graph\n * exported at 224x224 makes ORT abort the run with\n * `Got invalid dimensions for input: images ... Got: 640 Expected: 224`, and the\n * caller has no way to see that coming from the outside — the number lives in\n * the file. So the SDK reads it from the graph and treats any configured size as\n * a fallback for when the graph leaves it open.\n */\n\nimport type * as ort from \"onnxruntime-web\";\n\n/**\n * One declared dimension: a number when the graph pins it, `null` when the\n * dimension is symbolic (dynamic).\n */\nexport type DeclaredDim = number | null;\n\n/** A declared input/output shape, dynamic axes appearing as `null`. */\nexport type DeclaredShape = readonly DeclaredDim[];\n\n/**\n * Convert ORT value metadata into declared shapes.\n *\n * @param metadata Metadata as reported by `InferenceSession.inputMetadata`, or\n * `undefined` on ORT builds that predate it (added in onnxruntime 1.21).\n * @returns One shape per value, in declaration order. Non-tensor values and\n * builds without metadata yield empty shapes, which read as \"nothing\n * declared\" everywhere downstream.\n */\nexport function declaredShapesFrom(\n metadata: readonly ort.InferenceSession.ValueMetadata[] | undefined,\n): readonly DeclaredShape[] {\n if (metadata === undefined) return [];\n return metadata.map((value) =>\n value.isTensor\n ? value.shape.map((dim) =>\n typeof dim === \"number\" && Number.isInteger(dim) && dim > 0 ? dim : null,\n )\n : [],\n );\n}\n\n/**\n * Read the spatial input size out of a declared NCHW shape.\n *\n * @param shape The declared shape of the model's image input.\n * @returns `[width, height]` in pixels, or `null` when the shape is not 4D or\n * leaves either spatial axis dynamic — in which case the model accepts more\n * than one resolution and there is nothing to correct.\n */\nexport function spatialInputSize(shape: DeclaredShape): readonly [number, number] | null {\n if (shape.length !== 4) return null;\n const height = shape[2];\n const width = shape[3];\n if (height === null || height === undefined || width === null || width === undefined)\n return null;\n return [width, height];\n}\n\n/**\n * Infer how many classes a YOLO detection/segmentation head emits.\n *\n * Such a head declares `(B, 4 + nc, N)` — four box coordinates stacked above one\n * score per class, over `N` candidate anchors. `N` is in the thousands and the\n * batch is 1, so the channel axis is the smallest static axis above 1.\n *\n * @param shape Declared shape of the model's first output.\n * @returns The class count, or `null` when the shape leaves it undeterminable —\n * fully dynamic, or too small to hold boxes plus at least one class.\n */\nexport function detectionNumClasses(shape: DeclaredShape): number | null {\n const staticDims = shape.filter((dim): dim is number => dim !== null && dim > 1);\n if (staticDims.length === 0) return null;\n const channels = Math.min(...staticDims);\n if (channels < 5) return null;\n return channels - 4;\n}\n\n/**\n * Infer how many classes a classification head emits.\n *\n * A classifier declares `(B, nc)`, so the count is the last static axis.\n *\n * @param shape Declared shape of the model's first output.\n * @returns The class count, or `null` when the last axis is dynamic or absent.\n */\nexport function classificationNumClasses(shape: DeclaredShape): number | null {\n const last = shape[shape.length - 1];\n if (last === null || last === undefined || last < 1) return null;\n return last;\n}\n\nexport interface ResolveInputSizeOptions {\n /** Declared shape of the model's image input, from {@link declaredShapesFrom}. */\n readonly graphShape?: DeclaredShape;\n /** Size the caller asked for, if any. */\n readonly requested?: readonly [number, number];\n /** Size to use when neither the graph nor the caller pins one. */\n readonly fallback: readonly [number, number];\n}\n\n/**\n * Decide the input size a task will preprocess to.\n *\n * Precedence is graph → caller → fallback. The graph wins over an explicit\n * `inputSize` because a static shape is not a preference, it is what ORT will\n * accept: honoring the caller there would only turn a fixable mismatch into a\n * failed run. A disagreement is a configuration bug in the caller, so it is\n * reported through `console.warn` instead of being swallowed.\n *\n * @param options Graph shape, requested size and per-task fallback.\n * @returns The `[width, height]` to preprocess to.\n */\nexport function resolveInputSize(options: ResolveInputSizeOptions): readonly [number, number] {\n const graph = options.graphShape === undefined ? null : spatialInputSize(options.graphShape);\n const requested = options.requested;\n if (graph === null) return requested ?? options.fallback;\n if (requested !== undefined && (requested[0] !== graph[0] || requested[1] !== graph[1])) {\n console.warn(\n `[ort-vision-sdk] The model declares a ${graph[0]}x${graph[1]} input; ` +\n `ignoring the requested ${requested[0]}x${requested[1]}, which ONNX Runtime would reject.`,\n );\n }\n return graph;\n}\n"],"mappings":"AAiCA,SAAgB,EACZ,EACwB,CAExB,OADI,IAAa,IAAA,GAAkB,CAAC,EAC7B,EAAS,IAAK,GACjB,EAAM,SACA,EAAM,MAAM,IAAK,GACb,OAAO,GAAQ,UAAY,OAAO,UAAU,CAAG,GAAK,EAAM,EAAI,EAAM,IACxE,EACA,CAAC,CACX,CACJ,CAUA,SAAgB,EAAiB,EAAwD,CACrF,GAAI,EAAM,SAAW,EAAG,OAAO,KAC/B,IAAM,EAAS,EAAM,GACf,EAAQ,EAAM,GAGpB,OAFI,GAAW,MAAgC,GAAU,KAC9C,KACJ,CAAC,EAAO,CAAM,CACzB,CAaA,SAAgB,EAAoB,EAAqC,CACrE,IAAM,EAAa,EAAM,OAAQ,GAAuB,IAAQ,MAAQ,EAAM,CAAC,EAC/E,GAAI,EAAW,SAAW,EAAG,OAAO,KACpC,IAAM,EAAW,KAAK,IAAI,GAAG,CAAU,EAEvC,OADI,EAAW,EAAU,KAClB,EAAW,CACtB,CAUA,SAAgB,EAAyB,EAAqC,CAC1E,IAAM,EAAO,EAAM,EAAM,OAAS,GAElC,OADI,GAAS,MAA8B,EAAO,EAAU,KACrD,CACX,CAuBA,SAAgB,EAAiB,EAA6D,CAC1F,IAAM,EAAQ,EAAQ,aAAe,IAAA,GAAY,KAAO,EAAiB,EAAQ,UAAU,EACrF,EAAY,EAAQ,UAQ1B,OAPI,IAAU,KAAa,GAAa,EAAQ,UAC5C,IAAc,IAAA,KAAc,EAAU,KAAO,EAAM,IAAM,EAAU,KAAO,EAAM,KAChF,QAAQ,KACJ,yCAAyC,EAAM,GAAG,GAAG,EAAM,GAAG,iCAChC,EAAU,GAAG,GAAG,EAAU,GAAG,mCAC/D,EAEG,EACX"}
1
+ {"version":3,"file":"graph.cjs","names":[],"sources":["../../../src/vision/core/graph.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * What the ONNX graph itself says about its inputs.\n *\n * The resolution a session must be fed at is a property of the exported model,\n * not of the configuration around it. Feeding a 640x640 tensor to a graph\n * exported at 224x224 makes ORT abort the run with\n * `Got invalid dimensions for input: images ... Got: 640 Expected: 224`, and the\n * caller has no way to see that coming from the outside — the number lives in\n * the file. So the SDK reads it from the graph and treats any configured size as\n * a fallback for when the graph leaves it open.\n */\n\nimport type * as ort from \"onnxruntime-web\";\n\n/**\n * One declared dimension: a number when the graph pins it, `null` when the\n * dimension is symbolic (dynamic).\n */\nexport type DeclaredDim = number | null;\n\n/** A declared input/output shape, dynamic axes appearing as `null`. */\nexport type DeclaredShape = readonly DeclaredDim[];\n\n/**\n * Convert ORT value metadata into declared shapes.\n *\n * @param metadata Metadata as reported by `InferenceSession.inputMetadata`, or\n * `undefined` on ORT builds that predate it (added in onnxruntime 1.21).\n * @returns One shape per value, in declaration order. Non-tensor values and\n * builds without metadata yield empty shapes, which read as \"nothing\n * declared\" everywhere downstream.\n */\nexport function declaredShapesFrom(\n metadata: readonly ort.InferenceSession.ValueMetadata[] | undefined,\n): readonly DeclaredShape[] {\n if (metadata === undefined) return [];\n return metadata.map((value) =>\n value.isTensor\n ? value.shape.map((dim) =>\n typeof dim === \"number\" && Number.isInteger(dim) && dim > 0 ? dim : null,\n )\n : [],\n );\n}\n\n/**\n * Read the spatial input size out of a declared NCHW shape.\n *\n * @param shape The declared shape of the model's image input.\n * @returns `[width, height]` in pixels, or `null` when the shape is not 4D or\n * leaves either spatial axis dynamic — in which case the model accepts more\n * than one resolution and there is nothing to correct.\n */\nexport function spatialInputSize(shape: DeclaredShape): readonly [number, number] | null {\n if (shape.length !== 4) return null;\n const height = shape[2];\n const width = shape[3];\n if (height === null || height === undefined || width === null || width === undefined)\n return null;\n return [width, height];\n}\n\n/**\n * Infer how many classes a YOLO detection/segmentation head emits.\n *\n * Such a head declares `(B, 4 + nc, N)` — four box coordinates stacked above one\n * score per class, over `N` candidate anchors. `N` is in the thousands and the\n * batch is 1, so the channel axis is the smallest static axis above 1.\n *\n * @param shape Declared shape of the model's first output.\n * @returns The class count, or `null` when the shape leaves it undeterminable —\n * fully dynamic, or too small to hold boxes plus at least one class.\n */\nexport function detectionNumClasses(shape: DeclaredShape): number | null {\n const staticDims = shape.filter((dim): dim is number => dim !== null && dim > 1);\n if (staticDims.length === 0) return null;\n const channels = Math.min(...staticDims);\n if (channels < 5) return null;\n return channels - 4;\n}\n\n/**\n * Mask coefficients per anchor when no prototype shape says otherwise.\n *\n * Every Ultralytics seg head (v8, v11) emits 32; it is the fallback when the\n * prototype output's channel axis is dynamic or the runtime reports no shapes.\n */\nconst DEFAULT_MASK_COEFS = 32;\n\n/**\n * Infer how many classes a YOLO segmentation head emits.\n *\n * The per-anchor output declares `(B, 4 + nc + nm, N)`: the detection layout\n * with `nm` mask coefficients stacked under the class scores. Reading it with\n * {@link detectionNumClasses} counts those coefficients as classes — 33 for a\n * one-class YOLO11n-seg, 112 for a COCO one — and the label check then rejects\n * the model's own baked-in names. `nm` is the channel axis of the prototype\n * output `(B, nm, H, W)`, so it is read from there.\n *\n * @param shapes Declared shapes of every output, in declaration order.\n * @returns The class count, or `null` when the per-anchor shape is missing or\n * leaves it undeterminable.\n */\nexport function segmentationNumClasses(shapes: readonly DeclaredShape[]): number | null {\n const perAnchor = shapes.find((shape) => shape.length === 3);\n if (perAnchor === undefined) return null;\n const staticDims = perAnchor.filter((dim): dim is number => dim !== null && dim > 1);\n if (staticDims.length === 0) return null;\n const channels = Math.min(...staticDims);\n const prototypes = shapes.find((shape) => shape.length === 4);\n const declared = prototypes?.[1];\n const coefs = typeof declared === \"number\" && declared > 0 ? declared : DEFAULT_MASK_COEFS;\n const classes = channels - 4 - coefs;\n return classes > 0 ? classes : null;\n}\n\n/**\n * Infer how many classes a classification head emits.\n *\n * A classifier declares `(B, nc)`, so the count is the last static axis.\n *\n * @param shape Declared shape of the model's first output.\n * @returns The class count, or `null` when the last axis is dynamic or absent.\n */\nexport function classificationNumClasses(shape: DeclaredShape): number | null {\n const last = shape[shape.length - 1];\n if (last === null || last === undefined || last < 1) return null;\n return last;\n}\n\nexport interface ResolveInputSizeOptions {\n /** Declared shape of the model's image input, from {@link declaredShapesFrom}. */\n readonly graphShape?: DeclaredShape;\n /** Size the caller asked for, if any. */\n readonly requested?: readonly [number, number];\n /** Size to use when neither the graph nor the caller pins one. */\n readonly fallback: readonly [number, number];\n}\n\n/**\n * Decide the input size a task will preprocess to.\n *\n * Precedence is graph → caller → fallback. The graph wins over an explicit\n * `inputSize` because a static shape is not a preference, it is what ORT will\n * accept: honoring the caller there would only turn a fixable mismatch into a\n * failed run. A disagreement is a configuration bug in the caller, so it is\n * reported through `console.warn` instead of being swallowed.\n *\n * @param options Graph shape, requested size and per-task fallback.\n * @returns The `[width, height]` to preprocess to.\n */\nexport function resolveInputSize(options: ResolveInputSizeOptions): readonly [number, number] {\n const graph = options.graphShape === undefined ? null : spatialInputSize(options.graphShape);\n const requested = options.requested;\n if (graph === null) return requested ?? options.fallback;\n if (requested !== undefined && (requested[0] !== graph[0] || requested[1] !== graph[1])) {\n console.warn(\n `[ort-vision-sdk] The model declares a ${graph[0]}x${graph[1]} input; ` +\n `ignoring the requested ${requested[0]}x${requested[1]}, which ONNX Runtime would reject.`,\n );\n }\n return graph;\n}\n"],"mappings":"AAiCA,SAAgB,EACZ,EACwB,CAExB,OADI,IAAa,IAAA,GAAkB,CAAC,EAC7B,EAAS,IAAK,GACjB,EAAM,SACA,EAAM,MAAM,IAAK,GACb,OAAO,GAAQ,UAAY,OAAO,UAAU,CAAG,GAAK,EAAM,EAAI,EAAM,IACxE,EACA,CAAC,CACX,CACJ,CAUA,SAAgB,EAAiB,EAAwD,CACrF,GAAI,EAAM,SAAW,EAAG,OAAO,KAC/B,IAAM,EAAS,EAAM,GACf,EAAQ,EAAM,GAGpB,OAFI,GAAW,MAAgC,GAAU,KAC9C,KACJ,CAAC,EAAO,CAAM,CACzB,CAaA,SAAgB,EAAoB,EAAqC,CACrE,IAAM,EAAa,EAAM,OAAQ,GAAuB,IAAQ,MAAQ,EAAM,CAAC,EAC/E,GAAI,EAAW,SAAW,EAAG,OAAO,KACpC,IAAM,EAAW,KAAK,IAAI,GAAG,CAAU,EAEvC,OADI,EAAW,EAAU,KAClB,EAAW,CACtB,CAwBA,SAAgB,EAAuB,EAAiD,CACpF,IAAM,EAAY,EAAO,KAAM,GAAU,EAAM,SAAW,CAAC,EAC3D,GAAI,IAAc,IAAA,GAAW,OAAO,KACpC,IAAM,EAAa,EAAU,OAAQ,GAAuB,IAAQ,MAAQ,EAAM,CAAC,EACnF,GAAI,EAAW,SAAW,EAAG,OAAO,KACpC,IAAM,EAAW,KAAK,IAAI,GAAG,CAAU,EAEjC,EADa,EAAO,KAAM,GAAU,EAAM,SAAW,CAC1C,CAAA,GAAa,GACxB,EAAQ,OAAO,GAAa,UAAY,EAAW,EAAI,EAAW,GAClE,EAAU,EAAW,EAAI,EAC/B,OAAO,EAAU,EAAI,EAAU,IACnC,CAUA,SAAgB,EAAyB,EAAqC,CAC1E,IAAM,EAAO,EAAM,EAAM,OAAS,GAElC,OADI,GAAS,MAA8B,EAAO,EAAU,KACrD,CACX,CAuBA,SAAgB,EAAiB,EAA6D,CAC1F,IAAM,EAAQ,EAAQ,aAAe,IAAA,GAAY,KAAO,EAAiB,EAAQ,UAAU,EACrF,EAAY,EAAQ,UAQ1B,OAPI,IAAU,KAAa,GAAa,EAAQ,UAC5C,IAAc,IAAA,KAAc,EAAU,KAAO,EAAM,IAAM,EAAU,KAAO,EAAM,KAChF,QAAQ,KACJ,yCAAyC,EAAM,GAAG,GAAG,EAAM,GAAG,iCAChC,EAAU,GAAG,GAAG,EAAU,GAAG,mCAC/D,EAEG,EACX"}
@@ -14,14 +14,22 @@ function n(e) {
14
14
  return n < 5 ? null : n - 4;
15
15
  }
16
16
  function r(e) {
17
+ let t = e.find((e) => e.length === 3);
18
+ if (t === void 0) return null;
19
+ let n = t.filter((e) => e !== null && e > 1);
20
+ if (n.length === 0) return null;
21
+ let r = Math.min(...n), i = e.find((e) => e.length === 4)?.[1], a = typeof i == "number" && i > 0 ? i : 32, o = r - 4 - a;
22
+ return o > 0 ? o : null;
23
+ }
24
+ function i(e) {
17
25
  let t = e[e.length - 1];
18
26
  return t == null || t < 1 ? null : t;
19
27
  }
20
- function i(e) {
28
+ function a(e) {
21
29
  let n = e.graphShape === void 0 ? null : t(e.graphShape), r = e.requested;
22
30
  return n === null ? r ?? e.fallback : (r !== void 0 && (r[0] !== n[0] || r[1] !== n[1]) && console.warn(`[ort-vision-sdk] The model declares a ${n[0]}x${n[1]} input; ignoring the requested ${r[0]}x${r[1]}, which ONNX Runtime would reject.`), n);
23
31
  }
24
32
  //#endregion
25
- export { r as classificationNumClasses, e as declaredShapesFrom, n as detectionNumClasses, i as resolveInputSize, t as spatialInputSize };
33
+ export { i as classificationNumClasses, e as declaredShapesFrom, n as detectionNumClasses, a as resolveInputSize, r as segmentationNumClasses, t as spatialInputSize };
26
34
 
27
35
  //# sourceMappingURL=graph.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"graph.js","names":[],"sources":["../../../src/vision/core/graph.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * What the ONNX graph itself says about its inputs.\n *\n * The resolution a session must be fed at is a property of the exported model,\n * not of the configuration around it. Feeding a 640x640 tensor to a graph\n * exported at 224x224 makes ORT abort the run with\n * `Got invalid dimensions for input: images ... Got: 640 Expected: 224`, and the\n * caller has no way to see that coming from the outside — the number lives in\n * the file. So the SDK reads it from the graph and treats any configured size as\n * a fallback for when the graph leaves it open.\n */\n\nimport type * as ort from \"onnxruntime-web\";\n\n/**\n * One declared dimension: a number when the graph pins it, `null` when the\n * dimension is symbolic (dynamic).\n */\nexport type DeclaredDim = number | null;\n\n/** A declared input/output shape, dynamic axes appearing as `null`. */\nexport type DeclaredShape = readonly DeclaredDim[];\n\n/**\n * Convert ORT value metadata into declared shapes.\n *\n * @param metadata Metadata as reported by `InferenceSession.inputMetadata`, or\n * `undefined` on ORT builds that predate it (added in onnxruntime 1.21).\n * @returns One shape per value, in declaration order. Non-tensor values and\n * builds without metadata yield empty shapes, which read as \"nothing\n * declared\" everywhere downstream.\n */\nexport function declaredShapesFrom(\n metadata: readonly ort.InferenceSession.ValueMetadata[] | undefined,\n): readonly DeclaredShape[] {\n if (metadata === undefined) return [];\n return metadata.map((value) =>\n value.isTensor\n ? value.shape.map((dim) =>\n typeof dim === \"number\" && Number.isInteger(dim) && dim > 0 ? dim : null,\n )\n : [],\n );\n}\n\n/**\n * Read the spatial input size out of a declared NCHW shape.\n *\n * @param shape The declared shape of the model's image input.\n * @returns `[width, height]` in pixels, or `null` when the shape is not 4D or\n * leaves either spatial axis dynamic — in which case the model accepts more\n * than one resolution and there is nothing to correct.\n */\nexport function spatialInputSize(shape: DeclaredShape): readonly [number, number] | null {\n if (shape.length !== 4) return null;\n const height = shape[2];\n const width = shape[3];\n if (height === null || height === undefined || width === null || width === undefined)\n return null;\n return [width, height];\n}\n\n/**\n * Infer how many classes a YOLO detection/segmentation head emits.\n *\n * Such a head declares `(B, 4 + nc, N)` — four box coordinates stacked above one\n * score per class, over `N` candidate anchors. `N` is in the thousands and the\n * batch is 1, so the channel axis is the smallest static axis above 1.\n *\n * @param shape Declared shape of the model's first output.\n * @returns The class count, or `null` when the shape leaves it undeterminable —\n * fully dynamic, or too small to hold boxes plus at least one class.\n */\nexport function detectionNumClasses(shape: DeclaredShape): number | null {\n const staticDims = shape.filter((dim): dim is number => dim !== null && dim > 1);\n if (staticDims.length === 0) return null;\n const channels = Math.min(...staticDims);\n if (channels < 5) return null;\n return channels - 4;\n}\n\n/**\n * Infer how many classes a classification head emits.\n *\n * A classifier declares `(B, nc)`, so the count is the last static axis.\n *\n * @param shape Declared shape of the model's first output.\n * @returns The class count, or `null` when the last axis is dynamic or absent.\n */\nexport function classificationNumClasses(shape: DeclaredShape): number | null {\n const last = shape[shape.length - 1];\n if (last === null || last === undefined || last < 1) return null;\n return last;\n}\n\nexport interface ResolveInputSizeOptions {\n /** Declared shape of the model's image input, from {@link declaredShapesFrom}. */\n readonly graphShape?: DeclaredShape;\n /** Size the caller asked for, if any. */\n readonly requested?: readonly [number, number];\n /** Size to use when neither the graph nor the caller pins one. */\n readonly fallback: readonly [number, number];\n}\n\n/**\n * Decide the input size a task will preprocess to.\n *\n * Precedence is graph → caller → fallback. The graph wins over an explicit\n * `inputSize` because a static shape is not a preference, it is what ORT will\n * accept: honoring the caller there would only turn a fixable mismatch into a\n * failed run. A disagreement is a configuration bug in the caller, so it is\n * reported through `console.warn` instead of being swallowed.\n *\n * @param options Graph shape, requested size and per-task fallback.\n * @returns The `[width, height]` to preprocess to.\n */\nexport function resolveInputSize(options: ResolveInputSizeOptions): readonly [number, number] {\n const graph = options.graphShape === undefined ? null : spatialInputSize(options.graphShape);\n const requested = options.requested;\n if (graph === null) return requested ?? options.fallback;\n if (requested !== undefined && (requested[0] !== graph[0] || requested[1] !== graph[1])) {\n console.warn(\n `[ort-vision-sdk] The model declares a ${graph[0]}x${graph[1]} input; ` +\n `ignoring the requested ${requested[0]}x${requested[1]}, which ONNX Runtime would reject.`,\n );\n }\n return graph;\n}\n"],"mappings":";AAiCA,SAAgB,EACZ,GACwB;CAExB,OADI,MAAa,KAAA,IAAkB,CAAC,IAC7B,EAAS,KAAK,MACjB,EAAM,WACA,EAAM,MAAM,KAAK,MACb,OAAO,KAAQ,YAAY,OAAO,UAAU,CAAG,KAAK,IAAM,IAAI,IAAM,IACxE,IACA,CAAC,CACX;AACJ;AAUA,SAAgB,EAAiB,GAAwD;CACrF,IAAI,EAAM,WAAW,GAAG,OAAO;CAC/B,IAAM,IAAS,EAAM,IACf,IAAQ,EAAM;CAGpB,OAFI,KAAW,QAAgC,KAAU,OAC9C,OACJ,CAAC,GAAO,CAAM;AACzB;AAaA,SAAgB,EAAoB,GAAqC;CACrE,IAAM,IAAa,EAAM,QAAQ,MAAuB,MAAQ,QAAQ,IAAM,CAAC;CAC/E,IAAI,EAAW,WAAW,GAAG,OAAO;CACpC,IAAM,IAAW,KAAK,IAAI,GAAG,CAAU;CAEvC,OADI,IAAW,IAAU,OAClB,IAAW;AACtB;AAUA,SAAgB,EAAyB,GAAqC;CAC1E,IAAM,IAAO,EAAM,EAAM,SAAS;CAElC,OADI,KAAS,QAA8B,IAAO,IAAU,OACrD;AACX;AAuBA,SAAgB,EAAiB,GAA6D;CAC1F,IAAM,IAAQ,EAAQ,eAAe,KAAA,IAAY,OAAO,EAAiB,EAAQ,UAAU,GACrF,IAAY,EAAQ;CAQ1B,OAPI,MAAU,OAAa,KAAa,EAAQ,YAC5C,MAAc,KAAA,MAAc,EAAU,OAAO,EAAM,MAAM,EAAU,OAAO,EAAM,OAChF,QAAQ,KACJ,yCAAyC,EAAM,GAAG,GAAG,EAAM,GAAG,iCAChC,EAAU,GAAG,GAAG,EAAU,GAAG,mCAC/D,GAEG;AACX"}
1
+ {"version":3,"file":"graph.js","names":[],"sources":["../../../src/vision/core/graph.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * What the ONNX graph itself says about its inputs.\n *\n * The resolution a session must be fed at is a property of the exported model,\n * not of the configuration around it. Feeding a 640x640 tensor to a graph\n * exported at 224x224 makes ORT abort the run with\n * `Got invalid dimensions for input: images ... Got: 640 Expected: 224`, and the\n * caller has no way to see that coming from the outside — the number lives in\n * the file. So the SDK reads it from the graph and treats any configured size as\n * a fallback for when the graph leaves it open.\n */\n\nimport type * as ort from \"onnxruntime-web\";\n\n/**\n * One declared dimension: a number when the graph pins it, `null` when the\n * dimension is symbolic (dynamic).\n */\nexport type DeclaredDim = number | null;\n\n/** A declared input/output shape, dynamic axes appearing as `null`. */\nexport type DeclaredShape = readonly DeclaredDim[];\n\n/**\n * Convert ORT value metadata into declared shapes.\n *\n * @param metadata Metadata as reported by `InferenceSession.inputMetadata`, or\n * `undefined` on ORT builds that predate it (added in onnxruntime 1.21).\n * @returns One shape per value, in declaration order. Non-tensor values and\n * builds without metadata yield empty shapes, which read as \"nothing\n * declared\" everywhere downstream.\n */\nexport function declaredShapesFrom(\n metadata: readonly ort.InferenceSession.ValueMetadata[] | undefined,\n): readonly DeclaredShape[] {\n if (metadata === undefined) return [];\n return metadata.map((value) =>\n value.isTensor\n ? value.shape.map((dim) =>\n typeof dim === \"number\" && Number.isInteger(dim) && dim > 0 ? dim : null,\n )\n : [],\n );\n}\n\n/**\n * Read the spatial input size out of a declared NCHW shape.\n *\n * @param shape The declared shape of the model's image input.\n * @returns `[width, height]` in pixels, or `null` when the shape is not 4D or\n * leaves either spatial axis dynamic — in which case the model accepts more\n * than one resolution and there is nothing to correct.\n */\nexport function spatialInputSize(shape: DeclaredShape): readonly [number, number] | null {\n if (shape.length !== 4) return null;\n const height = shape[2];\n const width = shape[3];\n if (height === null || height === undefined || width === null || width === undefined)\n return null;\n return [width, height];\n}\n\n/**\n * Infer how many classes a YOLO detection/segmentation head emits.\n *\n * Such a head declares `(B, 4 + nc, N)` — four box coordinates stacked above one\n * score per class, over `N` candidate anchors. `N` is in the thousands and the\n * batch is 1, so the channel axis is the smallest static axis above 1.\n *\n * @param shape Declared shape of the model's first output.\n * @returns The class count, or `null` when the shape leaves it undeterminable —\n * fully dynamic, or too small to hold boxes plus at least one class.\n */\nexport function detectionNumClasses(shape: DeclaredShape): number | null {\n const staticDims = shape.filter((dim): dim is number => dim !== null && dim > 1);\n if (staticDims.length === 0) return null;\n const channels = Math.min(...staticDims);\n if (channels < 5) return null;\n return channels - 4;\n}\n\n/**\n * Mask coefficients per anchor when no prototype shape says otherwise.\n *\n * Every Ultralytics seg head (v8, v11) emits 32; it is the fallback when the\n * prototype output's channel axis is dynamic or the runtime reports no shapes.\n */\nconst DEFAULT_MASK_COEFS = 32;\n\n/**\n * Infer how many classes a YOLO segmentation head emits.\n *\n * The per-anchor output declares `(B, 4 + nc + nm, N)`: the detection layout\n * with `nm` mask coefficients stacked under the class scores. Reading it with\n * {@link detectionNumClasses} counts those coefficients as classes — 33 for a\n * one-class YOLO11n-seg, 112 for a COCO one — and the label check then rejects\n * the model's own baked-in names. `nm` is the channel axis of the prototype\n * output `(B, nm, H, W)`, so it is read from there.\n *\n * @param shapes Declared shapes of every output, in declaration order.\n * @returns The class count, or `null` when the per-anchor shape is missing or\n * leaves it undeterminable.\n */\nexport function segmentationNumClasses(shapes: readonly DeclaredShape[]): number | null {\n const perAnchor = shapes.find((shape) => shape.length === 3);\n if (perAnchor === undefined) return null;\n const staticDims = perAnchor.filter((dim): dim is number => dim !== null && dim > 1);\n if (staticDims.length === 0) return null;\n const channels = Math.min(...staticDims);\n const prototypes = shapes.find((shape) => shape.length === 4);\n const declared = prototypes?.[1];\n const coefs = typeof declared === \"number\" && declared > 0 ? declared : DEFAULT_MASK_COEFS;\n const classes = channels - 4 - coefs;\n return classes > 0 ? classes : null;\n}\n\n/**\n * Infer how many classes a classification head emits.\n *\n * A classifier declares `(B, nc)`, so the count is the last static axis.\n *\n * @param shape Declared shape of the model's first output.\n * @returns The class count, or `null` when the last axis is dynamic or absent.\n */\nexport function classificationNumClasses(shape: DeclaredShape): number | null {\n const last = shape[shape.length - 1];\n if (last === null || last === undefined || last < 1) return null;\n return last;\n}\n\nexport interface ResolveInputSizeOptions {\n /** Declared shape of the model's image input, from {@link declaredShapesFrom}. */\n readonly graphShape?: DeclaredShape;\n /** Size the caller asked for, if any. */\n readonly requested?: readonly [number, number];\n /** Size to use when neither the graph nor the caller pins one. */\n readonly fallback: readonly [number, number];\n}\n\n/**\n * Decide the input size a task will preprocess to.\n *\n * Precedence is graph → caller → fallback. The graph wins over an explicit\n * `inputSize` because a static shape is not a preference, it is what ORT will\n * accept: honoring the caller there would only turn a fixable mismatch into a\n * failed run. A disagreement is a configuration bug in the caller, so it is\n * reported through `console.warn` instead of being swallowed.\n *\n * @param options Graph shape, requested size and per-task fallback.\n * @returns The `[width, height]` to preprocess to.\n */\nexport function resolveInputSize(options: ResolveInputSizeOptions): readonly [number, number] {\n const graph = options.graphShape === undefined ? null : spatialInputSize(options.graphShape);\n const requested = options.requested;\n if (graph === null) return requested ?? options.fallback;\n if (requested !== undefined && (requested[0] !== graph[0] || requested[1] !== graph[1])) {\n console.warn(\n `[ort-vision-sdk] The model declares a ${graph[0]}x${graph[1]} input; ` +\n `ignoring the requested ${requested[0]}x${requested[1]}, which ONNX Runtime would reject.`,\n );\n }\n return graph;\n}\n"],"mappings":";AAiCA,SAAgB,EACZ,GACwB;CAExB,OADI,MAAa,KAAA,IAAkB,CAAC,IAC7B,EAAS,KAAK,MACjB,EAAM,WACA,EAAM,MAAM,KAAK,MACb,OAAO,KAAQ,YAAY,OAAO,UAAU,CAAG,KAAK,IAAM,IAAI,IAAM,IACxE,IACA,CAAC,CACX;AACJ;AAUA,SAAgB,EAAiB,GAAwD;CACrF,IAAI,EAAM,WAAW,GAAG,OAAO;CAC/B,IAAM,IAAS,EAAM,IACf,IAAQ,EAAM;CAGpB,OAFI,KAAW,QAAgC,KAAU,OAC9C,OACJ,CAAC,GAAO,CAAM;AACzB;AAaA,SAAgB,EAAoB,GAAqC;CACrE,IAAM,IAAa,EAAM,QAAQ,MAAuB,MAAQ,QAAQ,IAAM,CAAC;CAC/E,IAAI,EAAW,WAAW,GAAG,OAAO;CACpC,IAAM,IAAW,KAAK,IAAI,GAAG,CAAU;CAEvC,OADI,IAAW,IAAU,OAClB,IAAW;AACtB;AAwBA,SAAgB,EAAuB,GAAiD;CACpF,IAAM,IAAY,EAAO,MAAM,MAAU,EAAM,WAAW,CAAC;CAC3D,IAAI,MAAc,KAAA,GAAW,OAAO;CACpC,IAAM,IAAa,EAAU,QAAQ,MAAuB,MAAQ,QAAQ,IAAM,CAAC;CACnF,IAAI,EAAW,WAAW,GAAG,OAAO;CACpC,IAAM,IAAW,KAAK,IAAI,GAAG,CAAU,GAEjC,IADa,EAAO,MAAM,MAAU,EAAM,WAAW,CAC1C,CAAA,GAAa,IACxB,IAAQ,OAAO,KAAa,YAAY,IAAW,IAAI,IAAW,IAClE,IAAU,IAAW,IAAI;CAC/B,OAAO,IAAU,IAAI,IAAU;AACnC;AAUA,SAAgB,EAAyB,GAAqC;CAC1E,IAAM,IAAO,EAAM,EAAM,SAAS;CAElC,OADI,KAAS,QAA8B,IAAO,IAAU,OACrD;AACX;AAuBA,SAAgB,EAAiB,GAA6D;CAC1F,IAAM,IAAQ,EAAQ,eAAe,KAAA,IAAY,OAAO,EAAiB,EAAQ,UAAU,GACrF,IAAY,EAAQ;CAQ1B,OAPI,MAAU,OAAa,KAAa,EAAQ,YAC5C,MAAc,KAAA,MAAc,EAAU,OAAO,EAAM,MAAM,EAAU,OAAO,EAAM,OAChF,QAAQ,KACJ,yCAAyC,EAAM,GAAG,GAAG,EAAM,GAAG,iCAChC,EAAU,GAAG,GAAG,EAAU,GAAG,mCAC/D,GAEG;AACX"}
@@ -1,3 +1,3 @@
1
- function e(e){let t=0,n=0;for(;e.pos<e.end;){let r=e.bytes[e.pos];if(e.pos+=1,t+=(r&127)*2**n,!(r&128))return t;if(n+=7,n>63)return null}return null}function t(t,n){switch(n){case 0:return e(t)!==null;case 1:return t.pos+=8,t.pos<=t.end;case 2:{let n=e(t);return n!==null&&(t.pos+=n,t.pos<=t.end)}case 5:return t.pos+=4,t.pos<=t.end;default:return!1}}function n(t){let n=e(t);if(n===null||n>1048576)return null;let r=t.pos,i=r+n;return i>t.end?null:(t.pos=i,{start:r,end:i})}function r(r,i,a){let o={bytes:r,end:a,pos:i},s=new TextDecoder(`utf-8`,{fatal:!1}),c=null,l=null;for(;o.pos<a;){let i=e(o);if(i===null)return null;let a=i>>>3,u=i&7;if(u===2&&(a===1||a===2)){let e=n(o);if(e===null)return null;let t=s.decode(r.subarray(e.start,e.end));a===1?c=t:l=t;continue}if(!t(o,u))return null}return c===null||l===null?null:[c,l]}function i(i){let a=i instanceof Uint8Array?i:new Uint8Array(i),o={bytes:a,end:a.length,pos:0},s={};for(;o.pos<o.end;){let i=e(o);if(i===null)break;let c=i>>>3,l=i&7;if(c===14&&l===2){let e=n(o);if(e===null)break;let t=r(a,e.start,e.end);t&&(s[t[0]]=t[1]);continue}if(!t(o,l))break}return s}function a(e){return o(e?.names)}function o(e){let t=e?.trim();if(!t||!t.startsWith(`{`)||!t.endsWith(`}`))return null;let n=t.slice(1,-1).trim();if(!n)return null;let r=new Map,i=/(-?\d+)\s*:\s*(?:'((?:[^'\\]|\\.)*)'|"((?:[^"\\]|\\.)*)")/g,a=0;for(let e of n.matchAll(i)){let t=Number(e[1]),n=e[2]??e[3];if(!Number.isInteger(t)||n===void 0)return null;r.set(t,s(n)),a+=e[0].length}if(r.size===0||n.length-a>r.size*3)return null;let o=[];for(let e=0;e<r.size;e+=1){let t=r.get(e);if(t===void 0)return null;o.push(t)}return o}function s(e){return e.replace(/\\(.)/g,(e,t)=>t===`n`?`
2
- `:t===`r`?`\r`:t===`t`?` `:t)}exports.modelNames=a,exports.parseNames=o,exports.readModelMetadata=i;
1
+ function e(e){let t=0,n=0;for(;e.pos<e.end;){let r=e.bytes[e.pos];if(e.pos+=1,t+=(r&127)*2**n,!(r&128))return t;if(n+=7,n>63)return null}return null}function t(t,n){switch(n){case 0:return e(t)!==null;case 1:return t.pos+=8,t.pos<=t.end;case 2:{let n=e(t);return n!==null&&(t.pos+=n,t.pos<=t.end)}case 5:return t.pos+=4,t.pos<=t.end;default:return!1}}function n(t,n=1048576){let r=e(t);if(r===null||r>n)return null;let i=t.pos,a=i+r;return a>t.end?null:(t.pos=a,{start:i,end:a})}function r(r,i,a){let o={bytes:r,end:a,pos:i},s=new TextDecoder(`utf-8`,{fatal:!1}),c=null,l=null;for(;o.pos<a;){let i=e(o);if(i===null)return null;let a=i>>>3,u=i&7;if(u===2&&(a===1||a===2)){let e=n(o);if(e===null)return null;let t=s.decode(r.subarray(e.start,e.end));a===1?c=t:l=t;continue}if(!t(o,u))return null}return c===null||l===null?null:[c,l]}function i(i){let a=i instanceof Uint8Array?i:new Uint8Array(i),o={bytes:a,end:a.length,pos:0},s={};for(;o.pos<o.end;){let i=e(o);if(i===null)break;let c=i>>>3,l=i&7;if(c===14&&l===2){let e=n(o);if(e===null)break;let t=r(a,e.start,e.end);t&&(s[t[0]]=t[1]);continue}if(!t(o,l))break}return s}function a(n,r,i){let a={bytes:n,end:i,pos:r};for(;a.pos<a.end;){let n=e(a);if(n===null)return null;let r=n>>>3,i=n&7;if(r===1&&i===0)return e(a);if(!t(a,i))return null}return null}function o(r,i,o){let s={bytes:r,end:o,pos:i};for(;s.pos<s.end;){let i=e(s);if(i===null)return null;let o=i>>>3,c=i&7;if(o===1&&c===2){let e=n(s);return e===null?null:a(r,e.start,e.end)}if(!t(s,c))return null}return null}function s(r,i,a){let s={bytes:r,end:a,pos:i},c=null,l=null;for(;s.pos<s.end;){let i=e(s);if(i===null)return null;let a=i>>>3,u=i&7;if(u===2){let e=n(s);if(e===null)return null;a===1?c=new TextDecoder(`utf-8`,{fatal:!1}).decode(r.subarray(e.start,e.end)):a===2&&(l=o(r,e.start,e.end));continue}if(!t(s,u))return null}return c===null||l===null?null:[c,l]}function c(r){let i=r instanceof Uint8Array?r:new Uint8Array(r),a={bytes:i,end:i.length,pos:0},o={};for(;a.pos<a.end;){let r=e(a);if(r===null)break;let c=r>>>3,l=r&7;if(c===7&&l===2){let r=n(a,i.length);if(r===null)break;let c={bytes:i,end:r.end,pos:r.start};for(;c.pos<c.end;){let r=e(c);if(r===null)break;let a=r>>>3,l=r&7;if(a===11&&l===2){let e=n(c);if(e===null)break;let t=s(i,e.start,e.end);t&&(o[t[0]]=t[1]);continue}if(!t(c,l))break}continue}if(!t(a,l))break}return o}function l(e){return u(e?.names)}function u(e){let t=e?.trim();if(!t||!t.startsWith(`{`)||!t.endsWith(`}`))return null;let n=t.slice(1,-1).trim();if(!n)return null;let r=new Map,i=/(-?\d+)\s*:\s*(?:'((?:[^'\\]|\\.)*)'|"((?:[^"\\]|\\.)*)")/g,a=0;for(let e of n.matchAll(i)){let t=Number(e[1]),n=e[2]??e[3];if(!Number.isInteger(t)||n===void 0)return null;r.set(t,d(n)),a+=e[0].length}if(r.size===0||n.length-a>r.size*3)return null;let o=[];for(let e=0;e<r.size;e+=1){let t=r.get(e);if(t===void 0)return null;o.push(t)}return o}function d(e){return e.replace(/\\(.)/g,(e,t)=>t===`n`?`
2
+ `:t===`r`?`\r`:t===`t`?` `:t)}exports.modelNames=l,exports.parseNames=u,exports.readModelInputTypes=c,exports.readModelMetadata=i;
3
3
  //# sourceMappingURL=metadata.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"metadata.cjs","names":[],"sources":["../../../src/vision/core/metadata.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Read the metadata an exporter baked into a `.onnx` file.\n *\n * `onnxruntime-web` exposes input/output metadata but **not** the model's\n * custom metadata map, which is where Ultralytics writes `names`, `task` and\n * `imgsz`. The Python SDK gets it for free from\n * `InferenceSession.get_modelmeta().custom_metadata_map`; in the browser the\n * only way to the same information is to read it out of the file, so this\n * module walks just enough of the ModelProto wire format to collect\n * `metadata_props`.\n *\n * It never throws and never allocates unbounded: a truncated, hostile or\n * simply unexpected file yields an empty map, and every caller treats that as\n * \"the model says nothing\", falling back to what it was given.\n */\n\n/** Field number of `metadata_props` in `ModelProto` (repeated StringStringEntryProto). */\nconst MODEL_METADATA_PROPS_FIELD = 14;\n\n/** Field numbers of `key` and `value` in `StringStringEntryProto`. */\nconst ENTRY_KEY_FIELD = 1;\nconst ENTRY_VALUE_FIELD = 2;\n\n/** Protobuf wire types this reader understands. */\nconst WIRE_VARINT = 0;\nconst WIRE_FIXED64 = 1;\nconst WIRE_LENGTH_DELIMITED = 2;\nconst WIRE_FIXED32 = 5;\n\n/**\n * Hard ceiling on a single length-delimited field, as a guard against a corrupt\n * length turning into a huge slice. Model metadata values are strings — a class\n * name map for thousands of classes still fits well inside this.\n */\nconst MAX_FIELD_BYTES = 1 << 20;\n\n/** A cursor over a byte range, tracking its own position. */\ninterface Cursor {\n readonly bytes: Uint8Array;\n readonly end: number;\n pos: number;\n}\n\n/**\n * Read a base-128 varint.\n *\n * @param cursor Cursor to advance.\n * @returns The value, or `null` when the varint is truncated or overlong\n * (beyond the 64-bit range protobuf allows).\n */\nfunction readVarint(cursor: Cursor): number | null {\n let result = 0;\n let shift = 0;\n while (cursor.pos < cursor.end) {\n const byte = cursor.bytes[cursor.pos]!;\n cursor.pos += 1;\n result += (byte & 0x7f) * 2 ** shift;\n if ((byte & 0x80) === 0) return result;\n shift += 7;\n if (shift > 63) return null;\n }\n return null;\n}\n\n/**\n * Skip a field whose contents are not needed.\n *\n * @param cursor Cursor to advance past the field's payload.\n * @param wireType Wire type read from the field's tag.\n * @returns `true` when the field was skipped, `false` when the stream is\n * unreadable from here (unknown wire type or truncated payload).\n */\nfunction skipField(cursor: Cursor, wireType: number): boolean {\n switch (wireType) {\n case WIRE_VARINT:\n return readVarint(cursor) !== null;\n case WIRE_FIXED64:\n cursor.pos += 8;\n return cursor.pos <= cursor.end;\n case WIRE_LENGTH_DELIMITED: {\n const length = readVarint(cursor);\n if (length === null) return false;\n cursor.pos += length;\n return cursor.pos <= cursor.end;\n }\n case WIRE_FIXED32:\n cursor.pos += 4;\n return cursor.pos <= cursor.end;\n default:\n return false;\n }\n}\n\n/**\n * Read a length-delimited payload as a byte range.\n *\n * @param cursor Cursor to advance past the payload.\n * @returns Start and end offsets of the payload, or `null` when the length is\n * truncated, overruns the buffer, or exceeds {@link MAX_FIELD_BYTES}.\n */\nfunction readLengthDelimited(cursor: Cursor): { start: number; end: number } | null {\n const length = readVarint(cursor);\n if (length === null || length > MAX_FIELD_BYTES) return null;\n const start = cursor.pos;\n const end = start + length;\n if (end > cursor.end) return null;\n cursor.pos = end;\n return { start, end };\n}\n\n/**\n * Decode one `StringStringEntryProto` into a key/value pair.\n *\n * @param bytes The model buffer.\n * @param start Offset the entry's payload starts at.\n * @param end Offset the entry's payload ends at.\n * @returns The pair, or `null` when either half is missing or undecodable.\n */\nfunction readEntry(\n bytes: Uint8Array,\n start: number,\n end: number,\n): readonly [string, string] | null {\n const cursor: Cursor = { bytes, end, pos: start };\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n let key: string | null = null;\n let value: string | null = null;\n\n while (cursor.pos < end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (\n wireType === WIRE_LENGTH_DELIMITED &&\n (field === ENTRY_KEY_FIELD || field === ENTRY_VALUE_FIELD)\n ) {\n const range = readLengthDelimited(cursor);\n if (range === null) return null;\n const text = decoder.decode(bytes.subarray(range.start, range.end));\n if (field === ENTRY_KEY_FIELD) key = text;\n else value = text;\n continue;\n }\n if (!skipField(cursor, wireType)) return null;\n }\n\n if (key === null || value === null) return null;\n return [key, value];\n}\n\n/**\n * Collect a model's custom metadata map straight out of its bytes.\n *\n * @param model The `.onnx` file contents.\n * @returns Key/value metadata — `names`, `task`, `imgsz`, ... for an\n * Ultralytics export — or an empty object when the file carries none or\n * cannot be walked.\n */\nexport function readModelMetadata(\n model: Uint8Array | ArrayBufferLike,\n): Readonly<Record<string, string>> {\n const bytes = model instanceof Uint8Array ? model : new Uint8Array(model);\n const cursor: Cursor = { bytes, end: bytes.length, pos: 0 };\n const metadata: Record<string, string> = {};\n\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) break;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === MODEL_METADATA_PROPS_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) break;\n const entry = readEntry(bytes, range.start, range.end);\n if (entry) metadata[entry[0]] = entry[1];\n continue;\n }\n if (!skipField(cursor, wireType)) break;\n }\n\n return metadata;\n}\n\n/**\n * Read the class names an export baked into the model metadata.\n *\n * Ultralytics writes `names` as the Python `repr` of a `dict[int, str]` — e.g.\n * `\"{0: 'deworm', 1: 'not_deworm'}\"`. The value is parsed structurally (never\n * evaluated), and anything unparseable, non-`dict`, or not keyed by contiguous\n * integers from zero is rejected whole rather than half-applied: a partial name\n * map would silently mislabel predictions.\n *\n * @param metadata A model's custom metadata map.\n * @returns Class names in class-id order, or `null` when the model carries no\n * usable `names` entry.\n */\nexport function modelNames(\n metadata: Readonly<Record<string, string>> | undefined,\n): readonly string[] | null {\n return parseNames(metadata?.names);\n}\n\n/**\n * Parse a `repr`-encoded `dict[int, str]` class map.\n *\n * Split out of {@link modelNames} because the same encoding is reused by a\n * fused pipeline, which carries one class map per stage and therefore cannot\n * store both under the single `names` key Ultralytics uses.\n *\n * @param encoded The encoded map — e.g. `\"{0: 'deworm', 1: 'not_deworm'}\"`.\n * @returns Class names in class-id order, or `null` when the value is missing,\n * unparseable, not a `dict`, or not keyed by contiguous integers from zero.\n */\nexport function parseNames(encoded: string | undefined): readonly string[] | null {\n const raw = encoded?.trim();\n if (!raw || !raw.startsWith(\"{\") || !raw.endsWith(\"}\")) return null;\n\n const body = raw.slice(1, -1).trim();\n if (!body) return null;\n\n const names = new Map<number, string>();\n const entryPattern = /(-?\\d+)\\s*:\\s*(?:'((?:[^'\\\\]|\\\\.)*)'|\"((?:[^\"\\\\]|\\\\.)*)\")/g;\n let consumed = 0;\n for (const match of body.matchAll(entryPattern)) {\n const id = Number(match[1]);\n const text = match[2] ?? match[3];\n if (!Number.isInteger(id) || text === undefined) return null;\n names.set(id, unescapeQuoted(text));\n consumed += match[0].length;\n }\n if (names.size === 0) return null;\n\n const separators = body.length - consumed;\n if (separators > names.size * 3) return null;\n\n const ordered: string[] = [];\n for (let id = 0; id < names.size; id += 1) {\n const name = names.get(id);\n if (name === undefined) return null;\n ordered.push(name);\n }\n return ordered;\n}\n\n/**\n * Resolve the backslash escapes Python's `repr` emits inside a quoted string.\n *\n * @param text The quoted string's contents, escapes intact.\n * @returns The same text with `\\\\`, `\\'`, `\\\"`, `\\n`, `\\r` and `\\t` resolved.\n */\nfunction unescapeQuoted(text: string): string {\n return text.replace(/\\\\(.)/g, (_, char: string) => {\n if (char === \"n\") return \"\\n\";\n if (char === \"r\") return \"\\r\";\n if (char === \"t\") return \"\\t\";\n return char;\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"metadata.cjs","names":[],"sources":["../../../src/vision/core/metadata.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Read the metadata an exporter baked into a `.onnx` file.\n *\n * `onnxruntime-web` exposes input/output metadata but **not** the model's\n * custom metadata map, which is where Ultralytics writes `names`, `task` and\n * `imgsz`. The Python SDK gets it for free from\n * `InferenceSession.get_modelmeta().custom_metadata_map`; in the browser the\n * only way to the same information is to read it out of the file, so this\n * module walks just enough of the ModelProto wire format to collect\n * `metadata_props`.\n *\n * It never throws and never allocates unbounded: a truncated, hostile or\n * simply unexpected file yields an empty map, and every caller treats that as\n * \"the model says nothing\", falling back to what it was given.\n */\n\n/** Field number of `metadata_props` in `ModelProto` (repeated StringStringEntryProto). */\nconst MODEL_METADATA_PROPS_FIELD = 14;\n\n/** Field number of `graph` in `ModelProto` (GraphProto). */\nconst MODEL_GRAPH_FIELD = 7;\n\n/** Field number of `input` in `GraphProto` (repeated ValueInfoProto). */\nconst GRAPH_INPUT_FIELD = 11;\n\n/** Field numbers of `name` and `type` in `ValueInfoProto`. */\nconst VALUE_INFO_NAME_FIELD = 1;\nconst VALUE_INFO_TYPE_FIELD = 2;\n\n/** Field number of `tensor_type` in `TypeProto` (TypeProto.Tensor). */\nconst TYPE_TENSOR_FIELD = 1;\n\n/** Field number of `elem_type` in `TypeProto.Tensor` (a `TensorProto.DataType`). */\nconst TENSOR_ELEM_TYPE_FIELD = 1;\n\n/** Field numbers of `key` and `value` in `StringStringEntryProto`. */\nconst ENTRY_KEY_FIELD = 1;\nconst ENTRY_VALUE_FIELD = 2;\n\n/** Protobuf wire types this reader understands. */\nconst WIRE_VARINT = 0;\nconst WIRE_FIXED64 = 1;\nconst WIRE_LENGTH_DELIMITED = 2;\nconst WIRE_FIXED32 = 5;\n\n/**\n * Hard ceiling on a single length-delimited field, as a guard against a corrupt\n * length turning into a huge slice. Model metadata values are strings — a class\n * name map for thousands of classes still fits well inside this.\n *\n * It applies to leaf fields being read *out* of the file, not to the messages\n * walked *through* to reach them. The `graph` of a real export is the file: 21.79\n * MB on a reported YOLO detector. Applying this ceiling there made the reader\n * give up on every model anyone would actually load, and give up silently.\n */\nconst MAX_FIELD_BYTES = 1 << 20;\n\n/** A cursor over a byte range, tracking its own position. */\ninterface Cursor {\n readonly bytes: Uint8Array;\n readonly end: number;\n pos: number;\n}\n\n/**\n * Read a base-128 varint.\n *\n * @param cursor Cursor to advance.\n * @returns The value, or `null` when the varint is truncated or overlong\n * (beyond the 64-bit range protobuf allows).\n */\nfunction readVarint(cursor: Cursor): number | null {\n let result = 0;\n let shift = 0;\n while (cursor.pos < cursor.end) {\n const byte = cursor.bytes[cursor.pos]!;\n cursor.pos += 1;\n result += (byte & 0x7f) * 2 ** shift;\n if ((byte & 0x80) === 0) return result;\n shift += 7;\n if (shift > 63) return null;\n }\n return null;\n}\n\n/**\n * Skip a field whose contents are not needed.\n *\n * @param cursor Cursor to advance past the field's payload.\n * @param wireType Wire type read from the field's tag.\n * @returns `true` when the field was skipped, `false` when the stream is\n * unreadable from here (unknown wire type or truncated payload).\n */\nfunction skipField(cursor: Cursor, wireType: number): boolean {\n switch (wireType) {\n case WIRE_VARINT:\n return readVarint(cursor) !== null;\n case WIRE_FIXED64:\n cursor.pos += 8;\n return cursor.pos <= cursor.end;\n case WIRE_LENGTH_DELIMITED: {\n const length = readVarint(cursor);\n if (length === null) return false;\n cursor.pos += length;\n return cursor.pos <= cursor.end;\n }\n case WIRE_FIXED32:\n cursor.pos += 4;\n return cursor.pos <= cursor.end;\n default:\n return false;\n }\n}\n\n/**\n * Read a length-delimited payload as a byte range.\n *\n * @param cursor Cursor to advance past the payload.\n * @param maxBytes Largest payload to accept, defaulting to\n * {@link MAX_FIELD_BYTES}. Pass the buffer length when descending into a\n * message whose size is the file's size rather than a leaf value's.\n * @returns Start and end offsets of the payload, or `null` when the length is\n * truncated, overruns the buffer, or exceeds `maxBytes`.\n */\nfunction readLengthDelimited(\n cursor: Cursor,\n maxBytes: number = MAX_FIELD_BYTES,\n): { start: number; end: number } | null {\n const length = readVarint(cursor);\n if (length === null || length > maxBytes) return null;\n const start = cursor.pos;\n const end = start + length;\n if (end > cursor.end) return null;\n cursor.pos = end;\n return { start, end };\n}\n\n/**\n * Decode one `StringStringEntryProto` into a key/value pair.\n *\n * @param bytes The model buffer.\n * @param start Offset the entry's payload starts at.\n * @param end Offset the entry's payload ends at.\n * @returns The pair, or `null` when either half is missing or undecodable.\n */\nfunction readEntry(\n bytes: Uint8Array,\n start: number,\n end: number,\n): readonly [string, string] | null {\n const cursor: Cursor = { bytes, end, pos: start };\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n let key: string | null = null;\n let value: string | null = null;\n\n while (cursor.pos < end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (\n wireType === WIRE_LENGTH_DELIMITED &&\n (field === ENTRY_KEY_FIELD || field === ENTRY_VALUE_FIELD)\n ) {\n const range = readLengthDelimited(cursor);\n if (range === null) return null;\n const text = decoder.decode(bytes.subarray(range.start, range.end));\n if (field === ENTRY_KEY_FIELD) key = text;\n else value = text;\n continue;\n }\n if (!skipField(cursor, wireType)) return null;\n }\n\n if (key === null || value === null) return null;\n return [key, value];\n}\n\n/**\n * Collect a model's custom metadata map straight out of its bytes.\n *\n * @param model The `.onnx` file contents.\n * @returns Key/value metadata — `names`, `task`, `imgsz`, ... for an\n * Ultralytics export — or an empty object when the file carries none or\n * cannot be walked.\n */\nexport function readModelMetadata(\n model: Uint8Array | ArrayBufferLike,\n): Readonly<Record<string, string>> {\n const bytes = model instanceof Uint8Array ? model : new Uint8Array(model);\n const cursor: Cursor = { bytes, end: bytes.length, pos: 0 };\n const metadata: Record<string, string> = {};\n\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) break;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === MODEL_METADATA_PROPS_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) break;\n const entry = readEntry(bytes, range.start, range.end);\n if (entry) metadata[entry[0]] = entry[1];\n continue;\n }\n if (!skipField(cursor, wireType)) break;\n }\n\n return metadata;\n}\n\n/**\n * Read the element type of a `TypeProto.Tensor` message.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns The `TensorProto.DataType` value, or `null` when the message\n * carries none or cannot be walked.\n */\nfunction readTensorElemType(bytes: Uint8Array, start: number, end: number): number | null {\n const cursor: Cursor = { bytes, end, pos: start };\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === TENSOR_ELEM_TYPE_FIELD && wireType === WIRE_VARINT) {\n return readVarint(cursor);\n }\n if (!skipField(cursor, wireType)) return null;\n }\n return null;\n}\n\n/**\n * Read the element type out of a `TypeProto`, which wraps the tensor type.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns The `TensorProto.DataType` value, or `null` for a non-tensor type\n * (sequence, map, optional) or an unreadable message.\n */\nfunction readTypeElemType(bytes: Uint8Array, start: number, end: number): number | null {\n const cursor: Cursor = { bytes, end, pos: start };\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === TYPE_TENSOR_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) return null;\n return readTensorElemType(bytes, range.start, range.end);\n }\n if (!skipField(cursor, wireType)) return null;\n }\n return null;\n}\n\n/**\n * Read one `ValueInfoProto` into a name/element-type pair.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns The pair, or `null` when either half is missing or unreadable.\n */\nfunction readValueInfo(\n bytes: Uint8Array,\n start: number,\n end: number,\n): readonly [string, number] | null {\n const cursor: Cursor = { bytes, end, pos: start };\n let name: string | null = null;\n let elemType: number | null = null;\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) return null;\n if (field === VALUE_INFO_NAME_FIELD) {\n name = new TextDecoder(\"utf-8\", { fatal: false }).decode(\n bytes.subarray(range.start, range.end),\n );\n } else if (field === VALUE_INFO_TYPE_FIELD) {\n elemType = readTypeElemType(bytes, range.start, range.end);\n }\n continue;\n }\n if (!skipField(cursor, wireType)) return null;\n }\n if (name === null || elemType === null) return null;\n return [name, elemType];\n}\n\n/**\n * Read the element type each graph input declares.\n *\n * `onnxruntime-web` does not expose this. `session.inputMetadata` is\n * `undefined` on 1.20.1 — the same version where `declaredShapesFrom` comes\n * back empty — so the declared types have to come from the file, which the SDK\n * already downloads and walks for {@link readModelMetadata}. Same bytes, one\n * more pass, no extra request.\n *\n * @param model The `.onnx` file contents.\n * @returns Input name → `TensorProto.DataType` value. An empty object when the\n * file carries no readable graph, which every caller treats as \"assume\n * float32\" — the behaviour before any of this existed.\n */\nexport function readModelInputTypes(\n model: Uint8Array | ArrayBufferLike,\n): Readonly<Record<string, number>> {\n const bytes = model instanceof Uint8Array ? model : new Uint8Array(model);\n const cursor: Cursor = { bytes, end: bytes.length, pos: 0 };\n const types: Record<string, number> = {};\n\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) break;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === MODEL_GRAPH_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const graph = readLengthDelimited(cursor, bytes.length);\n if (graph === null) break;\n const inner: Cursor = { bytes, end: graph.end, pos: graph.start };\n while (inner.pos < inner.end) {\n const innerTag = readVarint(inner);\n if (innerTag === null) break;\n const innerField = innerTag >>> 3;\n const innerWire = innerTag & 0x07;\n if (innerField === GRAPH_INPUT_FIELD && innerWire === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(inner);\n if (range === null) break;\n const info = readValueInfo(bytes, range.start, range.end);\n if (info) types[info[0]] = info[1];\n continue;\n }\n if (!skipField(inner, innerWire)) break;\n }\n continue;\n }\n if (!skipField(cursor, wireType)) break;\n }\n\n return types;\n}\n\n/**\n * Read the class names an export baked into the model metadata.\n *\n * Ultralytics writes `names` as the Python `repr` of a `dict[int, str]` — e.g.\n * `\"{0: 'deworm', 1: 'not_deworm'}\"`. The value is parsed structurally (never\n * evaluated), and anything unparseable, non-`dict`, or not keyed by contiguous\n * integers from zero is rejected whole rather than half-applied: a partial name\n * map would silently mislabel predictions.\n *\n * @param metadata A model's custom metadata map.\n * @returns Class names in class-id order, or `null` when the model carries no\n * usable `names` entry.\n */\nexport function modelNames(\n metadata: Readonly<Record<string, string>> | undefined,\n): readonly string[] | null {\n return parseNames(metadata?.names);\n}\n\n/**\n * Parse a `repr`-encoded `dict[int, str]` class map.\n *\n * Split out of {@link modelNames} because the same encoding is reused by a\n * fused pipeline, which carries one class map per stage and therefore cannot\n * store both under the single `names` key Ultralytics uses.\n *\n * @param encoded The encoded map — e.g. `\"{0: 'deworm', 1: 'not_deworm'}\"`.\n * @returns Class names in class-id order, or `null` when the value is missing,\n * unparseable, not a `dict`, or not keyed by contiguous integers from zero.\n */\nexport function parseNames(encoded: string | undefined): readonly string[] | null {\n const raw = encoded?.trim();\n if (!raw || !raw.startsWith(\"{\") || !raw.endsWith(\"}\")) return null;\n\n const body = raw.slice(1, -1).trim();\n if (!body) return null;\n\n const names = new Map<number, string>();\n const entryPattern = /(-?\\d+)\\s*:\\s*(?:'((?:[^'\\\\]|\\\\.)*)'|\"((?:[^\"\\\\]|\\\\.)*)\")/g;\n let consumed = 0;\n for (const match of body.matchAll(entryPattern)) {\n const id = Number(match[1]);\n const text = match[2] ?? match[3];\n if (!Number.isInteger(id) || text === undefined) return null;\n names.set(id, unescapeQuoted(text));\n consumed += match[0].length;\n }\n if (names.size === 0) return null;\n\n const separators = body.length - consumed;\n if (separators > names.size * 3) return null;\n\n const ordered: string[] = [];\n for (let id = 0; id < names.size; id += 1) {\n const name = names.get(id);\n if (name === undefined) return null;\n ordered.push(name);\n }\n return ordered;\n}\n\n/**\n * Resolve the backslash escapes Python's `repr` emits inside a quoted string.\n *\n * @param text The quoted string's contents, escapes intact.\n * @returns The same text with `\\\\`, `\\'`, `\\\"`, `\\n`, `\\r` and `\\t` resolved.\n */\nfunction unescapeQuoted(text: string): string {\n return text.replace(/\\\\(.)/g, (_, char: string) => {\n if (char === \"n\") return \"\\n\";\n if (char === \"r\") return \"\\r\";\n if (char === \"t\") return \"\\t\";\n return char;\n });\n}\n"],"mappings":"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"}
@@ -19,13 +19,13 @@ function t(t, n) {
19
19
  default: return !1;
20
20
  }
21
21
  }
22
- function n(t) {
23
- let n = e(t);
24
- if (n === null || n > 1048576) return null;
25
- let r = t.pos, i = r + n;
26
- return i > t.end ? null : (t.pos = i, {
27
- start: r,
28
- end: i
22
+ function n(t, n = 1048576) {
23
+ let r = e(t);
24
+ if (r === null || r > n) return null;
25
+ let i = t.pos, a = i + r;
26
+ return a > t.end ? null : (t.pos = a, {
27
+ start: i,
28
+ end: a
29
29
  });
30
30
  }
31
31
  function r(r, i, a) {
@@ -70,10 +70,100 @@ function i(i) {
70
70
  }
71
71
  return s;
72
72
  }
73
- function a(e) {
74
- return o(e?.names);
73
+ function a(n, r, i) {
74
+ let a = {
75
+ bytes: n,
76
+ end: i,
77
+ pos: r
78
+ };
79
+ for (; a.pos < a.end;) {
80
+ let n = e(a);
81
+ if (n === null) return null;
82
+ let r = n >>> 3, i = n & 7;
83
+ if (r === 1 && i === 0) return e(a);
84
+ if (!t(a, i)) return null;
85
+ }
86
+ return null;
87
+ }
88
+ function o(r, i, o) {
89
+ let s = {
90
+ bytes: r,
91
+ end: o,
92
+ pos: i
93
+ };
94
+ for (; s.pos < s.end;) {
95
+ let i = e(s);
96
+ if (i === null) return null;
97
+ let o = i >>> 3, c = i & 7;
98
+ if (o === 1 && c === 2) {
99
+ let e = n(s);
100
+ return e === null ? null : a(r, e.start, e.end);
101
+ }
102
+ if (!t(s, c)) return null;
103
+ }
104
+ return null;
105
+ }
106
+ function s(r, i, a) {
107
+ let s = {
108
+ bytes: r,
109
+ end: a,
110
+ pos: i
111
+ }, c = null, l = null;
112
+ for (; s.pos < s.end;) {
113
+ let i = e(s);
114
+ if (i === null) return null;
115
+ let a = i >>> 3, u = i & 7;
116
+ if (u === 2) {
117
+ let e = n(s);
118
+ if (e === null) return null;
119
+ a === 1 ? c = new TextDecoder("utf-8", { fatal: !1 }).decode(r.subarray(e.start, e.end)) : a === 2 && (l = o(r, e.start, e.end));
120
+ continue;
121
+ }
122
+ if (!t(s, u)) return null;
123
+ }
124
+ return c === null || l === null ? null : [c, l];
125
+ }
126
+ function c(r) {
127
+ let i = r instanceof Uint8Array ? r : new Uint8Array(r), a = {
128
+ bytes: i,
129
+ end: i.length,
130
+ pos: 0
131
+ }, o = {};
132
+ for (; a.pos < a.end;) {
133
+ let r = e(a);
134
+ if (r === null) break;
135
+ let c = r >>> 3, l = r & 7;
136
+ if (c === 7 && l === 2) {
137
+ let r = n(a, i.length);
138
+ if (r === null) break;
139
+ let c = {
140
+ bytes: i,
141
+ end: r.end,
142
+ pos: r.start
143
+ };
144
+ for (; c.pos < c.end;) {
145
+ let r = e(c);
146
+ if (r === null) break;
147
+ let a = r >>> 3, l = r & 7;
148
+ if (a === 11 && l === 2) {
149
+ let e = n(c);
150
+ if (e === null) break;
151
+ let t = s(i, e.start, e.end);
152
+ t && (o[t[0]] = t[1]);
153
+ continue;
154
+ }
155
+ if (!t(c, l)) break;
156
+ }
157
+ continue;
158
+ }
159
+ if (!t(a, l)) break;
160
+ }
161
+ return o;
162
+ }
163
+ function l(e) {
164
+ return u(e?.names);
75
165
  }
76
- function o(e) {
166
+ function u(e) {
77
167
  let t = e?.trim();
78
168
  if (!t || !t.startsWith("{") || !t.endsWith("}")) return null;
79
169
  let n = t.slice(1, -1).trim();
@@ -82,7 +172,7 @@ function o(e) {
82
172
  for (let e of n.matchAll(i)) {
83
173
  let t = Number(e[1]), n = e[2] ?? e[3];
84
174
  if (!Number.isInteger(t) || n === void 0) return null;
85
- r.set(t, s(n)), a += e[0].length;
175
+ r.set(t, d(n)), a += e[0].length;
86
176
  }
87
177
  if (r.size === 0 || n.length - a > r.size * 3) return null;
88
178
  let o = [];
@@ -93,10 +183,10 @@ function o(e) {
93
183
  }
94
184
  return o;
95
185
  }
96
- function s(e) {
186
+ function d(e) {
97
187
  return e.replace(/\\(.)/g, (e, t) => t === "n" ? "\n" : t === "r" ? "\r" : t === "t" ? " " : t);
98
188
  }
99
189
  //#endregion
100
- export { a as modelNames, o as parseNames, i as readModelMetadata };
190
+ export { l as modelNames, u as parseNames, c as readModelInputTypes, i as readModelMetadata };
101
191
 
102
192
  //# sourceMappingURL=metadata.js.map