@sekyro/web 0.1.0-rc.3 → 0.1.0-rc.5

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +44 -0
  3. package/dist/{capture-session-v3-CvIfcwST.d.ts → capture-session-v3-Okq0EQHG.d.ts} +38 -2
  4. package/dist/{capture-session-v3-COIO_F2w.d.cts → capture-session-v3-UQU_WjO2.d.cts} +38 -2
  5. package/dist/{chunk-FIXX2AXC.js → chunk-SGDXLAXR.js} +309 -10
  6. package/dist/chunk-SGDXLAXR.js.map +1 -0
  7. package/dist/{chunk-7TC6TOZ4.js → chunk-TG5IE552.js} +37 -4
  8. package/dist/chunk-TG5IE552.js.map +1 -0
  9. package/dist/client/index.cjs.map +1 -1
  10. package/dist/client/index.d.cts +1 -1
  11. package/dist/client/index.d.ts +1 -1
  12. package/dist/core/index.cjs +36 -3
  13. package/dist/core/index.cjs.map +1 -1
  14. package/dist/core/index.d.cts +2 -2
  15. package/dist/core/index.d.ts +2 -2
  16. package/dist/core/index.js +1 -1
  17. package/dist/{create-verification-CswF2As-.d.ts → create-verification-CA-3szPI.d.cts} +108 -8
  18. package/dist/{create-verification-CP18eq1Q.d.cts → create-verification-c98uAxbl.d.ts} +108 -8
  19. package/dist/{hosted-client-BpvBqu9f.d.cts → hosted-client-DWzCRYJK.d.cts} +14 -1
  20. package/dist/{hosted-client-BpvBqu9f.d.ts → hosted-client-DWzCRYJK.d.ts} +14 -1
  21. package/dist/index.cjs +384 -13
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +25 -3
  24. package/dist/index.d.ts +25 -3
  25. package/dist/index.js +61 -4
  26. package/dist/index.js.map +1 -1
  27. package/dist/internal/index.cjs +261 -11
  28. package/dist/internal/index.cjs.map +1 -1
  29. package/dist/internal/index.d.cts +4 -4
  30. package/dist/internal/index.d.ts +4 -4
  31. package/dist/internal/index.js +12 -2
  32. package/dist/internal/index.js.map +1 -1
  33. package/package.json +1 -1
  34. package/dist/chunk-7TC6TOZ4.js.map +0 -1
  35. package/dist/chunk-FIXX2AXC.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @sekyro/web
2
2
 
