idmission-web-sdk 2.3.224 → 2.3.225-feature-per-runtime-capability-probe-e2ff01d

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.
@@ -3134,204 +3134,188 @@ function useStateWithCapturedAt() {
3134
3134
  return [value, setWithStamp, capturedAt];
3135
3135
  }
3136
3136
 
3137
- var visionTasksBasePath = "https://websdk-cdn-dev.idmission.com/assets/vision_wasm_internal_0.10.7";
3138
- var visionRuntimeHash = 'tdLjRcm8XLETT+lUxF1oNst5jULaTGDUc2YtazwbGnLVGD0D/4A274KuJF+adneW';
3139
- var wasmStderrPatterns = ['TensorFlow Lite', 'static-sized tensors', 'Attempting to use a delegate'];
3140
- function isWasmStderr(msg) {
3141
- return wasmStderrPatterns.some(function (p) {
3142
- return msg.includes(p);
3143
- });
3137
+ var RUNTIME_NAMES = ['mediapipe', 'litert'];
3138
+ var defaultImageSegmenterModelPath = 'https://websdk-cdn-dev.idmission.com/assets/models/selfiesegmenter20240524/selfie_segmenter.tflite';
3139
+ var defaultImageSegmenterModelHash = 'A2bQ8+iZyQM3KIGVBUf0FyetqxuynyKpjsjCE8uzoJEnj1ghCu6ge2daiRffAiS5';
3140
+ var imageSegmenterModelSizeInBytes = 256440.32;
3141
+ // We globally set a cache key based on the time at page load so the built-in
3142
+ // speed test isn't fooled by cache hits, but subsequent downloads of the
3143
+ // vision runtime do load from the cache.
3144
+ var tinyModelCacheKey = new Date().getTime();
3145
+ function makeInitialModelCapabilities() {
3146
+ return {
3147
+ networkProbeState: 'notProbed',
3148
+ networkTier: 'untested',
3149
+ networkSpeed: 0,
3150
+ networkTestTime: 0,
3151
+ delegateByRuntime: Object.fromEntries(RUNTIME_NAMES.map(function (name) {
3152
+ return [name, {
3153
+ probeState: 'notProbed',
3154
+ delegate: 'GPU'
3155
+ }];
3156
+ }))
3157
+ };
3144
3158
  }
3145
- var quietWasmRefCount = 0;
3146
- var savedNativeError = null;
3147
- /**
3148
- * Wraps an async operation that initializes WASM/TFLite models, temporarily
3149
- * intercepting console.error to downgrade known-benign TF Lite stderr messages
3150
- * (routed through Emscripten's fd_write -> console.error) to debug level.
3151
- *
3152
- * Uses a reference count so overlapping calls share a single patched handler
3153
- * and only restore the original console.error when the last one completes.
3154
- */
3155
- function withQuietWasm(fn) {
3156
- return __awaiter(this, void 0, void 0, function () {
3157
- return __generator(this, function (_a) {
3158
- if (quietWasmRefCount++ === 0) {
3159
- savedNativeError = console.error; // eslint-disable-line no-console
3160
- console.error = function () {
3161
- var args = [];
3162
- for (var _i = 0; _i < arguments.length; _i++) {
3163
- args[_i] = arguments[_i];
3164
- }
3165
- if (isWasmStderr(String(args[0]))) {
3166
- debug.apply(void 0, args);
3167
- return;
3168
- }
3169
- savedNativeError.apply(void 0, args);
3170
- };
3171
- }
3172
- return [2 /*return*/, fn()["finally"](function () {
3173
- if (--quietWasmRefCount === 0) {
3174
- console.error = savedNativeError; // eslint-disable-line no-console
3175
- savedNativeError = null;
3176
- }
3177
- })];
3178
- });
3179
- });
3159
+ var modelCapabilities = makeInitialModelCapabilities();
3160
+ function getDelegate(runtime) {
3161
+ return modelCapabilities.delegateByRuntime[runtime].delegate;
3180
3162
  }
3181
- var visionRuntimePreloading = false;
3182
- function preloadVisionRuntime() {
3163
+ function setDelegate(runtime, delegate) {
3164
+ modelCapabilities.delegateByRuntime[runtime].delegate = delegate;
3165
+ }
3166
+ // Network speed probe. Runtime-agnostic — just times an HTTP fetch of a
3167
+ // small known artifact. Idempotent across concurrent callers via the
3168
+ // 'probing' wait loop.
3169
+ function probeNetworkSpeed() {
3183
3170
  return __awaiter(this, void 0, void 0, function () {
3184
- function handleDownloadProgress(event) {
3185
- var detail = event.detail;
3186
- if (detail.url !== url) return;
3187
- progressByUseCase.visionRuntime = sumUpProgressForDependencies([url]);
3188
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress.visionRuntime', {
3189
- detail: progressByUseCase.visionRuntime
3190
- }));
3191
- }
3192
- var url;
3171
+ var modelAssetPath, startedAt, e_1, time, speedMbps;
3193
3172
  return __generator(this, function (_a) {
3194
3173
  switch (_a.label) {
3195
3174
  case 0:
3196
- if (visionRuntimePreloading) return [2 /*return*/, new Promise(function (resolve) {
3197
- setInterval(function () {
3198
- if (!visionRuntimePreloading) resolve();
3199
- }, 100);
3200
- })];
3201
- visionRuntimePreloading = true;
3202
- url = "".concat(visionTasksBasePath, "/vision_wasm_internal.wasm");
3203
- document.addEventListener('idmission.preloadProgress', handleDownloadProgress);
3175
+ if (modelCapabilities.networkProbeState === 'probed') return [2 /*return*/];
3176
+ if (modelCapabilities.networkProbeState === 'probing') {
3177
+ return [2 /*return*/, new Promise(function (resolve) {
3178
+ var id = setInterval(function () {
3179
+ if (modelCapabilities.networkProbeState === 'probed') {
3180
+ clearInterval(id);
3181
+ resolve();
3182
+ }
3183
+ }, 100);
3184
+ })];
3185
+ }
3186
+ modelCapabilities.networkProbeState = 'probing';
3204
3187
  _a.label = 1;
3205
3188
  case 1:
3206
- _a.trys.push([1,, 3, 4]);
3207
- return [4 /*yield*/, preloadDependency(url, visionRuntimeHash)];
3189
+ _a.trys.push([1,, 6, 7]);
3190
+ modelAssetPath = "".concat(defaultImageSegmenterModelPath, "?_=").concat(tinyModelCacheKey);
3191
+ startedAt = new Date();
3192
+ _a.label = 2;
3208
3193
  case 2:
3209
- _a.sent();
3210
- return [3 /*break*/, 4];
3194
+ _a.trys.push([2, 4,, 5]);
3195
+ return [4 /*yield*/, Promise.race([preloadDependency(modelAssetPath, defaultImageSegmenterModelHash), giveUpAfter(10000)])];
3211
3196
  case 3:
3212
- document.removeEventListener('idmission.preloadProgress', handleDownloadProgress);
3213
- visionRuntimePreloading = false;
3214
- return [7 /*endfinally*/];
3197
+ _a.sent();
3198
+ return [3 /*break*/, 5];
3215
3199
  case 4:
3200
+ e_1 = _a.sent();
3201
+ error('speed test failed', e_1);
3202
+ modelCapabilities.networkTier = 'unusable';
3203
+ return [2 /*return*/];
3204
+ case 5:
3205
+ time = (new Date().getTime() - startedAt.getTime()) / 1000.0;
3206
+ modelCapabilities.networkTestTime || (modelCapabilities.networkTestTime = time);
3207
+ modelCapabilities.networkSpeed || (modelCapabilities.networkSpeed = imageSegmenterModelSizeInBytes / time);
3208
+ modelCapabilities.networkTier = time < 0.5 ? 'fast' : time < 2 ? 'medium' : 'slow';
3209
+ speedMbps = modelCapabilities.networkSpeed / 1024 / 1024;
3210
+ log('Model Probing: network speed', speedMbps.toFixed(3), 'Mbps');
3211
+ log('Model Probing: network test took', time);
3212
+ log('Model Probing: network tier', modelCapabilities.networkTier);
3213
+ return [3 /*break*/, 7];
3214
+ case 6:
3215
+ modelCapabilities.networkProbeState = 'probed';
3216
+ return [7 /*endfinally*/];
3217
+ case 7:
3216
3218
  return [2 /*return*/];
3217
3219
  }
3218
3220
  });
3219
3221
  });
3220
3222
  }
