@richard.fadiora/liveness-detection 4.3.11 → 4.3.13
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
package/dist/angular/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"richard.fadiora-liveness-detection.mjs","sources":["../../../src/core/LivenessEngine.ts","../../../src/angular/liveness.service.ts","../../../src/angular/liveness.component.ts","../../../src/angular/liveness.component.html","../../../src/api.ts","../../../src/richard.fadiora-liveness-detection.ts"],"sourcesContent":["// src/core/LivenessEngine.ts\r\nimport { FaceLandmarker, HandLandmarker, FilesetResolver, NormalizedLandmark } from \"@mediapipe/tasks-vision\";\r\n\r\nexport type Challenge = \"Smile\" | \"Blink\" | \"Turn_Head\" | \"Thumbs_Up\";\r\n\r\nexport interface LivenessSDKResult {\r\n success: boolean;\r\n image?: string;\r\n reason?: string;\r\n skinConfidence?: number;\r\n}\r\n\r\nexport interface LivenessState {\r\n status: \"loading\" | \"ready\" | \"capturing\" | \"verifying\" | \"success\" | \"error\" | \"expired\";\r\n sequence: Challenge[];\r\n currentStep: number;\r\n timeLeft: number;\r\n isStepTransitioning: boolean;\r\n errorMsg: string;\r\n}\r\n\r\nexport interface LivenessEngineConfig {\r\n apiUrl: string;\r\n duration?: number;\r\n smileThreshold?: number;\r\n blinkThreshold?: number;\r\n minturnHeadThreshold?: number;\r\n maxturnHeadThreshold?: number;\r\n onStateChange?: (state: LivenessState) => void;\r\n onComplete?: (result: LivenessSDKResult) => void;\r\n onError?: (error: LivenessSDKResult) => void;\r\n}\r\n\r\nexport class LivenessEngine {\r\n private config: Required<LivenessEngineConfig>;\r\n private models: { face: FaceLandmarker | null; hand: HandLandmarker | null } = { face: null, hand: null };\r\n private webcam: HTMLVideoElement | null = null;\r\n private state: LivenessState;\r\n \r\n private currentStepRef = 0;\r\n private isStepTransitioningRef = false;\r\n private timerId: ReturnType<typeof setInterval> | null = null;\r\n private requestId: number | null = null;\r\n \r\n private offscreenCanvas = document.createElement(\"canvas\");\r\n private CHALLENGE_POOL: Challenge[] = [\"Smile\", \"Blink\", \"Turn_Head\", \"Thumbs_Up\"];\r\n\r\n constructor(config: LivenessEngineConfig) {\r\n this.config = {\r\n apiUrl: config.apiUrl,\r\n duration: config.duration ?? 60,\r\n smileThreshold: config.smileThreshold ?? 0.2,\r\n blinkThreshold: config.blinkThreshold ?? 0.012,\r\n minturnHeadThreshold: config.minturnHeadThreshold ?? 0.15,\r\n maxturnHeadThreshold: config.maxturnHeadThreshold ?? 0.85,\r\n onStateChange: config.onStateChange || (() => {}),\r\n onComplete: config.onComplete || (() => {}),\r\n onError: config.onError || (() => {}),\r\n };\r\n\r\n this.state = {\r\n status: \"loading\",\r\n sequence: [],\r\n currentStep: 0,\r\n timeLeft: this.config.duration,\r\n isStepTransitioning: false,\r\n errorMsg: \"\",\r\n };\r\n \r\n this.offscreenCanvas.width = 224;\r\n this.offscreenCanvas.height = 224;\r\n }\r\n\r\n /**\r\n * Phase 1: Load AI Assets (Call this immediately on mount)\r\n */\r\n public async loadModels() {\r\n console.log(\"[LivenessEngine] Loading AI Models...\");\r\n try {\r\n const vision = await FilesetResolver.forVisionTasks(\r\n \"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.3/wasm\"\r\n );\r\n\r\n this.models.face = await FaceLandmarker.createFromOptions(vision, {\r\n baseOptions: {\r\n modelAssetPath: \"https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task\",\r\n delegate: \"GPU\",\r\n },\r\n outputFaceBlendshapes: true,\r\n runningMode: \"VIDEO\",\r\n });\r\n\r\n this.models.hand = await HandLandmarker.createFromOptions(vision, {\r\n baseOptions: {\r\n modelAssetPath: \"https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task\",\r\n delegate: \"GPU\",\r\n },\r\n runningMode: \"VIDEO\",\r\n numHands: 1,\r\n });\r\n\r\n this.generateSequence();\r\n // Stay in 'loading' or move to a 'ready_to_mount' status if you prefer\r\n // For now, we move to ready to signal the UI can show the camera\r\n this.updateState({ status: \"ready\" });\r\n console.log(\"[LivenessEngine] Models Loaded.\");\r\n } catch (err) {\r\n console.error(\"[LivenessEngine] Init Error:\", err);\r\n this.updateState({ status: \"error\", errorMsg: \"Failed to load security assets.\" });\r\n }\r\n }\r\n\r\n /**\r\n * Phase 2: Attach Video (Call this once the Webcam is in the DOM)\r\n */\r\n public attachVideo = (video: HTMLVideoElement) => {\r\n this.webcam = video;\r\n console.log(\"[LivenessEngine] Video stream attached.\");\r\n };\r\n\r\n public start = () => {\r\n if (this.state.status !== \"ready\" || !this.webcam) {\r\n console.warn(\"[LivenessEngine] Engine not ready or video missing.\");\r\n return;\r\n }\r\n\r\n console.log(\"[LivenessEngine] Session Starting...\");\r\n this.state.status = \"capturing\"; // Sync internal status immediately\r\n this.updateState({ status: \"capturing\" });\r\n this.startTimer();\r\n this.detectLoop();\r\n };\r\n\r\n public stop = () => {\r\n if (this.timerId) clearInterval(this.timerId);\r\n if (this.requestId) cancelAnimationFrame(this.requestId);\r\n this.timerId = null;\r\n this.requestId = null;\r\n };\r\n\r\n public reset = () => {\r\n this.stop();\r\n this.currentStepRef = 0;\r\n this.isStepTransitioningRef = false;\r\n this.generateSequence();\r\n this.updateState({\r\n status: \"ready\",\r\n currentStep: 0,\r\n timeLeft: this.config.duration,\r\n isStepTransitioning: false,\r\n errorMsg: \"\",\r\n });\r\n };\r\n\r\n private updateState(newState: Partial<LivenessState>) {\r\n this.state = { ...this.state, ...newState };\r\n this.config.onStateChange(this.state);\r\n }\r\n\r\n private generateSequence(): Challenge[] {\r\n const seq = [...this.CHALLENGE_POOL].sort(() => 0.5 - Math.random()).slice(0, 3);\r\n this.state.sequence = seq;\r\n return seq;\r\n }\r\n\r\n private startTimer() {\r\n if (this.timerId) clearInterval(this.timerId);\r\n this.timerId = setInterval(() => {\r\n if (this.state.timeLeft > 0) {\r\n this.updateState({ timeLeft: this.state.timeLeft - 1 });\r\n } else {\r\n this.stop();\r\n this.updateState({ status: \"expired\" });\r\n }\r\n }, 1000);\r\n }\r\n\r\n private detectLoop = () => {\r\n if (this.state.status !== \"capturing\" || !this.webcam || !this.models.face) return;\r\n\r\n const now = performance.now();\r\n try {\r\n const faceRes = this.models.face.detectForVideo(this.webcam, now);\r\n const handRes = this.models.hand?.detectForVideo(this.webcam, now);\r\n\r\n const currentChallenge = this.state.sequence[this.currentStepRef];\r\n\r\n if (this.checkAction(faceRes, handRes, currentChallenge)) {\r\n this.handleStepSuccess();\r\n return; // handleStepSuccess schedules the next frame after a delay\r\n }\r\n } catch (err) {\r\n console.error(\"[LivenessEngine] Loop detection error:\", err);\r\n }\r\n\r\n this.requestId = requestAnimationFrame(this.detectLoop);\r\n };\r\n\r\n private handleStepSuccess() {\r\n if (this.isStepTransitioningRef) return;\r\n \r\n this.isStepTransitioningRef = true;\r\n this.updateState({ isStepTransitioning: true });\r\n\r\n setTimeout(() => {\r\n if (this.currentStepRef < this.state.sequence.length - 1) {\r\n this.currentStepRef++;\r\n this.isStepTransitioningRef = false;\r\n this.updateState({\r\n currentStep: this.currentStepRef,\r\n isStepTransitioning: false,\r\n });\r\n this.requestId = requestAnimationFrame(this.detectLoop);\r\n } else {\r\n this.sendFinalProof();\r\n }\r\n }, 1500);\r\n }\r\n\r\n private checkAction(faceRes: any, handRes: any, challenge: Challenge): boolean {\r\n if (this.isStepTransitioningRef) return false;\r\n\r\n if (challenge === \"Thumbs_Up\" && handRes?.landmarks?.length > 0) {\r\n const l = handRes.landmarks[0];\r\n return l[4].y < l[2].y && [8, 12, 16, 20].every(i => l[i].y > l[i - 2].y);\r\n }\r\n\r\n if (faceRes?.faceLandmarks?.length > 0) {\r\n const lms: NormalizedLandmark[] = faceRes.faceLandmarks[0];\r\n switch (challenge) {\r\n case \"Smile\":\r\n return (lms[291].x - lms[61].x) > this.config.smileThreshold;\r\n case \"Blink\":\r\n const leftEar = Math.abs(lms[159].y - lms[145].y);\r\n const rightEar = Math.abs(lms[386].y - lms[374].y);\r\n return ((leftEar + rightEar) / 2) < this.config.blinkThreshold;\r\n case \"Turn_Head\":\r\n const yaw = (lms[1].x - lms[33].x) / (lms[263].x - lms[33].x);\r\n return yaw < this.config.minturnHeadThreshold || yaw > this.config.maxturnHeadThreshold;\r\n default: return false;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n private async sendFinalProof() {\r\n this.stop();\r\n this.updateState({ status: \"verifying\" });\r\n\r\n try {\r\n const blobs: Blob[] = [];\r\n let finalBase64 = \"\";\r\n\r\n for (let i = 0; i < 5; i++) {\r\n if (!this.webcam) break;\r\n const faceRes = this.models.face?.detectForVideo(this.webcam, performance.now());\r\n if (faceRes?.faceLandmarks?.[0]) {\r\n const canvas = this.getFaceCrop(this.webcam, faceRes.faceLandmarks[0]);\r\n const blob = await new Promise<Blob | null>(res => canvas.toBlob(res, \"image/jpeg\", 0.9));\r\n if (blob) blobs.push(blob);\r\n if (i === 4) finalBase64 = canvas.toDataURL(\"image/jpeg\");\r\n }\r\n await new Promise(r => setTimeout(r, 100));\r\n }\r\n\r\n const { verifyLiveness } = await import(\"../api\");\r\n const result = await verifyLiveness(this.config.apiUrl, blobs, this.state.sequence);\r\n\r\n if (result.is_live) {\r\n this.updateState({ status: \"success\" });\r\n this.config.onComplete({ success: true, image: finalBase64, skinConfidence: result.skin_confidence });\r\n } else {\r\n const reason = result.reason || \"Liveness check failed\";\r\n this.updateState({ status: \"error\", errorMsg: reason });\r\n this.config.onError({ success: false, reason });\r\n }\r\n } catch (err) {\r\n this.updateState({ status: \"error\", errorMsg: \"Verification failed.\" });\r\n this.config.onError({ success: false, reason: \"Network error\" });\r\n }\r\n }\r\n\r\n private getFaceCrop(video: HTMLVideoElement, landmarks: NormalizedLandmark[]): HTMLCanvasElement {\r\n const ctx = this.offscreenCanvas.getContext(\"2d\")!;\r\n const xs = landmarks.map(l => l.x * video.videoWidth);\r\n const ys = landmarks.map(l => l.y * video.videoHeight);\r\n \r\n const minX = Math.min(...xs);\r\n const maxX = Math.max(...xs);\r\n const minY = Math.min(...ys);\r\n const maxY = Math.max(...ys);\r\n \r\n const width = maxX - minX;\r\n const height = maxY - minY;\r\n const margin = width * 0.3;\r\n\r\n ctx.clearRect(0, 0, 224, 224);\r\n ctx.drawImage(\r\n video,\r\n minX - margin, minY - margin, \r\n width + margin * 2, height + margin * 2,\r\n 0, 0, 224, 224\r\n );\r\n\r\n return this.offscreenCanvas;\r\n }\r\n}","import { Injectable, NgZone, OnDestroy } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\nimport { LivenessEngine, LivenessState, LivenessEngineConfig } from '../core/LivenessEngine';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class LivenessService implements OnDestroy {\r\n private engine!: LivenessEngine;\r\n private stateSubject = new BehaviorSubject<LivenessState | null>(null);\r\n \r\n // Components will subscribe to this\r\n public state$: Observable<LivenessState | null> = this.stateSubject.asObservable();\r\n\r\n constructor(private ngZone: NgZone) {}\r\n\r\n public init(config: LivenessEngineConfig) {\r\n // Run inside runOutsideAngular to prevent 60fps change detection triggers\r\n this.ngZone.runOutsideAngular(() => {\r\n this.engine = new LivenessEngine({\r\n ...config,\r\n onStateChange: (state) => {\r\n // Bring state changes BACK into the zone so the UI updates\r\n this.ngZone.run(() => this.stateSubject.next(state));\r\n }\r\n });\r\n this.engine.loadModels();\r\n });\r\n }\r\n\r\n public attach(video: HTMLVideoElement) {\r\n this.engine?.attachVideo(video);\r\n }\r\n\r\n public start() {\r\n this.engine?.start();\r\n }\r\n\r\n public reset() {\r\n this.engine?.reset();\r\n }\r\n\r\n ngOnDestroy() {\r\n this.engine?.stop();\r\n }\r\n}","import { Component, ElementRef, ViewChild, AfterViewInit, Input, Output, EventEmitter, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';\r\nimport { LivenessService } from './liveness.service';\r\nimport { LivenessSDKResult, Challenge, LivenessState } from '../core/LivenessEngine';\r\nimport { CommonModule } from '@angular/common'\r\n\r\n@Component({\r\n selector: 'LivenessCheck',\r\n standalone: true, // Make it standalone\r\n imports: [CommonModule], // Add CommonModule here to fix NG8002\r\n templateUrl: './liveness.component.html',\r\n encapsulation: ViewEncapsulation.None,\r\n})\r\n\r\nexport class LivenessComponent implements OnInit, AfterViewInit, OnDestroy {\r\n @ViewChild('webcam') webcamRef!: ElementRef<HTMLVideoElement>;\r\n\r\n // --- Logic Configuration ---\r\n @Input() apiUrl!: string;\r\n @Input() duration = 60;\r\n @Input() smileThreshold?: number;\r\n @Input() blinkThreshold?: number;\r\n @Input() minturnHeadThreshold?: number;\r\n @Input() maxturnHeadThreshold?: number;\r\n\r\n // --- Styling Configuration (Class Names) ---\r\n @Input() containerClass = '';\r\n @Input() videoWrapperClass = '';\r\n @Input() videoClass = '';\r\n @Input() timerClass = '';\r\n @Input() stateClass = '';\r\n @Input() challengeTextClass = '';\r\n @Input() buttonClass = '';\r\n @Input() retryButtonClass = '';\r\n @Input() statusOverlayClass = '';\r\n @Input() successMessageClass = '';\r\n @Input() errorMessageClass = '';\r\n @Input() instructionBoxClass = '';\r\n\r\n // --- Content Configuration ---\r\n @Input() successMessage = 'Verification Successful!';\r\n @Input() errorMessage = 'Verification failed. Please try again.';\r\n @Input() retryButtonLabel = 'Try Again';\r\n @Input() startButtonLabel = 'Start Verification';\r\n @Input() challengeMapping: Record<Challenge, string> = {\r\n 'Smile': 'Smile',\r\n 'Blink': 'Blink',\r\n 'Turn_Head': 'Turn Head',\r\n 'Thumbs_Up': 'Thumbs Up' // Default with a space\r\n };\r\n\r\n @Output() onComplete = new EventEmitter<LivenessSDKResult>();\r\n @Output() onError = new EventEmitter<any>();\r\n @Output() onStateChange = new EventEmitter<LivenessState | null>();\r\n\r\n constructor(public liveness: LivenessService) {}\r\n\r\n ngOnInit() {\r\n // Pass the custom thresholds directly to the service\r\n \r\n\r\n this.liveness.state$.subscribe(state => {\r\n // This bridges the Service to the Component's @Output\r\n this.onStateChange.emit(state);\r\n });\r\n\r\n }\r\n\r\n async ngAfterViewInit() {\r\n try {\r\n const stream = await navigator.mediaDevices.getUserMedia({ \r\n video: { width: 640, height: 480, facingMode: 'user' } \r\n });\r\n const video = this.webcamRef.nativeElement;\r\n video.srcObject = stream;\r\n video.onloadedmetadata = () => {\r\n video.play();\r\n\r\n this.liveness.init({\r\n apiUrl: this.apiUrl,\r\n duration: this.duration,\r\n smileThreshold: this.smileThreshold,\r\n blinkThreshold: this.blinkThreshold,\r\n minturnHeadThreshold: this.minturnHeadThreshold,\r\n maxturnHeadThreshold: this.maxturnHeadThreshold,\r\n onComplete: (res) => this.onComplete.emit(res),\r\n onError: (err) => this.onError.emit(err)\r\n });\r\n\r\n this.liveness.attach(video);\r\n };\r\n } catch (e) {\r\n this.onError.emit({ success: false, reason: 'Camera access denied' });\r\n }\r\n }\r\n\r\n ngOnDestroy() {\r\n const stream = this.webcamRef?.nativeElement?.srcObject as MediaStream;\r\n stream?.getTracks().forEach(track => track.stop());\r\n }\r\n}","<div [ngClass]=\"containerClass\">\r\n <div [ngClass]=\"videoWrapperClass\">\r\n <video #webcam \r\n autoplay \r\n playsinline \r\n muted \r\n [ngClass]=\"videoClass\" \r\n style=\"transform: scaleX(-1);\">\r\n </video>\r\n\r\n <ng-container *ngIf=\"(liveness.state$ | async) as state\">\r\n <div [ngClass]=\"statusOverlayClass\">\r\n \r\n <div class=\"instruction-box\">\r\n <h2 class=\"status-text\" [ngClass] = \"stateClass\">{{ state.status | uppercase }}</h2>\r\n \r\n <p *ngIf=\"state.status === 'capturing'\" \r\n [ngClass]=\"challengeTextClass\">\r\n {{ challengeMapping[state.sequence[state.currentStep]] }}\r\n </p>\r\n\r\n <p *ngIf=\"state.status === 'success'\"\r\n [ngClass]=\"successMessageClass\">\r\n {{ successMessage }}\r\n </p>\r\n \r\n <p *ngIf=\"state.status === 'error' || state.status === 'expired'\" \r\n [ngClass]=\"errorMessageClass\">\r\n {{ errorMessage }}\r\n </p>\r\n </div>\r\n\r\n <div *ngIf=\"state.status === 'capturing'\" \r\n [ngClass]=\"timerClass\">\r\n {{ state.timeLeft }}\r\n </div>\r\n\r\n <div class=\"action-area\">\r\n <button *ngIf=\"state.status === 'ready'\" \r\n (click)=\"liveness.start()\"\r\n [ngClass]=\"buttonClass\">\r\n {{ startButtonLabel }}\r\n </button>\r\n \r\n <button *ngIf=\"state.status === 'error' || state.status === 'expired'\" \r\n (click)=\"liveness.reset()\"\r\n [ngClass]=\"retryButtonClass\">\r\n {{ retryButtonLabel }}\r\n </button>\r\n </div>\r\n\r\n </div>\r\n </ng-container>\r\n </div>\r\n</div>","// src/api.ts\r\n\r\nimport { Challenge } from \"./core/LivenessEngine\";\r\n\r\nexport interface LivenessResponse {\r\n is_live: boolean;\r\n reason?: string;\r\n skin_confidence?: number;\r\n [key: string]: any; // allow extra fields if backend returns more\r\n}\r\n\r\n/**\r\n * Sends captured frames to the backend API for liveness verification.\r\n * @param apiUrl - Base URL of the liveness backend\r\n * @param frameBlobs - Array of Blob objects representing captured frames\r\n * @param challenge - The current challenge string\r\n * @returns LivenessResponse from backend\r\n */\r\nexport const verifyLiveness = async (\r\n apiUrl: string,\r\n frameBlobs: Blob[],\r\n challenge: Challenge[]\r\n): Promise<LivenessResponse> => {\r\n const formData = new FormData();\r\n\r\n frameBlobs.forEach((blob, i) => {\r\n formData.append('files', blob, `frame_${i}.jpg`);\r\n });\r\n formData.append('challenge', JSON.stringify(challenge));\r\n\r\n const response = await fetch(`${apiUrl}/v1/verify`, {\r\n method: 'POST',\r\n body: formData,\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(\"Network response was not ok\");\r\n }\r\n\r\n const data: LivenessResponse = await response.json();\r\n return data;\r\n};","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.LivenessService"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"richard.fadiora-liveness-detection.mjs","sources":["../../../src/core/LivenessEngine.ts","../../../src/angular/liveness.service.ts","../../../src/angular/liveness.component.ts","../../../src/angular/liveness.component.html","../../../src/api.ts","../../../src/richard.fadiora-liveness-detection.ts"],"sourcesContent":["// src/core/LivenessEngine.ts\r\nimport { FaceLandmarker, HandLandmarker, FilesetResolver, NormalizedLandmark } from \"@mediapipe/tasks-vision\";\r\n\r\nexport type Challenge = \"Smile\" | \"Blink\" | \"Turn_Head\" | \"Thumbs_Up\";\r\n\r\nexport interface LivenessSDKResult {\r\n success: boolean;\r\n image?: string;\r\n reason?: string;\r\n skinConfidence?: number;\r\n}\r\n\r\nexport interface LivenessState {\r\n status: \"loading\" | \"ready\" | \"capturing\" | \"verifying\" | \"success\" | \"error\" | \"expired\";\r\n sequence: Challenge[];\r\n currentStep: number;\r\n timeLeft: number;\r\n isStepTransitioning: boolean;\r\n errorMsg: string;\r\n}\r\n\r\nexport interface LivenessEngineConfig {\r\n apiUrl: string;\r\n duration?: number;\r\n smileThreshold?: number;\r\n blinkThreshold?: number;\r\n minturnHeadThreshold?: number;\r\n maxturnHeadThreshold?: number;\r\n onStateChange?: (state: LivenessState) => void;\r\n onComplete?: (result: LivenessSDKResult) => void;\r\n onError?: (error: LivenessSDKResult) => void;\r\n}\r\n\r\nexport class LivenessEngine {\r\n private config: Required<LivenessEngineConfig>;\r\n private models: { face: FaceLandmarker | null; hand: HandLandmarker | null } = { face: null, hand: null };\r\n private webcam: HTMLVideoElement | null = null;\r\n private state: LivenessState;\r\n \r\n private currentStepRef = 0;\r\n private isStepTransitioningRef = false;\r\n private timerId: ReturnType<typeof setInterval> | null = null;\r\n private requestId: number | null = null;\r\n \r\n \r\n private offscreenCanvas = document.createElement(\"canvas\");\r\n private CHALLENGE_POOL: Challenge[] = [\"Smile\", \"Blink\", \"Turn_Head\", \"Thumbs_Up\"];\r\n\r\n constructor(config: LivenessEngineConfig) {\r\n this.config = {\r\n apiUrl: config.apiUrl,\r\n duration: config.duration ?? 60,\r\n smileThreshold: config.smileThreshold ?? 0.2,\r\n blinkThreshold: config.blinkThreshold ?? 0.012,\r\n minturnHeadThreshold: config.minturnHeadThreshold ?? 0.15,\r\n maxturnHeadThreshold: config.maxturnHeadThreshold ?? 0.85,\r\n onStateChange: config.onStateChange || (() => {}),\r\n onComplete: config.onComplete || (() => {}),\r\n onError: config.onError || (() => {}),\r\n };\r\n\r\n this.state = {\r\n status: \"loading\",\r\n sequence: [],\r\n currentStep: 0,\r\n timeLeft: this.config.duration,\r\n isStepTransitioning: false,\r\n errorMsg: \"\",\r\n };\r\n \r\n this.offscreenCanvas.width = 224;\r\n this.offscreenCanvas.height = 224;\r\n }\r\n\r\n /**\r\n * Phase 1: Load AI Assets (Call this immediately on mount)\r\n */\r\n public async loadModels() {\r\n console.log(\"[LivenessEngine] Loading AI Models...\");\r\n try {\r\n const vision = await FilesetResolver.forVisionTasks(\r\n \"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.3/wasm\"\r\n );\r\n\r\n this.models.face = await FaceLandmarker.createFromOptions(vision, {\r\n baseOptions: {\r\n modelAssetPath: \"https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task\",\r\n delegate: \"GPU\",\r\n },\r\n outputFaceBlendshapes: true,\r\n runningMode: \"VIDEO\",\r\n });\r\n\r\n this.models.hand = await HandLandmarker.createFromOptions(vision, {\r\n baseOptions: {\r\n modelAssetPath: \"https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task\",\r\n delegate: \"GPU\",\r\n },\r\n runningMode: \"VIDEO\",\r\n numHands: 1,\r\n });\r\n\r\n this.generateSequence();\r\n // Stay in 'loading' or move to a 'ready_to_mount' status if you prefer\r\n // For now, we move to ready to signal the UI can show the camera\r\n this.updateState({ status: \"ready\" });\r\n console.log(\"[LivenessEngine] Models Loaded.\");\r\n } catch (err) {\r\n console.error(\"[LivenessEngine] Init Error:\", err);\r\n this.updateState({ status: \"error\", errorMsg: \"Failed to load security assets.\" });\r\n }\r\n }\r\n\r\n /**\r\n * Phase 2: Attach Video (Call this once the Webcam is in the DOM)\r\n */\r\n public attachVideo = (video: HTMLVideoElement) => {\r\n this.webcam = video;\r\n console.log(\"[LivenessEngine] Video stream attached.\");\r\n };\r\n\r\n public start = () => {\r\n if (this.state.status !== \"ready\" || !this.webcam) {\r\n console.warn(\"[LivenessEngine] Engine not ready or video missing.\");\r\n return;\r\n }\r\n\r\n console.log(\"[LivenessEngine] Session Starting...\");\r\n this.state.status = \"capturing\"; // Sync internal status immediately\r\n this.updateState({ status: \"capturing\" });\r\n this.startTimer();\r\n this.detectLoop();\r\n };\r\n\r\n public stop = () => {\r\n if (this.timerId) clearInterval(this.timerId);\r\n if (this.requestId) cancelAnimationFrame(this.requestId);\r\n this.timerId = null;\r\n this.requestId = null;\r\n };\r\n\r\n public reset = () => {\r\n this.stop();\r\n this.currentStepRef = 0;\r\n this.isStepTransitioningRef = false;\r\n this.generateSequence();\r\n this.updateState({\r\n status: \"ready\",\r\n currentStep: 0,\r\n timeLeft: this.config.duration,\r\n isStepTransitioning: false,\r\n errorMsg: \"\",\r\n });\r\n };\r\n\r\n private updateState(newState: Partial<LivenessState>) {\r\n this.state = { ...this.state, ...newState };\r\n this.config.onStateChange(this.state);\r\n }\r\n\r\n private generateSequence(): Challenge[] {\r\n const seq = [...this.CHALLENGE_POOL].sort(() => 0.5 - Math.random()).slice(0, 3);\r\n this.state.sequence = seq;\r\n return seq;\r\n }\r\n\r\n private startTimer() {\r\n if (this.timerId) clearInterval(this.timerId);\r\n this.timerId = setInterval(() => {\r\n if (this.state.timeLeft > 0) {\r\n this.updateState({ timeLeft: this.state.timeLeft - 1 });\r\n } else {\r\n this.stop();\r\n this.updateState({ status: \"expired\" });\r\n }\r\n }, 1000);\r\n }\r\n\r\n private detectLoop = () => {\r\n if (this.state.status !== \"capturing\" || !this.webcam || !this.models.face) return;\r\n\r\n const now = performance.now();\r\n try {\r\n const faceRes = this.models.face.detectForVideo(this.webcam, now);\r\n const handRes = this.models.hand?.detectForVideo(this.webcam, now);\r\n\r\n const currentChallenge = this.state.sequence[this.currentStepRef];\r\n\r\n if (this.checkAction(faceRes, handRes, currentChallenge)) {\r\n this.handleStepSuccess();\r\n return; // handleStepSuccess schedules the next frame after a delay\r\n }\r\n } catch (err) {\r\n console.error(\"[LivenessEngine] Loop detection error:\", err);\r\n }\r\n\r\n this.requestId = requestAnimationFrame(this.detectLoop);\r\n };\r\n\r\n private handleStepSuccess() {\r\n if (this.isStepTransitioningRef) return;\r\n \r\n this.isStepTransitioningRef = true;\r\n this.updateState({ isStepTransitioning: true });\r\n\r\n setTimeout(() => {\r\n if (this.currentStepRef < this.state.sequence.length - 1) {\r\n this.currentStepRef++;\r\n this.isStepTransitioningRef = false;\r\n this.updateState({\r\n currentStep: this.currentStepRef,\r\n isStepTransitioning: false,\r\n });\r\n this.requestId = requestAnimationFrame(this.detectLoop);\r\n } else {\r\n this.sendFinalProof();\r\n }\r\n }, 1500);\r\n }\r\n\r\n private checkAction(faceRes: any, handRes: any, challenge: Challenge): boolean {\r\n if (this.isStepTransitioningRef) return false;\r\n\r\n if (challenge === \"Thumbs_Up\" && handRes?.landmarks?.length > 0) {\r\n const l = handRes.landmarks[0];\r\n return l[4].y < l[2].y && [8, 12, 16, 20].every(i => l[i].y > l[i - 2].y);\r\n }\r\n\r\n if (faceRes?.faceLandmarks?.length > 0) {\r\n const lms: NormalizedLandmark[] = faceRes.faceLandmarks[0];\r\n switch (challenge) {\r\n case \"Smile\":\r\n return (lms[291].x - lms[61].x) > this.config.smileThreshold;\r\n case \"Blink\":\r\n const leftEar = Math.abs(lms[159].y - lms[145].y);\r\n const rightEar = Math.abs(lms[386].y - lms[374].y);\r\n return ((leftEar + rightEar) / 2) < this.config.blinkThreshold;\r\n case \"Turn_Head\":\r\n const yaw = (lms[1].x - lms[33].x) / (lms[263].x - lms[33].x);\r\n return yaw < this.config.minturnHeadThreshold || yaw > this.config.maxturnHeadThreshold;\r\n default: return false;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n private async sendFinalProof() {\r\n this.stop();\r\n this.updateState({ status: \"verifying\" });\r\n\r\n try {\r\n const blobs: Blob[] = [];\r\n let finalBase64 = \"\";\r\n\r\n for (let i = 0; i < 5; i++) {\r\n if (!this.webcam) break;\r\n const faceRes = this.models.face?.detectForVideo(this.webcam, performance.now());\r\n if (faceRes?.faceLandmarks?.[0]) {\r\n const canvas = this.getFaceCrop(this.webcam, faceRes.faceLandmarks[0]);\r\n const blob = await new Promise<Blob | null>(res => canvas.toBlob(res, \"image/jpeg\", 0.9));\r\n if (blob) blobs.push(blob);\r\n if (i === 4) finalBase64 = canvas.toDataURL(\"image/jpeg\");\r\n }\r\n await new Promise(r => setTimeout(r, 100));\r\n }\r\n\r\n const { verifyLiveness } = await import(\"../api\");\r\n const result = await verifyLiveness(this.config.apiUrl, blobs, this.state.sequence);\r\n\r\n if (result.is_live) {\r\n this.updateState({ status: \"success\" });\r\n this.config.onComplete({ success: true, image: finalBase64, skinConfidence: result.skin_confidence });\r\n } else {\r\n const reason = result.reason || \"Liveness check failed\";\r\n this.updateState({ status: \"error\", errorMsg: reason });\r\n this.config.onError({ success: false, reason });\r\n }\r\n } catch (err) {\r\n this.updateState({ status: \"error\", errorMsg: \"Verification failed.\" });\r\n this.config.onError({ success: false, reason: \"Network error\" });\r\n }\r\n }\r\n\r\n private getFaceCrop(video: HTMLVideoElement, landmarks: NormalizedLandmark[]): HTMLCanvasElement {\r\n const ctx = this.offscreenCanvas.getContext(\"2d\")!;\r\n const xs = landmarks.map(l => l.x * video.videoWidth);\r\n const ys = landmarks.map(l => l.y * video.videoHeight);\r\n \r\n const minX = Math.min(...xs);\r\n const maxX = Math.max(...xs);\r\n const minY = Math.min(...ys);\r\n const maxY = Math.max(...ys);\r\n \r\n const width = maxX - minX;\r\n const height = maxY - minY;\r\n const margin = width * 0.3;\r\n\r\n ctx.clearRect(0, 0, 224, 224);\r\n ctx.drawImage(\r\n video,\r\n minX - margin, minY - margin, \r\n width + margin * 2, height + margin * 2,\r\n 0, 0, 224, 224\r\n );\r\n\r\n return this.offscreenCanvas;\r\n }\r\n}","import { Injectable, NgZone, OnDestroy } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\nimport { LivenessEngine, LivenessState, LivenessEngineConfig } from '../core/LivenessEngine';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class LivenessService implements OnDestroy {\r\n private engine!: LivenessEngine;\r\n private stateSubject = new BehaviorSubject<LivenessState | null>(null);\r\n \r\n // Components will subscribe to this\r\n public state$: Observable<LivenessState | null> = this.stateSubject.asObservable();\r\n\r\n constructor(private ngZone: NgZone) {}\r\n\r\n public init(config: LivenessEngineConfig) {\r\n // Run inside runOutsideAngular to prevent 60fps change detection triggers\r\n this.ngZone.runOutsideAngular(() => {\r\n this.engine = new LivenessEngine({\r\n ...config,\r\n onStateChange: (state) => {\r\n // Bring state changes BACK into the zone so the UI updates\r\n this.ngZone.run(() => this.stateSubject.next(state));\r\n }\r\n });\r\n this.engine.loadModels();\r\n });\r\n }\r\n\r\n public attach(video: HTMLVideoElement) {\r\n this.engine?.attachVideo(video);\r\n }\r\n\r\n public start() {\r\n this.engine?.start();\r\n }\r\n\r\n public reset() {\r\n this.engine?.reset();\r\n }\r\n\r\n ngOnDestroy() {\r\n this.engine?.stop();\r\n }\r\n}","import { Component, ElementRef, ViewChild, AfterViewInit, Input, Output, EventEmitter, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';\r\nimport { LivenessService } from './liveness.service';\r\nimport { LivenessSDKResult, Challenge, LivenessState } from '../core/LivenessEngine';\r\nimport { CommonModule } from '@angular/common'\r\n\r\n@Component({\r\n selector: 'LivenessCheck',\r\n standalone: true, // Make it standalone\r\n imports: [CommonModule], // Add CommonModule here to fix NG8002\r\n templateUrl: './liveness.component.html',\r\n encapsulation: ViewEncapsulation.None,\r\n})\r\n\r\nexport class LivenessComponent implements OnInit, AfterViewInit, OnDestroy {\r\n @ViewChild('webcam') webcamRef!: ElementRef<HTMLVideoElement>;\r\n\r\n // --- Logic Configuration ---\r\n @Input() apiUrl!: string;\r\n @Input() duration = 60;\r\n @Input() smileThreshold?: number;\r\n @Input() blinkThreshold?: number;\r\n @Input() minturnHeadThreshold?: number;\r\n @Input() maxturnHeadThreshold?: number;\r\n\r\n // --- Styling Configuration (Class Names) ---\r\n @Input() containerClass = '';\r\n @Input() videoWrapperClass = '';\r\n @Input() videoClass = '';\r\n @Input() timerClass = '';\r\n @Input() stateClass = '';\r\n @Input() challengeTextClass = '';\r\n @Input() buttonClass = '';\r\n @Input() retryButtonClass = '';\r\n @Input() statusOverlayClass = '';\r\n @Input() successMessageClass = '';\r\n @Input() errorMessageClass = '';\r\n @Input() instructionBoxClass = '';\r\n\r\n // --- Content Configuration ---\r\n @Input() successMessage = 'Verification Successful!';\r\n @Input() errorMessage = 'Verification failed. Please try again.';\r\n @Input() retryButtonLabel = 'Try Again';\r\n @Input() startButtonLabel = 'Start Verification';\r\n @Input() challengeMapping: Record<Challenge, string> = {\r\n 'Smile': 'Smile',\r\n 'Blink': 'Blink',\r\n 'Turn_Head': 'Turn Head',\r\n 'Thumbs_Up': 'Thumbs Up' // Default with a space\r\n };\r\n\r\n @Output() onComplete = new EventEmitter<LivenessSDKResult>();\r\n @Output() onError = new EventEmitter<any>();\r\n @Output() onStateChange = new EventEmitter<LivenessState | null>();\r\n\r\n constructor(public liveness: LivenessService) {}\r\n\r\n ngOnInit() {\r\n // Pass the custom thresholds directly to the service\r\n \r\n\r\n this.liveness.state$.subscribe(state => {\r\n // This bridges the Service to the Component's @Output\r\n this.onStateChange.emit(state);\r\n });\r\n\r\n }\r\n\r\n async ngAfterViewInit() {\r\n try {\r\n const stream = await navigator.mediaDevices.getUserMedia({ \r\n video: { width: 640, height: 480, facingMode: 'user' } \r\n });\r\n const video = this.webcamRef.nativeElement;\r\n video.srcObject = stream;\r\n video.onloadedmetadata = () => {\r\n video.play();\r\n\r\n this.liveness.init({\r\n apiUrl: this.apiUrl,\r\n duration: this.duration,\r\n smileThreshold: this.smileThreshold,\r\n blinkThreshold: this.blinkThreshold,\r\n minturnHeadThreshold: this.minturnHeadThreshold,\r\n maxturnHeadThreshold: this.maxturnHeadThreshold,\r\n onComplete: (res) => this.onComplete.emit(res),\r\n onError: (err) => this.onError.emit(err)\r\n });\r\n\r\n this.liveness.attach(video);\r\n };\r\n } catch (e) {\r\n this.onError.emit({ success: false, reason: 'Camera access denied' });\r\n }\r\n }\r\n\r\n ngOnDestroy() {\r\n const stream = this.webcamRef?.nativeElement?.srcObject as MediaStream;\r\n stream?.getTracks().forEach(track => track.stop());\r\n }\r\n}","<div [ngClass]=\"containerClass\">\r\n <div [ngClass]=\"videoWrapperClass\">\r\n <video #webcam \r\n autoplay \r\n playsinline \r\n muted \r\n [ngClass]=\"videoClass\" \r\n style=\"transform: scaleX(-1);\">\r\n </video>\r\n\r\n <ng-container *ngIf=\"(liveness.state$ | async) as state\">\r\n <div [ngClass]=\"statusOverlayClass\">\r\n \r\n <div class=\"instruction-box\">\r\n <h2 class=\"status-text\" [ngClass] = \"stateClass\">{{ state.status | uppercase }}</h2>\r\n \r\n <p *ngIf=\"state.status === 'capturing'\" \r\n [ngClass]=\"challengeTextClass\">\r\n {{ challengeMapping[state.sequence[state.currentStep]] }}\r\n </p>\r\n\r\n <p *ngIf=\"state.status === 'success'\"\r\n [ngClass]=\"successMessageClass\">\r\n {{ successMessage }}\r\n </p>\r\n \r\n <p *ngIf=\"state.status === 'error' || state.status === 'expired'\" \r\n [ngClass]=\"errorMessageClass\">\r\n {{ errorMessage }}\r\n </p>\r\n </div>\r\n\r\n <div *ngIf=\"state.status === 'capturing'\" \r\n [ngClass]=\"timerClass\">\r\n {{ state.timeLeft }}\r\n </div>\r\n\r\n <div class=\"action-area\">\r\n <button *ngIf=\"state.status === 'ready'\" \r\n (click)=\"liveness.start()\"\r\n [ngClass]=\"buttonClass\">\r\n {{ startButtonLabel }}\r\n </button>\r\n \r\n <button *ngIf=\"state.status === 'error' || state.status === 'expired'\" \r\n (click)=\"liveness.reset()\"\r\n [ngClass]=\"retryButtonClass\">\r\n {{ retryButtonLabel }}\r\n </button>\r\n </div>\r\n\r\n </div>\r\n </ng-container>\r\n </div>\r\n</div>","// src/api.ts\r\n\r\nimport { Challenge } from \"./core/LivenessEngine\";\r\n\r\nexport interface LivenessResponse {\r\n is_live: boolean;\r\n reason?: string;\r\n skin_confidence?: number;\r\n [key: string]: any; // allow extra fields if backend returns more\r\n}\r\n\r\n/**\r\n * Sends captured frames to the backend API for liveness verification.\r\n * @param apiUrl - Base URL of the liveness backend\r\n * @param frameBlobs - Array of Blob objects representing captured frames\r\n * @param challenge - The current challenge string\r\n * @returns LivenessResponse from backend\r\n */\r\nexport const verifyLiveness = async (\r\n apiUrl: string,\r\n frameBlobs: Blob[],\r\n challenge: Challenge[]\r\n): Promise<LivenessResponse> => {\r\n const formData = new FormData();\r\n\r\n frameBlobs.forEach((blob, i) => {\r\n formData.append('files', blob, `frame_${i}.jpg`);\r\n });\r\n formData.append('challenge', JSON.stringify(challenge));\r\n\r\n const response = await fetch(`${apiUrl}/v1/verify`, {\r\n method: 'POST',\r\n body: formData,\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(\"Network response was not ok\");\r\n }\r\n\r\n const data: LivenessResponse = await response.json();\r\n return data;\r\n};","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.LivenessService"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LivenessEngine.d.ts","sourceRoot":"","sources":["../../src/core/LivenessEngine.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,WAAW,GAAG,WAAW,CAAC;AAEtE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IAC1F,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACjD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC9C;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,MAAM,CAA4F;IAC1G,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,KAAK,CAAgB;IAE7B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,sBAAsB,CAAS;IACvC,OAAO,CAAC,OAAO,CAA+C;IAC9D,OAAO,CAAC,SAAS,CAAuB;
|
|
1
|
+
{"version":3,"file":"LivenessEngine.d.ts","sourceRoot":"","sources":["../../src/core/LivenessEngine.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,WAAW,GAAG,WAAW,CAAC;AAEtE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IAC1F,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACjD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC9C;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,MAAM,CAA4F;IAC1G,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,KAAK,CAAgB;IAE7B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,sBAAsB,CAAS;IACvC,OAAO,CAAC,OAAO,CAA+C;IAC9D,OAAO,CAAC,SAAS,CAAuB;IAGxC,OAAO,CAAC,eAAe,CAAoC;IAC3D,OAAO,CAAC,cAAc,CAA6D;gBAEvE,MAAM,EAAE,oBAAoB;IA0BxC;;OAEG;IACU,UAAU;IAoCvB;;OAEG;IACI,WAAW,GAAI,OAAO,gBAAgB,UAG3C;IAEK,KAAK,aAWV;IAEK,IAAI,aAKT;IAEK,KAAK,aAYV;IAEF,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,UAAU,CAmBhB;IAEF,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,WAAW;YA0BL,cAAc;IAqC5B,OAAO,CAAC,WAAW;CAwBpB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@richard.fadiora/liveness-detection",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.13",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -42,26 +42,44 @@
|
|
|
42
42
|
"prepublishOnly": "npm run build"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
|
-
"@angular/common": ">=
|
|
46
|
-
"@angular/core": ">=
|
|
45
|
+
"@angular/common": ">=18.0.0",
|
|
46
|
+
"@angular/core": ">=18.0.0",
|
|
47
47
|
"@mediapipe/tasks-vision": "^0.10.0",
|
|
48
48
|
"react": ">=18.0.0 <20.0",
|
|
49
49
|
"react-dom": ">=18.0.0 <20.0",
|
|
50
|
-
"react-webcam": "
|
|
50
|
+
"react-webcam": ">=7.2.0"
|
|
51
|
+
},
|
|
52
|
+
"peerDependenciesMeta": {
|
|
53
|
+
"@angular/common": {
|
|
54
|
+
"optional": true
|
|
55
|
+
},
|
|
56
|
+
"@angular/core": {
|
|
57
|
+
"optional": true
|
|
58
|
+
},
|
|
59
|
+
"react": {
|
|
60
|
+
"optional": true
|
|
61
|
+
},
|
|
62
|
+
"react-dom": {
|
|
63
|
+
"optional": true
|
|
64
|
+
},
|
|
65
|
+
"react-webcam": {
|
|
66
|
+
"optional": true
|
|
67
|
+
}
|
|
51
68
|
},
|
|
52
69
|
"dependencies": {
|
|
53
70
|
"@mediapipe/tasks-vision": "^0.10.0",
|
|
54
|
-
"
|
|
55
|
-
"react-webcam": "^7.2.0"
|
|
71
|
+
"tslib": ">=2.3.0"
|
|
56
72
|
},
|
|
57
73
|
"devDependencies": {
|
|
58
|
-
"@
|
|
74
|
+
"@angular/common": "^18.0.0",
|
|
75
|
+
"@angular/core": "^18.0.0",
|
|
76
|
+
"@angular/compiler": "^18.0.0",
|
|
59
77
|
"@types/react": "^18.0.0",
|
|
60
78
|
"@types/react-dom": "^18.0.0",
|
|
61
|
-
"
|
|
62
|
-
"ng-packagr": "^21.2.0",
|
|
79
|
+
"ng-packagr": "^18.0.0",
|
|
63
80
|
"vite": "^5.0.0",
|
|
64
|
-
"
|
|
81
|
+
"react": "^18.0.0",
|
|
82
|
+
"react-webcam": "^7.2.0"
|
|
65
83
|
},
|
|
66
84
|
"description": "Cross-platform Liveness Detection SDK for React and Angular",
|
|
67
85
|
"keywords": [
|