3
+ ## 0.1.0-rc.5
4
+
5
+ ### Minor Changes
6
+
7
+ - a14ac15: Pre-capture building blocks: choose the camera at start, warm the face detector ahead of time, and read the camera state for a "get ready" screen.
8
+
9
+ - **Camera at start.** `handle.start({ facing: "user" | "environment" })` (new `LivenessStartOptions`, `CameraFacing` types) picks the camera for this attempt; `retry()` keeps it and `switchCamera()` still flips it. `start()` with no options behaves as before, and `LivenessCaptureOptions.facing` remains the default. `verification.liveness()` handles pass the option through.
10
+ - **Detector preload.** `preloadLivenessAssets({ assetBaseUrl?, idle?, respectSaveData? })` downloads and initialises the face detector so the capture starts instantly instead of racing the cold-start deadline. It is idempotent per `assetBaseUrl`, never rejects, and resolves the settled status (`LivenessAssetsStatus`): `'ready'`; `'failed'` (call it again to retry); or `'idle'`, meaning nothing was preloaded (server-side rendering, no camera API, or Data-Saver with `respectSaveData: true`) — start normally. `idle: true` defers the load to browser idle time; a capture that needs the detector meanwhile starts it at once. The preload warms the blaze (MediaPipe) tier only, with a generous 120 s init deadline; captures without a preload keep the existing detector ladder and deadline, unchanged.
11
+ - **Used automatically.** Every `createLivenessCapture` / `verification.liveness()` capture with the same `assetBaseUrl` reuses the preloaded detector — no extra wiring — and destroying or retrying a capture never frees it. The preload is shared across duplicate copies of `@sekyro/web` on the page.
12
+ - **Status store.** `getLivenessAssetsStatus(assetBaseUrl?)` and `subscribeLivenessAssets(listener, assetBaseUrl?)` (the `useSyncExternalStore` contract: no emit on subscribe) drive a Start button's loading / retry state.
13
+ - **Release.** `releaseLivenessAssets(assetBaseUrl?)` frees the warmed detector (or cancels a pending idle load) when the user leaves the flow. Never call it while a capture is mounted.
14
+ - **Camera probes.** `queryCameraPermission()` and `subscribeCameraPermission(listener)` report `CameraPermissionState` (`'granted' | 'prompt' | 'denied' | 'unknown'`; the subscription emits the current state first, then every change). `hasMultipleCameras()` tells whether a front/back choice makes sense (phones and tablets always; desktops with two or more cameras). All are safe to call during server-side rendering and never throw.
15
+ - 66522c3: The liveness capture now keeps the screen awake while the camera is live.
16
+
17
+ - **Screen Wake Lock.** From `starting` through `gating` and `recording`, the capture holds a Screen Wake Lock so the phone does not dim or lock while the person positions their face. It is released on `captured`, `error` and `destroy()`, taken again on `retry()`, and re-taken automatically when the person returns to the page (browsers drop the lock when a page is hidden).
18
+ - **On by default, best-effort.** Browsers without the Screen Wake Lock API, or a refused request (page not visible, insecure context, blocked by Permissions-Policy), leave the capture exactly as before — nothing throws and no `error` is emitted.
19
+ - **Opt out:** `keepScreenAwake: false` on `createLivenessCapture({ … })` / `verification.liveness({ … })` never requests the lock.
20
+ - **Iframes:** if you embed the capture in an iframe, allow the permission alongside the camera — `<iframe allow="camera; screen-wake-lock">` — and do not send `Permissions-Policy: screen-wake-lock=()`. Without it the capture still works; the screen may just dim.
21
+ - `@sekyro/react`'s `<LivenessCapture>` gets this automatically once it runs on this `@sekyro/web` version.
22
+
23
+ ## 0.1.0-rc.4
24
+
25
+ ### Minor Changes
26
+
27
+ - 9991ea5: Face-capture timing on `captured` and on the liveness submission (session insights).
28
+
29
+ - `CapturedArtifacts` gains `engine` (`'v3'`) and three optional whole-millisecond durations measured by the capture engine with `performance.now()`: `cameraReadyMs` (camera request → preview live), `faceAcquireMs` (camera ready → first accepted face) and `captureMs` (first accepted face → gate progress 100 %, i.e. capture complete, before the clip window and any upload; a face lost and re-acquired keeps the first start). The core `CaptureArtifacts` carries the same marks as `timing`.
30
+ - `createVerification` forwards them, together with the already-known `width` / `height` / `clipMs` and the engine id, as `input.capture` on the `liveness` submission (`LivenessInput.capture`, `LivenessCaptureInput`) so the Sekyro dashboard can show how long the face capture, the upload and the processing of each check took. Nothing else changes on the wire; `face_match` is untouched.
31
+ - `@sekyro/react`: `<LivenessCapture onCaptured>` receives the new fields unchanged (no code change — the dependency bump only).
32
+
3
33
  ## 0.1.0-rc.3
4
34
 
5
35
  ### Patch Changes
package/README.md CHANGED
@@ -31,6 +31,50 @@ under `/models-v3` (or `assetBaseUrl`), and your page origin registered with Sek
31
31
  > task (Changesets + Trusted Publishing). Sekyro's own hosted page consumes it via a
32
32
  > `file:` link today. Formerly `@ibtikar/identity-web-sdk` (internal).
33
33
 
