smartcomply-web-sdk 1.0.49 → 1.0.51
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/dist/camera/ActionDetector.d.ts +15 -21
- package/dist/camera/ActionDetector.d.ts.map +1 -1
- package/dist/camera/ActionDetector.js +51 -104
- package/dist/camera/ActionDetector.js.map +1 -1
- package/dist/esm/camera/ActionDetector.d.ts +15 -21
- package/dist/esm/camera/ActionDetector.d.ts.map +1 -1
- package/dist/esm/camera/ActionDetector.js +51 -104
- package/dist/esm/camera/ActionDetector.js.map +1 -1
- package/dist/esm/flow/SmartComplyFlow.d.ts.map +1 -1
- package/dist/esm/flow/SmartComplyFlow.js +3 -4
- package/dist/esm/flow/SmartComplyFlow.js.map +1 -1
- package/dist/esm/modules/liveness/LivenessUI.d.ts +19 -15
- package/dist/esm/modules/liveness/LivenessUI.d.ts.map +1 -1
- package/dist/esm/modules/liveness/LivenessUI.js +99 -311
- package/dist/esm/modules/liveness/LivenessUI.js.map +1 -1
- package/dist/esm/modules/liveness/liveness.d.ts +10 -9
- package/dist/esm/modules/liveness/liveness.d.ts.map +1 -1
- package/dist/esm/modules/liveness/liveness.js +57 -104
- package/dist/esm/modules/liveness/liveness.js.map +1 -1
- package/dist/esm/utils/constants.d.ts +12 -6
- package/dist/esm/utils/constants.d.ts.map +1 -1
- package/dist/esm/utils/constants.js +13 -7
- package/dist/esm/utils/constants.js.map +1 -1
- package/dist/flow/SmartComplyFlow.d.ts.map +1 -1
- package/dist/flow/SmartComplyFlow.js +3 -4
- package/dist/flow/SmartComplyFlow.js.map +1 -1
- package/dist/modules/liveness/LivenessUI.d.ts +19 -15
- package/dist/modules/liveness/LivenessUI.d.ts.map +1 -1
- package/dist/modules/liveness/LivenessUI.js +99 -311
- package/dist/modules/liveness/LivenessUI.js.map +1 -1
- package/dist/modules/liveness/liveness.d.ts +10 -9
- package/dist/modules/liveness/liveness.d.ts.map +1 -1
- package/dist/modules/liveness/liveness.js +56 -103
- package/dist/modules/liveness/liveness.js.map +1 -1
- package/dist/smartcomply.browser.js +213 -513
- package/dist/smartcomply.browser.js.map +3 -3
- package/dist/utils/constants.d.ts +12 -6
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/constants.js +13 -7
- package/dist/utils/constants.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,28 +1,22 @@
|
|
|
1
1
|
import { FaceDetectionResult } from "./FaceDetector";
|
|
2
|
-
export interface
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
export interface ScanProgress {
|
|
3
|
+
faceDetected: boolean;
|
|
4
|
+
blinkDetected: boolean;
|
|
5
|
+
motionDetected: boolean;
|
|
6
|
+
livenessConfirmed: boolean;
|
|
7
|
+
progress: number;
|
|
7
8
|
}
|
|
8
|
-
/**
|
|
9
|
-
* Sequential action detector aligned with backend's 5 UPPERCASE actions:
|
|
10
|
-
* BLINK, TURN_LEFT, TURN_RIGHT, TURN_HEAD, OPEN_MOUTH
|
|
11
|
-
*/
|
|
12
9
|
export declare class ActionDetector {
|
|
13
|
-
private
|
|
14
|
-
private
|
|
15
|
-
private
|
|
16
|
-
private
|
|
17
|
-
|
|
18
|
-
constructor(
|
|
19
|
-
check(result: FaceDetectionResult):
|
|
20
|
-
|
|
21
|
-
private buildStates;
|
|
22
|
-
private getConfidence;
|
|
10
|
+
private blinkHoldCount;
|
|
11
|
+
private blinkDetected;
|
|
12
|
+
private motionDetected;
|
|
13
|
+
private baselineYaw;
|
|
14
|
+
/** Kept for API compatibility with callers that still pass a list in. Unused internally. */
|
|
15
|
+
constructor(_requiredActions?: string[]);
|
|
16
|
+
check(result: FaceDetectionResult): ScanProgress;
|
|
17
|
+
private buildProgress;
|
|
23
18
|
private getHeadYaw;
|
|
24
|
-
|
|
25
|
-
completedCount(): number;
|
|
19
|
+
livenessConfirmed(): boolean;
|
|
26
20
|
reset(): void;
|
|
27
21
|
}
|
|
28
22
|
//# sourceMappingURL=ActionDetector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionDetector.d.ts","sourceRoot":"","sources":["../../src/camera/ActionDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"ActionDetector.d.ts","sourceRoot":"","sources":["../../src/camera/ActionDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAsBrD,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,WAAW,CAAuB;IAE1C,4FAA4F;gBAChF,gBAAgB,CAAC,EAAE,MAAM,EAAE;IAEvC,KAAK,CAAC,MAAM,EAAE,mBAAmB,GAAG,YAAY;IA+BhD,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,UAAU;IAKlB,iBAAiB,IAAI,OAAO;IAI5B,KAAK,IAAI,IAAI;CAMd"}
|
|
@@ -2,134 +2,81 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ActionDetector = void 0;
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* - threshold : minimum confidence score required to start counting.
|
|
7
|
-
* - holdFrames: consecutive frames above threshold before action is confirmed.
|
|
5
|
+
* Passive natural-motion liveness detector.
|
|
8
6
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const DEFAULT_CONFIG = { threshold: 0.40, holdFrames: 4 };
|
|
21
|
-
/**
|
|
22
|
-
* Sequential action detector aligned with backend's 5 UPPERCASE actions:
|
|
23
|
-
* BLINK, TURN_LEFT, TURN_RIGHT, TURN_HEAD, OPEN_MOUTH
|
|
7
|
+
* Replaces the earlier sequential "do BLINK, then TURN_HEAD, then OPEN_MOUTH"
|
|
8
|
+
* choreography with a single continuous scan window: the user is simply told
|
|
9
|
+
* to "blink and look around naturally" while the detector watches for signs
|
|
10
|
+
* of a live face (a genuine blink, or natural head movement) without
|
|
11
|
+
* commanding specific actions in order. This mirrors a passive liveness scan
|
|
12
|
+
* rather than a step-by-step obstacle course.
|
|
13
|
+
*
|
|
14
|
+
* Pass criteria: at least one genuine blink OR a natural head-yaw excursion
|
|
15
|
+
* detected at any point during the window — whichever happens first, since a
|
|
16
|
+
* real person glancing around naturally will trigger one or both without
|
|
17
|
+
* being told to.
|
|
24
18
|
*/
|
|
19
|
+
const BLINK_THRESHOLD = 0.25;
|
|
20
|
+
const BLINK_HOLD_FRAMES = 2;
|
|
21
|
+
const YAW_MOTION_THRESHOLD_DEG = 6; // small natural head movement, not a commanded turn
|
|
25
22
|
class ActionDetector {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
this.
|
|
29
|
-
this.
|
|
30
|
-
this.
|
|
31
|
-
this.
|
|
23
|
+
/** Kept for API compatibility with callers that still pass a list in. Unused internally. */
|
|
24
|
+
constructor(_requiredActions) {
|
|
25
|
+
this.blinkHoldCount = 0;
|
|
26
|
+
this.blinkDetected = false;
|
|
27
|
+
this.motionDetected = false;
|
|
28
|
+
this.baselineYaw = null;
|
|
32
29
|
}
|
|
33
30
|
check(result) {
|
|
34
|
-
const currentAction = this.getCurrentAction();
|
|
35
31
|
if (!result.faceDetected) {
|
|
36
|
-
return this.
|
|
32
|
+
return this.buildProgress(false);
|
|
37
33
|
}
|
|
38
34
|
const bs = result.blendshapes;
|
|
39
|
-
|
|
40
|
-
if (
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
this.holdCounters.set(currentAction, count);
|
|
46
|
-
if (count >= cfg.holdFrames) {
|
|
47
|
-
this.completedActions.add(currentAction);
|
|
48
|
-
this.holdCounters.delete(currentAction);
|
|
35
|
+
const blinkConf = ((bs.get("eyeBlinkLeft") || 0) + (bs.get("eyeBlinkRight") || 0)) / 2;
|
|
36
|
+
if (!this.blinkDetected) {
|
|
37
|
+
if (blinkConf >= BLINK_THRESHOLD) {
|
|
38
|
+
this.blinkHoldCount++;
|
|
39
|
+
if (this.blinkHoldCount >= BLINK_HOLD_FRAMES) {
|
|
40
|
+
this.blinkDetected = true;
|
|
49
41
|
}
|
|
50
42
|
}
|
|
51
43
|
else {
|
|
52
|
-
this.
|
|
44
|
+
this.blinkHoldCount = 0;
|
|
53
45
|
}
|
|
54
|
-
return this.buildStates(currentAction, conf);
|
|
55
46
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (!this.completedActions.has(action))
|
|
61
|
-
return action;
|
|
62
|
-
}
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
buildStates(currentAction, currentConf) {
|
|
66
|
-
return this.requiredActions.map((action) => ({
|
|
67
|
-
action,
|
|
68
|
-
detected: this.completedActions.has(action),
|
|
69
|
-
active: action === currentAction,
|
|
70
|
-
confidence: action === currentAction ? currentConf : 0,
|
|
71
|
-
}));
|
|
72
|
-
}
|
|
73
|
-
getConfidence(action, bs, matrix) {
|
|
74
|
-
switch (action) {
|
|
75
|
-
case "BLINK": {
|
|
76
|
-
const left = bs.get("eyeBlinkLeft") || 0;
|
|
77
|
-
const right = bs.get("eyeBlinkRight") || 0;
|
|
78
|
-
return (left + right) / 2;
|
|
47
|
+
if (!this.motionDetected) {
|
|
48
|
+
const yaw = this.getHeadYaw(result.transformMatrix);
|
|
49
|
+
if (this.baselineYaw === null) {
|
|
50
|
+
this.baselineYaw = yaw;
|
|
79
51
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// Using absolute yaw so any head turn registers
|
|
83
|
-
const yaw = Math.abs(this.getHeadYaw(matrix));
|
|
84
|
-
return yaw > 5 ? Math.min(1, yaw / 20) : 0;
|
|
52
|
+
else if (Math.abs(yaw - this.baselineYaw) >= YAW_MOTION_THRESHOLD_DEG) {
|
|
53
|
+
this.motionDetected = true;
|
|
85
54
|
}
|
|
86
|
-
case "TURN_RIGHT": {
|
|
87
|
-
// Accept either direction — instruction is "turn sideways"
|
|
88
|
-
const yaw = Math.abs(this.getHeadYaw(matrix));
|
|
89
|
-
return yaw > 5 ? Math.min(1, yaw / 20) : 0;
|
|
90
|
-
}
|
|
91
|
-
case "TURN_HEAD": {
|
|
92
|
-
// Proper side-to-side: head must reach left AND right within the
|
|
93
|
-
// recent frame window. 0.5 when one side is seen, 1.0 when both.
|
|
94
|
-
const yaw = this.getHeadYaw(matrix);
|
|
95
|
-
this.yawHistory.push(yaw);
|
|
96
|
-
if (this.yawHistory.length > this.YAW_HISTORY_SIZE) {
|
|
97
|
-
this.yawHistory.shift();
|
|
98
|
-
}
|
|
99
|
-
if (this.yawHistory.length < this.YAW_HISTORY_SIZE) {
|
|
100
|
-
return 0;
|
|
101
|
-
}
|
|
102
|
-
const left = this.yawHistory.some((y) => y <= -10);
|
|
103
|
-
const right = this.yawHistory.some((y) => y >= 10);
|
|
104
|
-
if (left && right)
|
|
105
|
-
return 1.0;
|
|
106
|
-
if (left || right)
|
|
107
|
-
return 0.5;
|
|
108
|
-
return 0;
|
|
109
|
-
}
|
|
110
|
-
case "OPEN_MOUTH":
|
|
111
|
-
return bs.get("jawOpen") || 0;
|
|
112
|
-
default:
|
|
113
|
-
return 0;
|
|
114
55
|
}
|
|
56
|
+
return this.buildProgress(true);
|
|
57
|
+
}
|
|
58
|
+
buildProgress(faceDetected) {
|
|
59
|
+
return {
|
|
60
|
+
faceDetected,
|
|
61
|
+
blinkDetected: this.blinkDetected,
|
|
62
|
+
motionDetected: this.motionDetected,
|
|
63
|
+
livenessConfirmed: this.blinkDetected || this.motionDetected,
|
|
64
|
+
progress: 0, // caller fills in time-based progress
|
|
65
|
+
};
|
|
115
66
|
}
|
|
116
67
|
getHeadYaw(matrix) {
|
|
117
68
|
if (!matrix || matrix.length < 16)
|
|
118
69
|
return 0;
|
|
119
|
-
// 4x4 column-major matrix from MediaPipe FaceLandmarker
|
|
120
|
-
// Yaw (rotation around Y axis): atan2(-m20, m00) where m20=matrix[2], m00=matrix[0]
|
|
121
70
|
return Math.atan2(-matrix[2], matrix[0]) * (180 / Math.PI);
|
|
122
71
|
}
|
|
123
|
-
|
|
124
|
-
return this.
|
|
125
|
-
}
|
|
126
|
-
completedCount() {
|
|
127
|
-
return this.completedActions.size;
|
|
72
|
+
livenessConfirmed() {
|
|
73
|
+
return this.blinkDetected || this.motionDetected;
|
|
128
74
|
}
|
|
129
75
|
reset() {
|
|
130
|
-
this.
|
|
131
|
-
this.
|
|
132
|
-
this.
|
|
76
|
+
this.blinkHoldCount = 0;
|
|
77
|
+
this.blinkDetected = false;
|
|
78
|
+
this.motionDetected = false;
|
|
79
|
+
this.baselineYaw = null;
|
|
133
80
|
}
|
|
134
81
|
}
|
|
135
82
|
exports.ActionDetector = ActionDetector;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionDetector.js","sourceRoot":"","sources":["../../src/camera/ActionDetector.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"ActionDetector.js","sourceRoot":"","sources":["../../src/camera/ActionDetector.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,eAAe,GAAG,IAAI,CAAC;AAC7B,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B,MAAM,wBAAwB,GAAG,CAAC,CAAC,CAAC,oDAAoD;AAUxF,MAAa,cAAc;IAMzB,4FAA4F;IAC5F,YAAY,gBAA2B;QAN/B,mBAAc,GAAG,CAAC,CAAC;QACnB,kBAAa,GAAG,KAAK,CAAC;QACtB,mBAAc,GAAG,KAAK,CAAC;QACvB,gBAAW,GAAkB,IAAI,CAAC;IAGA,CAAC;IAE3C,KAAK,CAAC,MAA2B;QAC/B,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC;QAC9B,MAAM,SAAS,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAEvF,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,IAAI,SAAS,IAAI,eAAe,EAAE,CAAC;gBACjC,IAAI,CAAC,cAAc,EAAE,CAAC;gBACtB,IAAI,IAAI,CAAC,cAAc,IAAI,iBAAiB,EAAE,CAAC;oBAC7C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;gBAC5B,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;YACpD,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;gBAC9B,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;YACzB,CAAC;iBAAM,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,wBAAwB,EAAE,CAAC;gBACxE,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAEO,aAAa,CAAC,YAAqB;QACzC,OAAO;YACL,YAAY;YACZ,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,iBAAiB,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,cAAc;YAC5D,QAAQ,EAAE,CAAC,EAAE,sCAAsC;SACpD,CAAC;IACJ,CAAC;IAEO,UAAU,CAAC,MAAuB;QACxC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,EAAE;YAAE,OAAO,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,cAAc,CAAC;IACnD,CAAC;IAED,KAAK;QACH,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC1B,CAAC;CACF;AAjED,wCAiEC"}
|
|
@@ -1,28 +1,22 @@
|
|
|
1
1
|
import { FaceDetectionResult } from "./FaceDetector";
|
|
2
|
-
export interface
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
export interface ScanProgress {
|
|
3
|
+
faceDetected: boolean;
|
|
4
|
+
blinkDetected: boolean;
|
|
5
|
+
motionDetected: boolean;
|
|
6
|
+
livenessConfirmed: boolean;
|
|
7
|
+
progress: number;
|
|
7
8
|
}
|
|
8
|
-
/**
|
|
9
|
-
* Sequential action detector aligned with backend's 5 UPPERCASE actions:
|
|
10
|
-
* BLINK, TURN_LEFT, TURN_RIGHT, TURN_HEAD, OPEN_MOUTH
|
|
11
|
-
*/
|
|
12
9
|
export declare class ActionDetector {
|
|
13
|
-
private
|
|
14
|
-
private
|
|
15
|
-
private
|
|
16
|
-
private
|
|
17
|
-
|
|
18
|
-
constructor(
|
|
19
|
-
check(result: FaceDetectionResult):
|
|
20
|
-
|
|
21
|
-
private buildStates;
|
|
22
|
-
private getConfidence;
|
|
10
|
+
private blinkHoldCount;
|
|
11
|
+
private blinkDetected;
|
|
12
|
+
private motionDetected;
|
|
13
|
+
private baselineYaw;
|
|
14
|
+
/** Kept for API compatibility with callers that still pass a list in. Unused internally. */
|
|
15
|
+
constructor(_requiredActions?: string[]);
|
|
16
|
+
check(result: FaceDetectionResult): ScanProgress;
|
|
17
|
+
private buildProgress;
|
|
23
18
|
private getHeadYaw;
|
|
24
|
-
|
|
25
|
-
completedCount(): number;
|
|
19
|
+
livenessConfirmed(): boolean;
|
|
26
20
|
reset(): void;
|
|
27
21
|
}
|
|
28
22
|
//# sourceMappingURL=ActionDetector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionDetector.d.ts","sourceRoot":"","sources":["../../../src/camera/ActionDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"ActionDetector.d.ts","sourceRoot":"","sources":["../../../src/camera/ActionDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAsBrD,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,WAAW,CAAuB;IAE1C,4FAA4F;gBAChF,gBAAgB,CAAC,EAAE,MAAM,EAAE;IAEvC,KAAK,CAAC,MAAM,EAAE,mBAAmB,GAAG,YAAY;IA+BhD,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,UAAU;IAKlB,iBAAiB,IAAI,OAAO;IAI5B,KAAK,IAAI,IAAI;CAMd"}
|
|
@@ -1,132 +1,79 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* - threshold : minimum confidence score required to start counting.
|
|
4
|
-
* - holdFrames: consecutive frames above threshold before action is confirmed.
|
|
2
|
+
* Passive natural-motion liveness detector.
|
|
5
3
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const DEFAULT_CONFIG = { threshold: 0.40, holdFrames: 4 };
|
|
18
|
-
/**
|
|
19
|
-
* Sequential action detector aligned with backend's 5 UPPERCASE actions:
|
|
20
|
-
* BLINK, TURN_LEFT, TURN_RIGHT, TURN_HEAD, OPEN_MOUTH
|
|
4
|
+
* Replaces the earlier sequential "do BLINK, then TURN_HEAD, then OPEN_MOUTH"
|
|
5
|
+
* choreography with a single continuous scan window: the user is simply told
|
|
6
|
+
* to "blink and look around naturally" while the detector watches for signs
|
|
7
|
+
* of a live face (a genuine blink, or natural head movement) without
|
|
8
|
+
* commanding specific actions in order. This mirrors a passive liveness scan
|
|
9
|
+
* rather than a step-by-step obstacle course.
|
|
10
|
+
*
|
|
11
|
+
* Pass criteria: at least one genuine blink OR a natural head-yaw excursion
|
|
12
|
+
* detected at any point during the window — whichever happens first, since a
|
|
13
|
+
* real person glancing around naturally will trigger one or both without
|
|
14
|
+
* being told to.
|
|
21
15
|
*/
|
|
16
|
+
const BLINK_THRESHOLD = 0.25;
|
|
17
|
+
const BLINK_HOLD_FRAMES = 2;
|
|
18
|
+
const YAW_MOTION_THRESHOLD_DEG = 6; // small natural head movement, not a commanded turn
|
|
22
19
|
export class ActionDetector {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
this.
|
|
26
|
-
this.
|
|
27
|
-
this.
|
|
28
|
-
this.
|
|
20
|
+
/** Kept for API compatibility with callers that still pass a list in. Unused internally. */
|
|
21
|
+
constructor(_requiredActions) {
|
|
22
|
+
this.blinkHoldCount = 0;
|
|
23
|
+
this.blinkDetected = false;
|
|
24
|
+
this.motionDetected = false;
|
|
25
|
+
this.baselineYaw = null;
|
|
29
26
|
}
|
|
30
27
|
check(result) {
|
|
31
|
-
const currentAction = this.getCurrentAction();
|
|
32
28
|
if (!result.faceDetected) {
|
|
33
|
-
return this.
|
|
29
|
+
return this.buildProgress(false);
|
|
34
30
|
}
|
|
35
31
|
const bs = result.blendshapes;
|
|
36
|
-
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
this.holdCounters.set(currentAction, count);
|
|
43
|
-
if (count >= cfg.holdFrames) {
|
|
44
|
-
this.completedActions.add(currentAction);
|
|
45
|
-
this.holdCounters.delete(currentAction);
|
|
32
|
+
const blinkConf = ((bs.get("eyeBlinkLeft") || 0) + (bs.get("eyeBlinkRight") || 0)) / 2;
|
|
33
|
+
if (!this.blinkDetected) {
|
|
34
|
+
if (blinkConf >= BLINK_THRESHOLD) {
|
|
35
|
+
this.blinkHoldCount++;
|
|
36
|
+
if (this.blinkHoldCount >= BLINK_HOLD_FRAMES) {
|
|
37
|
+
this.blinkDetected = true;
|
|
46
38
|
}
|
|
47
39
|
}
|
|
48
40
|
else {
|
|
49
|
-
this.
|
|
41
|
+
this.blinkHoldCount = 0;
|
|
50
42
|
}
|
|
51
|
-
return this.buildStates(currentAction, conf);
|
|
52
43
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (!this.completedActions.has(action))
|
|
58
|
-
return action;
|
|
59
|
-
}
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
buildStates(currentAction, currentConf) {
|
|
63
|
-
return this.requiredActions.map((action) => ({
|
|
64
|
-
action,
|
|
65
|
-
detected: this.completedActions.has(action),
|
|
66
|
-
active: action === currentAction,
|
|
67
|
-
confidence: action === currentAction ? currentConf : 0,
|
|
68
|
-
}));
|
|
69
|
-
}
|
|
70
|
-
getConfidence(action, bs, matrix) {
|
|
71
|
-
switch (action) {
|
|
72
|
-
case "BLINK": {
|
|
73
|
-
const left = bs.get("eyeBlinkLeft") || 0;
|
|
74
|
-
const right = bs.get("eyeBlinkRight") || 0;
|
|
75
|
-
return (left + right) / 2;
|
|
44
|
+
if (!this.motionDetected) {
|
|
45
|
+
const yaw = this.getHeadYaw(result.transformMatrix);
|
|
46
|
+
if (this.baselineYaw === null) {
|
|
47
|
+
this.baselineYaw = yaw;
|
|
76
48
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
// Using absolute yaw so any head turn registers
|
|
80
|
-
const yaw = Math.abs(this.getHeadYaw(matrix));
|
|
81
|
-
return yaw > 5 ? Math.min(1, yaw / 20) : 0;
|
|
49
|
+
else if (Math.abs(yaw - this.baselineYaw) >= YAW_MOTION_THRESHOLD_DEG) {
|
|
50
|
+
this.motionDetected = true;
|
|
82
51
|
}
|
|
83
|
-
case "TURN_RIGHT": {
|
|
84
|
-
// Accept either direction — instruction is "turn sideways"
|
|
85
|
-
const yaw = Math.abs(this.getHeadYaw(matrix));
|
|
86
|
-
return yaw > 5 ? Math.min(1, yaw / 20) : 0;
|
|
87
|
-
}
|
|
88
|
-
case "TURN_HEAD": {
|
|
89
|
-
// Proper side-to-side: head must reach left AND right within the
|
|
90
|
-
// recent frame window. 0.5 when one side is seen, 1.0 when both.
|
|
91
|
-
const yaw = this.getHeadYaw(matrix);
|
|
92
|
-
this.yawHistory.push(yaw);
|
|
93
|
-
if (this.yawHistory.length > this.YAW_HISTORY_SIZE) {
|
|
94
|
-
this.yawHistory.shift();
|
|
95
|
-
}
|
|
96
|
-
if (this.yawHistory.length < this.YAW_HISTORY_SIZE) {
|
|
97
|
-
return 0;
|
|
98
|
-
}
|
|
99
|
-
const left = this.yawHistory.some((y) => y <= -10);
|
|
100
|
-
const right = this.yawHistory.some((y) => y >= 10);
|
|
101
|
-
if (left && right)
|
|
102
|
-
return 1.0;
|
|
103
|
-
if (left || right)
|
|
104
|
-
return 0.5;
|
|
105
|
-
return 0;
|
|
106
|
-
}
|
|
107
|
-
case "OPEN_MOUTH":
|
|
108
|
-
return bs.get("jawOpen") || 0;
|
|
109
|
-
default:
|
|
110
|
-
return 0;
|
|
111
52
|
}
|
|
53
|
+
return this.buildProgress(true);
|
|
54
|
+
}
|
|
55
|
+
buildProgress(faceDetected) {
|
|
56
|
+
return {
|
|
57
|
+
faceDetected,
|
|
58
|
+
blinkDetected: this.blinkDetected,
|
|
59
|
+
motionDetected: this.motionDetected,
|
|
60
|
+
livenessConfirmed: this.blinkDetected || this.motionDetected,
|
|
61
|
+
progress: 0, // caller fills in time-based progress
|
|
62
|
+
};
|
|
112
63
|
}
|
|
113
64
|
getHeadYaw(matrix) {
|
|
114
65
|
if (!matrix || matrix.length < 16)
|
|
115
66
|
return 0;
|
|
116
|
-
// 4x4 column-major matrix from MediaPipe FaceLandmarker
|
|
117
|
-
// Yaw (rotation around Y axis): atan2(-m20, m00) where m20=matrix[2], m00=matrix[0]
|
|
118
67
|
return Math.atan2(-matrix[2], matrix[0]) * (180 / Math.PI);
|
|
119
68
|
}
|
|
120
|
-
|
|
121
|
-
return this.
|
|
122
|
-
}
|
|
123
|
-
completedCount() {
|
|
124
|
-
return this.completedActions.size;
|
|
69
|
+
livenessConfirmed() {
|
|
70
|
+
return this.blinkDetected || this.motionDetected;
|
|
125
71
|
}
|
|
126
72
|
reset() {
|
|
127
|
-
this.
|
|
128
|
-
this.
|
|
129
|
-
this.
|
|
73
|
+
this.blinkHoldCount = 0;
|
|
74
|
+
this.blinkDetected = false;
|
|
75
|
+
this.motionDetected = false;
|
|
76
|
+
this.baselineYaw = null;
|
|
130
77
|
}
|
|
131
78
|
}
|
|
132
79
|
//# sourceMappingURL=ActionDetector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionDetector.js","sourceRoot":"","sources":["../../../src/camera/ActionDetector.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ActionDetector.js","sourceRoot":"","sources":["../../../src/camera/ActionDetector.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,eAAe,GAAG,IAAI,CAAC;AAC7B,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B,MAAM,wBAAwB,GAAG,CAAC,CAAC,CAAC,oDAAoD;AAUxF,MAAM,OAAO,cAAc;IAMzB,4FAA4F;IAC5F,YAAY,gBAA2B;QAN/B,mBAAc,GAAG,CAAC,CAAC;QACnB,kBAAa,GAAG,KAAK,CAAC;QACtB,mBAAc,GAAG,KAAK,CAAC;QACvB,gBAAW,GAAkB,IAAI,CAAC;IAGA,CAAC;IAE3C,KAAK,CAAC,MAA2B;QAC/B,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC;QAC9B,MAAM,SAAS,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAEvF,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,IAAI,SAAS,IAAI,eAAe,EAAE,CAAC;gBACjC,IAAI,CAAC,cAAc,EAAE,CAAC;gBACtB,IAAI,IAAI,CAAC,cAAc,IAAI,iBAAiB,EAAE,CAAC;oBAC7C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;gBAC5B,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;YACpD,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;gBAC9B,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;YACzB,CAAC;iBAAM,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,wBAAwB,EAAE,CAAC;gBACxE,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAEO,aAAa,CAAC,YAAqB;QACzC,OAAO;YACL,YAAY;YACZ,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,iBAAiB,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,cAAc;YAC5D,QAAQ,EAAE,CAAC,EAAE,sCAAsC;SACpD,CAAC;IACJ,CAAC;IAEO,UAAU,CAAC,MAAuB;QACxC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,EAAE;YAAE,OAAO,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,cAAc,CAAC;IACnD,CAAC;IAED,KAAK;QACH,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC1B,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SmartComplyFlow.d.ts","sourceRoot":"","sources":["../../../src/flow/SmartComplyFlow.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"SmartComplyFlow.d.ts","sourceRoot":"","sources":["../../../src/flow/SmartComplyFlow.ts"],"names":[],"mappings":"AACA,OAAO,EAA6B,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAIxF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAO/C,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IAC1C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;CAC7C;AA2RD,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAc;IACzB,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,KAAK,CAAoC;IAGjD,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,UAAU,CAA+B;IAGjD,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,eAAe,CAAc;IACrC,OAAO,CAAC,iBAAiB,CAAa;IACtC,OAAO,CAAC,qBAAqB,CAA6D;IAC1F,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,kBAAkB,CAAc;IACxC,OAAO,CAAC,oBAAoB,CAAkC;IAC9D,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,gBAAgB,CAAqB;IAC7C,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,kBAAkB,CAAuC;IACjE,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,aAAa,CAAkC;IAGvD,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAK;IAGxC,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,UAAU,CAAc;IAGhC,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,UAAU,CAAc;IAChC,OAAO,CAAC,gBAAgB,CAAc;IACtC,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,cAAc,CAAkB;IAGxC,OAAO,CAAC,gBAAgB,CAA4B;IAGpD,OAAO,CAAC,aAAa,CAA8C;IAGnE,OAAO,CAAC,YAAY,CAA8C;IAGlE,OAAO,CAAC,kBAAkB,CAA8C;IAGxE,OAAO,CAAC,gBAAgB,CAA8C;IAGtE,OAAO,CAAC,UAAU,CAAgC;IAElD,OAAO;IAUP;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,eAAe;IAOlD;;OAEG;IACH,KAAK,IAAI,IAAI;IA8Cb,OAAO,CAAC,KAAK;YAyEC,UAAU;IA8CxB,OAAO,CAAC,QAAQ;IAmChB,OAAO,CAAC,UAAU;IA6DlB,OAAO,CAAC,aAAa;IAqCrB,OAAO,CAAC,aAAa;IA0IrB,OAAO,CAAC,mBAAmB;IAoC3B,OAAO,CAAC,kBAAkB;IAoF1B,OAAO,CAAC,aAAa;IA4VrB,OAAO,CAAC,qBAAqB;IAqD7B,OAAO,CAAC,qBAAqB;IA+E7B,OAAO,CAAC,qBAAqB;IAsG7B,OAAO,CAAC,aAAa;IAyGrB,OAAO,CAAC,sBAAsB;IAyB9B,OAAO,CAAC,qBAAqB;IA6B7B,OAAO,CAAC,UAAU;IA+ClB,OAAO,CAAC,wBAAwB;IAqBhC,OAAO,CAAC,cAAc;IAUtB;;OAEG;YACW,4BAA4B;IAgB1C;;OAEG;YACW,mBAAmB;IAqHjC,OAAO,CAAC,6BAA6B;IA8DrC,OAAO,CAAC,cAAc;IAgFtB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,aAAa;IA8FrB,OAAO,CAAC,YAAY;IAmGpB,OAAO,CAAC,YAAY;IAoBpB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,gBAAgB;IAkDxB,OAAO,CAAC,mBAAmB;IAsB3B,OAAO,CAAC,qBAAqB;IAmB7B,OAAO,CAAC,cAAc;IAgBtB,OAAO,CAAC,cAAc;IAkFtB,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,YAAY;CAoCrB"}
|
|
@@ -1504,10 +1504,9 @@ export class SmartComplyFlow {
|
|
|
1504
1504
|
title.style.cssText = `color:${this.theme.text};font-size:22px;font-weight:700;margin:0;`;
|
|
1505
1505
|
title.textContent = "You're all done!";
|
|
1506
1506
|
container.appendChild(title);
|
|
1507
|
-
const brandName = this.sdkConfig?.brand_name || "the service";
|
|
1508
1507
|
const desc = document.createElement("p");
|
|
1509
1508
|
desc.style.cssText = `color:${this.theme.textSecondary};font-size:14px;line-height:1.6;margin:0;max-width:300px;`;
|
|
1510
|
-
desc.textContent =
|
|
1509
|
+
desc.textContent = "Your verification is complete.";
|
|
1511
1510
|
container.appendChild(desc);
|
|
1512
1511
|
// Subtle info line
|
|
1513
1512
|
const info = document.createElement("div");
|
|
@@ -1614,7 +1613,7 @@ export class SmartComplyFlow {
|
|
|
1614
1613
|
identifier,
|
|
1615
1614
|
identifier_type: this.selectedIdType,
|
|
1616
1615
|
country,
|
|
1617
|
-
challenge_actions: ["BLINK"
|
|
1616
|
+
challenge_actions: ["BLINK"],
|
|
1618
1617
|
document: blob,
|
|
1619
1618
|
document_back: this.documentBackBlob || undefined,
|
|
1620
1619
|
device_type: deviceMeta.device_type,
|
|
@@ -1787,7 +1786,7 @@ export class SmartComplyFlow {
|
|
|
1787
1786
|
: "liveness_only",
|
|
1788
1787
|
// B4: pass pre-warmed stream so camera.open() is skipped
|
|
1789
1788
|
prewarmedStream: this._prewarmedStream || undefined,
|
|
1790
|
-
}, ["BLINK"
|
|
1789
|
+
}, ["BLINK"], this.livenessEntryId || undefined)
|
|
1791
1790
|
.then((result) => {
|
|
1792
1791
|
// W11: After submit, end user is done — show "You're all done" screen.
|
|
1793
1792
|
// Backend processing continues in background; client receives webhook.
|