@moveris/shared 3.0.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -530,26 +530,26 @@ const status = getStatusMessage('capturing', DEFAULT_LOCALE);
530
530
 
531
531
  #### Feedback Keys
532
532
 
533
- | Key | English | Description |
534
- | ------------------- | ------------------------------ | ---------------------------- |
535
- | `no_face` | "No face detected" | Face detection failed |
536
- | `face_not_centered` | "Center your face in the oval" | Face outside guide |
537
- | `too_close` | "Move back a little" | Face too close to camera |
538
- | `too_far` | "Move closer" | Face too far from camera |
539
- | `poor_lighting` | "Improve lighting" | Insufficient light |
540
- | `hold_still` | "Hold still" | Movement detected |
541
- | `capturing` | "Capturing..." | Frame capture in progress |
542
- | `processing` | "Processing..." | API verification in progress |
543
- | `success` | "Verification complete" | Successful completion |
544
- | `failed` | "Verification failed" | Failed verification |
545
- | `eyes_not_visible` | "Eyes not clearly visible" | Eye region featureless |
546
- | `eyes_shadowed` | "Eyes are in shadow…" | Eye region too dark |
547
- | `eyes_overexposed` | "Eye region overexposed…" | Eye region too bright |
548
- | `glasses_glare` | "Glare detected…" | Specular highlights on eyes |
549
- | `eye_quality_poor` | "Eye region quality is poor" | Generic eye quality failure |
550
- | `camera_angle_low` | "Raise camera to eye level" | Camera below face (Y < 0.3) |
551
- | `camera_angle_high` | "Lower camera to eye level" | Camera above face (Y > 0.7) |
552
- | `camera_tilted` | "Hold camera level" | Eye line deviates > 15° |
533
+ | Key | English | Description |
534
+ | ------------------- | ------------------------------ | --------------------------------------------------------------------------------- |
535
+ | `no_face` | "No face detected" | Face detection failed |
536
+ | `face_not_centered` | "Center your face in the oval" | Face outside guide |
537
+ | `too_close` | "Move back a little" | Face too close to camera |
538
+ | `too_far` | "Move closer" | Face too far from camera |
539
+ | `poor_lighting` | "Improve lighting" | Insufficient light |
540
+ | `hold_still` | "Hold still" | Movement detected |
541
+ | `capturing` | "Capturing..." | Frame capture in progress |
542
+ | `processing` | "Processing..." | API verification in progress |
543
+ | `success` | "Verification complete" | Successful completion |
544
+ | `failed` | "Verification failed" | Failed verification |
545
+ | `eyes_not_visible` | "Eyes not clearly visible" | Eye region featureless |
546
+ | `eyes_shadowed` | "Eyes are in shadow…" | Eye region too dark |
547
+ | `eyes_overexposed` | "Eye region overexposed…" | Eye region too bright |
548
+ | `glasses_glare` | "Glare detected…" | Specular highlights on eyes |
549
+ | `eye_quality_poor` | "Eye region quality is poor" | Generic eye quality failure |
550
+ | `camera_angle_low` | "Raise camera to eye level" | Camera below face (Y < 0.3) |
551
+ | `camera_angle_high` | "Lower camera to eye level" | Camera above face (Y > 0.7) |
552
+ | `camera_tilted` | "Hold camera level" | Device tilt > 15° (via transformation matrix, falls back to eye-corner landmarks) |
553
553
 
554
554
  ---
555
555
 
@@ -641,6 +641,7 @@ import {
641
641
  isFaceInOval,
642
642
  calculateFaceCropRegion,
643
643
  detectFaceRoll,
644
+ detectFaceRollFromMatrix,
644
645
  detectCameraAngle,
645
646
  } from '@moveris/shared';
646
647
 
@@ -663,9 +664,14 @@ import { calculateAdaptiveCropMultiplier } from '@moveris/shared';
663
664
  const multiplier = calculateAdaptiveCropMultiplier(faceBox, frameWidth, frameHeight);
664
665
  // Returns 2.5–4.0x (matched to cognito-check for ~33% face coverage in 224×224 crop)
665
666
 
666
- // Detect face roll (device tilt) from eye-corner landmarks
667
- const rollResult = detectFaceRoll(landmarks); // requires ≥364 landmarks
668
- // { roll: number (degrees), tooTilted: boolean }
667
+ // Detect face roll (device tilt) prefer matrix when available (more accurate under glasses/occlusion)
668
+ if (facialTransformationMatrix) {
669
+ const rollResult = detectFaceRollFromMatrix(facialTransformationMatrix); // 16-element column-major 4×4
670
+ // { roll: number (degrees), tooTilted: boolean }
671
+ } else {
672
+ const rollResult = detectFaceRoll(landmarks); // fallback: eye-corner landmarks, requires ≥364 points
673
+ // { roll: number (degrees), tooTilted: boolean }
674
+ }
669
675
 
670
676
  // Detect camera vertical angle from forehead/nose/chin landmark ratio
671
677
  const angleResult = detectCameraAngle(landmarks); // requires ≥153 landmarks
package/dist/index.d.mts CHANGED
@@ -336,6 +336,7 @@ declare const FACE_CENTER_VERTICAL_OFFSET = 0.05;
336
336
  declare const MIN_IDEAL_FACE_RATIO = 0.05;
337
337
  declare const MAX_IDEAL_FACE_RATIO = 0.2;
338
338
  declare const MIN_FACE_RATIO = 0.036;
