smartcomply-web-sdk 1.0.21 → 1.0.23

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.
@@ -4370,20 +4370,27 @@ var SmartComplySDK = (() => {
4370
4370
  // src/camera/FaceDetector.ts
4371
4371
  var WASM_CDN = "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm";
4372
4372
  var MODEL_URL = "https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/latest/face_landmarker.task";
4373
+ var _cachedVision = null;
4374
+ var _cachedModelBuffer = null;
4373
4375
  var FaceDetectorEngine = class {
4374
4376
  constructor() {
4375
4377
  this.landmarker = null;
4376
4378
  }
4377
4379
  async init() {
4378
- const vision = await na.forVisionTasks(WASM_CDN);
4379
- const modelResponse = await fetch(MODEL_URL);
4380
- if (!modelResponse.ok) {
4381
- throw new Error(`Failed to download face model (${modelResponse.status})`);
4380
+ if (!_cachedVision) {
4381
+ _cachedVision = await na.forVisionTasks(WASM_CDN);
4382
4382
  }
4383
- const modelBuffer = await modelResponse.arrayBuffer();
4384
- this.landmarker = await Ic.createFromOptions(vision, {
4383
+ if (!_cachedModelBuffer) {
4384
+ const res = await fetch(MODEL_URL);
4385
+ if (!res.ok) {
4386
+ throw new Error(`Failed to download face model (${res.status})`);
4387
+ }
4388
+ _cachedModelBuffer = await res.arrayBuffer();
4389
+ }
4390
+ this.landmarker = await Ic.createFromOptions(_cachedVision, {
4385
4391
  baseOptions: {
4386
- modelAssetBuffer: new Uint8Array(modelBuffer)
4392
+ // Pass a copy — MediaPipe takes ownership of the buffer
4393
+ modelAssetBuffer: new Uint8Array(_cachedModelBuffer.slice(0))
4387
4394
  },
4388
4395
  runningMode: "VIDEO",
4389
4396
  outputFaceBlendshapes: true,
@@ -4395,10 +4402,12 @@ var SmartComplySDK = (() => {
4395
4402
  if (!this.landmarker) {
4396
4403
  return { faceDetected: false, blendshapes: /* @__PURE__ */ new Map(), transformMatrix: null };
4397
4404
  }
4398
- const result = this.landmarker.detectForVideo(
4399
- video,
4400
- timestamp
4401
- );
4405
+ let result;
4406
+ try {
4407
+ result = this.landmarker.detectForVideo(video, timestamp);
4408
+ } catch {
4409
+ return { faceDetected: false, blendshapes: /* @__PURE__ */ new Map(), transformMatrix: null };
4410
+ }
4402
4411
  if (!result.faceBlendshapes || result.faceBlendshapes.length === 0) {
4403
4412
  return { faceDetected: false, blendshapes: /* @__PURE__ */ new Map(), transformMatrix: null };
4404
4413
  }
@@ -4419,13 +4428,13 @@ var SmartComplySDK = (() => {
4419
4428
 
4420
4429
  // src/camera/ActionDetector.ts
4421
4430
  var ACTION_CONFIGS = {
4422
- BLINK: { threshold: 0.3, holdFrames: 2 },
4423
- TURN_LEFT: { threshold: 0.45, holdFrames: 6 },
4424
- TURN_RIGHT: { threshold: 0.45, holdFrames: 6 },
4425
- TURN_HEAD: { threshold: 0.45, holdFrames: 6 },
4426
- OPEN_MOUTH: { threshold: 0.4, holdFrames: 3 }
4431
+ BLINK: { threshold: 0.28, holdFrames: 2 },
4432
+ TURN_LEFT: { threshold: 0.35, holdFrames: 5 },
4433
+ TURN_RIGHT: { threshold: 0.35, holdFrames: 5 },
4434
+ TURN_HEAD: { threshold: 0.35, holdFrames: 5 },
4435
+ OPEN_MOUTH: { threshold: 0.35, holdFrames: 3 }
4427
4436
  };
4428
- var DEFAULT_CONFIG = { threshold: 0.55, holdFrames: 8 };
4437
+ var DEFAULT_CONFIG = { threshold: 0.45, holdFrames: 6 };
4429
4438
  var ActionDetector = class {
4430
4439
  constructor(requiredActions) {
4431
4440
  this.requiredActions = requiredActions;
@@ -4478,15 +4487,15 @@ var SmartComplySDK = (() => {
4478
4487
  }
4479
4488
  case "TURN_LEFT": {
4480
4489
  const yaw = this.getHeadYaw(matrix);
4481
- return yaw > 12 ? Math.min(1, yaw / 30) : 0;
4490
+ return yaw > 8 ? Math.min(1, yaw / 25) : 0;
4482
4491
  }
4483
4492
  case "TURN_RIGHT": {
4484
4493
  const yaw = this.getHeadYaw(matrix);
4485
- return yaw < -12 ? Math.min(1, Math.abs(yaw) / 30) : 0;
4494
+ return yaw < -8 ? Math.min(1, Math.abs(yaw) / 25) : 0;
4486
4495
  }
4487
4496
  case "TURN_HEAD": {
4488
4497
  const yaw = Math.abs(this.getHeadYaw(matrix));
4489
- return yaw > 15 ? Math.min(1, yaw / 30) : 0;
4498
+ return yaw > 10 ? Math.min(1, yaw / 25) : 0;
4490
4499
  }
4491
4500
  case "OPEN_MOUTH":
4492
4501
  return bs2.get("jawOpen") || 0;
@@ -5247,33 +5256,40 @@ var SmartComplySDK = (() => {
5247
5256
  await new Promise((resolve) => {
5248
5257
  let attempts = 0;
5249
5258
  let stableFrames = 0;
5250
- const STABLE_REQUIRED = 5;
5251
- const maxAttempts = 120;
5259
+ let missedFrames = 0;
5260
+ const STABLE_REQUIRED = 3;
5261
+ const MISS_TOLERANCE = 2;
5262
+ const MAX_WAIT_MS = 12e3;
5263
+ const startTime = performance.now();
5252
5264
  const checkFace = () => {
5253
- attempts++;
5265
+ if (performance.now() - startTime >= MAX_WAIT_MS) {
5266
+ resolve();
5267
+ return;
5268
+ }
5254
5269
  if (videoForDetection.readyState >= 2) {
5255
5270
  const detection = faceEngine.detect(videoForDetection, performance.now());
5256
5271
  if (detection.faceDetected) {
5257
5272
  stableFrames++;
5273
+ missedFrames = 0;
5274
+ ui2.updateInstruction("Centre your face in the oval");
5258
5275
  if (stableFrames >= STABLE_REQUIRED) {
5259
5276
  resolve();
5260
5277
  return;
5261
5278
  }
5262
5279
  } else {
5263
- stableFrames = 0;
5264
- ui2.updateInstruction("Move your face into the oval");
5280
+ missedFrames++;
5281
+ if (missedFrames > MISS_TOLERANCE) {
5282
+ stableFrames = 0;
5283
+ ui2.updateInstruction("Move your face into the oval");
5284
+ }
5265
5285
  }
5266
5286
  }
5267
- if (attempts >= maxAttempts) {
5268
- resolve();
5269
- return;
5270
- }
5271
- setTimeout(checkFace, 100);
5287
+ requestAnimationFrame(checkFace);
5272
5288
  };
5273
- checkFace();
5289
+ requestAnimationFrame(checkFace);
5274
5290
  });
5275
- ui2.updateInstruction("Hold still \u2014 capturing your selfie...");
5276
- await new Promise((r2) => setTimeout(r2, 700));
5291
+ ui2.updateInstruction("Hold still...");
5292
+ await new Promise((r2) => setTimeout(r2, 300));
5277
5293
  const autoshotBlob = await this.captureFrame(videoForDetection);
5278
5294
  tempVideo.pause();
5279
5295
  if (!autoshotBlob || autoshotBlob.size === 0) {