@incodetech/web 2.1.0-rc.2 → 2.1.0-rc.3

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 (153) hide show
  1. package/dist/ae-signature/ae-signature.es.js +2 -2
  2. package/dist/ae-signature/styles.css +59 -45
  3. package/dist/antifraud/antifraud.es.js +4 -4
  4. package/dist/authentication/authentication.es.js +5 -4
  5. package/dist/base.css +87 -59
  6. package/dist/{button-Ch5-QgHB.js → button-Dz6AsbmF.js} +2 -1
  7. package/dist/cameraView-DIEzM5ru.js +47 -0
  8. package/dist/{tutorial-Cap8qKvM.js → capture-CkGvdDNH.js} +18 -568
  9. package/dist/certificate-issuance/certificate-issuance.es.js +7 -7
  10. package/dist/consent/consent.es.js +8 -8
  11. package/dist/{countrySelector-B4WuNUya.js → countrySelector-SvUOyPo0.js} +1 -1
  12. package/dist/cpf-ocr/cpf-ocr.es.js +1 -1
  13. package/dist/cpfOcr-B79245-3.js +2 -0
  14. package/dist/{cpfOcr-liTE9e70.js → cpfOcr-BhxT-lRN.js} +5 -5
  15. package/dist/cross-document-data-match/cross-document-data-match.es.js +4 -4
  16. package/dist/curp-validation/curp-validation.es.js +7 -7
  17. package/dist/{customFields-BQ4scZfL.js → customFields-BDsXR7A-.js} +6 -6
  18. package/dist/{customWatchlist-7s0_wGtE.js → customWatchlist-CYoRNCim.js} +5 -5
  19. package/dist/document-capture/document-capture.es.js +1 -1
  20. package/dist/documentCapture-DXYYyxZl.js +2 -0
  21. package/dist/{documentCapture-CwoSD_Iq.js → documentCapture-DhbO-A-V.js} +11 -9
  22. package/dist/{dynamicForms-DvTU65bW.js → dynamicForms-BifGbC9F.js} +19 -8
  23. package/dist/ekyb/ekyb.es.js +1 -1
  24. package/dist/ekybModule-C6Nttked.js +2 -0
  25. package/dist/{ekybModule-CwZvxios.js → ekybModule-DGnTw5UV.js} +12 -12
  26. package/dist/ekyc/ekyc.es.js +1 -1
  27. package/dist/ekycModule-CDIEjI6V.js +2 -0
  28. package/dist/{ekycModule-jkXByPXe.js → ekycModule-Dxpdd0ns.js} +10 -10
  29. package/dist/electronic-signature/electronic-signature.es.js +1 -1
  30. package/dist/{electronic-signature-h1sAGg7l.js → electronic-signature-Ueoffasr.js} +37 -26
  31. package/dist/email/email.es.js +7 -7
  32. package/dist/{emailInput-BRMJMJV6.js → emailInput-DsLkDtER.js} +5 -5
  33. package/dist/{expiredId-D17oN5K2.js → expiredId-BZXLrLk-.js} +4 -4
  34. package/dist/{extensibility-CTmAsaji.js → extensibility-7sRIN0JC.js} +41 -76
  35. package/dist/extensibility.es.js +13 -11
  36. package/dist/face-match/face-match.es.js +1 -1
  37. package/dist/face-match/styles.css +4 -0
  38. package/dist/faceMatch-B_HvxLm_.js +2 -0
  39. package/dist/{faceMatch-Dez_bq3n.js → faceMatch-DyTBoMDm.js} +8 -8
  40. package/dist/field-comparison/field-comparison.es.js +1 -1
  41. package/dist/fieldComparison-DfNEuEE5.js +2 -0
  42. package/dist/{fieldComparison-BelzSC48.js → fieldComparison-L_knHqgw.js} +7 -7
  43. package/dist/fiscal-qr/fiscal-qr.es.js +8 -7
  44. package/dist/flow/flow.es.js +22 -9
  45. package/dist/flow/styles.css +4151 -3042
  46. package/dist/geolocation/geolocation.es.js +14 -9
  47. package/dist/{governmentValidation/governmentValidation.es.js → government-validation/government-validation.es.js} +10 -14
  48. package/dist/{homeScreen-BIdVm9KA.js → homeScreen-B6T0JVh8.js} +2 -2
  49. package/dist/{hooks-Da_yP_Dr.js → hooks-CNu7o-v8.js} +39 -2
  50. package/dist/{i18n-DoP1NB7u.js → i18n-CU4xq8qC.js} +1 -1
  51. package/dist/id/id.es.js +76 -46
  52. package/dist/id/styles.css +1 -9
  53. package/dist/id-ocr/styles.css +12 -2
  54. package/dist/id-verification/id-verification.es.js +5 -5
  55. package/dist/{idOcr-C4K2XVJr.js → idOcr-WFBvqy3b.js} +31 -13
  56. package/dist/identity-reuse/identity-reuse.es.js +6 -6
  57. package/dist/{incodeComponent-Cmi1rlWs.js → incodeComponent-CfzJGETt.js} +2 -2
  58. package/dist/{incodeModule-M8DszCee.js → incodeModule-B-4_3JrK.js} +1 -1
  59. package/dist/index.es.js +1 -1
  60. package/dist/{mandatoryConsent-DOQ0DKgM.js → mandatoryConsent-D0GTKu-H.js} +7 -7
  61. package/dist/{optionAccessibleLabel-_nvVCTSL.js → optionAccessibleLabel-gfF-58Mv.js} +3 -3
  62. package/dist/{otpInput-Q_kzSZeD.js → otpInput-CnDc6pQm.js} +12 -11
  63. package/dist/{pdf-BMUXKJuC.js → pdf-BqtJTlor.js} +1 -1
  64. package/dist/{pdfViewer-BewML6eg.js → pdfViewer-B97DmT9m.js} +57 -20
  65. package/dist/phone/phone.es.js +6 -6
  66. package/dist/{processing-Boki1Z8j.js → processing-BeUMfdJJ.js} +1 -1
  67. package/dist/qe-signature/qe-signature.es.js +2 -2
  68. package/dist/{radioGroupComposed-TuAWUAFK.js → radioGroupComposed-DuQxslB2.js} +1 -1
  69. package/dist/redirect-to-mobile/redirect-to-mobile.es.js +17 -18
  70. package/dist/redirect-to-mobile/styles.css +2 -2
  71. package/dist/{richText-DsTP4H3j.js → richText-CB1fmegc.js} +1 -1
  72. package/dist/selfie/selfie.es.js +8 -7
  73. package/dist/selfie/styles.css +133 -63
  74. package/dist/signature/signature.es.js +8 -8
  75. package/dist/spinner-BCDCoi9C.js +1 -0
  76. package/dist/{spinner-BRNNKqPN.js → spinner-BMeIEK1d.js} +12 -6
  77. package/dist/themes/dark.css +16 -0
  78. package/dist/themes/light.css +16 -0
  79. package/dist/{transitionSpinner-4rPkt-KM.js → transitionSpinner-CuNCqHNi.js} +9 -8
  80. package/dist/tutorial-CCfPuVKX.js +706 -0
  81. package/dist/types/ae-signature.d.ts +23 -1
  82. package/dist/types/antifraud.d.ts +23 -1
  83. package/dist/types/authentication.d.ts +23 -1
  84. package/dist/types/certificate-issuance.d.ts +23 -1
  85. package/dist/types/consent.d.ts +23 -1
  86. package/dist/types/cross-document-data-match.d.ts +23 -1
  87. package/dist/types/curp-validation.d.ts +23 -1
  88. package/dist/types/document-capture.d.ts +23 -1
  89. package/dist/types/ekyb.d.ts +23 -1
  90. package/dist/types/ekyc.d.ts +23 -1
  91. package/dist/types/electronic-signature.d.ts +23 -1
  92. package/dist/types/email.d.ts +23 -1
  93. package/dist/types/extensibility.d.ts +39 -2
  94. package/dist/types/face-match.d.ts +23 -1
  95. package/dist/types/field-comparison.d.ts +23 -1
  96. package/dist/types/fiscal-qr.d.ts +23 -1
  97. package/dist/types/flow.d.ts +23 -1
  98. package/dist/types/geolocation.d.ts +27 -2
  99. package/dist/types/{governmentValidation.d.ts → government-validation.d.ts} +23 -1
  100. package/dist/types/id-verification.d.ts +23 -1
  101. package/dist/types/id.d.ts +23 -1
  102. package/dist/types/identity-reuse.d.ts +23 -1
  103. package/dist/types/phone.d.ts +23 -1
  104. package/dist/types/qe-signature.d.ts +23 -1
  105. package/dist/types/selfie.d.ts +23 -1
  106. package/dist/types/signature.d.ts +23 -1
  107. package/dist/types/video-selfie.d.ts +72 -0
  108. package/dist/types/watchlist.d.ts +23 -1
  109. package/dist/types/workflow.d.ts +23 -1
  110. package/dist/{useModuleLoader-Kt78XfNR.js → useModuleLoader-Gvo9qscB.js} +38 -23
  111. package/dist/{verificationResult-B6PBXbp9.js → verificationResult-BWWkmeiA.js} +3 -3
  112. package/dist/video-selfie/styles.css +1644 -0
  113. package/dist/video-selfie/video-selfie.es.js +854 -0
  114. package/dist/watchlist/watchlist.es.js +5 -5
  115. package/dist/{watchlistForBusiness-DCKlKG81.js → watchlistForBusiness-D2Uo_TwF.js} +7 -7
  116. package/dist/workflow/styles.css +148 -76
  117. package/dist/workflow/workflow.es.js +23 -27
  118. package/package.json +29 -2
  119. package/dist/cpfOcr-BJOYoITy.js +0 -2
  120. package/dist/documentCapture-3RHCHepT.js +0 -2
  121. package/dist/ekybModule-BkVQBQvW.js +0 -2
  122. package/dist/ekycModule-BIbj7hr1.js +0 -2
  123. package/dist/faceMatch-C0-RPzrc.js +0 -2
  124. package/dist/fieldComparison-7FUznk_9.js +0 -2
  125. package/dist/spinner-zRaUjXtH.js +0 -1
  126. /package/dist/{aligndevicelottie-DMXPhIDs.js → aligndevicelottie-DFscByAI.js} +0 -0
  127. /package/dist/{back-horizontal-hint-DNIIDrEW.js → back-horizontal-hint-xTnSQbzn.js} +0 -0
  128. /package/dist/{back-tutorial-B8JJSJBB.js → back-tutorial-cI_4VHmE.js} +0 -0
  129. /package/dist/{back-vertical-hint-CW6ZS7bP.js → back-vertical-hint-BWWlHfX2.js} +0 -0
  130. /package/dist/{backdevicelottie-By75Bznp.js → backdevicelottie-COyhTrxM.js} +0 -0
  131. /package/dist/{blurdevicelottie-C_9VAHkM.js → blurdevicelottie-BLVeJHEG.js} +0 -0
  132. /package/dist/{browser-ponyfill-C_DpU0lQ.js → browser-ponyfill-Df13Th-G.js} +0 -0
  133. /package/dist/{defineProperty-CTu-cLWm.js → defineProperty-Qjefk7Uf.js} +0 -0
  134. /package/dist/{flip-animation-st9bra1p.js → flip-animation-CZYSUtMm.js} +0 -0
  135. /package/dist/{front-horizontal-hint-DvME-aVk.js → front-horizontal-hint-B84GgTO1.js} +0 -0
  136. /package/dist/{front-vertical-hint-BUG1VMsP.js → front-vertical-hint-Bs_avngq.js} +0 -0
  137. /package/dist/{frontdevicelottie-uObOEs8p.js → frontdevicelottie-B4tE2PYQ.js} +0 -0
  138. /package/dist/{glaredevicelottie-CsfIgqIc.js → glaredevicelottie-D1pR73sx.js} +0 -0
  139. /package/dist/{governmentValidation → government-validation}/styles.css +0 -0
  140. /package/dist/{id-laser-h-BvVSaLyU.js → id-laser-h-CzPegPMn.js} +0 -0
  141. /package/dist/{id-laser-v-Dj_RN_s9.js → id-laser-v-BiUXkM4x.js} +0 -0
  142. /package/dist/{id-tutorial-BOOsXlAJ.js → id-tutorial-DwO90SAm.js} +0 -0
  143. /package/dist/{lottie_light-BG-RL2Iu.js → lottie_light-C6B2ec41.js} +0 -0
  144. /package/dist/{numberedStep-Dc0BUU-j.js → numberedStep-CEb-lFJm.js} +0 -0
  145. /package/dist/{passport-horizontal-hint-BhpVt73n.js → passport-horizontal-hint-Bj0ZJY0g.js} +0 -0
  146. /package/dist/{passport-tutorial-CeSup6m9.js → passport-tutorial-D9JNsMsM.js} +0 -0
  147. /package/dist/{passport-vertical-hint-CVRBnZXS.js → passport-vertical-hint-Dfk77xUJ.js} +0 -0
  148. /package/dist/{registerIncodeElement-CdlNRRv5.js → registerIncodeElement-DaNjbAwZ.js} +0 -0
  149. /package/dist/{requiredLabelHint-DX3oVNtu.js → requiredLabelHint-D0RhuMed.js} +0 -0
  150. /package/dist/{selfieTutorial-CYa8bq6B.js → selfieTutorial-pB-N-fj5.js} +0 -0
  151. /package/dist/{snackbar-CGL6gp9u.js → snackbar-DS7Mv62v.js} +0 -0
  152. /package/dist/{statusPage-BUm5gtQY.js → statusPage-Bk8nJwXV.js} +0 -0
  153. /package/dist/{tabs-DUkWjBGk.js → tabs-C__chW-u.js} +0 -0
