@neofaceid/web-sdk 1.19.0 → 1.23.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.
|
@@ -3430,14 +3430,14 @@ const CALIBRATION = {
|
|
|
3430
3430
|
CAPTURE_HOLD_TIME: 1500,
|
|
3431
3431
|
DETECTION_INTERVAL: 150,
|
|
3432
3432
|
// Um pouco mais rápido para melhor resposta
|
|
3433
|
-
|
|
3434
|
-
// Rosto deve ocupar
|
|
3435
|
-
|
|
3436
|
-
//
|
|
3437
|
-
CENTER_X_THRESHOLD: 0.
|
|
3438
|
-
//
|
|
3439
|
-
CENTER_Y_THRESHOLD: 0.
|
|
3440
|
-
|
|
3433
|
+
MIN_FACE_PERCENT: 0.35,
|
|
3434
|
+
// Rosto deve ocupar pelo menos 35% da largura do vídeo
|
|
3435
|
+
MAX_FACE_PERCENT: 0.65,
|
|
3436
|
+
// Rosto pode ocupar até 65% da largura do vídeo
|
|
3437
|
+
CENTER_X_THRESHOLD: 0.18,
|
|
3438
|
+
// Ligeiramente mais tolerante na centralização
|
|
3439
|
+
CENTER_Y_THRESHOLD: 0.22,
|
|
3440
|
+
STEP_TIMEOUT: 2e4
|
|
3441
3441
|
};
|
|
3442
3442
|
function BiometricRegistrationModal({
|
|
3443
3443
|
personData,
|
|
@@ -3455,6 +3455,7 @@ function BiometricRegistrationModal({
|
|
|
3455
3455
|
const isCapturingRef = useRef(false);
|
|
3456
3456
|
const currentStepRef = useRef("center");
|
|
3457
3457
|
const watchdogTimerRef = useRef(null);
|
|
3458
|
+
const stepTimeoutTimerRef = useRef(null);
|
|
3458
3459
|
const detectionStartedRef = useRef(false);
|
|
3459
3460
|
const captureStateRef = useRef(null);
|
|
3460
3461
|
const [state, dispatch] = useReducer(modalReducer, initialState);
|
|
@@ -3482,6 +3483,18 @@ function BiometricRegistrationModal({
|
|
|
3482
3483
|
currentStepIndex: state.currentStepIndex,
|
|
3483
3484
|
capturedPhotos: state.capturedPhotos
|
|
3484
3485
|
};
|
|
3486
|
+
if (stepTimeoutTimerRef.current) {
|
|
3487
|
+
clearTimeout(stepTimeoutTimerRef.current);
|
|
3488
|
+
}
|
|
3489
|
+
if (state.step !== "complete") {
|
|
3490
|
+
stepTimeoutTimerRef.current = window.setTimeout(() => {
|
|
3491
|
+
dispatch({
|
|
3492
|
+
type: "ERROR",
|
|
3493
|
+
message: "Tempo limite atingido para o movimento. Por favor, tente novamente em um ambiente bem iluminado.",
|
|
3494
|
+
retryable: true
|
|
3495
|
+
});
|
|
3496
|
+
}, CALIBRATION.STEP_TIMEOUT);
|
|
3497
|
+
}
|
|
3485
3498
|
}
|
|
3486
3499
|
}, [
|
|
3487
3500
|
state.status,
|
|
@@ -3522,9 +3535,14 @@ function BiometricRegistrationModal({
|
|
|
3522
3535
|
return null;
|
|
3523
3536
|
}
|
|
3524
3537
|
};
|
|
3525
|
-
const checkFacePosition = (
|
|
3526
|
-
if (
|
|
3527
|
-
|
|
3538
|
+
const checkFacePosition = (detection) => {
|
|
3539
|
+
if (!detection || !videoRef.current) return "not-detected";
|
|
3540
|
+
const { box } = detection.detection;
|
|
3541
|
+
const videoWidth = videoRef.current.videoWidth || 640;
|
|
3542
|
+
const videoHeight = videoRef.current.videoHeight || 480;
|
|
3543
|
+
const faceWidthRatio = box.width / videoWidth;
|
|
3544
|
+
if (faceWidthRatio < CALIBRATION.MIN_FACE_PERCENT) return "too-far";
|
|
3545
|
+
if (faceWidthRatio > CALIBRATION.MAX_FACE_PERCENT) return "too-close";
|
|
3528
3546
|
const faceCenterX = box.x + box.width / 2;
|
|
3529
3547
|
const faceCenterY = box.y + box.height / 2;
|
|
3530
3548
|
const deviationX = Math.abs(faceCenterX - videoWidth / 2) / videoWidth;
|
|
@@ -3627,6 +3645,10 @@ function BiometricRegistrationModal({
|
|
|
3627
3645
|
clearInterval(progressIntervalRef.current);
|
|
3628
3646
|
progressIntervalRef.current = null;
|
|
3629
3647
|
}
|
|
3648
|
+
if (stepTimeoutTimerRef.current) {
|
|
3649
|
+
clearTimeout(stepTimeoutTimerRef.current);
|
|
3650
|
+
stepTimeoutTimerRef.current = null;
|
|
3651
|
+
}
|
|
3630
3652
|
};
|
|
3631
3653
|
}, []);
|
|
3632
3654
|
useEffect(() => {
|
|
@@ -3740,21 +3762,20 @@ function BiometricRegistrationModal({
|
|
|
3740
3762
|
const detection = await faceapi.detectSingleFace(
|
|
3741
3763
|
videoRef.current,
|
|
3742
3764
|
new faceapi.TinyFaceDetectorOptions({
|
|
3743
|
-
inputSize:
|
|
3744
|
-
|
|
3765
|
+
inputSize: 224,
|
|
3766
|
+
// Aumentado para detectar rostos menores/mais distantes
|
|
3767
|
+
scoreThreshold: 0.35
|
|
3768
|
+
// Ligeiramente mais sensível
|
|
3745
3769
|
})
|
|
3746
3770
|
).withFaceLandmarks();
|
|
3747
3771
|
if (!isRunning) return;
|
|
3748
3772
|
const hasFace = !!detection;
|
|
3749
3773
|
setFaceDetected(hasFace);
|
|
3750
3774
|
if (hasFace && detection.detection) {
|
|
3751
|
-
const
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
video2.videoHeight
|
|
3756
|
-
);
|
|
3757
|
-
setFaceDistance(positionStatus);
|
|
3775
|
+
const positionStatus = checkFacePosition(detection);
|
|
3776
|
+
if (positionStatus !== "not-detected") {
|
|
3777
|
+
setFaceDistance(positionStatus);
|
|
3778
|
+
}
|
|
3758
3779
|
if (positionStatus !== "ok") {
|
|
3759
3780
|
manageHoldAndCapture(false);
|
|
3760
3781
|
requestAnimationFrame(detectFace2);
|
|
@@ -3940,40 +3961,25 @@ function BiometricRegistrationModal({
|
|
|
3940
3961
|
const stepProgress = state.stepProgress;
|
|
3941
3962
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "liveness-container", children: [
|
|
3942
3963
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "progress-indicator", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "progress-text", children: progress }) }),
|
|
3943
|
-
faceDetected && faceDistance !== "ok" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `
|
|
3964
|
+
faceDetected && faceDistance !== "ok" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `status-badge ${faceDistance === "not-centered" ? "warning" : "error"}`, children: [
|
|
3944
3965
|
faceDistance === "too-far" && "Aproxime-se mais",
|
|
3945
|
-
faceDistance === "too-close" && "
|
|
3966
|
+
faceDistance === "too-close" && "Afaste-se um pouco",
|
|
3946
3967
|
faceDistance === "not-centered" && "Centralize seu rosto"
|
|
3947
3968
|
] }),
|
|
3948
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "video-wrapper", children: /* @__PURE__ */ jsxRuntimeExports.
|
|
3969
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "video-wrapper", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3949
3970
|
"div",
|
|
3950
3971
|
{
|
|
3951
|
-
className: `video-circle ${faceDetected ? "face-detected" : ""} ${stepProgress > 0 ? "capturing" : ""}`,
|
|
3952
|
-
children:
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
),
|
|
3963
|
-
faceDetected && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "face-badge", children: [
|
|
3964
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("svg", { width: "16", height: "16", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3965
|
-
"path",
|
|
3966
|
-
{
|
|
3967
|
-
d: "M5 10 L8 13 L15 6",
|
|
3968
|
-
stroke: "currentColor",
|
|
3969
|
-
strokeWidth: "2.5",
|
|
3970
|
-
strokeLinecap: "round",
|
|
3971
|
-
strokeLinejoin: "round"
|
|
3972
|
-
}
|
|
3973
|
-
) }),
|
|
3974
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Rosto detectado" })
|
|
3975
|
-
] })
|
|
3976
|
-
]
|
|
3972
|
+
className: `video-circle ${faceDetected && faceDistance === "ok" ? "face-detected" : ""} ${stepProgress > 0 ? "capturing" : ""}`,
|
|
3973
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3974
|
+
"video",
|
|
3975
|
+
{
|
|
3976
|
+
ref: videoRef,
|
|
3977
|
+
className: `video-feed ${cameraReady ? "ready" : ""}`,
|
|
3978
|
+
autoPlay: true,
|
|
3979
|
+
muted: true,
|
|
3980
|
+
playsInline: true
|
|
3981
|
+
}
|
|
3982
|
+
)
|
|
3977
3983
|
}
|
|
3978
3984
|
) }),
|
|
3979
3985
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "instruction-box", children: [
|
|
@@ -4458,11 +4464,14 @@ function BiometricRegistrationModal({
|
|
|
4458
4464
|
}
|
|
4459
4465
|
|
|
4460
4466
|
.face-badge {
|
|
4467
|
+
display: none; /* Removido por ser redundante com o oval verde */
|
|
4468
|
+
}
|
|
4469
|
+
|
|
4470
|
+
.status-badge {
|
|
4461
4471
|
position: absolute;
|
|
4462
|
-
top:
|
|
4472
|
+
top: 72px; /* Logo abaixo do progress-indicator */
|
|
4463
4473
|
left: 50%;
|
|
4464
4474
|
transform: translateX(-50%);
|
|
4465
|
-
background: rgba(16, 185, 129, 0.95);
|
|
4466
4475
|
backdrop-filter: blur(10px);
|
|
4467
4476
|
border-radius: 20px;
|
|
4468
4477
|
padding: 8px 16px;
|
|
@@ -4473,22 +4482,30 @@ function BiometricRegistrationModal({
|
|
|
4473
4482
|
font-size: 13px;
|
|
4474
4483
|
font-weight: 600;
|
|
4475
4484
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
4476
|
-
box-shadow: 0 4px 12px rgba(
|
|
4485
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
|
4477
4486
|
animation: slideDown 0.3s ease-out;
|
|
4487
|
+
z-index: 10;
|
|
4488
|
+
white-space: nowrap;
|
|
4478
4489
|
}
|
|
4479
4490
|
|
|
4480
|
-
.
|
|
4491
|
+
.status-badge.info {
|
|
4492
|
+
background: rgba(255, 255, 255, 0.15);
|
|
4493
|
+
color: white;
|
|
4494
|
+
border-color: rgba(255, 255, 255, 0.1);
|
|
4495
|
+
}
|
|
4496
|
+
|
|
4497
|
+
.status-badge.warning {
|
|
4481
4498
|
background: rgba(251, 191, 36, 0.95);
|
|
4482
|
-
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
4483
|
-
box-shadow: 0 4px 12px rgba(251, 191, 36, 0.3);
|
|
4484
4499
|
color: #78350f;
|
|
4500
|
+
border-color: rgba(0, 0, 0, 0.1);
|
|
4501
|
+
box-shadow: 0 4px 15px rgba(251, 191, 36, 0.2);
|
|
4485
4502
|
}
|
|
4486
4503
|
|
|
4487
|
-
.
|
|
4504
|
+
.status-badge.error {
|
|
4488
4505
|
background: rgba(239, 68, 68, 0.95);
|
|
4489
|
-
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
4490
|
-
box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3);
|
|
4491
4506
|
color: white;
|
|
4507
|
+
border-color: rgba(255, 255, 255, 0.2);
|
|
4508
|
+
box-shadow: 0 4px 15px rgba(239, 68, 68, 0.2);
|
|
4492
4509
|
}
|
|
4493
4510
|
|
|
4494
4511
|
.instruction-box {
|
|
@@ -6885,7 +6902,7 @@ const biometricDetection = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.
|
|
|
6885
6902
|
initializeBiometricDetection,
|
|
6886
6903
|
isAdvancedDetectionAvailable
|
|
6887
6904
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
6888
|
-
const VERSION = "1.
|
|
6905
|
+
const VERSION = "1.23.0";
|
|
6889
6906
|
const RELEASE_DATE = "2026-03-13";
|
|
6890
6907
|
class OnboardingCaptureModal {
|
|
6891
6908
|
constructor(options) {
|