@incodetech/core 0.0.0-dev-20260729-9e7b030a → 0.0.0-dev-20260729-a31df3b7
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/{FaceDetectionProvider-BHweGBEM.d.ts → FaceDetectionProvider-Mh6q3EbA.d.ts} +1 -2
- package/dist/IIdCaptureCapability-Cj_aceph.d.ts +231 -0
- package/dist/{IStorageCapability-B8IGxCwe.d.ts → IStorageCapability-ORkQfK3F.d.ts} +112 -1
- package/dist/ae-signature.esm.js +1 -1
- package/dist/{apiError-CzR7Y6Ua.esm.js → apiError-CS9ZMDr2.esm.js} +1 -1
- package/dist/authentication.d.ts +3 -3
- package/dist/authentication.esm.js +2 -2
- package/dist/{authenticationManager-CmkHvt7_.esm.js → authenticationManager-Cd4tefr2.esm.js} +2 -2
- package/dist/{authenticationManager-BGM8bpD0.d.ts → authenticationManager-Y2_MuGXy.d.ts} +1 -1
- package/dist/{authenticationStateMachine-O3acuOqq.esm.js → authenticationStateMachine-BnH1mizY.esm.js} +2 -2
- package/dist/consent.d.ts +1 -1
- package/dist/{consentManager-uhDPdU6i.d.ts → consentManager-5HWbGwOa.d.ts} +9 -9
- package/dist/{deepsightLoader-CaUpu0Dy.esm.js → deepsightLoader-CN4B5ugn.esm.js} +3 -3
- package/dist/{deepsightService-CR-CYdka.d.ts → deepsightService-DLVQS_RH.d.ts} +2 -112
- package/dist/document-capture.d.ts +1 -1
- package/dist/document-upload.d.ts +4 -4
- package/dist/{documentCaptureManager-pEqMY_Oo.d.ts → documentCaptureManager-DeSYkGWc.d.ts} +70 -70
- package/dist/dynamic-forms.esm.js +2 -2
- package/dist/{dynamicFormsManager-BxUgij0L.esm.js → dynamicFormsManager-B80PGYEF.esm.js} +1 -1
- package/dist/{dynamicFormsStateMachine-D0cEsDMH.esm.js → dynamicFormsStateMachine-B7R09HRI.esm.js} +1 -1
- package/dist/ekyb.esm.js +3 -3
- package/dist/{ekybManager-LicVPYug.esm.js → ekybManager-Cg_boKM5.esm.js} +1 -1
- package/dist/{ekybStateMachine-IgLa1nXx.esm.js → ekybStateMachine-CAXjJ2gA.esm.js} +1 -1
- package/dist/electronic-signature.esm.js +1 -1
- package/dist/{electronicSignatureManager-DqPJCXMG.esm.js → electronicSignatureManager-JuycNykG.esm.js} +1 -1
- package/dist/extensibility.d.ts +14 -14
- package/dist/extensibility.esm.js +8 -8
- package/dist/{faceCaptureManagerFactory-2W_XduCs.esm.js → faceCaptureManagerFactory-Cd1uQnGS.esm.js} +1 -1
- package/dist/{faceCaptureManagerFactory-B92LFT16.d.ts → faceCaptureManagerFactory-K8iLKaRl.d.ts} +5 -4
- package/dist/{faceCaptureSetup-D-9s0vUS.esm.js → faceCaptureSetup-CS7exiIh.esm.js} +3 -2
- package/dist/flow.d.ts +5 -5
- package/dist/flow.esm.js +3 -3
- package/dist/{flowCompletionService-D_DJ1dNA.esm.js → flowCompletionService-C77_-GvG.esm.js} +1 -1
- package/dist/{flowServices-ZgW3UGcz.esm.js → flowServices-BuSZYjB9.esm.js} +3 -3
- package/dist/geolocation.esm.js +2 -2
- package/dist/{geolocationManager-oLdeMbdy.esm.js → geolocationManager-D2ptN5BO.esm.js} +1 -1
- package/dist/{geolocationStateMachine-CSDKlrHE.esm.js → geolocationStateMachine-fOQUnMxw.esm.js} +1 -1
- package/dist/id-ocr.d.ts +1 -1
- package/dist/id-selfie-flow.d.ts +179 -0
- package/dist/id-selfie-flow.esm.js +917 -0
- package/dist/id.d.ts +3 -2
- package/dist/id.esm.js +3 -2
- package/dist/{idCaptureManager-DAsfVDWq.esm.js → idCaptureManager-BokR8KKO.esm.js} +2 -1
- package/dist/{idCaptureManager-B2w2CGuV.d.ts → idCaptureManager-wKz4MXR8.d.ts} +10 -2
- package/dist/idCaptureServices-C3nAZ64o.esm.js +353 -0
- package/dist/{idCaptureStateMachine-BMZCf9M7.esm.js → idCaptureStateMachine-CM8EP_MM.esm.js} +38 -374
- package/dist/{idOcrManager-DXc_xRN7.d.ts → idOcrManager-dLuxey6y.d.ts} +1 -1
- package/dist/identity-reuse.d.ts +1 -1
- package/dist/{identityReuseManager-v2TH5g7e.d.ts → identityReuseManager-D6pD4hcZ.d.ts} +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/mandatory-consent.d.ts +2 -2
- package/dist/{mandatoryConsentManager-DOZSFZA2.d.ts → mandatoryConsentManager-DXlHM88Z.d.ts} +6 -6
- package/dist/manualReviewService-BnFXpAg9.esm.js +15 -0
- package/dist/{onDeviceFaceResults-D8FzOXsM.esm.js → onDeviceFaceResults-DFEU5wcC.esm.js} +3 -3
- package/dist/personhood.d.ts +4 -4
- package/dist/personhood.esm.js +3 -3
- package/dist/qe-signature.esm.js +1 -1
- package/dist/{recordingService-D6Hbc408.esm.js → recordingService-BwaHFQSV.esm.js} +2 -16
- package/dist/redirect-to-mobile.d.ts +2 -2
- package/dist/{redirectToMobileManager-BiVH2Ymm.d.ts → redirectToMobileManager-BD2PvT5B.d.ts} +1 -1
- package/dist/{runChildModule-CVKUUVl2.esm.js → runChildModule-1jsZfyb9.esm.js} +1 -1
- package/dist/selfie.d.ts +4 -4
- package/dist/selfie.esm.js +4 -4
- package/dist/{selfieManager-Cnw55Hp_.esm.js → selfieManager-hwv10r0j.esm.js} +2 -2
- package/dist/{selfieManager-CxeMb2tM.d.ts → selfieManager-tMxWiUk6.d.ts} +1 -1
- package/dist/{selfieStateMachine-D-wolitw.esm.js → selfieStateMachine-Cwb5y4OR.esm.js} +2 -2
- package/dist/{session-XugVyrIq.esm.js → session-DWfXLkyx.esm.js} +4 -4
- package/dist/session.esm.js +4 -4
- package/dist/{sessionInitializer-B3g2uAsl.esm.js → sessionInitializer-B58TmxdW.esm.js} +2 -2
- package/dist/{setup-BVuwm-QH.esm.js → setup-sxUVsl_J.esm.js} +4 -4
- package/dist/trueSight-D7YiTge6.esm.js +1 -0
- package/dist/{trueSightService-DGkNMx-E.esm.js → trueSightService-BIbE2pK1.esm.js} +1 -1
- package/dist/{types-4-pU2Nhm.d.ts → types-BsTkSXlg2.d.ts} +13 -232
- package/dist/{types-CrUhpMDP.d.ts → types-EELWyWpd.d.ts} +1 -1
- package/dist/{types-BBQjIaK4.d.ts → types-Hmd7U0JA.d.ts} +1 -1
- package/dist/video-selfie.d.ts +8 -100
- package/dist/video-selfie.esm.js +17 -608
- package/dist/videoSelfieCameraWarmer-lG-12ONu.esm.js +614 -0
- package/dist/videoSelfieStepDetector-144x423X.d.ts +117 -0
- package/dist/wasm.esm.js +1 -1
- package/dist/workflow.d.ts +1 -1
- package/dist/workflow.esm.js +14 -14
- package/package.json +8 -3
- package/dist/trueSight-DWfPmAL_.esm.js +0 -1
- /package/dist/{types-BX_XkMsQ.d.ts → types-BX_XkMsQ2.d.ts} +0 -0
- /package/dist/{types-BfgmV7s72.d.ts → types-BfgmV7s7.d.ts} +0 -0
- /package/dist/{types-DPIDuhut2.d.ts → types-DPIDuhut.d.ts} +0 -0
package/dist/video-selfie.esm.js
CHANGED
|
@@ -1,543 +1,13 @@
|
|
|
1
1
|
import { t as WasmUtilProvider } from "./WasmUtilProvider-D13sxEmA.esm.js";
|
|
2
|
-
import { t as ensureWasmPipelines } from "./setup-
|
|
2
|
+
import { t as ensureWasmPipelines } from "./setup-sxUVsl_J.esm.js";
|
|
3
3
|
import { t as BrowserTimerProvider } from "./BrowserTimerProvider-BXhgNxLt.esm.js";
|
|
4
4
|
import { t as api } from "./api-Bx3gKW_y.esm.js";
|
|
5
5
|
import { t as endpoints } from "./endpoints-DOfmJylF.esm.js";
|
|
6
|
-
import { d as videoSelfieWasmPipelines, l as facingModeForStep, u as resolveVideoSelfieSteps } from "./flowServices-
|
|
6
|
+
import { d as videoSelfieWasmPipelines, l as facingModeForStep, u as resolveVideoSelfieSteps } from "./flowServices-BuSZYjB9.esm.js";
|
|
7
7
|
import { c as createManager, o as createActor, r as assign, t as setup } from "./xstate.esm-Cf4e0Cfd.esm.js";
|
|
8
8
|
import { n as fromPromise, t as fromCallback } from "./xstate-actors.esm-CtI5S0f4.esm.js";
|
|
9
|
-
import { t as checkPermission } from "./permissionServices-GFikEK6S.esm.js";
|
|
10
|
-
import { i as requestCameraWithFallback, r as requestCameraAccess } from "./camera-BmFEyPP_.esm.js";
|
|
11
|
-
import { _ as StreamCanvasProcessingSession, a as encryptSelfieImage, l as startDetection, v as FaceDetectionProvider } from "./onDeviceFaceResults-D8FzOXsM.esm.js";
|
|
12
|
-
import { n as getBackCameraStream } from "./backCameraStream-BqiXcU28.esm.js";
|
|
13
|
-
import { n as getWindowDimensions } from "./getDeviceClass-CeBiEayS.esm.js";
|
|
14
|
-
import { t as FACE_ERROR_CODES } from "./types-BN5RPPIZ.esm.js";
|
|
15
|
-
import { i as uploadSelfie, r as processFace, t as getFaceErrorCodeFromUnknown } from "./selfieErrorUtils-DCRRRj38.esm.js";
|
|
16
|
-
import { t as StreamCanvasCapture } from "./StreamCanvasCapture-D2XcXCZ4.esm.js";
|
|
17
9
|
import { n as getSupportedMediaRecorderMimeType } from "./mediaRecorderOptions-CUsftWlH.esm.js";
|
|
18
|
-
import { n as
|
|
19
|
-
//#region src/modules/video-selfie/videoSelfieCompareService.ts
|
|
20
|
-
async function postVideoSelfieCompare(endpoint, base64Image) {
|
|
21
|
-
return (await api.post(endpoint, { base64Image })).data;
|
|
22
|
-
}
|
|
23
|
-
/** Compare a front-ID frame from the video selfie against the captured ID. */
|
|
24
|
-
const compareVideoSelfieId = (base64Image) => postVideoSelfieCompare(endpoints.videoSelfieCompareId, base64Image);
|
|
25
|
-
/** Compare OCR from a front-ID frame against the captured ID's OCR. */
|
|
26
|
-
const compareVideoSelfieOcr = (base64Image) => postVideoSelfieCompare(endpoints.videoSelfieCompareOcr, base64Image);
|
|
27
|
-
/** Compare a back-ID frame from the video selfie against the captured ID. */
|
|
28
|
-
const compareVideoSelfieBackId = (base64Image) => postVideoSelfieCompare(endpoints.videoSelfieCompareBackId, base64Image);
|
|
29
|
-
/** Compare OCR from a back-ID frame against the captured ID's OCR. */
|
|
30
|
-
const compareVideoSelfieBackOcr = (base64Image) => postVideoSelfieCompare(endpoints.videoSelfieCompareBackOcr, base64Image);
|
|
31
|
-
//#endregion
|
|
32
|
-
//#region src/modules/video-selfie/videoSelfieStepDetector.ts
|
|
33
|
-
/** Default autocapture window for the selfie step when the config omits one. */
|
|
34
|
-
const SELFIE_AUTOCAPTURE_MS = 1e4;
|
|
35
|
-
/**
|
|
36
|
-
* Whether the backend reported a confident face match on a front-ID compare.
|
|
37
|
-
* The backend normalizes `faceRecognitionConfidence` to 0 (no match) or 1 (match).
|
|
38
|
-
*/
|
|
39
|
-
function isFaceRecognitionMatch(confidence) {
|
|
40
|
-
if (typeof confidence !== "number") return true;
|
|
41
|
-
return confidence >= 1;
|
|
42
|
-
}
|
|
43
|
-
const SELFIE_SUCCESS_DWELL_MS = 900;
|
|
44
|
-
/**
|
|
45
|
-
* How long the ID step holds on the "success" state (green check) after the
|
|
46
|
-
* backend validates a side, before advancing. Gives the user a beat to see the
|
|
47
|
-
* capture succeeded instead of the step jumping silently. Mirrors V1's
|
|
48
|
-
* IdVideoSelfie success flash.
|
|
49
|
-
*/
|
|
50
|
-
const ID_SUCCESS_DWELL_MS = 900;
|
|
51
|
-
const SELFIE_VALIDATION_ERROR_CODES = [
|
|
52
|
-
FACE_ERROR_CODES.FACE_OCCLUDED,
|
|
53
|
-
FACE_ERROR_CODES.LIVENESS,
|
|
54
|
-
FACE_ERROR_CODES.BRIGHTNESS,
|
|
55
|
-
FACE_ERROR_CODES.LENSES,
|
|
56
|
-
FACE_ERROR_CODES.MASK,
|
|
57
|
-
FACE_ERROR_CODES.CLOSED_EYES,
|
|
58
|
-
FACE_ERROR_CODES.HEAD_COVER,
|
|
59
|
-
FACE_ERROR_CODES.FACE_NOT_FOUND,
|
|
60
|
-
FACE_ERROR_CODES.MULTIPLE_FACES,
|
|
61
|
-
FACE_ERROR_CODES.TOO_BLURRY,
|
|
62
|
-
FACE_ERROR_CODES.TOO_DARK,
|
|
63
|
-
FACE_ERROR_CODES.USER_IS_NOT_RECOGNIZED,
|
|
64
|
-
FACE_ERROR_CODES.SPOOF_ATTEMPT_DETECTED,
|
|
65
|
-
FACE_ERROR_CODES.FACE_TOO_DARK,
|
|
66
|
-
FACE_ERROR_CODES.LENSES_DETECTED,
|
|
67
|
-
FACE_ERROR_CODES.FACE_MASK_DETECTED,
|
|
68
|
-
FACE_ERROR_CODES.CLOSED_EYES_DETECTED,
|
|
69
|
-
FACE_ERROR_CODES.HEAD_COVER_DETECTED,
|
|
70
|
-
FACE_ERROR_CODES.FACE_CROPPING_FAILED,
|
|
71
|
-
FACE_ERROR_CODES.FACE_TOO_SMALL,
|
|
72
|
-
FACE_ERROR_CODES.FACE_TOO_BLURRY,
|
|
73
|
-
FACE_ERROR_CODES.BAD_PHOTO_QUALITY,
|
|
74
|
-
FACE_ERROR_CODES.SELFIE_IMAGE_LOW_QUALITY
|
|
75
|
-
];
|
|
76
|
-
const SELFIE_VALIDATION_STATUS_CODES = [
|
|
77
|
-
3004,
|
|
78
|
-
3005,
|
|
79
|
-
3006,
|
|
80
|
-
3007,
|
|
81
|
-
4010,
|
|
82
|
-
4019,
|
|
83
|
-
4077,
|
|
84
|
-
4078
|
|
85
|
-
];
|
|
86
|
-
function getErrorStatus(error) {
|
|
87
|
-
if (typeof error !== "object" || error === null) return;
|
|
88
|
-
if ("data" in error) {
|
|
89
|
-
const data = error.data;
|
|
90
|
-
if (typeof data === "object" && data !== null && "status" in data && typeof data.status === "number") return data.status;
|
|
91
|
-
}
|
|
92
|
-
if ("status" in error && typeof error.status === "number") return error.status;
|
|
93
|
-
}
|
|
94
|
-
function isSelfieValidationError(error) {
|
|
95
|
-
const errorCode = getFaceErrorCodeFromUnknown(error);
|
|
96
|
-
if (errorCode !== void 0 && SELFIE_VALIDATION_ERROR_CODES.includes(errorCode)) return true;
|
|
97
|
-
const status = getErrorStatus(error);
|
|
98
|
-
return status !== void 0 && SELFIE_VALIDATION_STATUS_CODES.includes(status);
|
|
99
|
-
}
|
|
100
|
-
function isIdComparisonValidationError(error) {
|
|
101
|
-
return typeof error === "object" && error !== null && "status" in error && typeof error.status === "number" && error.status > 0;
|
|
102
|
-
}
|
|
103
|
-
function abortError() {
|
|
104
|
-
return /* @__PURE__ */ new Error("aborted");
|
|
105
|
-
}
|
|
106
|
-
function throwIfAborted(signal) {
|
|
107
|
-
if (signal.aborted) throw abortError();
|
|
108
|
-
}
|
|
109
|
-
/** Resolves after `ms`, or rejects early if `signal` aborts. */
|
|
110
|
-
function delay(ms, signal) {
|
|
111
|
-
if (signal.aborted) return Promise.reject(abortError());
|
|
112
|
-
const timerProvider = BrowserTimerProvider.getInstance();
|
|
113
|
-
return new Promise((resolve, reject) => {
|
|
114
|
-
const timer = timerProvider.setTimeout(() => {
|
|
115
|
-
signal.removeEventListener("abort", onAbort);
|
|
116
|
-
resolve();
|
|
117
|
-
}, ms);
|
|
118
|
-
const onAbort = () => {
|
|
119
|
-
timerProvider.clearTimeout(timer);
|
|
120
|
-
reject(abortError());
|
|
121
|
-
};
|
|
122
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
123
|
-
if (signal.aborted) onAbort();
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
function isWrongVideoSelfieIdSide(step, reportedSide) {
|
|
127
|
-
const side = reportedSide.toLowerCase();
|
|
128
|
-
if (side === "wrong") return true;
|
|
129
|
-
const isFront = side.includes("front") && !side.includes("back");
|
|
130
|
-
const isBack = side.includes("back") && !side.includes("front");
|
|
131
|
-
return step === "frontId" ? isBack : isFront;
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Builds the default per-step detector from the module config. Today it
|
|
135
|
-
* auto-captures the `selfie` step (face detection → `add/face` → `process/face`);
|
|
136
|
-
* ID / proof-of-address / questions / speech advance manually until their
|
|
137
|
-
* detectors land.
|
|
138
|
-
*/
|
|
139
|
-
function createDefaultStepDetector(config, deps) {
|
|
140
|
-
return ({ step, stream, signal, onStatus }) => {
|
|
141
|
-
if (step === "selfie") return detectSelfie({
|
|
142
|
-
config,
|
|
143
|
-
deps,
|
|
144
|
-
stream,
|
|
145
|
-
signal,
|
|
146
|
-
onStatus
|
|
147
|
-
});
|
|
148
|
-
if (step === "frontId" || step === "backId") return detectId({
|
|
149
|
-
step,
|
|
150
|
-
config,
|
|
151
|
-
stream,
|
|
152
|
-
signal,
|
|
153
|
-
onStatus
|
|
154
|
-
});
|
|
155
|
-
return new Promise(() => {});
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
async function detectSelfie(params) {
|
|
159
|
-
const { config, deps, stream, signal, onStatus } = params;
|
|
160
|
-
const provider = new FaceDetectionProvider();
|
|
161
|
-
await provider.initialize({
|
|
162
|
-
autocaptureInterval: SELFIE_AUTOCAPTURE_MS,
|
|
163
|
-
useOnDeviceWorkflow: false,
|
|
164
|
-
videoSelfie: true
|
|
165
|
-
});
|
|
166
|
-
if (signal.aborted) {
|
|
167
|
-
provider.dispose();
|
|
168
|
-
throw abortError();
|
|
169
|
-
}
|
|
170
|
-
provider.setChecksEnabled({
|
|
171
|
-
lenses: config.validateLenses ?? false,
|
|
172
|
-
mask: config.validateFaceMask ?? false,
|
|
173
|
-
closedEyes: config.validateClosedEyes ?? false,
|
|
174
|
-
headWear: config.validateHeadCover ?? false,
|
|
175
|
-
occlusion: false
|
|
176
|
-
});
|
|
177
|
-
const imageType = config.useAsSelfie === true ? "selfie" : "videoSelfie";
|
|
178
|
-
const capturer = new StreamCanvasCapture(stream);
|
|
179
|
-
const detectionConfig = {
|
|
180
|
-
showTutorial: false,
|
|
181
|
-
validateBrightness: false,
|
|
182
|
-
validateLenses: config.validateLenses ?? false,
|
|
183
|
-
validateFaceMask: config.validateFaceMask ?? false,
|
|
184
|
-
validateClosedEyes: config.validateClosedEyes ?? false,
|
|
185
|
-
validateHeadCover: config.validateHeadCover ?? false,
|
|
186
|
-
autoCaptureTimeout: SELFIE_AUTOCAPTURE_MS / 1e3
|
|
187
|
-
};
|
|
188
|
-
const runAttempt = () => new Promise((resolve, reject) => {
|
|
189
|
-
if (signal.aborted) {
|
|
190
|
-
reject(abortError());
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
let settled = false;
|
|
194
|
-
function settle(run) {
|
|
195
|
-
if (settled) return;
|
|
196
|
-
settled = true;
|
|
197
|
-
signal.removeEventListener("abort", onAbort);
|
|
198
|
-
run();
|
|
199
|
-
}
|
|
200
|
-
const detection = startDetection({
|
|
201
|
-
config: detectionConfig,
|
|
202
|
-
capturer,
|
|
203
|
-
provider,
|
|
204
|
-
onUpdate: (status) => onStatus?.(status),
|
|
205
|
-
onSuccess: (canvas, faceCoordinates) => {
|
|
206
|
-
onStatus?.("capturing");
|
|
207
|
-
(async () => {
|
|
208
|
-
try {
|
|
209
|
-
const encryptedBase64Image = await encryptSelfieImage({
|
|
210
|
-
canvas,
|
|
211
|
-
dependencies: { getWasmUtil: async () => deps.getWasmUtil() }
|
|
212
|
-
});
|
|
213
|
-
throwIfAborted(signal);
|
|
214
|
-
await uploadSelfie({
|
|
215
|
-
encryptedBase64Image,
|
|
216
|
-
faceCoordinates,
|
|
217
|
-
imageType
|
|
218
|
-
});
|
|
219
|
-
throwIfAborted(signal);
|
|
220
|
-
await processFace(imageType);
|
|
221
|
-
throwIfAborted(signal);
|
|
222
|
-
onStatus?.("success");
|
|
223
|
-
await delay(SELFIE_SUCCESS_DWELL_MS, signal);
|
|
224
|
-
settle(resolve);
|
|
225
|
-
} catch (error) {
|
|
226
|
-
settle(() => reject(error instanceof Error ? error : new Error(String(error))));
|
|
227
|
-
}
|
|
228
|
-
})();
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
|
-
function onAbort() {
|
|
232
|
-
detection.cleanup();
|
|
233
|
-
settle(() => reject(abortError()));
|
|
234
|
-
}
|
|
235
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
236
|
-
if (signal.aborted) onAbort();
|
|
237
|
-
});
|
|
238
|
-
try {
|
|
239
|
-
await runAttempt();
|
|
240
|
-
return { outcome: "success" };
|
|
241
|
-
} catch (error) {
|
|
242
|
-
if (signal.aborted || !isSelfieValidationError(error)) throw error;
|
|
243
|
-
onStatus?.("error");
|
|
244
|
-
return {
|
|
245
|
-
outcome: "validationFailed",
|
|
246
|
-
failure: "selfieVerificationFailed"
|
|
247
|
-
};
|
|
248
|
-
} finally {
|
|
249
|
-
capturer.dispose();
|
|
250
|
-
provider.dispose();
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
async function detectId(params) {
|
|
254
|
-
const { step, config, stream, signal, onStatus } = params;
|
|
255
|
-
const provider = new IdCaptureProvider();
|
|
256
|
-
await provider.initialize({ videoSelfie: true });
|
|
257
|
-
if (signal.aborted) {
|
|
258
|
-
provider.dispose();
|
|
259
|
-
throw abortError();
|
|
260
|
-
}
|
|
261
|
-
const windowDimensions = getWindowDimensions();
|
|
262
|
-
provider.setGeometry({
|
|
263
|
-
...DEFAULT_ID_CAPTURE_GEOMETRY,
|
|
264
|
-
windowOuterWidth: windowDimensions.outerWidth,
|
|
265
|
-
windowOuterHeight: windowDimensions.outerHeight,
|
|
266
|
-
windowInnerWidth: windowDimensions.innerWidth,
|
|
267
|
-
windowInnerHeight: windowDimensions.innerHeight
|
|
268
|
-
});
|
|
269
|
-
provider.setSettings({
|
|
270
|
-
isFixedMask: false,
|
|
271
|
-
isIPhone14OrHigher: false,
|
|
272
|
-
idType: step === "backId" ? "BackId" : "FrontId",
|
|
273
|
-
blurCheckEnabled: true,
|
|
274
|
-
glareCheckEnabled: false,
|
|
275
|
-
faceQualityCheckEnabled: false,
|
|
276
|
-
iouCheckEnabled: true,
|
|
277
|
-
fpsLimitEnabled: false
|
|
278
|
-
});
|
|
279
|
-
provider.setThresholds(DEFAULT_ID_CAPTURE_THRESHOLDS);
|
|
280
|
-
provider.setModelType("v2");
|
|
281
|
-
const capturer = new StreamCanvasCapture(stream);
|
|
282
|
-
return new Promise((resolve, reject) => {
|
|
283
|
-
let validating = false;
|
|
284
|
-
let wrongSide = false;
|
|
285
|
-
let settled = false;
|
|
286
|
-
let toreDown = false;
|
|
287
|
-
const session = new StreamCanvasProcessingSession({
|
|
288
|
-
capturer,
|
|
289
|
-
provider
|
|
290
|
-
});
|
|
291
|
-
function teardown() {
|
|
292
|
-
if (toreDown) return;
|
|
293
|
-
toreDown = true;
|
|
294
|
-
session.dispose();
|
|
295
|
-
capturer.dispose();
|
|
296
|
-
provider.dispose();
|
|
297
|
-
}
|
|
298
|
-
function settle(run) {
|
|
299
|
-
if (settled) return;
|
|
300
|
-
settled = true;
|
|
301
|
-
signal.removeEventListener("abort", onAbort);
|
|
302
|
-
teardown();
|
|
303
|
-
run();
|
|
304
|
-
}
|
|
305
|
-
function onAbort() {
|
|
306
|
-
settle(() => reject(abortError()));
|
|
307
|
-
}
|
|
308
|
-
provider.setCallbacks({
|
|
309
|
-
onFarAway: () => {
|
|
310
|
-
if (!validating && !wrongSide) onStatus?.("tooFar");
|
|
311
|
-
},
|
|
312
|
-
onBlur: () => {
|
|
313
|
-
if (!validating && !wrongSide) onStatus?.("blur");
|
|
314
|
-
},
|
|
315
|
-
onIdSideChange: (side) => {
|
|
316
|
-
wrongSide = isWrongVideoSelfieIdSide(step, side);
|
|
317
|
-
onStatus?.(wrongSide ? "wrongSide" : "detecting");
|
|
318
|
-
},
|
|
319
|
-
onCapturing: () => {
|
|
320
|
-
if (validating || wrongSide) return;
|
|
321
|
-
const base64Image = capturer.getLatestCanvas()?.getBase64Image();
|
|
322
|
-
if (!base64Image) return;
|
|
323
|
-
validating = true;
|
|
324
|
-
onStatus?.("capturing");
|
|
325
|
-
(async () => {
|
|
326
|
-
try {
|
|
327
|
-
const result = await validateIdFrame(step, config, base64Image);
|
|
328
|
-
if (result.outcome === "success") {
|
|
329
|
-
throwIfAborted(signal);
|
|
330
|
-
onStatus?.("success");
|
|
331
|
-
await delay(ID_SUCCESS_DWELL_MS, signal);
|
|
332
|
-
settle(() => resolve(result));
|
|
333
|
-
return;
|
|
334
|
-
}
|
|
335
|
-
onStatus?.("error");
|
|
336
|
-
settle(() => resolve(result));
|
|
337
|
-
} catch (error) {
|
|
338
|
-
if (signal.aborted) {
|
|
339
|
-
settle(() => reject(error instanceof Error ? error : new Error(String(error))));
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
onStatus?.("error");
|
|
343
|
-
if (isIdComparisonValidationError(error)) {
|
|
344
|
-
settle(() => resolve({
|
|
345
|
-
outcome: "validationFailed",
|
|
346
|
-
failure: "idScanFailed"
|
|
347
|
-
}));
|
|
348
|
-
return;
|
|
349
|
-
}
|
|
350
|
-
settle(() => resolve({
|
|
351
|
-
outcome: "retryableFailure",
|
|
352
|
-
failure: "idScanFailed"
|
|
353
|
-
}));
|
|
354
|
-
}
|
|
355
|
-
})();
|
|
356
|
-
}
|
|
357
|
-
});
|
|
358
|
-
onStatus?.("detecting");
|
|
359
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
360
|
-
if (signal.aborted) onAbort();
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
/** Runs the configured ID/OCR comparisons for a captured ID frame. */
|
|
364
|
-
async function validateIdFrame(step, config, base64Image) {
|
|
365
|
-
if (step === "backId") {
|
|
366
|
-
if (config.compareBackIdEnabled) {
|
|
367
|
-
const result = await compareVideoSelfieBackId(base64Image);
|
|
368
|
-
if (result.idSideMatched === false || result.success === false) return {
|
|
369
|
-
outcome: "validationFailed",
|
|
370
|
-
failure: "idTypeMismatch"
|
|
371
|
-
};
|
|
372
|
-
}
|
|
373
|
-
if (config.compareBackOcrEnabled) {
|
|
374
|
-
if ((await compareVideoSelfieBackOcr(base64Image)).success === false) return {
|
|
375
|
-
outcome: "validationFailed",
|
|
376
|
-
failure: "nameVerificationFailed"
|
|
377
|
-
};
|
|
378
|
-
}
|
|
379
|
-
return { outcome: "success" };
|
|
380
|
-
}
|
|
381
|
-
if (config.compareIdEnabled) {
|
|
382
|
-
const result = await compareVideoSelfieId(base64Image);
|
|
383
|
-
if (result.idTypeMatched === false) return {
|
|
384
|
-
outcome: "validationFailed",
|
|
385
|
-
failure: "idTypeMismatch"
|
|
386
|
-
};
|
|
387
|
-
if (typeof result.faceRecognitionConfidence === "number" && !isFaceRecognitionMatch(result.faceRecognitionConfidence)) return {
|
|
388
|
-
outcome: "validationFailed",
|
|
389
|
-
failure: "photoVerificationFailed"
|
|
390
|
-
};
|
|
391
|
-
}
|
|
392
|
-
if (config.compareOcrEnabled) {
|
|
393
|
-
if ((await compareVideoSelfieOcr(base64Image)).success === false) return {
|
|
394
|
-
outcome: "validationFailed",
|
|
395
|
-
failure: "nameVerificationFailed"
|
|
396
|
-
};
|
|
397
|
-
}
|
|
398
|
-
return { outcome: "success" };
|
|
399
|
-
}
|
|
400
|
-
//#endregion
|
|
401
|
-
//#region ../infra/src/media/CameraCompositor.ts
|
|
402
|
-
const MAX_COMPOSITE_LONG_EDGE = 1280;
|
|
403
|
-
const MAX_COMPOSITE_SHORT_EDGE = 720;
|
|
404
|
-
const FRAME_INTERVAL_TOLERANCE_RATIO = .9;
|
|
405
|
-
/**
|
|
406
|
-
* Composites the *active* camera into a canvas and exposes the canvas as a
|
|
407
|
-
* single, stable `MediaStream` to record. Switching cameras (front ↔ back)
|
|
408
|
-
* just repoints what the canvas draws — the output stream and its audio track
|
|
409
|
-
* are never replaced — so a single `MediaRecorder` produces one continuous
|
|
410
|
-
* video that follows the camera switches (V1 parity), instead of restarting
|
|
411
|
-
* per camera.
|
|
412
|
-
*
|
|
413
|
-
* The audio track from the initial stream is carried through unchanged across
|
|
414
|
-
* video switches, so there's no audio glitch when the camera flips.
|
|
415
|
-
*/
|
|
416
|
-
var CameraCompositor = class {
|
|
417
|
-
constructor(options = {}) {
|
|
418
|
-
this.canvas = null;
|
|
419
|
-
this.ctx = null;
|
|
420
|
-
this.video = null;
|
|
421
|
-
this.frameRequestId = null;
|
|
422
|
-
this.frameRequestKind = null;
|
|
423
|
-
this.lastDrawTimeMs = null;
|
|
424
|
-
this.lastVideoTimeSeconds = null;
|
|
425
|
-
this.audioTrack = null;
|
|
426
|
-
this.videoTrack = null;
|
|
427
|
-
this.composite = null;
|
|
428
|
-
this.fps = options.fps ?? 30;
|
|
429
|
-
this.frameIntervalMs = this.fps > 0 ? 1e3 / this.fps : 0;
|
|
430
|
-
}
|
|
431
|
-
/**
|
|
432
|
-
* Begin compositing `stream` and return the composite stream to record. The
|
|
433
|
-
* stream's audio track (if any) is carried through unchanged across later
|
|
434
|
-
* `switchVideo` calls.
|
|
435
|
-
*/
|
|
436
|
-
start(stream) {
|
|
437
|
-
this.canvas = document.createElement("canvas");
|
|
438
|
-
this.ctx = this.canvas.getContext("2d");
|
|
439
|
-
this.video = document.createElement("video");
|
|
440
|
-
this.video.muted = true;
|
|
441
|
-
this.video.playsInline = true;
|
|
442
|
-
this.audioTrack = stream.getAudioTracks()[0] ?? null;
|
|
443
|
-
this.setVideoSource(stream);
|
|
444
|
-
const composite = this.canvas.captureStream(this.fps);
|
|
445
|
-
if (this.audioTrack) composite.addTrack(this.audioTrack);
|
|
446
|
-
this.composite = composite;
|
|
447
|
-
this.startDrawLoop();
|
|
448
|
-
return composite;
|
|
449
|
-
}
|
|
450
|
-
/**
|
|
451
|
-
* Swap the camera feeding the canvas without interrupting the composite
|
|
452
|
-
* stream. Pass a video-only stream (audio is kept from `start`). The previous
|
|
453
|
-
* video track is stopped.
|
|
454
|
-
*/
|
|
455
|
-
switchVideo(stream) {
|
|
456
|
-
if (!this.composite) return;
|
|
457
|
-
const previousVideoTrack = this.videoTrack;
|
|
458
|
-
this.setVideoSource(stream);
|
|
459
|
-
this.startDrawLoop();
|
|
460
|
-
if (previousVideoTrack) previousVideoTrack.stop();
|
|
461
|
-
}
|
|
462
|
-
/** The composite stream being recorded, if compositing is active. */
|
|
463
|
-
get stream() {
|
|
464
|
-
return this.composite ?? void 0;
|
|
465
|
-
}
|
|
466
|
-
/** Stop compositing and release the canvas, audio, and video tracks. */
|
|
467
|
-
stop() {
|
|
468
|
-
this.cancelDrawLoop();
|
|
469
|
-
this.videoTrack?.stop();
|
|
470
|
-
this.audioTrack?.stop();
|
|
471
|
-
this.composite?.getTracks().forEach((track) => track.stop());
|
|
472
|
-
if (this.video) this.video.srcObject = null;
|
|
473
|
-
this.canvas = null;
|
|
474
|
-
this.ctx = null;
|
|
475
|
-
this.video = null;
|
|
476
|
-
this.videoTrack = null;
|
|
477
|
-
this.audioTrack = null;
|
|
478
|
-
this.composite = null;
|
|
479
|
-
}
|
|
480
|
-
setVideoSource(stream) {
|
|
481
|
-
this.videoTrack = stream.getVideoTracks()[0] ?? null;
|
|
482
|
-
const video = this.video;
|
|
483
|
-
if (!video) return;
|
|
484
|
-
video.srcObject = new MediaStream(stream.getVideoTracks());
|
|
485
|
-
video.play().catch(() => {});
|
|
486
|
-
}
|
|
487
|
-
startDrawLoop() {
|
|
488
|
-
this.cancelDrawLoop();
|
|
489
|
-
this.lastDrawTimeMs = null;
|
|
490
|
-
this.lastVideoTimeSeconds = null;
|
|
491
|
-
const draw = (timeMs) => {
|
|
492
|
-
const elapsed = this.lastDrawTimeMs === null ? Infinity : timeMs - this.lastDrawTimeMs;
|
|
493
|
-
if ((this.frameIntervalMs === 0 || elapsed >= this.frameIntervalMs * FRAME_INTERVAL_TOLERANCE_RATIO) && this.drawCurrentFrame()) this.lastDrawTimeMs = timeMs;
|
|
494
|
-
this.scheduleNextFrame(draw);
|
|
495
|
-
};
|
|
496
|
-
this.scheduleNextFrame(draw);
|
|
497
|
-
}
|
|
498
|
-
scheduleNextFrame(callback) {
|
|
499
|
-
const video = this.video;
|
|
500
|
-
if (video && typeof video.requestVideoFrameCallback === "function") {
|
|
501
|
-
this.frameRequestKind = "video";
|
|
502
|
-
this.frameRequestId = video.requestVideoFrameCallback(callback);
|
|
503
|
-
return;
|
|
504
|
-
}
|
|
505
|
-
this.frameRequestKind = "animation";
|
|
506
|
-
this.frameRequestId = requestAnimationFrame(callback);
|
|
507
|
-
}
|
|
508
|
-
cancelDrawLoop() {
|
|
509
|
-
if (this.frameRequestId === null) return;
|
|
510
|
-
if (this.frameRequestKind === "video" && this.video && typeof this.video.cancelVideoFrameCallback === "function") this.video.cancelVideoFrameCallback(this.frameRequestId);
|
|
511
|
-
else cancelAnimationFrame(this.frameRequestId);
|
|
512
|
-
this.frameRequestId = null;
|
|
513
|
-
this.frameRequestKind = null;
|
|
514
|
-
}
|
|
515
|
-
drawCurrentFrame() {
|
|
516
|
-
const video = this.video;
|
|
517
|
-
const canvas = this.canvas;
|
|
518
|
-
const ctx = this.ctx;
|
|
519
|
-
if (!video || !canvas || !ctx || video.videoWidth <= 0) return false;
|
|
520
|
-
if (this.lastVideoTimeSeconds === video.currentTime) return false;
|
|
521
|
-
const dimensions = this.getBoundedDimensions(video.videoWidth, video.videoHeight);
|
|
522
|
-
if (canvas.width !== dimensions.width || canvas.height !== dimensions.height) {
|
|
523
|
-
canvas.width = dimensions.width;
|
|
524
|
-
canvas.height = dimensions.height;
|
|
525
|
-
}
|
|
526
|
-
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
527
|
-
this.lastVideoTimeSeconds = video.currentTime;
|
|
528
|
-
return true;
|
|
529
|
-
}
|
|
530
|
-
getBoundedDimensions(width, height) {
|
|
531
|
-
const longEdge = Math.max(width, height);
|
|
532
|
-
const shortEdge = Math.min(width, height);
|
|
533
|
-
const scale = Math.min(1, MAX_COMPOSITE_LONG_EDGE / longEdge, MAX_COMPOSITE_SHORT_EDGE / shortEdge);
|
|
534
|
-
return {
|
|
535
|
-
width: Math.max(1, Math.round(width * scale)),
|
|
536
|
-
height: Math.max(1, Math.round(height * scale))
|
|
537
|
-
};
|
|
538
|
-
}
|
|
539
|
-
};
|
|
540
|
-
//#endregion
|
|
10
|
+
import { i as createDefaultStepDetector, n as defaultAcquireCamera, r as CameraCompositor, t as createVideoSelfieCameraWarmer } from "./videoSelfieCameraWarmer-lG-12ONu.esm.js";
|
|
541
11
|
//#region ../infra/src/providers/browser/MultipartRecordingProvider.ts
|
|
542
12
|
/**
|
|
543
13
|
* S3 multipart requires every part except the last to be at least 5 MB, so we
|
|
@@ -767,80 +237,6 @@ var MultipartRecordingService = class {
|
|
|
767
237
|
}
|
|
768
238
|
};
|
|
769
239
|
//#endregion
|
|
770
|
-
//#region src/modules/video-selfie/videoSelfieCameraWarmer.ts
|
|
771
|
-
/**
|
|
772
|
-
* Acquire the camera for a Video Selfie step. The rear (`environment`) steps
|
|
773
|
-
* (frontId / backId / poa) route through {@link getBackCameraStream} so the
|
|
774
|
-
* main autofocus lens is selected — Samsung's default `facingMode:environment`
|
|
775
|
-
* camera is often a fixed-focus auxiliary lens, which blurs the ID steps and
|
|
776
|
-
* stalls capture (client-side blur check is on). This mirrors the ID Capture
|
|
777
|
-
* module. `getBackCameraStream` returns video only, so audio is acquired and
|
|
778
|
-
* merged separately when the step needs it. Front (`user`) steps keep the
|
|
779
|
-
* plain fallback path. Used both as the recording machine's default
|
|
780
|
-
* `acquireCamera` dependency and as this warmer's own acquire/fallback.
|
|
781
|
-
*/
|
|
782
|
-
async function defaultAcquireCamera(facingMode, withAudio) {
|
|
783
|
-
if (facingMode !== "environment") return requestCameraWithFallback({
|
|
784
|
-
video: { facingMode },
|
|
785
|
-
audio: withAudio
|
|
786
|
-
});
|
|
787
|
-
const { stream } = await getBackCameraStream();
|
|
788
|
-
if (withAudio) try {
|
|
789
|
-
const audioStream = await requestCameraAccess({ audio: true });
|
|
790
|
-
for (const audioTrack of audioStream.getAudioTracks()) stream.addTrack(audioTrack);
|
|
791
|
-
} catch (error) {
|
|
792
|
-
stream.getTracks().forEach((track) => track.stop());
|
|
793
|
-
throw error;
|
|
794
|
-
}
|
|
795
|
-
return stream;
|
|
796
|
-
}
|
|
797
|
-
function stopStream(stream) {
|
|
798
|
-
stream?.getTracks().forEach((track) => track.stop());
|
|
799
|
-
}
|
|
800
|
-
/**
|
|
801
|
-
* Creates a {@link VideoSelfieCameraWarmer} for the given config. The first
|
|
802
|
-
* camera (and whether it needs audio) is derived from the resolved step order —
|
|
803
|
-
* the same first acquire the recording machine performs on `START`.
|
|
804
|
-
*/
|
|
805
|
-
function createVideoSelfieCameraWarmer(config) {
|
|
806
|
-
const firstFacing = facingModeForStep(resolveVideoSelfieSteps(config)[0] ?? "selfie");
|
|
807
|
-
let warming = null;
|
|
808
|
-
let warmed = null;
|
|
809
|
-
let consumed = false;
|
|
810
|
-
return {
|
|
811
|
-
warm() {
|
|
812
|
-
if (warming) return;
|
|
813
|
-
warming = (async () => {
|
|
814
|
-
try {
|
|
815
|
-
if (await checkPermission() !== "granted") return null;
|
|
816
|
-
warmed = await defaultAcquireCamera(firstFacing, true);
|
|
817
|
-
return warmed;
|
|
818
|
-
} catch {
|
|
819
|
-
return null;
|
|
820
|
-
}
|
|
821
|
-
})();
|
|
822
|
-
},
|
|
823
|
-
async acquireCamera(facingMode, withAudio) {
|
|
824
|
-
if (!consumed && facingMode === firstFacing && withAudio) {
|
|
825
|
-
consumed = true;
|
|
826
|
-
const stream = warmed ?? (warming ? await warming : null);
|
|
827
|
-
warmed = null;
|
|
828
|
-
if (stream) return stream;
|
|
829
|
-
}
|
|
830
|
-
return defaultAcquireCamera(facingMode, withAudio);
|
|
831
|
-
},
|
|
832
|
-
dispose() {
|
|
833
|
-
if (consumed) return;
|
|
834
|
-
if (warmed) {
|
|
835
|
-
stopStream(warmed);
|
|
836
|
-
warmed = null;
|
|
837
|
-
} else if (warming) warming.then((stream) => {
|
|
838
|
-
if (!consumed) stopStream(stream);
|
|
839
|
-
});
|
|
840
|
-
}
|
|
841
|
-
};
|
|
842
|
-
}
|
|
843
|
-
//#endregion
|
|
844
240
|
//#region src/modules/video-selfie/videoSelfieRecordingMachine.ts
|
|
845
241
|
/** A detector that never settles — used when a step has no auto-capture yet. */
|
|
846
242
|
const manualStepDetector = () => new Promise(() => {});
|
|
@@ -865,6 +261,9 @@ function validationFailureFromEvent(event) {
|
|
|
865
261
|
function retryableFailureFromEvent(event) {
|
|
866
262
|
return event.failure;
|
|
867
263
|
}
|
|
264
|
+
function orientationFromEvent(event) {
|
|
265
|
+
return event.orientation;
|
|
266
|
+
}
|
|
868
267
|
const SWITCHING_CAMERA_MIN_DWELL_MS = 3e3;
|
|
869
268
|
const ID_FLIP_DWELL_MS = 4e3;
|
|
870
269
|
const FINAL_SUCCESS_DWELL_MS = 3e3;
|
|
@@ -968,6 +367,10 @@ const videoSelfieRecordingSetup = setup({
|
|
|
968
367
|
onStatus: (status) => sendBack({
|
|
969
368
|
type: "DETECTION_STATUS",
|
|
970
369
|
status
|
|
370
|
+
}),
|
|
371
|
+
onOrientation: (orientation) => sendBack({
|
|
372
|
+
type: "ORIENTATION",
|
|
373
|
+
orientation
|
|
971
374
|
})
|
|
972
375
|
}).then((result) => {
|
|
973
376
|
if (result.outcome === "retryableFailure") {
|
|
@@ -1006,6 +409,7 @@ const videoSelfieRecordingSetup = setup({
|
|
|
1006
409
|
validationFailure: () => void 0
|
|
1007
410
|
}),
|
|
1008
411
|
setDetectionStatus: assign({ detectionStatus: ({ event }) => detectionStatusFromEvent(event) }),
|
|
412
|
+
setOrientation: assign({ orientation: ({ event }) => orientationFromEvent(event) }),
|
|
1009
413
|
setDetectionError: assign({ detectionError: ({ event }) => detectionErrorFromEvent(event) }),
|
|
1010
414
|
setValidationFailure: assign(({ context, event }) => ({
|
|
1011
415
|
attemptsRemaining: context.attemptsRemaining === UNLIMITED_ATTEMPTS ? UNLIMITED_ATTEMPTS : Math.max(0, context.attemptsRemaining - 1),
|
|
@@ -1020,7 +424,8 @@ const videoSelfieRecordingSetup = setup({
|
|
|
1020
424
|
clearDetectionFeedback: assign({
|
|
1021
425
|
detectionStatus: () => void 0,
|
|
1022
426
|
detectionError: () => void 0,
|
|
1023
|
-
validationFailure: () => void 0
|
|
427
|
+
validationFailure: () => void 0,
|
|
428
|
+
orientation: () => void 0
|
|
1024
429
|
}),
|
|
1025
430
|
setUploadFailedError: assign({ error: () => "Video upload failed" }),
|
|
1026
431
|
resetSession: assign(({ context }) => ({
|
|
@@ -1028,6 +433,7 @@ const videoSelfieRecordingSetup = setup({
|
|
|
1028
433
|
stream: void 0,
|
|
1029
434
|
composite: void 0,
|
|
1030
435
|
detectionStatus: void 0,
|
|
436
|
+
orientation: void 0,
|
|
1031
437
|
detectionError: void 0,
|
|
1032
438
|
validationFailure: void 0,
|
|
1033
439
|
attemptsRemaining: context.attemptsPerStep,
|
|
@@ -1087,6 +493,7 @@ const videoSelfieRecordingMachine = videoSelfieRecordingSetup.createMachine({
|
|
|
1087
493
|
stream: void 0,
|
|
1088
494
|
composite: void 0,
|
|
1089
495
|
detectionStatus: void 0,
|
|
496
|
+
orientation: void 0,
|
|
1090
497
|
detectionError: void 0,
|
|
1091
498
|
validationFailure: void 0,
|
|
1092
499
|
attemptsPerStep: normalizeAttempts(input.attemptsPerStep),
|
|
@@ -1143,6 +550,7 @@ const videoSelfieRecordingMachine = videoSelfieRecordingSetup.createMachine({
|
|
|
1143
550
|
},
|
|
1144
551
|
on: {
|
|
1145
552
|
DETECTION_STATUS: { actions: "setDetectionStatus" },
|
|
553
|
+
ORIENTATION: { actions: "setOrientation" },
|
|
1146
554
|
DETECTION_DONE: ADVANCE_TRANSITIONS,
|
|
1147
555
|
NEXT_STEP: ADVANCE_TRANSITIONS,
|
|
1148
556
|
VALIDATION_FAILED: {
|
|
@@ -1286,6 +694,7 @@ function mapState(snapshot) {
|
|
|
1286
694
|
stream: context.stream,
|
|
1287
695
|
composite: context.composite,
|
|
1288
696
|
detectionStatus: context.detectionStatus,
|
|
697
|
+
orientation: context.orientation,
|
|
1289
698
|
validationFailure: context.validationFailure,
|
|
1290
699
|
attemptsRemaining: context.attemptsRemaining,
|
|
1291
700
|
recordingId: context.recordingId,
|