@@ -0,0 +1,706 @@
1
+ import { r as __toESM } from "./rolldown-runtime--E5BIlTp.js";
2
+ import { n as useTranslation } from "./i18n-CU4xq8qC.js";
3
+ import { _ as y, a as D, d as T, l as A, p as d, v as u, x as k } from "./vendor-preact-DThS2ZQ_.js";
4
+ import { n as cn, r as Spacer, t as LoadingIcon } from "./loadingIcon-B0ysgiNq.js";
5
+ import { t as Page } from "./page-DidH_RkX.js";
6
+ import { t as Title } from "./typography-BZIpjo97.js";
7
+ import { t as TransitionSpinner } from "./transitionSpinner-CuNCqHNi.js";
8
+ import { t as Button } from "./button-Dz6AsbmF.js";
9
+ import { t as ErrorIcon } from "./errorIcon-BA4T6iy-.js";
10
+ import { h as WarningIcon } from "./icons-CJJbIpBq.js";
11
+ import { t as SuccessIcon } from "./successIcon-B5mGvdx1.js";
12
+ import { t as Modal } from "./modal-OxkFuuiR.js";
13
+ import { n as LoadingBorder, r as FaceOutline, t as Notification } from "./capture-CkGvdDNH.js";
14
+ //#region src/shared/errorContent/errorContent.tsx
15
+ var ErrorContent = ({ title, description, attemptsRemaining, onButtonClick, "data-testid": testId }) => {
16
+ const { t } = useTranslation();
17
+ const noMoreAttempts = attemptsRemaining <= 0;
18
+ const titleRef = A(null);
19
+ y(() => {
20
+ titleRef.current?.focus();
21
+ }, []);
22
+ return /* @__PURE__ */ u(Modal.Root, {
23
+ open: true,
24
+ dismissible: false,
25
+ hasBackdrop: false,
26
+ manageInitialFocus: false,
27
+ class: "IncodeErrorContent",
28
+ children: /* @__PURE__ */ u(Modal.Content, {
29
+ class: "IncodeErrorContentContent",
30
+ children: /* @__PURE__ */ u(Page, {
31
+ "data-testid": testId,
32
+ className: "IncodeErrorContentPage",
33
+ children: /* @__PURE__ */ u("div", {
34
+ class: "IncodeErrorContentContainer",
35
+ children: [/* @__PURE__ */ u("div", {
36
+ class: "IncodeErrorContentIconContainer",
37
+ children: [
38
+ noMoreAttempts ? /* @__PURE__ */ u(ErrorIcon, { size: 32 }) : /* @__PURE__ */ u(WarningIcon, { size: 32 }),
39
+ /* @__PURE__ */ u(Spacer, { size: 16 }),
40
+ /* @__PURE__ */ u(Title, {
41
+ ref: titleRef,
42
+ id: "incode-modal-title",
43
+ tabIndex: -1,
44
+ className: "IncodeErrorContentTitle",
45
+ children: title
46
+ }),
47
+ /* @__PURE__ */ u(Spacer, { size: 12 }),
48
+ /* @__PURE__ */ u("p", {
49
+ class: "IncodeErrorContentDescription",
50
+ children: description
51
+ })
52
+ ]
53
+ }), /* @__PURE__ */ u("div", {
54
+ class: "IncodeErrorContentAttemptsContainer",
55
+ children: [
56
+ !noMoreAttempts ? /* @__PURE__ */ u("p", {
57
+ class: "IncodeErrorContentAttemptsText",
58
+ children: t("common.attemptsRemaining", { count: attemptsRemaining })
59
+ }) : null,
60
+ /* @__PURE__ */ u(Button, {
61
+ onClick: onButtonClick,
62
+ children: noMoreAttempts ? t("common.continue") : t("common.tryAgain")
63
+ }),
64
+ /* @__PURE__ */ u(Spacer, { size: 16 })
65
+ ]
66
+ })]
67
+ })
68
+ })
69
+ })
70
+ });
71
+ };
72
+ //#endregion
73
+ //#region src/shared/lottie/lottie.tsx
74
+ var lottiePromise = null;
75
+ async function loadLottie() {
76
+ if (lottiePromise) return lottiePromise;
77
+ lottiePromise = import("./lottie_light-C6B2ec41.js").then((m) => /* @__PURE__ */ __toESM(m.default, 1)).then((mod) => mod.default);
78
+ return lottiePromise;
79
+ }
80
+ var AUTO_STOP_AFTER_MS = 5e3;
81
+ function Lottie({ animationData, loop = true, autoplay = true, reverse = false, style, className, onComplete, autoStop = false, stopFramePosition }) {
82
+ const containerRef = A(null);
83
+ const effectiveAutoplay = reverse ? false : autoplay;
84
+ const animationOptionsRef = A({
85
+ container: containerRef.current,
86
+ renderer: "svg",
87
+ loop,
88
+ autoplay: effectiveAutoplay,
89
+ animationData
90
+ });
91
+ y(() => {
92
+ animationOptionsRef.current = {
93
+ container: containerRef.current,
94
+ renderer: "svg",
95
+ loop,
96
+ autoplay: effectiveAutoplay,
97
+ animationData
98
+ };
99
+ }, [
100
+ animationData,
101
+ loop,
102
+ effectiveAutoplay
103
+ ]);
104
+ y(() => {
105
+ if (!containerRef.current) return;
106
+ let anim;
107
+ let stopTimer;
108
+ let isMounted = true;
109
+ loadLottie().then((lottie) => {
110
+ if (!isMounted) return;
111
+ anim = lottie.loadAnimation(animationOptionsRef.current);
112
+ if (reverse) {
113
+ anim.setDirection(-1);
114
+ anim.goToAndPlay(anim.totalFrames - 1, true);
115
+ }
116
+ if (onComplete) anim.addEventListener("complete", onComplete);
117
+ if (autoStop) stopTimer = window.setTimeout(() => {
118
+ const current = anim;
119
+ if (!current) return;
120
+ if (!stopFramePosition) {
121
+ current.pause();
122
+ return;
123
+ }
124
+ const totalFrames = current.totalFrames;
125
+ if (!totalFrames || totalFrames <= 0) {
126
+ current.stop();
127
+ return;
128
+ }
129
+ const targetFrame = stopFramePosition === "last" ? Math.max(totalFrames - 1, 0) : stopFramePosition === "first" ? 0 : Math.floor((totalFrames - 1) / 2);
130
+ current.goToAndStop(targetFrame, true);
131
+ }, AUTO_STOP_AFTER_MS);
132
+ });
133
+ return () => {
134
+ isMounted = false;
135
+ if (stopTimer !== void 0) window.clearTimeout(stopTimer);
136
+ if (anim) {
137
+ if (onComplete) anim.removeEventListener("complete", onComplete);
138
+ anim.destroy();
139
+ }
140
+ };
141
+ }, [
142
+ onComplete,
143
+ reverse,
144
+ autoStop,
145
+ stopFramePosition
146
+ ]);
147
+ return /* @__PURE__ */ u("div", {
148
+ ref: containerRef,
149
+ style,
150
+ className,
151
+ "aria-hidden": "true"
152
+ });
153
+ }
154
+ //#endregion
155
+ //#region src/shared/baseTutorial/replaceBaseTutorial.ts
156
+ /**
157
+ * The brand blues baked into the tutorial animations. The selfie oval/shoulders
158
+ * use `#007aff`; the ID/passport tutorials additionally use `#006aff` (the
159
+ * default brand blue) for their accent. Both are re-tinted to the active
160
+ * branding color.
161
+ *
162
+ * Authored as hex and converted to Lottie's normalized `[r, g, b]` (0–1) form.
163
+ * The two greens are ~0.06 apart, comfortably outside `COLOR_MATCH_TOLERANCE`,
164
+ * so they neither cross-match nor catch the (grayscale/white) document and
165
+ * face artwork.
166
+ */
167
+ var SOURCE_BRAND_COLORS = ["#007aff", "#006aff"].map(hexToRgbUnit).filter((color) => color !== null);
168
+ /**
169
+ * Per-channel tolerance when matching a source color. The baked values are
170
+ * authored as rounded decimals (e.g. `0.48`), so an exact comparison is too
171
+ * brittle; a small tolerance keeps the match robust without catching
172
+ * unrelated colors.
173
+ */
174
+ var COLOR_MATCH_TOLERANCE = .02;
175
+ /**
176
+ * Reads a CSS custom property off the document root and returns its value.
177
+ * Returns `fallback` (empty by default) when the property is unset or
178
+ * unavailable (e.g. during SSR / tests). With the default empty fallback the
179
+ * recolor no-ops, leaving the animation's authored colors in place — which are
180
+ * the default brand blue, so no theme-specific literal is needed here.
181
+ */
182
+ function getCssVariableAsHex(variableName, fallback = "") {
183
+ if (typeof document === "undefined") return fallback;
184
+ return getComputedStyle(document.documentElement).getPropertyValue(variableName).trim() || fallback;
185
+ }
186
+ function hexToRgbUnit(hex) {
187
+ let normalized = hex.replace("#", "").trim();
188
+ if (normalized.length === 3) normalized = normalized.split("").map((char) => char + char).join("");
189
+ const result = /^([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(normalized);
190
+ if (!result) return null;
191
+ return [
192
+ Number.parseInt(result[1], 16) / 255,
193
+ Number.parseInt(result[2], 16) / 255,
194
+ Number.parseInt(result[3], 16) / 255
195
+ ];
196
+ }
197
+ function channelMatches(a, b) {
198
+ return Math.abs(a - b) <= COLOR_MATCH_TOLERANCE;
199
+ }
200
+ function isSourceColor(r, g, b) {
201
+ return SOURCE_BRAND_COLORS.some(([sr, sg, sb]) => channelMatches(r, sr) && channelMatches(g, sg) && channelMatches(b, sb));
202
+ }
203
+ function isStaticColorArray(value) {
204
+ return Array.isArray(value) && value.length >= 3 && value.every((entry) => typeof entry === "number");
205
+ }
206
+ function recolorSolid(node, target) {
207
+ const colorHolder = node.c;
208
+ if (!colorHolder || typeof colorHolder !== "object") return;
209
+ const k = colorHolder.k;
210
+ if (isStaticColorArray(k) && isSourceColor(k[0], k[1], k[2])) {
211
+ k[0] = target[0];
212
+ k[1] = target[1];
213
+ k[2] = target[2];
214
+ }
215
+ }
216
+ function recolorGradient(node, target) {
217
+ const gradient = node.g;
218
+ if (!gradient || typeof gradient !== "object") return;
219
+ const { p, k } = gradient;
220
+ const stopCount = typeof p === "number" ? p : 0;
221
+ const stops = k?.k;
222
+ if (stopCount <= 0 || !Array.isArray(stops)) return;
223
+ for (let stop = 0; stop < stopCount; stop++) {
224
+ const base = stop * 4;
225
+ const r = stops[base + 1];
226
+ const g = stops[base + 2];
227
+ const b = stops[base + 3];
228
+ if (typeof r === "number" && typeof g === "number" && typeof b === "number" && isSourceColor(r, g, b)) {
229
+ stops[base + 1] = target[0];
230
+ stops[base + 2] = target[1];
231
+ stops[base + 3] = target[2];
232
+ }
233
+ }
234
+ }
235
+ function recolorNode(node, target) {
236
+ if (Array.isArray(node)) {
237
+ for (const child of node) recolorNode(child, target);
238
+ return;
239
+ }
240
+ if (!node || typeof node !== "object") return;
241
+ const obj = node;
242
+ if (obj.ty === "fl" || obj.ty === "st") recolorSolid(obj, target);
243
+ else if (obj.ty === "gf" || obj.ty === "gs") recolorGradient(obj, target);
244
+ for (const key of Object.keys(obj)) recolorNode(obj[key], target);
245
+ }
246
+ /**
247
+ * Returns a deep copy of `animationData` with the baked-in brand blue swapped
248
+ * for `hexColor`. The input is never mutated. Unparseable colors leave the
249
+ * animation untouched.
250
+ */
251
+ function replaceLottieColor(animationData, hexColor) {
252
+ const target = hexToRgbUnit(hexColor);
253
+ if (!target) return animationData;
254
+ const clone = JSON.parse(JSON.stringify(animationData));
255
+ recolorNode(clone, target);
256
+ return clone;
257
+ }
258
+ //#endregion
259
+ //#region src/shared/baseTutorial/baseTutorial.tsx
260
+ var BaseTutorial = ({ className = "", animationData, title, titleId, subtitle, onContinue, buttonText, disclaimerText, isLoading, stopFramePosition = "middle" }) => {
261
+ const themedAnimationData = T(() => animationData ? replaceLottieColor(animationData, getCssVariableAsHex("--primitive-color-brand-500")) : null, [animationData]);
262
+ return /* @__PURE__ */ u(Page, {
263
+ className: cn("IncodeTutorialPage", className),
264
+ title,
265
+ titleId,
266
+ subtitle,
267
+ children: [/* @__PURE__ */ u("div", {
268
+ class: "IncodeBaseTutorialContainer",
269
+ children: /* @__PURE__ */ u("div", {
270
+ class: "IncodeBaseTutorialAnimationContainer",
271
+ "aria-hidden": "true",
272
+ children: themedAnimationData ? /* @__PURE__ */ u(Lottie, {
273
+ animationData: themedAnimationData,
274
+ className: "IncodeBaseTutorialAnimation",
275
+ autoStop: true,
276
+ stopFramePosition
277
+ }) : null
278
+ })
279
+ }), /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ u("p", {
280
+ class: "IncodeBaseTutorialDisclaimer",
281
+ children: disclaimerText
282
+ }), /* @__PURE__ */ u("div", {
283
+ class: "IncodeBaseTutorialButtonContainer",
284
+ children: /* @__PURE__ */ u(Button, {
285
+ onClick: onContinue,
286
+ class: "m-auto max-w-[420px]",
287
+ isLoading,
288
+ children: buttonText
289
+ })
290
+ })] })]
291
+ });
292
+ };
293
+ //#endregion
294
+ //#region src/modules/selfie/avatarCanvas.tsx
295
+ /**
296
+ * Mounts the avatar `<canvas>` in place of the live selfie video. The element
297
+ * is created and rendered to in the infra layer; the UI only hosts it and
298
+ * applies layout + mirror classes (the latter parallels the video's
299
+ * `.IncodeCaptureVideoMirrored`, keeping handedness in one place). Cosmetic
300
+ * only — the capture pipeline runs on the real frames regardless.
301
+ */
302
+ var AvatarCanvas = ({ canvas, mirrored }) => {
303
+ const hostRef = A(null);
304
+ y(() => {
305
+ const host = hostRef.current;
306
+ if (!host || !canvas) return void 0;
307
+ canvas.classList.add("IncodeCaptureAvatarElement");
308
+ canvas.classList.toggle("IncodeCaptureAvatarMirrored", mirrored);
309
+ host.appendChild(canvas);
310
+ return () => {
311
+ if (canvas.parentElement === host) host.removeChild(canvas);
312
+ };
313
+ }, [canvas, mirrored]);
314
+ return /* @__PURE__ */ u("div", {
315
+ ref: hostRef,
316
+ class: "IncodeCaptureAvatarHost",
317
+ "aria-hidden": "true"
318
+ });
319
+ };
320
+ //#endregion
321
+ //#region src/modules/selfie/captureStatusPage.tsx
322
+ var CaptureStatusPage = ({ icon, title, className, isLoading }) => {
323
+ const titleRef = A(null);
324
+ y(() => {
325
+ titleRef.current?.focus();
326
+ }, []);
327
+ return /* @__PURE__ */ u(Page, {
328
+ className: `IncodeCaptureStatusPage ${className ?? ""}`,
329
+ children: [/* @__PURE__ */ u(Spacer, { size: 40 }), /* @__PURE__ */ u("div", {
330
+ class: "IncodeCaptureStatusContainer",
331
+ role: isLoading ? "status" : void 0,
332
+ "aria-live": isLoading ? "polite" : void 0,
333
+ children: [
334
+ /* @__PURE__ */ u(Spacer, { size: 120 }),
335
+ icon,
336
+ /* @__PURE__ */ u(Spacer, { size: 16 }),
337
+ /* @__PURE__ */ u(Title, {
338
+ ref: titleRef,
339
+ className: "IncodeCaptureStatusTitle",
340
+ tabIndex: -1,
341
+ children: title
342
+ })
343
+ ]
344
+ })]
345
+ });
346
+ };
347
+ //#endregion
348
+ //#region src/modules/selfie/errorModal.tsx
349
+ var defaultError = {
350
+ title: "Something went wrong",
351
+ description: "Please try again later"
352
+ };
353
+ var errorContent = {
354
+ MASK_ERROR: {
355
+ title: "notifications.mask",
356
+ description: "notifications.maskDescription"
357
+ },
358
+ BRIGHTNESS_ERROR: {
359
+ title: "notifications.brightness",
360
+ description: "notifications.brightnessDescription"
361
+ },
362
+ LIVENESS_ERROR: {
363
+ title: "notifications.spoof",
364
+ description: "notifications.spoofDescription"
365
+ },
366
+ CLOSED_EYES_ERROR: {
367
+ title: "notifications.closedEyes",
368
+ description: "notifications.closedEyesDescription"
369
+ },
370
+ HEAD_COVER_ERROR: {
371
+ title: "notifications.removeHeadwear",
372
+ description: "notifications.removeHeadwearDescription"
373
+ },
374
+ LENSES_ERROR: {
375
+ title: "notifications.lenses",
376
+ description: "notifications.lensesDescription"
377
+ },
378
+ FACE_NOT_FOUND: {
379
+ title: "notifications.faceNotFound",
380
+ description: "notifications.faceNotFoundDescription"
381
+ },
382
+ MULTIPLE_FACES: {
383
+ title: "notifications.multiple",
384
+ description: "notifications.multipleDescription"
385
+ },
386
+ TOO_BLURRY_ERROR: defaultError,
387
+ TOO_DARK_ERROR: defaultError,
388
+ SERVER_ERROR: defaultError,
389
+ FACE_CROPPING_FAILED: defaultError,
390
+ FACE_TOO_SMALL: defaultError,
391
+ PROCESSING_ERROR: defaultError,
392
+ BAD_REQUEST: defaultError,
393
+ USER_IS_NOT_RECOGNIZED: {
394
+ title: "notifications.accessDenied",
395
+ description: "notifications.accessDeniedDescription"
396
+ },
397
+ SPOOF_ATTEMPT_DETECTED: {
398
+ title: "notifications.spoof",
399
+ description: "notifications.spoofDescription"
400
+ },
401
+ FACE_TOO_DARK: {
402
+ title: "notifications.brightness",
403
+ description: "notifications.brightnessDescription"
404
+ },
405
+ LENSES_DETECTED: {
406
+ title: "notifications.lenses",
407
+ description: "notifications.lensesDescription"
408
+ },
409
+ FACE_MASK_DETECTED: {
410
+ title: "notifications.mask",
411
+ description: "notifications.maskDescription"
412
+ },
413
+ CLOSED_EYES_DETECTED: {
414
+ title: "notifications.closedEyes",
415
+ description: "notifications.closedEyesDescription"
416
+ },
417
+ HEAD_COVER_DETECTED: {
418
+ title: "notifications.removeHeadwear",
419
+ description: "notifications.removeHeadwearDescription"
420
+ },
421
+ FACE_TOO_BLURRY: {
422
+ title: "notifications.spoof",
423
+ description: "notifications.spoofDescription"
424
+ },
425
+ BAD_PHOTO_QUALITY: {
426
+ title: "notifications.lowQualityImage",
427
+ description: "notifications.lowQualityImageDescription"
428
+ },
429
+ NONEXISTENT_CUSTOMER: {
430
+ title: "notifications.nonexistentCustomer",
431
+ description: "notifications.nonexistentCustomerDescription"
432
+ },
433
+ HINT_NOT_PROVIDED: {
434
+ title: "notifications.hintNotProvided",
435
+ description: "notifications.hintNotProvidedDescription"
436
+ },
437
+ SELFIE_IMAGE_LOW_QUALITY: {
438
+ title: "notifications.selfieImageLowQuality",
439
+ description: "notifications.selfieImageLowQualityDescription"
440
+ }
441
+ };
442
+ var ERROR_CODES = [
443
+ "LIVENESS_ERROR",
444
+ "BRIGHTNESS_ERROR",
445
+ "LENSES_ERROR",
446
+ "MASK_ERROR",
447
+ "CLOSED_EYES_ERROR",
448
+ "HEAD_COVER_ERROR",
449
+ "SERVER_ERROR",
450
+ "FACE_NOT_FOUND",
451
+ "MULTIPLE_FACES",
452
+ "TOO_BLURRY_ERROR",
453
+ "TOO_DARK_ERROR",
454
+ "USER_IS_NOT_RECOGNIZED",
455
+ "SPOOF_ATTEMPT_DETECTED",
456
+ "FACE_TOO_DARK",
457
+ "LENSES_DETECTED",
458
+ "FACE_MASK_DETECTED",
459
+ "CLOSED_EYES_DETECTED",
460
+ "HEAD_COVER_DETECTED",
461
+ "FACE_CROPPING_FAILED",
462
+ "FACE_TOO_SMALL",
463
+ "FACE_TOO_BLURRY",
464
+ "BAD_PHOTO_QUALITY",
465
+ "PROCESSING_ERROR",
466
+ "BAD_REQUEST",
467
+ "NONEXISTENT_CUSTOMER",
468
+ "HINT_NOT_PROVIDED",
469
+ "SELFIE_IMAGE_LOW_QUALITY"
470
+ ];
471
+ var parseErrorCode = (error) => {
472
+ const upperError = error.toUpperCase();
473
+ if (upperError.includes("HTTP 400") || upperError.includes("BAD_REQUEST")) return "BAD_REQUEST";
474
+ if (upperError.includes("HTTP 500") || upperError.includes("SERVER_ERROR")) return "SERVER_ERROR";
475
+ for (const code of ERROR_CODES) if (upperError.includes(code)) return code;
476
+ return null;
477
+ };
478
+ var ErrorModal = ({ error, attemptsRemaining, onTryAgain }) => {
479
+ const { t } = useTranslation();
480
+ if (!error) return null;
481
+ const { title, description } = errorContent[parseErrorCode(error) ?? error] ?? defaultError;
482
+ const titleText = t(title) ?? title;
483
+ const descriptionText = attemptsRemaining <= 0 ? t("notifications.selfieCaptureFailedDescription") : t(description);
484
+ return /* @__PURE__ */ u(ErrorContent, {
485
+ "data-testid": "face-capture-error-modal",
486
+ title: titleText,
487
+ description: descriptionText,
488
+ attemptsRemaining,
489
+ onButtonClick: onTryAgain
490
+ });
491
+ };
492
+ //#endregion
493
+ //#region src/modules/selfie/cameraButton.tsx
494
+ var CameraButton = () => {
495
+ return /* @__PURE__ */ u("div", {
496
+ class: "IncodeCameraButton",
497
+ children: /* @__PURE__ */ u("svg", {
498
+ width: "64",
499
+ height: "64",
500
+ viewBox: "0 0 64 64",
501
+ fill: "none",
502
+ xmlns: "http://www.w3.org/2000/svg",
503
+ "aria-hidden": "true",
504
+ children: [
505
+ /* @__PURE__ */ u("circle", {
506
+ cx: "32",
507
+ cy: "32",
508
+ r: "32",
509
+ class: "IncodeCameraButtonBackground"
510
+ }),
511
+ /* @__PURE__ */ u("path", {
512
+ d: "M55.5874 31.8191C55.5872 18.6938 44.9464 8.0537 31.821 8.0537C18.6958 8.05385 8.05581 18.6939 8.05566 31.8191C8.05566 44.9444 18.6958 55.5853 31.821 55.5854C44.9465 55.5854 55.5874 44.9445 55.5874 31.8191ZM57.5566 31.8191C57.5566 46.0321 46.034 57.5547 31.821 57.5547C17.6082 57.5545 6.08643 46.032 6.08643 31.8191C6.08657 17.6063 17.6083 6.08462 31.821 6.08447C46.0339 6.08447 57.5565 17.6062 57.5566 31.8191Z",
513
+ class: "IncodeCameraButtonRing"
514
+ }),
515
+ /* @__PURE__ */ u("path", {
516
+ d: "M35.5186 20.6768C36.887 20.677 37.995 21.777 37.9951 23.1338V24.1045H41.4766C43.0397 24.1052 44.3074 25.3626 44.3076 26.9131V38.5459C44.3076 40.0966 43.0398 41.3535 41.4766 41.3535H21.5381C19.975 41.3533 18.7081 40.0965 18.708 38.5459V26.9131C18.7083 25.3627 19.9751 24.1057 21.5381 24.1055H25.0205V23.1338C25.0206 21.7769 26.1285 20.6768 27.4971 20.6768H35.5186ZM31.5068 26.5273C28.0604 26.5273 25.2559 29.309 25.2559 32.7285C25.2559 36.148 28.0604 38.9297 31.5068 38.9297C34.954 38.9297 37.7588 36.148 37.7588 32.7285C37.7588 29.309 34.954 26.5274 31.5068 26.5273ZM31.5068 28.6348C33.7835 28.6348 35.6357 30.4728 35.6357 32.7305C35.6356 34.9887 33.7833 36.8252 31.5068 36.8252C29.2303 36.8252 27.3791 34.9887 27.3789 32.7305C27.3789 30.4721 29.2302 28.6348 31.5068 28.6348Z",
517
+ class: "IncodeCameraButtonPath"
518
+ })
519
+ ]
520
+ })
521
+ });
522
+ };
523
+ //#endregion
524
+ //#region src/modules/selfie/manualCaptureButton.tsx
525
+ var ManualCaptureButton = D(({ onClick, disabled }, ref) => {
526
+ const { t } = useTranslation();
527
+ return /* @__PURE__ */ u("div", {
528
+ class: "IncodeSelfieManualCapture",
529
+ "data-testid": "manual-capture-button",
530
+ children: [
531
+ /* @__PURE__ */ u("p", {
532
+ id: "manual-capture-instructions",
533
+ class: "IncodeSelfieManualCaptureText",
534
+ children: t("selfiev2.manualCapture.instructions")
535
+ }),
536
+ /* @__PURE__ */ u(Spacer, { size: 32 }),
537
+ /* @__PURE__ */ u("div", { children: /* @__PURE__ */ u(Button, {
538
+ ref,
539
+ id: "manual-capture-button",
540
+ variant: "link",
541
+ onClick,
542
+ disabled,
543
+ class: "IncodeSelfieManualCaptureButton",
544
+ "aria-label": t("selfiev2.manualCapture.captureButton"),
545
+ children: /* @__PURE__ */ u(CameraButton, {})
546
+ }) })
547
+ ]
548
+ });
549
+ });
550
+ //#endregion
551
+ //#region src/modules/selfie/capture.tsx
552
+ var Capture = ({ manager, state }) => {
553
+ const { captureStatus, stream, detectionStatus, attemptsRemaining, uploadError, assistedOnboarding, ageAssurance, onDeviceMode, obfuscateWithAvatar, avatarCanvas, avatarVariant } = state;
554
+ const [isManualCapturing, setIsManualCapturing] = d(false);
555
+ const { t } = useTranslation();
556
+ const manualCaptureRef = A(null);
557
+ const lensLanded = obfuscateWithAvatar && avatarVariant === "privacy-lens" && !!avatarCanvas;
558
+ y(() => {
559
+ if (detectionStatus === "manualCapture") manualCaptureRef.current?.focus();
560
+ }, [detectionStatus]);
561
+ if (captureStatus === "initializing") return /* @__PURE__ */ u(TransitionSpinner, { spinnerConfig: { subtitle: t("loadingCircle.preparingCamera") } });
562
+ if (captureStatus === "detecting") {
563
+ if (detectionStatus === "offline") return /* @__PURE__ */ u(Page, { title: "No internet connection" });
564
+ const getBorderState = () => {
565
+ if (isManualCapturing) return "capturing";
566
+ if (detectionStatus === "detecting") return "idle";
567
+ if (detectionStatus === "getReady") return "loading";
568
+ if (detectionStatus === "getReadyFinished") return "loading";
569
+ if (detectionStatus === "success") return "success";
570
+ if (detectionStatus === "error") return "error";
571
+ return "idle";
572
+ };
573
+ return /* @__PURE__ */ u(Page, {
574
+ "data-testid": "capture-container",
575
+ children: [
576
+ /* @__PURE__ */ u(Title, {
577
+ className: "IncodeCaptureVisuallyHidden",
578
+ children: t("selfiev2.capture.title")
579
+ }),
580
+ /* @__PURE__ */ u(Spacer, { size: 48 }),
581
+ lensLanded ? /* @__PURE__ */ u("p", {
582
+ class: "IncodePrivacyLensBanner",
583
+ children: t("selfiev2.capture.privacyLensMessage")
584
+ }) : null,
585
+ /* @__PURE__ */ u("div", {
586
+ class: "IncodeCaptureContainer",
587
+ children: [
588
+ /* @__PURE__ */ u(LoadingBorder, { borderState: getBorderState() }),
589
+ /* @__PURE__ */ u("div", {
590
+ class: "IncodeCaptureFrame",
591
+ children: /* @__PURE__ */ u("div", {
592
+ class: "IncodeCaptureVideoWrapper",
593
+ "aria-hidden": "true",
594
+ children: stream ? /* @__PURE__ */ u(k, { children: [obfuscateWithAvatar ? /* @__PURE__ */ u(AvatarCanvas, {
595
+ canvas: avatarCanvas,
596
+ mirrored: !assistedOnboarding
597
+ }) : /* @__PURE__ */ u(Video, {
598
+ stream,
599
+ mirrored: !assistedOnboarding
600
+ }), obfuscateWithAvatar && avatarVariant !== "privacy-lens" ? null : /* @__PURE__ */ u("div", {
601
+ class: "IncodeCaptureVideo",
602
+ children: /* @__PURE__ */ u(FaceOutline, {})
603
+ })] }) : null
604
+ })
605
+ }),
606
+ /* @__PURE__ */ u(Spacer, { size: 32 }),
607
+ detectionStatus ? /* @__PURE__ */ u(Notification, {
608
+ detectionState: detectionStatus,
609
+ disabled: !!uploadError || isManualCapturing
610
+ }) : null,
611
+ detectionStatus === "manualCapture" && !onDeviceMode ? /* @__PURE__ */ u(ManualCaptureButton, {
612
+ ref: manualCaptureRef,
613
+ onClick: () => {
614
+ setIsManualCapturing(true);
615
+ manager.capture();
616
+ },
617
+ disabled: isManualCapturing
618
+ }) : null
619
+ ]
620
+ }),
621
+ uploadError ? /* @__PURE__ */ u(ErrorModal, {
622
+ error: uploadError,
623
+ attemptsRemaining,
624
+ onTryAgain: () => {
625
+ manager.retryCapture();
626
+ setIsManualCapturing(false);
627
+ }
628
+ }) : null
629
+ ]
630
+ });
631
+ }
632
+ if (captureStatus === "capturing") return /* @__PURE__ */ u(Page, {
633
+ className: "IncodeCaptureCapturingPage",
634
+ title: "Capturing",
635
+ subtitle: "Taking photo...",
636
+ children: /* @__PURE__ */ u("div", {
637
+ class: "IncodeCaptureCapturingActions",
638
+ children: /* @__PURE__ */ u(Button, {
639
+ isLoading: true,
640
+ children: "Capturing..."
641
+ })
642
+ })
643
+ });
644
+ if (captureStatus === "uploading") return /* @__PURE__ */ u(CaptureStatusPage, {
645
+ className: "IncodeCaptureStatusUploading",
646
+ isLoading: true,
647
+ icon: /* @__PURE__ */ u(LoadingIcon, { size: 64 }),
648
+ title: t(ageAssurance ? "idv2.capture.processing.verifying" : "idv2.capture.processing.uploading")
649
+ });
650
+ if (captureStatus === "uploadError") return /* @__PURE__ */ u(ErrorModal, {
651
+ error: uploadError,
652
+ attemptsRemaining,
653
+ onTryAgain: () => {
654
+ manager.retryCapture();
655
+ setIsManualCapturing(false);
656
+ }
657
+ });
658
+ if (captureStatus === "success") return /* @__PURE__ */ u(CaptureStatusPage, {
659
+ icon: /* @__PURE__ */ u(SuccessIcon, { size: 64 }),
660
+ title: t("idv2.capture.processing.success")
661
+ });
662
+ return null;
663
+ };
664
+ var Video = ({ stream, mirrored }) => {
665
+ const ref = A(null);
666
+ y(() => {
667
+ if (ref.current && stream) ref.current.srcObject = stream;
668
+ }, [stream]);
669
+ return /* @__PURE__ */ u("video", {
670
+ ref,
671
+ autoplay: true,
672
+ playsInline: true,
673
+ muted: true,
674
+ "aria-hidden": "true",
675
+ class: mirrored ? "IncodeCaptureVideoElement IncodeCaptureVideoMirrored" : "IncodeCaptureVideoElement"
676
+ });
677
+ };
678
+ //#endregion
679
+ //#region src/modules/selfie/tutorial.tsx
680
+ var Tutorial = ({ manager, ageAssurance = false }) => {
681
+ const { t } = useTranslation();
682
+ const [isLoading, setIsLoading] = d(false);
683
+ const [animationData, setAnimationData] = d(null);
684
+ y(() => {
685
+ import("./selfieTutorial-pB-N-fj5.js").then((module) => {
686
+ setAnimationData(module.default);
687
+ });
688
+ }, []);
689
+ const handleContinue = async () => {
690
+ setIsLoading(true);
691
+ await manager.nextStep();
692
+ };
693
+ return /* @__PURE__ */ u(BaseTutorial, {
694
+ animationData,
695
+ title: t(ageAssurance ? "face.tutorial.ageAssuranceTitle" : "face.tutorial.title"),
696
+ titleId: "face-tutorial-heading",
697
+ subtitle: t(ageAssurance ? "face.tutorial.ageAssuranceSubtitle" : "face.tutorial.subtitle"),
698
+ onContinue: handleContinue,
699
+ buttonText: t(ageAssurance ? "face.tutorial.ageAssuranceStartCapture" : "face.tutorial.startCapture"),
700
+ disclaimerText: t("face.tutorial.autoCapture"),
701
+ isLoading,
702
+ className: "IncodeSelfieTutorial"
703
+ });
704
+ };
705
+ //#endregion
706
+ export { ErrorContent as a, Lottie as i, Capture as n, BaseTutorial as r, Tutorial as t };