34
+ ## Preload & camera probes
35
+
36
+ Warm the face detector before the user taps Start (on the step before the
37
+ capture, or at mount), and read the camera permission for your "get ready" UI:
38
+
39
+ ```ts
40
+ import { createLivenessCapture, getLivenessAssetsStatus, hasMultipleCameras,
41
+ preloadLivenessAssets, subscribeCameraPermission, subscribeLivenessAssets } from "@sekyro/web";
42
+
43
+ void preloadLivenessAssets({ assetBaseUrl: "/models-v3", idle: true }); // never rejects
44
+ const gateStart = (s: string) => (startBtn.disabled = s === "loading");
45
+ gateStart(getLivenessAssetsStatus("/models-v3")); // subscribe does not emit the current status
46
+ subscribeLivenessAssets(gateStart, "/models-v3");
47
+ subscribeCameraPermission((p) => showCameraRow(p)); // granted|prompt|denied|unknown
48
+ const showFacingChoice = await hasMultipleCameras();
49
+
50
+ const cap = createLivenessCapture({ video, assetBaseUrl: "/models-v3" });
51
+ await cap.start({ facing: "user" }); // reuses the warm detector automatically
52
+ ```
53
+
54
+ - `preloadLivenessAssets` is idempotent per `assetBaseUrl` and resolves the settled
55
+ status: `'ready'`, `'failed'` (call it again to retry), or `'idle'` — nothing was
56
+ preloaded (SSR, no camera API, Data-Saver with `respectSaveData`); just start
57
+ normally. `idle: true` defers the load to browser idle time; a capture that
58
+ starts meanwhile begins it at once.
59
+ - The preload warms the blaze (MediaPipe) tier with a generous deadline. Every
60
+ capture created afterwards with the same `assetBaseUrl` uses it without any extra
61
+ wiring, and destroying a capture never frees it; call
62
+ `releaseLivenessAssets(assetBaseUrl)` when the user leaves the flow (never while a
63
+ capture is mounted). Without a preload the capture loads the detector itself, as
64
+ before.
65
+ - `getLivenessAssetsStatus` / `subscribeLivenessAssets` follow the
66
+ `useSyncExternalStore` contract (no emit on subscribe). `subscribeCameraPermission`
67
+ emits the current state first, then every change; `queryCameraPermission` is the
68
+ one-shot read. Both report `'unknown'` where the Permissions API cannot tell.
69
+ - `start({ facing })` picks the camera for this attempt and its retries;
70
+ `switchCamera()` still flips it mid-capture.
71
+ - `keepScreenAwake` (capture option, default `true`) holds a Screen Wake Lock while
72
+ the camera is live (`starting` / `gating` / `recording`), released on `captured`,
73
+ `error` and `destroy()`, re-taken on `retry()` and when the page is visible again.
74
+ Best-effort — unsupported or refused requests never affect the capture. In an
75
+ iframe, allow it: `<iframe allow="camera; screen-wake-lock">`. Pass `false` to
76
+ never request it.
77
+
34
78
  ## Entry points
35
79
 
36
80
  | Export | Contents | Public API |
@@ -105,6 +105,23 @@ interface GateChecks {
105
105
  goodQuality: boolean;
106
106
  stable: boolean;
107
107
  }
108
+ /**
109
+ * Client-side capture timing (face-capture duration, 2026-10-17), measured
110
+ * by the engine with its monotonic clock (`performance.now()` by default) and
111
+ * rounded to whole milliseconds. All fields are optional: a phase that never
112
+ * happened (e.g. no face ever detected before a retry) is simply absent.
113
+ */
114
+ interface CaptureTiming {
115
+ /** `getUserMedia` call → stream attached and the preview playing. */
116
+ cameraReadyMs?: number;
117
+ /** Camera ready → the first tick on which the GATE accepted the face
118
+ * (present + size / centering / quality good enough to make progress —
119
+ * not merely detected). */
120
+ faceAcquireMs?: number;
121
+ /** FIRST accepted face → gate progress 100 % (capture complete, BEFORE the
122
+ * clip window / upload). A face lost and re-acquired keeps the first start. */
123
+ captureMs?: number;
124
+ }
108
125
  /** Capture output. Upload is NOT the engine's job — hosts submit these themselves. */
