tempest-react-sdk 0.71.0 → 0.73.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.
@@ -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 * 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"}
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 (`onnxruntime-web` < 1.22,\n * measured). The session then falls back to the shapes in the model file.\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":"AAkCA,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"}
@@ -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 * 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
+ {"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 (`onnxruntime-web` < 1.22,\n * measured). The session then falls back to the shapes in the model file.\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":";AAkCA,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,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;
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}var a={elemType:null,shape:[]};function o(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){let t=e(a);return t!==null&&Number.isSafeInteger(t)&&t>0?t:null}if(!t(a,i))return null}return null}function s(r,i,a){let s={bytes:r,end:a,pos:i},c=[];for(;s.pos<s.end;){let i=e(s);if(i===null)return[];let a=i>>>3,l=i&7;if(a===1&&l===2){let e=n(s);if(e===null)return[];c.push(o(r,e.start,e.end));continue}if(!t(s,l))return[]}return c}function c(r,i,a){let o={bytes:r,end:a,pos:i},c=null,l=[];for(;o.pos<o.end;){let i=e(o);if(i===null)break;let a=i>>>3,u=i&7;if(a===1&&u===0){c=e(o);continue}if(a===2&&u===2){let e=n(o);if(e===null)break;l=s(r,e.start,e.end);continue}if(!t(o,u))break}return{elemType:c,shape:l}}function l(r,i,o){let s={bytes:r,end:o,pos:i};for(;s.pos<s.end;){let i=e(s);if(i===null)return a;let o=i>>>3,l=i&7;if(o===1&&l===2){let e=n(s);return e===null?a:c(r,e.start,e.end)}if(!t(s,l))return a}return a}function u(r,i,o){let s={bytes:r,end:o,pos:i},c=null,u=a;for(;s.pos<s.end;){let i=e(s);if(i===null)return null;let a=i>>>3,o=i&7;if(o===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&&(u=l(r,e.start,e.end));continue}if(!t(s,o))return null}return c===null?null:{name:c,...u}}function d(r){let i=r instanceof Uint8Array?r:new Uint8Array(r),a={bytes:i,end:i.length,pos:0},o=[],s=[];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||a===12)&&l===2){let e=n(c);if(e===null)break;let t=u(i,e.start,e.end);t&&(a===11?o:s).push(t);continue}if(!t(c,l))break}continue}if(!t(a,l))break}return{inputs:o,outputs:s}}function f(e){let t={};for(let n of d(e).inputs)n.elemType!==null&&(t[n.name]=n.elemType);return t}function p(e){let{inputs:t,outputs:n}=d(e);return{inputs:Object.fromEntries(t.map(e=>[e.name,e.shape])),outputs:Object.fromEntries(n.map(e=>[e.name,e.shape]))}}function m(e){return h(e?.names)}function h(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,g(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 g(e){return e.replace(/\\(.)/g,(e,t)=>t===`n`?`
2
+ `:t===`r`?`\r`:t===`t`?` `:t)}exports.modelNames=m,exports.parseNames=h,exports.readModelInputTypes=f,exports.readModelMetadata=i,exports.readModelShapes=p;
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 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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"}
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\nimport type { DeclaredDim, DeclaredShape } from \"./graph\";\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 number of `output` in `GraphProto` (repeated ValueInfoProto). */\nconst GRAPH_OUTPUT_FIELD = 12;\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 number of `shape` in `TypeProto.Tensor` (TensorShapeProto). */\nconst TENSOR_SHAPE_FIELD = 2;\n\n/** Field number of `dim` in `TensorShapeProto` (repeated Dimension). */\nconst SHAPE_DIM_FIELD = 1;\n\n/** Field number of `dim_value` in `TensorShapeProto.Dimension` (int64). */\nconst DIM_VALUE_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/** What a graph value declares about itself: its element type and its shape. */\ninterface DeclaredTensor {\n readonly elemType: number | null;\n readonly shape: DeclaredShape;\n}\n\n/** A graph value with nothing readable declared. */\nconst UNDECLARED: DeclaredTensor = { elemType: null, shape: [] };\n\n/**\n * Read one `TensorShapeProto.Dimension`.\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 size when the graph pins it to a positive integer, `null` for a\n * symbolic (`dim_param`) or absent one — the same convention as\n * `declaredShapesFrom`, so both sources read alike downstream.\n */\nfunction readDimension(bytes: Uint8Array, start: number, end: number): DeclaredDim {\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 === DIM_VALUE_FIELD && wireType === WIRE_VARINT) {\n const value = readVarint(cursor);\n return value !== null && Number.isSafeInteger(value) && value > 0 ? value : null;\n }\n if (!skipField(cursor, wireType)) return null;\n }\n return null;\n}\n\n/**\n * Read a `TensorShapeProto` into a declared shape.\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 One entry per dimension, or an empty shape when the message cannot\n * be walked — a half-read shape would claim the wrong rank.\n */\nfunction readShape(bytes: Uint8Array, start: number, end: number): DeclaredShape {\n const cursor: Cursor = { bytes, end, pos: start };\n const dims: DeclaredDim[] = [];\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return [];\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === SHAPE_DIM_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) return [];\n dims.push(readDimension(bytes, range.start, range.end));\n continue;\n }\n if (!skipField(cursor, wireType)) return [];\n }\n return dims;\n}\n\n/**\n * Read 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 Its element type and shape; either is left undeclared when the\n * message carries none or cannot be walked.\n */\nfunction readTensorType(bytes: Uint8Array, start: number, end: number): DeclaredTensor {\n const cursor: Cursor = { bytes, end, pos: start };\n let elemType: number | null = null;\n let shape: DeclaredShape = [];\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 === TENSOR_ELEM_TYPE_FIELD && wireType === WIRE_VARINT) {\n elemType = readVarint(cursor);\n continue;\n }\n if (field === TENSOR_SHAPE_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) break;\n shape = readShape(bytes, range.start, range.end);\n continue;\n }\n if (!skipField(cursor, wireType)) break;\n }\n return { elemType, shape };\n}\n\n/**\n * Read 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 tensor's declarations, or {@link UNDECLARED} for a non-tensor\n * type (sequence, map, optional) or an unreadable message.\n */\nfunction readType(bytes: Uint8Array, start: number, end: number): DeclaredTensor {\n const cursor: Cursor = { bytes, end, pos: start };\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return UNDECLARED;\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 UNDECLARED;\n return readTensorType(bytes, range.start, range.end);\n }\n if (!skipField(cursor, wireType)) return UNDECLARED;\n }\n return UNDECLARED;\n}\n\n/**\n * Read one `ValueInfoProto`.\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 value's name and declarations, or `null` when the name is\n * missing or the message is unreadable.\n */\nfunction readValueInfo(\n bytes: Uint8Array,\n start: number,\n end: number,\n): (DeclaredTensor & { readonly name: string }) | null {\n const cursor: Cursor = { bytes, end, pos: start };\n let name: string | null = null;\n let declared: DeclaredTensor = UNDECLARED;\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 declared = readType(bytes, range.start, range.end);\n }\n continue;\n }\n if (!skipField(cursor, wireType)) return null;\n }\n if (name === null) return null;\n return { name, ...declared };\n}\n\n/** The graph's declared inputs and outputs, each in declaration order. */\ninterface GraphValues {\n readonly inputs: readonly (DeclaredTensor & { readonly name: string })[];\n readonly outputs: readonly (DeclaredTensor & { readonly name: string })[];\n}\n\n/**\n * Walk the `GraphProto` and collect what its inputs and outputs declare.\n *\n * @param model The `.onnx` file contents.\n * @returns Both lists, empty when the file carries no readable graph.\n */\nfunction readGraphValues(model: Uint8Array | ArrayBufferLike): GraphValues {\n const bytes = model instanceof Uint8Array ? model : new Uint8Array(model);\n const cursor: Cursor = { bytes, end: bytes.length, pos: 0 };\n const inputs: (DeclaredTensor & { readonly name: string })[] = [];\n const outputs: (DeclaredTensor & { readonly name: 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_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 (\n (innerField === GRAPH_INPUT_FIELD || innerField === GRAPH_OUTPUT_FIELD) &&\n innerWire === WIRE_LENGTH_DELIMITED\n ) {\n const range = readLengthDelimited(inner);\n if (range === null) break;\n const info = readValueInfo(bytes, range.start, range.end);\n if (info) (innerField === GRAPH_INPUT_FIELD ? inputs : outputs).push(info);\n continue;\n }\n if (!skipField(inner, innerWire)) break;\n }\n continue;\n }\n if (!skipField(cursor, wireType)) break;\n }\n\n return { inputs, outputs };\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 types: Record<string, number> = {};\n for (const input of readGraphValues(model).inputs) {\n if (input.elemType !== null) types[input.name] = input.elemType;\n }\n return types;\n}\n\n/**\n * Read the shape each graph input and output declares, straight from the file.\n *\n * `onnxruntime-web` reports these through `inputMetadata` / `outputMetadata`\n * only from 1.22 on. Below that the session answers nothing, and a task that\n * reads its input size or class count off the session silently fell back to\n * its defaults: a 64x64 detector was fed 640x640 and ORT aborted with\n * `Got invalid dimensions for input` (measured on 1.17.3, 1.18.0, 1.19.2,\n * 1.20.1 and 1.21.0). The\n * file carries the same declarations, in the same `ValueInfoProto` the element\n * types are read from.\n *\n * Keyed by name rather than position: in an older IR the graph's `input` list\n * also carries the initializers, so its order does not line up with the\n * session's `inputNames`.\n *\n * @param model The `.onnx` file contents.\n * @returns Input and output name → shape, dynamic axes as `null`. Both maps\n * are empty when the file carries no readable graph.\n */\nexport function readModelShapes(model: Uint8Array | ArrayBufferLike): {\n readonly inputs: Readonly<Record<string, DeclaredShape>>;\n readonly outputs: Readonly<Record<string, DeclaredShape>>;\n} {\n const { inputs, outputs } = readGraphValues(model);\n return {\n inputs: Object.fromEntries(inputs.map((value) => [value.name, value.shape])),\n outputs: Object.fromEntries(outputs.map((value) => [value.name, value.shape])),\n };\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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"}
@@ -70,7 +70,11 @@ function i(i) {
70
70
  }
71
71
  return s;
72
72
  }