3221
-
3222
- var defaultImageSegmenterModelPath = 'https://websdk-cdn-dev.idmission.com/assets/models/selfiesegmenter20240524/selfie_segmenter.tflite';
3223
- var defaultImageSegmenterModelHash = 'A2bQ8+iZyQM3KIGVBUf0FyetqxuynyKpjsjCE8uzoJEnj1ghCu6ge2daiRffAiS5';
3224
- var imageSegmenterModelSizeInBytes = 256440.32;
3225
- // The idea here is that we globally set a cache key based on the time at page load. That way our built-in speed test
3226
- // isn't fooled by cache times, but subsequent downloads of the vision runtime still do load from the cache.
3227
- var tinyModelCacheKey = new Date().getTime();
3228
- var initialModelCapabilities = {
3229
- probeState: 'notProbed',
3230
- delegate: 'GPU',
3231
- networkTier: 'untested',
3232
- networkSpeed: 0,
3233
- networkTestTime: 0
3234
- };
3235
- var modelCapabilities = _assign({}, initialModelCapabilities);
3236
- function probeModelCapabilities() {
3223
+ // Probe a specific runtime's GPU/CPU delegate. Lazily dispatches to the
3224
+ // runtime-specific verifier via dynamic import so a customer who never
3225
+ // invokes a particular runtime never loads its WASM payload.
3226
+ function probeDelegateForRuntime(runtime) {
3237
3227
  return __awaiter(this, void 0, void 0, function () {
3238
- var error_1, error_2;
3228
+ var state, firstError_1, secondError_1;
3239
3229
  return __generator(this, function (_a) {
3240
3230
  switch (_a.label) {
3241
3231
  case 0:
3242
- if (modelCapabilities.probeState === 'probed') return [2 /*return*/];
3243
- if (modelCapabilities.probeState === 'probing') return [2 /*return*/, new Promise(function (resolve) {
3244
- var id = setInterval(function () {
3245
- if (modelCapabilities.probeState === 'probed') {
3246
- clearInterval(id);
3247
- resolve();
3248
- }
3249
- }, 100);
3250
- })];
3251
- modelCapabilities.probeState = 'probing';
3252
- return [4 /*yield*/, preloadVisionRuntime()];
3232
+ state = modelCapabilities.delegateByRuntime[runtime];
3233
+ if (state.probeState === 'probed') return [2 /*return*/];
3234
+ if (state.probeState === 'probing') {
3235
+ return [2 /*return*/, new Promise(function (resolve) {
3236
+ var id = setInterval(function () {
3237
+ if (state.probeState === 'probed') {
3238
+ clearInterval(id);
3239
+ resolve();
3240
+ }
3241
+ }, 100);
3242
+ })];
3243
+ }
3244
+ state.probeState = 'probing';
3245
+ _a.label = 1;
3253
3246
  case 1:
3254
- _a.sent();
3255
- _a.label = 2;
3247
+ _a.trys.push([1,, 11, 12]);
3248
+ // Need network speed first because the delegate verifier reuses the
3249
+ // segmenter test model bytes.
3250
+ return [4 /*yield*/, probeNetworkSpeed()];
3256
3251
  case 2:
3257
- _a.trys.push([2, 4, 9, 10]);
3258
- log('Model Probing: testing GPU capabilities...');
3259
- return [4 /*yield*/, loadTinyModel('GPU')];
3252
+ // Need network speed first because the delegate verifier reuses the
3253
+ // segmenter test model bytes.
3254
+ _a.sent();
3255
+ if (modelCapabilities.networkTier === 'unusable') {
3256
+ state.delegate = 'NONE';
3257
+ return [2 /*return*/];
3258
+ }
3259
+ _a.label = 3;
3260
3260
  case 3:
3261
+ _a.trys.push([3, 5,, 10]);
3262
+ log("Model Probing: testing ".concat(runtime, " GPU capabilities..."));
3263
+ return [4 /*yield*/, verifyDelegate(runtime, 'GPU')];
3264
+ case 4:
3261
3265
  _a.sent();
3262
- log('Model Probing: GPU is capable.');
3266
+ log("Model Probing: ".concat(runtime, " GPU is capable."));
3263
3267
  return [3 /*break*/, 10];
3264
- case 4:
3265
- error_1 = _a.sent();
3266
- warn('Model Probing: GPU delegate could not be loaded', error_1);
3267
- modelCapabilities.delegate = 'CPU';
3268
- _a.label = 5;
3269
3268
  case 5:
3270
- _a.trys.push([5, 7,, 8]);
3271
- log('Model Probing: testing CPU capabilities...');
3272
- return [4 /*yield*/, loadTinyModel('CPU')];
3269
+ firstError_1 = _a.sent();
3270
+ warn("Model Probing: ".concat(runtime, " GPU delegate could not be loaded"), firstError_1);
3271
+ state.delegate = 'CPU';
3272
+ _a.label = 6;
3273
3273
  case 6:
3274
- _a.sent();
3275
- log('Model Probing: CPU is capable.');
3276
- return [3 /*break*/, 8];
3274
+ _a.trys.push([6, 8,, 9]);
3275
+ log("Model Probing: testing ".concat(runtime, " CPU capabilities..."));
3276
+ return [4 /*yield*/, verifyDelegate(runtime, 'CPU')];
3277
3277
  case 7:
3278
- error_2 = _a.sent();
3279
- warn('Model Probing: CPU delegate could not be loaded', error_2);
3280
- modelCapabilities.delegate = 'NONE';
3281
- return [3 /*break*/, 8];
3278
+ _a.sent();
3279
+ log("Model Probing: ".concat(runtime, " CPU is capable."));
3280
+ return [3 /*break*/, 9];
3282
3281
  case 8:
3283
- return [3 /*break*/, 10];
3282
+ secondError_1 = _a.sent();
3283
+ warn("Model Probing: ".concat(runtime, " CPU delegate could not be loaded"), secondError_1);
3284
+ state.delegate = 'NONE';
3285
+ return [3 /*break*/, 9];
3284
3286
  case 9:
3285
- modelCapabilities.probeState = 'probed';
3286
- return [7 /*endfinally*/];
3287
+ return [3 /*break*/, 10];
3287
3288
  case 10:
3289
+ return [3 /*break*/, 12];
3290
+ case 11:
3291
+ state.probeState = 'probed';
3292
+ return [7 /*endfinally*/];
3293
+ case 12:
3288
3294
  return [2 /*return*/];
3289
3295
  }
3290
3296
  });
3291
3297
  });
3292
3298
  }
3293
- function loadTinyModel() {
3294
- return __awaiter(this, arguments, void 0, function (delegate, maxTime) {
3295
- var modelAssetPath, startedAt, e_1, time, speedMbps, verifyMediaPipeDelegate;
3296
- if (delegate === void 0) {
3297
- delegate = 'GPU';
3298
- }
3299
- if (maxTime === void 0) {
3300
- maxTime = 10000;
3301
- }
3299
+ function verifyDelegate(runtime, delegate) {
3300
+ return __awaiter(this, void 0, void 0, function () {
3301
+ var modelAssetPath, preloadVisionRuntime, verifyMediaPipeDelegate, exhaustive;
3302
3302
  return __generator(this, function (_a) {
3303
3303
  switch (_a.label) {
3304
3304
  case 0:
3305
3305
  modelAssetPath = "".concat(defaultImageSegmenterModelPath, "?_=").concat(tinyModelCacheKey);
3306
- startedAt = new Date();
3307
- _a.label = 1;
3306
+ return [4 /*yield*/, Promise.resolve().then(function () { return VisionRuntime; })];
3308
3307
  case 1:
3309
- _a.trys.push([1, 3,, 4]);
3310
- return [4 /*yield*/, Promise.race([preloadDependency(modelAssetPath, defaultImageSegmenterModelHash), giveUpAfter(maxTime)])];
3308
+ preloadVisionRuntime = _a.sent().preloadVisionRuntime;
3309
+ return [4 /*yield*/, preloadVisionRuntime()];
3311
3310
  case 2:
3312
3311
  _a.sent();
3313
- return [3 /*break*/, 4];
3314
- case 3:
3315
- e_1 = _a.sent();
3316
- error('speed test failed', e_1);
3317
- modelCapabilities.networkTier = 'unusable';
3318
- return [2 /*return*/];
3319
- case 4:
3320
- time = (new Date().getTime() - startedAt.getTime()) / 1000.0;
3321
- modelCapabilities.networkTestTime || (modelCapabilities.networkTestTime = time);
3322
- modelCapabilities.networkSpeed || (modelCapabilities.networkSpeed = imageSegmenterModelSizeInBytes / time);
3323
- modelCapabilities.networkTier = time < 0.5 ? 'fast' : time < 2 ? 'medium' : 'slow';
3324
- speedMbps = modelCapabilities.networkSpeed / 1024 / 1024;
3325
- log('Model Probing: network speed', speedMbps.toFixed(3), 'Mbps');
3326
- log('Model Probing: network test took', time);
3327
- log('Model Probing: network tier', modelCapabilities.networkTier);
3328
3312
  return [4 /*yield*/, Promise.resolve().then(function () { return CapabilityProbe; })];
3329
- case 5:
3313
+ case 3:
3330
3314
  verifyMediaPipeDelegate = _a.sent().verifyMediaPipeDelegate;
3331
- return [4 /*yield*/, verifyMediaPipeDelegate(delegate, modelAssetPath)];
3332
- case 6:
3333
- _a.sent();
3334
- return [2 /*return*/];
3315
+ return [2 /*return*/, verifyMediaPipeDelegate(delegate, modelAssetPath)];
3316
+ case 4:
3317
+ exhaustive = runtime;
3318
+ throw new Error("Unknown runtime: ".concat(exhaustive));
3335
3319
  }
3336
3320
  });
3337
3321
  });
@@ -3376,7 +3360,7 @@ var defaultModelPaths = {
3376
3360
 
3377
3361
  var preloadModels = function preloadModels(_a) {
3378
3362
  return __awaiter(void 0, [_a], void 0, function (_b) {
3379
- var preloadTasks;
3363
+ var needsMediaPipe, preloadTasks;
3380
3364
  var _c = _b.documentDetectionModel,
3381
3365
  documentDetectionModel = _c === void 0 ? true : _c,
3382
3366
  _d = _b.focusModel,
@@ -3390,9 +3374,24 @@ var preloadModels = function preloadModels(_a) {
3390
3374
  return __generator(this, function (_h) {
3391
3375
  switch (_h.label) {
3392
3376
  case 0:
3393
- return [4 /*yield*/, probeModelCapabilities()];
3377
+ // Network probe is runtime-agnostic. The delegate probe is per-runtime;
3378
+ // every model preloaded by this function is currently MediaPipe-backed,
3379
+ // so probe MP only when at least one such model is in the config. If a
3380
+ // future caller passes only LiteRT-backed models, MP will not be probed.
3381
+ return [4 /*yield*/, probeNetworkSpeed()];
3394
3382
  case 1:
3383
+ // Network probe is runtime-agnostic. The delegate probe is per-runtime;
3384
+ // every model preloaded by this function is currently MediaPipe-backed,
3385
+ // so probe MP only when at least one such model is in the config. If a
3386
+ // future caller passes only LiteRT-backed models, MP will not be probed.
3387
+ _h.sent();
3388
+ needsMediaPipe = !!documentDetectionModel || !!focusModel || !!faceDetectionModel || !!faceLandmarkerModel || !!barcodeReadabilityModel;
3389
+ if (!needsMediaPipe) return [3 /*break*/, 3];
3390
+ return [4 /*yield*/, probeDelegateForRuntime('mediapipe')];
3391
+ case 2:
3395
3392
  _h.sent();
3393
+ _h.label = 3;
3394
+ case 3:
3396
3395
  preloadTasks = [];
3397
3396
  if (documentDetectionModel) {
3398
3397
  preloadTasks.push(preloadDocumentDetectorDependencies);
@@ -3410,7 +3409,7 @@ var preloadModels = function preloadModels(_a) {
3410
3409
  preloadTasks.push(preloadBarcodeReadabilityModelDependencies);
3411
3410
  }
3412
3411
  return [4 /*yield*/, Promise.all(preloadTasks)];
3413
- case 2:
3412
+ case 4:
3414
3413
  _h.sent();
3415
3414
  return [2 /*return*/];
3416
3415
  }
@@ -3571,10 +3570,19 @@ function preloadModelDependencies(model) {
3571
3570
  }, 100);
3572
3571
  })];
3573
3572
  modelsPreloading[model] = true;
3574
- return [4 /*yield*/, probeModelCapabilities()];
3573
+ // All five models in this function are MediaPipe-backed; probe MP's
3574
+ // delegate to surface NONE before we waste bandwidth downloading bytes
3575
+ // for a model the device can't run.
3576
+ return [4 /*yield*/, probeNetworkSpeed()];
3575
3577
  case 1:
3578
+ // All five models in this function are MediaPipe-backed; probe MP's
3579
+ // delegate to surface NONE before we waste bandwidth downloading bytes
3580
+ // for a model the device can't run.
3576
3581
  _a.sent();
3577
- if (modelCapabilities.delegate === 'NONE') {
3582
+ return [4 /*yield*/, probeDelegateForRuntime('mediapipe')];
3583
+ case 2:
3584
+ _a.sent();
3585
+ if (getDelegate('mediapipe') === 'NONE') {
3578
3586
  throw new Error("No available delegate for ".concat(model, " model."));
3579
3587
  }
3580
3588
  dependencies = [{
@@ -3582,20 +3590,20 @@ function preloadModelDependencies(model) {
3582
3590
  hash: defaultModelPaths[model + 'Hash']
3583
3591
  }];
3584
3592
  document.addEventListener('idmission.preloadProgress', handleModelDownloadProgress);
3585
- _a.label = 2;
3586
- case 2:
3587
- _a.trys.push([2,, 4, 5]);
3593
+ _a.label = 3;
3594
+ case 3:
3595
+ _a.trys.push([3,, 5, 6]);
3588
3596
  return [4 /*yield*/, Promise.all(dependencies.map(function (d) {
3589
3597
  return preloadDependency(d.url, d.hash);
3590
3598
  }))];
3591
- case 3:
3592
- _a.sent();
3593
- return [3 /*break*/, 5];
3594
3599
  case 4:
3600
+ _a.sent();
3601
+ return [3 /*break*/, 6];
3602
+ case 5:
3595
3603
  document.removeEventListener('idmission.preloadProgress', handleModelDownloadProgress);
3596
3604
  modelsPreloading[model] = false;
3597
3605
  return [7 /*endfinally*/];
3598
- case 5:
3606
+ case 6:
3599
3607
  return [2 /*return*/];
3600
3608
  }
3601
3609
  });
@@ -17215,7 +17223,7 @@ var SelfieCapture = function SelfieCapture(_a) {
17215
17223
  top: top - 2
17216
17224
  }
17217
17225
  });
17218
- })))), debugMode && (/*#__PURE__*/React__namespace.default.createElement(DebugStatsPane, null, camera ? (/*#__PURE__*/React__namespace.default.createElement(React__namespace.default.Fragment, null, "\u2705 Camera: ", camera.label, " (", camera.width, "x", camera.height, ")")) : '❌ Camera not ready', /*#__PURE__*/React__namespace.default.createElement("br", null), modelCapabilities.delegate !== 'NONE' ? '✅' : '❌', " Delegate:", ' ', modelCapabilities.delegate, /*#__PURE__*/React__namespace.default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceNotDetected) ? '✅' : '❌', " Face Detected", /*#__PURE__*/React__namespace.default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceNotCentered) ? '✅' : '❌', " Face Centered", /*#__PURE__*/React__namespace.default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceTooClose) && !(prediction === null || prediction === void 0 ? void 0 : prediction.faceTooFar) ? '✅' : '❌', ' ', "Face", ' ', (prediction === null || prediction === void 0 ? void 0 : prediction.faceTooClose) ? 'Too Close' : (prediction === null || prediction === void 0 ? void 0 : prediction.faceTooFar) ? 'Too Far' : 'Distance Correct', /*#__PURE__*/React__namespace.default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceLookingAway) ? '✅' : '❌', " Face Looking Forward", /*#__PURE__*/React__namespace.default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceIsStable) ? '✅' : '❌', " Face Is Stable", /*#__PURE__*/React__namespace.default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.noseIsStable) ? '✅' : '❌', " Nose Is Stable", /*#__PURE__*/React__namespace.default.createElement("br", null), !timedOut ? '✅' : '❌', " Time Remaining:", ' ', Math.max(0, timeoutDurationMs - (new Date().getTime() - (timeoutStartedAt !== null && timeoutStartedAt !== void 0 ? timeoutStartedAt : new Date()).getTime())), "ms", /*#__PURE__*/React__namespace.default.createElement("br", null), (prediction === null || prediction === void 0 ? void 0 : prediction.faceVisibilityTooLow) ? '❌' : '✅', " Visibility", minCaptureBrightnessThreshold !== undefined && (/*#__PURE__*/React__namespace.default.createElement(React__namespace.default.Fragment, null, /*#__PURE__*/React__namespace.default.createElement("br", null), "\xA0\xA0Brightness:", ' ', (_e = (_d = prediction === null || prediction === void 0 ? void 0 : prediction.brightness) === null || _d === void 0 ? void 0 : _d.toFixed(1)) !== null && _e !== void 0 ? _e : '—', " (min:", ' ', minCaptureBrightnessThreshold, ")")), minCaptureRangeThreshold !== undefined && (/*#__PURE__*/React__namespace.default.createElement(React__namespace.default.Fragment, null, /*#__PURE__*/React__namespace.default.createElement("br", null), "\xA0\xA0Range: ", (_g = (_f = prediction === null || prediction === void 0 ? void 0 : prediction.range) === null || _f === void 0 ? void 0 : _f.toFixed(1)) !== null && _g !== void 0 ? _g : '—', " (min: ", minCaptureRangeThreshold, ")")), minCaptureVarianceThreshold !== undefined && (/*#__PURE__*/React__namespace.default.createElement(React__namespace.default.Fragment, null, /*#__PURE__*/React__namespace.default.createElement("br", null), "\xA0\xA0Variance: ", (_j = (_h = prediction === null || prediction === void 0 ? void 0 : prediction.variance) === null || _h === void 0 ? void 0 : _h.toFixed(1)) !== null && _j !== void 0 ? _j : '—', ' ', "(min: ", minCaptureVarianceThreshold, ")")))), allowManualCapture && (/*#__PURE__*/React__namespace.default.createElement(CaptureButtonContainer$1, {
17226
+ })))), debugMode && (/*#__PURE__*/React__namespace.default.createElement(DebugStatsPane, null, camera ? (/*#__PURE__*/React__namespace.default.createElement(React__namespace.default.Fragment, null, "\u2705 Camera: ", camera.label, " (", camera.width, "x", camera.height, ")")) : '❌ Camera not ready', /*#__PURE__*/React__namespace.default.createElement("br", null), getDelegate('mediapipe') !== 'NONE' ? '✅' : '❌', " Delegate:", ' ', getDelegate('mediapipe'), /*#__PURE__*/React__namespace.default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceNotDetected) ? '✅' : '❌', " Face Detected", /*#__PURE__*/React__namespace.default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceNotCentered) ? '✅' : '❌', " Face Centered", /*#__PURE__*/React__namespace.default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceTooClose) && !(prediction === null || prediction === void 0 ? void 0 : prediction.faceTooFar) ? '✅' : '❌', ' ', "Face", ' ', (prediction === null || prediction === void 0 ? void 0 : prediction.faceTooClose) ? 'Too Close' : (prediction === null || prediction === void 0 ? void 0 : prediction.faceTooFar) ? 'Too Far' : 'Distance Correct', /*#__PURE__*/React__namespace.default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceLookingAway) ? '✅' : '❌', " Face Looking Forward", /*#__PURE__*/React__namespace.default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceIsStable) ? '✅' : '❌', " Face Is Stable", /*#__PURE__*/React__namespace.default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.noseIsStable) ? '✅' : '❌', " Nose Is Stable", /*#__PURE__*/React__namespace.default.createElement("br", null), !timedOut ? '✅' : '❌', " Time Remaining:", ' ', Math.max(0, timeoutDurationMs - (new Date().getTime() - (timeoutStartedAt !== null && timeoutStartedAt !== void 0 ? timeoutStartedAt : new Date()).getTime())), "ms", /*#__PURE__*/React__namespace.default.createElement("br", null), (prediction === null || prediction === void 0 ? void 0 : prediction.faceVisibilityTooLow) ? '❌' : '✅', " Visibility", minCaptureBrightnessThreshold !== undefined && (/*#__PURE__*/React__namespace.default.createElement(React__namespace.default.Fragment, null, /*#__PURE__*/React__namespace.default.createElement("br", null), "\xA0\xA0Brightness:", ' ', (_e = (_d = prediction === null || prediction === void 0 ? void 0 : prediction.brightness) === null || _d === void 0 ? void 0 : _d.toFixed(1)) !== null && _e !== void 0 ? _e : '—', " (min:", ' ', minCaptureBrightnessThreshold, ")")), minCaptureRangeThreshold !== undefined && (/*#__PURE__*/React__namespace.default.createElement(React__namespace.default.Fragment, null, /*#__PURE__*/React__namespace.default.createElement("br", null), "\xA0\xA0Range: ", (_g = (_f = prediction === null || prediction === void 0 ? void 0 : prediction.range) === null || _f === void 0 ? void 0 : _f.toFixed(1)) !== null && _g !== void 0 ? _g : '—', " (min: ", minCaptureRangeThreshold, ")")), minCaptureVarianceThreshold !== undefined && (/*#__PURE__*/React__namespace.default.createElement(React__namespace.default.Fragment, null, /*#__PURE__*/React__namespace.default.createElement("br", null), "\xA0\xA0Variance: ", (_j = (_h = prediction === null || prediction === void 0 ? void 0 : prediction.variance) === null || _h === void 0 ? void 0 : _h.toFixed(1)) !== null && _j !== void 0 ? _j : '—', ' ', "(min: ", minCaptureVarianceThreshold, ")")))), allowManualCapture && (/*#__PURE__*/React__namespace.default.createElement(CaptureButtonContainer$1, {
17219
17227
  className: classNames.manualCaptureBtnContainer
17220
17228
  }, /*#__PURE__*/React__namespace.default.createElement(CaptureButton$1, {
17221
17229
  className: classNames.manualCaptureBtn,
@@ -25536,6 +25544,99 @@ globalThis.IDmissionSDK = {
25536
25544
  setServerUrl: setServerUrl
25537
25545
  };
25538
25546
 
25547
+ var visionTasksBasePath = "https://websdk-cdn-dev.idmission.com/assets/vision_wasm_internal_0.10.7";
25548
+ var visionRuntimeHash = 'tdLjRcm8XLETT+lUxF1oNst5jULaTGDUc2YtazwbGnLVGD0D/4A274KuJF+adneW';
25549
+ var wasmStderrPatterns = ['TensorFlow Lite', 'static-sized tensors', 'Attempting to use a delegate'];
25550
+ function isWasmStderr(msg) {
25551
+ return wasmStderrPatterns.some(function (p) {
25552
+ return msg.includes(p);
25553
+ });
25554
+ }
25555
+ var quietWasmRefCount = 0;
25556
+ var savedNativeError = null;
25557
+ /**
25558
+ * Wraps an async operation that initializes WASM/TFLite models, temporarily
25559
+ * intercepting console.error to downgrade known-benign TF Lite stderr messages
25560
+ * (routed through Emscripten's fd_write -> console.error) to debug level.
25561
+ *
25562
+ * Uses a reference count so overlapping calls share a single patched handler
25563
+ * and only restore the original console.error when the last one completes.
25564
+ */
25565
+ function withQuietWasm(fn) {
25566
+ return __awaiter(this, void 0, void 0, function () {
25567
+ return __generator(this, function (_a) {
25568
+ if (quietWasmRefCount++ === 0) {
25569
+ savedNativeError = console.error; // eslint-disable-line no-console
25570
+ console.error = function () {
25571
+ var args = [];
25572
+ for (var _i = 0; _i < arguments.length; _i++) {
25573
+ args[_i] = arguments[_i];
25574
+ }
25575
+ if (isWasmStderr(String(args[0]))) {
25576
+ debug.apply(void 0, args);
25577
+ return;
25578
+ }
25579
+ savedNativeError.apply(void 0, args);
25580
+ };
25581
+ }
25582
+ return [2 /*return*/, fn()["finally"](function () {
25583
+ if (--quietWasmRefCount === 0) {
25584
+ console.error = savedNativeError; // eslint-disable-line no-console
25585
+ savedNativeError = null;
25586
+ }
25587
+ })];
25588
+ });
25589
+ });
25590
+ }
25591
+ var visionRuntimePreloading = false;
25592
+ function preloadVisionRuntime() {
25593
+ return __awaiter(this, void 0, void 0, function () {
25594
+ function handleDownloadProgress(event) {
25595
+ var detail = event.detail;
25596
+ if (detail.url !== url) return;
25597
+ progressByUseCase.visionRuntime = sumUpProgressForDependencies([url]);
25598
+ document.dispatchEvent(new CustomEvent('idmission.preloadProgress.visionRuntime', {
25599
+ detail: progressByUseCase.visionRuntime
25600
+ }));
25601
+ }
25602
+ var url;
25603
+ return __generator(this, function (_a) {
25604
+ switch (_a.label) {
25605
+ case 0:
25606
+ if (visionRuntimePreloading) return [2 /*return*/, new Promise(function (resolve) {
25607
+ setInterval(function () {
25608
+ if (!visionRuntimePreloading) resolve();
25609
+ }, 100);
25610
+ })];
25611
+ visionRuntimePreloading = true;
25612
+ url = "".concat(visionTasksBasePath, "/vision_wasm_internal.wasm");
25613
+ document.addEventListener('idmission.preloadProgress', handleDownloadProgress);
25614
+ _a.label = 1;
25615
+ case 1:
25616
+ _a.trys.push([1,, 3, 4]);
25617
+ return [4 /*yield*/, preloadDependency(url, visionRuntimeHash)];
25618
+ case 2:
25619
+ _a.sent();
25620
+ return [3 /*break*/, 4];
25621
+ case 3:
25622
+ document.removeEventListener('idmission.preloadProgress', handleDownloadProgress);
25623
+ visionRuntimePreloading = false;
25624
+ return [7 /*endfinally*/];
25625
+ case 4:
25626
+ return [2 /*return*/];
25627
+ }
25628
+ });
25629
+ });
25630
+ }
25631
+
25632
+ var VisionRuntime = /*#__PURE__*/Object.freeze({
25633
+ __proto__: null,
25634
+ preloadVisionRuntime: preloadVisionRuntime,
25635
+ visionRuntimeHash: visionRuntimeHash,
25636
+ visionTasksBasePath: visionTasksBasePath,
25637
+ withQuietWasm: withQuietWasm
25638
+ });
25639
+
25539
25640
  // Verify a given delegate (GPU or CPU) can actually run a TFLite model in this
25540
25641
  // browser. Creates an ImageSegmenter, runs it once against an empty canvas,
25541
25642
  // and lets any thrown error propagate up so the caller can fall back. We
@@ -25584,11 +25685,12 @@ var CapabilityProbe = /*#__PURE__*/Object.freeze({
25584
25685
  verifyMediaPipeDelegate: verifyMediaPipeDelegate
25585
25686
  });
25586
25687
 
25688
+ var RUNTIME$3 = 'mediapipe';
25587
25689
  var detector = null;
25588
25690
  var detectorSettings = null;
25589
25691
  function load$3(_a) {
25590
25692
  return __awaiter(this, arguments, void 0, function (_b) {
25591
- var cachedBuffer, delegate;
25693
+ var delegate, cachedBuffer;
25592
25694
  var _this = this;
25593
25695
  var modelAssetPath = _b.modelAssetPath,
25594
25696
  scoreThreshold = _b.scoreThreshold;
@@ -25597,11 +25699,11 @@ function load$3(_a) {
25597
25699
  case 0:
25598
25700
  if (detector && (detectorSettings === null || detectorSettings === void 0 ? void 0 : detectorSettings.modelAssetPath) === modelAssetPath && (detectorSettings === null || detectorSettings === void 0 ? void 0 : detectorSettings.scoreThreshold) === scoreThreshold) return [2 /*return*/];
25599
25701
  close$3();
25600
- if (modelCapabilities.delegate === 'NONE') {
25702
+ delegate = getDelegate(RUNTIME$3);
25703
+ if (delegate === 'NONE') {
25601
25704
  throw new Error('No available delegate for document detector.');
25602
25705
  }
25603
25706
  cachedBuffer = getCachedModelBuffer(modelAssetPath);
25604
- delegate = modelCapabilities.delegate;
25605
25707
  return [4 /*yield*/, withQuietWasm(function () {
25606
25708
  return __awaiter(_this, void 0, void 0, function () {
25607
25709
  var _a, _b;
@@ -25710,11 +25812,12 @@ var DocumentDetection = /*#__PURE__*/Object.freeze({
25710
25812
  testAgainstKnownImage: testAgainstKnownImage
25711
25813
  });
25712
25814
 
25815
+ var RUNTIME$2 = 'mediapipe';
25713
25816
  var classifier$1 = null;
25714
25817
  var classifierSettings$1 = null;
25715
25818
  function load$2(_a) {
25716
25819
  return __awaiter(this, arguments, void 0, function (_b) {
25717
- var cachedBuffer, delegate;
25820
+ var delegate, cachedBuffer;
25718
25821
  var _this = this;
25719
25822
  var modelAssetPath = _b.modelAssetPath;
25720
25823
  return __generator(this, function (_c) {
@@ -25722,11 +25825,11 @@ function load$2(_a) {
25722
25825
  case 0:
25723
25826
  if (classifier$1 && (classifierSettings$1 === null || classifierSettings$1 === void 0 ? void 0 : classifierSettings$1.modelAssetPath) === modelAssetPath) return [2 /*return*/];
25724
25827
  close$2();
25725
- if (modelCapabilities.delegate === 'NONE') {
25828
+ delegate = getDelegate(RUNTIME$2);
25829
+ if (delegate === 'NONE') {
25726
25830
  throw new Error('No available delegate for focus detector.');
25727
25831
  }
25728
25832
  cachedBuffer = getCachedModelBuffer(modelAssetPath);
25729
- delegate = modelCapabilities.delegate;
25730
25833
  return [4 /*yield*/, withQuietWasm(function () {
25731
25834
  return __awaiter(_this, void 0, void 0, function () {
25732
25835
  var _a, _b;
@@ -25793,6 +25896,7 @@ var Focus = /*#__PURE__*/Object.freeze({
25793
25896
  predict: predict$2
25794
25897
  });
25795
25898
 
25899
+ var RUNTIME$1 = 'mediapipe';
25796
25900
  var classifier = null;
25797
25901
  var classifierSettings = null;
25798
25902
  function load$1(_a) {
@@ -25805,7 +25909,7 @@ function load$1(_a) {
25805
25909
  case 0:
25806
25910
  if (classifier && (classifierSettings === null || classifierSettings === void 0 ? void 0 : classifierSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/];
25807
25911
  close$1();
25808
- if (modelCapabilities.delegate === 'NONE') {
25912
+ if (getDelegate(RUNTIME$1) === 'NONE') {
25809
25913
  throw new Error('No available delegate for barcode readability model.');
25810
25914
  }
25811
25915
  cachedBuffer = getCachedModelBuffer(modelAssetPath);
@@ -25877,6 +25981,7 @@ var BarcodeReadability = /*#__PURE__*/Object.freeze({
25877
25981
  predict: predict$1
25878
25982
  });
25879
25983
 
25984
+ var RUNTIME = 'mediapipe';
25880
25985
  // MediaPipe canonical face mesh (468-point) indices used to construct the
25881
25986
  // BlazeFace-style 6-keypoint Face shape. Order matches FaceDetection.ts:
25882
25987
  // [0] right eye [1] left eye [2] nose tip
@@ -25945,29 +26050,30 @@ function load(_a) {
25945
26050
  });
25946
26051
  });
25947
26052
  }
25948
- var cachedBuffer, firstError_1;
26053
+ var initialDelegate, cachedBuffer, firstError_1;
25949
26054
  var modelAssetPath = _b.modelAssetPath;
25950
26055
  return __generator(this, function (_c) {
25951
26056
  switch (_c.label) {
25952
26057
  case 0:
25953
26058
  if (landmarker && (landmarkerSettings === null || landmarkerSettings === void 0 ? void 0 : landmarkerSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/];
25954
26059
  close();
25955
- if (modelCapabilities.delegate === 'NONE') {
26060
+ initialDelegate = getDelegate(RUNTIME);
26061
+ if (initialDelegate === 'NONE') {
25956
26062
  throw new Error('No available delegate for face landmarker.');
25957
26063
  }
25958
26064
  cachedBuffer = getCachedModelBuffer(modelAssetPath);
25959
26065
  _c.label = 1;
25960
26066
  case 1:
25961
26067
  _c.trys.push([1, 3,, 7]);
25962
- return [4 /*yield*/, tryDelegate(modelCapabilities.delegate)];
26068
+ return [4 /*yield*/, tryDelegate(initialDelegate)];
25963
26069
  case 2:
25964
26070
  landmarker = _c.sent();
25965
26071
  return [3 /*break*/, 7];
25966
26072
  case 3:
25967
26073
  firstError_1 = _c.sent();
25968
- if (!(modelCapabilities.delegate === 'GPU')) return [3 /*break*/, 5];
26074
+ if (!(initialDelegate === 'GPU')) return [3 /*break*/, 5];
25969
26075
  warn('face landmarker failed known-good frame validation on GPU; falling back to CPU', firstError_1);
25970
- modelCapabilities.delegate = 'CPU';
26076
+ setDelegate(RUNTIME, 'CPU');
25971
26077
  return [4 /*yield*/, tryDelegate('CPU')];
25972
26078
  case 4:
25973
26079
  landmarker = _c.sent();