109
126
  interface CaptureArtifacts {
110
127
  /** Absent in photo mode. */
@@ -115,6 +132,8 @@ interface CaptureArtifacts {
115
132
  keyframe: Blob;
116
133
  /** JPEG data URL of the keyframe canvas (v1 preview, quality 0.92). */
117
134
  previewDataUrl: string;
135
+ /** Capture-phase timing of the attempt that produced these artifacts. */
136
+ timing?: CaptureTiming;
118
137
  }
119
138
  interface CaptureSessionEvents {
120
139
  statechange: {
@@ -218,6 +237,10 @@ interface V3GateTick {
218
237
  guidanceKey: string;
219
238
  /** Fire signal: p ≥ 1 AND no second bad tick (q < Q_GOOD) in READY_WINDOW_MS. */
220
239
  ready: boolean;
240
+ /** The face on THIS tick is ACCEPTED by the gate — present and every factor
241
+ * (size, centering, pose, sharpness, exposure, motion) good enough that the
242
+ * integrator RISES (q ≥ Q_GOOD). The engine's "first accepted face" mark. */
243
+ accepted: boolean;
221
244
  }
222
245
  declare class FaceGateV3 {
223
246
  private readonly t;
@@ -406,6 +429,11 @@ interface CaptureSessionV3Options {
406
429
  now?: () => number;
407
430
  }
408
431
  type Handler<K extends keyof CaptureSessionV3Events> = (payload: CaptureSessionV3Events[K]) => void;
432
+ /** Per-start options (the public handle's `start({ facing })`). */
433
+ interface CaptureSessionV3StartOptions {
434
+ /** Camera for this attempt AND later retries; absent → keep the current one. */
435
+ facingMode?: "user" | "environment";
436
+ }
409
437
  declare class CaptureSessionV3 {
410
438
  private readonly options;
411
439
  private readonly handlers;
@@ -419,6 +447,10 @@ declare class CaptureSessionV3 {
419
447
  private profiler;
420
448
  private lastGuidanceKey;
421
449
  private positioningStartedAt;
450
+ private cameraRequestedAt;
451
+ private cameraReadyAt;
452
+ private faceAcquiredAt;
453
+ private captureCompleteAt;
422
454
  private fired;
423
455
  private carriedDegrade;
424
456
  private carriedMeans;
@@ -426,7 +458,9 @@ declare class CaptureSessionV3 {
426
458
  get state(): CaptureState;
427
459
  on<K extends keyof CaptureSessionV3Events>(event: K, handler: Handler<K>): () => void;
428
460
  private emit;
429
- start(): Promise<void>;
461
+ start(options?: CaptureSessionV3StartOptions): Promise<void>;
462
+ /** The camera the current/next attempt requests (start option, switchCamera toggles). */
463
+ get facingMode(): "user" | "environment";
430
464
  /** Full reset + camera restart — the documented recovery path (v1 parity). */
431
465
  retry(): void;
432
466
  switchCamera(): void;
@@ -441,6 +475,8 @@ declare class CaptureSessionV3 {
441
475
  * sharpest wins (reuses frame-quality.sharpness via the capture seam). */
442
476
  private collectKeyframes;
443
477
  private finishCapture;
478
+ /** The attempt's capture-phase timing (whole ms, ≥ 0); undefined when no mark landed. */
479
+ private captureTiming;
444
480
  private defaultKeyframe;
445
481
  /** Reused downscale canvas — falls back to the raw video where canvas 2D
446
482
  * is unavailable (jsdom) so tests and exotic hosts keep detecting. */
@@ -455,4 +491,4 @@ declare class CaptureSessionV3 {
455
491
  private now;
456
492
  }
457
493
 
458
- export { V3_GATE_DEFAULTS as A, VIDEO_BPS as B, type CameraErrorKind as C, DEFAULT_CLIP_MIME as D, type EscalationClipArtifact as E, FaceGateV3 as F, type GateChecks as G, buildLivenessV2FormData as H, cameraPreflight as I, classifyDevice as J, KEYFRAME_CANDIDATES as K, extForMime as L, MAX_CLIP_BYTES as M, isClipTooLarge as N, isMediaRecorderSupported as O, mapGetUserMediaError as P, pickMimeType as Q, probeDevice as R, STOP_GRACE_MS as S, TIMESLICE_MS as T, type V3ChecksPayload as V, CLIP_MS as a, type CaptureArtifacts as b, type CaptureErrorKind as c, type CaptureSessionEvents as d, CaptureSessionV3 as e, type CaptureSessionV3Events as f, type CaptureSessionV3Options as g, type CaptureState as h, ClipError as i, type ClipErrorKind as j, ClipRecorder as k, type ClipResult as l, DEVICE_PROFILES as m, type DeviceClass as n, type DeviceProbe as o, type DeviceProfile as p, DeviceProfiler as q, type EscalationHook as r, KEYFRAME_WINDOW_MS as s, MIME_CANDIDATES as t, type V3GateFactor as u, type V3GateQuality as v, type V3GateThresholds as w, type V3GateTick as x, type V3GateTickInput as y, type V3TelemetryEvent as z };
494
+ export { type V3GateTickInput as A, type V3TelemetryEvent as B, type CameraErrorKind as C, DEFAULT_CLIP_MIME as D, type EscalationClipArtifact as E, FaceGateV3 as F, type GateChecks as G, V3_GATE_DEFAULTS as H, VIDEO_BPS as I, buildLivenessV2FormData as J, KEYFRAME_CANDIDATES as K, cameraPreflight as L, MAX_CLIP_BYTES as M, classifyDevice as N, extForMime as O, isClipTooLarge as P, isMediaRecorderSupported as Q, mapGetUserMediaError as R, STOP_GRACE_MS as S, TIMESLICE_MS as T, pickMimeType as U, type V3ChecksPayload as V, probeDevice as W, CLIP_MS as a, type CaptureArtifacts as b, type CaptureErrorKind as c, type CaptureSessionEvents as d, CaptureSessionV3 as e, type CaptureSessionV3Events as f, type CaptureSessionV3Options as g, type CaptureSessionV3StartOptions as h, type CaptureState as i, type CaptureTiming as j, ClipError as k, type ClipErrorKind as l, ClipRecorder as m, type ClipResult as n, DEVICE_PROFILES as o, type DeviceClass as p, type DeviceProbe as q, type DeviceProfile as r, DeviceProfiler as s, type EscalationHook as t, KEYFRAME_WINDOW_MS as u, MIME_CANDIDATES as v, type V3GateFactor as w, type V3GateQuality as x, type V3GateThresholds as y, type V3GateTick as z };
@@ -105,6 +105,23 @@ interface GateChecks {
105
105
  goodQuality: boolean;
106
106
  stable: boolean;
107
107
  }
108
+ /**
109
+ * Client-side capture timing (face-capture duration, 2026-10-17), measured
110
+ * by the engine with its monotonic clock (`performance.now()` by default) and
111
+ * rounded to whole milliseconds. All fields are optional: a phase that never
112
+ * happened (e.g. no face ever detected before a retry) is simply absent.
113
+ */
114
+ interface CaptureTiming {
115
+ /** `getUserMedia` call → stream attached and the preview playing. */
116
+ cameraReadyMs?: number;
117
+ /** Camera ready → the first tick on which the GATE accepted the face
118
+ * (present + size / centering / quality good enough to make progress —
119
+ * not merely detected). */
120
+ faceAcquireMs?: number;
121
+ /** FIRST accepted face → gate progress 100 % (capture complete, BEFORE the
122
+ * clip window / upload). A face lost and re-acquired keeps the first start. */
123
+ captureMs?: number;
124
+ }
108
125
  /** Capture output. Upload is NOT the engine's job — hosts submit these themselves. */
109
126
  interface CaptureArtifacts {
110
127
  /** Absent in photo mode. */
@@ -115,6 +132,8 @@ interface CaptureArtifacts {
115
132
  keyframe: Blob;
116
133
  /** JPEG data URL of the keyframe canvas (v1 preview, quality 0.92). */
117
134
  previewDataUrl: string;
135
+ /** Capture-phase timing of the attempt that produced these artifacts. */
136
+ timing?: CaptureTiming;
118
137
  }
119
138
  interface CaptureSessionEvents {
120
139
  statechange: {
@@ -218,6 +237,10 @@ interface V3GateTick {
218
237
  guidanceKey: string;
219
238
  /** Fire signal: p ≥ 1 AND no second bad tick (q < Q_GOOD) in READY_WINDOW_MS. */
220
239
  ready: boolean;
240
+ /** The face on THIS tick is ACCEPTED by the gate — present and every factor
241
+ * (size, centering, pose, sharpness, exposure, motion) good enough that the
242
+ * integrator RISES (q ≥ Q_GOOD). The engine's "first accepted face" mark. */
243
+ accepted: boolean;
221
244
  }
222
245
  declare class FaceGateV3 {
223
246
  private readonly t;
@@ -406,6 +429,11 @@ interface CaptureSessionV3Options {
406
429
  now?: () => number;
407
430
  }
408
431
  type Handler<K extends keyof CaptureSessionV3Events> = (payload: CaptureSessionV3Events[K]) => void;
432
+ /** Per-start options (the public handle's `start({ facing })`). */
433
+ interface CaptureSessionV3StartOptions {
434
+ /** Camera for this attempt AND later retries; absent → keep the current one. */
435
+ facingMode?: "user" | "environment";
436
+ }
409
437
  declare class CaptureSessionV3 {
410
438
  private readonly options;
411
439
  private readonly handlers;
@@ -419,6 +447,10 @@ declare class CaptureSessionV3 {
419
447
  private profiler;
420
448
  private lastGuidanceKey;
421
449
  private positioningStartedAt;
450
+ private cameraRequestedAt;
451
+ private cameraReadyAt;
452
+ private faceAcquiredAt;
453
+ private captureCompleteAt;
422
454
  private fired;
423
455
  private carriedDegrade;
424
456
  private carriedMeans;
@@ -426,7 +458,9 @@ declare class CaptureSessionV3 {
426
458
  get state(): CaptureState;
427
459
  on<K extends keyof CaptureSessionV3Events>(event: K, handler: Handler<K>): () => void;
428
460
  private emit;
429
- start(): Promise<void>;
461
+ start(options?: CaptureSessionV3StartOptions): Promise<void>;
462
+ /** The camera the current/next attempt requests (start option, switchCamera toggles). */
463
+ get facingMode(): "user" | "environment";
430
464
  /** Full reset + camera restart — the documented recovery path (v1 parity). */
431
465
  retry(): void;
432
466
  switchCamera(): void;
@@ -441,6 +475,8 @@ declare class CaptureSessionV3 {
441
475
  * sharpest wins (reuses frame-quality.sharpness via the capture seam). */
442
476
  private collectKeyframes;
443
477
  private finishCapture;
478
+ /** The attempt's capture-phase timing (whole ms, ≥ 0); undefined when no mark landed. */
479
+ private captureTiming;
444
480
  private defaultKeyframe;
445
481
  /** Reused downscale canvas — falls back to the raw video where canvas 2D
446
482
  * is unavailable (jsdom) so tests and exotic hosts keep detecting. */
@@ -455,4 +491,4 @@ declare class CaptureSessionV3 {
455
491
  private now;
456
492
  }
457
493
 
458
- export { V3_GATE_DEFAULTS as A, VIDEO_BPS as B, type CameraErrorKind as C, DEFAULT_CLIP_MIME as D, type EscalationClipArtifact as E, FaceGateV3 as F, type GateChecks as G, buildLivenessV2FormData as H, cameraPreflight as I, classifyDevice as J, KEYFRAME_CANDIDATES as K, extForMime as L, MAX_CLIP_BYTES as M, isClipTooLarge as N, isMediaRecorderSupported as O, mapGetUserMediaError as P, pickMimeType as Q, probeDevice as R, STOP_GRACE_MS as S, TIMESLICE_MS as T, type V3ChecksPayload as V, CLIP_MS as a, type CaptureArtifacts as b, type CaptureErrorKind as c, type CaptureSessionEvents as d, CaptureSessionV3 as e, type CaptureSessionV3Events as f, type CaptureSessionV3Options as g, type CaptureState as h, ClipError as i, type ClipErrorKind as j, ClipRecorder as k, type ClipResult as l, DEVICE_PROFILES as m, type DeviceClass as n, type DeviceProbe as o, type DeviceProfile as p, DeviceProfiler as q, type EscalationHook as r, KEYFRAME_WINDOW_MS as s, MIME_CANDIDATES as t, type V3GateFactor as u, type V3GateQuality as v, type V3GateThresholds as w, type V3GateTick as x, type V3GateTickInput as y, type V3TelemetryEvent as z };
494
+ export { type V3GateTickInput as A, type V3TelemetryEvent as B, type CameraErrorKind as C, DEFAULT_CLIP_MIME as D, type EscalationClipArtifact as E, FaceGateV3 as F, type GateChecks as G, V3_GATE_DEFAULTS as H, VIDEO_BPS as I, buildLivenessV2FormData as J, KEYFRAME_CANDIDATES as K, cameraPreflight as L, MAX_CLIP_BYTES as M, classifyDevice as N, extForMime as O, isClipTooLarge as P, isMediaRecorderSupported as Q, mapGetUserMediaError as R, STOP_GRACE_MS as S, TIMESLICE_MS as T, pickMimeType as U, type V3ChecksPayload as V, probeDevice as W, CLIP_MS as a, type CaptureArtifacts as b, type CaptureErrorKind as c, type CaptureSessionEvents as d, CaptureSessionV3 as e, type CaptureSessionV3Events as f, type CaptureSessionV3Options as g, type CaptureSessionV3StartOptions as h, type CaptureState as i, type CaptureTiming as j, ClipError as k, type ClipErrorKind as l, ClipRecorder as m, type ClipResult as n, DEVICE_PROFILES as o, type DeviceClass as p, type DeviceProbe as q, type DeviceProfile as r, DeviceProfiler as s, type EscalationHook as t, KEYFRAME_WINDOW_MS as u, MIME_CANDIDATES as v, type V3GateFactor as w, type V3GateQuality as x, type V3GateThresholds as y, type V3GateTick as z };