73
- function a(n, r, i) {
73
+ var a = {
74
+ elemType: null,
75
+ shape: []
76
+ };
77
+ function o(n, r, i) {
74
78
  let a = {
75
79
  bytes: n,
76
80
  end: i,
@@ -80,12 +84,62 @@ function a(n, r, i) {
80
84
  let n = e(a);
81
85
  if (n === null) return null;
82
86
  let r = n >>> 3, i = n & 7;
83
- if (r === 1 && i === 0) return e(a);
87
+ if (r === 1 && i === 0) {
88
+ let t = e(a);
89
+ return t !== null && Number.isSafeInteger(t) && t > 0 ? t : null;
90
+ }
84
91
  if (!t(a, i)) return null;
85
92
  }
86
93
  return null;
87
94
  }
88
- function o(r, i, o) {
95
+ function s(r, i, a) {
96
+ let s = {
97
+ bytes: r,
98
+ end: a,
99
+ pos: i
100
+ }, c = [];
101
+ for (; s.pos < s.end;) {
102
+ let i = e(s);
103
+ if (i === null) return [];
104
+ let a = i >>> 3, l = i & 7;
105
+ if (a === 1 && l === 2) {
106
+ let e = n(s);
107
+ if (e === null) return [];
108
+ c.push(o(r, e.start, e.end));
109
+ continue;
110
+ }
111
+ if (!t(s, l)) return [];
112
+ }
113
+ return c;
114
+ }
115
+ function c(r, i, a) {
116
+ let o = {
117
+ bytes: r,
118
+ end: a,
119
+ pos: i
120
+ }, c = null, l = [];
121
+ for (; o.pos < o.end;) {
122
+ let i = e(o);
123
+ if (i === null) break;
124
+ let a = i >>> 3, u = i & 7;
125
+ if (a === 1 && u === 0) {
126
+ c = e(o);
127
+ continue;
128
+ }
129
+ if (a === 2 && u === 2) {
130
+ let e = n(o);
131
+ if (e === null) break;
132
+ l = s(r, e.start, e.end);
133
+ continue;
134
+ }
135
+ if (!t(o, u)) break;
136
+ }
137
+ return {
138
+ elemType: c,
139
+ shape: l
140
+ };
141
+ }
142
+ function l(r, i, o) {
89
143
  let s = {
90
144
  bytes: r,
91
145
  end: o,
@@ -93,42 +147,45 @@ function o(r, i, o) {
93
147
  };
94
148
  for (; s.pos < s.end;) {
95
149
  let i = e(s);
96
- if (i === null) return null;
97
- let o = i >>> 3, c = i & 7;
98
- if (o === 1 && c === 2) {
150
+ if (i === null) return a;
151
+ let o = i >>> 3, l = i & 7;
152
+ if (o === 1 && l === 2) {
99
153
  let e = n(s);
100
- return e === null ? null : a(r, e.start, e.end);
154
+ return e === null ? a : c(r, e.start, e.end);
101
155
  }
102
- if (!t(s, c)) return null;
156
+ if (!t(s, l)) return a;
103
157
  }
104
- return null;
158
+ return a;
105
159
  }
106
- function s(r, i, a) {
160
+ function u(r, i, o) {
107
161
  let s = {
108
162
  bytes: r,
109
- end: a,
163
+ end: o,
110
164
  pos: i
111
- }, c = null, l = null;
165
+ }, c = null, u = a;
112
166
  for (; s.pos < s.end;) {
113
167
  let i = e(s);
114
168
  if (i === null) return null;
115
- let a = i >>> 3, u = i & 7;
116
- if (u === 2) {
169
+ let a = i >>> 3, o = i & 7;
170
+ if (o === 2) {
117
171
  let e = n(s);
118
172
  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));
173
+ a === 1 ? c = new TextDecoder("utf-8", { fatal: !1 }).decode(r.subarray(e.start, e.end)) : a === 2 && (u = l(r, e.start, e.end));
120
174
  continue;
121
175
  }
122
- if (!t(s, u)) return null;
176
+ if (!t(s, o)) return null;
123
177
  }
124
- return c === null || l === null ? null : [c, l];
178
+ return c === null ? null : {
179
+ name: c,
180
+ ...u
181
+ };
125
182
  }
126
- function c(r) {
183
+ function d(r) {
127
184
  let i = r instanceof Uint8Array ? r : new Uint8Array(r), a = {
128
185
  bytes: i,
129
186
  end: i.length,
130
187
  pos: 0
131
- }, o = {};
188
+ }, o = [], s = [];
132
189
  for (; a.pos < a.end;) {
133
190
  let r = e(a);
134
191
  if (r === null) break;
@@ -145,11 +202,11 @@ function c(r) {
145
202
  let r = e(c);
146
203
  if (r === null) break;
147
204
  let a = r >>> 3, l = r & 7;
148
- if (a === 11 && l === 2) {
205
+ if ((a === 11 || a === 12) && l === 2) {
149
206
  let e = n(c);
150
207
  if (e === null) break;
151
- let t = s(i, e.start, e.end);
152
- t && (o[t[0]] = t[1]);
208
+ let t = u(i, e.start, e.end);
209
+ t && (a === 11 ? o : s).push(t);
153
210
  continue;
154
211
  }
155
212
  if (!t(c, l)) break;
@@ -158,12 +215,27 @@ function c(r) {
158
215
  }
159
216
  if (!t(a, l)) break;
160
217
  }
161
- return o;
218
+ return {
219
+ inputs: o,
220
+ outputs: s
221
+ };
222
+ }
223
+ function f(e) {
224
+ let t = {};
225
+ for (let n of d(e).inputs) n.elemType !== null && (t[n.name] = n.elemType);
226
+ return t;
227
+ }
228
+ function p(e) {
229
+ let { inputs: t, outputs: n } = d(e);
230
+ return {
231
+ inputs: Object.fromEntries(t.map((e) => [e.name, e.shape])),
232
+ outputs: Object.fromEntries(n.map((e) => [e.name, e.shape]))
233
+ };
162
234
  }
163
- function l(e) {
164
- return u(e?.names);
235
+ function m(e) {
236
+ return h(e?.names);
165
237
  }
166
- function u(e) {
238
+ function h(e) {
167
239
  let t = e?.trim();
168
240
  if (!t || !t.startsWith("{") || !t.endsWith("}")) return null;
169
241
  let n = t.slice(1, -1).trim();
@@ -172,7 +244,7 @@ function u(e) {
172
244
  for (let e of n.matchAll(i)) {
173
245
  let t = Number(e[1]), n = e[2] ?? e[3];
174
246
  if (!Number.isInteger(t) || n === void 0) return null;
175
- r.set(t, d(n)), a += e[0].length;
247
+ r.set(t, g(n)), a += e[0].length;
176
248
  }
177
249
  if (r.size === 0 || n.length - a > r.size * 3) return null;
178
250
  let o = [];
@@ -183,10 +255,10 @@ function u(e) {
183
255
  }
184
256
  return o;
185
257
  }
186
- function d(e) {
258
+ function g(e) {
187
259
  return e.replace(/\\(.)/g, (e, t) => t === "n" ? "\n" : t === "r" ? "\r" : t === "t" ? " " : t);
188
260
  }
189
261
  //#endregion
190
- export { l as modelNames, u as parseNames, c as readModelInputTypes, i as readModelMetadata };
262
+ export { m as modelNames, h as parseNames, f as readModelInputTypes, i as readModelMetadata, p as readModelShapes };
191
263
 
192
264
  //# sourceMappingURL=metadata.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"metadata.js","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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"}
1
+ {"version":3,"file":"metadata.js","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\nimport type { DeclaredDim, DeclaredShape } from \"./graph\";\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 number of `output` in `GraphProto` (repeated ValueInfoProto). */\nconst GRAPH_OUTPUT_FIELD = 12;\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 number of `shape` in `TypeProto.Tensor` (TensorShapeProto). */\nconst TENSOR_SHAPE_FIELD = 2;\n\n/** Field number of `dim` in `TensorShapeProto` (repeated Dimension). */\nconst SHAPE_DIM_FIELD = 1;\n\n/** Field number of `dim_value` in `TensorShapeProto.Dimension` (int64). */\nconst DIM_VALUE_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/** What a graph value declares about itself: its element type and its shape. */\ninterface DeclaredTensor {\n readonly elemType: number | null;\n readonly shape: DeclaredShape;\n}\n\n/** A graph value with nothing readable declared. */\nconst UNDECLARED: DeclaredTensor = { elemType: null, shape: [] };\n\n/**\n * Read one `TensorShapeProto.Dimension`.\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 size when the graph pins it to a positive integer, `null` for a\n * symbolic (`dim_param`) or absent one — the same convention as\n * `declaredShapesFrom`, so both sources read alike downstream.\n */\nfunction readDimension(bytes: Uint8Array, start: number, end: number): DeclaredDim {\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 === DIM_VALUE_FIELD && wireType === WIRE_VARINT) {\n const value = readVarint(cursor);\n return value !== null && Number.isSafeInteger(value) && value > 0 ? value : null;\n }\n if (!skipField(cursor, wireType)) return null;\n }\n return null;\n}\n\n/**\n * Read a `TensorShapeProto` into a declared shape.\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 One entry per dimension, or an empty shape when the message cannot\n * be walked — a half-read shape would claim the wrong rank.\n */\nfunction readShape(bytes: Uint8Array, start: number, end: number): DeclaredShape {\n const cursor: Cursor = { bytes, end, pos: start };\n const dims: DeclaredDim[] = [];\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return [];\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === SHAPE_DIM_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) return [];\n dims.push(readDimension(bytes, range.start, range.end));\n continue;\n }\n if (!skipField(cursor, wireType)) return [];\n }\n return dims;\n}\n\n/**\n * Read 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 Its element type and shape; either is left undeclared when the\n * message carries none or cannot be walked.\n */\nfunction readTensorType(bytes: Uint8Array, start: number, end: number): DeclaredTensor {\n const cursor: Cursor = { bytes, end, pos: start };\n let elemType: number | null = null;\n let shape: DeclaredShape = [];\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 === TENSOR_ELEM_TYPE_FIELD && wireType === WIRE_VARINT) {\n elemType = readVarint(cursor);\n continue;\n }\n if (field === TENSOR_SHAPE_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) break;\n shape = readShape(bytes, range.start, range.end);\n continue;\n }\n if (!skipField(cursor, wireType)) break;\n }\n return { elemType, shape };\n}\n\n/**\n * Read 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 tensor's declarations, or {@link UNDECLARED} for a non-tensor\n * type (sequence, map, optional) or an unreadable message.\n */\nfunction readType(bytes: Uint8Array, start: number, end: number): DeclaredTensor {\n const cursor: Cursor = { bytes, end, pos: start };\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return UNDECLARED;\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 UNDECLARED;\n return readTensorType(bytes, range.start, range.end);\n }\n if (!skipField(cursor, wireType)) return UNDECLARED;\n }\n return UNDECLARED;\n}\n\n/**\n * Read one `ValueInfoProto`.\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 value's name and declarations, or `null` when the name is\n * missing or the message is unreadable.\n */\nfunction readValueInfo(\n bytes: Uint8Array,\n start: number,\n end: number,\n): (DeclaredTensor & { readonly name: string }) | null {\n const cursor: Cursor = { bytes, end, pos: start };\n let name: string | null = null;\n let declared: DeclaredTensor = UNDECLARED;\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 declared = readType(bytes, range.start, range.end);\n }\n continue;\n }\n if (!skipField(cursor, wireType)) return null;\n }\n if (name === null) return null;\n return { name, ...declared };\n}\n\n/** The graph's declared inputs and outputs, each in declaration order. */\ninterface GraphValues {\n readonly inputs: readonly (DeclaredTensor & { readonly name: string })[];\n readonly outputs: readonly (DeclaredTensor & { readonly name: string })[];\n}\n\n/**\n * Walk the `GraphProto` and collect what its inputs and outputs declare.\n *\n * @param model The `.onnx` file contents.\n * @returns Both lists, empty when the file carries no readable graph.\n */\nfunction readGraphValues(model: Uint8Array | ArrayBufferLike): GraphValues {\n const bytes = model instanceof Uint8Array ? model : new Uint8Array(model);\n const cursor: Cursor = { bytes, end: bytes.length, pos: 0 };\n const inputs: (DeclaredTensor & { readonly name: string })[] = [];\n const outputs: (DeclaredTensor & { readonly name: 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_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 (\n (innerField === GRAPH_INPUT_FIELD || innerField === GRAPH_OUTPUT_FIELD) &&\n innerWire === WIRE_LENGTH_DELIMITED\n ) {\n const range = readLengthDelimited(inner);\n if (range === null) break;\n const info = readValueInfo(bytes, range.start, range.end);\n if (info) (innerField === GRAPH_INPUT_FIELD ? inputs : outputs).push(info);\n continue;\n }\n if (!skipField(inner, innerWire)) break;\n }\n continue;\n }\n if (!skipField(cursor, wireType)) break;\n }\n\n return { inputs, outputs };\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 types: Record<string, number> = {};\n for (const input of readGraphValues(model).inputs) {\n if (input.elemType !== null) types[input.name] = input.elemType;\n }\n return types;\n}\n\n/**\n * Read the shape each graph input and output declares, straight from the file.\n *\n * `onnxruntime-web` reports these through `inputMetadata` / `outputMetadata`\n * only from 1.22 on. Below that the session answers nothing, and a task that\n * reads its input size or class count off the session silently fell back to\n * its defaults: a 64x64 detector was fed 640x640 and ORT aborted with\n * `Got invalid dimensions for input` (measured on 1.17.3, 1.18.0, 1.19.2,\n * 1.20.1 and 1.21.0). The\n * file carries the same declarations, in the same `ValueInfoProto` the element\n * types are read from.\n *\n * Keyed by name rather than position: in an older IR the graph's `input` list\n * also carries the initializers, so its order does not line up with the\n * session's `inputNames`.\n *\n * @param model The `.onnx` file contents.\n * @returns Input and output name → shape, dynamic axes as `null`. Both maps\n * are empty when the file carries no readable graph.\n */\nexport function readModelShapes(model: Uint8Array | ArrayBufferLike): {\n readonly inputs: Readonly<Record<string, DeclaredShape>>;\n readonly outputs: Readonly<Record<string, DeclaredShape>>;\n} {\n const { inputs, outputs } = readGraphValues(model);\n return {\n inputs: Object.fromEntries(inputs.map((value) => [value.name, value.shape])),\n outputs: Object.fromEntries(outputs.map((value) => [value.name, value.shape])),\n };\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,2 +1,2 @@
1
- const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("./exceptions.cjs"),n=require("./dtypes.cjs"),r=require("./graph.cjs"),i=require("./metadata.cjs"),a=require("./providers.cjs");let o=require("onnxruntime-web");o=e.__toESM(o,1);var s=`ort_vision_sdk.graph_optimization`,c=`CAcSDm9ydC12aXNpb24tc2RrOjoKEAoBeBIBeSIISWRlbnRpdHkSBHdhcm1aDwoBeBIKCggIARIECgIIAWIPCgF5EgoKCAgBEgQKAggBQgQKABAN`,l=new Map;function u(e){let t=e.map(a.providerName).join(`,`),n=l.get(t);return n===void 0&&(n=(async()=>{try{let t=Uint8Array.from(atob(c),e=>e.charCodeAt(0));await(await o.InferenceSession.create(t,{executionProviders:e})).release()}catch{return}})(),l.set(t,n)),n}function d(){console.warn(`[@ort-vision-sdk/web] This model was pre-optimized by optimize_model, which targets the WASM backend; on WebGPU some of its fused nodes fall back to the CPU. For WebGPU, ship the original export instead.`)}var f=`ort_vision_sdk.quantization`;function p(e,t){if(t[`ort_vision_sdk.quantization`]===void 0)return[...e];let n=e.filter(e=>a.providerName(e)!==`webgpu`);return n.length===e.length?n:(console.warn(`[@ort-vision-sdk/web] This model was quantized by quantize_model (${t[f]}); ONNX Runtime Web's WebGPU backend cannot run its quantized operators, so it runs on WASM.`),n.length>0?n:[a.FALLBACK_PROVIDER])}var m=`ort-vision-sdk-models`;async function h(e,t){let n=t===null?null:await _(t);if(n!==null){let t=await n.match(e).catch(()=>void 0);if(t!==void 0)return new Uint8Array(await t.arrayBuffer())}try{let t=await fetch(e);if(!t.ok)return v(e,`HTTP ${t.status} ${t.statusText}`),e;let r=await t.arrayBuffer();return n!==null&&await g(n,e,r),new Uint8Array(r)}catch(t){return v(e,t.message),e}}async function g(e,t,n){try{await e.put(t,new Response(n))}catch{return}}async function _(e){if(typeof caches>`u`)return null;try{return await caches.open(e)}catch{return null}}function v(e,t){console.warn(`[@ort-vision-sdk/web] Could not fetch ${e} to read its metadata (${t}). Letting ONNX Runtime load it instead: the model will work, but its baked-in class names are unavailable, so labels fall back to class_0, class_1, ... Pass \`labels\` explicitly to name them.`)}function y(e,t){let n=e.filter(e=>!t.includes(e));n.length!==0&&console.warn(`This browser cannot offer the requested execution provider(s) ${JSON.stringify(n)}; the session will run on ${JSON.stringify(t)}. Inference still produces correct results, on the fallback provider.`)}function b(e){let t=i.readModelInputTypes(e),r={};for(let[e,i]of Object.entries(t))r[e]=n.tensorTypeFor(i);return r}function x(){console.warn(`Could not read any input type from this model's bytes; feeds will be built as float32. A half-precision model will fail at inference with 'Unexpected input data type'. Please report this with the model that produced it.`)}function S(e){let r=Object.entries(e).filter(([,e])=>e===`float16`);if(r.length===0||n.hasFloat16Array())return;let i=r.map(([e])=>e).join(`, `);throw new t.ModelLoadError(`This model declares half-precision input(s) [${i}], but this environment has no Float16Array, which ONNX Runtime requires for a float16 tensor. Use a float32 export of the model, or run in a browser that supports Float16Array.`)}var C=class e{_session;providers;_metadata;requestedProviders;_inputTypes;constructor(e,t,n,r,i={}){this._session=e,this.providers=t,this._metadata=n,this.requestedProviders=r,this._inputTypes=i}_runQueue=Promise.resolve();static async create(n,r={}){let s=a.resolveProviders(r.providers),c=r.readMetadata!==!1,l=r.cache===!0?m:r.cache?r.cache:null,f=typeof n==`string`&&(c||l!==null),g=a.detectProviders(s).then(e=>e.length>0?e:[a.FALLBACK_PROVIDER]),[_,v]=await Promise.all([g,f?h(n,l):Promise.resolve(n),f?g.then(u):Promise.resolve()]),C=c&&typeof v!=`string`?i.readModelMetadata(v):{},w=p(_,C),T=s.map(a.providerName),E=w.map(a.providerName);r.providers!==void 0&&r.providers.length>0&&y(T,_.map(a.providerName)),C[`ort_vision_sdk.graph_optimization`]!==void 0&&E.includes(`webgpu`)&&d();let D={...C[`ort_vision_sdk.graph_optimization`]!==void 0&&r.sessionOptions?.graphOptimizationLevel===void 0?{graphOptimizationLevel:`disabled`}:{},...r.sessionOptions??{},executionProviders:w},O=typeof v==`string`?{}:b(v);typeof v!=`string`&&Object.keys(O).length===0&&x(),S(O);let k;try{k=(typeof v==`string`||v instanceof Uint8Array,await o.InferenceSession.create(v,D))}catch(e){throw new t.ModelLoadError(`Failed to load ONNX model: ${e.message}`,{cause:e})}return new e(k,E,C,T,O)}get inputDtypes(){return this.inputNames.map(e=>this._inputTypes[e]??`float32`)}get inputDtype(){return this._inputTypes[this.inputName]??`float32`}get inputNames(){return this._session.inputNames}get inputName(){let e=this._session.inputNames[0];if(e===void 0)throw new t.InferenceError(`Model has no inputs.`);return e}get outputNames(){return this._session.outputNames}get inputShapes(){return r.declaredShapesFrom(this._session.inputMetadata)}get inputShape(){return this.inputShapes[0]??[]}get outputShapes(){return r.declaredShapesFrom(this._session.outputMetadata)}get outputShape(){return this.outputShapes[0]??[]}get metadata(){return this._metadata}async release(){await this._session.release().catch(()=>void 0)}get raw(){return this._session}run(e){let t=this._runQueue.then(()=>this._runNow(e));return this._runQueue=t.catch(()=>void 0),t}async _runNow(e){try{return await this._session.run(this._asDeclaredTypes(e))}catch(e){throw new t.InferenceError(`Inference failed: ${e.message}`,{cause:e})}}_asDeclaredTypes(e){let t=null;for(let[r,i]of Object.entries(e)){let a=this._inputTypes[r];if(a===void 0||a===i.type||!(i.data instanceof Float32Array))continue;let s=n.toFeedData(i.data,a);s!==i.data&&(t??={...e},t[r]=new o.Tensor(a,s,i.dims))}return t??e}};exports.DEFAULT_MODEL_CACHE=m,exports.GRAPH_OPTIMIZATION_KEY=s,exports.OrtSession=C,exports.QUANTIZATION_KEY=f;
1
+ const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("./exceptions.cjs"),n=require("./dtypes.cjs"),r=require("./graph.cjs"),i=require("./metadata.cjs"),a=require("./providers.cjs");let o=require("onnxruntime-web");o=e.__toESM(o,1);var s=`ort_vision_sdk.graph_optimization`,c=`CAcSDm9ydC12aXNpb24tc2RrOjoKEAoBeBIBeSIISWRlbnRpdHkSBHdhcm1aDwoBeBIKCggIARIECgIIAWIPCgF5EgoKCAgBEgQKAggBQgQKABAN`,l=new Map;function u(e){let t=e.map(a.providerName).join(`,`),n=l.get(t);return n===void 0&&(n=(async()=>{try{let t=Uint8Array.from(atob(c),e=>e.charCodeAt(0));await(await o.InferenceSession.create(t,{executionProviders:e})).release()}catch{return}})(),l.set(t,n)),n}function d(){console.warn(`[@ort-vision-sdk/web] This model was pre-optimized by optimize_model, which targets the WASM backend; on WebGPU some of its fused nodes fall back to the CPU. For WebGPU, ship the original export instead.`)}var f=`ort_vision_sdk.quantization`;function p(e,t){if(t[`ort_vision_sdk.quantization`]===void 0)return[...e];let n=e.filter(e=>a.providerName(e)!==`webgpu`);return n.length===e.length?n:(console.warn(`[@ort-vision-sdk/web] This model was quantized by quantize_model (${t[f]}); ONNX Runtime Web's WebGPU backend cannot run its quantized operators, so it runs on WASM.`),n.length>0?n:[a.FALLBACK_PROVIDER])}var m=`ort-vision-sdk-models`;async function h(e,t){let n=t===null?null:await _(t);if(n!==null){let t=await n.match(e).catch(()=>void 0);if(t!==void 0)return new Uint8Array(await t.arrayBuffer())}try{let t=await fetch(e);if(!t.ok)return v(e,`HTTP ${t.status} ${t.statusText}`),e;let r=await t.arrayBuffer();return n!==null&&await g(n,e,r),new Uint8Array(r)}catch(t){return v(e,t.message),e}}async function g(e,t,n){try{await e.put(t,new Response(n))}catch{return}}async function _(e){if(typeof caches>`u`)return null;try{return await caches.open(e)}catch{return null}}function v(e,t){console.warn(`[@ort-vision-sdk/web] Could not fetch ${e} to read its metadata (${t}). Letting ONNX Runtime load it instead: the model will work, but its baked-in class names are unavailable, so labels fall back to class_0, class_1, ... Pass \`labels\` explicitly to name them.`)}function y(e,t){let n=e.filter(e=>!t.includes(e));n.length!==0&&console.warn(`This browser cannot offer the requested execution provider(s) ${JSON.stringify(n)}; the session will run on ${JSON.stringify(t)}. Inference still produces correct results, on the fallback provider.`)}function b(e){let t=i.readModelInputTypes(e),r={};for(let[e,i]of Object.entries(t))r[e]=n.tensorTypeFor(i);return r}function x(){console.warn(`Could not read any input type from this model's bytes; feeds will be built as float32. A half-precision model will fail at inference with 'Unexpected input data type'. Please report this with the model that produced it.`)}function S(e){let r=Object.entries(e).filter(([,e])=>e===`float16`);if(r.length===0||n.hasFloat16Array())return;let i=r.map(([e])=>e).join(`, `);throw new t.ModelLoadError(`This model declares half-precision input(s) [${i}], but this environment has no Float16Array, which ONNX Runtime requires for a float16 tensor. Use a float32 export of the model, or run in a browser that supports Float16Array.`)}var C=class e{_session;providers;_metadata;requestedProviders;_inputTypes;_fileShapes;constructor(e,t,n,r,i={},a={inputs:{},outputs:{}}){this._session=e,this.providers=t,this._metadata=n,this.requestedProviders=r,this._inputTypes=i,this._fileShapes=a}_runQueue=Promise.resolve();static async create(n,r={}){let s=a.resolveProviders(r.providers),c=r.readMetadata!==!1,l=r.cache===!0?m:r.cache?r.cache:null,f=typeof n==`string`&&(c||l!==null),g=a.detectProviders(s).then(e=>e.length>0?e:[a.FALLBACK_PROVIDER]),[_,v]=await Promise.all([g,f?h(n,l):Promise.resolve(n),f?g.then(u):Promise.resolve()]),C=c&&typeof v!=`string`?i.readModelMetadata(v):{},w=p(_,C),T=s.map(a.providerName),E=w.map(a.providerName);r.providers!==void 0&&r.providers.length>0&&y(T,_.map(a.providerName)),C[`ort_vision_sdk.graph_optimization`]!==void 0&&E.includes(`webgpu`)&&d();let D={...C[`ort_vision_sdk.graph_optimization`]!==void 0&&r.sessionOptions?.graphOptimizationLevel===void 0?{graphOptimizationLevel:`disabled`}:{},...r.sessionOptions??{},executionProviders:w},O=typeof v==`string`?{}:b(v),k=typeof v==`string`?{inputs:{},outputs:{}}:i.readModelShapes(v);typeof v!=`string`&&Object.keys(O).length===0&&x(),S(O);let A;try{A=(typeof v==`string`||v instanceof Uint8Array,await o.InferenceSession.create(v,D))}catch(e){throw new t.ModelLoadError(`Failed to load ONNX model: ${e.message}`,{cause:e})}return new e(A,E,C,T,O,k)}get inputDtypes(){return this.inputNames.map(e=>this._inputTypes[e]??`float32`)}get inputDtype(){return this._inputTypes[this.inputName]??`float32`}get inputNames(){return this._session.inputNames}get inputName(){let e=this._session.inputNames[0];if(e===void 0)throw new t.InferenceError(`Model has no inputs.`);return e}get outputNames(){return this._session.outputNames}get inputShapes(){return this._shapesOf(this._session.inputMetadata,this._session.inputNames,this._fileShapes.inputs)}get inputShape(){return this.inputShapes[0]??[]}get outputShapes(){return this._shapesOf(this._session.outputMetadata,this._session.outputNames,this._fileShapes.outputs)}_shapesOf(e,t,n){let i=r.declaredShapesFrom(e);return i.length>0?i:t.map(e=>n[e]??[])}get outputShape(){return this.outputShapes[0]??[]}get metadata(){return this._metadata}async release(){await this._session.release().catch(()=>void 0)}get raw(){return this._session}run(e){let t=this._runQueue.then(()=>this._runNow(e));return this._runQueue=t.catch(()=>void 0),t}async _runNow(e){try{return await this._session.run(this._asDeclaredTypes(e))}catch(e){throw new t.InferenceError(`Inference failed: ${e.message}`,{cause:e})}}_asDeclaredTypes(e){let t=null;for(let[r,i]of Object.entries(e)){let a=this._inputTypes[r];if(a===void 0||a===i.type||!(i.data instanceof Float32Array))continue;let s=n.toFeedData(i.data,a);s!==i.data&&(t??={...e},t[r]=new o.Tensor(a,s,i.dims))}return t??e}};exports.DEFAULT_MODEL_CACHE=m,exports.GRAPH_OPTIMIZATION_KEY=s,exports.OrtSession=C,exports.QUANTIZATION_KEY=f;
2
2
  //# sourceMappingURL=session.cjs.map