@moveris/shared 2.9.0 → 3.1.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 +147 -17
- package/dist/index.d.mts +38 -1
- package/dist/index.d.ts +38 -1
- package/dist/index.js +169 -46
- package/dist/index.mjs +167 -46
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -35,7 +35,8 @@ var FRAME_BUFFER_CONFIG = {
|
|
|
35
35
|
var AUTH_CONFIG = {
|
|
36
36
|
timeout: 3e4,
|
|
37
37
|
// 30 seconds for API requests
|
|
38
|
-
apiKeyHeader: "X-API-Key"
|
|
38
|
+
apiKeyHeader: "X-API-Key",
|
|
39
|
+
modelVersionHeader: "X-Model-Version"
|
|
39
40
|
};
|
|
40
41
|
var FRAME_CONFIG = {
|
|
41
42
|
targetFPS: 30,
|
|
@@ -164,14 +165,22 @@ var LivenessClient = class _LivenessClient {
|
|
|
164
165
|
constructor(config) {
|
|
165
166
|
this.baseUrl = (config.baseUrl ?? DEFAULT_ENDPOINT).replace(/\/$/, "");
|
|
166
167
|
this.apiKey = config.apiKey;
|
|
168
|
+
this.modelVersion = config.modelVersion;
|
|
167
169
|
this.timeout = config.timeout ?? AUTH_CONFIG.timeout;
|
|
168
170
|
this.enableRetry = config.enableRetry ?? true;
|
|
169
171
|
this.fetchFn = config.customFetch ?? (typeof window !== "undefined" ? fetch.bind(window) : fetch);
|
|
170
172
|
}
|
|
171
173
|
/**
|
|
172
|
-
* Make an authenticated API request
|
|
174
|
+
* Make an authenticated API request, returning the parsed body.
|
|
173
175
|
*/
|
|
174
176
|
async request(path, options = {}) {
|
|
177
|
+
const { data } = await this.requestRaw(path, options);
|
|
178
|
+
return data;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Make an authenticated API request, returning both parsed body and headers.
|
|
182
|
+
*/
|
|
183
|
+
async requestRaw(path, options = {}) {
|
|
175
184
|
const url = `${this.baseUrl}${path}`;
|
|
176
185
|
const controller = new AbortController();
|
|
177
186
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
@@ -189,7 +198,8 @@ var LivenessClient = class _LivenessClient {
|
|
|
189
198
|
if (!response.ok) {
|
|
190
199
|
throw await this.parseErrorResponse(response);
|
|
191
200
|
}
|
|
192
|
-
|
|
201
|
+
const data = await response.json();
|
|
202
|
+
return { data, headers: response.headers };
|
|
193
203
|
} catch (error) {
|
|
194
204
|
clearTimeout(timeoutId);
|
|
195
205
|
if (error instanceof LivenessApiError) {
|
|
@@ -274,6 +284,30 @@ var LivenessClient = class _LivenessClient {
|
|
|
274
284
|
const match = /'error'\s*:\s*'([^']+)'/.exec(text) ?? /"error"\s*:\s*"([^"]+)"/.exec(text);
|
|
275
285
|
return match?.[1] ?? null;
|
|
276
286
|
}
|
|
287
|
+
/**
|
|
288
|
+
* Parse deprecation-related headers from an API response.
|
|
289
|
+
* Returns undefined when no deprecation info is present.
|
|
290
|
+
*/
|
|
291
|
+
static parseDeprecationHeaders(headers) {
|
|
292
|
+
const resolved = headers.get("x-moveris-model-resolved");
|
|
293
|
+
if (!resolved) return void 0;
|
|
294
|
+
const deprecated = headers.get("deprecation") === "true";
|
|
295
|
+
return {
|
|
296
|
+
deprecated,
|
|
297
|
+
resolvedModel: resolved,
|
|
298
|
+
deprecatedModel: headers.get("x-moveris-deprecated-model") ?? void 0,
|
|
299
|
+
sunsetDate: headers.get("sunset") ?? void 0,
|
|
300
|
+
suggestedModel: headers.get("x-moveris-suggested-model") ?? void 0
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Build extra request headers for model versioning.
|
|
305
|
+
*/
|
|
306
|
+
buildModelVersionHeaders(modelVersion) {
|
|
307
|
+
const version = modelVersion ?? this.modelVersion;
|
|
308
|
+
if (!version) return {};
|
|
309
|
+
return { [AUTH_CONFIG.modelVersionHeader]: version };
|
|
310
|
+
}
|
|
277
311
|
/**
|
|
278
312
|
* Make a request with optional retry
|
|
279
313
|
*/
|
|
@@ -288,6 +322,20 @@ var LivenessClient = class _LivenessClient {
|
|
|
288
322
|
}
|
|
289
323
|
return this.request(path, options);
|
|
290
324
|
}
|
|
325
|
+
/**
|
|
326
|
+
* Make a request with optional retry, returning both data and headers.
|
|
327
|
+
*/
|
|
328
|
+
async requestWithRetryRaw(path, options = {}) {
|
|
329
|
+
if (this.enableRetry) {
|
|
330
|
+
return retryWithBackoff(() => this.requestRaw(path, options), {
|
|
331
|
+
maxAttempts: RETRY_CONFIG.maxAttempts,
|
|
332
|
+
initialDelay: RETRY_CONFIG.initialDelay,
|
|
333
|
+
maxDelay: RETRY_CONFIG.maxDelay,
|
|
334
|
+
backoffMultiplier: RETRY_CONFIG.backoffMultiplier
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
return this.requestRaw(path, options);
|
|
338
|
+
}
|
|
291
339
|
// ===========================================================================
|
|
292
340
|
// Health & Status
|
|
293
341
|
// ===========================================================================
|
|
@@ -322,18 +370,31 @@ var LivenessClient = class _LivenessClient {
|
|
|
322
370
|
* @returns Liveness result
|
|
323
371
|
*/
|
|
324
372
|
async fastCheck(frames, options = {}) {
|
|
373
|
+
const effectiveVersion = options.modelVersion ?? this.modelVersion;
|
|
325
374
|
const request = {
|
|
326
375
|
session_id: options.sessionId ?? generateSessionId(),
|
|
327
376
|
model: options.model ?? "10",
|
|
328
377
|
source: options.source ?? "live",
|
|
329
378
|
frames: toFrameData(frames),
|
|
379
|
+
...options.frameCount != null ? { frame_count: options.frameCount } : {},
|
|
330
380
|
...options.warnings?.length ? { warnings: options.warnings } : {}
|
|
331
381
|
};
|
|
332
|
-
const response = await this.
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
382
|
+
const { data: response, headers } = await this.requestWithRetryRaw(
|
|
383
|
+
API_PATHS.fastCheck,
|
|
384
|
+
{
|
|
385
|
+
method: "POST",
|
|
386
|
+
body: JSON.stringify(request),
|
|
387
|
+
headers: this.buildModelVersionHeaders(effectiveVersion)
|
|
388
|
+
}
|
|
389
|
+
);
|
|
390
|
+
const result = toLivenessResult(response);
|
|
391
|
+
result.deprecation = _LivenessClient.parseDeprecationHeaders(headers);
|
|
392
|
+
if (result.deprecation?.deprecated) {
|
|
393
|
+
console.warn(
|
|
394
|
+
`[Moveris] Model "${result.deprecation.resolvedModel}" is deprecated.` + (result.deprecation.suggestedModel ? ` Migrate to "${result.deprecation.suggestedModel}".` : "") + (result.deprecation.sunsetDate ? ` Sunset date: ${result.deprecation.sunsetDate}.` : "")
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
return result;
|
|
337
398
|
}
|
|
338
399
|
/**
|
|
339
400
|
* Perform fast liveness check with pre-cropped face images
|
|
@@ -343,19 +404,32 @@ var LivenessClient = class _LivenessClient {
|
|
|
343
404
|
* @returns Liveness result
|
|
344
405
|
*/
|
|
345
406
|
async fastCheckCrops(crops, options = {}) {
|
|
407
|
+
const effectiveVersion = options.modelVersion ?? this.modelVersion;
|
|
346
408
|
const request = {
|
|
347
409
|
session_id: options.sessionId ?? generateSessionId(),
|
|
348
410
|
model: options.model ?? "10",
|
|
349
411
|
source: options.source ?? "live",
|
|
350
412
|
crops,
|
|
413
|
+
...options.frameCount != null ? { frame_count: options.frameCount } : {},
|
|
351
414
|
...options.warnings?.length ? { warnings: options.warnings } : {},
|
|
352
415
|
...options.bgSegmentation !== void 0 ? { bg_segmentation: options.bgSegmentation } : {}
|
|
353
416
|
};
|
|
354
|
-
const response = await this.
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
417
|
+
const { data: response, headers } = await this.requestWithRetryRaw(
|
|
418
|
+
API_PATHS.fastCheckCrops,
|
|
419
|
+
{
|
|
420
|
+
method: "POST",
|
|
421
|
+
body: JSON.stringify(request),
|
|
422
|
+
headers: this.buildModelVersionHeaders(effectiveVersion)
|
|
423
|
+
}
|
|
424
|
+
);
|
|
425
|
+
const result = toLivenessResult(response);
|
|
426
|
+
result.deprecation = _LivenessClient.parseDeprecationHeaders(headers);
|
|
427
|
+
if (result.deprecation?.deprecated) {
|
|
428
|
+
console.warn(
|
|
429
|
+
`[Moveris] Model "${result.deprecation.resolvedModel}" is deprecated.` + (result.deprecation.suggestedModel ? ` Migrate to "${result.deprecation.suggestedModel}".` : "") + (result.deprecation.sunsetDate ? ` Sunset date: ${result.deprecation.sunsetDate}.` : "")
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
return result;
|
|
359
433
|
}
|
|
360
434
|
/**
|
|
361
435
|
* Send a single captured frame to the streaming endpoint.
|
|
@@ -383,28 +457,29 @@ var LivenessClient = class _LivenessClient {
|
|
|
383
457
|
return this.sendStreamFrameInternal(frameData, {
|
|
384
458
|
sessionId: options.sessionId,
|
|
385
459
|
model: options.model ?? "10",
|
|
460
|
+
modelVersion: options.modelVersion,
|
|
461
|
+
frameCount: options.frameCount,
|
|
386
462
|
source: options.source ?? "live",
|
|
387
463
|
warnings: options.warnings
|
|
388
464
|
});
|
|
389
465
|
}
|
|
390
466
|
/**
|
|
391
467
|
* Send a single FrameData to the streaming endpoint with retry (internal)
|
|
392
|
-
*
|
|
393
|
-
* @param frame - Single frame to send
|
|
394
|
-
* @param options - Session and model options
|
|
395
|
-
* @returns Stream response with status
|
|
396
468
|
*/
|
|
397
469
|
async sendStreamFrameInternal(frameData, options) {
|
|
470
|
+
const effectiveVersion = options.modelVersion ?? this.modelVersion;
|
|
398
471
|
const request = {
|
|
399
472
|
session_id: options.sessionId,
|
|
400
473
|
model: options.model,
|
|
401
474
|
source: options.source,
|
|
402
475
|
frame: frameData,
|
|
476
|
+
...options.frameCount != null ? { frame_count: options.frameCount } : {},
|
|
403
477
|
...options.warnings?.length ? { warnings: options.warnings } : {}
|
|
404
478
|
};
|
|
405
479
|
return this.requestWithRetry(API_PATHS.fastCheckStream, {
|
|
406
480
|
method: "POST",
|
|
407
|
-
body: JSON.stringify(request)
|
|
481
|
+
body: JSON.stringify(request),
|
|
482
|
+
headers: this.buildModelVersionHeaders(effectiveVersion)
|
|
408
483
|
});
|
|
409
484
|
}
|
|
410
485
|
/**
|
|
@@ -429,6 +504,8 @@ var LivenessClient = class _LivenessClient {
|
|
|
429
504
|
const response = await this.sendStreamFrameInternal(frameData, {
|
|
430
505
|
sessionId,
|
|
431
506
|
model,
|
|
507
|
+
modelVersion: options.modelVersion,
|
|
508
|
+
frameCount: options.frameCount,
|
|
432
509
|
source,
|
|
433
510
|
warnings: options.warnings
|
|
434
511
|
});
|
|
@@ -479,6 +556,8 @@ var LivenessClient = class _LivenessClient {
|
|
|
479
556
|
const response = await this.sendStreamFrameInternal(frameData, {
|
|
480
557
|
sessionId,
|
|
481
558
|
model,
|
|
559
|
+
modelVersion: options.modelVersion,
|
|
560
|
+
frameCount: options.frameCount,
|
|
482
561
|
source,
|
|
483
562
|
warnings: options.warnings
|
|
484
563
|
});
|
|
@@ -755,6 +834,7 @@ var FrameQueue = class {
|
|
|
755
834
|
};
|
|
756
835
|
|
|
757
836
|
// src/types/models.ts
|
|
837
|
+
var VALID_FRAME_COUNTS = [10, 30, 60, 90, 120];
|
|
758
838
|
var MODEL_CONFIGS = {
|
|
759
839
|
// Standard fast-check models
|
|
760
840
|
"10": {
|
|
@@ -762,21 +842,24 @@ var MODEL_CONFIGS = {
|
|
|
762
842
|
minFrames: 10,
|
|
763
843
|
recommendedFrames: 10,
|
|
764
844
|
description: "Fast model - 10 frames, quick verification",
|
|
765
|
-
deprecated: false
|
|
845
|
+
deprecated: false,
|
|
846
|
+
aliases: ["fast"]
|
|
766
847
|
},
|
|
767
848
|
"50": {
|
|
768
849
|
type: "50",
|
|
769
850
|
minFrames: 50,
|
|
770
851
|
recommendedFrames: 50,
|
|
771
852
|
description: "Balanced model - 50 frames, good accuracy",
|
|
772
|
-
deprecated: false
|
|
853
|
+
deprecated: false,
|
|
854
|
+
aliases: ["spatial"]
|
|
773
855
|
},
|
|
774
856
|
"250": {
|
|
775
857
|
type: "250",
|
|
776
858
|
minFrames: 250,
|
|
777
859
|
recommendedFrames: 250,
|
|
778
860
|
description: "High-accuracy model - 250 frames, best accuracy",
|
|
779
|
-
deprecated: false
|
|
861
|
+
deprecated: false,
|
|
862
|
+
aliases: ["spatial"]
|
|
780
863
|
},
|
|
781
864
|
// Hybrid V2 models with physiological features
|
|
782
865
|
"hybrid-v2-10": {
|
|
@@ -784,63 +867,72 @@ var MODEL_CONFIGS = {
|
|
|
784
867
|
minFrames: 10,
|
|
785
868
|
recommendedFrames: 10,
|
|
786
869
|
description: "Hybrid V2 10-frame model with physio features",
|
|
787
|
-
deprecated: false
|
|
870
|
+
deprecated: false,
|
|
871
|
+
aliases: ["hybrid"]
|
|
788
872
|
},
|
|
789
873
|
"hybrid-v2-30": {
|
|
790
874
|
type: "hybrid-v2-30",
|
|
791
875
|
minFrames: 30,
|
|
792
876
|
recommendedFrames: 30,
|
|
793
877
|
description: "Hybrid V2 30-frame model with physio features",
|
|
794
|
-
deprecated: false
|
|
878
|
+
deprecated: false,
|
|
879
|
+
aliases: ["hybrid"]
|
|
795
880
|
},
|
|
796
881
|
"hybrid-v2-50": {
|
|
797
882
|
type: "hybrid-v2-50",
|
|
798
883
|
minFrames: 50,
|
|
799
884
|
recommendedFrames: 50,
|
|
800
885
|
description: "Hybrid V2 50-frame model with physio features",
|
|
801
|
-
deprecated: false
|
|
886
|
+
deprecated: false,
|
|
887
|
+
aliases: ["hybrid"]
|
|
802
888
|
},
|
|
803
889
|
"hybrid-v2-60": {
|
|
804
890
|
type: "hybrid-v2-60",
|
|
805
891
|
minFrames: 60,
|
|
806
892
|
recommendedFrames: 60,
|
|
807
893
|
description: "Hybrid V2 60-frame model with physio features",
|
|
808
|
-
deprecated: false
|
|
894
|
+
deprecated: false,
|
|
895
|
+
aliases: ["hybrid"]
|
|
809
896
|
},
|
|
810
897
|
"hybrid-v2-90": {
|
|
811
898
|
type: "hybrid-v2-90",
|
|
812
899
|
minFrames: 90,
|
|
813
900
|
recommendedFrames: 90,
|
|
814
901
|
description: "Hybrid V2 90-frame model with physio features",
|
|
815
|
-
deprecated: false
|
|
902
|
+
deprecated: false,
|
|
903
|
+
aliases: ["hybrid"]
|
|
816
904
|
},
|
|
817
905
|
"hybrid-v2-100": {
|
|
818
906
|
type: "hybrid-v2-100",
|
|
819
907
|
minFrames: 100,
|
|
820
908
|
recommendedFrames: 100,
|
|
821
909
|
description: "Hybrid V2 100-frame model with physio features",
|
|
822
|
-
deprecated: false
|
|
910
|
+
deprecated: false,
|
|
911
|
+
aliases: ["hybrid"]
|
|
823
912
|
},
|
|
824
913
|
"hybrid-v2-125": {
|
|
825
914
|
type: "hybrid-v2-125",
|
|
826
915
|
minFrames: 125,
|
|
827
916
|
recommendedFrames: 125,
|
|
828
917
|
description: "Hybrid V2 125-frame model with physio features",
|
|
829
|
-
deprecated: false
|
|
918
|
+
deprecated: false,
|
|
919
|
+
aliases: ["hybrid"]
|
|
830
920
|
},
|
|
831
921
|
"hybrid-v2-150": {
|
|
832
922
|
type: "hybrid-v2-150",
|
|
833
923
|
minFrames: 150,
|
|
834
924
|
recommendedFrames: 150,
|
|
835
925
|
description: "Hybrid V2 150-frame model with physio features",
|
|
836
|
-
deprecated: false
|
|
926
|
+
deprecated: false,
|
|
927
|
+
aliases: ["hybrid"]
|
|
837
928
|
},
|
|
838
929
|
"hybrid-v2-250": {
|
|
839
930
|
type: "hybrid-v2-250",
|
|
840
931
|
minFrames: 250,
|
|
841
932
|
recommendedFrames: 250,
|
|
842
933
|
description: "Hybrid V2 250-frame model with physio features",
|
|
843
|
-
deprecated: false
|
|
934
|
+
deprecated: false,
|
|
935
|
+
aliases: ["hybrid"]
|
|
844
936
|
},
|
|
845
937
|
// Mixed V1 models — deprecated, use mixed-*-v2 equivalents instead
|
|
846
938
|
"mixed-10": {
|
|
@@ -848,49 +940,68 @@ var MODEL_CONFIGS = {
|
|
|
848
940
|
minFrames: 10,
|
|
849
941
|
recommendedFrames: 10,
|
|
850
942
|
description: "Mixed 10-frame model",
|
|
851
|
-
deprecated: true
|
|
943
|
+
deprecated: true,
|
|
944
|
+
aliases: ["v1"],
|
|
945
|
+
sunsetDate: "2026-09-01",
|
|
946
|
+
replacement: "mixed-10-v2"
|
|
852
947
|
},
|
|
853
948
|
"mixed-30": {
|
|
854
949
|
type: "mixed-30",
|
|
855
950
|
minFrames: 30,
|
|
856
951
|
recommendedFrames: 30,
|
|
857
952
|
description: "Mixed 30-frame model",
|
|
858
|
-
deprecated: true
|
|
953
|
+
deprecated: true,
|
|
954
|
+
aliases: ["v1"],
|
|
955
|
+
sunsetDate: "2026-09-01",
|
|
956
|
+
replacement: "mixed-30-v2"
|
|
859
957
|
},
|
|
860
958
|
"mixed-60": {
|
|
861
959
|
type: "mixed-60",
|
|
862
960
|
minFrames: 60,
|
|
863
961
|
recommendedFrames: 60,
|
|
864
962
|
description: "Mixed 60-frame model",
|
|
865
|
-
deprecated: true
|
|
963
|
+
deprecated: true,
|
|
964
|
+
aliases: ["v1"],
|
|
965
|
+
sunsetDate: "2026-09-01",
|
|
966
|
+
replacement: "mixed-60-v2"
|
|
866
967
|
},
|
|
867
968
|
"mixed-90": {
|
|
868
969
|
type: "mixed-90",
|
|
869
970
|
minFrames: 90,
|
|
870
971
|
recommendedFrames: 90,
|
|
871
972
|
description: "Mixed 90-frame model",
|
|
872
|
-
deprecated: true
|
|
973
|
+
deprecated: true,
|
|
974
|
+
aliases: ["v1"],
|
|
975
|
+
sunsetDate: "2026-09-01",
|
|
976
|
+
replacement: "mixed-90-v2"
|
|
873
977
|
},
|
|
874
978
|
"mixed-120": {
|
|
875
979
|
type: "mixed-120",
|
|
876
980
|
minFrames: 120,
|
|
877
981
|
recommendedFrames: 120,
|
|
878
982
|
description: "Mixed 120-frame model",
|
|
879
|
-
deprecated: true
|
|
983
|
+
deprecated: true,
|
|
984
|
+
aliases: ["v1"],
|
|
985
|
+
sunsetDate: "2026-09-01",
|
|
986
|
+
replacement: "mixed-120-v2"
|
|
880
987
|
},
|
|
881
988
|
"mixed-150": {
|
|
882
989
|
type: "mixed-150",
|
|
883
990
|
minFrames: 150,
|
|
884
991
|
recommendedFrames: 150,
|
|
885
992
|
description: "Mixed 150-frame model",
|
|
886
|
-
deprecated: true
|
|
993
|
+
deprecated: true,
|
|
994
|
+
aliases: ["v1"],
|
|
995
|
+
sunsetDate: "2026-09-01"
|
|
887
996
|
},
|
|
888
997
|
"mixed-250": {
|
|
889
998
|
type: "mixed-250",
|
|
890
999
|
minFrames: 250,
|
|
891
1000
|
recommendedFrames: 250,
|
|
892
1001
|
description: "Mixed 250-frame model",
|
|
893
|
-
deprecated: true
|
|
1002
|
+
deprecated: true,
|
|
1003
|
+
aliases: ["v1"],
|
|
1004
|
+
sunsetDate: "2026-09-01"
|
|
894
1005
|
},
|
|
895
1006
|
// Mixed V2 models (exp_042 checkpoints — EER: 4.0% / AUC: 0.991 at 30f)
|
|
896
1007
|
"mixed-10-v2": {
|
|
@@ -898,35 +1009,40 @@ var MODEL_CONFIGS = {
|
|
|
898
1009
|
minFrames: 10,
|
|
899
1010
|
recommendedFrames: 10,
|
|
900
1011
|
description: "Mixed V2 10-frame model",
|
|
901
|
-
deprecated: false
|
|
1012
|
+
deprecated: false,
|
|
1013
|
+
aliases: ["latest", "v2"]
|
|
902
1014
|
},
|
|
903
1015
|
"mixed-30-v2": {
|
|
904
1016
|
type: "mixed-30-v2",
|
|
905
1017
|
minFrames: 30,
|
|
906
1018
|
recommendedFrames: 30,
|
|
907
1019
|
description: "Mixed V2 30-frame model (recommended \u2014 95.7% balanced accuracy)",
|
|
908
|
-
deprecated: false
|
|
1020
|
+
deprecated: false,
|
|
1021
|
+
aliases: ["latest", "v2"]
|
|
909
1022
|
},
|
|
910
1023
|
"mixed-60-v2": {
|
|
911
1024
|
type: "mixed-60-v2",
|
|
912
1025
|
minFrames: 60,
|
|
913
1026
|
recommendedFrames: 60,
|
|
914
1027
|
description: "Mixed V2 60-frame model",
|
|
915
|
-
deprecated: false
|
|
1028
|
+
deprecated: false,
|
|
1029
|
+
aliases: ["latest", "v2"]
|
|
916
1030
|
},
|
|
917
1031
|
"mixed-90-v2": {
|
|
918
1032
|
type: "mixed-90-v2",
|
|
919
1033
|
minFrames: 90,
|
|
920
1034
|
recommendedFrames: 90,
|
|
921
1035
|
description: "Mixed V2 90-frame model",
|
|
922
|
-
deprecated: false
|
|
1036
|
+
deprecated: false,
|
|
1037
|
+
aliases: ["latest", "v2"]
|
|
923
1038
|
},
|
|
924
1039
|
"mixed-120-v2": {
|
|
925
1040
|
type: "mixed-120-v2",
|
|
926
1041
|
minFrames: 120,
|
|
927
1042
|
recommendedFrames: 120,
|
|
928
1043
|
description: "Mixed V2 120-frame model",
|
|
929
|
-
deprecated: false
|
|
1044
|
+
deprecated: false,
|
|
1045
|
+
aliases: ["latest", "v2"]
|
|
930
1046
|
}
|
|
931
1047
|
};
|
|
932
1048
|
var HYBRID_MODEL_CONFIGS = {
|
|
@@ -1226,7 +1342,8 @@ function getCaptureQualityFeedback(state) {
|
|
|
1226
1342
|
tooCloseToIdeal,
|
|
1227
1343
|
cameraAngleLow,
|
|
1228
1344
|
cameraAngleHigh,
|
|
1229
|
-
cameraTilted
|
|
1345
|
+
cameraTilted,
|
|
1346
|
+
faceAreaLow
|
|
1230
1347
|
} = state;
|
|
1231
1348
|
if (!hasFace) {
|
|
1232
1349
|
return FEEDBACK_MESSAGES.no_face;
|
|
@@ -1243,7 +1360,7 @@ function getCaptureQualityFeedback(state) {
|
|
|
1243
1360
|
if (tooClose) {
|
|
1244
1361
|
return FEEDBACK_MESSAGES.too_close;
|
|
1245
1362
|
}
|
|
1246
|
-
if (tooFar) {
|
|
1363
|
+
if (tooFar || faceAreaLow) {
|
|
1247
1364
|
return FEEDBACK_MESSAGES.too_far;
|
|
1248
1365
|
}
|
|
1249
1366
|
if (isPartialFace) {
|
|
@@ -1284,9 +1401,10 @@ function canCaptureFrame(state) {
|
|
|
1284
1401
|
tooCloseToIdeal,
|
|
1285
1402
|
cameraAngleLow,
|
|
1286
1403
|
cameraAngleHigh,
|
|
1287
|
-
cameraTilted
|
|
1404
|
+
cameraTilted,
|
|
1405
|
+
faceAreaLow
|
|
1288
1406
|
} = state;
|
|
1289
|
-
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;
|
|
1290
1408
|
}
|
|
1291
1409
|
|
|
1292
1410
|
// src/utils/validators.ts
|
|
@@ -1370,6 +1488,7 @@ var FACE_CENTER_VERTICAL_OFFSET = 0.05;
|
|
|
1370
1488
|
var MIN_IDEAL_FACE_RATIO = 0.05;
|
|
1371
1489
|
var MAX_IDEAL_FACE_RATIO = 0.2;
|
|
1372
1490
|
var MIN_FACE_RATIO = 0.036;
|
|
1491
|
+
var MIN_FACE_AREA_RATIO = 0.04;
|
|
1373
1492
|
var MAX_FACE_RATIO = 0.7;
|
|
1374
1493
|
var FACE_CROP_OUTPUT_SIZE = 224;
|
|
1375
1494
|
var MAX_FACE_PERCENTAGE_IN_CROP = 0.45;
|
|
@@ -1935,6 +2054,7 @@ export {
|
|
|
1935
2054
|
MAX_IDEAL_FACE_RATIO,
|
|
1936
2055
|
MIN_CAPTURE_ALIGNMENT,
|
|
1937
2056
|
MIN_CROP_MULTIPLIER,
|
|
2057
|
+
MIN_FACE_AREA_RATIO,
|
|
1938
2058
|
MIN_FACE_BOTTOM_MARGIN,
|
|
1939
2059
|
MIN_FACE_RATIO,
|
|
1940
2060
|
MIN_FACE_SIDE_MARGIN,
|
|
@@ -1948,6 +2068,7 @@ export {
|
|
|
1948
2068
|
OVAL_REGION_MOBILE,
|
|
1949
2069
|
RETRY_CONFIG,
|
|
1950
2070
|
TARGET_FACE_PERCENTAGE_IN_CROP,
|
|
2071
|
+
VALID_FRAME_COUNTS,
|
|
1951
2072
|
analyzeBlur,
|
|
1952
2073
|
analyzeEyeRegionBrightness,
|
|
1953
2074
|
analyzeEyeRegionContrast,
|