339
+ declare const MIN_FACE_AREA_RATIO = 0.04;
339
340
  declare const MAX_FACE_RATIO = 0.7;
340
341
  declare const FACE_CROP_OUTPUT_SIZE = 224;
341
342
  declare const MAX_FACE_PERCENTAGE_IN_CROP = 0.45;
@@ -371,6 +372,7 @@ interface FaceRollResult {
371
372
  }
372
373
  declare const MAX_FACE_ROLL_DEGREES = 15;
373
374
  declare function detectFaceRoll(landmarks: FaceLandmarkPoint[]): FaceRollResult;
375
+ declare function detectFaceRollFromMatrix(matrix: number[]): FaceRollResult;
374
376
  interface CameraAngleResult {
375
377
  ratio: number;
376
378
  cameraAbove: boolean;
@@ -786,6 +788,7 @@ interface CaptureQualityState {
786
788
  cameraAngleLow?: boolean;
787
789
  cameraAngleHigh?: boolean;
788
790
  cameraTilted?: boolean;
791
+ faceAreaLow?: boolean;
789
792
  }
790
793
  declare function getCaptureQualityFeedback(state: CaptureQualityState): string;
791
794
  declare function canCaptureFrame(state: Omit<CaptureQualityState, 'framesCaptured' | 'targetFrames' | 'isCapturing'>): boolean;
@@ -836,4 +839,4 @@ declare function analyzeEyeRegionContrast(pixels: Uint8Array | Uint8ClampedArray
836
839
  declare function detectSpecularHighlights(pixels: Uint8Array | Uint8ClampedArray, relativeFactor?: number, meanBrightness?: number): number;
837
840
  declare function checkEyeRegionQuality(pixels: Uint8Array | Uint8ClampedArray, thresholds?: EyeQualityThresholds): EyeRegionQuality;
838
841
 
839
- export { ALIGNMENT_THRESHOLD_CAPTURE, ALIGNMENT_THRESHOLD_GOOD, ALIGNMENT_THRESHOLD_PERFECT, ALIGNMENT_THRESHOLD_POOR, API_ENDPOINTS, API_ERROR_CODES, API_PATHS, AUTH_CONFIG, type ApiErrorCode, BACKLIT_RATIO_THRESHOLD, BLUR_THRESHOLD_MOBILE, BaseFrameCollector, type BlurAnalysis, CAMERA_ANGLE_HIGH_RATIO, CAMERA_ANGLE_LOW_RATIO, type CameraAngleResult, type CaptureQualityState, type CapturedFrame, type CropData, DEFAULT_BLUR_THRESHOLD, DEFAULT_ENDPOINT, DEFAULT_FACE_DETECTION_TIERS, DEFAULT_GAZE_THRESHOLDS, DEFAULT_HAND_OCCLUSION_CONFIG, DEFAULT_LIVENESS_CONFIG, DEFAULT_LOCALE, DEFAULT_OVAL_REGION, DEFAULT_STABILIZER_CONFIG, DEFAULT_STATUS_MESSAGES, type DeprecationInfo, type DetectionResult, type DetectionSummary, type DetectorConfig, ERROR_MESSAGES, ERROR_MESSAGES_ES, ES_LOCALE, EYE_LANDMARK_INDICES, EYE_QUALITY_THRESHOLDS, type ErrorResponse, type EyeQualityThresholds, type EyeRegionBounds, type EyeRegionQuality, type EyeRegionsBounds, FACE_CENTER_VERTICAL_OFFSET, FACE_CROP_OUTPUT_SIZE, FEEDBACK_MESSAGES, FRAME_BUFFER_CONFIG, FRAME_CONFIG, type FaceAlignmentResult, type FaceBoundingBox, type FaceDetectionTiers, type FaceInOvalResult, type FaceLandmarkPoint, type FaceRollResult, type FaceVisibilityResult, type FastCheckCropsRequest, type FastCheckModel, type FastCheckRequest, type FastCheckResponse, type FastCheckStreamRequest, type FastCheckStreamResponse, type FeedbackLocale, type FeedbackMessageKey, type Frame, FrameBuffer, type FrameData, type FrameQualityResult, FrameQueue, type FrameSource, GOOD_ALIGNMENT, type GazeThresholds, HIGH_ALIGNMENT, HYBRID_MODEL_CONFIGS, type HandOcclusionConfig, type HeadPose, type HealthResponse, type Hybrid150CheckRequest, type Hybrid50CheckRequest, type HybridCheckRequest, type HybridCheckResponse, type HybridFrameData, type HybridModelConfig, IDEAL_CROP_MULTIPLIER, type JobStatus, type JobStatusResponse, LANDMARK_INDEX, LANDMARK_MAX_BOUND, LANDMARK_MIN_BOUND, LOW_LIGHT_THRESHOLD, type LandmarkValidationResult, type LightingAnalysis, LivenessApiError, type LivenessCallbacks, LivenessClient, type LivenessClientConfig, type LivenessConfig, type LivenessResult, type LivenessState, MAX_CROP_MULTIPLIER, MAX_FACE_PERCENTAGE_IN_CROP, MAX_FACE_RATIO, MAX_FACE_ROLL_DEGREES, MAX_IDEAL_FACE_RATIO, MIN_CAPTURE_ALIGNMENT, MIN_CROP_MULTIPLIER, MIN_FACE_BOTTOM_MARGIN, MIN_FACE_RATIO, MIN_FACE_SIDE_MARGIN, MIN_FACE_TOP_MARGIN, MIN_IDEAL_FACE_RATIO, MIN_LANDMARK_COUNT, MODEL_CONFIGS, type ModelConfig, type ModelEntry, type ModelType, type ModelVersion, type ModelsResponse, OVAL_GUIDE_COLORS, OVAL_GUIDE_STYLES, OVAL_REGION_DESKTOP, OVAL_REGION_MOBILE, type OnErrorCallback, type OnFrameCapturedCallback, type OnProgressCallback, type OnResultCallback, type OnStateChangeCallback, type OvalGuideState, type OvalRegion, type QueueStatsResponse, RETRY_CONFIG, type RetryOptions, type StabilizationProgress, type StabilizationResult, type StabilizerConfig, type StatusMessageKey, type StreamingStatus, TARGET_FACE_PERCENTAGE_IN_CROP, VALID_FRAME_COUNTS, type Verdict, type VerifyRequest, type VerifyResponse, type VideoFrameMetadata, analyzeBlur, analyzeEyeRegionBrightness, analyzeEyeRegionContrast, analyzeLighting, calculateAdaptiveCropMultiplier, calculateBrightness, calculateFaceAlignment, calculateFaceCropRegion, canCaptureFrame, checkEyeRegionQuality, checkFrameQuality, decodeBase64, detectCameraAngle, detectFaceRoll, detectSpecularHighlights, encodeBase64, generateSessionId, getActiveModels, getApiErrorMessage, getCaptureQualityFeedback, getEyeRegionBounds, getFeedbackMessage, getMinFramesForModel, getOvalGuideState, getStatusMessage, hasEnoughFrames, isDeprecatedModel, isFaceCropFullyInFrame, isFaceFullyVisible, isFaceInOval, isRetryableError, retryWithBackoff, rgbaToGrayscale, sleep, toFrameData, toHybridFrameData, toLivenessResult, toLivenessResultFromStream, validateApiKey, validateFaceLandmarks, validateFrameCount, validateFrameData, validateFrameIndex, validateTimestamp, validateUUID, validateUrl };
842
+ export { ALIGNMENT_THRESHOLD_CAPTURE, ALIGNMENT_THRESHOLD_GOOD, ALIGNMENT_THRESHOLD_PERFECT, ALIGNMENT_THRESHOLD_POOR, API_ENDPOINTS, API_ERROR_CODES, API_PATHS, AUTH_CONFIG, type ApiErrorCode, BACKLIT_RATIO_THRESHOLD, BLUR_THRESHOLD_MOBILE, BaseFrameCollector, type BlurAnalysis, CAMERA_ANGLE_HIGH_RATIO, CAMERA_ANGLE_LOW_RATIO, type CameraAngleResult, type CaptureQualityState, type CapturedFrame, type CropData, DEFAULT_BLUR_THRESHOLD, DEFAULT_ENDPOINT, DEFAULT_FACE_DETECTION_TIERS, DEFAULT_GAZE_THRESHOLDS, DEFAULT_HAND_OCCLUSION_CONFIG, DEFAULT_LIVENESS_CONFIG, DEFAULT_LOCALE, DEFAULT_OVAL_REGION, DEFAULT_STABILIZER_CONFIG, DEFAULT_STATUS_MESSAGES, type DeprecationInfo, type DetectionResult, type DetectionSummary, type DetectorConfig, ERROR_MESSAGES, ERROR_MESSAGES_ES, ES_LOCALE, EYE_LANDMARK_INDICES, EYE_QUALITY_THRESHOLDS, type ErrorResponse, type EyeQualityThresholds, type EyeRegionBounds, type EyeRegionQuality, type EyeRegionsBounds, FACE_CENTER_VERTICAL_OFFSET, FACE_CROP_OUTPUT_SIZE, FEEDBACK_MESSAGES, FRAME_BUFFER_CONFIG, FRAME_CONFIG, type FaceAlignmentResult, type FaceBoundingBox, type FaceDetectionTiers, type FaceInOvalResult, type FaceLandmarkPoint, type FaceRollResult, type FaceVisibilityResult, type FastCheckCropsRequest, type FastCheckModel, type FastCheckRequest, type FastCheckResponse, type FastCheckStreamRequest, type FastCheckStreamResponse, type FeedbackLocale, type FeedbackMessageKey, type Frame, FrameBuffer, type FrameData, type FrameQualityResult, FrameQueue, type FrameSource, GOOD_ALIGNMENT, type GazeThresholds, HIGH_ALIGNMENT, HYBRID_MODEL_CONFIGS, type HandOcclusionConfig, type HeadPose, type HealthResponse, type Hybrid150CheckRequest, type Hybrid50CheckRequest, type HybridCheckRequest, type HybridCheckResponse, type HybridFrameData, type HybridModelConfig, IDEAL_CROP_MULTIPLIER, type JobStatus, type JobStatusResponse, LANDMARK_INDEX, LANDMARK_MAX_BOUND, LANDMARK_MIN_BOUND, LOW_LIGHT_THRESHOLD, type LandmarkValidationResult, type LightingAnalysis, LivenessApiError, type LivenessCallbacks, LivenessClient, type LivenessClientConfig, type LivenessConfig, type LivenessResult, type LivenessState, MAX_CROP_MULTIPLIER, MAX_FACE_PERCENTAGE_IN_CROP, MAX_FACE_RATIO, MAX_FACE_ROLL_DEGREES, MAX_IDEAL_FACE_RATIO, MIN_CAPTURE_ALIGNMENT, MIN_CROP_MULTIPLIER, MIN_FACE_AREA_RATIO, MIN_FACE_BOTTOM_MARGIN, MIN_FACE_RATIO, MIN_FACE_SIDE_MARGIN, MIN_FACE_TOP_MARGIN, MIN_IDEAL_FACE_RATIO, MIN_LANDMARK_COUNT, MODEL_CONFIGS, type ModelConfig, type ModelEntry, type ModelType, type ModelVersion, type ModelsResponse, OVAL_GUIDE_COLORS, OVAL_GUIDE_STYLES, OVAL_REGION_DESKTOP, OVAL_REGION_MOBILE, type OnErrorCallback, type OnFrameCapturedCallback, type OnProgressCallback, type OnResultCallback, type OnStateChangeCallback, type OvalGuideState, type OvalRegion, type QueueStatsResponse, RETRY_CONFIG, type RetryOptions, type StabilizationProgress, type StabilizationResult, type StabilizerConfig, type StatusMessageKey, type StreamingStatus, TARGET_FACE_PERCENTAGE_IN_CROP, VALID_FRAME_COUNTS, type Verdict, type VerifyRequest, type VerifyResponse, type VideoFrameMetadata, analyzeBlur, analyzeEyeRegionBrightness, analyzeEyeRegionContrast, analyzeLighting, calculateAdaptiveCropMultiplier, calculateBrightness, calculateFaceAlignment, calculateFaceCropRegion, canCaptureFrame, checkEyeRegionQuality, checkFrameQuality, decodeBase64, detectCameraAngle, detectFaceRoll, detectFaceRollFromMatrix, detectSpecularHighlights, encodeBase64, generateSessionId, getActiveModels, getApiErrorMessage, getCaptureQualityFeedback, getEyeRegionBounds, getFeedbackMessage, getMinFramesForModel, getOvalGuideState, getStatusMessage, hasEnoughFrames, isDeprecatedModel, isFaceCropFullyInFrame, isFaceFullyVisible, isFaceInOval, isRetryableError, retryWithBackoff, rgbaToGrayscale, sleep, toFrameData, toHybridFrameData, toLivenessResult, toLivenessResultFromStream, validateApiKey, validateFaceLandmarks, validateFrameCount, validateFrameData, validateFrameIndex, validateTimestamp, validateUUID, validateUrl };
package/dist/index.d.ts CHANGED
@@ -336,6 +336,7 @@ declare const FACE_CENTER_VERTICAL_OFFSET = 0.05;
336
336
  declare const MIN_IDEAL_FACE_RATIO = 0.05;
337
337
  declare const MAX_IDEAL_FACE_RATIO = 0.2;
338
338
  declare const MIN_FACE_RATIO = 0.036;
339
+ declare const MIN_FACE_AREA_RATIO = 0.04;
339
340
  declare const MAX_FACE_RATIO = 0.7;
340
341
  declare const FACE_CROP_OUTPUT_SIZE = 224;
341
342
  declare const MAX_FACE_PERCENTAGE_IN_CROP = 0.45;
@@ -371,6 +372,7 @@ interface FaceRollResult {
371
372
  }
372
373
  declare const MAX_FACE_ROLL_DEGREES = 15;
373
374
  declare function detectFaceRoll(landmarks: FaceLandmarkPoint[]): FaceRollResult;
375
+ declare function detectFaceRollFromMatrix(matrix: number[]): FaceRollResult;
374
376
  interface CameraAngleResult {
375
377
  ratio: number;
376
378
  cameraAbove: boolean;
@@ -786,6 +788,7 @@ interface CaptureQualityState {
786
788
  cameraAngleLow?: boolean;
787
789
  cameraAngleHigh?: boolean;
788
790
  cameraTilted?: boolean;
791
+ faceAreaLow?: boolean;
789
792
  }
790
793
  declare function getCaptureQualityFeedback(state: CaptureQualityState): string;
791
794
  declare function canCaptureFrame(state: Omit<CaptureQualityState, 'framesCaptured' | 'targetFrames' | 'isCapturing'>): boolean;
@@ -836,4 +839,4 @@ declare function analyzeEyeRegionContrast(pixels: Uint8Array | Uint8ClampedArray
836
839
  declare function detectSpecularHighlights(pixels: Uint8Array | Uint8ClampedArray, relativeFactor?: number, meanBrightness?: number): number;
837
840
  declare function checkEyeRegionQuality(pixels: Uint8Array | Uint8ClampedArray, thresholds?: EyeQualityThresholds): EyeRegionQuality;
838
841
 
839
- export { ALIGNMENT_THRESHOLD_CAPTURE, ALIGNMENT_THRESHOLD_GOOD, ALIGNMENT_THRESHOLD_PERFECT, ALIGNMENT_THRESHOLD_POOR, API_ENDPOINTS, API_ERROR_CODES, API_PATHS, AUTH_CONFIG, type ApiErrorCode, BACKLIT_RATIO_THRESHOLD, BLUR_THRESHOLD_MOBILE, BaseFrameCollector, type BlurAnalysis, CAMERA_ANGLE_HIGH_RATIO, CAMERA_ANGLE_LOW_RATIO, type CameraAngleResult, type CaptureQualityState, type CapturedFrame, type CropData, DEFAULT_BLUR_THRESHOLD, DEFAULT_ENDPOINT, DEFAULT_FACE_DETECTION_TIERS, DEFAULT_GAZE_THRESHOLDS, DEFAULT_HAND_OCCLUSION_CONFIG, DEFAULT_LIVENESS_CONFIG, DEFAULT_LOCALE, DEFAULT_OVAL_REGION, DEFAULT_STABILIZER_CONFIG, DEFAULT_STATUS_MESSAGES, type DeprecationInfo, type DetectionResult, type DetectionSummary, type DetectorConfig, ERROR_MESSAGES, ERROR_MESSAGES_ES, ES_LOCALE, EYE_LANDMARK_INDICES, EYE_QUALITY_THRESHOLDS, type ErrorResponse, type EyeQualityThresholds, type EyeRegionBounds, type EyeRegionQuality, type EyeRegionsBounds, FACE_CENTER_VERTICAL_OFFSET, FACE_CROP_OUTPUT_SIZE, FEEDBACK_MESSAGES, FRAME_BUFFER_CONFIG, FRAME_CONFIG, type FaceAlignmentResult, type FaceBoundingBox, type FaceDetectionTiers, type FaceInOvalResult, type FaceLandmarkPoint, type FaceRollResult, type FaceVisibilityResult, type FastCheckCropsRequest, type FastCheckModel, type FastCheckRequest, type FastCheckResponse, type FastCheckStreamRequest, type FastCheckStreamResponse, type FeedbackLocale, type FeedbackMessageKey, type Frame, FrameBuffer, type FrameData, type FrameQualityResult, FrameQueue, type FrameSource, GOOD_ALIGNMENT, type GazeThresholds, HIGH_ALIGNMENT, HYBRID_MODEL_CONFIGS, type HandOcclusionConfig, type HeadPose, type HealthResponse, type Hybrid150CheckRequest, type Hybrid50CheckRequest, type HybridCheckRequest, type HybridCheckResponse, type HybridFrameData, type HybridModelConfig, IDEAL_CROP_MULTIPLIER, type JobStatus, type JobStatusResponse, LANDMARK_INDEX, LANDMARK_MAX_BOUND, LANDMARK_MIN_BOUND, LOW_LIGHT_THRESHOLD, type LandmarkValidationResult, type LightingAnalysis, LivenessApiError, type LivenessCallbacks, LivenessClient, type LivenessClientConfig, type LivenessConfig, type LivenessResult, type LivenessState, MAX_CROP_MULTIPLIER, MAX_FACE_PERCENTAGE_IN_CROP, MAX_FACE_RATIO, MAX_FACE_ROLL_DEGREES, MAX_IDEAL_FACE_RATIO, MIN_CAPTURE_ALIGNMENT, MIN_CROP_MULTIPLIER, MIN_FACE_BOTTOM_MARGIN, MIN_FACE_RATIO, MIN_FACE_SIDE_MARGIN, MIN_FACE_TOP_MARGIN, MIN_IDEAL_FACE_RATIO, MIN_LANDMARK_COUNT, MODEL_CONFIGS, type ModelConfig, type ModelEntry, type ModelType, type ModelVersion, type ModelsResponse, OVAL_GUIDE_COLORS, OVAL_GUIDE_STYLES, OVAL_REGION_DESKTOP, OVAL_REGION_MOBILE, type OnErrorCallback, type OnFrameCapturedCallback, type OnProgressCallback, type OnResultCallback, type OnStateChangeCallback, type OvalGuideState, type OvalRegion, type QueueStatsResponse, RETRY_CONFIG, type RetryOptions, type StabilizationProgress, type StabilizationResult, type StabilizerConfig, type StatusMessageKey, type StreamingStatus, TARGET_FACE_PERCENTAGE_IN_CROP, VALID_FRAME_COUNTS, type Verdict, type VerifyRequest, type VerifyResponse, type VideoFrameMetadata, analyzeBlur, analyzeEyeRegionBrightness, analyzeEyeRegionContrast, analyzeLighting, calculateAdaptiveCropMultiplier, calculateBrightness, calculateFaceAlignment, calculateFaceCropRegion, canCaptureFrame, checkEyeRegionQuality, checkFrameQuality, decodeBase64, detectCameraAngle, detectFaceRoll, detectSpecularHighlights, encodeBase64, generateSessionId, getActiveModels, getApiErrorMessage, getCaptureQualityFeedback, getEyeRegionBounds, getFeedbackMessage, getMinFramesForModel, getOvalGuideState, getStatusMessage, hasEnoughFrames, isDeprecatedModel, isFaceCropFullyInFrame, isFaceFullyVisible, isFaceInOval, isRetryableError, retryWithBackoff, rgbaToGrayscale, sleep, toFrameData, toHybridFrameData, toLivenessResult, toLivenessResultFromStream, validateApiKey, validateFaceLandmarks, validateFrameCount, validateFrameData, validateFrameIndex, validateTimestamp, validateUUID, validateUrl };
842
+ export { ALIGNMENT_THRESHOLD_CAPTURE, ALIGNMENT_THRESHOLD_GOOD, ALIGNMENT_THRESHOLD_PERFECT, ALIGNMENT_THRESHOLD_POOR, API_ENDPOINTS, API_ERROR_CODES, API_PATHS, AUTH_CONFIG, type ApiErrorCode, BACKLIT_RATIO_THRESHOLD, BLUR_THRESHOLD_MOBILE, BaseFrameCollector, type BlurAnalysis, CAMERA_ANGLE_HIGH_RATIO, CAMERA_ANGLE_LOW_RATIO, type CameraAngleResult, type CaptureQualityState, type CapturedFrame, type CropData, DEFAULT_BLUR_THRESHOLD, DEFAULT_ENDPOINT, DEFAULT_FACE_DETECTION_TIERS, DEFAULT_GAZE_THRESHOLDS, DEFAULT_HAND_OCCLUSION_CONFIG, DEFAULT_LIVENESS_CONFIG, DEFAULT_LOCALE, DEFAULT_OVAL_REGION, DEFAULT_STABILIZER_CONFIG, DEFAULT_STATUS_MESSAGES, type DeprecationInfo, type DetectionResult, type DetectionSummary, type DetectorConfig, ERROR_MESSAGES, ERROR_MESSAGES_ES, ES_LOCALE, EYE_LANDMARK_INDICES, EYE_QUALITY_THRESHOLDS, type ErrorResponse, type EyeQualityThresholds, type EyeRegionBounds, type EyeRegionQuality, type EyeRegionsBounds, FACE_CENTER_VERTICAL_OFFSET, FACE_CROP_OUTPUT_SIZE, FEEDBACK_MESSAGES, FRAME_BUFFER_CONFIG, FRAME_CONFIG, type FaceAlignmentResult, type FaceBoundingBox, type FaceDetectionTiers, type FaceInOvalResult, type FaceLandmarkPoint, type FaceRollResult, type FaceVisibilityResult, type FastCheckCropsRequest, type FastCheckModel, type FastCheckRequest, type FastCheckResponse, type FastCheckStreamRequest, type FastCheckStreamResponse, type FeedbackLocale, type FeedbackMessageKey, type Frame, FrameBuffer, type FrameData, type FrameQualityResult, FrameQueue, type FrameSource, GOOD_ALIGNMENT, type GazeThresholds, HIGH_ALIGNMENT, HYBRID_MODEL_CONFIGS, type HandOcclusionConfig, type HeadPose, type HealthResponse, type Hybrid150CheckRequest, type Hybrid50CheckRequest, type HybridCheckRequest, type HybridCheckResponse, type HybridFrameData, type HybridModelConfig, IDEAL_CROP_MULTIPLIER, type JobStatus, type JobStatusResponse, LANDMARK_INDEX, LANDMARK_MAX_BOUND, LANDMARK_MIN_BOUND, LOW_LIGHT_THRESHOLD, type LandmarkValidationResult, type LightingAnalysis, LivenessApiError, type LivenessCallbacks, LivenessClient, type LivenessClientConfig, type LivenessConfig, type LivenessResult, type LivenessState, MAX_CROP_MULTIPLIER, MAX_FACE_PERCENTAGE_IN_CROP, MAX_FACE_RATIO, MAX_FACE_ROLL_DEGREES, MAX_IDEAL_FACE_RATIO, MIN_CAPTURE_ALIGNMENT, MIN_CROP_MULTIPLIER, MIN_FACE_AREA_RATIO, MIN_FACE_BOTTOM_MARGIN, MIN_FACE_RATIO, MIN_FACE_SIDE_MARGIN, MIN_FACE_TOP_MARGIN, MIN_IDEAL_FACE_RATIO, MIN_LANDMARK_COUNT, MODEL_CONFIGS, type ModelConfig, type ModelEntry, type ModelType, type ModelVersion, type ModelsResponse, OVAL_GUIDE_COLORS, OVAL_GUIDE_STYLES, OVAL_REGION_DESKTOP, OVAL_REGION_MOBILE, type OnErrorCallback, type OnFrameCapturedCallback, type OnProgressCallback, type OnResultCallback, type OnStateChangeCallback, type OvalGuideState, type OvalRegion, type QueueStatsResponse, RETRY_CONFIG, type RetryOptions, type StabilizationProgress, type StabilizationResult, type StabilizerConfig, type StatusMessageKey, type StreamingStatus, TARGET_FACE_PERCENTAGE_IN_CROP, VALID_FRAME_COUNTS, type Verdict, type VerifyRequest, type VerifyResponse, type VideoFrameMetadata, analyzeBlur, analyzeEyeRegionBrightness, analyzeEyeRegionContrast, analyzeLighting, calculateAdaptiveCropMultiplier, calculateBrightness, calculateFaceAlignment, calculateFaceCropRegion, canCaptureFrame, checkEyeRegionQuality, checkFrameQuality, decodeBase64, detectCameraAngle, detectFaceRoll, detectFaceRollFromMatrix, detectSpecularHighlights, encodeBase64, generateSessionId, getActiveModels, getApiErrorMessage, getCaptureQualityFeedback, getEyeRegionBounds, getFeedbackMessage, getMinFramesForModel, getOvalGuideState, getStatusMessage, hasEnoughFrames, isDeprecatedModel, isFaceCropFullyInFrame, isFaceFullyVisible, isFaceInOval, isRetryableError, retryWithBackoff, rgbaToGrayscale, sleep, toFrameData, toHybridFrameData, toLivenessResult, toLivenessResultFromStream, validateApiKey, validateFaceLandmarks, validateFrameCount, validateFrameData, validateFrameIndex, validateTimestamp, validateUUID, validateUrl };
package/dist/index.js CHANGED
@@ -72,6 +72,7 @@ __export(index_exports, {
72
72
  MAX_IDEAL_FACE_RATIO: () => MAX_IDEAL_FACE_RATIO,
73
73
  MIN_CAPTURE_ALIGNMENT: () => MIN_CAPTURE_ALIGNMENT,
74
74
  MIN_CROP_MULTIPLIER: () => MIN_CROP_MULTIPLIER,
75
+ MIN_FACE_AREA_RATIO: () => MIN_FACE_AREA_RATIO,
75
76
  MIN_FACE_BOTTOM_MARGIN: () => MIN_FACE_BOTTOM_MARGIN,
76
77
  MIN_FACE_RATIO: () => MIN_FACE_RATIO,
77
78
  MIN_FACE_SIDE_MARGIN: () => MIN_FACE_SIDE_MARGIN,
@@ -100,6 +101,7 @@ __export(index_exports, {
100
101
  decodeBase64: () => decodeBase64,
101
102
  detectCameraAngle: () => detectCameraAngle,
102
103
  detectFaceRoll: () => detectFaceRoll,
104
+ detectFaceRollFromMatrix: () => detectFaceRollFromMatrix,
103
105
  detectSpecularHighlights: () => detectSpecularHighlights,
104
106
  encodeBase64: () => encodeBase64,
105
107
  generateSessionId: () => generateSessionId,
@@ -1479,7 +1481,8 @@ function getCaptureQualityFeedback(state) {
1479
1481
  tooCloseToIdeal,
1480
1482
  cameraAngleLow,
1481
1483
  cameraAngleHigh,
1482
- cameraTilted
1484
+ cameraTilted,
1485
+ faceAreaLow
1483
1486
  } = state;
1484
1487
  if (!hasFace) {
1485
1488
  return FEEDBACK_MESSAGES.no_face;
@@ -1496,7 +1499,7 @@ function getCaptureQualityFeedback(state) {
1496
1499
  if (tooClose) {
1497
1500
  return FEEDBACK_MESSAGES.too_close;
1498
1501
  }
1499
- if (tooFar) {
1502
+ if (tooFar || faceAreaLow) {
1500
1503
  return FEEDBACK_MESSAGES.too_far;
1501
1504
  }
1502
1505
  if (isPartialFace) {
@@ -1537,9 +1540,10 @@ function canCaptureFrame(state) {
1537
1540
  tooCloseToIdeal,
1538
1541
  cameraAngleLow,
1539
1542
  cameraAngleHigh,
1540
- cameraTilted
1543
+ cameraTilted,
1544
+ faceAreaLow
1541
1545
  } = state;
1542
- return hasFace && alignment >= ALIGNMENT_THRESHOLD_CAPTURE && !tooClose && !tooFar && !isBlurry && !isPartialFace && !tooFarFromIdeal && !tooCloseToIdeal && !cameraAngleLow && !cameraAngleHigh && !cameraTilted;
1546
+ return hasFace && alignment >= ALIGNMENT_THRESHOLD_CAPTURE && !tooClose && !tooFar && !isBlurry && !isPartialFace && !tooFarFromIdeal && !tooCloseToIdeal && !cameraAngleLow && !cameraAngleHigh && !cameraTilted && !faceAreaLow;
1543
1547
  }
1544
1548
 
1545
1549
  // src/utils/validators.ts
@@ -1623,6 +1627,7 @@ var FACE_CENTER_VERTICAL_OFFSET = 0.05;
1623
1627
  var MIN_IDEAL_FACE_RATIO = 0.05;
1624
1628
  var MAX_IDEAL_FACE_RATIO = 0.2;
1625
1629
  var MIN_FACE_RATIO = 0.036;
1630
+ var MIN_FACE_AREA_RATIO = 0.04;
1626
1631
  var MAX_FACE_RATIO = 0.7;
1627
1632
  var FACE_CROP_OUTPUT_SIZE = 224;
1628
1633
  var MAX_FACE_PERCENTAGE_IN_CROP = 0.45;
@@ -1907,6 +1912,21 @@ function detectFaceRoll(landmarks) {
1907
1912
  tooTilted: roll > MAX_FACE_ROLL_DEGREES
1908
1913
  };
1909
1914
  }
1915
+ function detectFaceRollFromMatrix(matrix) {
1916
+ if (matrix.length < 9) {
1917
+ return { roll: 0, tooTilted: false };
1918
+ }
1919
+ const m4 = matrix[4];
1920
+ const m5 = matrix[5];
1921
+ if (m4 === void 0 || m5 === void 0) {
1922
+ return { roll: 0, tooTilted: false };
1923
+ }
1924
+ const roll = Math.abs(Math.atan2(m4, m5) * (180 / Math.PI));
1925
+ return {
1926
+ roll,
1927
+ tooTilted: roll > MAX_FACE_ROLL_DEGREES
1928
+ };
1929
+ }
1910
1930
  var CAMERA_ANGLE_HIGH_RATIO = 1.35;
1911
1931
  var CAMERA_ANGLE_LOW_RATIO = 0.75;
1912
1932
  function detectCameraAngle(landmarks) {
@@ -2189,6 +2209,7 @@ function checkEyeRegionQuality(pixels, thresholds = EYE_QUALITY_THRESHOLDS) {
2189
2209
  MAX_IDEAL_FACE_RATIO,
2190
2210
  MIN_CAPTURE_ALIGNMENT,
2191
2211
  MIN_CROP_MULTIPLIER,
2212
+ MIN_FACE_AREA_RATIO,
2192
2213
  MIN_FACE_BOTTOM_MARGIN,
2193
2214
  MIN_FACE_RATIO,
2194
2215
  MIN_FACE_SIDE_MARGIN,
@@ -2217,6 +2238,7 @@ function checkEyeRegionQuality(pixels, thresholds = EYE_QUALITY_THRESHOLDS) {
2217
2238
  decodeBase64,
2218
2239
  detectCameraAngle,
2219
2240
  detectFaceRoll,
2241
+ detectFaceRollFromMatrix,
2220
2242
  detectSpecularHighlights,
2221
2243
  encodeBase64,
2222
2244
  generateSessionId,
package/dist/index.mjs CHANGED
@@ -1342,7 +1342,8 @@ function getCaptureQualityFeedback(state) {
1342
1342
  tooCloseToIdeal,
1343
1343
  cameraAngleLow,
1344
1344
  cameraAngleHigh,
1345
- cameraTilted
1345
+ cameraTilted,
1346
+ faceAreaLow
1346
1347
  } = state;
1347
1348
  if (!hasFace) {
1348
1349
  return FEEDBACK_MESSAGES.no_face;
@@ -1359,7 +1360,7 @@ function getCaptureQualityFeedback(state) {
1359
1360
  if (tooClose) {
1360
1361
  return FEEDBACK_MESSAGES.too_close;
1361
1362
  }
1362
- if (tooFar) {
1363
+ if (tooFar || faceAreaLow) {
1363
1364
  return FEEDBACK_MESSAGES.too_far;
1364
1365
  }
1365
1366
  if (isPartialFace) {
@@ -1400,9 +1401,10 @@ function canCaptureFrame(state) {
1400
1401
  tooCloseToIdeal,
1401
1402
  cameraAngleLow,
1402
1403
  cameraAngleHigh,
1403
- cameraTilted
1404
+ cameraTilted,
1405
+ faceAreaLow
1404
1406
  } = state;
1405
- return hasFace && alignment >= ALIGNMENT_THRESHOLD_CAPTURE && !tooClose && !tooFar && !isBlurry && !isPartialFace && !tooFarFromIdeal && !tooCloseToIdeal && !cameraAngleLow && !cameraAngleHigh && !cameraTilted;
1407
+ return hasFace && alignment >= ALIGNMENT_THRESHOLD_CAPTURE && !tooClose && !tooFar && !isBlurry && !isPartialFace && !tooFarFromIdeal && !tooCloseToIdeal && !cameraAngleLow && !cameraAngleHigh && !cameraTilted && !faceAreaLow;
1406
1408
  }
1407
1409
 
1408
1410
  // src/utils/validators.ts
@@ -1486,6 +1488,7 @@ var FACE_CENTER_VERTICAL_OFFSET = 0.05;
1486
1488
  var MIN_IDEAL_FACE_RATIO = 0.05;
1487
1489
  var MAX_IDEAL_FACE_RATIO = 0.2;
1488
1490
  var MIN_FACE_RATIO = 0.036;
1491
+ var MIN_FACE_AREA_RATIO = 0.04;
1489
1492
  var MAX_FACE_RATIO = 0.7;
1490
1493
  var FACE_CROP_OUTPUT_SIZE = 224;
1491
1494
  var MAX_FACE_PERCENTAGE_IN_CROP = 0.45;
@@ -1770,6 +1773,21 @@ function detectFaceRoll(landmarks) {
1770
1773
  tooTilted: roll > MAX_FACE_ROLL_DEGREES
1771
1774
  };
1772
1775
  }
1776
+ function detectFaceRollFromMatrix(matrix) {
1777
+ if (matrix.length < 9) {
1778
+ return { roll: 0, tooTilted: false };
1779
+ }
1780
+ const m4 = matrix[4];
1781
+ const m5 = matrix[5];
1782
+ if (m4 === void 0 || m5 === void 0) {
1783
+ return { roll: 0, tooTilted: false };
1784
+ }
1785
+ const roll = Math.abs(Math.atan2(m4, m5) * (180 / Math.PI));
1786
+ return {
1787
+ roll,
1788
+ tooTilted: roll > MAX_FACE_ROLL_DEGREES
1789
+ };
1790
+ }
1773
1791
  var CAMERA_ANGLE_HIGH_RATIO = 1.35;
1774
1792
  var CAMERA_ANGLE_LOW_RATIO = 0.75;
1775
1793
  function detectCameraAngle(landmarks) {
@@ -2051,6 +2069,7 @@ export {
2051
2069
  MAX_IDEAL_FACE_RATIO,
2052
2070
  MIN_CAPTURE_ALIGNMENT,
2053
2071
  MIN_CROP_MULTIPLIER,
2072
+ MIN_FACE_AREA_RATIO,
2054
2073
  MIN_FACE_BOTTOM_MARGIN,
2055
2074
  MIN_FACE_RATIO,
2056
2075
  MIN_FACE_SIDE_MARGIN,
@@ -2079,6 +2098,7 @@ export {
2079
2098
  decodeBase64,
2080
2099
  detectCameraAngle,
2081
2100
  detectFaceRoll,
2101
+ detectFaceRollFromMatrix,
2082
2102
  detectSpecularHighlights,
2083
2103
  encodeBase64,
2084
2104
  generateSessionId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moveris/shared",
3
- "version": "3.0.0",
3
+ "version": "3.2.0",
4
4
  "description": "Core business logic for Moveris Live SDK",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",