@41devs/naya-id-js 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -208
- package/dist/naya-id.cjs +422 -207
- package/dist/naya-id.cjs.map +1 -1
- package/dist/naya-id.d.cts +233 -81
- package/dist/naya-id.d.ts +233 -81
- package/dist/naya-id.min.js +422 -207
- package/dist/naya-id.min.js.map +1 -1
- package/dist/naya-id.mjs +422 -207
- package/dist/naya-id.mjs.map +1 -1
- package/package.json +36 -4
package/dist/naya-id.min.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/models/config.ts","../src/theme/theme.ts","../src/ui/styles.ts","../src/models/result.ts","../src/api/client.ts","../src/i18n/strings.ts","../src/flow/flow.ts","../src/ui/dom.ts","../src/ui/icons.ts","../src/ui/components.ts","../src/screens/welcome.ts","../src/screens/document-selection.ts","../src/utils/image-utils.ts","../src/screens/document-capture.ts","../src/liveness/liveness-challenge.ts","../src/liveness/face-tracker.ts","../src/screens/liveness.ts","../src/screens/processing.ts","../src/screens/result.ts","../src/flow/host.ts","../src/index.ts"],"names":["NAYA_COUNTRIES","NAYA_DOCUMENT_TYPES","NAYA_DEFAULT_PRIMARY","NAYA_DEFAULT_ACCENT","NAYA_DEFAULT_BASE_URL","resolveConfig","config","c","countryLabel","code","documentNeedsVerso","doc","NAYA_TOKENS","buildThemeVars","STYLES","OCR_FIELDS","parseOcrData","raw","src","out","field","value","ocrToDeclaredData","ocr","cancelledResult","verificationId","errorResult","errorMessage","NayaApiError","message","statusCode","SECONDS","NayaApiClient","auth","baseUrl","h","path","body","timeoutMs","controller","timer","res","err","aborted","json","params","data","userDeclaredData","numOrUndef","v","NayaStrings","locale","fr","en","NayaFlow","finish","next","prev","step","created","upload","s","result","escapeHtml","PATHS","iconSvg","name","size","stroke","brandHtml","stepsDotsHtml","labels","activeIndex","l","i","primaryButtonHtml","label","opts","secondaryButtonHtml","act","buildShell","canClose","root","content","WelcomeScreen","flow","stepLabels","logo","cfg","docIcon","DocumentSelectionScreen","lockedCountry","chips","cards","btn","on","canvasToJpegDataUrl","source","maxDimension","quality","srcW","srcH","scale","w","canvas","ctx","measureFrameQuality","video","scratch","region","sampleWidth","vw","vh","sx","sy","sw","sh","lum","sumLum","p","luminance","sum","sumSq","count","y","x","idx","lap","mean","sharpness","DocumentCaptureScreen","side","instruction","stream","q","ok","ready","dataUrl","t","LivenessChallenge","sig","before","r","yaw","partial","MP_VERSION","DEFAULT_ESM","DEFAULT_WASM_BASE","DEFAULT_MODEL","NOSE_TIP","FACE_LEFT_EDGE","FACE_RIGHT_EDGE","FaceTracker","assets","vision","FaceLandmarker","FilesetResolver","fileset","timestampMs","faceCount","leftEyeOpen","rightEyeOpen","shapes","yawDegrees","lm","nose","left","right","span","RING_PATH","STEP_INDEX","LivenessScreen","signals","csteps","progress","icon","text","dot","n","done","active","resolve","tick","msg","ProcessingScreen","rows","item","cur","row","lbl","session","response","ResultScreen","status","view","fullName","id","reference","middle","b","canRetry","doneLabel","buttons","subtitle","note","createScreen","mountNayaFlow","container","shadow","style","hostEl","vars","k","prevOverflow","settled","current","onKey","route","e","startVerification","version","src_default"],"mappings":"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","file":"naya-id.min.js","sourcesContent":["/**\n * Configuration du parcours de vérification Naya ID.\n *\n * Reprend, à l'identique, le modèle des SDK Flutter et Angular : tous les champs\n * sont optionnels et le SDK fonctionne avec des valeurs par défaut raisonnables\n * (tous pays, tous documents, français).\n */\n\n/** Pays supportés par Naya ID (zone CEDEAO). Code = ISO 3166-1 alpha-2. */\nexport const NAYA_COUNTRIES = [\n { code: 'BJ', label: 'Bénin' },\n { code: 'CI', label: \"Côte d'Ivoire\" },\n { code: 'SN', label: 'Sénégal' },\n { code: 'ML', label: 'Mali' },\n { code: 'BF', label: 'Burkina Faso' },\n { code: 'TG', label: 'Togo' },\n] as const;\n\nexport type NayaCountryCode = (typeof NAYA_COUNTRIES)[number]['code'];\n\n/** Types de documents acceptés. La valeur est envoyée telle quelle à l'API. */\nexport type NayaDocumentType = 'cni' | 'passeport' | 'permis';\n\nexport const NAYA_DOCUMENT_TYPES: readonly NayaDocumentType[] = [\n 'cni',\n 'passeport',\n 'permis',\n];\n\n/** Langues de l'interface du SDK. */\nexport type NayaLocale = 'fr' | 'en';\n\n/**\n * Fournisseur d'authentification.\n *\n * Deux modes, un seul à renseigner :\n * • `apiKey` — la clé d'application est transmise depuis le navigateur.\n * Simple, mais la clé est lisible côté client : à réserver\n * aux démos et aux intégrations où le front est maîtrisé.\n * • `sessionToken` — jeton éphémère obtenu par le backend du client, limité à\n * une vérification. À privilégier en production.\n */\nexport interface NayaAuth {\n apiKey?: string;\n sessionToken?: string;\n}\n\n/** Palette optionnelle : surcharge des couleurs de marque. */\nexport interface NayaThemeOverrides {\n /** Couleur principale (défaut : navy Naya #1A3A5C). */\n primaryColor?: string;\n /** Couleur d'accent des CTA (défaut : ambre Naya #F5A623). */\n accentColor?: string;\n}\n\n/**\n * Emplacement des ressources de détection de vivacité (MediaPipe). Par défaut,\n * elles sont chargées depuis un CDN public. Les applications à CSP stricte\n * (qui bloquent les hôtes externes) doivent auto-héberger ces fichiers et\n * renseigner ici leurs URL.\n */\nexport interface NayaLivenessAssets {\n /** URL du module ESM `@mediapipe/tasks-vision` (`vision_bundle.mjs`). */\n esmUrl?: string;\n /** Base des fichiers WASM `@mediapipe/tasks-vision`. */\n wasmBaseUrl?: string;\n /** URL du modèle `.task` de Face Landmarker. */\n modelUrl?: string;\n}\n\nexport interface NayaConfig {\n /** Pré-sélectionne le pays : l'utilisateur ne le choisit plus. */\n country?: NayaCountryCode;\n\n /**\n * Types de documents proposés. S'il n'y en a qu'un et que `country` est\n * défini, l'écran de sélection est sauté.\n */\n documentTypes?: readonly NayaDocumentType[];\n\n /** Pays proposés quand `country` n'est pas défini. */\n countries?: readonly NayaCountryCode[];\n\n /** Langue de l'interface. */\n locale?: NayaLocale;\n\n /**\n * URL (HTTPS) notifiée par le serveur Naya à chaque décision sur cette\n * session — décision automatique puis, le cas échéant, revue manuelle.\n */\n callbackUrl?: string;\n\n /** Nombre de parcours autorisés après un rejet (bouton « Réessayer »). */\n maxAttempts?: number;\n\n /** Surcharge des couleurs de marque. */\n theme?: NayaThemeOverrides;\n\n /** URL d'un logo client, affiché à côté de « Propulsé par Naya ID ». */\n clientLogoUrl?: string;\n\n /** Base URL de l'API — ne changer que pour un environnement de test. */\n baseUrl?: string;\n\n /** Auto-hébergement des ressources MediaPipe (CSP stricte). */\n livenessAssets?: NayaLivenessAssets;\n}\n\n/** Configuration effective : `NayaConfig` avec tous les défauts appliqués. */\nexport interface ResolvedNayaConfig {\n country?: NayaCountryCode;\n documentTypes: readonly NayaDocumentType[];\n countries: readonly NayaCountryCode[];\n locale: NayaLocale;\n callbackUrl?: string;\n maxAttempts: number;\n theme: Required<NayaThemeOverrides>;\n clientLogoUrl?: string;\n baseUrl: string;\n livenessAssets: NayaLivenessAssets;\n}\n\nexport const NAYA_DEFAULT_PRIMARY = '#1A3A5C';\nexport const NAYA_DEFAULT_ACCENT = '#F5A623';\nexport const NAYA_DEFAULT_BASE_URL = 'https://api.naya.41devs.com/v1';\n\n/** Applique les valeurs par défaut à une configuration partielle. */\nexport function resolveConfig(config: NayaConfig = {}): ResolvedNayaConfig {\n return {\n country: config.country,\n documentTypes: config.documentTypes ?? NAYA_DOCUMENT_TYPES,\n countries: config.countries ?? NAYA_COUNTRIES.map((c) => c.code),\n locale: config.locale ?? 'fr',\n callbackUrl: config.callbackUrl,\n maxAttempts: config.maxAttempts ?? 2,\n theme: {\n primaryColor: config.theme?.primaryColor ?? NAYA_DEFAULT_PRIMARY,\n accentColor: config.theme?.accentColor ?? NAYA_DEFAULT_ACCENT,\n },\n clientLogoUrl: config.clientLogoUrl,\n baseUrl: config.baseUrl ?? NAYA_DEFAULT_BASE_URL,\n livenessAssets: {\n esmUrl: config.livenessAssets?.esmUrl,\n wasmBaseUrl: config.livenessAssets?.wasmBaseUrl,\n modelUrl: config.livenessAssets?.modelUrl,\n },\n };\n}\n\n/** Libellé lisible d'un code pays. */\nexport function countryLabel(code: NayaCountryCode): string {\n return NAYA_COUNTRIES.find((c) => c.code === code)?.label ?? code;\n}\n\n/** La CNI CEDEAO porte sa MRZ au verso ; passeport et permis n'en ont pas besoin. */\nexport function documentNeedsVerso(doc: NayaDocumentType): boolean {\n return doc === 'cni';\n}\n","import type { ResolvedNayaConfig } from '../models/config';\n\n/**\n * Jetons de design Naya — charte produit (navy, ambre, rayons 12/8/24), exposés\n * en variables CSS. Reprend `naya_theme.dart` / `naya-theme.ts`.\n *\n * `primary` et `accent` sont surchargeables par le client ; le reste est fixe.\n * Toutes les variables sont posées sur l'élément hôte de l'overlay, si bien que\n * le thème du SDK reste isolé de celui de l'application.\n */\n\nexport const NAYA_TOKENS = {\n success: '#27AE60',\n error: '#E74C3C',\n warning: '#F39C12',\n background: '#F7F8FA',\n surface: '#FFFFFF',\n textPrimary: '#1A1A2E',\n textSecondary: '#6B7280',\n line: '#E5E7EB',\n dark: '#0E1C2C',\n radiusCard: '12px',\n radiusInput: '8px',\n radiusButton: '24px',\n} as const;\n\n/** Construit le dictionnaire de variables CSS à appliquer sur l'hôte. */\nexport function buildThemeVars(config: ResolvedNayaConfig): Record<string, string> {\n return {\n '--naya-primary': config.theme.primaryColor,\n '--naya-accent': config.theme.accentColor,\n '--naya-success': NAYA_TOKENS.success,\n '--naya-error': NAYA_TOKENS.error,\n '--naya-warning': NAYA_TOKENS.warning,\n '--naya-bg': NAYA_TOKENS.background,\n '--naya-surface': NAYA_TOKENS.surface,\n '--naya-text': NAYA_TOKENS.textPrimary,\n '--naya-text-2': NAYA_TOKENS.textSecondary,\n '--naya-line': NAYA_TOKENS.line,\n '--naya-dark': NAYA_TOKENS.dark,\n '--naya-r-card': NAYA_TOKENS.radiusCard,\n '--naya-r-input': NAYA_TOKENS.radiusInput,\n '--naya-r-button': NAYA_TOKENS.radiusButton,\n };\n}\n","/**\n * Feuille de style unique du SDK, injectée dans le Shadow DOM de l'overlay.\n *\n * Portage fidèle des styles des composants Angular. Comme tout vit dans un seul\n * shadow root, chaque écran est **scopé** par sa classe (`.n-welcome`,\n * `.n-select`, …) : les règles génériques (`.pad`, `.title`) d'un écran\n * n'affectent jamais un autre. Les composants partagés portent un préfixe `n-`.\n */\nexport const STYLES = /* css */ `\n/* ── Hôte + reset ─────────────────────────────────────────────────────────── */\n.naya-host {\n position: fixed; inset: 0; z-index: 2147483000; display: block;\n background: var(--naya-bg); color: var(--naya-text);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n -webkit-font-smoothing: antialiased; text-align: left; line-height: 1.4;\n}\n.naya-host, .naya-host * { box-sizing: border-box; }\n.naya-host button { font-family: inherit; }\n.naya-host h1, .naya-host p, .naya-host ul, .naya-host li { margin: 0; padding: 0; }\n.naya-host img { max-width: 100%; }\n.n-icon { display: inline-flex; line-height: 0; flex: 0 0 auto; }\n@keyframes naya-spin { to { transform: rotate(360deg); } }\n\n/* ── Gabarit d'écran ──────────────────────────────────────────────────────── */\n.n-shell { display: flex; flex-direction: column; height: 100%; background: var(--naya-bg); color: var(--naya-text); }\n.n-shell.n-dark { background: var(--naya-dark); color: #fff; }\n.n-bar { display: flex; justify-content: space-between; align-items: center; padding: 8px 12px 0; flex: 0 0 auto; }\n.n-spacer { width: 40px; height: 40px; }\n.n-round {\n width: 40px; height: 40px; display: inline-flex; align-items: center; justify-content: center;\n border: none; border-radius: 50%; cursor: pointer; color: var(--naya-primary);\n background: color-mix(in srgb, var(--naya-primary) 8%, transparent); transition: background .15s ease;\n}\n.n-dark .n-round { color: #fff; background: rgba(255,255,255,.16); }\n.n-round:hover { background: color-mix(in srgb, var(--naya-primary) 16%, transparent); }\n.n-round:focus-visible { outline: 2px solid var(--naya-accent); outline-offset: 2px; }\n.n-content { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; }\n.n-powered { flex: 0 0 auto; text-align: center; padding: 6px 0 12px; font-size: 11px; font-weight: 600; color: #B3BAC4; }\n.n-dark .n-powered { color: rgba(255,255,255,.38); }\n\n/* ── Composants partagés ──────────────────────────────────────────────────── */\n.n-brand { display: inline-flex; align-items: center; gap: 7px; }\n.n-mark {\n width: 26px; height: 26px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center;\n background: var(--naya-primary); color: var(--naya-accent);\n}\n.n-name { font-size: 17px; font-weight: 800; letter-spacing: -0.2px; color: var(--naya-primary); }\n\n.n-btn { width: 100%; min-height: 52px; cursor: pointer; }\n.n-btn-primary {\n display: inline-flex; align-items: center; justify-content: center; gap: 8px;\n border: none; border-radius: var(--naya-r-button); background: var(--naya-accent); color: var(--naya-primary);\n font-size: 15px; font-weight: 800; transition: filter .15s ease;\n}\n.n-btn-primary:hover:not(:disabled) { filter: brightness(.96); }\n.n-btn-primary:disabled { opacity: .5; cursor: not-allowed; }\n.n-btn-primary:focus-visible { outline: 2px solid var(--naya-primary); outline-offset: 2px; }\n.n-btn-secondary {\n border: 1.5px solid var(--naya-primary); border-radius: var(--naya-r-button);\n background: transparent; color: var(--naya-primary); font-size: 15px; font-weight: 800;\n}\n.n-btn-secondary:hover { background: color-mix(in srgb, var(--naya-primary) 6%, transparent); }\n.n-btn-secondary:focus-visible { outline: 2px solid var(--naya-accent); outline-offset: 2px; }\n\n.n-dots { display: flex; justify-content: center; gap: 22px; }\n.n-step { display: flex; flex-direction: column; align-items: center; gap: 5px; }\n.n-dot { width: 9px; height: 9px; border-radius: 50%; background: #D6DCE4; }\n.n-dot.on { background: var(--naya-accent); }\n.n-dotlbl { font-size: 11px; color: var(--naya-text-2); }\n\n/* ── 1 · Bienvenue ────────────────────────────────────────────────────────── */\n.n-welcome .pad { display: flex; flex-direction: column; flex: 1; padding: 4px 24px 8px; }\n.n-welcome .brandRow { display: flex; align-items: center; justify-content: center; gap: 14px; }\n.n-welcome .sep { width: 1px; height: 22px; background: var(--naya-line); }\n.n-welcome .clientLogo { height: 24px; width: auto; object-fit: contain; }\n.n-welcome .spacer { flex: 1 1 auto; }\n.n-welcome .hero {\n align-self: center; width: 116px; height: 116px; border-radius: 32px;\n display: flex; align-items: center; justify-content: center; background: var(--naya-primary); color: var(--naya-accent);\n}\n.n-welcome .title {\n margin: 28px 0 10px; text-align: center; text-wrap: balance;\n font-size: 23px; font-weight: 800; line-height: 1.25; letter-spacing: -0.2px; color: var(--naya-primary);\n}\n.n-welcome .body { margin: 0; text-align: center; white-space: pre-line; font-size: 15px; line-height: 1.5; color: var(--naya-text-2); }\n.n-welcome .steps { margin-top: 26px; }\n.n-welcome .secure { display: flex; align-items: center; justify-content: center; gap: 5px; margin-top: 12px; text-align: center; font-size: 11px; color: var(--naya-text-2); }\n\n/* ── 2 · Choix du document ────────────────────────────────────────────────── */\n.n-select .pad { display: flex; flex-direction: column; flex: 1; padding: 8px 24px 16px; }\n.n-select .title { margin: 0 0 8px; white-space: pre-line; text-wrap: balance; font-size: 23px; font-weight: 800; line-height: 1.25; letter-spacing: -0.2px; color: var(--naya-primary); }\n.n-select .body { margin: 0 0 18px; font-size: 15px; line-height: 1.5; color: var(--naya-text-2); }\n.n-select .chips { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; margin-bottom: 18px; }\n.n-select .chip {\n flex: 0 0 auto; padding: 8px 14px; border-radius: 999px; cursor: pointer;\n background: var(--naya-surface); border: 1px solid var(--naya-line);\n font-size: 13px; font-weight: 500; color: var(--naya-text); white-space: nowrap;\n}\n.n-select .chip.on { border: 1.6px solid var(--naya-accent); font-weight: 700; background: color-mix(in srgb, var(--naya-accent) 18%, transparent); }\n.n-select .chip:focus-visible { outline: 2px solid var(--naya-accent); outline-offset: 2px; }\n.n-select .cards { display: flex; flex-direction: column; gap: 10px; }\n.n-select .card {\n display: flex; align-items: center; gap: 12px; width: 100%; padding: 14px; cursor: pointer; text-align: left;\n background: var(--naya-surface); border: 1px solid var(--naya-line); border-radius: var(--naya-r-card);\n}\n.n-select .card.on { border: 1.8px solid var(--naya-accent); background: #FFF9EE; }\n.n-select .card:focus-visible { outline: 2px solid var(--naya-accent); outline-offset: 2px; }\n.n-select .ico { width: 36px; height: 36px; border-radius: 8px; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; background: #EDF3FA; color: var(--naya-primary); }\n.n-select .lbl { flex: 1; font-size: 14px; font-weight: 700; color: var(--naya-text); }\n.n-select .card > .n-icon { color: var(--naya-text-2); }\n.n-select .spacer { flex: 1 1 auto; min-height: 16px; }\n\n/* ── 3-4 · Capture du document ────────────────────────────────────────────── */\n.n-capture .pad { display: flex; flex-direction: column; flex: 1; align-items: center; padding: 0 16px 16px; }\n.n-capture .instruction { width: 100%; margin: 0 0 12px; padding: 12px 16px; text-align: center; background: rgba(0,0,0,.55); border-radius: 12px; color: #fff; font-size: 15.5px; line-height: 1.35; font-weight: 600; }\n.n-capture .cardWrap { flex: 1 1 auto; display: flex; align-items: center; width: 100%; min-height: 0; }\n.n-capture .card { position: relative; width: 100%; aspect-ratio: 1.586; border-radius: 10px; overflow: hidden; background: rgba(255,255,255,.06); }\n.n-capture .preview { width: 100%; height: 100%; object-fit: cover; display: block; }\n.n-capture .camMsg { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 16px; text-align: center; color: rgba(255,255,255,.7); font-size: 13px; }\n.n-capture .corners { position: absolute; inset: 0; width: 100%; height: 100%; fill: none; stroke: var(--naya-accent); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; transition: stroke .2s ease; pointer-events: none; }\n.n-capture .card.ready .corners { stroke: var(--naya-success); }\n.n-capture .pills { display: flex; gap: 8px; justify-content: center; margin: 14px 0; }\n.n-capture .pill { display: inline-flex; align-items: center; gap: 6px; padding: 7px 14px; border-radius: 999px; background: color-mix(in srgb, var(--naya-warning) 92%, transparent); color: #fff; font-size: 12.5px; font-weight: 700; }\n.n-capture .pill.ok { background: color-mix(in srgb, var(--naya-success) 92%, transparent); }\n.n-capture .shutter { width: 72px; height: 72px; border-radius: 50%; cursor: pointer; border: 4.5px solid #fff; background: rgba(255,255,255,.3); display: inline-flex; align-items: center; justify-content: center; transition: border-color .2s ease, background .2s ease; }\n.n-capture .shutter.ready { border-color: var(--naya-success); background: color-mix(in srgb, var(--naya-success) 30%, transparent); }\n.n-capture .shutter:disabled { cursor: default; }\n.n-capture .shutter:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }\n.n-capture .hint { margin: 12px 0 0; text-align: center; font-size: 13px; font-weight: 500; color: #9FB2C6; }\n.n-capture .hint.ready { color: var(--naya-success); font-weight: 700; }\n.n-capture .loader { width: 30px; height: 30px; border-radius: 50%; border: 3px solid rgba(255,255,255,.25); border-top-color: #fff; animation: naya-spin .8s linear infinite; }\n.n-capture .loader.sm { width: 24px; height: 24px; border-width: 2.5px; }\n\n/* ── 5 · Vivacité ─────────────────────────────────────────────────────────── */\n.n-liveness .pad { display: flex; flex-direction: column; flex: 1; align-items: center; padding: 4px 24px 12px; }\n.n-liveness .title { margin: 0; font-size: 23px; font-weight: 800; color: var(--naya-primary); text-align: center; }\n.n-liveness .sub { margin: 6px 0 18px; font-size: 15px; color: var(--naya-text-2); text-align: center; }\n.n-liveness .ovalWrap { position: relative; width: min(230px, 62vw); aspect-ratio: 210 / 270; margin: 4px 0; }\n.n-liveness .oval { position: absolute; inset: 7px; border-radius: 50%; overflow: hidden; background: rgba(0,0,0,.04); display: flex; align-items: center; justify-content: center; }\n.n-liveness .preview { width: 100%; height: 100%; object-fit: cover; transform: scaleX(-1); }\n.n-liveness .camMsg { padding: 20px; text-align: center; color: var(--naya-text-2); font-size: 12px; }\n.n-liveness .ring { position: absolute; inset: 0; width: 100%; height: 100%; fill: none; overflow: visible; }\n.n-liveness .ring .track { stroke: #D8DFE8; stroke-width: 4; }\n.n-liveness .ring .prog { stroke: var(--naya-accent); stroke-width: 4; stroke-linecap: round; transition: stroke-dashoffset .35s ease; }\n.n-liveness .instruction { display: inline-flex; align-items: center; gap: 10px; margin: 18px 0 14px; padding: 12px 16px; background: var(--naya-surface); border: 1px solid var(--naya-line); border-radius: var(--naya-r-card); color: var(--naya-primary); }\n.n-liveness .instruction span { font-size: 16px; font-weight: 700; color: var(--naya-text); }\n.n-liveness .steps { display: flex; gap: 20px; justify-content: center; }\n.n-liveness .cstep { display: flex; flex-direction: column; align-items: center; gap: 5px; }\n.n-liveness .cdot { width: 22px; height: 22px; border-radius: 50%; background: #D6DCE4; display: inline-flex; align-items: center; justify-content: center; color: #fff; }\n.n-liveness .cdot.active { background: var(--naya-accent); }\n.n-liveness .cdot.done { background: var(--naya-success); }\n.n-liveness .clbl { font-size: 11px; color: var(--naya-text-2); }\n.n-liveness .spacer { flex: 1 1 auto; min-height: 12px; }\n.n-liveness .privacy { margin: 0; text-align: center; white-space: pre-line; font-size: 12.5px; color: var(--naya-text-2); }\n.n-liveness .loader { width: 30px; height: 30px; border-radius: 50%; border: 3px solid rgba(0,0,0,.12); border-top-color: var(--naya-accent); animation: naya-spin .8s linear infinite; }\n\n/* ── 6 · Traitement ───────────────────────────────────────────────────────── */\n.n-processing .pad { display: flex; flex-direction: column; flex: 1; align-items: center; padding: 8px 32px 16px; }\n.n-processing .pad.center { justify-content: center; text-align: center; }\n.n-processing .spacer { flex: 1 1 auto; }\n.n-processing .title { margin: 16px 0 8px; font-size: 23px; font-weight: 800; color: var(--naya-primary); text-wrap: balance; }\n.n-processing .body { margin: 0; font-size: 15px; line-height: 1.5; color: var(--naya-text-2); }\n.n-processing .cta { width: 100%; margin-top: 24px; }\n.n-processing .spin { width: 110px; height: 110px; border-radius: 50%; border: 7px solid #E1E6EC; border-top-color: var(--naya-primary); animation: naya-spin 1s linear infinite; }\n.n-processing .steps { list-style: none; margin: 34px 0 0; padding: 0; align-self: flex-start; }\n.n-processing .row { display: flex; align-items: center; gap: 10px; padding: 5px 0; }\n.n-processing .dot { width: 20px; height: 20px; border-radius: 50%; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; }\n.n-processing .dot.done { background: var(--naya-success); color: #fff; }\n.n-processing .dot.idle { background: #D6DCE4; }\n.n-processing .dot.active { border: 2.5px solid var(--naya-accent); border-top-color: transparent; animation: naya-spin .8s linear infinite; }\n.n-processing .lbl { font-size: 15px; font-weight: 600; color: var(--naya-text); }\n.n-processing .lbl.dim { color: var(--naya-text-2); font-weight: 500; }\n.n-processing .wait { font-size: 13px; color: var(--naya-text-2); margin: 0; }\n\n/* ── 7 · Résultat ─────────────────────────────────────────────────────────── */\n.n-result .pad { display: flex; flex-direction: column; flex: 1; align-items: center; padding: 8px 24px 16px; }\n.n-result .spacer { flex: 1 1 auto; }\n.n-result .badge { width: 88px; height: 88px; border-radius: 50%; color: #fff; display: inline-flex; align-items: center; justify-content: center; }\n.n-result .title { margin: 18px 0 8px; text-align: center; text-wrap: balance; font-size: 23px; font-weight: 800; color: var(--naya-primary); }\n.n-result .body { margin: 0; text-align: center; font-size: 15px; line-height: 1.5; color: var(--naya-text-2); }\n.n-result .summary { width: 100%; margin-top: 20px; padding: 14px; background: var(--naya-surface); border: 1px solid var(--naya-line); border-radius: var(--naya-r-card); }\n.n-result .srow { display: flex; justify-content: space-between; align-items: center; padding: 4px 0; gap: 12px; }\n.n-result .k { font-size: 13px; color: var(--naya-text-2); }\n.n-result .v { font-size: 13px; font-weight: 800; color: var(--naya-text); text-align: right; }\n.n-result .v.mono { font-family: ui-monospace, \"SF Mono\", Menlo, monospace; }\n.n-result .bullets { list-style: none; margin: 20px 0 0; padding: 0; align-self: stretch; }\n.n-result .bullets li { display: flex; align-items: center; gap: 9px; padding: 4px 0; font-size: 13px; color: var(--naya-text); }\n.n-result .pip { width: 6px; height: 6px; border-radius: 50%; background: var(--naya-warning); flex: 0 0 auto; }\n.n-result .gap { height: 10px; }\n\n@media (prefers-reduced-motion: reduce) {\n .n-capture .loader, .n-liveness .loader { animation-duration: 1.6s; }\n .n-liveness .ring .prog { transition: none; }\n .n-processing .spin { animation-duration: 2s; }\n .n-processing .dot.active { animation-duration: 1.6s; }\n}\n`;\n","/**\n * Résultat du parcours, rendu à l'application cliente à la fermeture du SDK.\n * Miroir fidèle des modèles Flutter et Angular.\n */\n\n/** Issue du parcours de vérification. */\nexport type NayaStatus =\n /** Identité vérifiée et approuvée automatiquement. */\n | 'approved'\n /** Dossier envoyé en revue manuelle — décision finale ultérieure. */\n | 'review'\n /** Vérification rejetée (document expiré, visage non concordant…). */\n | 'rejected'\n /** L'utilisateur a quitté le parcours avant la fin. */\n | 'cancelled'\n /** Erreur technique (réseau, serveur…) ayant interrompu le parcours. */\n | 'error';\n\n/**\n * Données d'identité extraites du document par l'OCR Naya, éventuellement\n * corrigées par l'utilisateur.\n */\nexport interface NayaOcrData {\n lastName?: string;\n firstName?: string;\n /** Format YYYY-MM-DD. */\n dateOfBirth?: string;\n placeOfBirth?: string;\n nationality?: string;\n /** Format YYYY-MM-DD. */\n expirationDate?: string;\n documentNumber?: string;\n /** Numéro Personnel d'Identification (Bénin) — 10 chiffres. */\n npi?: string;\n issuingCountry?: string;\n issuingAuthority?: string;\n /** 'M' ou 'F'. */\n gender?: string;\n}\n\nconst OCR_FIELDS: (keyof NayaOcrData)[] = [\n 'lastName', 'firstName', 'dateOfBirth', 'placeOfBirth', 'nationality',\n 'expirationDate', 'documentNumber', 'npi', 'issuingCountry',\n 'issuingAuthority', 'gender',\n];\n\n/** Lit un objet OCR brut de l'API en ne retenant que les champs connus. */\nexport function parseOcrData(raw: unknown): NayaOcrData | undefined {\n if (!raw || typeof raw !== 'object') return undefined;\n const src = raw as Record<string, unknown>;\n const out: NayaOcrData = {};\n for (const field of OCR_FIELDS) {\n const value = src[field];\n if (typeof value === 'string' && value.length > 0) out[field] = value;\n }\n return Object.keys(out).length ? out : undefined;\n}\n\n/** Réduit un objet OCR à ses seuls champs renseignés, en chaînes. */\nexport function ocrToDeclaredData(ocr: NayaOcrData): Record<string, string> {\n const out: Record<string, string> = {};\n for (const field of OCR_FIELDS) {\n const value = ocr[field];\n if (value) out[field] = value;\n }\n return out;\n}\n\n/** Résultat retourné à l'application cliente. */\nexport interface NayaResult {\n status: NayaStatus;\n /**\n * Identifiant de la session Naya — à conserver côté client pour rapprocher\n * les notifications `callbackUrl` et le dashboard.\n */\n verificationId?: string;\n /** Score de risque agrégé 0-100 (plus haut = plus sûr). */\n riskScore?: number;\n /** Concordance faciale document ↔ selfie, 0-100. */\n matchScore?: number;\n /** Intégrité du document, 0-100. */\n authenticityScore?: number;\n /** Score de vivacité, 0-100. */\n livenessScore?: number;\n /** Confiance de l'extraction OCR, 0-100. */\n ocrConfidence?: number;\n /** Données d'identité finales (OCR fusionné avec les corrections). */\n ocrData?: NayaOcrData;\n /** Note d'analyse produite par le pipeline Naya. */\n note?: string;\n /** Détail de l'erreur quand `status` vaut `'error'`. */\n errorMessage?: string;\n}\n\nexport function cancelledResult(verificationId?: string): NayaResult {\n return { status: 'cancelled', verificationId };\n}\n\nexport function errorResult(errorMessage: string, verificationId?: string): NayaResult {\n return { status: 'error', errorMessage, verificationId };\n}\n","import type { NayaAuth } from '../models/config';\nimport { type NayaOcrData, parseOcrData } from '../models/result';\n\n/**\n * Client HTTP du pipeline de vérification Naya.\n *\n * Bâti sur `fetch` natif, sans dépendance. Les délais sont dimensionnés pour les\n * étapes longues (OCR et décision côté serveur).\n *\n * Authentification via `NayaAuth` : `apiKey` (en-tête `X-API-Key`) ou\n * `sessionToken` (en-tête `Authorization: Bearer`). Le choix est transparent\n * pour le reste du SDK.\n */\n\n/** Erreur renvoyée par l'API Naya ou par le transport réseau. */\nexport class NayaApiError extends Error {\n readonly statusCode?: number;\n constructor(message: string, statusCode?: number) {\n super(message);\n this.name = 'NayaApiError';\n this.statusCode = statusCode;\n }\n}\n\n/** Réponse de POST /verifications/start. */\nexport interface NayaSession {\n verificationId: string;\n sessionToken: string;\n}\n\n/** Réponse de POST /verifications/:id/submit. */\nexport interface NayaSubmitResponse {\n status: string;\n riskScore?: number;\n matchScore?: number;\n authenticityScore?: number;\n livenessScore?: number;\n ocrConfidence?: number;\n ocrData?: NayaOcrData;\n note?: string;\n}\n\nconst SECONDS = 1000;\n\nexport class NayaApiClient {\n constructor(\n private readonly auth: NayaAuth,\n private readonly baseUrl: string,\n ) {}\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.auth.sessionToken) {\n h['Authorization'] = `Bearer ${this.auth.sessionToken}`;\n } else if (this.auth.apiKey) {\n h['X-API-Key'] = this.auth.apiKey;\n }\n return h;\n }\n\n private async post<T>(\n path: string,\n body: Record<string, unknown>,\n timeoutMs = 30 * SECONDS,\n ): Promise<T> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n let res: Response;\n try {\n res = await fetch(`${this.baseUrl}${path}`, {\n method: 'POST',\n headers: this.headers(),\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n } catch (err) {\n const aborted = err instanceof DOMException && err.name === 'AbortError';\n throw new NayaApiError(\n aborted ? 'Délai dépassé — réessayez.' : 'Réseau indisponible.',\n );\n } finally {\n clearTimeout(timer);\n }\n\n let json: any;\n try {\n json = await res.json();\n } catch {\n throw new NayaApiError('Réponse illisible du serveur.', res.status);\n }\n\n if (res.status >= 400 || json?.success !== true) {\n const message =\n (json?.error && typeof json.error === 'object'\n ? json.error.message\n : undefined) ?? 'Erreur inconnue.';\n throw new NayaApiError(message, res.status);\n }\n return (json.data ?? {}) as T;\n }\n\n /** Ouvre une session de vérification. */\n async start(params: {\n documentType: string;\n country: string;\n callbackUrl?: string;\n }): Promise<NayaSession> {\n const data = await this.post<Record<string, unknown>>(\n '/verifications/start',\n {\n documentType: params.documentType,\n country: params.country,\n ...(params.callbackUrl ? { callbackUrl: params.callbackUrl } : {}),\n device: 'Web',\n },\n );\n return {\n verificationId: String(data['verificationId'] ?? ''),\n sessionToken: String(data['sessionToken'] ?? ''),\n };\n }\n\n /**\n * Envoie le document capturé. L'OCR serveur est synchrone : la réponse\n * contient les champs extraits, utilisés pour pré-remplir l'étape suivante.\n * Le verso, quand il est fourni, porte la MRZ des CNI CEDEAO.\n */\n async uploadDocument(\n verificationId: string,\n params: { rectoBase64: string; versoBase64?: string },\n ): Promise<NayaOcrData | undefined> {\n const data = await this.post<Record<string, unknown>>(\n `/verifications/${verificationId}/document`,\n {\n imageBase64Recto: params.rectoBase64,\n ...(params.versoBase64 ? { imageBase64Verso: params.versoBase64 } : {}),\n },\n 120 * SECONDS,\n );\n return parseOcrData(data['ocrData']);\n }\n\n /**\n * Envoie le selfie et le score de vivacité mesuré sur l'appareil.\n * `matchScore` est requis par l'endpoint mais recalculé côté serveur : on\n * transmet 0, comme les SDK Flutter et Angular.\n */\n async submitLiveness(\n verificationId: string,\n params: { livenessScore: number; selfieBase64: string },\n ): Promise<void> {\n await this.post(\n `/verifications/${verificationId}/liveness`,\n {\n livenessScore: params.livenessScore,\n matchScore: 0,\n selfieBase64: params.selfieBase64,\n },\n 60 * SECONDS,\n );\n }\n\n /** Déclenche l'analyse finale (OCR différé, biométrie, AML, décision). */\n async submit(\n verificationId: string,\n userDeclaredData?: Record<string, string>,\n ): Promise<NayaSubmitResponse> {\n const data = await this.post<Record<string, unknown>>(\n `/verifications/${verificationId}/submit`,\n userDeclaredData && Object.keys(userDeclaredData).length\n ? { userDeclaredData }\n : {},\n 180 * SECONDS,\n );\n return {\n status: String(data['status'] ?? 'review'),\n riskScore: numOrUndef(data['riskScore']),\n matchScore: numOrUndef(data['matchScore']),\n authenticityScore: numOrUndef(data['authenticityScore']),\n livenessScore: numOrUndef(data['livenessScore']),\n ocrConfidence: numOrUndef(data['ocrConfidence']),\n ocrData: parseOcrData(data['ocrData']),\n note: typeof data['note'] === 'string' ? (data['note'] as string) : undefined,\n };\n }\n}\n\nfunction numOrUndef(v: unknown): number | undefined {\n return typeof v === 'number' && !Number.isNaN(v) ? v : undefined;\n}\n","import type { NayaDocumentType, NayaLocale } from '../models/config';\n\n/**\n * Chaînes de l'interface, français et anglais. Reprise fidèle des SDK Flutter\n * et Angular — mêmes intitulés, mêmes étapes.\n */\nexport class NayaStrings {\n constructor(private readonly locale: NayaLocale) {}\n\n private t(fr: string, en: string): string {\n return this.locale === 'fr' ? fr : en;\n }\n\n // Commun\n get poweredBy() { return this.t('Propulsé par Naya ID (41Devs)', 'Powered by Naya ID (41Devs)'); }\n get continueLabel() { return this.t('Continuer', 'Continue'); }\n get backToApp() { return this.t(\"Retourner à l'application\", 'Back to the app'); }\n\n // 1 · Bienvenue\n get welcomeTitle() { return this.t('Vérifiez votre identité', 'Verify your identity'); }\n get welcomeSubtitle() {\n return this.t(\n \"Prêt en moins de 60 secondes.\\nMunissez-vous de votre pièce d'identité.\",\n 'Ready in under 60 seconds.\\nHave your ID document at hand.',\n );\n }\n get welcomeCta() { return this.t('Commencer', 'Get started'); }\n get welcomeSecurity() {\n return this.t(\n 'Vos données sont chiffrées et transmises de façon sécurisée',\n 'Your data is encrypted and transmitted securely',\n );\n }\n get stepDocument() { return this.t('Document', 'Document'); }\n get stepSelfie() { return this.t('Selfie', 'Selfie'); }\n get stepResult() { return this.t('Résultat', 'Result'); }\n\n // 2 · Choix du document\n get docSelectTitle() { return this.t('Quel document\\navez-vous ?', 'Which document\\ndo you have?'); }\n get docSelectSubtitle() {\n return this.t(\n \"Choisissez votre pays et votre pièce d'identité.\",\n 'Choose your country and your ID document.',\n );\n }\n docLabel(doc: NayaDocumentType): string {\n switch (doc) {\n case 'cni': return this.t(\"Carte Nationale d'Identité\", 'National Identity Card');\n case 'passeport': return this.t('Passeport', 'Passport');\n case 'permis': return this.t('Permis de conduire', 'Driving licence');\n }\n }\n\n // 3-4 · Capture\n get captureRectoInstruction() {\n return this.t(\n 'Cadrez le recto de votre document dans le rectangle',\n 'Frame the front of your document inside the rectangle',\n );\n }\n get captureVersoInstruction() {\n return this.t(\n 'Retournez la carte — la bande MRZ doit être lisible',\n 'Flip the card — the MRZ strip must be readable',\n );\n }\n get captureHint() {\n return this.t(\n 'Appuyez sur le déclencheur quand le cadre est vert',\n 'Tap the shutter when the frame turns green',\n );\n }\n get captureReady() {\n return this.t('Image nette — appuyez pour capturer', 'Sharp image — tap to capture');\n }\n get qualityLight() { return this.t('Luminosité', 'Lighting'); }\n get qualitySharpness() { return this.t('Netteté', 'Sharpness'); }\n\n // 5 · Liveness\n get livenessTitle() { return this.t('Un selfie rapide', 'A quick selfie'); }\n get livenessSubtitle() { return this.t(\"Placez votre visage dans l'ovale.\", 'Place your face in the oval.'); }\n get livenessLookStraight() { return this.t('Regardez droit vers la caméra', 'Look straight at the camera'); }\n get livenessBlink() { return this.t('Clignez des yeux', 'Blink your eyes'); }\n get livenessTurnHead() { return this.t('Tournez lentement la tête', 'Slowly turn your head'); }\n get livenessHold() { return this.t('Ne bougez plus…', 'Hold still…'); }\n get livenessStepFace() { return this.t('Visage', 'Face'); }\n get livenessStepBlink() { return this.t('Clignement', 'Blink'); }\n get livenessStepTurn() { return this.t('Rotation', 'Turn'); }\n get livenessPrivacy() {\n return this.t(\n \"L'analyse s'effectue sur votre appareil —\\nla photo n'est envoyée qu'à la fin du défi\",\n 'Analysis runs on your device —\\nthe photo is only sent once the challenge is done',\n );\n }\n\n // 6 · Traitement\n get processingDocument() { return this.t('Document analysé', 'Document analyzed'); }\n get processingFace() { return this.t('Visage comparé', 'Face compared'); }\n get processingCompliance() { return this.t('Contrôles de conformité', 'Compliance checks'); }\n get processingDecision() { return this.t('Décision', 'Decision'); }\n get processingWait() { return this.t('Ne fermez pas la fenêtre', \"Don't close the window\"); }\n\n // 7 · Résultats\n get resultApprovedTitle() { return this.t('Identité vérifiée !', 'Identity verified!'); }\n get resultApprovedSubtitle() {\n return this.t(\n 'Votre vérification a été transmise avec succès.',\n 'Your verification was submitted successfully.',\n );\n }\n get resultReference() { return this.t('Référence', 'Reference'); }\n get resultName() { return this.t('Nom complet', 'Full name'); }\n get resultReviewTitle() { return this.t(\"Vérification en cours d'examen\", 'Verification under review'); }\n get resultReviewSubtitle() {\n return this.t('Un analyste examine votre dossier.', 'An analyst is reviewing your file.');\n }\n get resultReviewB1() { return this.t('Réponse généralement sous 24 h', 'Usually answered within 24 h'); }\n get resultReviewB2() { return this.t(\"Vous serez notifié par l'application\", 'The app will notify you'); }\n get resultReviewB3() { return this.t('Aucune action requise de votre part', 'No action needed from you'); }\n get resultRejectedTitle() { return this.t('Vérification non aboutie', 'Verification unsuccessful'); }\n get resultRejectedReason() { return this.t('Motif', 'Reason'); }\n get retry() { return this.t('Réessayer', 'Try again'); }\n\n // Erreurs\n get errorTitle() { return this.t('Une erreur est survenue', 'Something went wrong'); }\n get errorNetwork() {\n return this.t(\n 'Vérifiez votre connexion internet puis réessayez.',\n 'Check your internet connection and try again.',\n );\n }\n get errorCamera() {\n return this.t(\n \"Impossible d'accéder à la caméra. Vérifiez les autorisations du navigateur.\",\n 'Cannot access the camera. Check the browser permissions.',\n );\n }\n}\n","import {\n NayaApiClient,\n type NayaSession,\n type NayaSubmitResponse,\n} from '../api/client';\nimport {\n type NayaAuth,\n type NayaCountryCode,\n type NayaDocumentType,\n type ResolvedNayaConfig,\n documentNeedsVerso,\n} from '../models/config';\nimport type { NayaResult } from '../models/result';\nimport { NayaStrings } from '../i18n/strings';\n\n/** Étapes du parcours. L'ordre reflète la progression nominale. */\nexport type NayaStep =\n | 'welcome'\n | 'select'\n | 'capture-recto'\n | 'capture-verso'\n | 'liveness'\n | 'processing'\n | 'result';\n\n/**\n * État partagé du parcours et logique de session — équivalent du\n * `NayaFlowService` Angular / `NayaFlowController` Flutter, mais sans framework :\n * état en champs simples, l'hôte réagit au changement d'étape via `onStep`.\n */\nexport class NayaFlow {\n private readonly api: NayaApiClient;\n readonly config: ResolvedNayaConfig;\n readonly strings: NayaStrings;\n private readonly finishCb: (result: NayaResult) => void;\n\n /** Notifié par le contrôleur à chaque changement d'étape ; posé par l'hôte. */\n onStep: (step: NayaStep) => void = () => {};\n\n // ── État ─────────────────────────────────────────────────────────────────\n step: NayaStep = 'welcome';\n session: NayaSession | null = null;\n country: NayaCountryCode | null = null;\n document: NayaDocumentType | null = null;\n rectoBase64: string | null = null;\n versoBase64: string | null = null;\n livenessScore = 0;\n selfieBase64: string | null = null;\n attemptsUsed = 0;\n submitResponse: NayaSubmitResponse | null = null;\n\n private stepHistory: NayaStep[] = [];\n private documentUpload: Promise<void> | null = null;\n private finished = false;\n\n constructor(\n auth: NayaAuth,\n config: ResolvedNayaConfig,\n finish: (result: NayaResult) => void,\n ) {\n this.config = config;\n this.finishCb = finish;\n this.api = new NayaApiClient(auth, config.baseUrl);\n this.strings = new NayaStrings(config.locale);\n this.country = config.country ?? null;\n }\n\n // ── Navigation ─────────────────────────────────────────────────────────────\n /** Empile l'étape courante et avance vers `next`. */\n go(next: NayaStep): void {\n this.stepHistory.push(this.step);\n this.setStep(next);\n }\n\n /** Remplace l'étape courante sans l'empiler (transitions sans retour). */\n replace(next: NayaStep): void {\n this.setStep(next);\n }\n\n get canGoBack(): boolean {\n return this.stepHistory.length > 0;\n }\n\n /** Revient à l'étape précédente si elle existe. */\n back(): void {\n const prev = this.stepHistory.pop();\n if (prev) this.setStep(prev);\n }\n\n private setStep(step: NayaStep): void {\n this.step = step;\n this.onStep(step);\n }\n\n get client(): NayaApiClient {\n return this.api;\n }\n\n /** La CNI CEDEAO porte sa MRZ au verso ; les autres pièces n'en ont pas besoin. */\n get needsVerso(): boolean {\n return this.document === 'cni';\n }\n\n get canRetry(): boolean {\n return this.attemptsUsed < this.config.maxAttempts;\n }\n\n /** Crée la session serveur si nécessaire (documentType + pays requis). */\n async ensureSession(): Promise<NayaSession> {\n if (this.session) return this.session;\n const created = await this.api.start({\n documentType: this.document!,\n country: this.country!,\n callbackUrl: this.config.callbackUrl,\n });\n this.session = created;\n return created;\n }\n\n /**\n * Lance (une seule fois) l'envoi du document en arrière-plan : l'OCR serveur\n * tourne pendant que l'utilisateur fait son selfie.\n */\n startDocumentUpload(): void {\n if (this.documentUpload) return;\n const upload = this.uploadDocument();\n this.documentUpload = upload;\n // Personne n'attend cet envoi (il tourne pendant le selfie) : on neutralise\n // un éventuel rejet non géré. `ensureDocumentUploaded` en relancera un frais\n // puisque `uploadDocument` a remis `documentUpload` à null en cas d'échec.\n upload.catch(() => {});\n }\n\n /**\n * Attend la fin de l'envoi du document, en le (re)lançant si besoin. Après un\n * échec, un nouvel appel retente l'envoi.\n */\n ensureDocumentUploaded(): Promise<void> {\n return (this.documentUpload ??= this.uploadDocument());\n }\n\n private async uploadDocument(): Promise<void> {\n try {\n const s = await this.ensureSession();\n await this.api.uploadDocument(s.verificationId, {\n rectoBase64: this.rectoBase64!,\n versoBase64: this.versoBase64 ?? undefined,\n });\n } catch (err) {\n this.documentUpload = null; // permet le retry\n throw err;\n }\n }\n\n /**\n * Prépare une nouvelle tentative après un rejet : nouvelle session, captures\n * remises à zéro.\n */\n resetForRetry(): void {\n this.attemptsUsed += 1;\n this.session = null;\n this.rectoBase64 = null;\n this.versoBase64 = null;\n this.livenessScore = 0;\n this.selfieBase64 = null;\n this.submitResponse = null;\n this.documentUpload = null;\n this.stepHistory = [];\n }\n\n documentTypeNeedsVerso(doc: NayaDocumentType): boolean {\n return documentNeedsVerso(doc);\n }\n\n complete(result: NayaResult): void {\n if (this.finished) return;\n this.finished = true;\n this.finishCb({\n ...result,\n verificationId: result.verificationId ?? this.session?.verificationId,\n });\n }\n\n cancel(): void {\n this.complete({ status: 'cancelled' });\n }\n}\n","/** Petits utilitaires DOM, sans dépendance. */\n\n/** Échappe une chaîne pour une insertion sûre en contenu HTML. */\nexport function escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, (c) =>\n ({ '&': '&', '<': '<', '>': '>', '\"': '"', \"'\": ''' })[c]!,\n );\n}\n\n/** Crée un élément et lui pose optionnellement une classe et du HTML interne. */\nexport function el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n className?: string,\n html?: string,\n): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag);\n if (className) node.className = className;\n if (html !== undefined) node.innerHTML = html;\n return node;\n}\n","/**\n * Jeu d'icônes SVG inline (style outline). Aucun emoji, aucune dépendance\n * externe. Reprend `naya-icon.component.ts`. Les tracés sont des constantes\n * statiques, sans donnée externe — sûrs à injecter en `innerHTML`.\n */\n\nexport type NayaIconName =\n | 'shield'\n | 'lock'\n | 'fingerprint'\n | 'close'\n | 'back'\n | 'chevron'\n | 'check'\n | 'clock'\n | 'wifi-off'\n | 'refresh'\n | 'id-card'\n | 'passport'\n | 'car'\n | 'sun'\n | 'focus'\n | 'eye'\n | 'rotate'\n | 'hourglass';\n\nconst PATHS: Record<NayaIconName, string> = {\n shield: '<path d=\"M12 3l7 3v5c0 4.5-3 8.3-7 10-4-1.7-7-5.5-7-10V6l7-3z\"/><path d=\"M9 12l2 2 4-4\"/>',\n lock: '<rect x=\"5\" y=\"11\" width=\"14\" height=\"9\" rx=\"2\"/><path d=\"M8 11V8a4 4 0 0 1 8 0v3\"/>',\n fingerprint:\n '<path d=\"M12 11a2 2 0 0 1 2 2v1a5 5 0 0 1-.5 2.2\"/><path d=\"M8 13a4 4 0 0 1 8 0v1a8 8 0 0 1-.8 3.5\"/><path d=\"M5.5 15A7 7 0 0 1 5 12a7 7 0 0 1 12-5\"/><path d=\"M12 20v-7\"/>',\n close: '<path d=\"M6 6l12 12M18 6L6 18\"/>',\n back: '<path d=\"M15 5l-7 7 7 7\"/>',\n chevron: '<path d=\"M9 6l6 6-6 6\"/>',\n check: '<path d=\"M5 12l5 5L20 7\"/>',\n clock: '<circle cx=\"12\" cy=\"12\" r=\"8\"/><path d=\"M12 8v4l3 2\"/>',\n 'wifi-off':\n '<path d=\"M3 3l18 18\"/><path d=\"M5 12a11 11 0 0 1 4-2.5\"/><path d=\"M8.5 16.5A5 5 0 0 1 12 15a5 5 0 0 1 2 .4\"/><path d=\"M12 20h.01\"/>',\n refresh:\n '<path d=\"M4 12a8 8 0 0 1 13.7-5.7L20 8\"/><path d=\"M20 4v4h-4\"/><path d=\"M20 12a8 8 0 0 1-13.7 5.7L4 16\"/><path d=\"M4 20v-4h4\"/>',\n 'id-card':\n '<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\"/><circle cx=\"8.5\" cy=\"11\" r=\"2\"/><path d=\"M13 10h5M13 14h5M5.5 15a3 3 0 0 1 6 0\"/>',\n passport:\n '<rect x=\"5\" y=\"3\" width=\"14\" height=\"18\" rx=\"2\"/><circle cx=\"12\" cy=\"10\" r=\"3\"/><path d=\"M9 16h6\"/>',\n car: '<path d=\"M5 16l1.5-5A2 2 0 0 1 8.4 10h7.2a2 2 0 0 1 1.9 1l1.5 5\"/><rect x=\"3\" y=\"16\" width=\"18\" height=\"4\" rx=\"1\"/><circle cx=\"7.5\" cy=\"20\" r=\"1\"/><circle cx=\"16.5\" cy=\"20\" r=\"1\"/>',\n sun: '<circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M12 2v2M12 20v2M2 12h2M20 12h2M5 5l1.5 1.5M17.5 17.5L19 19M19 5l-1.5 1.5M6.5 17.5L5 19\"/>',\n focus:\n '<path d=\"M4 8V6a2 2 0 0 1 2-2h2M16 4h2a2 2 0 0 1 2 2v2M20 16v2a2 2 0 0 1-2 2h-2M8 20H6a2 2 0 0 1-2-2v-2\"/><circle cx=\"12\" cy=\"12\" r=\"2.5\"/>',\n eye: '<path d=\"M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/>',\n rotate: '<path d=\"M12 4a8 8 0 1 1-7.5 5.3\"/><path d=\"M4 4v5h5\"/>',\n hourglass: '<path d=\"M7 3h10M7 21h10M8 3c0 4 8 5 8 9s-8 5-8 9M16 3c0 4-8 5-8 9s8 5 8 9\"/>',\n};\n\n/** Renvoie le balisage `<svg>` d'une icône. */\nexport function iconSvg(name: NayaIconName, size = 20, stroke = 2): string {\n return (\n `<svg class=\"n-icon\" width=\"${size}\" height=\"${size}\" viewBox=\"0 0 24 24\" fill=\"none\" ` +\n `stroke=\"currentColor\" stroke-width=\"${stroke}\" stroke-linecap=\"round\" ` +\n `stroke-linejoin=\"round\" aria-hidden=\"true\">${PATHS[name]}</svg>`\n );\n}\n","import { escapeHtml } from './dom';\nimport { iconSvg, type NayaIconName } from './icons';\n\n/** Contrat d'un écran : un élément racine à monter et un nettoyage. */\nexport interface Screen {\n readonly el: HTMLElement;\n dispose(): void;\n}\n\n/** Marque Naya (pictogramme + nom). Écrans bienvenue et traitement. */\nexport function brandHtml(): string {\n return (\n `<span class=\"n-brand\"><span class=\"n-mark\">${iconSvg('fingerprint', 17)}</span>` +\n `<span class=\"n-name\">Naya ID</span></span>`\n );\n}\n\n/** Indicateur des trois grandes étapes (Document · Selfie · Résultat). */\nexport function stepsDotsHtml(labels: string[], activeIndex: number): string {\n const steps = labels\n .map(\n (l, i) =>\n `<div class=\"n-step\"><span class=\"n-dot${i <= activeIndex ? ' on' : ''}\"></span>` +\n `<span class=\"n-dotlbl\">${escapeHtml(l)}</span></div>`,\n )\n .join('');\n return `<div class=\"n-dots\">${steps}</div>`;\n}\n\n/** CTA principal (plein, ambre). `act` sert de sélecteur `data-act`. */\nexport function primaryButtonHtml(\n label: string,\n opts: { icon?: NayaIconName; disabled?: boolean; act?: string } = {},\n): string {\n const act = opts.act ?? 'primary';\n return (\n `<button type=\"button\" class=\"n-btn n-btn-primary\" data-act=\"${act}\"${opts.disabled ? ' disabled' : ''}>` +\n `${opts.icon ? iconSvg(opts.icon, 18) : ''}<span>${escapeHtml(label)}</span></button>`\n );\n}\n\n/** Bouton secondaire (contour). */\nexport function secondaryButtonHtml(label: string, act = 'secondary'): string {\n return `<button type=\"button\" class=\"n-btn n-btn-secondary\" data-act=\"${act}\">${escapeHtml(label)}</button>`;\n}\n\nexport interface ShellOptions {\n poweredBy: string;\n /** Classe de l'écran, portée sur `<main>` pour scoper ses styles. */\n screenClass: string;\n dark?: boolean;\n canBack?: boolean;\n /** Défaut : true. */\n canClose?: boolean;\n onBack?: () => void;\n onClose?: () => void;\n}\n\n/**\n * Gabarit d'écran : en-tête (retour / fermer), zone de contenu, pied « Propulsé\n * par Naya ID ». Reprend `naya-screen.component.ts`.\n */\nexport function buildShell(opts: ShellOptions): { root: HTMLElement; content: HTMLElement } {\n const canClose = opts.canClose !== false;\n const root = document.createElement('div');\n root.className = 'n-shell' + (opts.dark ? ' n-dark' : '');\n root.innerHTML =\n `<header class=\"n-bar\">` +\n (opts.canBack\n ? `<button type=\"button\" class=\"n-round\" data-nav=\"back\" aria-label=\"Retour\">${iconSvg('back', 20)}</button>`\n : `<span class=\"n-spacer\"></span>`) +\n (canClose\n ? `<button type=\"button\" class=\"n-round\" data-nav=\"close\" aria-label=\"Fermer\">${iconSvg('close', 20)}</button>`\n : `<span class=\"n-spacer\"></span>`) +\n `</header>` +\n `<main class=\"n-content ${opts.screenClass}\"></main>` +\n `<footer class=\"n-powered\">${escapeHtml(opts.poweredBy)}</footer>`;\n\n root.querySelector('[data-nav=\"back\"]')?.addEventListener('click', () => opts.onBack?.());\n root.querySelector('[data-nav=\"close\"]')?.addEventListener('click', () => opts.onClose?.());\n\n const content = root.querySelector('.n-content') as HTMLElement;\n return { root, content };\n}\n","import type { NayaFlow } from '../flow/flow';\nimport { buildShell, brandHtml, primaryButtonHtml, stepsDotsHtml, type Screen } from '../ui/components';\nimport { iconSvg } from '../ui/icons';\nimport { escapeHtml } from '../ui/dom';\n\n/** Écran 1 — Bienvenue. */\nexport class WelcomeScreen implements Screen {\n readonly el: HTMLElement;\n\n constructor(private readonly flow: NayaFlow) {\n const s = flow.strings;\n const config = flow.config;\n const { root, content } = buildShell({\n poweredBy: s.poweredBy,\n screenClass: 'n-welcome',\n onClose: () => flow.cancel(),\n });\n this.el = root;\n\n const stepLabels = [s.stepDocument, s.stepSelfie, s.stepResult];\n const logo = config.clientLogoUrl\n ? `<span class=\"sep\"></span><img class=\"clientLogo\" src=\"${escapeHtml(config.clientLogoUrl)}\" alt=\"\">`\n : '';\n\n content.innerHTML = `\n <div class=\"pad\">\n <div class=\"brandRow\">${brandHtml()}${logo}</div>\n <div class=\"spacer\"></div>\n <div class=\"hero\">${iconSvg('shield', 56, 1.6)}</div>\n <h1 class=\"title\">${escapeHtml(s.welcomeTitle)}</h1>\n <p class=\"body\">${escapeHtml(s.welcomeSubtitle)}</p>\n <div class=\"steps\">${stepsDotsHtml(stepLabels, 0)}</div>\n <div class=\"spacer\"></div>\n ${primaryButtonHtml(s.welcomeCta, { act: 'start' })}\n <div class=\"secure\">${iconSvg('lock', 13, 2)}<span>${escapeHtml(s.welcomeSecurity)}</span></div>\n </div>`;\n\n content.querySelector('[data-act=\"start\"]')?.addEventListener('click', () => this.start());\n }\n\n dispose(): void {}\n\n private start(): void {\n const cfg = this.flow.config;\n const single = !!cfg.country && cfg.documentTypes.length === 1;\n if (single) {\n this.flow.country = cfg.country!;\n this.flow.document = cfg.documentTypes[0]!;\n this.flow.go('capture-recto');\n } else {\n this.flow.go('select');\n }\n }\n}\n","import type { NayaFlow } from '../flow/flow';\nimport {\n type NayaCountryCode,\n type NayaDocumentType,\n countryLabel,\n} from '../models/config';\nimport { buildShell, primaryButtonHtml, type Screen } from '../ui/components';\nimport { iconSvg, type NayaIconName } from '../ui/icons';\nimport { escapeHtml } from '../ui/dom';\n\nfunction docIcon(doc: NayaDocumentType): NayaIconName {\n switch (doc) {\n case 'cni': return 'id-card';\n case 'passeport': return 'passport';\n case 'permis': return 'car';\n }\n}\n\n/** Écran 2 — Choix du pays et du type de document. */\nexport class DocumentSelectionScreen implements Screen {\n readonly el: HTMLElement;\n private readonly content: HTMLElement;\n private country: NayaCountryCode;\n private document: NayaDocumentType | null;\n\n constructor(private readonly flow: NayaFlow) {\n const s = flow.strings;\n const config = flow.config;\n const lockedCountry = !!config.country;\n this.country = config.country ?? config.countries[0]!;\n this.document = config.documentTypes.length === 1 ? config.documentTypes[0]! : null;\n\n const { root, content } = buildShell({\n poweredBy: s.poweredBy,\n screenClass: 'n-select',\n canBack: flow.canGoBack,\n onBack: () => flow.back(),\n onClose: () => flow.cancel(),\n });\n this.el = root;\n this.content = content;\n\n const chips = lockedCountry\n ? ''\n : `<div class=\"chips\" role=\"listbox\" aria-label=\"Pays\">${config.countries\n .map(\n (code) =>\n `<button type=\"button\" class=\"chip${code === this.country ? ' on' : ''}\" role=\"option\" ` +\n `data-country=\"${code}\" aria-selected=\"${code === this.country}\">${escapeHtml(countryLabel(code))}</button>`,\n )\n .join('')}</div>`;\n\n const cards = config.documentTypes\n .map(\n (doc) =>\n `<button type=\"button\" class=\"card${doc === this.document ? ' on' : ''}\" data-doc=\"${doc}\">` +\n `<span class=\"ico\">${iconSvg(docIcon(doc), 20)}</span>` +\n `<span class=\"lbl\">${escapeHtml(s.docLabel(doc))}</span>${iconSvg('chevron', 20, 2)}</button>`,\n )\n .join('');\n\n content.innerHTML = `\n <div class=\"pad\">\n <h1 class=\"title\">${escapeHtml(s.docSelectTitle)}</h1>\n <p class=\"body\">${escapeHtml(s.docSelectSubtitle)}</p>\n ${chips}\n <div class=\"cards\">${cards}</div>\n <div class=\"spacer\"></div>\n ${primaryButtonHtml(s.continueLabel, { disabled: !this.document, act: 'next' })}\n </div>`;\n\n content.querySelectorAll<HTMLElement>('[data-country]').forEach((btn) =>\n btn.addEventListener('click', () => this.selectCountry(btn)),\n );\n content.querySelectorAll<HTMLElement>('[data-doc]').forEach((btn) =>\n btn.addEventListener('click', () => this.selectDoc(btn)),\n );\n content.querySelector('[data-act=\"next\"]')?.addEventListener('click', () => this.next());\n }\n\n dispose(): void {}\n\n private selectCountry(btn: HTMLElement): void {\n this.country = btn.getAttribute('data-country') as NayaCountryCode;\n this.content.querySelectorAll<HTMLElement>('.chip').forEach((c) => {\n const on = c === btn;\n c.classList.toggle('on', on);\n c.setAttribute('aria-selected', String(on));\n });\n }\n\n private selectDoc(btn: HTMLElement): void {\n this.document = btn.getAttribute('data-doc') as NayaDocumentType;\n this.content.querySelectorAll<HTMLElement>('.card').forEach((c) => c.classList.toggle('on', c === btn));\n const next = this.content.querySelector<HTMLButtonElement>('[data-act=\"next\"]');\n if (next) next.disabled = false;\n }\n\n private next(): void {\n if (!this.document) return;\n this.flow.country = this.country;\n this.flow.document = this.document;\n this.flow.go('capture-recto');\n }\n}\n","/**\n * Traitement d'image pour le web — équivalent de `image_utils.dart`, adapté au\n * pipeline canvas du navigateur.\n *\n * Les seuils sont repris de Flutter à titre de point de départ. Ils devront\n * être **recalibrés** : la mesure porte ici sur des pixels RGBA issus d'un\n * canvas, pas sur les plans NV21/BGRA natifs.\n */\n\n/**\n * Seuil de netteté (variance du Laplacien) au-delà duquel le cadre passe au\n * vert. Volontairement prudent — à ajuster après essais multi-navigateurs.\n */\nexport const SHARPNESS_READY_THRESHOLD = 60;\n\n/** En dessous, l'éclairage est jugé insuffisant (luminance moyenne 0-255). */\nexport const LUMINANCE_MIN = 60;\n/** Au-dessus, l'image est surexposée. */\nexport const LUMINANCE_MAX = 235;\n\n/**\n * Compresse une image (élément vidéo ou canvas) en data-URL JPEG.\n *\n * Un JPEG ≤ 1600 px de côté à qualité 0,85 reste largement sous la limite du\n * corps JSON tout en préservant la lisibilité OCR — important sur les réseaux\n * mobiles d'Afrique de l'Ouest.\n */\nexport function canvasToJpegDataUrl(\n source: HTMLCanvasElement | HTMLVideoElement,\n maxDimension = 1600,\n quality = 0.85,\n): string {\n const srcW = source instanceof HTMLVideoElement ? source.videoWidth : source.width;\n const srcH = source instanceof HTMLVideoElement ? source.videoHeight : source.height;\n\n const scale = Math.min(1, maxDimension / Math.max(srcW, srcH));\n const w = Math.round(srcW * scale);\n const h = Math.round(srcH * scale);\n\n const canvas = document.createElement('canvas');\n canvas.width = w;\n canvas.height = h;\n const ctx = canvas.getContext('2d');\n if (!ctx) return '';\n ctx.drawImage(source, 0, 0, w, h);\n return canvas.toDataURL('image/jpeg', quality);\n}\n\nexport interface FrameQuality {\n luminance: number;\n sharpness: number;\n lightOk: boolean;\n sharpOk: boolean;\n}\n\n/**\n * Échantillonne une zone d'une trame vidéo et renvoie luminance moyenne et\n * netteté (variance du Laplacien) en une seule passe, sur un canvas réduit.\n * `region` cible la fenêtre du cadre de guidage (fractions 0-1).\n */\nexport function measureFrameQuality(\n video: HTMLVideoElement,\n scratch: HTMLCanvasElement,\n region = { x: 0.25, y: 0.25, w: 0.5, h: 0.5 },\n sampleWidth = 240,\n): FrameQuality {\n const vw = video.videoWidth;\n const vh = video.videoHeight;\n if (vw < 8 || vh < 8) {\n return { luminance: 0, sharpness: 0, lightOk: false, sharpOk: false };\n }\n\n const sx = Math.floor(vw * region.x);\n const sy = Math.floor(vh * region.y);\n const sw = Math.floor(vw * region.w);\n const sh = Math.floor(vh * region.h);\n\n const scale = Math.min(1, sampleWidth / sw);\n const w = Math.max(8, Math.round(sw * scale));\n const h = Math.max(8, Math.round(sh * scale));\n\n scratch.width = w;\n scratch.height = h;\n const ctx = scratch.getContext('2d', { willReadFrequently: true });\n if (!ctx) return { luminance: 0, sharpness: 0, lightOk: false, sharpOk: false };\n\n ctx.drawImage(video, sx, sy, sw, sh, 0, 0, w, h);\n const { data } = ctx.getImageData(0, 0, w, h);\n\n // Luminance (Rec. 601) par pixel, puis variance du Laplacien 4-voisins.\n const lum = new Float32Array(w * h);\n let sumLum = 0;\n for (let i = 0, p = 0; i < data.length; i += 4, p++) {\n const l = 0.299 * data[i] + 0.587 * data[i + 1] + 0.114 * data[i + 2];\n lum[p] = l;\n sumLum += l;\n }\n const luminance = sumLum / (w * h);\n\n let sum = 0;\n let sumSq = 0;\n let count = 0;\n for (let y = 1; y < h - 1; y++) {\n for (let x = 1; x < w - 1; x++) {\n const idx = y * w + x;\n const lap =\n 4 * lum[idx] - lum[idx - 1] - lum[idx + 1] - lum[idx - w] - lum[idx + w];\n sum += lap;\n sumSq += lap * lap;\n count++;\n }\n }\n const mean = count ? sum / count : 0;\n const sharpness = count ? sumSq / count - mean * mean : 0;\n\n return {\n luminance,\n sharpness,\n lightOk: luminance >= LUMINANCE_MIN && luminance <= LUMINANCE_MAX,\n sharpOk: sharpness >= SHARPNESS_READY_THRESHOLD,\n };\n}\n","import type { NayaFlow } from '../flow/flow';\nimport { buildShell, type Screen } from '../ui/components';\nimport { iconSvg } from '../ui/icons';\nimport { escapeHtml } from '../ui/dom';\nimport { canvasToJpegDataUrl, measureFrameQuality } from '../utils/image-utils';\n\n/**\n * Écrans 3-4 — Capture du document (recto puis verso pour la CNI).\n *\n * Caméra arrière, cadre de guidage au ratio carte (1,586), contrôles qualité en\n * direct (luminosité + netteté). Cadre et déclencheur passent au vert quand\n * l'image est nette et bien éclairée — c'est l'utilisateur qui valide.\n */\nexport class DocumentCaptureScreen implements Screen {\n readonly el: HTMLElement;\n private readonly content: HTMLElement;\n private readonly scratch = document.createElement('canvas');\n\n private video: HTMLVideoElement | null = null;\n private cardEl!: HTMLElement;\n private shutterEl!: HTMLButtonElement;\n private hintEl!: HTMLElement;\n private loadingEl!: HTMLElement;\n private lightPill!: HTMLElement;\n private sharpPill!: HTMLElement;\n\n private stream: MediaStream | null = null;\n private qualityTimer: ReturnType<typeof setInterval> | null = null;\n private streaming = false;\n private capturing = false;\n private lightOk = false;\n private sharpOk = false;\n private disposed = false;\n\n constructor(\n private readonly flow: NayaFlow,\n private readonly side: 'recto' | 'verso',\n ) {\n const s = flow.strings;\n const { root, content } = buildShell({\n poweredBy: s.poweredBy,\n screenClass: 'n-capture',\n dark: true,\n canBack: flow.canGoBack,\n onBack: () => flow.back(),\n onClose: () => flow.cancel(),\n });\n this.el = root;\n this.content = content;\n\n const instruction = side === 'recto' ? s.captureRectoInstruction : s.captureVersoInstruction;\n content.innerHTML = `\n <div class=\"pad\">\n <p class=\"instruction\">${escapeHtml(instruction)}</p>\n <div class=\"cardWrap\">\n <div class=\"card\" data-card>\n <video class=\"preview\" playsinline muted autoplay></video>\n <div class=\"camMsg\" data-loading><span class=\"loader\"></span></div>\n <svg class=\"corners\" viewBox=\"0 0 100 63\" preserveAspectRatio=\"none\" aria-hidden=\"true\">\n <path d=\"M2,14 L2,6 Q2,2 6,2 L16,2\"/>\n <path d=\"M84,2 L94,2 Q98,2 98,6 L98,14\"/>\n <path d=\"M98,49 L98,57 Q98,61 94,61 L84,61\"/>\n <path d=\"M16,61 L6,61 Q2,61 2,57 L2,49\"/>\n </svg>\n </div>\n </div>\n <div class=\"pills\">\n <span class=\"pill\" data-pill=\"light\"><span class=\"pico\" data-ico>${iconSvg('sun', 15, 2.4)}</span><span>${escapeHtml(s.qualityLight)}</span></span>\n <span class=\"pill\" data-pill=\"sharp\"><span class=\"pico\" data-ico>${iconSvg('focus', 15, 2.4)}</span><span>${escapeHtml(s.qualitySharpness)}</span></span>\n </div>\n <button type=\"button\" class=\"shutter\" data-act=\"capture\" disabled aria-label=\"${escapeHtml(s.captureHint)}\"></button>\n <p class=\"hint\">${escapeHtml(s.captureHint)}</p>\n </div>`;\n\n this.video = content.querySelector('.preview');\n this.cardEl = content.querySelector('[data-card]')!;\n this.shutterEl = content.querySelector('[data-act=\"capture\"]')!;\n this.hintEl = content.querySelector('.hint')!;\n this.loadingEl = content.querySelector('[data-loading]')!;\n this.lightPill = content.querySelector('[data-pill=\"light\"]')!;\n this.sharpPill = content.querySelector('[data-pill=\"sharp\"]')!;\n this.shutterEl.addEventListener('click', () => void this.capture());\n\n void this.startCamera();\n }\n\n dispose(): void {\n this.disposed = true;\n this.stopCamera();\n }\n\n private async startCamera(): Promise<void> {\n if (!navigator.mediaDevices?.getUserMedia) {\n this.showCameraError();\n return;\n }\n try {\n // Caméra arrière privilégiée pour le document ; repli sur défaut.\n const stream = await navigator.mediaDevices.getUserMedia({\n video: { facingMode: { ideal: 'environment' }, width: { ideal: 1920 } },\n audio: false,\n });\n // L'écran a pu être quitté pendant l'attente d'autorisation.\n if (this.disposed || !this.video) {\n stream.getTracks().forEach((t) => t.stop());\n return;\n }\n this.stream = stream;\n this.video.srcObject = stream;\n await this.video.play().catch(() => {});\n this.loadingEl.hidden = true;\n this.streaming = true;\n this.updateReady();\n this.startQualityLoop();\n } catch {\n this.showCameraError();\n }\n }\n\n private startQualityLoop(): void {\n // ~350 ms : retour fluide sans saturer le thread principal.\n this.qualityTimer = setInterval(() => {\n if (this.capturing || !this.video || this.video.videoWidth < 8) return;\n const q = measureFrameQuality(this.video, this.scratch);\n if (q.lightOk !== this.lightOk) this.setLight(q.lightOk);\n if (q.sharpOk !== this.sharpOk) this.setSharp(q.sharpOk);\n }, 350);\n }\n\n private setLight(ok: boolean): void {\n this.lightOk = ok;\n this.lightPill.classList.toggle('ok', ok);\n this.lightPill.querySelector('[data-ico]')!.innerHTML = iconSvg(ok ? 'check' : 'sun', 15, 2.4);\n this.updateReady();\n }\n\n private setSharp(ok: boolean): void {\n this.sharpOk = ok;\n this.sharpPill.classList.toggle('ok', ok);\n this.sharpPill.querySelector('[data-ico]')!.innerHTML = iconSvg(ok ? 'check' : 'focus', 15, 2.4);\n this.updateReady();\n }\n\n private updateReady(): void {\n const s = this.flow.strings;\n const ready = this.lightOk && this.sharpOk && !this.capturing;\n this.cardEl.classList.toggle('ready', ready);\n this.shutterEl.classList.toggle('ready', ready);\n this.hintEl.classList.toggle('ready', ready);\n this.hintEl.textContent = ready ? s.captureReady : s.captureHint;\n this.shutterEl.disabled = !this.streaming || this.capturing;\n }\n\n private showCameraError(): void {\n if (this.disposed) return;\n if (this.video) this.video.hidden = true;\n this.loadingEl.hidden = false;\n this.loadingEl.textContent = this.flow.strings.errorCamera;\n }\n\n private async capture(): Promise<void> {\n if (!this.video || this.capturing || !this.streaming) return;\n this.capturing = true;\n this.shutterEl.innerHTML = '<span class=\"loader sm\"></span>';\n this.updateReady();\n try {\n const dataUrl = canvasToJpegDataUrl(this.video);\n this.stopCamera();\n\n if (this.side === 'recto') {\n this.flow.rectoBase64 = dataUrl;\n if (this.flow.needsVerso) {\n this.flow.go('capture-verso');\n return;\n }\n } else {\n this.flow.versoBase64 = dataUrl;\n }\n\n // Dernière face : l'envoi (session + document) part en arrière-plan\n // pendant que l'utilisateur enchaîne sur le selfie.\n this.flow.startDocumentUpload();\n this.flow.go('liveness');\n } finally {\n this.capturing = false;\n }\n }\n\n private stopCamera(): void {\n if (this.qualityTimer) clearInterval(this.qualityTimer);\n this.qualityTimer = null;\n this.stream?.getTracks().forEach((t) => t.stop());\n this.stream = null;\n this.streaming = false;\n }\n}\n","/**\n * Machine à états du défi de vivacité, exécutée sur l'appareil.\n *\n * Port fidèle de `liveness_challenge.dart` / `liveness-challenge.ts`. La logique\n * est identique ; l'entrée est un jeu de signaux normalisés par l'adaptateur\n * MediaPipe — probabilités d'yeux ouverts (0-1) et lacet approximatif en degrés.\n *\n * Séquence : détection du visage → clignement → rotation de la tête. Chaque\n * trame fait avancer (ou reculer) l'état ; le score final reflète la complétion\n * du défi et la stabilité du suivi.\n */\n\nexport type LivenessStep = 'searching-face' | 'blink' | 'turn-head' | 'done';\n\n/** Signaux extraits d'une trame par l'adaptateur de suivi facial. */\nexport interface FaceSignals {\n /** Nombre de visages détectés. Le défi exige exactement un. */\n faceCount: number;\n /** Probabilité d'œil gauche ouvert (0-1), ou null si indisponible. */\n leftEyeOpen: number | null;\n /** Probabilité d'œil droit ouvert (0-1), ou null si indisponible. */\n rightEyeOpen: number | null;\n /** Lacet de la tête en degrés (négatif/positif selon le côté), ou null. */\n yawDegrees: number | null;\n}\n\n// Seuils repris de Flutter. Valeurs de départ : la source des signaux diffère\n// (blendshapes MediaPipe vs classification ML Kit), un recalibrage sur visages\n// réels est attendu.\nconst EYES_CLOSED_THRESHOLD = 0.25;\nconst EYES_OPEN_THRESHOLD = 0.65;\nconst HEAD_TURN_DEGREES = 16;\nconst FRAMES_TO_LOCK_FACE = 6;\nconst FRAMES_LOST_BEFORE_RESET = 12;\n\nexport class LivenessChallenge {\n step: LivenessStep = 'searching-face';\n\n private framesWithFace = 0;\n private framesWithoutFace = 0;\n private eyesClosedSeen = false;\n private blinkDone = false;\n private turnDone = false;\n\n /** Index numérique de l'étape (pour l'anneau de progression). */\n get stepIndex(): number {\n return { 'searching-face': 0, blink: 1, 'turn-head': 2, done: 3 }[this.step];\n }\n\n get isDone(): boolean {\n return this.step === 'done';\n }\n\n /**\n * Fait avancer la machine avec les signaux d'une trame. Retourne `true` si\n * l'étape courante a changé (pour rafraîchir l'interface).\n */\n onFrame(sig: FaceSignals): boolean {\n const before = this.step;\n\n if (sig.faceCount !== 1) {\n this.framesWithoutFace++;\n // Visage perdu trop longtemps → retour à la détection, sans annuler les\n // défis déjà réussis.\n if (this.framesWithoutFace > FRAMES_LOST_BEFORE_RESET && this.step !== 'done') {\n this.step = 'searching-face';\n this.framesWithFace = 0;\n }\n return this.step !== before;\n }\n\n this.framesWithoutFace = 0;\n this.framesWithFace++;\n\n switch (this.step) {\n case 'searching-face':\n if (this.framesWithFace >= FRAMES_TO_LOCK_FACE) {\n this.step = this.blinkDone ? 'turn-head' : 'blink';\n }\n break;\n\n case 'blink': {\n const { leftEyeOpen: l, rightEyeOpen: r } = sig;\n if (l == null || r == null) break;\n if (l < EYES_CLOSED_THRESHOLD && r < EYES_CLOSED_THRESHOLD) {\n this.eyesClosedSeen = true;\n } else if (this.eyesClosedSeen && l > EYES_OPEN_THRESHOLD && r > EYES_OPEN_THRESHOLD) {\n this.blinkDone = true;\n this.step = this.turnDone ? 'done' : 'turn-head';\n }\n break;\n }\n\n case 'turn-head': {\n const yaw = sig.yawDegrees;\n if (yaw != null && Math.abs(yaw) > HEAD_TURN_DEGREES) {\n this.turnDone = true;\n this.step = 'done';\n }\n break;\n }\n\n case 'done':\n break;\n }\n\n return this.step !== before;\n }\n\n /**\n * Score 0-100 transmis à l'API. Défi complet → 90 + bonus de stabilité de\n * suivi (jusqu'à 8). Jamais de score élevé sans défi réussi.\n */\n score(): number {\n if (!this.isDone) {\n let partial = 20;\n if (this.framesWithFace >= FRAMES_TO_LOCK_FACE) partial += 15;\n if (this.blinkDone) partial += 15;\n return partial;\n }\n const stabilityBonus = Math.min(8, Math.round(this.framesWithFace / 30));\n return 90 + stabilityBonus;\n }\n}\n","import type { NayaLivenessAssets } from '../models/config';\nimport type { FaceSignals } from './liveness-challenge';\n\n/**\n * Adaptateur de suivi facial pour le web, sur MediaPipe Face Landmarker.\n *\n * Contrairement au SDK Angular (qui importe `@mediapipe/tasks-vision` en\n * dépendance npm), la version « balise script » charge le module ESM **au\n * runtime depuis un CDN** — via un `import()` dynamique dont l'URL est une\n * variable, si bien qu'il n'est jamais inclus dans le bundle et n'est cherché\n * qu'au démarrage du défi de vivacité.\n *\n * Deux sorties du modèle sont exploitées :\n * • **Blendshapes** `eyeBlinkLeft` / `eyeBlinkRight` (0 = ouvert, 1 = fermé).\n * ML Kit fournissait l'inverse ; on convertit par `ouvert = 1 - clignement`.\n * • **Landmarks** — le lacet de la tête est estimé par la position du nez\n * entre les deux bords du visage. Robuste, au prix d'une échelle\n * approximative (documentée, à recalibrer).\n */\n\nexport interface FaceTrackerAssets {\n /** URL du module ESM `@mediapipe/tasks-vision`. Défaut : jsDelivr. */\n esmUrl?: string;\n /** Base des fichiers WASM de `tasks-vision`. Défaut : jsDelivr. */\n wasmBaseUrl?: string;\n /** URL du modèle `.task` de Face Landmarker. Défaut : stockage Google. */\n modelUrl?: string;\n}\n\n// La version du module ESM et celle du WASM doivent correspondre, sous peine\n// d'incompatibilité runtime.\nconst MP_VERSION = '1.0.1';\nconst DEFAULT_ESM =\n `https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@${MP_VERSION}/vision_bundle.mjs`;\nconst DEFAULT_WASM_BASE =\n `https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@${MP_VERSION}/wasm`;\nconst DEFAULT_MODEL =\n 'https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task';\n\n// Indices de landmarks (topologie 468 points de MediaPipe Face Mesh).\nconst NOSE_TIP = 1;\nconst FACE_LEFT_EDGE = 234;\nconst FACE_RIGHT_EDGE = 454;\n\nexport class FaceTracker {\n private landmarker: any = null;\n\n /** Charge le module et le modèle. À appeler une fois, avant `detect`. */\n async init(assets: NayaLivenessAssets & FaceTrackerAssets = {}): Promise<void> {\n // URL en variable : esbuild laisse l'`import()` en dynamique (non bundlé).\n const esmUrl = assets.esmUrl ?? DEFAULT_ESM;\n const vision: any = await import(/* @vite-ignore */ /* webpackIgnore: true */ esmUrl);\n const { FaceLandmarker, FilesetResolver } = vision;\n\n const fileset = await FilesetResolver.forVisionTasks(\n assets.wasmBaseUrl ?? DEFAULT_WASM_BASE,\n );\n this.landmarker = await FaceLandmarker.createFromOptions(fileset, {\n baseOptions: {\n modelAssetPath: assets.modelUrl ?? DEFAULT_MODEL,\n delegate: 'GPU',\n },\n runningMode: 'VIDEO',\n numFaces: 1,\n outputFaceBlendshapes: true,\n });\n }\n\n get ready(): boolean {\n return !!this.landmarker;\n }\n\n /** Analyse une trame vidéo et renvoie les signaux normalisés du défi. */\n detect(video: HTMLVideoElement, timestampMs: number): FaceSignals {\n if (!this.landmarker || video.videoWidth < 8) {\n return { faceCount: 0, leftEyeOpen: null, rightEyeOpen: null, yawDegrees: null };\n }\n\n const result = this.landmarker.detectForVideo(video, timestampMs);\n const faceCount = result.faceLandmarks?.length ?? 0;\n if (faceCount !== 1) {\n return { faceCount, leftEyeOpen: null, rightEyeOpen: null, yawDegrees: null };\n }\n\n // ── Clignement via blendshapes ────────────────────────────────────────\n let leftEyeOpen: number | null = null;\n let rightEyeOpen: number | null = null;\n const shapes = result.faceBlendshapes?.[0]?.categories as\n | Array<{ categoryName: string; score: number }>\n | undefined;\n if (shapes) {\n for (const c of shapes) {\n if (c.categoryName === 'eyeBlinkLeft') leftEyeOpen = 1 - c.score;\n else if (c.categoryName === 'eyeBlinkRight') rightEyeOpen = 1 - c.score;\n }\n }\n\n // ── Lacet via landmarks ───────────────────────────────────────────────\n let yawDegrees: number | null = null;\n const lm = result.faceLandmarks[0];\n const nose = lm[NOSE_TIP];\n const left = lm[FACE_LEFT_EDGE];\n const right = lm[FACE_RIGHT_EDGE];\n if (nose && left && right) {\n const span = right.x - left.x;\n if (Math.abs(span) > 1e-4) {\n // Position relative du nez entre les bords : 0,5 = centré.\n const ratio = (nose.x - left.x) / span;\n // Conversion en pseudo-degrés : ±0,1 d'écart ≈ ±16°, seuil Flutter.\n yawDegrees = (ratio - 0.5) * 160;\n }\n }\n\n return { faceCount: 1, leftEyeOpen, rightEyeOpen, yawDegrees };\n }\n\n close(): void {\n this.landmarker?.close?.();\n this.landmarker = null;\n }\n}\n","import type { NayaFlow } from '../flow/flow';\nimport { buildShell, type Screen } from '../ui/components';\nimport { iconSvg, type NayaIconName } from '../ui/icons';\nimport { escapeHtml } from '../ui/dom';\nimport { canvasToJpegDataUrl } from '../utils/image-utils';\nimport { LivenessChallenge, type LivenessStep } from '../liveness/liveness-challenge';\nimport { FaceTracker } from '../liveness/face-tracker';\n\nconst RING_PATH = 'M105,4 A101,131 0 0 1 105,266 A101,131 0 0 1 105,4 Z';\nconst STEP_INDEX: Record<LivenessStep, number> = {\n 'searching-face': 0, blink: 1, 'turn-head': 2, done: 3,\n};\n\n/**\n * Écran 5 — Selfie avec défi de vivacité sur l'appareil (MediaPipe).\n *\n * Caméra frontale, chaque trame alimente le suivi facial puis la machine à\n * états (visage → clignement → rotation). Défi complet → photo capturée,\n * compressée, passage au traitement. L'analyse est locale : la photo n'est\n * transmise qu'à la fin du défi.\n */\nexport class LivenessScreen implements Screen {\n readonly el: HTMLElement;\n private readonly content: HTMLElement;\n\n private video: HTMLVideoElement | null = null;\n private progEl!: SVGPathElement;\n private instrIcon!: HTMLElement;\n private instrText!: HTMLElement;\n private stepEls: HTMLElement[] = [];\n private loadingEl!: HTMLElement;\n\n private readonly challenge = new LivenessChallenge();\n private readonly tracker = new FaceTracker();\n private stream: MediaStream | null = null;\n private rafId = 0;\n private step: LivenessStep = 'searching-face';\n private streaming = false;\n private finishing = false;\n private disposed = false;\n\n constructor(private readonly flow: NayaFlow) {\n const s = flow.strings;\n const { root, content } = buildShell({\n poweredBy: s.poweredBy,\n screenClass: 'n-liveness',\n onClose: () => flow.cancel(),\n });\n this.el = root;\n this.content = content;\n\n const csteps = [s.livenessStepFace, s.livenessStepBlink, s.livenessStepTurn]\n .map(\n (label) =>\n `<div class=\"cstep\"><span class=\"cdot\" data-cdot></span><span class=\"clbl\">${escapeHtml(label)}</span></div>`,\n )\n .join('');\n\n content.innerHTML = `\n <div class=\"pad\">\n <h1 class=\"title\">${escapeHtml(s.livenessTitle)}</h1>\n <p class=\"sub\">${escapeHtml(s.livenessSubtitle)}</p>\n <div class=\"ovalWrap\">\n <div class=\"oval\">\n <video class=\"preview\" playsinline muted autoplay></video>\n <div class=\"camMsg\" data-loading><span class=\"loader\"></span></div>\n </div>\n <svg class=\"ring\" viewBox=\"0 0 210 270\" aria-hidden=\"true\">\n <path class=\"track\" d=\"${RING_PATH}\"/>\n <path class=\"prog\" data-prog d=\"${RING_PATH}\" pathLength=\"100\" stroke-dasharray=\"100\" stroke-dashoffset=\"100\"/>\n </svg>\n </div>\n <div class=\"instruction\">\n <span data-instr-ico>${iconSvg('focus', 22, 2)}</span>\n <span data-instr-text>${escapeHtml(s.livenessLookStraight)}</span>\n </div>\n <div class=\"steps\">${csteps}</div>\n <div class=\"spacer\"></div>\n <p class=\"privacy\">${escapeHtml(s.livenessPrivacy)}</p>\n </div>`;\n\n this.video = content.querySelector('.preview');\n this.progEl = content.querySelector('[data-prog]')!;\n this.instrIcon = content.querySelector('[data-instr-ico]')!;\n this.instrText = content.querySelector('[data-instr-text]')!;\n this.loadingEl = content.querySelector('[data-loading]')!;\n this.stepEls = Array.from(content.querySelectorAll<HTMLElement>('[data-cdot]'));\n\n void this.start();\n }\n\n dispose(): void {\n this.disposed = true;\n this.teardown();\n }\n\n private async start(): Promise<void> {\n const s = this.flow.strings;\n if (!navigator.mediaDevices?.getUserMedia) {\n this.showError(s.errorCamera);\n return;\n }\n try {\n // Le modèle et son WASM (volumineux) ne sont chargés qu'ici.\n await this.tracker.init(this.flow.config.livenessAssets);\n } catch {\n this.showError(s.errorNetwork);\n return;\n }\n if (this.disposed) return;\n try {\n const stream = await navigator.mediaDevices.getUserMedia({\n video: { facingMode: { ideal: 'user' }, width: { ideal: 1280 } },\n audio: false,\n });\n if (this.disposed || !this.video) {\n stream.getTracks().forEach((t) => t.stop());\n return;\n }\n this.stream = stream;\n this.video.srcObject = stream;\n await this.video.play().catch(() => {});\n this.loadingEl.hidden = true;\n this.streaming = true;\n this.loop();\n } catch {\n this.showError(s.errorCamera);\n }\n }\n\n private loop = (): void => {\n if (!this.video || this.finishing || this.disposed) return;\n if (this.tracker.ready && this.video.videoWidth > 8) {\n try {\n const signals = this.tracker.detect(this.video, performance.now());\n this.challenge.onFrame(signals);\n if (this.challenge.step !== this.step) this.render(this.challenge.step);\n if (this.challenge.isDone) {\n void this.finish();\n return;\n }\n } catch {\n // Trame illisible : ignorée, la suivante arrive au prochain rAF.\n }\n }\n this.rafId = requestAnimationFrame(this.loop);\n };\n\n private render(step: LivenessStep): void {\n this.step = step;\n const s = this.flow.strings;\n const idx = STEP_INDEX[step];\n\n // Anneau de progression.\n const progress = Math.min(1, idx / 3);\n this.progEl.setAttribute('stroke-dashoffset', String(100 * (1 - progress)));\n\n // Consigne (icône + texte).\n const icon: NayaIconName =\n step === 'searching-face' ? 'focus' : step === 'blink' ? 'eye' : step === 'turn-head' ? 'rotate' : 'hourglass';\n const text =\n step === 'searching-face' ? s.livenessLookStraight\n : step === 'blink' ? s.livenessBlink\n : step === 'turn-head' ? s.livenessTurnHead\n : s.livenessHold;\n this.instrIcon.innerHTML = iconSvg(icon, 22, 2);\n this.instrText.textContent = text;\n\n // Pastilles d'étape (visage · clignement · rotation).\n this.stepEls.forEach((dot, i) => {\n const n = i + 1;\n const done = idx >= n;\n const active = idx === n - 1;\n dot.classList.toggle('done', done);\n dot.classList.toggle('active', active && !done);\n dot.innerHTML = done ? iconSvg('check', 13, 3) : '';\n });\n }\n\n private async finish(): Promise<void> {\n if (this.finishing) return;\n this.finishing = true;\n cancelAnimationFrame(this.rafId);\n\n // Libérer MediaPipe (contexte WebGL/GPU) AVANT la capture : sur iOS Safari,\n // dessiner la vidéo sur un canvas 2D pendant que MediaPipe détient sa texture\n // GPU corrompt l'image (striures, dérive magenta) — ce que l'anti-fraude\n // serveur interprète, à raison, comme une photo d'écran.\n this.tracker.close();\n\n try {\n await this.waitFrames(3);\n await new Promise((r) => setTimeout(r, 300));\n if (this.disposed) return;\n if (this.video && this.video.videoWidth > 8) {\n this.flow.livenessScore = this.challenge.score();\n this.flow.selfieBase64 = canvasToJpegDataUrl(this.video, 1080);\n }\n this.stopStream();\n this.flow.replace('processing');\n } catch {\n this.finishing = false;\n this.stopStream();\n this.showError(this.flow.strings.errorCamera);\n }\n }\n\n /** Attend `n` trames d'affichage — laisse le compositeur présenter du frais. */\n private waitFrames(n: number): Promise<void> {\n return new Promise((resolve) => {\n let i = 0;\n const tick = () => (++i >= n ? resolve() : requestAnimationFrame(tick));\n requestAnimationFrame(tick);\n });\n }\n\n private showError(msg: string): void {\n if (this.disposed) return;\n if (this.video) this.video.hidden = true;\n this.loadingEl.hidden = false;\n this.loadingEl.textContent = msg;\n }\n\n private stopStream(): void {\n this.stream?.getTracks().forEach((t) => t.stop());\n this.stream = null;\n this.streaming = false;\n }\n\n private teardown(): void {\n cancelAnimationFrame(this.rafId);\n this.tracker.close();\n this.stopStream();\n }\n}\n","import type { NayaFlow } from '../flow/flow';\nimport { NayaApiError } from '../api/client';\nimport { buildShell, brandHtml, primaryButtonHtml, type Screen } from '../ui/components';\nimport { iconSvg } from '../ui/icons';\nimport { escapeHtml } from '../ui/dom';\n\n/**\n * Écran 6 — Traitement : envoi du liveness puis `submit` (OCR différé,\n * biométrie, AML, décision — 30 à 90 s).\n */\nexport class ProcessingScreen implements Screen {\n readonly el: HTMLElement;\n private readonly content: HTMLElement;\n private readonly closeBtn: HTMLElement | null;\n\n private visualStep = 0;\n private timer: ReturnType<typeof setInterval> | null = null;\n private disposed = false;\n\n private readonly steps: { label: string; index: number }[];\n\n constructor(private readonly flow: NayaFlow) {\n const s = flow.strings;\n const { root, content } = buildShell({\n poweredBy: s.poweredBy,\n screenClass: 'n-processing',\n onClose: () => flow.cancel(),\n });\n this.el = root;\n this.content = content;\n // Fermeture masquée pendant le traitement ; révélée seulement en cas d'erreur.\n this.closeBtn = root.querySelector('[data-nav=\"close\"]');\n if (this.closeBtn) this.closeBtn.hidden = true;\n\n this.steps = [\n { label: s.processingDocument, index: 0 },\n { label: s.processingFace, index: 1 },\n { label: s.processingCompliance, index: 2 },\n { label: s.processingDecision, index: 3 },\n ];\n\n this.renderProgress();\n this.startVisualProgress();\n void this.run();\n }\n\n dispose(): void {\n this.disposed = true;\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n }\n\n private renderProgress(): void {\n const s = this.flow.strings;\n const rows = this.steps\n .map((item) => `<li class=\"row\" data-row=\"${item.index}\"><span class=\"dot idle\"></span><span class=\"lbl\">${escapeHtml(item.label)}</span></li>`)\n .join('');\n this.content.innerHTML = `\n <div class=\"pad\">\n ${brandHtml()}\n <div class=\"spacer\"></div>\n <span class=\"spin\" aria-hidden=\"true\"></span>\n <ul class=\"steps\">${rows}</ul>\n <div class=\"spacer\"></div>\n <p class=\"wait\">${escapeHtml(s.processingWait)}</p>\n </div>`;\n if (this.closeBtn) this.closeBtn.hidden = true;\n this.updateSteps();\n }\n\n private updateSteps(): void {\n const cur = this.visualStep;\n this.steps.forEach((item) => {\n const row = this.content.querySelector<HTMLElement>(`[data-row=\"${item.index}\"]`);\n if (!row) return;\n const dot = row.querySelector('.dot')!;\n const lbl = row.querySelector('.lbl')!;\n if (item.index <= cur) {\n dot.className = 'dot done';\n dot.innerHTML = iconSvg('check', 12, 3);\n } else if (item.index === cur + 1) {\n dot.className = 'dot active';\n dot.innerHTML = '';\n } else {\n dot.className = 'dot idle';\n dot.innerHTML = '';\n }\n lbl.classList.toggle('dim', item.index > cur + 1);\n });\n }\n\n private startVisualProgress(): void {\n // Progression indicative pendant l'attente réelle du serveur.\n this.timer = setInterval(() => {\n if (this.visualStep < 2) {\n this.visualStep += 1;\n this.updateSteps();\n }\n }, 9000);\n }\n\n private renderError(message: string): void {\n const s = this.flow.strings;\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n if (this.closeBtn) this.closeBtn.hidden = false;\n this.content.innerHTML = `\n <div class=\"pad center\">\n ${iconSvg('wifi-off', 48, 1.8)}\n <h1 class=\"title\">${escapeHtml(s.errorTitle)}</h1>\n <p class=\"body\">${escapeHtml(message)}</p>\n <div class=\"cta\">${primaryButtonHtml(s.retry, { act: 'retry' })}</div>\n </div>`;\n this.content.querySelector('[data-act=\"retry\"]')?.addEventListener('click', () => {\n this.renderProgress();\n this.startVisualProgress();\n void this.run();\n });\n }\n\n private async run(): Promise<void> {\n this.visualStep = 0;\n this.updateSteps();\n try {\n // L'envoi du document est parti pendant le selfie — on s'assure qu'il est\n // terminé (et on le relance s'il a échoué).\n await this.flow.ensureDocumentUploaded();\n const session = this.flow.session;\n if (!session) throw new NayaApiError('Session introuvable.');\n\n await this.flow.client.submitLiveness(session.verificationId, {\n livenessScore: this.flow.livenessScore,\n selfieBase64: this.flow.selfieBase64!,\n });\n\n const response = await this.flow.client.submit(session.verificationId);\n if (this.disposed) return;\n this.flow.submitResponse = response;\n this.flow.replace('result');\n } catch (err) {\n if (this.disposed) return;\n const message = err instanceof NayaApiError ? err.message : this.flow.strings.errorNetwork;\n this.renderError(message);\n }\n }\n}\n","import type { NayaFlow } from '../flow/flow';\nimport type { NayaStatus } from '../models/result';\nimport {\n buildShell,\n primaryButtonHtml,\n secondaryButtonHtml,\n type Screen,\n} from '../ui/components';\nimport { iconSvg, type NayaIconName } from '../ui/icons';\nimport { escapeHtml } from '../ui/dom';\n\n/** Écran 7 — Résultat (approuvé / en revue / rejeté). */\nexport class ResultScreen implements Screen {\n readonly el: HTMLElement;\n\n constructor(private readonly flow: NayaFlow) {\n const s = flow.strings;\n const response = flow.submitResponse;\n\n const status: NayaStatus =\n response?.status === 'approved' ? 'approved'\n : response?.status === 'rejected' ? 'rejected'\n : 'review';\n\n const view = this.viewFor(status);\n\n const fullName = [response?.ocrData?.firstName, response?.ocrData?.lastName]\n .filter((p) => p && p.length)\n .join(' ');\n const id = flow.session?.verificationId;\n const reference = id ? id.split('-')[0]!.toUpperCase() : '—';\n\n // Bloc central selon l'issue.\n let middle = '';\n if (status === 'approved') {\n const nameRow = fullName\n ? `<div class=\"srow\"><span class=\"k\">${escapeHtml(s.resultName)}</span><span class=\"v\">${escapeHtml(fullName)}</span></div>`\n : '';\n middle = `<div class=\"summary\">${nameRow}<div class=\"srow\"><span class=\"k\">${escapeHtml(s.resultReference)}</span><span class=\"v mono\">${escapeHtml(reference)}</span></div></div>`;\n } else if (status === 'review') {\n const bullets = [s.resultReviewB1, s.resultReviewB2, s.resultReviewB3]\n .map((b) => `<li><span class=\"pip\"></span>${escapeHtml(b)}</li>`)\n .join('');\n middle = `<ul class=\"bullets\">${bullets}</ul>`;\n }\n\n // Boutons : rejet avec réessai possible → primaire « Réessayer » + secondaire.\n const canRetry = status === 'rejected' && flow.canRetry;\n const doneLabel = response?.ocrData ? s.continueLabel : s.backToApp;\n const buttons = canRetry\n ? `${primaryButtonHtml(s.retry, { icon: 'refresh', act: 'retry' })}<div class=\"gap\"></div>${secondaryButtonHtml(s.backToApp, 'done')}`\n : primaryButtonHtml(doneLabel, { act: 'done' });\n\n const subtitle = view.subtitle\n ? `<p class=\"body\">${escapeHtml(view.subtitle)}</p>`\n : '';\n\n const { root, content } = buildShell({\n poweredBy: s.poweredBy,\n screenClass: 'n-result',\n canClose: false,\n });\n this.el = root;\n\n content.innerHTML = `\n <div class=\"pad\">\n <div class=\"spacer\"></div>\n <span class=\"badge\" style=\"background:${view.color}\">${iconSvg(view.icon, 44, 3)}</span>\n <h1 class=\"title\">${escapeHtml(view.title)}</h1>\n ${subtitle}\n ${middle}\n <div class=\"spacer\"></div>\n ${buttons}\n </div>`;\n\n content.querySelector('[data-act=\"retry\"]')?.addEventListener('click', () => this.retry());\n content.querySelector('[data-act=\"done\"]')?.addEventListener('click', () => this.done(status));\n }\n\n dispose(): void {}\n\n private viewFor(status: NayaStatus): {\n icon: NayaIconName;\n color: string;\n title: string;\n subtitle: string;\n } {\n const s = this.flow.strings;\n switch (status) {\n case 'approved':\n return {\n icon: 'check', color: 'var(--naya-success)',\n title: s.resultApprovedTitle, subtitle: s.resultApprovedSubtitle,\n };\n case 'rejected': {\n const note = this.flow.submitResponse?.note;\n return {\n icon: 'close', color: 'var(--naya-error)',\n title: s.resultRejectedTitle,\n subtitle: note ? `${s.resultRejectedReason} : ${note}` : '',\n };\n }\n default:\n return {\n icon: 'clock', color: 'var(--naya-warning)',\n title: s.resultReviewTitle, subtitle: s.resultReviewSubtitle,\n };\n }\n }\n\n private retry(): void {\n this.flow.resetForRetry();\n this.flow.replace('capture-recto');\n }\n\n private done(status: NayaStatus): void {\n const r = this.flow.submitResponse;\n this.flow.complete({\n status,\n verificationId: this.flow.session?.verificationId,\n riskScore: r?.riskScore,\n matchScore: r?.matchScore,\n authenticityScore: r?.authenticityScore,\n livenessScore: r?.livenessScore,\n ocrConfidence: r?.ocrConfidence,\n ocrData: r?.ocrData,\n note: r?.note,\n });\n }\n}\n","import { buildThemeVars } from '../theme/theme';\nimport { STYLES } from '../ui/styles';\nimport type { Screen } from '../ui/components';\nimport type { NayaAuth, ResolvedNayaConfig } from '../models/config';\nimport { type NayaResult, errorResult } from '../models/result';\nimport { NayaFlow, type NayaStep } from './flow';\nimport { WelcomeScreen } from '../screens/welcome';\nimport { DocumentSelectionScreen } from '../screens/document-selection';\nimport { DocumentCaptureScreen } from '../screens/document-capture';\nimport { LivenessScreen } from '../screens/liveness';\nimport { ProcessingScreen } from '../screens/processing';\nimport { ResultScreen } from '../screens/result';\n\n/** Instancie l'écran correspondant à une étape. */\nfunction createScreen(step: NayaStep, flow: NayaFlow): Screen {\n switch (step) {\n case 'welcome': return new WelcomeScreen(flow);\n case 'select': return new DocumentSelectionScreen(flow);\n case 'capture-recto': return new DocumentCaptureScreen(flow, 'recto');\n case 'capture-verso': return new DocumentCaptureScreen(flow, 'verso');\n case 'liveness': return new LivenessScreen(flow);\n case 'processing': return new ProcessingScreen(flow);\n case 'result': return new ResultScreen(flow);\n }\n}\n\n/**\n * Monte l'interface Naya en plein écran, au-dessus de l'application, dans un\n * **Shadow DOM** — le CSS du SDK et celui de la page hôte restent mutuellement\n * isolés. Résout le `NayaResult` à la fermeture ; ne rejette jamais.\n */\nexport function mountNayaFlow(\n auth: NayaAuth,\n config: ResolvedNayaConfig,\n): Promise<NayaResult> {\n if (typeof document === 'undefined') {\n return Promise.resolve(errorResult('Le SDK Naya nécessite un environnement navigateur.'));\n }\n\n return new Promise<NayaResult>((resolve) => {\n const container = document.createElement('div');\n container.setAttribute('data-naya-id', '');\n const shadow = container.attachShadow({ mode: 'open' });\n\n const style = document.createElement('style');\n style.textContent = STYLES;\n shadow.appendChild(style);\n\n const hostEl = document.createElement('div');\n hostEl.className = 'naya-host';\n const vars = buildThemeVars(config);\n for (const [k, v] of Object.entries(vars)) hostEl.style.setProperty(k, v);\n shadow.appendChild(hostEl);\n\n const prevOverflow = document.body.style.overflow;\n let settled = false;\n let current: Screen | null = null;\n\n const finish = (result: NayaResult): void => {\n if (settled) return;\n settled = true;\n current?.dispose();\n document.removeEventListener('keydown', onKey);\n document.body.style.overflow = prevOverflow;\n container.remove();\n resolve(result);\n };\n\n const flow = new NayaFlow(auth, config, finish);\n\n const route = (step: NayaStep): void => {\n current?.dispose();\n current = createScreen(step, flow);\n hostEl.replaceChildren(current.el);\n };\n flow.onStep = route;\n\n // Échap ferme le parcours (annulation), comme le bouton système Android.\n const onKey = (e: KeyboardEvent): void => {\n if (e.key === 'Escape') flow.cancel();\n };\n document.addEventListener('keydown', onKey);\n\n document.body.appendChild(container);\n document.body.style.overflow = 'hidden'; // fige le défilement de la page\n route(flow.step);\n });\n}\n","/**\n * SDK JavaScript officiel de Naya ID — vérification d'identité (eKYC) clé en\n * main pour l'Afrique de l'Ouest (zone CEDEAO), chargeable en une balise\n * `<script>`.\n *\n * Pendant web « sans framework » des SDK Flutter et Angular : même parcours,\n * mêmes écrans, même contrat d'API.\n *\n * ```html\n * <script src=\"https://cdn.jsdelivr.net/npm/@41devs/naya-id-js@0/dist/naya-id.min.js\"></script>\n * <script>\n * const result = await NayaId.startVerification({\n * apiKey: 'naya_live_xxx',\n * config: { country: 'BJ' },\n * });\n * // result.status → 'approved' | 'review' | 'rejected' | 'cancelled' | 'error'\n * </script>\n * ```\n */\n\nimport { type NayaAuth, type NayaConfig, resolveConfig } from './models/config';\nimport type { NayaResult } from './models/result';\nimport { mountNayaFlow } from './flow/host';\n\nexport interface StartVerificationParams {\n /** Clé d'application `naya_live_…` / `naya_test_…` (lisible côté navigateur). */\n apiKey?: string;\n /** Jeton de session éphémère obtenu par votre backend (à privilégier). */\n sessionToken?: string;\n /** Alternative aux deux champs ci-dessus, forme objet. */\n auth?: NayaAuth;\n /** Configuration optionnelle (pays, documents, langue, callbackUrl, thème…). */\n config?: NayaConfig;\n}\n\n/**\n * Lance le parcours de vérification d'identité : l'interface Naya s'ouvre en\n * plein écran au-dessus de la page, prend en charge la capture du document, la\n * vivacité et la décision, puis résout un `NayaResult` et rend la main.\n *\n * **Ne rejette jamais** : une erreur réseau ou une annulation revient toujours\n * sous forme de `NayaResult` (`status: 'error'` ou `'cancelled'`).\n */\nexport async function startVerification(\n params: StartVerificationParams,\n): Promise<NayaResult> {\n const auth: NayaAuth = params.auth ?? {\n apiKey: params.apiKey,\n sessionToken: params.sessionToken,\n };\n\n if (!auth.apiKey && !auth.sessionToken) {\n return {\n status: 'error',\n errorMessage:\n 'Authentification manquante : fournissez apiKey ou sessionToken.',\n };\n }\n\n const config = resolveConfig(params.config);\n return mountNayaFlow(auth, config);\n}\n\n/** Version du SDK. */\nexport const version = '0.1.0';\n\n// ── Surface publique : modèles, constantes et type d'erreur ──────────────────\nexport {\n type NayaConfig,\n type NayaAuth,\n type NayaThemeOverrides,\n type NayaLivenessAssets,\n type NayaCountryCode,\n type NayaDocumentType,\n type NayaLocale,\n type ResolvedNayaConfig,\n NAYA_COUNTRIES,\n NAYA_DOCUMENT_TYPES,\n NAYA_DEFAULT_PRIMARY,\n NAYA_DEFAULT_ACCENT,\n NAYA_DEFAULT_BASE_URL,\n resolveConfig,\n countryLabel,\n documentNeedsVerso,\n} from './models/config';\n\nexport {\n type NayaResult,\n type NayaStatus,\n type NayaOcrData,\n parseOcrData,\n ocrToDeclaredData,\n cancelledResult,\n errorResult,\n} from './models/result';\n\nexport { NayaApiError } from './api/client';\n\n// Export par défaut : pratique pour `import NayaId from '@41devs/naya-id-js'`.\nexport default { startVerification, version };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/models/config.ts","../src/theme/theme.ts","../src/ui/styles.ts","../src/models/result.ts","../src/version.ts","../src/api/client.ts","../src/i18n/strings.ts","../src/support/capabilities.ts","../src/support/telemetry.ts","../src/support/log.ts","../src/support/haptics.ts","../src/support/network.ts","../src/liveness/face-tracker.ts","../src/liveness/liveness-challenge.ts","../src/flow/flow.ts","../src/support/focus-trap.ts","../src/ui/dom.ts","../src/ui/icons.ts","../src/ui/brand.ts","../src/ui/components.ts","../src/screens/welcome.ts","../src/screens/unsupported.ts","../src/screens/consent.ts","../src/screens/handoff.ts","../src/screens/document-selection.ts","../src/screens/tips.ts","../src/utils/image-utils.ts","../src/screens/document-capture.ts","../src/screens/liveness.ts","../src/utils/dates.ts","../src/screens/ocr-confirm.ts","../src/screens/processing.ts","../src/screens/result.ts","../src/flow/host.ts","../src/support/emitter.ts","../src/index.ts"],"names":["NAYA_COUNTRIES","NAYA_DOCUMENT_TYPES","NAYA_LOCALES","countryLabel","code","c","documentNeedsVerso","doc","NAYA_DEFAULT_PRIMARY","NAYA_DEFAULT_ACCENT","NAYA_DEFAULT_BASE_URL","NAYA_DEFAULT_FONT","detectLocale","lang","resolveConfig","config","consent","handoff","NAYA_LIGHT","NAYA_DARK","RADII","relativeLuminance","hex","m","h","chan","i","v","contrastRatio","b","la","lb","hi","lo","readableTextOn","background","light","dark","cl","effectiveMode","buildThemeVars","mode","r","primary","accent","STYLES","OCR_FIELDS","parseOcrData","raw","src","out","field","value","ocrToDeclaredData","ocr","cancelledResult","verificationId","errorResult","errorMessage","extra","SDK_VERSION","NayaApiError","message","opts","SECONDS","RETRY_BASE_MS","RETRY_MAX","mapHttpError","status","numOrUndef","strRecord","k","val","strArray","x","NayaApiClient","auth","baseUrl","sessionToken","method","path","body","timeoutMs","retries","attempt","err","e","wait","keepalive","controller","timer","res","aborted","requestId","json","mapped","error","ra","params","data","version","cv","declaredData","dataDisputed","q","events","device","final","DICT","LOCALE_INDEX","NayaStrings","locale","overrides","key","s","step","IN_APP_PATTERNS","detectInAppBrowser","ua","re","name","detectSupport","hasWindow","secureContext","mediaDevices","webAssembly","webGL","ios","android","tablet","mobile","inAppBrowserName","base","hasEnvironmentCamera","cams","d","Telemetry","client","enabled","log","event","now","batch","PREFIX","createLogger","noop","PATTERNS","vibrate","pattern","networkHint","conn","effectiveType","saveData","MP_VERSION","NAYA_ASSET_BASE","MODEL_FILE","MODEL_SHA256","PUBLIC_ESM","PUBLIC_WASM_BASE","PUBLIC_MODEL","NOSE_TIP","FACE_LEFT_EDGE","FACE_RIGHT_EDGE","RIGHT_EYE_OUTER","LEFT_EYE_OUTER","resolveAssetUrls","assets","fallback","nayaBase","pick","custom","naya","pub","list","firstThatWorks","urls","load","lastError","url","sha256Hex","buffer","digest","moduleCache","modelCache","filesetCache","loadModule","p","loadModel","expectedSha","buf","actual","loadFileset","vision","poseFromMatrix","rowMajor","j","r00","r02","r10","r12","r22","deg","rollFromEyes","lm","aspect","a","dx","dy","yawFromNose","nose","left","right","span","FaceTracker","FaceLandmarker","fileset","model","create","delegate","video","timestampMs","none","result","faces","faceCount","leftEyeOpen","rightEyeOpen","smileL","smileR","shapes","smile","noseYaw","pose","matrixYaw","yawDegrees","rollDegrees","pitchDegrees","minX","minY","maxX","maxY","box","CHALLENGE_STEPS","DEFAULT_CHALLENGE","isStep","normalizeChallenge","steps","known","frontalGuidance","sig","yaw","roll","pitch","l","LivenessChallenge","total","done","cx","cy","before","guidance","completed","capture","closed","open","closedMs","g","entry","partial","NayaFlow","finish","os","type","next","prev","direction","from","side","info","country","cfgDoc","created","upload","FOCUSABLE","trapFocus","root","onKey","nodes","n","first","last","active","focusFirst","escapeHtml","multiline","copyText","text","ta","ok","PATHS","iconSvg","size","stroke","LOGO_VIEWBOX","LOGO_PATHS","logoSvg","height","label","width","brandHtml","stepsDotsHtml","labels","activeIndex","primaryButtonHtml","secondaryButtonHtml","act","icon","ghostButtonHtml","alertHtml","tone","html","fieldHtml","o","buildShell","canClose","logo","content","illustrationHtml","kind","WelcomeScreen","flow","stepLabels","UnsupportedScreen","sup","title","link","btn","ConsentScreen","bullets","policy","cta","POLL_MS","HandoffScreen","qr","id","docIcon","DocumentSelectionScreen","lockedCountry","chips","cards","on","TipsScreen","tips","t","DOCUMENT_REGION","analyzePixels","w","previous","lum","sumLum","saturated","luminance","glare","sum","sumSq","count","y","idx","lap","mean","sharpness","motion","diff","lightOk","sharpOk","glareOk","steady","issue","measureFrameQuality","scratch","state","region","sampleWidth","vw","vh","empty","sx","sy","sw","sh","scale","ctx","_luma","rest","toJpegDataUrl","source","maxDimension","quality","srcW","srcH","canvas","fileToJpegDataUrl","file","bmp","img","resolve","reject","el","CARD_ASPECT","QUALITY_INTERVAL_MS","STABLE_SAMPLES_BEFORE_CAPTURE","COUNTDOWN_TICK_MS","visibleRegion","videoW","videoH","cardAspect","inset","videoAspect","DocumentCaptureScreen","instruction","auto","visible","stream","env","track","msg","dataUrl","RING_PATH","DETECT_INTERVAL_MS","KEYFRAME_MAX_DIMENSION","MAX_TIMEOUTS_BEFORE_PASSIVE","HOLD_TIMEOUT_MS","stepIcon","LivenessScreen","signals","csteps","st","proof","toast","phase","cls","dot","isDone","allowPassive","order","f","tick","retry","ISO","parseIsoDate","mo","date","normalizeDateInput","iso","isExpired","today","isPlausibleBirthDate","years","FIELDS","OcrConfirmScreen","rows","wide","disputed","fields","wrap","values","valid","firstInvalid","warnings","input","declared","STAGES","LONG_WAIT_MS","ProcessingScreen","item","cur","row","lbl","stage","session","response","ResultScreen","view","fullName","reference","reasons","middle","buttons","createScreen","BUSY_STEPS","mountNayaFlow","closeFn","flowRef","inline","container","shadow","style","hostEl","frame","applyTheme","vars","mql","prevOverflow","previouslyFocused","settled","current","releaseTrap","onBeforeUnload","onVisibility","route","leaving","gone","h1","Emitter","cb","set","payload","validateAuth","startVerification","isSupported","emitter","handle","hostOnEvent","ELEMENT_TAG","defineElement","tag","NayaIdVerificationElement","attr","docs","_default","src_default"],"mappings":"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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","file":"naya-id.min.js","sourcesContent":["/**\n * Configuration publique du SDK et valeurs par défaut.\n */\n\nexport const NAYA_COUNTRIES = [\n { code: 'BJ', label: 'Bénin' },\n { code: 'CI', label: \"Côte d'Ivoire\" },\n { code: 'SN', label: 'Sénégal' },\n { code: 'ML', label: 'Mali' },\n { code: 'BF', label: 'Burkina Faso' },\n { code: 'TG', label: 'Togo' },\n] as const;\n\nexport type NayaCountryCode = (typeof NAYA_COUNTRIES)[number]['code'];\n\nexport type NayaDocumentType = 'cni' | 'passeport' | 'permis';\nexport const NAYA_DOCUMENT_TYPES: readonly NayaDocumentType[] = ['cni', 'passeport', 'permis'];\n\n/** Langues de l'interface du SDK. */\nexport type NayaLocale = 'fr' | 'en' | 'pt';\nexport const NAYA_LOCALES: readonly NayaLocale[] = ['fr', 'en', 'pt'];\n\nexport function countryLabel(code: NayaCountryCode): string {\n return NAYA_COUNTRIES.find((c) => c.code === code)?.label ?? code;\n}\n\n/** La CNI CEDEAO porte sa MRZ au verso ; les autres pièces n'en ont pas besoin. */\nexport function documentNeedsVerso(doc: NayaDocumentType): boolean {\n return doc === 'cni';\n}\n\n/**\n * Authentification.\n *\n * • `apiKey` — la clé d'application est transmise depuis le navigateur ; le\n * SDK ouvre lui-même la session. Réservé aux démos et aux fronts maîtrisés :\n * une clé live doit déclarer ses origines dans le dashboard.\n * • `sessionToken` + `verificationId` — la session a été ouverte par le\n * backend du client ; le SDK la reprend et n'appelle jamais `/start`.\n * À privilégier en production.\n */\nexport interface NayaAuth {\n apiKey?: string;\n sessionToken?: string;\n verificationId?: string;\n}\n\nexport interface NayaThemeOverrides {\n /** Couleur principale (défaut : encre Naya #172062). */\n primaryColor?: string;\n /** Couleur d'accent des CTA (défaut : flamme Naya #E6950A). */\n accentColor?: string;\n /** Pile de polices ; défaut : police système. */\n fontFamily?: string;\n /** Rayons : `sharp` (4/8 px), `soft` (12/24 px, défaut), `round` (pilule). */\n radius?: 'sharp' | 'soft' | 'round';\n /** Thème clair, sombre, ou suivant les préférences du système (défaut). */\n mode?: 'light' | 'dark' | 'auto';\n}\n\n/**\n * Ressources de détection de vivacité (MediaPipe). Par défaut, servies par le\n * CDN Naya, avec repli automatique sur les CDN publics si celui-ci ne répond\n * pas. Les applications à CSP stricte peuvent auto-héberger ces fichiers.\n */\nexport type NayaOcrConfirmMode = 'display' | 'edit';\n\nexport interface NayaLivenessAssets {\n /** URL du module ESM `@mediapipe/tasks-vision` (`vision_bundle.mjs`). */\n esmUrl?: string;\n /** Base des fichiers WASM `@mediapipe/tasks-vision`. */\n wasmBaseUrl?: string;\n /** URL du modèle `.task` de Face Landmarker. */\n modelUrl?: string;\n /** Empreinte SHA-256 attendue du modèle (hex) ; `null` désactive le contrôle. */\n modelSha256?: string | null;\n /** Replier sur jsDelivr / Google si l'hôte principal échoue (défaut : true). */\n fallbackToPublicCdn?: boolean;\n}\n\nexport interface NayaConsentOptions {\n /** Lien vers la politique de confidentialité affichée sur l'écran de consentement. */\n policyUrl?: string;\n /** Version du texte de consentement, transmise à l'API. */\n version?: string;\n}\n\nexport interface NayaCaptureOptions {\n /** Déclenchement automatique quand la qualité est stable (défaut : true). */\n autoCapture?: boolean;\n /** Côté max de l'image envoyée, en pixels (défaut : 1600 ; 1200 sur réseau lent). */\n maxDimension?: number;\n /**\n * Import d'une photo depuis un fichier : `auto` (proposé quand aucune caméra\n * arrière n'est disponible, typiquement sur ordinateur), `always`, `never`.\n */\n fileUpload?: 'auto' | 'always' | 'never';\n}\n\nexport interface NayaLivenessOptions {\n /** Délai avant de proposer des conseils et un nouvel essai (défaut : 45 s). */\n timeoutMs?: number;\n /**\n * Après un délai dépassé ou deux échecs, proposer le parcours sans défi\n * (selfie seul, décision plafonnée à la revue). Défaut : true.\n */\n allowPassive?: boolean;\n /** Précharger le modèle pendant la capture du document (défaut : true). */\n preload?: boolean;\n}\n\nexport interface NayaHandoffOptions {\n /** Proposer le relais vers un téléphone par QR code sur ordinateur (défaut : true). */\n enabled?: boolean;\n /** Page hébergée qui reprend la session ; défaut : celle configurée côté API. */\n baseUrl?: string;\n}\n\nexport type NayaEventName =\n | 'ready'\n | 'step'\n | 'session'\n | 'consent'\n | 'document_captured'\n | 'liveness_step'\n | 'liveness_done'\n | 'submitted'\n | 'result'\n | 'error'\n | 'cancelled'\n | 'handoff_shown';\n\nexport interface NayaEvent {\n type: NayaEventName;\n /** `performance.now()` au moment de l'événement. */\n at: number;\n step?: string;\n data?: Record<string, unknown>;\n}\n\nexport interface NayaConfig {\n /** Pré-sélectionne le pays : l'utilisateur ne le choisit plus. */\n country?: NayaCountryCode;\n /**\n * Types de documents proposés. S'il n'y en a qu'un et que `country` est\n * défini, l'écran de sélection est sauté.\n */\n documentTypes?: readonly NayaDocumentType[];\n /** Pays proposés quand `country` n'est pas défini. */\n countries?: readonly NayaCountryCode[];\n /** Langue de l'interface ; défaut : celle du navigateur (fr, en, pt). */\n locale?: NayaLocale;\n /** URL HTTPS notifiée par le serveur Naya à chaque décision (mode apiKey). */\n callbackUrl?: string;\n /** Nombre de parcours autorisés après un rejet (bouton « Réessayer »). */\n maxAttempts?: number;\n /** Surcharge des couleurs, de la police, des rayons et du mode. */\n theme?: NayaThemeOverrides;\n /** URL d'un logo client, affiché à côté de « Propulsé par Naya ID ». */\n clientLogoUrl?: string;\n /** Base URL de l'API — ne changer que pour un environnement de test. */\n baseUrl?: string;\n /** Auto-hébergement des ressources MediaPipe (CSP stricte). */\n livenessAssets?: NayaLivenessAssets;\n /** Monter le parcours dans cet élément au lieu d'un overlay plein écran. */\n container?: HTMLElement | null;\n /** Écran de consentement biométrique ; `false` si recueilli en amont par l'hôte. */\n consent?: boolean | NayaConsentOptions;\n /**\n * Écran des données lues sur le document. `false` (défaut) : rien n'est\n * montré ; `'display'` : lecture seule, l'utilisateur dit si c'est exact ;\n * `'edit'` : il peut saisir des corrections. Dans tous les cas l'extraction\n * (`ocrData`) reste intacte côté serveur : ce qui est saisi part à part\n * (`declaredData`) et un écart plafonne la décision à la revue.\n * `true` vaut `'edit'`.\n */\n confirmOcr?: boolean | NayaOcrConfirmMode;\n capture?: NayaCaptureOptions;\n liveness?: NayaLivenessOptions;\n handoff?: boolean | NayaHandoffOptions;\n /**\n * Ouvrir la session dès le choix du document pour recouvrir la latence\n * réseau. Attention : une session ouverte peut être facturée même si la\n * capture est abandonnée. Défaut : false.\n */\n eagerSession?: boolean;\n /** Télémétrie anonyme (entonnoir, erreurs, qualité). Défaut : true. */\n telemetry?: boolean;\n /** Journal détaillé dans la console (préfixe `[NayaId]`). */\n debug?: boolean;\n /** Retour haptique aux étapes clés sur mobile (défaut : true). */\n haptics?: boolean;\n /** Surcharge de libellés, par clé de chaîne. */\n strings?: Partial<Record<string, string>>;\n /** Hook d'événements pour l'analytique de l'hôte. */\n onEvent?: (event: NayaEvent) => void;\n}\n\n/** Configuration effective : `NayaConfig` avec tous les défauts appliqués. */\nexport interface ResolvedNayaConfig {\n country?: NayaCountryCode;\n documentTypes: readonly NayaDocumentType[];\n countries: readonly NayaCountryCode[];\n locale: NayaLocale;\n callbackUrl?: string;\n maxAttempts: number;\n theme: Required<NayaThemeOverrides>;\n clientLogoUrl?: string;\n baseUrl: string;\n livenessAssets: NayaLivenessAssets;\n container: HTMLElement | null;\n consent: false | Required<NayaConsentOptions>;\n confirmOcr: false | NayaOcrConfirmMode;\n capture: Required<NayaCaptureOptions>;\n liveness: Required<NayaLivenessOptions>;\n handoff: Required<NayaHandoffOptions>;\n eagerSession: boolean;\n telemetry: boolean;\n debug: boolean;\n haptics: boolean;\n strings: Partial<Record<string, string>>;\n onEvent?: (event: NayaEvent) => void;\n}\n\nexport const NAYA_DEFAULT_PRIMARY = '#172062';\nexport const NAYA_DEFAULT_ACCENT = '#E6950A';\nexport const NAYA_DEFAULT_BASE_URL = 'https://api.naya.41devs.com/v1';\nexport const NAYA_DEFAULT_FONT =\n \"'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif\";\n\n/** Langue du navigateur ramenée aux langues supportées. */\nexport function detectLocale(): NayaLocale {\n const raw = typeof navigator !== 'undefined' ? navigator.language || '' : '';\n const lang = raw.slice(0, 2).toLowerCase();\n return (NAYA_LOCALES as readonly string[]).includes(lang) ? (lang as NayaLocale) : 'fr';\n}\n\n/** Applique les valeurs par défaut à une configuration partielle. */\nexport function resolveConfig(config: NayaConfig = {}): ResolvedNayaConfig {\n const consent =\n config.consent === false\n ? false\n : {\n policyUrl: (typeof config.consent === 'object' ? config.consent.policyUrl : undefined) ?? '',\n version: (typeof config.consent === 'object' ? config.consent.version : undefined) ?? '2026-09',\n };\n const handoff =\n typeof config.handoff === 'boolean'\n ? { enabled: config.handoff, baseUrl: '' }\n : { enabled: config.handoff?.enabled ?? true, baseUrl: config.handoff?.baseUrl ?? '' };\n\n return {\n country: config.country,\n documentTypes: config.documentTypes ?? NAYA_DOCUMENT_TYPES,\n countries: config.countries ?? NAYA_COUNTRIES.map((c) => c.code),\n locale: config.locale ?? detectLocale(),\n callbackUrl: config.callbackUrl,\n maxAttempts: config.maxAttempts ?? 2,\n theme: {\n primaryColor: config.theme?.primaryColor ?? NAYA_DEFAULT_PRIMARY,\n accentColor: config.theme?.accentColor ?? NAYA_DEFAULT_ACCENT,\n fontFamily: config.theme?.fontFamily ?? NAYA_DEFAULT_FONT,\n radius: config.theme?.radius ?? 'soft',\n mode: config.theme?.mode ?? 'auto',\n },\n clientLogoUrl: config.clientLogoUrl,\n baseUrl: (config.baseUrl ?? NAYA_DEFAULT_BASE_URL).replace(/\\/+$/, ''),\n livenessAssets: config.livenessAssets ?? {},\n container: config.container ?? null,\n consent,\n confirmOcr:\n config.confirmOcr === 'display' || config.confirmOcr === 'edit'\n ? config.confirmOcr\n : config.confirmOcr === true\n ? 'edit'\n : false,\n capture: {\n autoCapture: config.capture?.autoCapture ?? true,\n maxDimension: config.capture?.maxDimension ?? 1600,\n fileUpload: config.capture?.fileUpload ?? 'auto',\n },\n liveness: {\n timeoutMs: config.liveness?.timeoutMs ?? 45_000,\n allowPassive: config.liveness?.allowPassive ?? true,\n preload: config.liveness?.preload ?? true,\n },\n handoff,\n eagerSession: config.eagerSession ?? false,\n telemetry: config.telemetry ?? true,\n debug: config.debug ?? false,\n haptics: config.haptics ?? true,\n strings: config.strings ?? {},\n onEvent: config.onEvent,\n };\n}\n","import type { ResolvedNayaConfig } from '../models/config';\n\n/**\n * Jetons de design Naya v2 (charte du back-office) exposés en variables CSS\n * sur l'élément hôte, pour rester isolés du thème de l'application.\n */\nexport const NAYA_LIGHT = {\n bg: '#FBFBFE', // papier\n surface: '#FFFFFF',\n surface2: '#EEF0F7', // brume\n line: '#D9DCEC', // ligne\n text: '#0A1160', // texte\n text2: '#5B6185', // gris-600\n success: '#0E9C85', // lagune-600\n successSoft: '#D6F7F0',\n warning: '#C27C05', // flamme-600\n warningSoft: '#FCF0D2',\n error: '#E0354C', // erreur-500\n errorSoft: '#FDE3E7',\n dark: '#0F1650', // encre-800\n} as const;\n\nexport const NAYA_DARK = {\n bg: '#0B1030',\n surface: '#141A46',\n surface2: '#1C2358',\n line: '#2B357F',\n text: '#F1F3FC',\n text2: '#B7BEE8',\n success: '#17C3A6',\n successSoft: '#0E3D36',\n warning: '#F3C77A',\n warningSoft: '#3D2E0A',\n error: '#FF7A8A',\n errorSoft: '#4A1A22',\n dark: '#060A20',\n} as const;\n\nconst RADII = {\n sharp: { card: '6px', input: '4px', button: '8px' },\n soft: { card: '14px', input: '10px', button: '14px' },\n round: { card: '20px', input: '12px', button: '999px' },\n} as const;\n\n/** Luminance relative (WCAG) d'une couleur hex ; null si illisible. */\nexport function relativeLuminance(hex: string): number | null {\n const m = hex.trim().match(/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i);\n if (!m) return null;\n let h = m[1]!;\n if (h.length === 3)\n h = h\n .split('')\n .map((c) => c + c)\n .join('');\n const chan = (i: number): number => {\n const v = parseInt(h.slice(i, i + 2), 16) / 255;\n return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\n };\n return 0.2126 * chan(0) + 0.7152 * chan(2) + 0.0722 * chan(4);\n}\n\nexport function contrastRatio(a: string, b: string): number | null {\n const la = relativeLuminance(a);\n const lb = relativeLuminance(b);\n if (la == null || lb == null) return null;\n const [hi, lo] = la > lb ? [la, lb] : [lb, la];\n return (hi + 0.05) / (lo + 0.05);\n}\n\n/**\n * Couleur de texte lisible sur un fond donné : celle des deux candidates qui\n * offre le meilleur contraste. Évite qu'une couleur de marque imposée par le\n * client rende un bouton illisible.\n */\nexport function readableTextOn(background: string, light = '#FFFFFF', dark = '#0A1160'): string {\n const cl = contrastRatio(background, light) ?? 0;\n const cd = contrastRatio(background, dark) ?? 0;\n return cd >= cl ? dark : light;\n}\n\nexport type ThemeMode = 'light' | 'dark';\n\nexport function effectiveMode(config: ResolvedNayaConfig): ThemeMode {\n if (config.theme.mode !== 'auto') return config.theme.mode;\n try {\n return typeof matchMedia === 'function' && matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light';\n } catch {\n return 'light';\n }\n}\n\n/** Construit le dictionnaire de variables CSS à appliquer sur l'hôte. */\nexport function buildThemeVars(\n config: ResolvedNayaConfig,\n mode: ThemeMode = effectiveMode(config),\n): Record<string, string> {\n const t = mode === 'dark' ? NAYA_DARK : NAYA_LIGHT;\n const r = RADII[config.theme.radius];\n const primary = config.theme.primaryColor;\n const accent = config.theme.accentColor;\n return {\n '--naya-primary': primary,\n '--naya-on-primary': readableTextOn(primary),\n '--naya-accent': accent,\n '--naya-on-accent': readableTextOn(accent, '#FFFFFF', primary),\n '--naya-success': t.success,\n '--naya-success-soft': t.successSoft,\n '--naya-warning': t.warning,\n '--naya-warning-soft': t.warningSoft,\n '--naya-error': t.error,\n '--naya-error-soft': t.errorSoft,\n '--naya-bg': t.bg,\n '--naya-surface': t.surface,\n '--naya-surface-2': t.surface2,\n '--naya-text': t.text,\n '--naya-text-2': t.text2,\n '--naya-line': t.line,\n '--naya-dark': t.dark,\n '--naya-font': config.theme.fontFamily,\n '--naya-r-card': r.card,\n '--naya-r-input': r.input,\n '--naya-r-button': r.button,\n };\n}\n","/**\n * Feuille de style du SDK, injectée dans le Shadow DOM. Jetons v2 exposés en\n * variables CSS par `theme.ts` ; mode sombre par variables, pas par sélecteur.\n */\nexport const STYLES = `\n:host, .naya-host { all: initial; }\n.naya-host {\n position: fixed; inset: 0; z-index: 2147483000;\n display: flex; align-items: center; justify-content: center;\n font-family: var(--naya-font); color: var(--naya-text);\n background: rgba(10, 17, 96, .55);\n -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);\n -webkit-text-size-adjust: 100%; text-size-adjust: 100%;\n -webkit-font-smoothing: antialiased;\n}\n.naya-host.n-inline {\n position: relative; inset: auto; z-index: auto; height: 100%; min-height: 560px;\n background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none;\n}\n.naya-host *, .naya-host *::before, .naya-host *::after { box-sizing: border-box; }\n.n-frame {\n position: relative; width: 100%; height: 100%; overflow: hidden;\n background: var(--naya-bg); color: var(--naya-text);\n display: flex; flex-direction: column;\n}\n/* Ordinateur et tablette : carte centrée au format téléphone. La hauteur\n suit la fenêtre (fenêtres basses, zoom 125 %) sans jamais retomber sur le\n plein écran mobile, qui étirerait boutons et textes sur toute la largeur. */\n@media (min-width: 720px) {\n .naya-host:not(.n-inline) .n-frame {\n width: min(480px, 100% - 32px); height: min(860px, 100% - 32px);\n border-radius: 24px; box-shadow: 0 30px 80px rgba(4, 17, 136, .35);\n }\n}\n.n-inline .n-frame { border-radius: var(--naya-r-card); border: 1px solid var(--naya-line); }\n\n/* ── Gabarit ─────────────────────────────────────────────────────────────── */\n.n-shell { position: absolute; inset: 0; display: flex; flex-direction: column; background: var(--naya-bg); color: var(--naya-text); }\n.n-shell.n-dark { background: var(--naya-dark); color: #fff; }\n.n-enter { animation: n-in .22s ease both; }\n.n-enter-back { animation: n-in-back .22s ease both; }\n.n-leave { animation: n-out .16s ease both; pointer-events: none; }\n@keyframes n-in { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: none; } }\n@keyframes n-in-back { from { opacity: 0; transform: translateX(-24px); } to { opacity: 1; transform: none; } }\n@keyframes n-out { from { opacity: 1; } to { opacity: 0; } }\n\n.n-bar {\n display: flex; align-items: center; justify-content: space-between;\n padding: calc(8px + env(safe-area-inset-top, 0px)) 12px 4px;\n min-height: 56px; flex: none;\n}\n.n-round {\n width: 40px; height: 40px; border-radius: 50%; border: none; cursor: pointer;\n display: inline-flex; align-items: center; justify-content: center;\n background: var(--naya-surface-2); color: var(--naya-text);\n transition: background .15s ease, transform .1s ease;\n}\n.n-round:hover { background: var(--naya-line); }\n.n-round:active { transform: scale(.94); }\n.n-round:focus-visible { outline: 2px solid var(--naya-accent); outline-offset: 2px; }\n.n-dark .n-round { background: rgba(255,255,255,.14); color: #fff; }\n.n-spacer { width: 40px; height: 40px; }\n\n.n-content { flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }\n.n-powered {\n flex: none; display: flex; align-items: center; justify-content: center; gap: 10px;\n padding: 10px 16px calc(12px + env(safe-area-inset-bottom, 0px));\n font-size: 11px; letter-spacing: .02em; color: var(--naya-text-2);\n}\n.n-dark .n-powered { color: rgba(255,255,255,.6); }\n.n-client-logo { height: 18px; width: auto; max-width: 96px; object-fit: contain; }\n\n.pad { display: flex; flex-direction: column; gap: 14px; min-height: 100%; padding: 4px 24px 24px; width: 100%; max-width: 560px; margin: 0 auto; }\n.pad.center { align-items: center; text-align: center; justify-content: center; }\n.spacer { flex: 1; min-height: 8px; }\n.title { margin: 0; font-size: 26px; line-height: 1.15; font-weight: 800; letter-spacing: -.01em; }\n.title:focus { outline: none; }\n.body { margin: 0; font-size: 15px; line-height: 1.5; color: var(--naya-text-2); }\n.n-dark .body { color: rgba(255,255,255,.75); }\n.sub { margin: 0; font-size: 14px; color: var(--naya-text-2); }\n.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }\n.n-ico { flex: none; }\n.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }\n\n/* ── Boutons ────────────────────────────────────────────────────────────── */\n.n-btn {\n width: 100%; min-height: 52px; cursor: pointer; font: inherit; font-size: 15px; font-weight: 700;\n display: inline-flex; align-items: center; justify-content: center; gap: 8px;\n border-radius: var(--naya-r-button); padding: 0 18px;\n transition: filter .15s ease, transform .1s ease, background .15s ease;\n}\n.n-btn:active:not(:disabled) { transform: scale(.985); }\n.n-btn:disabled { opacity: .45; cursor: not-allowed; }\n.n-btn-primary { border: none; background: var(--naya-accent); color: var(--naya-on-accent); font-weight: 800; }\n.n-btn-primary:hover:not(:disabled) { filter: brightness(1.05); }\n.n-btn-primary:focus-visible { outline: 2px solid var(--naya-primary); outline-offset: 2px; }\n.n-btn-secondary { background: transparent; border: 2px solid var(--naya-line); color: var(--naya-text); }\n.n-btn-secondary:hover:not(:disabled) { background: var(--naya-surface-2); }\n.n-btn-secondary:focus-visible { outline: 2px solid var(--naya-accent); outline-offset: 2px; }\n.n-dark .n-btn-secondary { border-color: rgba(255,255,255,.35); color: #fff; }\n.n-btn-ghost { background: transparent; border: none; color: var(--naya-primary); min-height: 44px; font-weight: 700; }\n.n-btn-ghost:focus-visible { outline: 2px solid var(--naya-accent); outline-offset: 2px; }\n.n-dark .n-btn-ghost { color: #fff; }\n.cta { width: 100%; display: flex; flex-direction: column; gap: 10px; }\n.gap { height: 4px; }\n\n/* ── Alertes, champs ────────────────────────────────────────────────────── */\n.n-alert { display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px; border-radius: var(--naya-r-card); font-size: 14px; line-height: 1.45; }\n.n-alert .n-ico { margin-top: 2px; }\n.n-alert-info { background: var(--naya-surface-2); color: var(--naya-text); }\n.n-alert-warning { background: var(--naya-warning-soft); color: var(--naya-text); }\n.n-alert-error { background: var(--naya-error-soft); color: var(--naya-text); }\n.n-alert-success { background: var(--naya-success-soft); color: var(--naya-text); }\n.n-field { display: flex; flex-direction: column; gap: 6px; }\n.n-field label { font-size: 13px; font-weight: 700; }\n.n-field .req { color: var(--naya-error); }\n.n-field input {\n font: inherit; font-size: 16px; min-height: 48px; padding: 0 14px;\n border: 2px solid var(--naya-line); border-radius: var(--naya-r-input);\n background: var(--naya-surface); color: var(--naya-text);\n}\n.n-field input:focus { outline: none; border-color: var(--naya-primary); }\n.n-field.invalid input { border-color: var(--naya-error); }\n.n-field-msg { margin: 0; min-height: 16px; font-size: 12px; color: var(--naya-text-2); }\n.n-field.invalid .n-field-msg { color: var(--naya-error); font-weight: 600; }\n\n/* ── Marque, étapes ─────────────────────────────────────────────────────── */\n.n-brand { display: inline-flex; align-items: center; color: var(--naya-text); line-height: 0; }\n.n-dark .n-brand { color: #fff; }\n.n-logo { display: block; width: auto; }\n.brandRow { display: flex; align-items: center; justify-content: center; gap: 12px; }\n/* Écrans informatifs : titres et textes centrés, lecture plus directe ;\n listes et formulaires restent alignés à gauche (lisibilité). */\n.n-welcome .title, .n-welcome .body, .n-select .title, .n-select .body, .n-tips .title,\n.n-consent .title, .n-consent .body, .n-handoff .title, .n-handoff .body,\n.n-liveness .title, .n-liveness .sub { text-align: center; }\n.n-tips .list { align-self: center; width: 100%; max-width: 400px; }\n/* Carte bureau : le contenu se répartit dans la hauteur au lieu de rester\n collé en haut ; le bouton principal garde le bas de la carte. */\n@media (min-width: 720px) {\n .naya-host:not(.n-inline) .n-content:not(.n-capture):not(.n-liveness):not(.n-ocr) .pad:not(.center)::before { content: ''; flex: 0.6 1 0; min-height: 0; }\n}\n.brandRow .sep { width: 1px; height: 22px; background: var(--naya-line); }\n.brandRow .clientLogo { height: 26px; max-width: 120px; object-fit: contain; }\n.n-dots { display: flex; justify-content: space-between; gap: 8px; margin: 0 8px; }\n.n-step { display: flex; flex-direction: column; align-items: center; gap: 6px; flex: 1; font-size: 12px; color: var(--naya-text-2); }\n.n-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--naya-line); }\n.n-dot.on { background: var(--naya-accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--naya-accent) 25%, transparent); }\n\n/* ── Accueil ────────────────────────────────────────────────────────────── */\n.n-welcome .n-dots { margin-top: 16px; }\n.n-welcome .hero { align-self: center; width: 112px; height: 112px; border-radius: 32px; display: flex; align-items: center; justify-content: center; background: var(--naya-surface-2); color: var(--naya-primary); }\n.n-welcome .secure { display: flex; align-items: center; justify-content: center; gap: 6px; font-size: 12px; color: var(--naya-text-2); }\n\n/* ── Non pris en charge ─────────────────────────────────────────────────── */\n.n-unsupported .hero { width: 96px; height: 96px; border-radius: 28px; background: var(--naya-warning-soft); color: var(--naya-warning); display: flex; align-items: center; justify-content: center; }\n.n-unsupported .link { width: 100%; display: flex; gap: 8px; align-items: center; padding: 10px 12px; border-radius: var(--naya-r-input); background: var(--naya-surface-2); font-size: 13px; }\n.n-unsupported .link code { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n\n/* ── Consentement ───────────────────────────────────────────────────────── */\n.n-consent .check { display: flex; gap: 12px; align-items: flex-start; padding: 14px; border: 2px solid var(--naya-line); border-radius: var(--naya-r-card); cursor: pointer; font-size: 14px; line-height: 1.45; }\n.n-consent .check.on { border-color: var(--naya-primary); background: var(--naya-surface); }\n.n-consent .check input { width: 22px; height: 22px; margin: 1px 0 0; accent-color: var(--naya-primary); flex: none; }\n.n-consent .policy { font-size: 13px; color: var(--naya-primary); font-weight: 700; text-decoration: underline; }\n.n-consent .bullets { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; font-size: 14px; }\n.n-consent .bullets li { display: flex; gap: 10px; align-items: flex-start; color: var(--naya-text-2); }\n.n-consent .bullets .n-ico { color: var(--naya-success); margin-top: 2px; }\n\n/* ── Relais QR ──────────────────────────────────────────────────────────── */\n.n-handoff .qr { align-self: center; width: 220px; height: 220px; padding: 12px; background: #fff; border-radius: var(--naya-r-card); border: 1px solid var(--naya-line); }\n.n-handoff .qr svg { width: 100%; height: 100%; display: block; }\n.n-handoff .wait { display: flex; align-items: center; gap: 10px; justify-content: center; font-size: 14px; color: var(--naya-text-2); }\n.n-handoff .qr.loading { display: flex; align-items: center; justify-content: center; }\n\n/* ── Sélection ──────────────────────────────────────────────────────────── */\n.n-select .chips { display: flex; flex-wrap: wrap; gap: 8px; }\n.n-select .chip { font: inherit; font-size: 13px; font-weight: 700; padding: 8px 14px; border-radius: 999px; border: 2px solid var(--naya-line); background: var(--naya-surface); color: var(--naya-text); cursor: pointer; }\n.n-select .chip.on { border-color: var(--naya-primary); background: var(--naya-primary); color: var(--naya-on-primary); }\n.n-select .chip:focus-visible { outline: 2px solid var(--naya-accent); outline-offset: 2px; }\n.n-select .cards { display: flex; flex-direction: column; gap: 10px; }\n.n-select .card { font: inherit; display: flex; align-items: center; gap: 12px; width: 100%; padding: 14px; border-radius: var(--naya-r-card); border: 2px solid var(--naya-line); background: var(--naya-surface); color: var(--naya-text); cursor: pointer; text-align: left; font-size: 15px; font-weight: 700; }\n.n-select .card.on { border-color: var(--naya-primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--naya-primary) 18%, transparent); }\n.n-select .card:focus-visible { outline: 2px solid var(--naya-accent); outline-offset: 2px; }\n.n-select .card .ico { width: 40px; height: 40px; border-radius: 12px; background: var(--naya-surface-2); color: var(--naya-primary); display: inline-flex; align-items: center; justify-content: center; }\n.n-select .card .lbl { flex: 1; }\n\n/* ── Conseils ───────────────────────────────────────────────────────────── */\n.n-tips .list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 12px; }\n.n-tips .list li { display: flex; gap: 12px; align-items: flex-start; font-size: 15px; line-height: 1.45; }\n.n-tips .list .num { flex: none; width: 28px; height: 28px; border-radius: 50%; background: var(--naya-surface-2); color: var(--naya-primary); font-size: 13px; font-weight: 800; display: inline-flex; align-items: center; justify-content: center; }\n.n-illu { position: relative; align-self: center; width: 220px; height: 150px; border-radius: 20px; background: var(--naya-surface-2); overflow: hidden; }\n.n-illu-doc .tbl { position: absolute; left: 0; right: 0; bottom: 0; height: 46%; background: var(--naya-dark); opacity: .85; }\n.n-illu-doc .card { position: absolute; left: 50%; top: 46%; width: 128px; height: 82px; margin-left: -64px; border-radius: 8px; background: #fff; box-shadow: 0 6px 18px rgba(0,0,0,.25); animation: n-card 3s ease-in-out infinite; }\n.n-illu-doc .card .ph { position: absolute; left: 10px; top: 12px; width: 28px; height: 34px; border-radius: 4px; background: var(--naya-line); }\n.n-illu-doc .card .ln { position: absolute; left: 46px; height: 6px; border-radius: 3px; background: var(--naya-line); }\n.n-illu-doc .card .ln.a { top: 14px; width: 66px; } .n-illu-doc .card .ln.b { top: 28px; width: 50px; } .n-illu-doc .card .ln.c { top: 42px; width: 60px; }\n.n-illu-doc .glow { position: absolute; left: -40px; top: -40px; width: 120px; height: 120px; border-radius: 50%; background: radial-gradient(circle, rgba(255,255,255,.9), transparent 70%); animation: n-glow 3s ease-in-out infinite; }\n@keyframes n-card { 0%, 100% { transform: translateY(0) rotate(-6deg); } 50% { transform: translateY(-4px) rotate(0deg); } }\n@keyframes n-glow { 0%, 100% { opacity: .2; } 50% { opacity: .7; } }\n.n-illu-face .oval { position: absolute; left: 50%; top: 50%; width: 90px; height: 118px; margin: -59px 0 0 -45px; border-radius: 50%; border: 3px solid var(--naya-accent); }\n.n-illu-face .head { position: absolute; inset: 10px; border-radius: 50%; background: #F3C77A; animation: n-head 4s ease-in-out infinite; }\n.n-illu-face .eye { position: absolute; top: 40%; width: 10px; height: 10px; border-radius: 50%; background: var(--naya-dark); animation: n-blink 4s ease-in-out infinite; }\n.n-illu-face .eye.l { left: 26%; } .n-illu-face .eye.r { right: 26%; }\n.n-illu-face .mouth { position: absolute; left: 50%; top: 66%; width: 28px; height: 12px; margin-left: -14px; border-radius: 0 0 20px 20px; border: 3px solid var(--naya-dark); border-top: 0; }\n.n-illu-face .light { position: absolute; right: 14px; top: 12px; width: 34px; height: 34px; border-radius: 50%; background: radial-gradient(circle, #fff, var(--naya-accent)); box-shadow: 0 0 24px rgba(230,149,10,.8); }\n@keyframes n-head { 0%, 35%, 100% { transform: rotateY(0deg); } 55%, 75% { transform: rotateY(28deg); } }\n@keyframes n-blink { 0%, 18%, 24%, 100% { transform: scaleY(1); } 21% { transform: scaleY(.1); } }\n\n/* ── Capture ────────────────────────────────────────────────────────────── */\n.n-capture .instruction { margin: 0; font-size: 15px; font-weight: 700; text-align: center; }\n.n-capture .cardWrap { position: relative; width: 100%; }\n.n-capture .card { position: relative; width: 100%; aspect-ratio: 1.586; border-radius: 14px; overflow: hidden; background: #000; }\n.n-capture .card.ready { box-shadow: 0 0 0 3px var(--naya-success); }\n.n-capture .preview { width: 100%; height: 100%; object-fit: cover; display: block; }\n.n-capture .corners { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }\n.n-capture .corners path { fill: none; stroke: rgba(255,255,255,.9); stroke-width: 2.2; stroke-linecap: round; transition: stroke .2s ease; }\n.n-capture .card.ready .corners path { stroke: var(--naya-success); }\n.n-capture .countdown { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 64px; font-weight: 900; color: #fff; text-shadow: 0 2px 12px rgba(0,0,0,.6); pointer-events: none; }\n.n-capture .banner { display: flex; align-items: center; justify-content: center; gap: 8px; min-height: 40px; padding: 8px 14px; border-radius: 12px; background: rgba(255,255,255,.12); font-size: 14px; font-weight: 600; text-align: center; }\n.n-capture .banner.good { background: color-mix(in srgb, var(--naya-success) 30%, transparent); }\n.n-capture .pills { display: flex; gap: 8px; justify-content: center; }\n.n-capture .pill { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 999px; background: rgba(255,255,255,.12); font-size: 12px; font-weight: 700; }\n.n-capture .pill.ok { background: color-mix(in srgb, var(--naya-success) 35%, transparent); }\n.n-capture .tools { display: flex; align-items: center; justify-content: center; gap: 22px; }\n.n-capture .tool { font: inherit; display: inline-flex; flex-direction: column; align-items: center; gap: 4px; background: none; border: none; color: #fff; font-size: 11px; cursor: pointer; opacity: .85; }\n.n-capture .tool.on { color: var(--naya-accent); opacity: 1; }\n.n-capture .tool:focus-visible { outline: 2px solid #fff; outline-offset: 2px; border-radius: 8px; }\n.n-capture .shutter { align-self: center; width: 76px; height: 76px; border-radius: 50%; border: 5px solid rgba(255,255,255,.6); background: #fff; cursor: pointer; transition: transform .1s ease, border-color .2s ease; }\n.n-capture .shutter.ready { border-color: var(--naya-success); }\n.n-capture .shutter:active:not(:disabled) { transform: scale(.94); }\n.n-capture .shutter:disabled { opacity: .5; cursor: not-allowed; }\n.n-capture .shutter:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }\n.n-capture .hint { margin: 0; text-align: center; font-size: 13px; opacity: .8; }\n.n-capture .hint.ready { opacity: 1; color: var(--naya-success); font-weight: 700; }\n.n-capture .camMsg, .n-liveness .camMsg { position: absolute; inset: 0; display: flex; flex-direction: column; gap: 10px; align-items: center; justify-content: center; padding: 20px; text-align: center; font-size: 14px; background: rgba(0,0,0,.55); color: #fff; }\n.n-capture .camMsg[hidden], .n-liveness .camMsg[hidden] { display: none; }\n.loader { width: 28px; height: 28px; border-radius: 50%; border: 3px solid rgba(255,255,255,.3); border-top-color: #fff; animation: n-spin .8s linear infinite; }\n.loader.sm { width: 18px; height: 18px; border-width: 2px; }\n@keyframes n-spin { to { transform: rotate(360deg); } }\n\n/* ── Vivacité ───────────────────────────────────────────────────────────── */\n.n-liveness .ovalWrap { position: relative; align-self: center; width: 210px; height: 270px; }\n.n-liveness .oval { position: absolute; inset: 4px; border-radius: 50%; overflow: hidden; background: #000; }\n.n-liveness .preview { width: 100%; height: 100%; object-fit: cover; transform: scaleX(-1); }\n.n-liveness .ring { position: absolute; inset: 0; width: 100%; height: 100%; }\n.n-liveness .ring .track { fill: none; stroke: var(--naya-line); stroke-width: 4; }\n.n-liveness .ring .prog { fill: none; stroke: var(--naya-accent); stroke-width: 4; stroke-linecap: round; transition: stroke-dashoffset .4s ease; }\n.n-liveness .ring.done .prog { stroke: var(--naya-success); }\n.n-liveness .instruction { display: flex; align-items: center; justify-content: center; gap: 10px; min-height: 52px; padding: 10px 16px; border-radius: 14px; background: var(--naya-surface-2); font-size: 16px; font-weight: 700; text-align: center; }\n.n-liveness .instruction.ok { background: var(--naya-success-soft); color: var(--naya-success); }\n.n-liveness .instruction.guide { background: var(--naya-warning-soft); }\n.n-liveness .steps { display: flex; justify-content: center; gap: 18px; }\n.n-liveness .cstep { display: flex; flex-direction: column; align-items: center; gap: 6px; font-size: 12px; color: var(--naya-text-2); min-width: 64px; }\n.n-liveness .cdot { width: 26px; height: 26px; border-radius: 50%; border: 2px solid var(--naya-line); display: inline-flex; align-items: center; justify-content: center; color: #fff; }\n.n-liveness .cdot.active { border-color: var(--naya-accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--naya-accent) 25%, transparent); }\n.n-liveness .cdot.done { background: var(--naya-success); border-color: var(--naya-success); }\n.n-liveness .privacy { margin: 0; padding-top: 4px; text-align: center; font-size: 12px; line-height: 1.4; color: var(--naya-text-2); }\n.n-liveness .toast { position: absolute; left: 50%; top: -6px; transform: translateX(-50%); padding: 6px 12px; border-radius: 999px; background: var(--naya-success); color: #fff; font-size: 12px; font-weight: 800; display: flex; gap: 6px; align-items: center; animation: n-pop .5s ease both; }\n@keyframes n-pop { 0% { transform: translate(-50%, 8px) scale(.8); opacity: 0; } 60% { transform: translate(-50%, -2px) scale(1.05); opacity: 1; } 100% { transform: translate(-50%, 0) scale(1); } }\n\n/* ── Confirmation OCR ───────────────────────────────────────────────────── */\n.n-ocr .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 10px; }\n.n-ocr .dl { margin: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }\n.n-ocr .dl > div { padding: 10px 12px; border-radius: var(--naya-r-input); background: var(--naya-surface-2); min-width: 0; }\n.n-ocr .dl > div.wide { grid-column: 1 / -1; }\n.n-ocr .dl dt { margin: 0; font-size: 11px; letter-spacing: .02em; text-transform: uppercase; color: var(--naya-text-2); }\n.n-ocr .dl dd { margin: 2px 0 0; font-size: 15px; font-weight: 700; overflow-wrap: anywhere; }\n.n-ocr .dl dd.empty { font-weight: 500; color: var(--naya-text-2); font-style: italic; }\n.n-ocr .question { margin: 4px 0 0; text-align: center; font-size: 15px; font-weight: 700; }\n.n-ocr .cta { display: flex; flex-direction: column; gap: 10px; }\n.n-ocr .grid .wide { grid-column: 1 / -1; }\n.n-ocr .waiting { display: flex; align-items: center; gap: 10px; font-size: 14px; color: var(--naya-text-2); }\n.n-ocr .waiting .loader { border-color: var(--naya-line); border-top-color: var(--naya-primary); }\n\n/* ── Traitement ─────────────────────────────────────────────────────────── */\n.n-processing .spin { align-self: center; width: 54px; height: 54px; border-radius: 50%; border: 4px solid var(--naya-line); border-top-color: var(--naya-accent); animation: n-spin .9s linear infinite; }\n.n-processing .steps { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 14px; }\n.n-processing .row { display: flex; align-items: center; gap: 12px; font-size: 15px; }\n.n-processing .dot { width: 26px; height: 26px; border-radius: 50%; border: 2px solid var(--naya-line); display: inline-flex; align-items: center; justify-content: center; color: #fff; flex: none; }\n.n-processing .dot.active { border-color: var(--naya-accent); animation: n-pulse 1.2s ease-in-out infinite; }\n.n-processing .dot.done { background: var(--naya-success); border-color: var(--naya-success); }\n.n-processing .lbl.dim { color: var(--naya-text-2); }\n.n-processing .wait { margin: 0; text-align: center; font-size: 13px; color: var(--naya-text-2); }\n@keyframes n-pulse { 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--naya-accent) 40%, transparent); } 50% { box-shadow: 0 0 0 8px transparent; } }\n\n/* ── Résultat ───────────────────────────────────────────────────────────── */\n.n-result .badge { align-self: center; width: 96px; height: 96px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #fff; animation: n-badge .5s cubic-bezier(.2, .9, .3, 1.3) both; }\n@keyframes n-badge { from { transform: scale(.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }\n.n-result .title { text-align: center; }\n.n-result .body { text-align: center; }\n.n-result .summary { display: flex; flex-direction: column; gap: 8px; padding: 14px; border-radius: var(--naya-r-card); background: var(--naya-surface-2); }\n.n-result .srow { display: flex; justify-content: space-between; gap: 12px; font-size: 14px; }\n.n-result .srow .k { color: var(--naya-text-2); }\n.n-result .srow .v { font-weight: 700; text-align: right; }\n.n-result .bullets, .n-result .reasons { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 10px; font-size: 14px; line-height: 1.45; }\n.n-result .bullets li, .n-result .reasons li { display: flex; gap: 10px; align-items: flex-start; }\n.n-result .pip { flex: none; width: 8px; height: 8px; margin-top: 7px; border-radius: 50%; background: var(--naya-accent); }\n.n-result .reasons .n-ico { flex: none; margin-top: 1px; color: var(--naya-error); }\n\n/* ── Préférences système ────────────────────────────────────────────────── */\n@media (prefers-reduced-motion: reduce) {\n .n-enter, .n-enter-back, .n-leave, .n-result .badge, .n-liveness .toast { animation: none; }\n .n-illu *, .n-processing .dot.active, .loader, .n-processing .spin { animation: none; }\n .n-liveness .ring .prog { transition: none; }\n}\n@media (prefers-contrast: more) {\n .n-btn-secondary, .n-select .card, .n-select .chip, .n-field input, .n-consent .check { border-width: 3px; }\n .body, .sub, .n-powered { color: var(--naya-text); }\n}\n`;\n","/**\n * Résultat du parcours, rendu à l'application cliente à la fermeture du SDK.\n */\n\n/** Issue du parcours de vérification. */\nexport type NayaStatus =\n /** Identité vérifiée et approuvée automatiquement. */\n | 'approved'\n /** Dossier envoyé en revue manuelle — décision finale ultérieure. */\n | 'review'\n /** Vérification rejetée (document expiré, visage non concordant…). */\n | 'rejected'\n /** L'utilisateur a quitté le parcours avant la fin. */\n | 'cancelled'\n /** Erreur technique (réseau, serveur, caméra…) ayant interrompu le parcours. */\n | 'error';\n\n/**\n * Code d'erreur stable, indépendant de la langue. `errorMessage` porte le\n * détail lisible (souvent celui du serveur) et `requestId` la référence à\n * communiquer au support.\n */\nexport type NayaErrorCode =\n | 'network'\n | 'timeout'\n | 'unauthorized'\n | 'origin_not_allowed'\n | 'session_expired'\n | 'session_closed'\n | 'quota'\n | 'kyb_pending'\n | 'rate_limited'\n | 'upload_limit'\n | 'bad_request'\n | 'server'\n | 'camera_denied'\n | 'camera_unavailable'\n | 'camera_busy'\n | 'liveness_assets'\n | 'unsupported_browser'\n | 'in_app_browser'\n | 'insecure_context'\n | 'invalid_params'\n | 'unknown';\n\n/**\n * Données d'identité extraites du document par l'OCR Naya, éventuellement\n * corrigées par l'utilisateur.\n */\nexport interface NayaOcrData {\n lastName?: string;\n firstName?: string;\n /** Format YYYY-MM-DD. */\n dateOfBirth?: string;\n placeOfBirth?: string;\n nationality?: string;\n /** Format YYYY-MM-DD. */\n expirationDate?: string;\n documentNumber?: string;\n /** Numéro Personnel d'Identification (Bénin) — 10 chiffres. */\n npi?: string;\n issuingCountry?: string;\n issuingAuthority?: string;\n /** 'M' ou 'F'. */\n gender?: string;\n}\n\nexport const OCR_FIELDS: readonly (keyof NayaOcrData)[] = [\n 'lastName',\n 'firstName',\n 'dateOfBirth',\n 'placeOfBirth',\n 'nationality',\n 'expirationDate',\n 'documentNumber',\n 'npi',\n 'issuingCountry',\n 'issuingAuthority',\n 'gender',\n];\n\n/** Lit un objet OCR brut de l'API en ne retenant que les champs connus. */\nexport function parseOcrData(raw: unknown): NayaOcrData | undefined {\n if (!raw || typeof raw !== 'object') return undefined;\n const src = raw as Record<string, unknown>;\n const out: NayaOcrData = {};\n for (const field of OCR_FIELDS) {\n const value = src[field];\n if (typeof value === 'string' && value.length > 0) out[field] = value;\n }\n return Object.keys(out).length ? out : undefined;\n}\n\n/** Réduit un objet OCR à ses seuls champs renseignés, en chaînes. */\nexport function ocrToDeclaredData(ocr: NayaOcrData): Record<string, string> {\n const out: Record<string, string> = {};\n for (const field of OCR_FIELDS) {\n const value = ocr[field];\n if (value) out[field] = value;\n }\n return out;\n}\n\n/** Résultat retourné à l'application cliente. */\nexport interface NayaResult {\n status: NayaStatus;\n /**\n * Identifiant de la session Naya — à conserver côté client pour rapprocher\n * les notifications `callbackUrl` et le dashboard.\n */\n verificationId?: string;\n /** Motifs stables de la décision (DOC_EXPIRED, FACE_MISMATCH…). */\n reasonCodes?: string[];\n /** `active` (défi exécuté) ou `passive` (selfie seul). */\n livenessMode?: 'active' | 'passive';\n riskScore?: number;\n matchScore?: number;\n authenticityScore?: number;\n livenessScore?: number;\n ocrConfidence?: number;\n /** Extraction brute du document, telle que lue par le serveur ; jamais altérée. */\n ocrData?: NayaOcrData;\n /** Ce que l'utilisateur a déclaré (mode `confirmOcr: 'edit'`), conservé à part. */\n declaredData?: Record<string, string>;\n /** Champs où `declaredData` diffère de `ocrData`. */\n dataMismatches?: string[];\n /** L'utilisateur a contesté les données lues (mode `'display'`). */\n dataDisputed?: boolean;\n /** Note d'analyse du serveur (rejet, revue). */\n note?: string;\n /** Renseignés quand `status === 'error'`. */\n errorCode?: NayaErrorCode;\n errorMessage?: string;\n /** Statut HTTP de l'erreur serveur, le cas échéant. */\n statusCode?: number;\n /** Référence de requête renvoyée par l'API, à transmettre au support. */\n requestId?: string;\n}\n\nexport function cancelledResult(verificationId?: string): NayaResult {\n return { status: 'cancelled', verificationId };\n}\n\nexport function errorResult(\n errorMessage: string,\n verificationId?: string,\n extra: { errorCode?: NayaErrorCode; statusCode?: number; requestId?: string } = {},\n): NayaResult {\n return {\n status: 'error',\n errorMessage,\n verificationId,\n errorCode: extra.errorCode ?? 'unknown',\n statusCode: extra.statusCode,\n requestId: extra.requestId,\n };\n}\n","declare const __NAYA_VERSION__: string | undefined;\n\n/** Version du SDK, injectée à la compilation depuis package.json. */\nexport const SDK_VERSION: string = typeof __NAYA_VERSION__ === 'string' ? __NAYA_VERSION__ : '0.0.0-dev';\n","import type { NayaAuth } from '../models/config';\nimport { type NayaErrorCode, type NayaOcrData, parseOcrData } from '../models/result';\nimport type { TelemetryEvent } from '../support/telemetry';\nimport { SDK_VERSION } from '../version';\n\n/**\n * Client HTTP du pipeline de vérification Naya.\n *\n * Bâti sur `fetch` natif, sans dépendance. Les délais sont dimensionnés pour\n * les étapes longues (OCR et décision côté serveur). Les échecs transitoires\n * (réseau, délai, 429, 502-504) sont retentés avec un délai croissant.\n *\n * Authentification : `apiKey` (en-tête `X-API-Key`) ou `sessionToken`\n * (en-tête `Authorization: Bearer`).\n */\n\n/** Erreur typée renvoyée par l'API Naya ou par le transport réseau. */\nexport class NayaApiError extends Error {\n readonly code: NayaErrorCode;\n readonly statusCode?: number;\n readonly requestId?: string;\n readonly retryable: boolean;\n\n constructor(\n message: string,\n code: NayaErrorCode,\n opts: { statusCode?: number; requestId?: string; retryable?: boolean } = {},\n ) {\n super(message);\n this.name = 'NayaApiError';\n this.code = code;\n this.statusCode = opts.statusCode;\n this.requestId = opts.requestId;\n this.retryable = opts.retryable ?? false;\n }\n}\n\n/** Réponse de POST /verifications/start. */\nexport interface NayaSession {\n verificationId: string;\n sessionToken: string;\n /** Gestes imposés par le serveur, à exécuter dans l'ordre. */\n challenge: string[];\n}\n\n/** Extrait de GET /verifications/:id (projection jeton de session). */\nexport interface NayaVerificationInfo {\n status: string;\n decision: string | null;\n documentType: string | null;\n country: string | null;\n challenge: string[];\n consentAt: string | null;\n processingStage: string | null;\n reasonCodes: string[];\n hasDocument: boolean;\n hasSelfie: boolean;\n}\n\n/** Réponse de POST /verifications/:id/submit. */\nexport interface NayaSubmitResponse {\n status: string;\n decision?: string;\n reasonCodes: string[];\n riskScore?: number;\n matchScore?: number;\n authenticityScore?: number;\n livenessScore?: number;\n ocrConfidence?: number;\n /** Extraction brute du document, jamais altérée par le serveur. */\n ocrData?: NayaOcrData;\n /** Ce que l'utilisateur a déclaré, conservé à part par le serveur. */\n declaredData?: Record<string, string>;\n /** Champs où déclaration et extraction diffèrent. */\n dataMismatches?: string[];\n dataDisputed?: boolean;\n note?: string;\n replayed?: boolean;\n}\n\nexport interface NayaHandoff {\n url: string;\n qrSvg: string;\n expiresAt: string;\n}\n\nexport interface LivenessSubmission {\n selfieBase64: string;\n livenessMode: 'active' | 'passive';\n challengeProof?: Array<{ step: string; at: number }>;\n frames?: string[];\n clientScore?: number;\n}\n\nconst SECONDS = 1000;\nconst RETRY_BASE_MS = 800;\nconst RETRY_MAX = 2;\n\n/** Traduit un statut HTTP et le message serveur en code d'erreur stable. */\nexport function mapHttpError(status: number, message: string): { code: NayaErrorCode; retryable: boolean } {\n const m = message.toLowerCase();\n if (status === 401) {\n if (m.includes('expired')) return { code: 'session_expired', retryable: false };\n if (m.includes('session closed')) return { code: 'session_closed', retryable: false };\n return { code: 'unauthorized', retryable: false };\n }\n if (status === 403) {\n if (m.includes('origin')) return { code: 'origin_not_allowed', retryable: false };\n if (m.includes('kyb')) return { code: 'kyb_pending', retryable: false };\n return { code: 'unauthorized', retryable: false };\n }\n if (status === 402) return { code: 'quota', retryable: false };\n if (status === 429) {\n if (m.includes('upload limit')) return { code: 'upload_limit', retryable: false };\n return { code: 'rate_limited', retryable: true };\n }\n if (status >= 500) return { code: 'server', retryable: status === 502 || status === 503 || status === 504 };\n if (status >= 400) return { code: 'bad_request', retryable: false };\n return { code: 'unknown', retryable: false };\n}\n\nfunction numOrUndef(v: unknown): number | undefined {\n return typeof v === 'number' && !Number.isNaN(v) ? v : undefined;\n}\n\nfunction strRecord(v: unknown): Record<string, string> | undefined {\n if (!v || typeof v !== 'object') return undefined;\n const out: Record<string, string> = {};\n for (const [k, val] of Object.entries(v as Record<string, unknown>))\n if (typeof val === 'string') out[k] = val;\n return Object.keys(out).length ? out : undefined;\n}\n\nfunction strArray(v: unknown): string[] {\n return Array.isArray(v) ? v.filter((x): x is string => typeof x === 'string') : [];\n}\n\nexport class NayaApiClient {\n constructor(\n private readonly auth: NayaAuth,\n private readonly baseUrl: string,\n ) {}\n\n get canAuthenticate(): boolean {\n return !!(this.auth.sessionToken || this.auth.apiKey);\n }\n\n /** Après `/start` en mode clé, les appels suivants portent le jeton de session. */\n useSession(sessionToken: string): void {\n this.auth.sessionToken = sessionToken;\n }\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Naya-SDK': `js/${SDK_VERSION}`,\n };\n if (this.auth.sessionToken) {\n h['Authorization'] = `Bearer ${this.auth.sessionToken}`;\n } else if (this.auth.apiKey) {\n h['X-API-Key'] = this.auth.apiKey;\n }\n return h;\n }\n\n private async request<T>(\n method: 'GET' | 'POST',\n path: string,\n body?: Record<string, unknown>,\n opts: { timeoutMs?: number; retries?: number; keepalive?: boolean } = {},\n ): Promise<T> {\n const timeoutMs = opts.timeoutMs ?? 30 * SECONDS;\n const retries = opts.retries ?? RETRY_MAX;\n let attempt = 0;\n for (;;) {\n try {\n return await this.once<T>(method, path, body, timeoutMs, opts.keepalive);\n } catch (err) {\n const e = err as NayaApiError;\n if (!(e instanceof NayaApiError) || !e.retryable || attempt >= retries) throw err;\n const retryAfter = (e as NayaApiError & { retryAfterMs?: number }).retryAfterMs;\n const wait = retryAfter ?? RETRY_BASE_MS * 2 ** attempt + Math.random() * 300;\n attempt += 1;\n await new Promise((r) => setTimeout(r, wait));\n }\n }\n }\n\n private async once<T>(\n method: 'GET' | 'POST',\n path: string,\n body: Record<string, unknown> | undefined,\n timeoutMs: number,\n keepalive?: boolean,\n ): Promise<T> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n let res: Response;\n try {\n res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: this.headers(),\n body: body === undefined ? undefined : JSON.stringify(body),\n signal: controller.signal,\n keepalive,\n });\n } catch (err) {\n const aborted = err instanceof DOMException && err.name === 'AbortError';\n // Un `TypeError` de fetch, sans réponse : hors-ligne, pare-feu, DNS, ou\n // refus CORS. Le navigateur ne dit pas lequel ; le message le rappelle.\n throw new NayaApiError(\n aborted ? 'Délai dépassé.' : 'Service injoignable (réseau, pare-feu ou origine non autorisée).',\n aborted ? 'timeout' : 'network',\n { retryable: true },\n );\n } finally {\n clearTimeout(timer);\n }\n\n const requestId = res.headers.get('x-request-id') ?? undefined;\n let json: any = null;\n try {\n json = await res.json();\n } catch {\n if (res.ok) return {} as T;\n const mapped = mapHttpError(res.status, '');\n throw new NayaApiError('Réponse illisible du serveur.', mapped.code, {\n statusCode: res.status,\n requestId,\n retryable: mapped.retryable,\n });\n }\n\n if (res.status >= 400 || json?.success !== true) {\n const message: string =\n (json?.error && typeof json.error === 'object' ? json.error.message : undefined) ??\n 'Erreur inconnue.';\n const mapped = mapHttpError(res.status, message);\n const error = new NayaApiError(message, mapped.code, {\n statusCode: res.status,\n requestId: json?.error?.requestId ?? requestId,\n retryable: mapped.retryable,\n });\n const ra = res.headers.get('retry-after');\n if (ra && /^\\d+$/.test(ra))\n (error as NayaApiError & { retryAfterMs?: number }).retryAfterMs = Math.min(\n 30_000,\n parseInt(ra, 10) * 1000,\n );\n throw error;\n }\n return (json.data ?? {}) as T;\n }\n\n /** Ouvre une session de vérification (mode clé d'API). */\n async start(params: {\n documentType: string;\n country: string;\n callbackUrl?: string;\n device: string;\n simulate?: 'approved' | 'review' | 'rejected';\n }): Promise<NayaSession> {\n const data = await this.request<Record<string, unknown>>(\n 'POST',\n '/verifications/start',\n {\n documentType: params.documentType,\n country: params.country,\n device: params.device,\n ...(params.callbackUrl ? { callbackUrl: params.callbackUrl } : {}),\n ...(params.simulate ? { simulate: params.simulate } : {}),\n },\n { retries: 1 },\n );\n return {\n verificationId: String(data['verificationId'] ?? ''),\n sessionToken: String(data['sessionToken'] ?? ''),\n challenge: strArray(data['challenge']),\n };\n }\n\n /** Lit une vérification (projection minimale avec un jeton de session). */\n async getVerification(verificationId: string): Promise<NayaVerificationInfo> {\n const data = await this.request<Record<string, unknown>>(\n 'GET',\n `/verifications/${verificationId}`,\n undefined,\n { timeoutMs: 15 * SECONDS },\n );\n const v = (data['verification'] ?? data) as Record<string, unknown>;\n return {\n status: String(v['status'] ?? 'pending'),\n decision: typeof v['decision'] === 'string' ? (v['decision'] as string) : null,\n documentType: typeof v['documentType'] === 'string' ? (v['documentType'] as string) : null,\n country: typeof v['country'] === 'string' ? (v['country'] as string) : null,\n challenge: strArray(v['challenge']),\n consentAt: typeof v['consentAt'] === 'string' ? (v['consentAt'] as string) : null,\n processingStage: typeof v['processingStage'] === 'string' ? (v['processingStage'] as string) : null,\n reasonCodes: strArray(v['reasonCodes']),\n hasDocument: !!v['hasDocument'],\n hasSelfie: !!v['hasSelfie'],\n };\n }\n\n /** Horodate le consentement biométrique. */\n async consent(verificationId: string, version?: string): Promise<void> {\n await this.request('POST', `/verifications/${verificationId}/consent`, {\n granted: true,\n ...(version ? { version } : {}),\n });\n }\n\n /**\n * Envoie le document capturé. L'OCR serveur est synchrone : la réponse\n * contient les champs extraits, utilisés pour pré-remplir la confirmation.\n */\n async uploadDocument(\n verificationId: string,\n params: { rectoBase64: string; versoBase64?: string },\n ): Promise<NayaOcrData | undefined> {\n const data = await this.request<Record<string, unknown>>(\n 'POST',\n `/verifications/${verificationId}/document`,\n {\n imageBase64Recto: params.rectoBase64,\n ...(params.versoBase64 ? { imageBase64Verso: params.versoBase64 } : {}),\n },\n { timeoutMs: 120 * SECONDS, retries: 1 },\n );\n return parseOcrData(data['ocrData']);\n }\n\n /** Envoie le selfie, le mode de vivacité et la preuve du défi. */\n async submitLiveness(\n verificationId: string,\n params: LivenessSubmission,\n ): Promise<{ challengeValid: boolean | null }> {\n const data = await this.request<Record<string, unknown>>(\n 'POST',\n `/verifications/${verificationId}/liveness`,\n {\n selfieBase64: params.selfieBase64,\n livenessMode: params.livenessMode,\n ...(params.challengeProof ? { challengeProof: params.challengeProof } : {}),\n ...(params.frames?.length ? { frames: params.frames } : {}),\n ...(params.clientScore != null ? { livenessScore: params.clientScore } : {}),\n matchScore: 0,\n },\n { timeoutMs: 60 * SECONDS, retries: 1 },\n );\n const cv = data['challengeValid'];\n return { challengeValid: typeof cv === 'boolean' ? cv : null };\n }\n\n /** Déclenche l'analyse finale (OCR différé, biométrie, AML, décision). */\n async submit(\n verificationId: string,\n declaredData?: Record<string, string>,\n dataDisputed = false,\n ): Promise<NayaSubmitResponse> {\n const body: Record<string, unknown> = {};\n if (declaredData && Object.keys(declaredData).length) body['declaredData'] = declaredData;\n if (dataDisputed) body['dataDisputed'] = true;\n const data = await this.request<Record<string, unknown>>(\n 'POST',\n `/verifications/${verificationId}/submit`,\n body,\n // Le serveur est idempotent : une décision déjà rendue est rejouée.\n { timeoutMs: 180 * SECONDS, retries: 1 },\n );\n return {\n status: String(data['status'] ?? 'review'),\n decision: typeof data['decision'] === 'string' ? (data['decision'] as string) : undefined,\n reasonCodes: strArray(data['reasonCodes']),\n riskScore: numOrUndef(data['riskScore']),\n matchScore: numOrUndef(data['matchScore']),\n authenticityScore: numOrUndef(data['authenticityScore']),\n livenessScore: numOrUndef(data['livenessScore']),\n ocrConfidence: numOrUndef(data['ocrConfidence']),\n ocrData: parseOcrData(data['ocrData']),\n declaredData: strRecord(data['declaredData']),\n dataMismatches: strArray(data['dataMismatches']),\n dataDisputed: data['dataDisputed'] === true,\n note: typeof data['note'] === 'string' ? (data['note'] as string) : undefined,\n replayed: data['replayed'] === true,\n };\n }\n\n /** URL et QR code du relais vers mobile. */\n async handoff(verificationId: string, baseUrl?: string): Promise<NayaHandoff> {\n const q = baseUrl ? `?baseUrl=${encodeURIComponent(baseUrl)}` : '';\n const data = await this.request<Record<string, unknown>>(\n 'GET',\n `/verifications/${verificationId}/handoff${q}`,\n undefined,\n { timeoutMs: 15 * SECONDS },\n );\n return {\n url: String(data['url'] ?? ''),\n qrSvg: String(data['qrSvg'] ?? ''),\n expiresAt: String(data['expiresAt'] ?? ''),\n };\n }\n\n /** Lot de télémétrie anonyme. */\n async sendEvents(events: TelemetryEvent[], device: string, final: boolean): Promise<void> {\n await this.request(\n 'POST',\n '/sdk/events',\n { sdk: 'js', version: SDK_VERSION, device, events },\n {\n timeoutMs: 10 * SECONDS,\n retries: 0,\n keepalive: final,\n },\n );\n }\n}\n","import type { NayaDocumentType, NayaLocale } from '../models/config';\nimport type { NayaErrorCode } from '../models/result';\n\n/**\n * Chaînes de l'interface en français, anglais et portugais. Chaque clé est\n * surchargeable par l'hôte via `config.strings`. `{name}` est interpolé.\n */\ntype Tri = readonly [fr: string, en: string, pt: string];\n\nconst DICT = {\n // Commun\n poweredBy: ['Propulsé par 41Devs', 'Powered by 41Devs', 'Desenvolvido por 41Devs'],\n continue: ['Continuer', 'Continue', 'Continuar'],\n back: ['Retour', 'Back', 'Voltar'],\n close: ['Fermer', 'Close', 'Fechar'],\n cancel: ['Annuler', 'Cancel', 'Cancelar'],\n retry: ['Réessayer', 'Try again', 'Tentar novamente'],\n backToApp: [\"Retourner à l'application\", 'Back to the app', 'Voltar à aplicação'],\n understood: [\"J'ai compris\", 'Got it', 'Entendi'],\n confirm: ['Confirmer', 'Confirm', 'Confirmar'],\n copyLink: ['Copier le lien', 'Copy link', 'Copiar ligação'],\n copied: ['Lien copié', 'Link copied', 'Ligação copiada'],\n loading: ['Chargement…', 'Loading…', 'A carregar…'],\n dialogLabel: [\n \"Vérification d'identité Naya ID\",\n 'Naya ID identity verification',\n 'Verificação de identidade Naya ID',\n ],\n\n // 1 · Bienvenue\n welcomeTitle: ['Vérifiez votre identité', 'Verify your identity', 'Verifique a sua identidade'],\n welcomeSubtitle: [\n \"Prêt en moins de 60 secondes.\\nMunissez-vous de votre pièce d'identité.\",\n 'Ready in under 60 seconds.\\nHave your ID document at hand.',\n 'Pronto em menos de 60 segundos.\\nTenha o seu documento de identidade à mão.',\n ],\n welcomeCta: ['Commencer', 'Get started', 'Começar'],\n welcomeOnMobile: ['Continuer sur mon téléphone', 'Continue on my phone', 'Continuar no meu telemóvel'],\n welcomeSecurity: [\n 'Vos données sont chiffrées et transmises de façon sécurisée',\n 'Your data is encrypted and transmitted securely',\n 'Os seus dados são cifrados e transmitidos com segurança',\n ],\n stepDocument: ['Document', 'Document', 'Documento'],\n stepSelfie: ['Selfie', 'Selfie', 'Selfie'],\n stepResult: ['Résultat', 'Result', 'Resultado'],\n\n // Navigateur non pris en charge\n unsupportedTitle: [\n 'Ouvrez cette page dans votre navigateur',\n 'Open this page in your browser',\n 'Abra esta página no seu navegador',\n ],\n unsupportedInApp: [\n \"L'application {name} n'autorise pas l'accès à la caméra. Copiez le lien et ouvrez-le dans Chrome ou Safari.\",\n 'The {name} app does not allow camera access. Copy the link and open it in Chrome or Safari.',\n 'A aplicação {name} não permite o acesso à câmara. Copie a ligação e abra-a no Chrome ou no Safari.',\n ],\n unsupportedBrowserTitle: [\n 'Navigateur non pris en charge',\n 'Unsupported browser',\n 'Navegador não suportado',\n ],\n unsupportedBrowser: [\n 'Ce navigateur ne permet pas la capture vidéo nécessaire à la vérification. Utilisez une version récente de Chrome, Safari, Firefox ou Edge.',\n 'This browser cannot capture video, which the verification requires. Use a recent version of Chrome, Safari, Firefox or Edge.',\n 'Este navegador não permite a captura de vídeo necessária à verificação. Utilize uma versão recente do Chrome, Safari, Firefox ou Edge.',\n ],\n unsupportedInsecure: [\n 'La caméra exige une page sécurisée (https). Contactez le service qui vous a envoyé ce lien.',\n 'The camera requires a secure page (https). Contact the service that sent you this link.',\n 'A câmara exige uma página segura (https). Contacte o serviço que lhe enviou esta ligação.',\n ],\n\n // Consentement\n consentTitle: ['Votre accord', 'Your consent', 'O seu consentimento'],\n consentBody: [\n \"Pour vérifier votre identité, nous allons photographier votre pièce d'identité et votre visage, puis les comparer. Ces données biométriques sont traitées par Naya ID pour le compte de {org}, uniquement à cette fin, et conservées selon sa politique de confidentialité.\",\n 'To verify your identity we will photograph your ID document and your face, then compare them. This biometric data is processed by Naya ID on behalf of {org}, for this purpose only, and kept according to its privacy policy.',\n 'Para verificar a sua identidade, vamos fotografar o seu documento de identidade e o seu rosto, e depois compará-los. Estes dados biométricos são tratados pela Naya ID em nome de {org}, apenas para este fim, e conservados segundo a sua política de privacidade.',\n ],\n consentCheckbox: [\n \"J'accepte le traitement de mes données biométriques pour vérifier mon identité.\",\n 'I agree to the processing of my biometric data to verify my identity.',\n 'Aceito o tratamento dos meus dados biométricos para verificar a minha identidade.',\n ],\n consentPolicy: ['Politique de confidentialité', 'Privacy policy', 'Política de privacidade'],\n consentCta: [\"J'accepte et je continue\", 'I agree and continue', 'Aceito e continuo'],\n consentOrg: ['ce service', 'this service', 'este serviço'],\n\n // Relais vers mobile\n handoffTitle: ['Continuez sur votre téléphone', 'Continue on your phone', 'Continue no seu telemóvel'],\n handoffBody: [\n \"Scannez ce code avec l'appareil photo de votre téléphone : la vérification s'y poursuit, avec une meilleure caméra. Cette page se mettra à jour toute seule.\",\n 'Scan this code with your phone camera: the verification continues there, with a better camera. This page will update by itself.',\n 'Leia este código com a câmara do seu telemóvel: a verificação continua aí, com uma câmara melhor. Esta página atualiza-se sozinha.',\n ],\n handoffWaiting: ['En attente du téléphone…', 'Waiting for the phone…', 'À espera do telemóvel…'],\n handoffProgress: [\n 'Vérification en cours sur le téléphone',\n 'Verification in progress on the phone',\n 'Verificação em curso no telemóvel',\n ],\n handoffOrHere: [\n 'Ou continuer sur cet appareil',\n 'Or continue on this device',\n 'Ou continuar neste dispositivo',\n ],\n handoffExpired: [\n 'Le code a expiré. Relancez la vérification.',\n 'The code has expired. Start the verification again.',\n 'O código expirou. Reinicie a verificação.',\n ],\n handoffQrLabel: [\n 'QR code à scanner avec un téléphone',\n 'QR code to scan with a phone',\n 'Código QR para ler com um telemóvel',\n ],\n\n // 2 · Choix du document\n docSelectTitle: [\n 'Quel document\\navez-vous ?',\n 'Which document\\ndo you have?',\n 'Que documento\\ntem consigo?',\n ],\n docSelectSubtitle: [\n 'Choisissez votre pays et votre pièce.',\n 'Choose your country and your document.',\n 'Escolha o seu país e o seu documento.',\n ],\n countryLabel: ['Pays', 'Country', 'País'],\n docCni: [\"Carte nationale d'identité\", 'National ID card', 'Cartão nacional de identidade'],\n docPasseport: ['Passeport', 'Passport', 'Passaporte'],\n docPermis: ['Permis de conduire', \"Driver's licence\", 'Carta de condução'],\n\n // Conseils\n tipsDocTitle: ['Avant de photographier', 'Before you take the photo', 'Antes de fotografar'],\n tipsDoc1: [\n 'Posez le document à plat sur une surface sombre et unie.',\n 'Lay the document flat on a dark, plain surface.',\n 'Coloque o documento sobre uma superfície escura e lisa.',\n ],\n tipsDoc2: [\n 'Évitez les reflets : pas de flash, pas de lumière directe.',\n 'Avoid glare: no flash, no direct light.',\n 'Evite reflexos: sem flash, sem luz direta.',\n ],\n tipsDoc3: [\n 'Retirez la pochette plastique, cadrez les quatre coins.',\n 'Remove the plastic sleeve and frame all four corners.',\n 'Retire a capa de plástico e enquadre os quatro cantos.',\n ],\n tipsSelfieTitle: ['Pour le selfie', 'For the selfie', 'Para a selfie'],\n tipsSelfie1: [\n 'Placez-vous face à une source de lumière, pas dos à une fenêtre.',\n 'Face a light source, not a window behind you.',\n 'Fique de frente para a luz, não de costas para uma janela.',\n ],\n tipsSelfie2: [\n 'Retirez lunettes de soleil, casquette et masque.',\n 'Remove sunglasses, cap and mask.',\n 'Retire óculos de sol, boné e máscara.',\n ],\n tipsSelfie3: [\n \"Suivez les consignes à l'écran : elles changent à chaque fois.\",\n 'Follow the on-screen prompts: they change every time.',\n 'Siga as instruções no ecrã: mudam de cada vez.',\n ],\n\n // 3-4 · Capture\n captureRectoInstruction: [\n 'Placez le recto de votre document dans le cadre',\n 'Place the front of your document within the frame',\n 'Coloque a frente do documento dentro da moldura',\n ],\n captureVersoInstruction: [\n 'Retournez le document : le verso maintenant',\n 'Flip the document: now the back',\n 'Vire o documento: agora o verso',\n ],\n captureHint: [\n 'Alignez le document, la photo se prend toute seule',\n 'Align the document, the photo is taken automatically',\n 'Alinhe o documento, a foto é tirada automaticamente',\n ],\n captureManualHint: [\n 'Alignez le document puis appuyez sur le déclencheur',\n 'Align the document then press the shutter',\n 'Alinhe o documento e prima o botão',\n ],\n captureReady: ['Ne bougez plus…', 'Hold still…', 'Não se mexa…'],\n captureAuto: ['Capture dans {n}', 'Capturing in {n}', 'Captura em {n}'],\n qualityLight: ['Lumière', 'Light', 'Luz'],\n qualitySharpness: ['Netteté', 'Sharpness', 'Nitidez'],\n guideTooDark: [\n \"Trop sombre : rapprochez-vous d'une lumière\",\n 'Too dark: move closer to a light',\n 'Demasiado escuro: aproxime-se de uma luz',\n ],\n guideTooBright: [\n 'Trop de lumière : éloignez-vous de la source',\n 'Too bright: move away from the light',\n 'Demasiada luz: afaste-se da fonte',\n ],\n guideGlare: [\n 'Reflet détecté : inclinez légèrement le document',\n 'Glare detected: tilt the document slightly',\n 'Reflexo detetado: incline ligeiramente o documento',\n ],\n guideBlurry: [\n 'Image floue : stabilisez et faites la mise au point',\n 'Blurry: hold steady and let the camera focus',\n 'Imagem desfocada: estabilize e deixe focar',\n ],\n guideHoldSteady: [\"Tenez l'appareil immobile\", 'Hold the device still', 'Mantenha o dispositivo imóvel'],\n guideGood: ['Parfait, ne bougez plus', 'Perfect, hold still', 'Perfeito, não se mexa'],\n importPhoto: ['Importer une photo', 'Import a photo', 'Importar uma foto'],\n switchCamera: ['Changer de caméra', 'Switch camera', 'Mudar de câmara'],\n torch: ['Lampe', 'Torch', 'Lanterna'],\n shutterLabel: ['Prendre la photo', 'Take the photo', 'Tirar a foto'],\n fileInvalid: [\n \"Ce fichier n'est pas une image lisible.\",\n 'This file is not a readable image.',\n 'Este ficheiro não é uma imagem legível.',\n ],\n cameraDenied: [\n 'Accès à la caméra refusé. Autorisez la caméra dans les réglages du navigateur, puis réessayez.',\n 'Camera access denied. Allow the camera in your browser settings, then try again.',\n 'Acesso à câmara recusado. Autorize a câmara nas definições do navegador e tente novamente.',\n ],\n cameraUnavailable: [\n 'Aucune caméra détectée sur cet appareil.',\n 'No camera detected on this device.',\n 'Nenhuma câmara detetada neste dispositivo.',\n ],\n cameraBusy: [\n 'La caméra est utilisée par une autre application. Fermez-la puis réessayez.',\n 'The camera is in use by another app. Close it and try again.',\n 'A câmara está a ser usada por outra aplicação. Feche-a e tente novamente.',\n ],\n cameraGeneric: [\n 'Impossible de démarrer la caméra.',\n 'Unable to start the camera.',\n 'Não foi possível iniciar a câmara.',\n ],\n\n // 5 · Vivacité\n livenessTitle: ['À vous maintenant', 'Your turn now', 'Agora é a sua vez'],\n livenessSubtitle: [\n \"Placez votre visage dans l'ovale et suivez les consignes.\",\n 'Place your face in the oval and follow the prompts.',\n 'Coloque o rosto na oval e siga as instruções.',\n ],\n livenessLoading: ['Préparation de la caméra…', 'Preparing the camera…', 'A preparar a câmara…'],\n livenessLookStraight: ['Regardez droit devant vous', 'Look straight ahead', 'Olhe em frente'],\n livenessBlink: ['Clignez des yeux', 'Blink your eyes', 'Pisque os olhos'],\n livenessTurnLeft: [\n 'Tournez la tête vers la gauche',\n 'Turn your head to the left',\n 'Vire a cabeça para a esquerda',\n ],\n livenessTurnRight: [\n 'Tournez la tête vers la droite',\n 'Turn your head to the right',\n 'Vire a cabeça para a direita',\n ],\n livenessSmile: ['Souriez', 'Smile', 'Sorria'],\n livenessHold: ['Ne bougez plus…', 'Hold still…', 'Não se mexa…'],\n livenessStraighten: [\n 'Redressez la tête et regardez l’objectif',\n 'Straighten your head and look at the camera',\n 'Endireite a cabeça e olhe para a câmara',\n ],\n livenessEyesOpen: ['Gardez les yeux ouverts', 'Keep your eyes open', 'Mantenha os olhos abertos'],\n livenessDetected: ['Détecté', 'Detected', 'Detetado'],\n livenessStepFace: ['Visage', 'Face', 'Rosto'],\n livenessCenter: [\n \"Centrez votre visage dans l'ovale\",\n 'Centre your face in the oval',\n 'Centre o rosto na oval',\n ],\n livenessCloser: ['Rapprochez-vous', 'Move closer', 'Aproxime-se'],\n livenessFarther: ['Éloignez-vous un peu', 'Move back a little', 'Afaste-se um pouco'],\n livenessOneFace: [\n 'Une seule personne dans le cadre',\n 'Only one person in the frame',\n 'Apenas uma pessoa no enquadramento',\n ],\n livenessPrivacy: [\n 'Analyse effectuée sur votre appareil. Seule la photo finale est transmise.',\n 'Analysis runs on your device. Only the final photo is sent.',\n 'A análise é feita no seu dispositivo. Só a foto final é enviada.',\n ],\n livenessTimeoutTitle: ['On recommence ?', 'Shall we try again?', 'Tentamos de novo?'],\n livenessTimeoutBody: [\n \"Le geste n'a pas été reconnu. Placez-vous face à la lumière, retirez lunettes et casquette, et gardez le visage dans l'ovale.\",\n 'The gesture was not recognised. Face the light, remove glasses and cap, and keep your face in the oval.',\n 'O gesto não foi reconhecido. Fique de frente para a luz, retire óculos e boné, e mantenha o rosto na oval.',\n ],\n livenessPassiveCta: [\n 'Je ne peux pas faire ce geste',\n \"I can't make this gesture\",\n 'Não consigo fazer este gesto',\n ],\n livenessPassiveNote: [\n 'Sans le geste, votre dossier sera examiné par une personne : cela peut prendre plus de temps.',\n 'Without the gesture, a person will review your file: this may take longer.',\n 'Sem o gesto, o seu processo será analisado por uma pessoa: pode demorar mais.',\n ],\n livenessAssetsError: [\n 'Impossible de charger le module de détection. Vérifiez votre connexion puis réessayez.',\n 'Unable to load the detection module. Check your connection and try again.',\n 'Não foi possível carregar o módulo de deteção. Verifique a sua ligação e tente novamente.',\n ],\n\n // Confirmation OCR\n ocrTitle: ['Vérifiez vos informations', 'Check your details', 'Verifique os seus dados'],\n ocrSubtitle: [\n 'Corrigez ce qui a été mal lu sur le document.',\n 'Correct anything misread from the document.',\n 'Corrija o que foi mal lido no documento.',\n ],\n ocrReadSubtitle: [\n 'Voici ce que nous avons lu sur votre document.',\n 'Here is what we read on your document.',\n 'Eis o que lemos no seu documento.',\n ],\n ocrQuestion: [\n 'Ces informations sont-elles exactes ?',\n 'Is this information correct?',\n 'Estas informações estão corretas?',\n ],\n ocrYes: ['Oui, c’est exact', 'Yes, it is correct', 'Sim, está correto'],\n ocrNo: ['Non, il y a une erreur', 'No, there is a mistake', 'Não, há um erro'],\n ocrEmptyValue: ['Non lu', 'Not read', 'Não lido'],\n ocrWaiting: ['Lecture du document en cours…', 'Reading the document…', 'A ler o documento…'],\n ocrNone: [\n \"Nous n'avons pas pu lire le document. Renseignez vos informations.\",\n 'We could not read the document. Enter your details.',\n 'Não conseguimos ler o documento. Introduza os seus dados.',\n ],\n ocrLastName: ['Nom', 'Last name', 'Apelido'],\n ocrFirstName: ['Prénom(s)', 'First name(s)', 'Nome(s) próprio(s)'],\n ocrDateOfBirth: ['Date de naissance', 'Date of birth', 'Data de nascimento'],\n ocrPlaceOfBirth: ['Lieu de naissance', 'Place of birth', 'Local de nascimento'],\n ocrDocumentNumber: ['Numéro du document', 'Document number', 'Número do documento'],\n ocrExpirationDate: [\"Date d'expiration\", 'Expiry date', 'Data de validade'],\n ocrNationality: ['Nationalité', 'Nationality', 'Nacionalidade'],\n ocrGender: ['Sexe', 'Sex', 'Sexo'],\n ocrGenderM: ['Masculin', 'Male', 'Masculino'],\n ocrGenderF: ['Féminin', 'Female', 'Feminino'],\n ocrDateFormat: [\n 'Format attendu : AAAA-MM-JJ',\n 'Expected format: YYYY-MM-DD',\n 'Formato esperado: AAAA-MM-DD',\n ],\n ocrExpired: [\n 'Ce document est expiré : la vérification sera refusée.',\n 'This document has expired: the verification will be refused.',\n 'Este documento está expirado: a verificação será recusada.',\n ],\n ocrDobInvalid: ['Date de naissance invalide.', 'Invalid date of birth.', 'Data de nascimento inválida.'],\n ocrRequired: ['Champ requis', 'Required', 'Obrigatório'],\n\n // 6 · Traitement\n processingDocument: ['Analyse du document', 'Document analysis', 'Análise do documento'],\n processingFace: ['Comparaison du visage', 'Face comparison', 'Comparação do rosto'],\n processingCompliance: ['Contrôles de conformité', 'Compliance checks', 'Controlos de conformidade'],\n processingDecision: ['Décision', 'Decision', 'Decisão'],\n processingWait: [\n \"Cela prend généralement moins d'une minute.\",\n 'This usually takes under a minute.',\n 'Normalmente demora menos de um minuto.',\n ],\n processingLong: [\n 'Cela prend un peu plus de temps que prévu, merci de patienter.',\n 'This is taking a little longer than expected, please wait.',\n 'Está a demorar um pouco mais do que o previsto, aguarde.',\n ],\n\n // 7 · Résultat\n resultApprovedTitle: ['Identité vérifiée', 'Identity verified', 'Identidade verificada'],\n resultApprovedSubtitle: [\n 'Merci, tout est en ordre.',\n 'Thank you, everything is in order.',\n 'Obrigado, está tudo em ordem.',\n ],\n resultReviewTitle: [\n \"Vérification en cours d'examen\",\n 'Verification under review',\n 'Verificação em análise',\n ],\n resultReviewSubtitle: [\n 'Une personne va examiner votre dossier.',\n 'A person will review your file.',\n 'Uma pessoa vai analisar o seu processo.',\n ],\n resultReviewB1: [\n \"Vous n'avez rien d'autre à faire.\",\n 'There is nothing else for you to do.',\n 'Não tem mais nada a fazer.',\n ],\n resultReviewB2: [\n 'Le service qui vous a envoyé ici vous préviendra.',\n 'The service that sent you here will let you know.',\n 'O serviço que o enviou aqui irá avisá-lo.',\n ],\n resultReviewB3: [\n \"Délai habituel : moins d'un jour ouvré.\",\n 'Usual delay: under one working day.',\n 'Prazo habitual: menos de um dia útil.',\n ],\n resultRejectedTitle: ['Vérification refusée', 'Verification refused', 'Verificação recusada'],\n resultRejectedReason: ['Motif', 'Reason', 'Motivo'],\n resultName: ['Nom', 'Name', 'Nome'],\n resultReference: ['Référence', 'Reference', 'Referência'],\n resultWhatNext: ['Que faire ?', 'What now?', 'O que fazer?'],\n\n // Motifs de décision (codes serveur)\n reason_DOC_EXPIRED: [\n \"Votre pièce d'identité est expirée. Recommencez avec un document valide.\",\n 'Your ID document has expired. Try again with a valid document.',\n 'O seu documento de identidade está expirado. Tente novamente com um documento válido.',\n ],\n reason_DOC_INCONSISTENT: [\n \"Le document n'a pas pu être lu correctement. Recommencez avec une photo nette, sans reflet.\",\n 'The document could not be read properly. Try again with a sharp, glare-free photo.',\n 'O documento não pôde ser lido corretamente. Tente novamente com uma foto nítida, sem reflexos.',\n ],\n reason_FACE_MISMATCH: [\n 'Le selfie ne correspond pas à la photo du document.',\n 'The selfie does not match the photo on the document.',\n 'A selfie não corresponde à foto do documento.',\n ],\n reason_FACE_LOW_CONFIDENCE: [\n \"La ressemblance avec la photo du document n'est pas assez nette pour décider automatiquement.\",\n 'The likeness to the document photo is not clear enough to decide automatically.',\n 'A semelhança com a foto do documento não é suficiente para decidir automaticamente.',\n ],\n reason_FACE_NOT_COMPARED: [\n \"Le visage du document n'a pas pu être comparé au selfie.\",\n 'The face on the document could not be compared with the selfie.',\n 'O rosto do documento não pôde ser comparado com a selfie.',\n ],\n reason_LIVENESS_NOT_EVALUATED: [\n \"La vivacité n'a pas pu être évaluée automatiquement.\",\n 'Liveness could not be evaluated automatically.',\n 'A vivacidade não pôde ser avaliada automaticamente.',\n ],\n reason_LIVENESS_LOW: [\n \"Le selfie ressemble à une photo d'écran ou d'impression.\",\n 'The selfie looks like a photo of a screen or a print.',\n 'A selfie parece uma foto de um ecrã ou de uma impressão.',\n ],\n reason_LIVENESS_PASSIVE: [\n 'Le parcours a été fait sans le geste de vivacité.',\n 'The flow was completed without the liveness gesture.',\n 'O percurso foi feito sem o gesto de vivacidade.',\n ],\n reason_LIVENESS_CHALLENGE_INVALID: [\n \"Les gestes demandés n'ont pas été reconnus dans le bon ordre.\",\n 'The requested gestures were not recognised in the right order.',\n 'Os gestos pedidos não foram reconhecidos pela ordem certa.',\n ],\n reason_AML_SANCTION: [\n 'Un contrôle réglementaire complémentaire est nécessaire.',\n 'An additional regulatory check is required.',\n 'É necessário um controlo regulamentar adicional.',\n ],\n reason_AML_PEP: [\n 'Un contrôle réglementaire complémentaire est nécessaire.',\n 'An additional regulatory check is required.',\n 'É necessário um controlo regulamentar adicional.',\n ],\n reason_SCORE_BELOW_THRESHOLD: [\n 'La qualité globale des éléments est insuffisante pour une décision automatique.',\n 'The overall quality of the evidence is insufficient for an automatic decision.',\n 'A qualidade global dos elementos é insuficiente para uma decisão automática.',\n ],\n reason_DECLARED_MISMATCH: [\n 'Les informations déclarées diffèrent de celles lues sur le document.',\n 'The declared information differs from what was read on the document.',\n 'As informações declaradas diferem das lidas no documento.',\n ],\n reason_DATA_DISPUTED: [\n 'Vous avez signalé une erreur dans les informations lues.',\n 'You reported an error in the information read.',\n 'Assinalou um erro nas informações lidas.',\n ],\n reason_AUTO_APPROVED: ['Approbation automatique.', 'Automatic approval.', 'Aprovação automática.'],\n reason_SIMULATED: [\n 'Résultat simulé (clé de test).',\n 'Simulated result (test key).',\n 'Resultado simulado (chave de teste).',\n ],\n\n // Erreurs\n errorTitle: ['Une erreur est survenue', 'Something went wrong', 'Ocorreu um erro'],\n errorRef: ['Référence : {id}', 'Reference: {id}', 'Referência: {id}'],\n error_network: [\n \"Impossible de joindre le service de vérification. Vérifiez votre connexion, ou que votre réseau n'en bloque pas l'accès.\",\n 'Unable to reach the verification service. Check your connection, or whether your network blocks it.',\n 'Não foi possível contactar o serviço de verificação. Verifique a sua ligação ou se a rede o bloqueia.',\n ],\n error_timeout: [\n 'Le serveur met trop de temps à répondre. Réessayez.',\n 'The server is taking too long to respond. Try again.',\n 'O servidor está a demorar demasiado a responder. Tente novamente.',\n ],\n error_unauthorized: [\n 'Accès refusé : clé ou session invalide.',\n 'Access denied: invalid key or session.',\n 'Acesso recusado: chave ou sessão inválida.',\n ],\n error_origin_not_allowed: [\n \"Cette page n'est pas autorisée à utiliser ce service.\",\n 'This page is not allowed to use this service.',\n 'Esta página não está autorizada a utilizar este serviço.',\n ],\n error_session_expired: [\n 'La session a expiré. Relancez la vérification.',\n 'The session has expired. Start the verification again.',\n 'A sessão expirou. Reinicie a verificação.',\n ],\n error_session_closed: [\n 'Cette vérification est déjà terminée.',\n 'This verification is already complete.',\n 'Esta verificação já está concluída.',\n ],\n error_quota: [\n 'Le service est temporairement indisponible pour cet organisme.',\n 'The service is temporarily unavailable for this organisation.',\n 'O serviço está temporariamente indisponível para esta organização.',\n ],\n error_kyb_pending: [\n \"Le service n'est pas encore activé pour cet organisme.\",\n 'The service is not yet enabled for this organisation.',\n 'O serviço ainda não está ativo para esta organização.',\n ],\n error_rate_limited: [\n 'Trop de tentatives. Patientez une minute puis réessayez.',\n 'Too many attempts. Wait a minute and try again.',\n 'Demasiadas tentativas. Aguarde um minuto e tente novamente.',\n ],\n error_upload_limit: [\n \"Nombre maximal d'essais atteint pour cette vérification.\",\n 'Maximum number of attempts reached for this verification.',\n 'Número máximo de tentativas atingido para esta verificação.',\n ],\n error_bad_request: ['Requête invalide.', 'Invalid request.', 'Pedido inválido.'],\n error_server: [\n 'Le service rencontre un problème. Réessayez dans un instant.',\n 'The service is having a problem. Try again shortly.',\n 'O serviço está com um problema. Tente novamente daqui a pouco.',\n ],\n error_camera_denied: ['Accès à la caméra refusé.', 'Camera access denied.', 'Acesso à câmara recusado.'],\n error_camera_unavailable: [\n 'Aucune caméra disponible.',\n 'No camera available.',\n 'Nenhuma câmara disponível.',\n ],\n error_camera_busy: [\n 'Caméra déjà utilisée par une autre application.',\n 'Camera already in use by another app.',\n 'Câmara já em uso por outra aplicação.',\n ],\n error_liveness_assets: [\n 'Module de détection indisponible.',\n 'Detection module unavailable.',\n 'Módulo de deteção indisponível.',\n ],\n error_unsupported_browser: [\n 'Navigateur non pris en charge.',\n 'Unsupported browser.',\n 'Navegador não suportado.',\n ],\n error_in_app_browser: [\n 'Ouvrez cette page dans votre navigateur.',\n 'Open this page in your browser.',\n 'Abra esta página no seu navegador.',\n ],\n error_insecure_context: [\n 'Cette page doit être servie en https.',\n 'This page must be served over https.',\n 'Esta página deve ser servida em https.',\n ],\n error_invalid_params: [\n 'Configuration du SDK invalide.',\n 'Invalid SDK configuration.',\n 'Configuração do SDK inválida.',\n ],\n error_unknown: ['Erreur inconnue.', 'Unknown error.', 'Erro desconhecido.'],\n} as const satisfies Record<string, Tri>;\n\nexport type StringKey = keyof typeof DICT;\n\nconst LOCALE_INDEX: Record<NayaLocale, 0 | 1 | 2> = { fr: 0, en: 1, pt: 2 };\n\nexport class NayaStrings {\n constructor(\n readonly locale: NayaLocale,\n private readonly overrides: Partial<Record<string, string>> = {},\n ) {}\n\n /** Chaîne localisée, surcharge hôte prioritaire, `{param}` interpolés. */\n t(key: StringKey, params?: Record<string, string | number>): string {\n let s = this.overrides[key] ?? DICT[key][LOCALE_INDEX[this.locale]];\n if (params) {\n for (const [k, v] of Object.entries(params)) s = s.split(`{${k}}`).join(String(v));\n }\n return s;\n }\n\n has(key: string): key is StringKey {\n return Object.prototype.hasOwnProperty.call(DICT, key);\n }\n\n docLabel(doc: NayaDocumentType): string {\n return this.t(doc === 'cni' ? 'docCni' : doc === 'passeport' ? 'docPasseport' : 'docPermis');\n }\n\n /** Message utilisateur d'un motif de décision serveur, ou null s'il est inconnu. */\n reason(code: string): string | null {\n const key = `reason_${code}`;\n return this.has(key) ? this.t(key) : null;\n }\n\n errorMessage(code: NayaErrorCode): string {\n const key = `error_${code}`;\n return this.has(key) ? this.t(key) : this.t('error_unknown');\n }\n\n challengeInstruction(step: string): string {\n switch (step) {\n case 'blink':\n return this.t('livenessBlink');\n case 'turn-left':\n return this.t('livenessTurnLeft');\n case 'turn-right':\n return this.t('livenessTurnRight');\n case 'smile':\n return this.t('livenessSmile');\n default:\n return this.t('livenessLookStraight');\n }\n }\n}\n","import type { NayaErrorCode } from '../models/result';\n\n/**\n * Détection des capacités du navigateur, avant d'ouvrir l'interface : mieux\n * vaut refuser proprement avec la raison que d'échouer au moment du selfie.\n */\nexport interface NayaSupport {\n ok: boolean;\n code?: NayaErrorCode;\n reason?: string;\n secureContext: boolean;\n mediaDevices: boolean;\n webAssembly: boolean;\n webGL: boolean;\n inAppBrowser: boolean;\n inAppBrowserName: string | null;\n mobile: boolean;\n ios: boolean;\n android: boolean;\n /** Classe d'appareil rapportée à la télémétrie : `mobile` | `tablet` | `desktop`. */\n deviceClass: 'mobile' | 'tablet' | 'desktop';\n}\n\nconst IN_APP_PATTERNS: Array<[RegExp, string]> = [\n [/FBAN|FBAV|FB_IAB|FB4A|FBIOS/i, 'Facebook'],\n [/Instagram/i, 'Instagram'],\n [/Messenger|FBMD/i, 'Messenger'],\n [/WhatsApp/i, 'WhatsApp'],\n [/Twitter|TwitterAndroid/i, 'X'],\n [/LinkedInApp/i, 'LinkedIn'],\n [/Snapchat/i, 'Snapchat'],\n [/TikTok|musical_ly|BytedanceWebview/i, 'TikTok'],\n [/Line\\//i, 'LINE'],\n [/MicroMessenger/i, 'WeChat'],\n [/GSA\\//i, 'Google'],\n];\n\nexport function detectInAppBrowser(ua: string): string | null {\n for (const [re, name] of IN_APP_PATTERNS) if (re.test(ua)) return name;\n // WebView Android générique (Chrome « ; wv »).\n if (/; wv\\)/.test(ua) && /Android/i.test(ua)) return 'WebView';\n return null;\n}\n\nexport function detectSupport(\n ua: string = typeof navigator !== 'undefined' ? navigator.userAgent : '',\n): NayaSupport {\n const hasWindow = typeof window !== 'undefined';\n const secureContext = hasWindow ? window.isSecureContext !== false : false;\n const mediaDevices = typeof navigator !== 'undefined' && !!navigator.mediaDevices?.getUserMedia;\n const webAssembly = typeof WebAssembly === 'object' && typeof WebAssembly.instantiate === 'function';\n let webGL = false;\n try {\n if (typeof document !== 'undefined') {\n const c = document.createElement('canvas');\n webGL = !!(c.getContext('webgl2') || c.getContext('webgl'));\n }\n } catch {\n webGL = false;\n }\n const ios =\n /iPhone|iPad|iPod/i.test(ua) ||\n (typeof navigator !== 'undefined' &&\n navigator.platform === 'MacIntel' &&\n (navigator as any).maxTouchPoints > 1);\n const android = /Android/i.test(ua);\n const tablet = /iPad|Tablet|(Android(?!.*Mobile))/i.test(ua) || (ios && !/iPhone|iPod/i.test(ua));\n const mobile = ios || android || /Mobile|webOS|BlackBerry|Opera Mini/i.test(ua);\n const inAppBrowserName = detectInAppBrowser(ua);\n\n const base = {\n secureContext,\n mediaDevices,\n webAssembly,\n webGL,\n inAppBrowser: !!inAppBrowserName,\n inAppBrowserName,\n mobile,\n ios,\n android,\n deviceClass: (tablet ? 'tablet' : mobile ? 'mobile' : 'desktop') as NayaSupport['deviceClass'],\n };\n\n if (!hasWindow || typeof document === 'undefined') {\n return { ...base, ok: false, code: 'unsupported_browser', reason: 'no-dom' };\n }\n if (!secureContext) {\n return { ...base, ok: false, code: 'insecure_context', reason: 'insecure-context' };\n }\n if (inAppBrowserName) {\n return { ...base, ok: false, code: 'in_app_browser', reason: inAppBrowserName };\n }\n if (!mediaDevices) {\n return { ...base, ok: false, code: 'unsupported_browser', reason: 'no-getusermedia' };\n }\n if (!webAssembly) {\n return { ...base, ok: false, code: 'unsupported_browser', reason: 'no-webassembly' };\n }\n return { ...base, ok: true };\n}\n\n/** Vrai si un `deviceId` de caméra arrière est présent (après autorisation seulement). */\nexport async function hasEnvironmentCamera(): Promise<boolean | null> {\n try {\n if (!navigator.mediaDevices?.enumerateDevices) return null;\n const devices = await navigator.mediaDevices.enumerateDevices();\n const cams = devices.filter((d) => d.kind === 'videoinput');\n if (cams.length === 0) return false;\n if (cams.some((d) => /back|rear|environment|arrière/i.test(d.label))) return true;\n // Labels vides tant que la permission n'est pas accordée : indéterminé.\n return cams.every((d) => !d.label) ? null : false;\n } catch {\n return null;\n }\n}\n","import type { NayaApiClient } from '../api/client';\nimport type { NayaLogger } from './log';\n\n/**\n * Télémétrie anonyme : entonnoir par étape, durées, erreurs, qualité de\n * capture, classe d'appareil. Jamais d'image ni de donnée personnelle — l'API\n * refuse d'ailleurs les clés suspectes. Envoi groupé, `keepalive` à la\n * fermeture pour ne pas perdre les derniers événements.\n */\nexport interface TelemetryEvent {\n event: string;\n at: string;\n data?: Record<string, string | number | boolean | null>;\n}\n\nconst FLUSH_INTERVAL_MS = 5_000;\nconst MAX_BATCH = 50;\n\nexport class Telemetry {\n private queue: TelemetryEvent[] = [];\n private timer: ReturnType<typeof setTimeout> | null = null;\n private readonly startedAt = performance.now();\n private stepStartedAt = performance.now();\n\n constructor(\n private readonly client: NayaApiClient,\n private readonly enabled: boolean,\n private readonly device: string,\n private readonly log: NayaLogger,\n ) {}\n\n /** Enregistre un événement ; les valeurs sont bornées par l'API. */\n track(event: string, data?: Record<string, string | number | boolean | null>): void {\n if (!this.enabled) return;\n this.queue.push({ event, at: new Date().toISOString(), data });\n if (this.queue.length >= MAX_BATCH) void this.flush();\n else if (!this.timer) this.timer = setTimeout(() => void this.flush(), FLUSH_INTERVAL_MS);\n }\n\n /** Durée depuis le dernier changement d'étape, puis remise à zéro. */\n stepDuration(): number {\n const now = performance.now();\n const d = Math.round(now - this.stepStartedAt);\n this.stepStartedAt = now;\n return d;\n }\n\n elapsed(): number {\n return Math.round(performance.now() - this.startedAt);\n }\n\n async flush(final = false): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n if (!this.enabled || this.queue.length === 0 || !this.client.canAuthenticate) return;\n const batch = this.queue.splice(0, MAX_BATCH);\n try {\n await this.client.sendEvents(batch, this.device, final);\n } catch (err) {\n this.log.debug('telemetry dropped', err);\n }\n }\n}\n","/** Journal de diagnostic, actif seulement avec `debug: true`. */\nexport interface NayaLogger {\n debug(message: string, data?: unknown): void;\n warn(message: string, data?: unknown): void;\n error(message: string, data?: unknown): void;\n}\n\nconst PREFIX = '[NayaId]';\n\nexport function createLogger(enabled: boolean): NayaLogger {\n const noop = (): void => {};\n if (!enabled) return { debug: noop, warn: noop, error: noop };\n return {\n debug: (m, d) => (d === undefined ? console.debug(PREFIX, m) : console.debug(PREFIX, m, d)),\n warn: (m, d) => (d === undefined ? console.warn(PREFIX, m) : console.warn(PREFIX, m, d)),\n error: (m, d) => (d === undefined ? console.error(PREFIX, m) : console.error(PREFIX, m, d)),\n };\n}\n","/** Retour haptique (Android, navigateurs qui l'exposent) ; silencieux ailleurs. */\nexport type HapticPattern = 'tap' | 'success' | 'error';\n\nconst PATTERNS: Record<HapticPattern, number | number[]> = {\n tap: 12,\n success: [18, 40, 18],\n error: [60, 40, 60],\n};\n\nexport function vibrate(pattern: HapticPattern, enabled = true): void {\n if (!enabled) return;\n try {\n if (typeof navigator !== 'undefined' && typeof navigator.vibrate === 'function') {\n navigator.vibrate(PATTERNS[pattern]);\n }\n } catch {\n // Certains navigateurs lèvent hors geste utilisateur : sans importance.\n }\n}\n","/** Indices sur la qualité du réseau, quand le navigateur les expose. */\nexport interface NetworkHint {\n /** `slow-2g` | `2g` | `3g` | `4g` | inconnu. */\n effectiveType: string | null;\n saveData: boolean;\n slow: boolean;\n}\n\nexport function networkHint(): NetworkHint {\n const conn = (\n typeof navigator !== 'undefined'\n ? ((navigator as any).connection ??\n (navigator as any).mozConnection ??\n (navigator as any).webkitConnection)\n : null\n ) as { effectiveType?: string; saveData?: boolean } | null;\n const effectiveType = conn?.effectiveType ?? null;\n const saveData = !!conn?.saveData;\n const slow = saveData || effectiveType === 'slow-2g' || effectiveType === '2g';\n return { effectiveType, saveData, slow };\n}\n","import type { NayaLivenessAssets } from '../models/config';\nimport type { FaceSignals } from './liveness-challenge';\n\n/**\n * Adaptateur de suivi facial sur MediaPipe Face Landmarker, chargé au runtime.\n *\n * Hébergement : par défaut le CDN Naya (versions épinglées, cache immuable,\n * un seul domaine à autoriser), avec repli automatique sur jsDelivr et Google\n * si celui-ci ne répond pas. Le modèle est téléchargé par le SDK, son\n * empreinte SHA-256 vérifiée, puis passé en mémoire au moteur : ce qui\n * s'exécute est ce qui a été validé.\n *\n * Signaux : clignement (blendshapes `eyeBlink*`), sourire (`mouthSmile*`),\n * lacet de la tête (matrice de transformation faciale, avec le rapport de\n * position du nez en secours et pour le signe), boîte du visage.\n */\n\nexport const MP_VERSION = '1.0.1';\nexport const NAYA_ASSET_BASE = 'https://sdk.naya.41devs.com/mediapipe';\nexport const MODEL_FILE = 'face_landmarker.task';\n/** SHA-256 de face_landmarker.task (float16/1), vérifié avant chargement. */\nexport const MODEL_SHA256 = '64184e229b263107bc2b804c6625db1341ff2bb731874b0bcc2fe6544e0bc9ff';\n\nconst PUBLIC_ESM = `https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@${MP_VERSION}/vision_bundle.mjs`;\nconst PUBLIC_WASM_BASE = `https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@${MP_VERSION}/wasm`;\nconst PUBLIC_MODEL =\n 'https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task';\n\n// Indices de landmarks (topologie 468 points de MediaPipe Face Mesh).\nconst NOSE_TIP = 1;\nconst FACE_LEFT_EDGE = 234;\nconst FACE_RIGHT_EDGE = 454;\nconst RIGHT_EYE_OUTER = 33;\nconst LEFT_EYE_OUTER = 263;\n\ninterface ResolvedAssets {\n esm: string[];\n wasm: string[];\n model: string[];\n modelSha256: string | null;\n}\n\n/** Ordonne les URL candidates : hôte configuré ou Naya, puis CDN publics. */\nexport function resolveAssetUrls(assets: NayaLivenessAssets = {}): ResolvedAssets {\n const fallback = assets.fallbackToPublicCdn ?? true;\n const nayaBase = `${NAYA_ASSET_BASE}/${MP_VERSION}`;\n const pick = (custom: string | undefined, naya: string, pub: string): string[] => {\n const list = [custom ?? naya];\n if (fallback && !list.includes(pub)) list.push(pub);\n return list;\n };\n return {\n esm: pick(assets.esmUrl, `${nayaBase}/vision_bundle.mjs`, PUBLIC_ESM),\n wasm: pick(assets.wasmBaseUrl, `${nayaBase}/wasm`, PUBLIC_WASM_BASE),\n model: pick(assets.modelUrl, `${nayaBase}/${MODEL_FILE}`, PUBLIC_MODEL),\n // Un modèle personnalisé n'a pas d'empreinte connue sauf si fournie.\n modelSha256:\n assets.modelSha256 === undefined ? (assets.modelUrl ? null : MODEL_SHA256) : assets.modelSha256,\n };\n}\n\nasync function firstThatWorks<T>(urls: string[], load: (url: string) => Promise<T>): Promise<T> {\n let lastError: unknown;\n for (const url of urls) {\n try {\n return await load(url);\n } catch (err) {\n lastError = err;\n }\n }\n throw lastError ?? new Error('no-asset-url');\n}\n\nasync function sha256Hex(buffer: ArrayBuffer): Promise<string | null> {\n try {\n if (!globalThis.crypto?.subtle) return null;\n const digest = await crypto.subtle.digest('SHA-256', buffer);\n return Array.from(new Uint8Array(digest))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n } catch {\n return null;\n }\n}\n\n// Caches de module : un seul téléchargement par page, partagé entre\n// préchargement et initialisation.\nconst moduleCache = new Map<string, Promise<any>>();\nconst modelCache = new Map<string, Promise<Uint8Array>>();\nconst filesetCache = new Map<string, Promise<any>>();\n\nfunction loadModule(url: string): Promise<any> {\n let p = moduleCache.get(url);\n if (!p) {\n // URL en variable : esbuild laisse l'`import()` en dynamique (non bundlé).\n p = import(/* @vite-ignore */ /* webpackIgnore: true */ url);\n p.catch(() => moduleCache.delete(url));\n moduleCache.set(url, p);\n }\n return p;\n}\n\nfunction loadModel(url: string, expectedSha: string | null): Promise<Uint8Array> {\n let p = modelCache.get(url);\n if (!p) {\n p = (async () => {\n const res = await fetch(url, { cache: 'force-cache' });\n if (!res.ok) throw new Error(`model:${res.status}`);\n const buf = await res.arrayBuffer();\n if (expectedSha) {\n const actual = await sha256Hex(buf);\n if (actual && actual !== expectedSha) throw new Error('model:integrity');\n }\n return new Uint8Array(buf);\n })();\n p.catch(() => modelCache.delete(url));\n modelCache.set(url, p);\n }\n return p;\n}\n\nfunction loadFileset(vision: any, base: string): Promise<any> {\n let p = filesetCache.get(base);\n if (!p) {\n p = vision.FilesetResolver.forVisionTasks(base);\n p!.catch(() => filesetCache.delete(base));\n filesetCache.set(base, p!);\n }\n return p!;\n}\n\nexport interface HeadPose {\n yaw: number;\n pitch: number;\n roll: number;\n}\n\n/**\n * Lacet, tangage et roulis (degrés) depuis la matrice de transformation\n * faciale 4×4, quelle que soit sa disposition (ligne- ou colonne-major).\n */\nexport function poseFromMatrix(\n m: { rows: number; columns: number; data: number[] } | undefined,\n): HeadPose | null {\n if (!m || m.rows !== 4 || m.columns !== 4 || m.data.length !== 16) return null;\n const d = m.data;\n // Ligne-major : la dernière ligne vaut [0,0,0,1] ; colonne-major : la\n // translation occupe d[12..14] et d[3], d[7], d[11] sont nuls.\n const rowMajor = Math.abs(d[12]!) + Math.abs(d[13]!) + Math.abs(d[14]!) < 1e-6;\n const r = (i: number, j: number): number => (rowMajor ? d[i * 4 + j]! : d[j * 4 + i]!);\n const r00 = r(0, 0);\n const r02 = r(0, 2);\n const r10 = r(1, 0);\n const r12 = r(1, 2);\n const r22 = r(2, 2);\n if (![r00, r02, r10, r12, r22].every(Number.isFinite)) return null;\n const deg = (v: number) => (v * 180) / Math.PI;\n return {\n yaw: deg(Math.atan2(r02, r22)),\n pitch: deg(Math.atan2(-r12, r22)),\n roll: deg(Math.atan2(r10, r00)),\n };\n}\n\n/** Yaw (degrés) depuis la matrice de transformation faciale 4×4. */\nexport function yawFromMatrix(\n m: { rows: number; columns: number; data: number[] } | undefined,\n): number | null {\n return poseFromMatrix(m)?.yaw ?? null;\n}\n\n/**\n * Roulis approché par la droite des coins externes des yeux, en degrés.\n * `aspect` = largeur/hauteur de la trame, pour corriger les coordonnées\n * normalisées.\n */\nexport function rollFromEyes(lm: Array<{ x: number; y: number }>, aspect = 1): number | null {\n const a = lm[RIGHT_EYE_OUTER];\n const b = lm[LEFT_EYE_OUTER];\n if (!a || !b) return null;\n const dx = (b.x - a.x) * aspect;\n const dy = b.y - a.y;\n if (Math.abs(dx) < 1e-4) return null;\n return (Math.atan2(dy, dx) * 180) / Math.PI;\n}\n\n/** Yaw approché par la position du nez entre les bords du visage (signe : + = gauche de l'utilisateur). */\nexport function yawFromNose(lm: Array<{ x: number; y: number }>): number | null {\n const nose = lm[NOSE_TIP];\n const left = lm[FACE_LEFT_EDGE];\n const right = lm[FACE_RIGHT_EDGE];\n if (!nose || !left || !right) return null;\n const span = right.x - left.x;\n if (Math.abs(span) < 1e-4) return null;\n const ratio = (nose.x - left.x) / span;\n // ±0,1 d'écart ≈ ±16° (seuil du défi).\n return (ratio - 0.5) * 160;\n}\n\nexport class FaceTracker {\n private landmarker: any = null;\n private vision: any = null;\n private delegate: 'GPU' | 'CPU' | null = null;\n\n /**\n * Précharge module, WASM et modèle sans créer le moteur — à lancer pendant\n * la capture du document pour que le selfie démarre sans attente.\n */\n static async preload(assets: NayaLivenessAssets = {}): Promise<void> {\n const r = resolveAssetUrls(assets);\n const vision = await firstThatWorks(r.esm, loadModule);\n await Promise.all([\n firstThatWorks(r.wasm, (base) => loadFileset(vision, base)),\n firstThatWorks(r.model, (url) => loadModel(url, r.modelSha256)),\n ]);\n }\n\n /** Charge le module et le modèle, GPU d'abord puis CPU en repli. */\n async init(assets: NayaLivenessAssets = {}): Promise<void> {\n const r = resolveAssetUrls(assets);\n this.vision = await firstThatWorks(r.esm, loadModule);\n const { FaceLandmarker } = this.vision;\n const [fileset, model] = await Promise.all([\n firstThatWorks(r.wasm, (base) => loadFileset(this.vision, base)),\n firstThatWorks(r.model, (url) => loadModel(url, r.modelSha256)),\n ]);\n\n const create = (delegate: 'GPU' | 'CPU') =>\n FaceLandmarker.createFromOptions(fileset, {\n baseOptions: { modelAssetBuffer: model, delegate },\n runningMode: 'VIDEO',\n numFaces: 2,\n outputFaceBlendshapes: true,\n outputFacialTransformationMatrixes: true,\n });\n\n try {\n this.landmarker = await create('GPU');\n this.delegate = 'GPU';\n } catch {\n this.landmarker = await create('CPU');\n this.delegate = 'CPU';\n }\n }\n\n get ready(): boolean {\n return !!this.landmarker;\n }\n\n get activeDelegate(): 'GPU' | 'CPU' | null {\n return this.delegate;\n }\n\n /** Analyse une trame vidéo et renvoie les signaux normalisés du défi. */\n detect(video: HTMLVideoElement, timestampMs: number): FaceSignals {\n const none: FaceSignals = {\n faceCount: 0,\n leftEyeOpen: null,\n rightEyeOpen: null,\n yawDegrees: null,\n rollDegrees: null,\n pitchDegrees: null,\n smile: null,\n box: null,\n };\n if (!this.landmarker || video.videoWidth < 8) return none;\n\n const result = this.landmarker.detectForVideo(video, timestampMs);\n const faces: Array<Array<{ x: number; y: number }>> = result.faceLandmarks ?? [];\n const faceCount = faces.length;\n if (faceCount !== 1) return { ...none, faceCount };\n\n const lm = faces[0]!;\n\n // ── Blendshapes : clignement et sourire ───────────────────────────────\n let leftEyeOpen: number | null = null;\n let rightEyeOpen: number | null = null;\n let smileL: number | null = null;\n let smileR: number | null = null;\n const shapes = result.faceBlendshapes?.[0]?.categories as\n Array<{ categoryName: string; score: number }> | undefined;\n if (shapes) {\n for (const c of shapes) {\n switch (c.categoryName) {\n case 'eyeBlinkLeft':\n leftEyeOpen = 1 - c.score;\n break;\n case 'eyeBlinkRight':\n rightEyeOpen = 1 - c.score;\n break;\n case 'mouthSmileLeft':\n smileL = c.score;\n break;\n case 'mouthSmileRight':\n smileR = c.score;\n break;\n }\n }\n }\n const smile = smileL != null && smileR != null ? (smileL + smileR) / 2 : null;\n\n // ── Lacet : magnitude par la matrice, signe par le nez ────────────────\n const noseYaw = yawFromNose(lm);\n const pose = poseFromMatrix(result.facialTransformationMatrixes?.[0]);\n const matrixYaw = pose?.yaw ?? null;\n let yawDegrees: number | null = noseYaw;\n if (matrixYaw != null && noseYaw != null) {\n const sign = noseYaw === 0 ? Math.sign(matrixYaw) || 1 : Math.sign(noseYaw);\n yawDegrees = sign * Math.abs(matrixYaw);\n }\n\n // ── Roulis et tangage : matrice si disponible, sinon droite des yeux ──\n const aspect = video.videoHeight > 0 ? video.videoWidth / video.videoHeight : 1;\n const rollDegrees = pose?.roll ?? rollFromEyes(lm, aspect);\n const pitchDegrees = pose?.pitch ?? null;\n\n // ── Boîte englobante normalisée ───────────────────────────────────────\n let minX = 1,\n minY = 1,\n maxX = 0,\n maxY = 0;\n for (const p of lm) {\n if (p.x < minX) minX = p.x;\n if (p.y < minY) minY = p.y;\n if (p.x > maxX) maxX = p.x;\n if (p.y > maxY) maxY = p.y;\n }\n const box = maxX > minX && maxY > minY ? { x: minX, y: minY, w: maxX - minX, h: maxY - minY } : null;\n\n return { faceCount: 1, leftEyeOpen, rightEyeOpen, yawDegrees, rollDegrees, pitchDegrees, smile, box };\n }\n\n close(): void {\n this.landmarker?.close?.();\n this.landmarker = null;\n }\n}\n","/**\n * Machine à états du défi de vivacité, exécutée sur l'appareil.\n *\n * La séquence de gestes est **imposée par le serveur** (`challenge` rendu à\n * l'ouverture de la session) : le SDK ne choisit ni les gestes ni leur ordre,\n * il les fait exécuter et rapporte une preuve horodatée que le serveur\n * confronte au défi émis. Le score calculé ici reste indicatif — la décision\n * de vivacité appartient au serveur, sur la photo et les trames clés.\n *\n * Conventions : `yawDegrees > 0` quand l'utilisateur tourne la tête vers\n * **sa** gauche (dans la trame brute, non miroir, le nez part vers la droite\n * de l'image). Les probabilités d'yeux ouverts et de sourire sont dans 0-1.\n */\n\nexport type ChallengeStep = 'blink' | 'turn-left' | 'turn-right' | 'smile';\nexport const CHALLENGE_STEPS: readonly ChallengeStep[] = ['blink', 'turn-left', 'turn-right', 'smile'];\nexport const DEFAULT_CHALLENGE: readonly ChallengeStep[] = ['blink', 'turn-left', 'smile'];\n\n/**\n * `hold` : tous les gestes sont faits, on attend que la tête soit droite et\n * immobile avant la photo finale ; `done` : selfie à prendre maintenant.\n */\nexport type LivenessPhase = 'searching-face' | ChallengeStep | 'hold' | 'done';\n\n/** Signaux extraits d'une trame par l'adaptateur de suivi facial. */\nexport interface FaceSignals {\n /** Nombre de visages détectés. Le défi exige exactement un. */\n faceCount: number;\n /** Probabilité d'œil gauche ouvert (0-1), ou null si indisponible. */\n leftEyeOpen: number | null;\n /** Probabilité d'œil droit ouvert (0-1), ou null si indisponible. */\n rightEyeOpen: number | null;\n /** Lacet de la tête en degrés (positif = gauche de l'utilisateur), ou null. */\n yawDegrees: number | null;\n /** Roulis de la tête en degrés (inclinaison gauche/droite), ou null. */\n rollDegrees: number | null;\n /** Tangage de la tête en degrés (haut/bas), ou null. */\n pitchDegrees: number | null;\n /** Probabilité de sourire (0-1), ou null. */\n smile: number | null;\n /** Boîte englobante normalisée (0-1) du visage, ou null. */\n box: { x: number; y: number; w: number; h: number } | null;\n}\n\nexport interface ChallengeProofStep {\n step: ChallengeStep;\n /** Millisecondes depuis le verrouillage du visage. */\n at: number;\n /** Durée du geste (clignement : yeux fermés) en ms, quand elle a un sens. */\n durationMs?: number;\n}\n\n/** Trame clé à capturer pour le serveur, au moment où un geste aboutit. */\nexport type KeyFrame = 'neutral' | 'eyes-closed' | 'turned' | 'smile';\n\nexport interface FrameOutcome {\n /** L'étape affichée a changé : rafraîchir l'interface. */\n changed: boolean;\n /** Geste qui vient d'aboutir, le cas échéant. */\n completed?: ChallengeStep;\n /** Trame à capturer maintenant, le cas échéant. */\n capture?: KeyFrame;\n /** Consigne de cadrage prioritaire sur le geste, ou null si le cadrage est bon. */\n guidance: LivenessGuidance | null;\n}\n\nexport type LivenessGuidance =\n 'no-face' | 'multiple-faces' | 'too-small' | 'too-large' | 'off-center' | 'tilted' | 'eyes-closed';\n\n// Seuils de départ (issus du portage Flutter) ; la télémétrie sert à les recalibrer.\n/**\n * Clignement. Un clignement naturel dure 100-400 ms, soit 1 à 4 trames à la\n * cadence d'analyse (~15/s) ; la fermeture peut donc n'être vue que sur une\n * trame, au pic. On regarde la **moyenne** des deux yeux (tolère une\n * asymétrie) tout en exigeant que chacun se ferme (un clin d'œil ne compte\n * pas), et on encadre la durée : trop long, ce sont des yeux fermés, pas un\n * clignement. Les yeux doivent avoir été vus ouverts avant, et la tête doit\n * être à peu près de face (les formes d'yeux sont peu fiables de profil).\n */\nexport const EYES_CLOSED_THRESHOLD = 0.35;\nexport const EYE_CLOSED_EACH_THRESHOLD = 0.5;\nexport const EYES_OPEN_THRESHOLD = 0.6;\nexport const BLINK_MIN_OPEN_FRAMES = 2;\nexport const BLINK_MAX_CLOSED_MS = 700;\nexport const BLINK_MAX_YAW_DEGREES = 20;\nexport const HEAD_TURN_DEGREES = 16;\n/** Tête « droite » pour la photo finale (et la trame neutre). */\nexport const FRONTAL_YAW_DEGREES = 8;\nexport const FRONTAL_ROLL_DEGREES = 8;\nexport const FRONTAL_PITCH_DEGREES = 12;\n/** Trames consécutives de face et immobiles avant de déclencher la photo. */\nexport const FRAMES_TO_SETTLE = 4;\nexport const SMILE_THRESHOLD = 0.55;\nexport const FRAMES_TO_LOCK_FACE = 6;\nexport const FRAMES_LOST_BEFORE_RESET = 12;\n/** Le visage doit occuper entre 22 % et 70 % de la largeur de la trame. */\nexport const FACE_MIN_WIDTH = 0.22;\nexport const FACE_MAX_WIDTH = 0.7;\nexport const FACE_CENTER_TOLERANCE = 0.18;\n\nfunction isStep(v: unknown): v is ChallengeStep {\n return typeof v === 'string' && (CHALLENGE_STEPS as readonly string[]).includes(v);\n}\n\n/** Ne retient que les gestes connus ; séquence par défaut si rien d'exploitable. */\nexport function normalizeChallenge(steps: readonly unknown[] | null | undefined): ChallengeStep[] {\n const known = (steps ?? []).filter(isStep);\n return known.length ? known : [...DEFAULT_CHALLENGE];\n}\n\n/**\n * La tête est-elle droite, de face, yeux ouverts ? `null` si oui, sinon la\n * consigne à afficher. Les signaux absents (null) ne bloquent pas.\n */\nexport function frontalGuidance(sig: FaceSignals): 'tilted' | 'eyes-closed' | null {\n const yaw = sig.yawDegrees == null ? 0 : Math.abs(sig.yawDegrees);\n const roll = sig.rollDegrees == null ? 0 : Math.abs(sig.rollDegrees);\n const pitch = sig.pitchDegrees == null ? 0 : Math.abs(sig.pitchDegrees);\n if (yaw > FRONTAL_YAW_DEGREES || roll > FRONTAL_ROLL_DEGREES || pitch > FRONTAL_PITCH_DEGREES)\n return 'tilted';\n const l = sig.leftEyeOpen ?? 1;\n const r = sig.rightEyeOpen ?? 1;\n if (l < EYES_OPEN_THRESHOLD || r < EYES_OPEN_THRESHOLD) return 'eyes-closed';\n return null;\n}\n\nexport class LivenessChallenge {\n readonly steps: readonly ChallengeStep[];\n phase: LivenessPhase = 'searching-face';\n private index = 0;\n private framesWithFace = 0;\n private framesWithoutFace = 0;\n private eyesOpenFrames = 0;\n private eyesClosedSince: number | null = null;\n private lockedAt: number | null = null;\n private neutralCaptured = false;\n private settleFrames = 0;\n private lastBlinkMs: number | null = null;\n private holdSince: number | null = null;\n private forcedDone = false;\n private readonly proofSteps: ChallengeProofStep[] = [];\n\n constructor(\n steps: readonly ChallengeStep[] = DEFAULT_CHALLENGE,\n private readonly now: () => number = () => performance.now(),\n ) {\n this.steps = steps.length ? [...steps] : [...DEFAULT_CHALLENGE];\n }\n\n get isDone(): boolean {\n return this.phase === 'done';\n }\n\n get currentStep(): ChallengeStep | null {\n return this.phase === 'searching-face' || this.phase === 'done' || this.phase === 'hold'\n ? null\n : this.phase;\n }\n\n /** Progression 0-1 pour l'anneau : visage verrouillé compte pour une part. */\n get progress(): number {\n const total = this.steps.length + 1;\n const done =\n this.phase === 'searching-face'\n ? 0\n : this.phase === 'done' || this.phase === 'hold'\n ? total\n : 1 + this.index;\n return Math.min(1, done / total);\n }\n\n /** Nombre de gestes aboutis. */\n get completedCount(): number {\n return this.proofSteps.length;\n }\n\n /** Millisecondes passées à attendre une tête droite (phase `hold`), sinon 0. */\n get holdElapsed(): number {\n return this.holdSince == null ? 0 : Math.max(0, this.now() - this.holdSince);\n }\n\n /** Vrai si la photo finale a été déclenchée tête droite (et non par délai). */\n get settled(): boolean {\n return this.isDone && !this.forcedDone;\n }\n\n /**\n * Termine sans attendre une tête droite (délai d'attente dépassé) : la\n * photo est prise telle quelle ; `settled` (télémétrie) garde la trace.\n */\n forceDone(): void {\n if (this.phase === 'hold') {\n this.forcedDone = true;\n this.phase = 'done';\n }\n }\n\n /** Preuve à transmettre au serveur. */\n get proof(): ChallengeProofStep[] {\n return this.proofSteps.map((p) => ({ ...p }));\n }\n\n private elapsed(): number {\n return this.lockedAt == null ? 0 : Math.max(0, Math.round(this.now() - this.lockedAt));\n }\n\n private guidanceFor(sig: FaceSignals): FrameOutcome['guidance'] {\n if (sig.faceCount === 0) return 'no-face';\n if (sig.faceCount > 1) return 'multiple-faces';\n const b = sig.box;\n if (!b) return null;\n if (b.w < FACE_MIN_WIDTH) return 'too-small';\n if (b.w > FACE_MAX_WIDTH) return 'too-large';\n const cx = b.x + b.w / 2;\n const cy = b.y + b.h / 2;\n if (Math.abs(cx - 0.5) > FACE_CENTER_TOLERANCE || Math.abs(cy - 0.5) > FACE_CENTER_TOLERANCE + 0.06)\n return 'off-center';\n return null;\n }\n\n /** Fait avancer la machine avec les signaux d'une trame. */\n onFrame(sig: FaceSignals): FrameOutcome {\n const before = this.phase;\n const guidance = this.guidanceFor(sig);\n\n if (sig.faceCount !== 1) {\n this.framesWithoutFace++;\n // Visage perdu trop longtemps → retour à la détection, sans annuler les\n // gestes déjà réussis.\n if (this.framesWithoutFace > FRAMES_LOST_BEFORE_RESET && this.phase !== 'done') {\n this.phase = 'searching-face';\n this.framesWithFace = 0;\n }\n return { changed: this.phase !== before, guidance };\n }\n\n this.framesWithoutFace = 0;\n this.framesWithFace++;\n\n let completed: ChallengeStep | undefined;\n let capture: KeyFrame | undefined;\n\n // Référence « yeux ouverts » pour le clignement, accumulée dès le\n // verrouillage du visage (tête à peu près de face uniquement).\n {\n const { leftEyeOpen: l, rightEyeOpen: r, yawDegrees: yaw } = sig;\n const frontal = yaw == null || Math.abs(yaw) <= BLINK_MAX_YAW_DEGREES;\n if (frontal && l != null && r != null && l > EYES_OPEN_THRESHOLD && r > EYES_OPEN_THRESHOLD)\n this.eyesOpenFrames++;\n }\n\n switch (this.phase) {\n case 'searching-face':\n if (this.framesWithFace >= FRAMES_TO_LOCK_FACE && guidance === null) {\n if (this.lockedAt == null) this.lockedAt = this.now();\n // La trame neutre sert de référence au serveur : tête droite exigée.\n if (!this.neutralCaptured && frontalGuidance(sig) === null) {\n this.neutralCaptured = true;\n capture = 'neutral';\n }\n this.phase = this.index < this.steps.length ? this.steps[this.index]! : 'hold';\n if (this.phase === 'hold') this.holdSince = this.now();\n }\n break;\n\n case 'blink': {\n const { leftEyeOpen: l, rightEyeOpen: r } = sig;\n if (l == null || r == null) break;\n if (sig.yawDegrees != null && Math.abs(sig.yawDegrees) > BLINK_MAX_YAW_DEGREES) {\n // De profil, les formes d'yeux ne valent rien : on repart de zéro.\n this.eyesOpenFrames = 0;\n this.eyesClosedSince = null;\n break;\n }\n const mean = (l + r) / 2;\n const closed =\n mean < EYES_CLOSED_THRESHOLD && l < EYE_CLOSED_EACH_THRESHOLD && r < EYE_CLOSED_EACH_THRESHOLD;\n const open = l > EYES_OPEN_THRESHOLD && r > EYES_OPEN_THRESHOLD;\n if (closed) {\n if (this.eyesOpenFrames < BLINK_MIN_OPEN_FRAMES) break; // yeux jamais vus ouverts\n if (this.eyesClosedSince == null) {\n this.eyesClosedSince = this.now();\n capture = 'eyes-closed';\n } else if (this.now() - this.eyesClosedSince > BLINK_MAX_CLOSED_MS) {\n // Yeux fermés trop longtemps : ce n'est pas un clignement.\n this.eyesClosedSince = null;\n this.eyesOpenFrames = 0;\n }\n } else if (open && this.eyesClosedSince != null) {\n const closedMs = Math.round(this.now() - this.eyesClosedSince);\n this.eyesClosedSince = null;\n if (closedMs <= BLINK_MAX_CLOSED_MS) {\n completed = 'blink';\n this.lastBlinkMs = closedMs;\n }\n }\n // Entre les deux (yeux mi-clos) : on laisse l'état courant courir.\n break;\n }\n\n case 'turn-left':\n case 'turn-right': {\n const yaw = sig.yawDegrees;\n if (yaw == null) break;\n const wanted = this.phase === 'turn-left' ? yaw > HEAD_TURN_DEGREES : yaw < -HEAD_TURN_DEGREES;\n if (wanted) {\n completed = this.phase;\n capture = 'turned';\n }\n break;\n }\n\n case 'smile': {\n if (sig.smile != null && sig.smile > SMILE_THRESHOLD) {\n completed = 'smile';\n capture = 'smile';\n }\n break;\n }\n\n case 'hold': {\n // Tête droite, yeux ouverts, bien cadrée, pendant plusieurs trames\n // consécutives : la photo finale peut être prise.\n const g = guidance ?? frontalGuidance(sig);\n if (g === null) {\n this.settleFrames++;\n if (this.settleFrames >= FRAMES_TO_SETTLE) this.phase = 'done';\n } else {\n this.settleFrames = 0;\n }\n return { changed: this.phase !== before, guidance: g };\n }\n\n case 'done':\n break;\n }\n\n if (completed) {\n const entry: ChallengeProofStep = { step: completed, at: this.elapsed() };\n if (completed === 'blink' && this.lastBlinkMs != null) entry.durationMs = this.lastBlinkMs;\n this.proofSteps.push(entry);\n this.index += 1;\n this.eyesOpenFrames = 0;\n this.eyesClosedSince = null;\n this.lastBlinkMs = null;\n this.phase = this.index < this.steps.length ? this.steps[this.index]! : 'hold';\n if (this.phase === 'hold') this.holdSince = this.now();\n }\n\n return { changed: this.phase !== before, completed, capture, guidance };\n }\n\n /**\n * Score indicatif 0-100 (jamais décisionnel côté serveur) : défi complet →\n * 90 + bonus de stabilité de suivi (jusqu'à 8).\n */\n score(): number {\n if (!this.isDone) {\n let partial = 20;\n if (this.framesWithFace >= FRAMES_TO_LOCK_FACE) partial += 15;\n partial += Math.min(40, this.proofSteps.length * 15);\n return partial;\n }\n const stabilityBonus = Math.min(8, Math.round(this.framesWithFace / 30));\n return 90 + stabilityBonus;\n }\n}\n","import {\n NayaApiClient,\n NayaApiError,\n type NayaHandoff,\n type NayaSession,\n type NayaSubmitResponse,\n} from '../api/client';\nimport {\n NAYA_COUNTRIES,\n NAYA_DOCUMENT_TYPES,\n type NayaAuth,\n type NayaCountryCode,\n type NayaDocumentType,\n type NayaEvent,\n type NayaEventName,\n type ResolvedNayaConfig,\n documentNeedsVerso,\n} from '../models/config';\nimport { type NayaErrorCode, type NayaOcrData, type NayaResult, errorResult } from '../models/result';\nimport { NayaStrings } from '../i18n/strings';\nimport { detectSupport, type NayaSupport } from '../support/capabilities';\nimport { Telemetry } from '../support/telemetry';\nimport { createLogger, type NayaLogger } from '../support/log';\nimport { vibrate, type HapticPattern } from '../support/haptics';\nimport { networkHint } from '../support/network';\nimport { FaceTracker } from '../liveness/face-tracker';\nimport {\n normalizeChallenge,\n type ChallengeProofStep,\n type ChallengeStep,\n} from '../liveness/liveness-challenge';\n\n/** Étapes du parcours. L'ordre reflète la progression nominale. */\nexport type NayaStep =\n | 'unsupported'\n | 'welcome'\n | 'consent'\n | 'handoff'\n | 'select'\n | 'tips-document'\n | 'capture-recto'\n | 'capture-verso'\n | 'tips-selfie'\n | 'liveness'\n | 'ocr-confirm'\n | 'processing'\n | 'result';\n\nexport type StepDirection = 'forward' | 'back' | 'replace';\n\nexport interface NormalizedError {\n message: string;\n code: NayaErrorCode;\n statusCode?: number;\n requestId?: string;\n}\n\n/**\n * État partagé du parcours et logique de session — sans framework : état en\n * champs simples, l'hôte réagit au changement d'étape via `onStep`, les\n * écrans lisent et écrivent l'état et demandent la suite via `nextAfter*`.\n */\nexport class NayaFlow {\n private readonly api: NayaApiClient;\n readonly config: ResolvedNayaConfig;\n readonly strings: NayaStrings;\n readonly support: NayaSupport;\n readonly log: NayaLogger;\n readonly telemetry: Telemetry;\n readonly slowNetwork: boolean;\n /**\n * Vrai quand la session a été ouverte par le backend du client\n * (`verificationId` + `sessionToken`) : le SDK ne crée jamais de session.\n */\n readonly resumed: boolean;\n private readonly finishCb: (result: NayaResult) => void;\n\n /** Notifié à chaque changement d'étape ; posé par l'hôte. */\n onStep: (step: NayaStep, direction: StepDirection) => void = () => {};\n\n // ── État ─────────────────────────────────────────────────────────────────\n step: NayaStep = 'welcome';\n session: NayaSession | null = null;\n challenge: ChallengeStep[] = [];\n country: NayaCountryCode | null;\n document: NayaDocumentType | null;\n rectoBase64: string | null = null;\n versoBase64: string | null = null;\n selfieBase64: string | null = null;\n livenessFrames: string[] = [];\n livenessProof: ChallengeProofStep[] = [];\n livenessMode: 'active' | 'passive' = 'active';\n livenessScore = 0;\n livenessDelegate: string | null = null;\n ocrData: NayaOcrData | undefined;\n declaredData: Record<string, string> | undefined;\n /** L'utilisateur a indiqué que les données lues sont inexactes (mode `display`). */\n dataDisputed = false;\n submitResponse: NayaSubmitResponse | null = null;\n attemptsUsed = 0;\n captureAttempts = 0;\n consentGranted = false;\n consentAlreadyOnServer = false;\n tipsShown = { document: false, selfie: false };\n pendingHandoff = false;\n handoffInfo: NayaHandoff | null = null;\n\n private stepHistory: NayaStep[] = [];\n private documentUpload: Promise<NayaOcrData | undefined> | null = null;\n private finished = false;\n private preparation: Promise<void> | null = null;\n private sessionPromise: Promise<NayaSession> | null = null;\n private consentSent = false;\n private livenessPreload: Promise<void> | null = null;\n\n constructor(auth: NayaAuth, config: ResolvedNayaConfig, finish: (result: NayaResult) => void) {\n this.config = config;\n this.finishCb = finish;\n this.strings = new NayaStrings(config.locale, config.strings);\n this.support = detectSupport();\n this.log = createLogger(config.debug);\n this.slowNetwork = networkHint().slow;\n this.api = new NayaApiClient({ ...auth }, config.baseUrl);\n const os = this.support.ios ? 'ios' : this.support.android ? 'android' : 'other';\n this.telemetry = new Telemetry(this.api, config.telemetry, `${this.support.deviceClass}/${os}`, this.log);\n this.country = config.country ?? null;\n this.document = config.documentTypes.length === 1 ? config.documentTypes[0]! : null;\n\n this.resumed = !!(auth.sessionToken && auth.verificationId);\n if (this.resumed) {\n this.session = {\n verificationId: auth.verificationId!,\n sessionToken: auth.sessionToken!,\n challenge: [],\n };\n }\n if (!this.support.ok) this.step = 'unsupported';\n this.log.debug('flow created', {\n resumed: this.resumed,\n support: this.support,\n slowNetwork: this.slowNetwork,\n });\n }\n\n get client(): NayaApiClient {\n return this.api;\n }\n\n // ── Événements hôte, télémétrie, haptique ────────────────────────────────\n emit(type: NayaEventName, data?: Record<string, unknown>): void {\n const event: NayaEvent = { type, at: performance.now(), step: this.step, data };\n try {\n this.config.onEvent?.(event);\n } catch (err) {\n this.log.warn('onEvent handler threw', err);\n }\n }\n\n haptic(pattern: HapticPattern): void {\n vibrate(pattern, this.config.haptics && this.support.mobile);\n }\n\n // ── Navigation ─────────────────────────────────────────────────────────────\n /** Empile l'étape courante et avance vers `next`. */\n go(next: NayaStep): void {\n this.stepHistory.push(this.step);\n this.setStep(next, 'forward');\n }\n\n /** Remplace l'étape courante sans l'empiler (transitions sans retour). */\n replace(next: NayaStep): void {\n this.setStep(next, 'replace');\n }\n\n get canGoBack(): boolean {\n return this.stepHistory.length > 0;\n }\n\n /** Revient à l'étape précédente si elle existe. */\n back(): void {\n const prev = this.stepHistory.pop();\n if (prev) this.setStep(prev, 'back');\n }\n\n private setStep(step: NayaStep, direction: StepDirection): void {\n const from = this.step;\n this.telemetry.track('step_completed', {\n step: from,\n durationMs: this.telemetry.stepDuration(),\n next: step,\n });\n this.step = step;\n this.telemetry.track('step_started', { step });\n this.emit('step', { from, to: step, direction });\n this.onStep(step, direction);\n }\n\n // ── Décisions d'enchaînement ───────────────────────────────────────────────\n get consentRequired(): boolean {\n return this.config.consent !== false && !this.consentAlreadyOnServer && !this.consentGranted;\n }\n\n get handoffAvailable(): boolean {\n return this.config.handoff.enabled && !this.support.mobile && this.config.container === null;\n }\n\n get selectionComplete(): boolean {\n return !!this.country && !!this.document;\n }\n\n nextAfterWelcome(): NayaStep {\n if (this.consentRequired) return 'consent';\n return this.nextAfterConsent();\n }\n\n nextAfterConsent(): NayaStep {\n if (this.pendingHandoff && this.selectionComplete) return 'handoff';\n if (!this.selectionComplete) return 'select';\n return this.nextAfterSelect();\n }\n\n nextAfterSelect(): NayaStep {\n if (this.pendingHandoff) return 'handoff';\n if (this.config.eagerSession && !this.session) void this.ensureSession().catch(() => {});\n return this.tipsShown.document ? 'capture-recto' : 'tips-document';\n }\n\n nextAfterCapture(side: 'recto' | 'verso'): NayaStep {\n if (side === 'recto' && this.needsVerso) return 'capture-verso';\n return this.tipsShown.selfie ? 'liveness' : 'tips-selfie';\n }\n\n nextAfterLiveness(): NayaStep {\n return this.config.confirmOcr ? 'ocr-confirm' : 'processing';\n }\n\n // ── Session ────────────────────────────────────────────────────────────────\n /**\n * En reprise de session, lit chez Naya le défi, le type de document, le pays\n * et l'état du consentement. Un échec de lecture n'est pas bloquant si la\n * configuration hôte suffit.\n */\n prepare(): Promise<void> {\n return (this.preparation ??= this.loadResumedSession());\n }\n\n private async loadResumedSession(): Promise<void> {\n if (!this.resumed || !this.session) return;\n try {\n const info = await this.api.getVerification(this.session.verificationId);\n const doc = NAYA_DOCUMENT_TYPES.find((d) => d === info.documentType);\n const country = NAYA_COUNTRIES.find((c) => c.code === info.country)?.code;\n if (doc) this.document = doc;\n if (country) this.country = country;\n this.challenge = normalizeChallenge(info.challenge);\n this.session.challenge = this.challenge;\n this.consentAlreadyOnServer = !!info.consentAt;\n this.emit('session', { verificationId: this.session.verificationId, resumed: true });\n this.log.debug('resumed session', info);\n } catch (err) {\n const cfgDoc = this.config.documentTypes.length === 1 ? this.config.documentTypes[0] : null;\n if (this.config.country && cfgDoc) {\n this.country = this.config.country;\n this.document = cfgDoc;\n this.challenge = normalizeChallenge(null);\n return;\n }\n throw err;\n }\n }\n\n /**\n * Rend la session : celle reprise du backend, ou celle créée ici à la\n * première demande (documentType + pays requis). Le consentement recueilli\n * est transmis dès que la session existe.\n */\n ensureSession(): Promise<NayaSession> {\n if (this.session && this.challenge.length) return this.maybeSendConsent().then(() => this.session!);\n return (this.sessionPromise ??= this.createSession().finally(() => {\n this.sessionPromise = null;\n }));\n }\n\n private async createSession(): Promise<NayaSession> {\n if (this.session) {\n if (!this.challenge.length) await this.prepare();\n await this.maybeSendConsent();\n return this.session;\n }\n if (!this.document || !this.country) throw new NayaApiError('Document et pays requis.', 'invalid_params');\n const created = await this.api.start({\n documentType: this.document,\n country: this.country,\n callbackUrl: this.config.callbackUrl,\n device:\n this.support.deviceClass === 'desktop'\n ? 'Web'\n : this.support.deviceClass === 'tablet'\n ? 'Tablette'\n : 'Mobile',\n });\n this.session = created;\n this.challenge = normalizeChallenge(created.challenge);\n // La suite du parcours porte le jeton de session, pas la clé.\n if (created.sessionToken) this.api.useSession(created.sessionToken);\n this.emit('session', { verificationId: created.verificationId, resumed: false });\n this.telemetry.track('session_opened', { resumed: false });\n await this.maybeSendConsent();\n return created;\n }\n\n /** Transmet le consentement une seule fois, dès qu'une session existe. */\n private async maybeSendConsent(): Promise<void> {\n if (!this.session || this.consentSent || this.consentAlreadyOnServer || !this.consentGranted) return;\n this.consentSent = true;\n const version = this.config.consent === false ? undefined : this.config.consent.version;\n try {\n await this.api.consent(this.session.verificationId, version);\n this.emit('consent', { verificationId: this.session.verificationId });\n } catch (err) {\n this.consentSent = false;\n this.log.warn('consent not recorded', err);\n }\n }\n\n /** Appelé par l'écran de consentement ; transmis maintenant si possible. */\n grantConsent(): void {\n this.consentGranted = true;\n this.telemetry.track('consent_granted');\n if (this.session) void this.maybeSendConsent();\n }\n\n // ── Document ───────────────────────────────────────────────────────────────\n /**\n * Lance (une seule fois) l'envoi du document en arrière-plan : l'OCR serveur\n * tourne pendant que l'utilisateur fait son selfie.\n */\n startDocumentUpload(): void {\n if (this.documentUpload) return;\n const upload = this.uploadDocument();\n this.documentUpload = upload;\n upload.catch(() => {});\n }\n\n /** Attend la fin de l'envoi du document, en le (re)lançant si besoin. */\n ensureDocumentUploaded(): Promise<NayaOcrData | undefined> {\n return (this.documentUpload ??= this.uploadDocument());\n }\n\n get documentUploadInFlight(): boolean {\n return this.documentUpload !== null && this.ocrData === undefined && !!this.rectoBase64;\n }\n\n private async uploadDocument(): Promise<NayaOcrData | undefined> {\n try {\n const s = await this.ensureSession();\n const ocr = await this.api.uploadDocument(s.verificationId, {\n rectoBase64: this.rectoBase64!,\n versoBase64: this.versoBase64 ?? undefined,\n });\n this.ocrData = ocr;\n this.telemetry.track('document_uploaded', { hasOcr: !!ocr, fields: ocr ? Object.keys(ocr).length : 0 });\n return ocr;\n } catch (err) {\n this.documentUpload = null; // permet le retry\n throw err;\n }\n }\n\n /** Côté maximal des images envoyées ; réduit sur réseau lent. */\n get imageMaxDimension(): number {\n return this.slowNetwork\n ? Math.min(1200, this.config.capture.maxDimension)\n : this.config.capture.maxDimension;\n }\n\n get wantsFileUpload(): boolean {\n const mode = this.config.capture.fileUpload;\n return mode === 'always' || (mode === 'auto' && !this.support.mobile);\n }\n\n // ── Vivacité ───────────────────────────────────────────────────────────────\n /** Précharge MediaPipe pendant la capture du document. */\n preloadLiveness(): void {\n if (!this.config.liveness.preload || this.livenessPreload) return;\n this.livenessPreload = FaceTracker.preload(this.config.livenessAssets).catch((err) => {\n this.log.warn('liveness preload failed', err);\n this.livenessPreload = null;\n });\n }\n\n /** Défi à exécuter : celui du serveur, sinon la séquence par défaut. */\n get challengeSteps(): ChallengeStep[] {\n return this.challenge.length ? this.challenge : normalizeChallenge(null);\n }\n\n // ── Relais vers mobile ────────────────────────────────────────────────────\n async requestHandoff(): Promise<NayaHandoff> {\n const s = await this.ensureSession();\n this.handoffInfo = await this.api.handoff(s.verificationId, this.config.handoff.baseUrl || undefined);\n this.emit('handoff_shown', { verificationId: s.verificationId });\n this.telemetry.track('handoff_shown');\n return this.handoffInfo;\n }\n\n // ── Nouvelle tentative ────────────────────────────────────────────────────\n get canRetry(): boolean {\n // Une session reprise ne peut pas être rouverte par le SDK (le jeton ne\n // désigne que cette vérification) : pas de nouvelle tentative ici.\n return !this.resumed && this.attemptsUsed < this.config.maxAttempts;\n }\n\n /** Prépare une nouvelle tentative après un rejet : nouvelle session, captures à zéro. */\n resetForRetry(): void {\n this.attemptsUsed += 1;\n this.session = null;\n this.challenge = [];\n this.rectoBase64 = null;\n this.versoBase64 = null;\n this.selfieBase64 = null;\n this.livenessFrames = [];\n this.livenessProof = [];\n this.livenessMode = 'active';\n this.livenessScore = 0;\n this.ocrData = undefined;\n this.declaredData = undefined;\n this.dataDisputed = false;\n this.submitResponse = null;\n this.documentUpload = null;\n this.consentSent = false;\n this.stepHistory = [];\n this.telemetry.track('retry', { attempt: this.attemptsUsed });\n }\n\n get needsVerso(): boolean {\n return !!this.document && documentNeedsVerso(this.document);\n }\n\n documentTypeNeedsVerso(doc: NayaDocumentType): boolean {\n return documentNeedsVerso(doc);\n }\n\n // ── Erreurs et fin de parcours ────────────────────────────────────────────\n normalizeError(err: unknown, fallback: NayaErrorCode = 'unknown'): NormalizedError {\n if (err instanceof NayaApiError) {\n const message =\n err.code === 'network' || err.code === 'timeout' ? this.strings.errorMessage(err.code) : err.message;\n return { message, code: err.code, statusCode: err.statusCode, requestId: err.requestId };\n }\n if (err instanceof DOMException || (err && typeof err === 'object' && 'name' in err)) {\n const name = String((err as { name?: string }).name);\n if (name === 'NotAllowedError' || name === 'SecurityError')\n return { message: this.strings.t('cameraDenied'), code: 'camera_denied' };\n if (name === 'NotFoundError' || name === 'OverconstrainedError')\n return { message: this.strings.t('cameraUnavailable'), code: 'camera_unavailable' };\n if (name === 'NotReadableError' || name === 'AbortError')\n return { message: this.strings.t('cameraBusy'), code: 'camera_busy' };\n }\n const message = err instanceof Error && err.message ? err.message : this.strings.errorMessage(fallback);\n return { message, code: fallback };\n }\n\n complete(result: NayaResult): void {\n if (this.finished) return;\n this.finished = true;\n const final: NayaResult = {\n ...result,\n verificationId: result.verificationId ?? this.session?.verificationId,\n };\n this.telemetry.track('result', {\n status: final.status,\n code: final.errorCode ?? null,\n reasons: final.reasonCodes?.length ?? 0,\n elapsedMs: this.telemetry.elapsed(),\n });\n this.emit(final.status === 'error' ? 'error' : final.status === 'cancelled' ? 'cancelled' : 'result', {\n ...final,\n });\n // Les images ne survivent pas au parcours.\n this.rectoBase64 = this.versoBase64 = this.selfieBase64 = null;\n this.livenessFrames = [];\n void this.telemetry.flush(true);\n this.finishCb(final);\n }\n\n /** Termine le parcours sur une erreur typée. */\n fail(err: unknown, fallback: NayaErrorCode = 'unknown'): void {\n const n = this.normalizeError(err, fallback);\n this.log.error('flow failed', n);\n this.telemetry.track('error', { code: n.code, status: n.statusCode ?? null, step: this.step });\n this.complete(\n errorResult(n.message, this.session?.verificationId, {\n errorCode: n.code,\n statusCode: n.statusCode,\n requestId: n.requestId,\n }),\n );\n }\n\n cancel(): void {\n this.haptic('tap');\n this.complete({ status: 'cancelled' });\n }\n}\n","/** Confine la navigation clavier (Tab) à l'intérieur d'un conteneur. */\nconst FOCUSABLE =\n 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nexport function trapFocus(root: HTMLElement | ShadowRoot): () => void {\n const onKey = (e: KeyboardEvent): void => {\n if (e.key !== 'Tab') return;\n const nodes = Array.from(root.querySelectorAll<HTMLElement>(FOCUSABLE)).filter(\n (n) => !n.hidden && n.offsetParent !== null,\n );\n if (nodes.length === 0) return;\n const first = nodes[0]!;\n const last = nodes[nodes.length - 1]!;\n const active = (root as ShadowRoot).activeElement ?? document.activeElement;\n if (e.shiftKey && (active === first || !root.contains(active as Node))) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && active === last) {\n e.preventDefault();\n first.focus();\n }\n };\n document.addEventListener('keydown', onKey, true);\n return () => document.removeEventListener('keydown', onKey, true);\n}\n\n/** Donne le focus au premier élément focalisable d'un écran fraîchement monté. */\nexport function focusFirst(root: HTMLElement): void {\n const target =\n root.querySelector<HTMLElement>('[data-autofocus]') ??\n root.querySelector<HTMLElement>('h1[tabindex=\"-1\"]') ??\n root.querySelector<HTMLElement>(FOCUSABLE);\n target?.focus({ preventScroll: true });\n}\n","/** Petits utilitaires DOM, sans dépendance. */\n\n/** Échappe une chaîne pour une insertion sûre en contenu HTML. */\nexport function escapeHtml(s: string): string {\n return s.replace(\n /[&<>\"']/g,\n (c) => ({ '&': '&', '<': '<', '>': '>', '\"': '"', \"'\": ''' })[c]!,\n );\n}\n\n/** Texte avec retours à la ligne (`\\n` → `<br>`), échappé. */\nexport function multiline(s: string): string {\n return escapeHtml(s).replace(/\\n/g, '<br>');\n}\n\n/** Crée un élément et lui pose optionnellement une classe et du HTML interne. */\nexport function el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n className?: string,\n html?: string,\n): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag);\n if (className) node.className = className;\n if (html !== undefined) node.innerHTML = html;\n return node;\n}\n\n/** Copie dans le presse-papiers ; vrai si réussi. */\nexport async function copyText(text: string): Promise<boolean> {\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch {\n try {\n const ta = document.createElement('textarea');\n ta.value = text;\n ta.setAttribute('readonly', '');\n ta.style.position = 'fixed';\n ta.style.opacity = '0';\n document.body.appendChild(ta);\n ta.select();\n const ok = document.execCommand('copy');\n ta.remove();\n return ok;\n } catch {\n return false;\n }\n }\n}\n","/** Icônes SVG inline (trait, 24×24), sans dépendance. */\nexport type NayaIconName =\n | 'back'\n | 'close'\n | 'check'\n | 'chevron'\n | 'shield'\n | 'lock'\n | 'fingerprint'\n | 'id-card'\n | 'passport'\n | 'car'\n | 'sun'\n | 'focus'\n | 'eye'\n | 'rotate-left'\n | 'rotate-right'\n | 'smile'\n | 'hourglass'\n | 'clock'\n | 'wifi-off'\n | 'refresh'\n | 'upload'\n | 'flip'\n | 'flash'\n | 'qr'\n | 'phone'\n | 'alert'\n | 'info'\n | 'user'\n | 'copy'\n | 'external'\n | 'camera'\n | 'sparkle'\n | 'hand';\n\nconst PATHS: Record<NayaIconName, string> = {\n back: '<path d=\"M15 18l-6-6 6-6\"/>',\n close: '<path d=\"M18 6L6 18M6 6l12 12\"/>',\n check: '<path d=\"M20 6L9 17l-5-5\"/>',\n chevron: '<path d=\"M9 18l6-6-6-6\"/>',\n shield: '<path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"/><path d=\"M9 12l2 2 4-4\"/>',\n lock: '<rect x=\"4\" y=\"11\" width=\"16\" height=\"10\" rx=\"2\"/><path d=\"M8 11V7a4 4 0 018 0v4\"/>',\n fingerprint:\n '<path d=\"M12 10a2 2 0 00-2 2c0 1.5.5 3 1 4.5\"/><path d=\"M8.5 8.5A5 5 0 0117 12c0 2-.3 4-1 6\"/><path d=\"M6 10.5A7 7 0 0119 12c0 1.4-.1 2.8-.4 4\"/><path d=\"M5 15a10 10 0 01-.3-3\"/><path d=\"M12 14c0 2 .5 4 1.5 6\"/>',\n 'id-card':\n '<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\"/><circle cx=\"8.5\" cy=\"11\" r=\"2\"/><path d=\"M5.5 16c.6-1.5 1.7-2 3-2s2.4.5 3 2\"/><path d=\"M14 9h4M14 12h4M14 15h3\"/>',\n passport:\n '<rect x=\"5\" y=\"3\" width=\"14\" height=\"18\" rx=\"2\"/><circle cx=\"12\" cy=\"10\" r=\"3\"/><path d=\"M8 17h8\"/>',\n car: '<path d=\"M5 17h14M6 17l1.5-6h9L18 17\"/><path d=\"M4 12h16\"/><circle cx=\"7.5\" cy=\"17\" r=\"1.5\"/><circle cx=\"16.5\" cy=\"17\" r=\"1.5\"/>',\n sun: '<circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4\"/>',\n focus:\n '<path d=\"M4 8V6a2 2 0 012-2h2M16 4h2a2 2 0 012 2v2M20 16v2a2 2 0 01-2 2h-2M8 20H6a2 2 0 01-2-2v-2\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/>',\n eye: '<path d=\"M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6S2 12 2 12z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/>',\n 'rotate-left': '<path d=\"M3 12a9 9 0 109-9\"/><path d=\"M3 4v5h5\"/>',\n 'rotate-right': '<path d=\"M21 12a9 9 0 11-9-9\"/><path d=\"M21 4v5h-5\"/>',\n smile: '<circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M8 14s1.5 2 4 2 4-2 4-2\"/><path d=\"M9 9h.01M15 9h.01\"/>',\n hourglass: '<path d=\"M6 2h12M6 22h12M7 2v5l5 5 5-5V2M7 22v-5l5-5 5 5v5\"/>',\n clock: '<circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 7v5l3 2\"/>',\n 'wifi-off':\n '<path d=\"M2 2l20 20\"/><path d=\"M8.5 16.5a5 5 0 017 0\"/><path d=\"M5 12.5a10 10 0 015.5-2.8M16.5 10.5c1 .5 1.9 1.1 2.7 1.9\"/><path d=\"M2 8.8a15 15 0 015.2-2.7M15 6.3c2.5.7 4.9 2 7 3.8\"/><circle cx=\"12\" cy=\"20\" r=\"1\"/>',\n refresh: '<path d=\"M21 12a9 9 0 11-2.6-6.4\"/><path d=\"M21 3v6h-6\"/>',\n upload: '<path d=\"M12 16V4M6 10l6-6 6 6\"/><path d=\"M4 20h16\"/>',\n flip: '<path d=\"M4 7h11l-3-3M20 17H9l3 3\"/>',\n flash: '<path d=\"M13 2L4 14h7l-1 8 9-12h-7l1-8z\"/>',\n qr: '<rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\"/><rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\"/><rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\"/><path d=\"M14 14h3v3h-3zM20 14v3M17 20h3M14 20h.01\"/>',\n phone: '<rect x=\"7\" y=\"2\" width=\"10\" height=\"20\" rx=\"2\"/><path d=\"M11 18h2\"/>',\n alert: '<path d=\"M12 3l10 18H2L12 3z\"/><path d=\"M12 10v4M12 17h.01\"/>',\n info: '<circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5M12 8h.01\"/>',\n user: '<circle cx=\"12\" cy=\"8\" r=\"4\"/><path d=\"M4 21c0-4 3.6-7 8-7s8 3 8 7\"/>',\n copy: '<rect x=\"9\" y=\"9\" width=\"12\" height=\"12\" rx=\"2\"/><path d=\"M5 15V5a2 2 0 012-2h10\"/>',\n external: '<path d=\"M14 4h6v6M20 4l-9 9\"/><path d=\"M19 14v5a1 1 0 01-1 1H5a1 1 0 01-1-1V6a1 1 0 011-1h5\"/>',\n camera: '<path d=\"M4 8h3l2-3h6l2 3h3v11H4z\"/><circle cx=\"12\" cy=\"13\" r=\"3.5\"/>',\n sparkle: '<path d=\"M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8z\"/>',\n hand: '<path d=\"M8 13V5a1.5 1.5 0 013 0v6M11 11V4a1.5 1.5 0 013 0v7M14 11V5.5a1.5 1.5 0 013 0V13\"/><path d=\"M17 13v2a6 6 0 01-6 6h-1a6 6 0 01-5-2.7L3.6 14A1.6 1.6 0 016 12.5L8 15\"/>',\n};\n\nexport function iconSvg(name: NayaIconName, size = 20, stroke = 2): string {\n return (\n `<svg class=\"n-ico\" width=\"${size}\" height=\"${size}\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" ` +\n `stroke-width=\"${stroke}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\">${PATHS[name]}</svg>`\n );\n}\n","/**\n * Logo Naya ID (marque « naya » + « iD »), vectoriel, tiré de la charte.\n * Le mot-symbole suit `currentColor` (encre en clair, blanc en sombre) ; le\n * « D » garde la flamme (#E6950A) sauf surcharge `--naya-brand-accent`.\n */\nexport const LOGO_VIEWBOX = '0 0 838 240';\n\nconst LOGO_PATHS =\n '<path fill=\"var(--naya-brand-accent, #E6950A)\" d=\"M713.96 23.28C748.32 29.10 776.61 40.61 797.04 56.24C817.48 71.87 830.83 92.31 832.56 115.36C834.32 138.61 824.00 161.01 804.17 179.75C784.49 198.35 754.92 213.98 715.67 225.15L706.15 195.27C742.32 184.98 767.56 170.30 782.34 156.33C796.97 142.51 801.61 129.07 800.76 117.79C799.89 106.31 793.08 93.53 777.75 81.81C762.42 70.09 739.34 60.14 708.67 54.95L713.96 23.28Z\"/><path fill=\"var(--naya-brand-accent, #E6950A)\" d=\"M686.03 61.99C683.68 73.95 677.15 101.86 677.68 125.45C677.95 137.56 680.10 145.18 682.78 148.84C683.82 150.26 684.83 150.94 686.08 151.34C687.52 151.80 690.43 152.20 695.60 151.04L702.55 182.38C693.47 184.43 684.65 184.55 676.52 181.98C668.18 179.34 661.75 174.24 657.09 167.87C648.37 155.94 646.10 139.90 645.79 126.18C645.16 98.13 652.78 65.72 654.73 55.77L686.03 61.99Z\"/><path fill=\"var(--naya-brand-accent, #E6950A)\" d=\"M714.79 18.35C749.73 24.27 778.84 36.03 800.08 52.26C821.32 68.50 835.68 90.15 837.55 114.98C839.44 140.08 828.25 163.87 807.60 183.38C787.16 202.71 756.78 218.65 717.03 229.96L712.37 231.28L699.82 191.87L704.79 190.46C740.39 180.33 764.86 165.98 778.91 152.70C792.71 139.65 796.48 127.61 795.77 118.17C795.04 108.46 789.23 96.88 774.72 85.79C760.19 74.68 737.92 64.98 707.83 59.88L702.92 59.05L709.85 17.52L714.79 18.35ZM708.67 54.95C739.34 60.14 762.42 70.09 777.75 81.81C793.08 93.53 799.89 106.31 800.76 117.79C801.61 129.07 796.97 142.51 782.34 156.33C767.56 170.30 742.32 184.98 706.15 195.27L715.67 225.15C754.31 214.16 783.56 198.83 803.24 180.62L804.17 179.75C823.69 161.30 833.99 139.31 832.64 116.45L832.56 115.36C830.85 92.67 817.90 72.50 797.99 56.97L797.04 56.24C776.61 40.61 748.32 29.10 713.96 23.28L708.67 54.95ZM691.89 58.06L690.93 62.96C688.53 75.23 682.16 102.44 682.68 125.34C682.95 137.21 685.08 143.51 686.82 145.89C687.11 146.29 687.28 146.42 687.32 146.46C687.36 146.48 687.41 146.52 687.59 146.57C687.98 146.70 689.95 147.19 694.50 146.16L699.4 145.06L708.51 186.17L703.65 187.26C693.95 189.44 684.20 189.65 675.01 186.75C665.56 183.76 658.27 177.96 653.05 170.82C643.39 157.61 641.11 140.26 640.79 126.30C640.14 97.56 647.94 64.46 649.83 54.81L650.79 49.89L691.89 58.06ZM654.73 55.77C652.78 65.72 645.16 98.13 645.79 126.18C646.10 139.90 648.37 155.94 657.09 167.87C661.75 174.24 668.18 179.34 676.52 181.98C684.65 184.55 693.47 184.43 702.55 182.38L695.60 151.04C690.75 152.13 687.89 151.84 686.37 151.42L686.08 151.34C684.91 150.97 683.95 150.35 682.98 149.10L682.78 148.84C680.19 145.29 678.09 138.04 677.71 126.58L677.68 125.45C677.15 101.86 683.68 73.95 686.03 61.99L654.73 55.77Z\"/><path fill=\"currentColor\" d=\"M694.67 11.50C701.03 22.50 697.26 36.57 686.26 42.92C675.25 49.27 661.19 45.50 654.84 34.50C648.49 23.50 652.25 9.43 663.26 3.08C674.26 -3.26 688.32 0.50 694.67 11.50Z\"/><path fill=\"currentColor\" d=\"M88.65 115.93C88.65 101.41 76.87 89.64 62.35 89.64H36.06V187.30H0V53.58H62.35C96.79 53.58 124.71 81.49 124.71 115.93V187.30H88.65V115.93Z\"/><path fill=\"currentColor\" d=\"M443.45 123.55C443.45 111.30 446.31 100.04 452.02 89.76C457.90 79.47 465.74 71.39 475.53 65.51C485.33 59.47 496.02 56.45 507.61 56.45C514.79 56.45 521.32 57.60 527.20 59.88C533.24 62.17 538.62 65.43 543.36 69.68V58.66H578.86V188.44H543.36V177.66C538.62 181.75 533.24 184.93 527.20 187.21C521.32 189.34 514.79 190.40 507.61 190.40C496.18 190.40 485.49 187.38 475.53 181.34C465.74 175.13 457.90 166.97 452.02 156.85C446.31 146.57 443.45 135.47 443.45 123.55ZM476.51 123.55C476.51 129.75 477.98 135.55 480.92 140.93C484.02 146.16 488.18 150.40 493.41 153.67C498.63 156.77 504.51 158.32 511.04 158.32C517.24 158.32 522.95 156.77 528.18 153.67C533.56 150.40 537.81 146.08 540.91 140.69C544.17 135.30 545.81 129.59 545.81 123.55C545.81 117.51 544.17 111.79 540.91 106.41C537.81 101.02 533.56 96.69 528.18 93.43C522.95 90.16 517.24 88.53 511.04 88.53C504.67 88.53 498.79 90.16 493.41 93.43C488.18 96.53 484.02 100.78 480.92 106.16C477.98 111.55 476.51 117.34 476.51 123.55Z\"/><path fill=\"currentColor\" d=\"M289.55 58.66H327.26L361.05 146.08L393.13 58.66H430.84L359.09 239.86H322.36L342.93 187.70L289.55 58.66Z\"/><path fill=\"currentColor\" d=\"M138.33 123.55C138.33 111.30 141.18 100.04 146.90 89.76C152.77 79.47 160.61 71.39 170.40 65.51C180.20 59.47 190.89 56.45 202.48 56.45C209.66 56.45 216.19 57.60 222.07 59.88C228.11 62.17 233.50 65.43 238.23 69.68V58.66H273.74V188.44H238.23V177.66C233.50 181.75 228.11 184.93 222.07 187.21C216.19 189.34 209.66 190.40 202.48 190.40C191.05 190.40 180.36 187.38 170.40 181.34C160.61 175.13 152.77 166.97 146.90 156.85C141.18 146.57 138.33 135.47 138.33 123.55ZM171.38 123.55C171.38 129.75 172.85 135.55 175.79 140.93C178.89 146.16 183.05 150.40 188.28 153.67C193.50 156.77 199.38 158.32 205.91 158.32C212.11 158.32 217.83 156.77 223.05 153.67C228.44 150.40 232.68 146.08 235.78 140.69C239.05 135.30 240.68 129.59 240.68 123.55C240.68 117.51 239.05 111.79 235.78 106.41C232.68 101.02 228.44 96.69 223.05 93.43C217.83 90.16 212.11 88.53 205.91 88.53C199.54 88.53 193.67 90.16 188.28 93.43C183.05 96.53 178.89 100.78 175.79 106.16C172.85 111.55 171.38 117.34 171.38 123.55Z\"/>';\n\n/** SVG du logo à la hauteur donnée (px) ; la largeur suit le ratio 838:240. */\nexport function logoSvg(height = 28, label = 'Naya ID'): string {\n const width = Math.round((height * 838) / 240);\n return (\n `<svg class=\"n-logo\" viewBox=\"${LOGO_VIEWBOX}\" width=\"${width}\" height=\"${height}\" role=\"img\" aria-label=\"${label}\" focusable=\"false\">` +\n `${LOGO_PATHS}</svg>`\n );\n}\n","import { escapeHtml } from './dom';\nimport { iconSvg, type NayaIconName } from './icons';\nimport { logoSvg } from './brand';\n\n/** Contrat d'un écran : un élément racine à monter et un nettoyage. */\nexport interface Screen {\n readonly el: HTMLElement;\n dispose(): void;\n /** Fermeture (Échap, bouton) autorisée ; défaut true. */\n readonly canClose?: boolean;\n /** Appelé quand l'onglet redevient visible / masqué. */\n onVisibility?(visible: boolean): void;\n}\n\n/** Marque Naya ID : le logo officiel, à la couleur du texte courant. */\nexport function brandHtml(height = 28): string {\n return `<span class=\"n-brand\">${logoSvg(height)}</span>`;\n}\n\n/** Indicateur des trois grandes étapes (Document · Selfie · Résultat). */\nexport function stepsDotsHtml(labels: string[], activeIndex: number): string {\n const steps = labels\n .map(\n (l, i) =>\n `<div class=\"n-step\"><span class=\"n-dot${i <= activeIndex ? ' on' : ''}\"></span>` +\n `<span class=\"n-dotlbl\">${escapeHtml(l)}</span></div>`,\n )\n .join('');\n return `<div class=\"n-dots\" aria-hidden=\"true\">${steps}</div>`;\n}\n\nexport interface ButtonOptions {\n icon?: NayaIconName;\n disabled?: boolean;\n act?: string;\n autofocus?: boolean;\n}\n\n/** CTA principal (plein, accent). `act` sert de sélecteur `data-act`. */\nexport function primaryButtonHtml(label: string, opts: ButtonOptions = {}): string {\n const act = opts.act ?? 'primary';\n return (\n `<button type=\"button\" class=\"n-btn n-btn-primary\" data-act=\"${act}\"${opts.disabled ? ' disabled' : ''}${opts.autofocus ? ' data-autofocus' : ''}>` +\n `${opts.icon ? iconSvg(opts.icon, 18) : ''}<span>${escapeHtml(label)}</span></button>`\n );\n}\n\n/** Bouton secondaire (contour). */\nexport function secondaryButtonHtml(label: string, act = 'secondary', icon?: NayaIconName): string {\n return `<button type=\"button\" class=\"n-btn n-btn-secondary\" data-act=\"${act}\">${icon ? iconSvg(icon, 18) : ''}<span>${escapeHtml(label)}</span></button>`;\n}\n\n/** Bouton discret (texte). */\nexport function ghostButtonHtml(label: string, act: string, icon?: NayaIconName): string {\n return `<button type=\"button\" class=\"n-btn n-btn-ghost\" data-act=\"${act}\">${icon ? iconSvg(icon, 16) : ''}<span>${escapeHtml(label)}</span></button>`;\n}\n\nexport type AlertTone = 'info' | 'warning' | 'error' | 'success';\n\nexport function alertHtml(tone: AlertTone, html: string, icon?: NayaIconName): string {\n const ico =\n icon ??\n (tone === 'error' ? 'alert' : tone === 'success' ? 'check' : tone === 'warning' ? 'alert' : 'info');\n return `<div class=\"n-alert n-alert-${tone}\" role=\"${tone === 'error' ? 'alert' : 'status'}\">${iconSvg(ico, 18)}<div>${html}</div></div>`;\n}\n\nexport interface FieldOptions {\n id: string;\n label: string;\n value?: string;\n type?: 'text' | 'date' | 'number';\n placeholder?: string;\n help?: string;\n required?: boolean;\n autocomplete?: string;\n inputmode?: string;\n maxlength?: number;\n}\n\nexport function fieldHtml(o: FieldOptions): string {\n return (\n `<div class=\"n-field\" data-field=\"${o.id}\">` +\n `<label for=\"n-f-${o.id}\">${escapeHtml(o.label)}${o.required ? ' <span class=\"req\" aria-hidden=\"true\">*</span>' : ''}</label>` +\n `<input id=\"n-f-${o.id}\" name=\"${o.id}\" type=\"${o.type ?? 'text'}\" value=\"${escapeHtml(o.value ?? '')}\"` +\n `${o.placeholder ? ` placeholder=\"${escapeHtml(o.placeholder)}\"` : ''}` +\n `${o.autocomplete ? ` autocomplete=\"${o.autocomplete}\"` : ' autocomplete=\"off\"'}` +\n `${o.inputmode ? ` inputmode=\"${o.inputmode}\"` : ''}` +\n `${o.maxlength ? ` maxlength=\"${o.maxlength}\"` : ''}` +\n `${o.required ? ' required aria-required=\"true\"' : ''} aria-describedby=\"n-f-${o.id}-msg\">` +\n `<p class=\"n-field-msg\" id=\"n-f-${o.id}-msg\">${o.help ? escapeHtml(o.help) : ''}</p>` +\n `</div>`\n );\n}\n\nexport interface ShellOptions {\n poweredBy: string;\n backLabel: string;\n closeLabel: string;\n /** Classe de l'écran, portée sur `<main>` pour scoper ses styles. */\n screenClass: string;\n dark?: boolean;\n canBack?: boolean;\n /** Défaut : true. */\n canClose?: boolean;\n onBack?: () => void;\n onClose?: () => void;\n /** Logo client affiché à côté de la mention « Propulsé par ». */\n clientLogoUrl?: string;\n}\n\n/**\n * Gabarit d'écran : en-tête (retour / fermer), zone de contenu, pied\n * « Propulsé par Naya ID ». Le titre `h1` de l'écran reçoit le focus au\n * montage (cf. host), pour les lecteurs d'écran.\n */\nexport function buildShell(opts: ShellOptions): { root: HTMLElement; content: HTMLElement } {\n const canClose = opts.canClose !== false;\n const root = document.createElement('div');\n root.className = 'n-shell' + (opts.dark ? ' n-dark' : '');\n const logo = opts.clientLogoUrl\n ? `<img class=\"n-client-logo\" src=\"${escapeHtml(opts.clientLogoUrl)}\" alt=\"\">`\n : '';\n root.innerHTML =\n `<header class=\"n-bar\">` +\n (opts.canBack\n ? `<button type=\"button\" class=\"n-round\" data-nav=\"back\" aria-label=\"${escapeHtml(opts.backLabel)}\">${iconSvg('back', 20)}</button>`\n : `<span class=\"n-spacer\"></span>`) +\n (canClose\n ? `<button type=\"button\" class=\"n-round\" data-nav=\"close\" aria-label=\"${escapeHtml(opts.closeLabel)}\">${iconSvg('close', 20)}</button>`\n : `<span class=\"n-spacer\"></span>`) +\n `</header>` +\n `<main class=\"n-content ${opts.screenClass}\"></main>` +\n `<footer class=\"n-powered\">${logo}<span>${escapeHtml(opts.poweredBy)}</span></footer>`;\n\n root.querySelector('[data-nav=\"back\"]')?.addEventListener('click', () => opts.onBack?.());\n root.querySelector('[data-nav=\"close\"]')?.addEventListener('click', () => opts.onClose?.());\n\n const content = root.querySelector('.n-content') as HTMLElement;\n return { root, content };\n}\n\n/** Illustration animée pour les conseils (document / selfie), en CSS pur. */\nexport function illustrationHtml(kind: 'document' | 'selfie'): string {\n if (kind === 'document') {\n return `<div class=\"n-illu n-illu-doc\" aria-hidden=\"true\"><div class=\"tbl\"></div><div class=\"card\"><span class=\"ph\"></span><span class=\"ln a\"></span><span class=\"ln b\"></span><span class=\"ln c\"></span></div><div class=\"glow\"></div></div>`;\n }\n return `<div class=\"n-illu n-illu-face\" aria-hidden=\"true\"><div class=\"oval\"><div class=\"head\"><span class=\"eye l\"></span><span class=\"eye r\"></span><span class=\"mouth\"></span></div></div><div class=\"light\"></div></div>`;\n}\n","import type { NayaFlow } from '../flow/flow';\nimport {\n buildShell,\n brandHtml,\n primaryButtonHtml,\n secondaryButtonHtml,\n stepsDotsHtml,\n type Screen,\n} from '../ui/components';\nimport { iconSvg } from '../ui/icons';\nimport { escapeHtml, multiline } from '../ui/dom';\n\n/** Écran 1 — Bienvenue. */\nexport class WelcomeScreen implements Screen {\n readonly el: HTMLElement;\n private busy = false;\n\n constructor(private readonly flow: NayaFlow) {\n const s = flow.strings;\n const config = flow.config;\n const { root, content } = buildShell({\n poweredBy: s.t('poweredBy'),\n backLabel: s.t('back'),\n closeLabel: s.t('close'),\n screenClass: 'n-welcome',\n onClose: () => flow.cancel(),\n });\n this.el = root;\n\n const stepLabels = [s.t('stepDocument'), s.t('stepSelfie'), s.t('stepResult')];\n const logo = config.clientLogoUrl\n ? `<span class=\"sep\"></span><img class=\"clientLogo\" src=\"${escapeHtml(config.clientLogoUrl)}\" alt=\"\">`\n : '';\n\n content.innerHTML = `\n <div class=\"pad\">\n <div class=\"brandRow\">${brandHtml()}${logo}</div>\n <div class=\"spacer\"></div>\n <div class=\"hero\">${iconSvg('shield', 56, 1.6)}</div>\n <h1 class=\"title\">${escapeHtml(s.t('welcomeTitle'))}</h1>\n <p class=\"body\">${multiline(s.t('welcomeSubtitle'))}</p>\n <div class=\"steps\">${stepsDotsHtml(stepLabels, 0)}</div>\n <div class=\"spacer\"></div>\n <div class=\"cta\">\n ${primaryButtonHtml(s.t('welcomeCta'), { act: 'start', autofocus: true })}\n ${flow.handoffAvailable ? secondaryButtonHtml(s.t('welcomeOnMobile'), 'handoff', 'phone') : ''}\n </div>\n <div class=\"secure\">${iconSvg('lock', 13, 2)}<span>${escapeHtml(s.t('welcomeSecurity'))}</span></div>\n </div>`;\n\n content.querySelector('[data-act=\"start\"]')?.addEventListener('click', () => {\n void this.start(false);\n });\n content.querySelector('[data-act=\"handoff\"]')?.addEventListener('click', () => {\n void this.start(true);\n });\n }\n\n dispose(): void {}\n\n private async start(handoff: boolean): Promise<void> {\n if (this.busy) return;\n this.busy = true;\n const flow = this.flow;\n flow.haptic('tap');\n try {\n // Session reprise : document, pays et défi sont ceux fixés par le backend.\n if (flow.resumed) {\n try {\n await flow.prepare();\n } catch {\n return; // l'hôte a déjà été notifié (cf. mountNayaFlow)\n }\n }\n flow.pendingHandoff = handoff;\n flow.go(flow.nextAfterWelcome());\n } finally {\n this.busy = false;\n }\n }\n}\n","import type { NayaFlow } from '../flow/flow';\nimport { buildShell, primaryButtonHtml, secondaryButtonHtml, type Screen } from '../ui/components';\nimport { iconSvg } from '../ui/icons';\nimport { escapeHtml, copyText } from '../ui/dom';\n\n/**\n * Écran 0 — Navigateur non pris en charge : navigateur intégré (WhatsApp,\n * Facebook…) qui bloque la caméra, page non sécurisée, ou capacités absentes.\n * Explique, propose de copier le lien pour l'ouvrir ailleurs, et rend la main.\n */\nexport class UnsupportedScreen implements Screen {\n readonly el: HTMLElement;\n\n constructor(private readonly flow: NayaFlow) {\n const s = flow.strings;\n const sup = flow.support;\n const { root, content } = buildShell({\n poweredBy: s.t('poweredBy'),\n backLabel: s.t('back'),\n closeLabel: s.t('close'),\n screenClass: 'n-unsupported',\n onClose: () => flow.cancel(),\n clientLogoUrl: flow.config.clientLogoUrl,\n });\n this.el = root;\n\n const title = sup.code === 'in_app_browser' ? s.t('unsupportedTitle') : s.t('unsupportedBrowserTitle');\n const body =\n sup.code === 'in_app_browser'\n ? s.t('unsupportedInApp', { name: sup.inAppBrowserName ?? 'app' })\n : sup.code === 'insecure_context'\n ? s.t('unsupportedInsecure')\n : s.t('unsupportedBrowser');\n const link = typeof location !== 'undefined' ? location.href : '';\n\n content.innerHTML = `\n <div class=\"pad center\">\n <div class=\"spacer\"></div>\n <div class=\"hero\">${iconSvg('external', 44, 1.8)}</div>\n <h1 class=\"title\">${escapeHtml(title)}</h1>\n <p class=\"body\">${escapeHtml(body)}</p>\n ${link ? `<div class=\"link\">${iconSvg('external', 16)}<code>${escapeHtml(link)}</code></div>` : ''}\n <div class=\"spacer\"></div>\n <div class=\"cta\">\n ${link ? primaryButtonHtml(s.t('copyLink'), { icon: 'copy', act: 'copy', autofocus: true }) : ''}\n ${secondaryButtonHtml(s.t('backToApp'), 'done')}\n </div>\n </div>`;\n\n content.querySelector('[data-act=\"copy\"]')?.addEventListener('click', async (e) => {\n const ok = await copyText(link);\n const btn = e.currentTarget as HTMLButtonElement;\n if (ok) btn.querySelector('span')!.textContent = s.t('copied');\n });\n content.querySelector('[data-act=\"done\"]')?.addEventListener('click', () => {\n flow.fail(new Error(body), sup.code ?? 'unsupported_browser');\n });\n flow.telemetry.track('unsupported', { code: sup.code ?? null, reason: sup.reason ?? null });\n }\n\n dispose(): void {}\n}\n","import type { NayaFlow } from '../flow/flow';\nimport { buildShell, primaryButtonHtml, type Screen } from '../ui/components';\nimport { iconSvg } from '../ui/icons';\nimport { escapeHtml } from '../ui/dom';\n\n/**\n * Écran 1b — Consentement explicite au traitement biométrique, horodaté côté\n * serveur dès que la session existe. L'hôte peut le désactiver s'il l'a déjà\n * recueilli (`consent: false`).\n */\nexport class ConsentScreen implements Screen {\n readonly el: HTMLElement;\n\n constructor(private readonly flow: NayaFlow) {\n const s = flow.strings;\n const opts = flow.config.consent === false ? null : flow.config.consent;\n const { root, content } = buildShell({\n poweredBy: s.t('poweredBy'),\n backLabel: s.t('back'),\n closeLabel: s.t('close'),\n screenClass: 'n-consent',\n canBack: flow.canGoBack,\n onBack: () => flow.back(),\n onClose: () => flow.cancel(),\n });\n this.el = root;\n\n const bullets = [s.t('welcomeSecurity'), s.t('livenessPrivacy')]\n .map((b) => `<li>${iconSvg('check', 16, 2.5)}<span>${escapeHtml(b)}</span></li>`)\n .join('');\n const policy = opts?.policyUrl\n ? `<a class=\"policy\" href=\"${escapeHtml(opts.policyUrl)}\" target=\"_blank\" rel=\"noopener noreferrer\">${escapeHtml(s.t('consentPolicy'))} ${iconSvg('external', 12)}</a>`\n : '';\n\n content.innerHTML = `\n <div class=\"pad\">\n <h1 class=\"title\">${escapeHtml(s.t('consentTitle'))}</h1>\n <p class=\"body\">${escapeHtml(s.t('consentBody', { org: s.t('consentOrg') }))}</p>\n <ul class=\"bullets\">${bullets}</ul>\n ${policy}\n <div class=\"spacer\"></div>\n <label class=\"check\" data-check>\n <input type=\"checkbox\" data-consent aria-describedby=\"n-consent-note\">\n <span id=\"n-consent-note\">${escapeHtml(s.t('consentCheckbox'))}</span>\n </label>\n ${primaryButtonHtml(s.t('consentCta'), { act: 'accept', disabled: true })}\n </div>`;\n\n const box = content.querySelector<HTMLInputElement>('[data-consent]')!;\n const label = content.querySelector<HTMLElement>('[data-check]')!;\n const cta = content.querySelector<HTMLButtonElement>('[data-act=\"accept\"]')!;\n box.addEventListener('change', () => {\n label.classList.toggle('on', box.checked);\n cta.disabled = !box.checked;\n });\n cta.addEventListener('click', () => {\n if (!box.checked) return;\n flow.haptic('tap');\n flow.grantConsent();\n flow.go(flow.nextAfterConsent());\n });\n }\n\n dispose(): void {}\n}\n","import type { NayaFlow } from '../flow/flow';\nimport { buildShell, ghostButtonHtml, alertHtml, type Screen } from '../ui/components';\n\nimport { escapeHtml, copyText } from '../ui/dom';\n\nconst POLL_MS = 3000;\n\n/**\n * Écran 1c — Relais d'un poste de bureau vers un téléphone : QR code de la\n * page hébergée qui reprend la session, puis suivi du statut jusqu'à la\n * décision. Le jeton voyage dans le fragment de l'URL, jamais dans un journal.\n */\nexport class HandoffScreen implements Screen {\n readonly el: HTMLElement;\n private readonly content: HTMLElement;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private disposed = false;\n private url = '';\n\n constructor(private readonly flow: NayaFlow) {\n const s = flow.strings;\n const { root, content } = buildShell({\n poweredBy: s.t('poweredBy'),\n backLabel: s.t('back'),\n closeLabel: s.t('close'),\n screenClass: 'n-handoff',\n canBack: flow.canGoBack,\n onBack: () => {\n flow.pendingHandoff = false;\n flow.back();\n },\n onClose: () => flow.cancel(),\n });\n this.el = root;\n this.content = content;\n\n content.innerHTML = `\n <div class=\"pad\">\n <h1 class=\"title\">${escapeHtml(s.t('handoffTitle'))}</h1>\n <p class=\"body\">${escapeHtml(s.t('handoffBody'))}</p>\n <div class=\"qr loading\" data-qr role=\"img\" aria-label=\"${escapeHtml(s.t('handoffQrLabel'))}\"><span class=\"loader\"></span></div>\n <div class=\"wait\" data-wait aria-live=\"polite\"><span class=\"loader sm\"></span><span>${escapeHtml(s.t('handoffWaiting'))}</span></div>\n <div data-msg></div>\n <div class=\"spacer\"></div>\n <div class=\"cta\">\n ${ghostButtonHtml(s.t('copyLink'), 'copy', 'copy')}\n ${ghostButtonHtml(s.t('handoffOrHere'), 'here', 'camera')}\n </div>\n </div>`;\n\n content.querySelector('[data-act=\"here\"]')?.addEventListener('click', () => {\n flow.pendingHandoff = false;\n flow.replace(flow.nextAfterSelect());\n });\n content.querySelector('[data-act=\"copy\"]')?.addEventListener('click', async (e) => {\n if (!this.url) return;\n const ok = await copyText(this.url);\n if (ok) (e.currentTarget as HTMLElement).querySelector('span')!.textContent = s.t('copied');\n });\n\n void this.load();\n }\n\n dispose(): void {\n this.disposed = true;\n if (this.timer) clearTimeout(this.timer);\n }\n\n private async load(): Promise<void> {\n const flow = this.flow;\n try {\n const info = await flow.requestHandoff();\n if (this.disposed) return;\n this.url = info.url;\n const qr = this.content.querySelector<HTMLElement>('[data-qr]')!;\n qr.classList.remove('loading');\n // SVG produit par l'API Naya (bibliothèque qrcode) : contenu de confiance.\n qr.innerHTML = info.qrSvg;\n this.poll();\n } catch (err) {\n if (this.disposed) return;\n const n = flow.normalizeError(err);\n this.content.querySelector('[data-msg]')!.innerHTML = alertHtml('error', escapeHtml(n.message));\n this.content.querySelector<HTMLElement>('[data-wait]')!.hidden = true;\n }\n }\n\n private poll(): void {\n if (this.disposed) return;\n this.timer = setTimeout(async () => {\n const flow = this.flow;\n const id = flow.session?.verificationId;\n if (!id) return;\n try {\n const v = await flow.client.getVerification(id);\n if (this.disposed) return;\n const wait = this.content.querySelector<HTMLElement>('[data-wait] span:last-child')!;\n if (v.hasDocument || v.hasSelfie || v.status === 'processing')\n wait.textContent = flow.strings.t('handoffProgress');\n if (v.status === 'approved' || v.status === 'review' || v.status === 'rejected') {\n flow.submitResponse = {\n status: v.status,\n decision: v.decision ?? undefined,\n reasonCodes: v.reasonCodes,\n };\n flow.telemetry.track('handoff_completed', { status: v.status });\n flow.replace('result');\n return;\n }\n if (flow.handoffInfo && Date.parse(flow.handoffInfo.expiresAt) < Date.now()) {\n this.content.querySelector('[data-msg]')!.innerHTML = alertHtml(\n 'warning',\n escapeHtml(flow.strings.t('handoffExpired')),\n );\n return;\n }\n } catch (err) {\n const n = flow.normalizeError(err);\n if (n.code === 'session_expired' || n.code === 'unauthorized') {\n this.content.querySelector('[data-msg]')!.innerHTML = alertHtml(\n 'warning',\n escapeHtml(flow.strings.t('handoffExpired')),\n );\n return;\n }\n }\n this.poll();\n }, POLL_MS);\n }\n}\n","import type { NayaFlow } from '../flow/flow';\nimport { type NayaCountryCode, type NayaDocumentType, countryLabel } from '../models/config';\nimport { buildShell, primaryButtonHtml, type Screen } from '../ui/components';\nimport { iconSvg, type NayaIconName } from '../ui/icons';\nimport { escapeHtml, multiline } from '../ui/dom';\n\nfunction docIcon(doc: NayaDocumentType): NayaIconName {\n switch (doc) {\n case 'cni':\n return 'id-card';\n case 'passeport':\n return 'passport';\n case 'permis':\n return 'car';\n }\n}\n\n/** Écran 2 — Choix du pays et du type de document. */\nexport class DocumentSelectionScreen implements Screen {\n readonly el: HTMLElement;\n private readonly content: HTMLElement;\n private country: NayaCountryCode;\n private document: NayaDocumentType | null;\n\n constructor(private readonly flow: NayaFlow) {\n const s = flow.strings;\n const config = flow.config;\n const lockedCountry = !!config.country;\n this.country = flow.country ?? config.country ?? config.countries[0]!;\n this.document = flow.document ?? (config.documentTypes.length === 1 ? config.documentTypes[0]! : null);\n\n const { root, content } = buildShell({\n poweredBy: s.t('poweredBy'),\n backLabel: s.t('back'),\n closeLabel: s.t('close'),\n screenClass: 'n-select',\n canBack: flow.canGoBack,\n onBack: () => flow.back(),\n onClose: () => flow.cancel(),\n });\n this.el = root;\n this.content = content;\n\n const chips = lockedCountry\n ? ''\n : `<div class=\"chips\" role=\"listbox\" aria-label=\"${escapeHtml(s.t('countryLabel'))}\">${config.countries\n .map(\n (code) =>\n `<button type=\"button\" class=\"chip${code === this.country ? ' on' : ''}\" role=\"option\" ` +\n `data-country=\"${code}\" aria-selected=\"${code === this.country}\">${escapeHtml(countryLabel(code))}</button>`,\n )\n .join('')}</div>`;\n\n const cards = config.documentTypes\n .map(\n (doc) =>\n `<button type=\"button\" class=\"card${doc === this.document ? ' on' : ''}\" data-doc=\"${doc}\" aria-pressed=\"${doc === this.document}\">` +\n `<span class=\"ico\">${iconSvg(docIcon(doc), 20)}</span>` +\n `<span class=\"lbl\">${escapeHtml(s.docLabel(doc))}</span>${iconSvg('chevron', 20, 2)}</button>`,\n )\n .join('');\n\n content.innerHTML = `\n <div class=\"pad\">\n <h1 class=\"title\">${multiline(s.t('docSelectTitle'))}</h1>\n <p class=\"body\">${escapeHtml(s.t('docSelectSubtitle'))}</p>\n ${chips}\n <div class=\"cards\">${cards}</div>\n <div class=\"spacer\"></div>\n ${primaryButtonHtml(s.t('continue'), { disabled: !this.document, act: 'next' })}\n </div>`;\n\n content\n .querySelectorAll<HTMLElement>('[data-country]')\n .forEach((btn) => btn.addEventListener('click', () => this.selectCountry(btn)));\n content\n .querySelectorAll<HTMLElement>('[data-doc]')\n .forEach((btn) => btn.addEventListener('click', () => this.selectDoc(btn)));\n content.querySelector('[data-act=\"next\"]')?.addEventListener('click', () => this.next());\n }\n\n dispose(): void {}\n\n private selectCountry(btn: HTMLElement): void {\n this.country = btn.getAttribute('data-country') as NayaCountryCode;\n this.content.querySelectorAll<HTMLElement>('.chip').forEach((c) => {\n const on = c === btn;\n c.classList.toggle('on', on);\n c.setAttribute('aria-selected', String(on));\n });\n }\n\n private selectDoc(btn: HTMLElement): void {\n this.document = btn.getAttribute('data-doc') as NayaDocumentType;\n this.content.querySelectorAll<HTMLElement>('.card').forEach((c) => {\n const on = c === btn;\n c.classList.toggle('on', on);\n c.setAttribute('aria-pressed', String(on));\n });\n const next = this.content.querySelector<HTMLButtonElement>('[data-act=\"next\"]');\n if (next) next.disabled = false;\n this.flow.haptic('tap');\n }\n\n private next(): void {\n if (!this.document) return;\n this.flow.country = this.country;\n this.flow.document = this.document;\n this.flow.go(this.flow.nextAfterSelect());\n }\n}\n","import type { NayaFlow } from '../flow/flow';\nimport { buildShell, illustrationHtml, primaryButtonHtml, type Screen } from '../ui/components';\nimport { escapeHtml } from '../ui/dom';\n\n/**\n * Écrans de conseils illustrés, avant la capture du document et avant le\n * selfie. Affichés une fois par parcours ; le préchargement du module de\n * vivacité démarre ici pour que le selfie n'attende pas.\n */\nexport class TipsScreen implements Screen {\n readonly el: HTMLElement;\n\n constructor(\n private readonly flow: NayaFlow,\n private readonly kind: 'document' | 'selfie',\n ) {\n const s = flow.strings;\n const { root, content } = buildShell({\n poweredBy: s.t('poweredBy'),\n backLabel: s.t('back'),\n closeLabel: s.t('close'),\n screenClass: 'n-tips',\n canBack: flow.canGoBack,\n onBack: () => flow.back(),\n onClose: () => flow.cancel(),\n });\n this.el = root;\n\n const title = kind === 'document' ? s.t('tipsDocTitle') : s.t('tipsSelfieTitle');\n const tips =\n kind === 'document'\n ? [s.t('tipsDoc1'), s.t('tipsDoc2'), s.t('tipsDoc3')]\n : [s.t('tipsSelfie1'), s.t('tipsSelfie2'), s.t('tipsSelfie3')];\n\n content.innerHTML = `\n <div class=\"pad\">\n ${illustrationHtml(kind)}\n <h1 class=\"title\">${escapeHtml(title)}</h1>\n <ol class=\"list\">${tips.map((t, i) => `<li><span class=\"num\">${i + 1}</span><span>${escapeHtml(t)}</span></li>`).join('')}</ol>\n <div class=\"spacer\"></div>\n ${primaryButtonHtml(s.t('understood'), { act: 'ok', autofocus: true })}\n </div>`;\n\n if (kind === 'document') flow.preloadLiveness();\n\n content.querySelector('[data-act=\"ok\"]')?.addEventListener('click', () => {\n flow.tipsShown[kind] = true;\n flow.haptic('tap');\n flow.replace(kind === 'document' ? 'capture-recto' : 'liveness');\n });\n }\n\n dispose(): void {}\n}\n","/**\n * Traitement d'image pour le web : compression, recadrage sur le gabarit,\n * mesures de qualité en direct (luminance, netteté, reflets, mouvement) et\n * import de fichier avec orientation EXIF.\n *\n * Les seuils sont un point de départ ; la télémétrie de capture sert à les\n * recalibrer sur des appareils réels.\n */\n\n/** Seuil de netteté (variance du Laplacien) au-delà duquel le cadre passe au vert. */\nexport const SHARPNESS_READY_THRESHOLD = 60;\n/** En dessous, l'éclairage est jugé insuffisant (luminance moyenne 0-255). */\nexport const LUMINANCE_MIN = 60;\n/** Au-dessus, l'image est surexposée. */\nexport const LUMINANCE_MAX = 235;\n/** Fraction de pixels saturés (reflet spéculaire) tolérée. */\nexport const GLARE_MAX_FRACTION = 0.035;\n/** Différence moyenne entre deux échantillons successifs au-delà de laquelle l'appareil bouge. */\nexport const MOTION_MAX = 14;\n\nexport interface Region {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n/** Zone du cadre de guidage document (fractions de la trame). */\nexport const DOCUMENT_REGION: Region = { x: 0.08, y: 0.22, w: 0.84, h: 0.56 };\n\nexport interface FrameQuality {\n luminance: number;\n sharpness: number;\n glare: number;\n motion: number;\n lightOk: boolean;\n sharpOk: boolean;\n glareOk: boolean;\n steady: boolean;\n /** Tout est bon : l'image peut être capturée. */\n ok: boolean;\n /** Premier problème à corriger, dans l'ordre d'importance. */\n issue: 'dark' | 'bright' | 'glare' | 'motion' | 'blur' | null;\n}\n\n/**\n * Mesures sur un tampon RGBA : luminance moyenne (Rec. 601), variance du\n * Laplacien 4-voisins, fraction de pixels saturés, mouvement par rapport à\n * l'échantillon précédent. Pure : testable sans navigateur.\n */\nexport function analyzePixels(\n data: Uint8ClampedArray,\n w: number,\n h: number,\n previous?: Float32Array | null,\n): FrameQuality & { luma: Float32Array } {\n const n = w * h;\n const lum = new Float32Array(n);\n let sumLum = 0;\n let saturated = 0;\n for (let i = 0, p = 0; i < data.length; i += 4, p++) {\n const r = data[i]!;\n const g = data[i + 1]!;\n const b = data[i + 2]!;\n const l = 0.299 * r + 0.587 * g + 0.114 * b;\n lum[p] = l;\n sumLum += l;\n if (r > 250 && g > 250 && b > 250) saturated++;\n }\n const luminance = n ? sumLum / n : 0;\n const glare = n ? saturated / n : 0;\n\n let sum = 0;\n let sumSq = 0;\n let count = 0;\n for (let y = 1; y < h - 1; y++) {\n for (let x = 1; x < w - 1; x++) {\n const idx = y * w + x;\n const lap = 4 * lum[idx]! - lum[idx - 1]! - lum[idx + 1]! - lum[idx - w]! - lum[idx + w]!;\n sum += lap;\n sumSq += lap * lap;\n count++;\n }\n }\n const mean = count ? sum / count : 0;\n const sharpness = count ? sumSq / count - mean * mean : 0;\n\n let motion = 0;\n if (previous && previous.length === n) {\n let diff = 0;\n for (let i = 0; i < n; i++) diff += Math.abs(lum[i]! - previous[i]!);\n motion = diff / n;\n }\n\n const lightOk = luminance >= LUMINANCE_MIN && luminance <= LUMINANCE_MAX;\n const sharpOk = sharpness >= SHARPNESS_READY_THRESHOLD;\n const glareOk = glare <= GLARE_MAX_FRACTION;\n const steady = !previous || motion <= MOTION_MAX;\n const issue: FrameQuality['issue'] =\n luminance < LUMINANCE_MIN\n ? 'dark'\n : luminance > LUMINANCE_MAX\n ? 'bright'\n : !glareOk\n ? 'glare'\n : !steady\n ? 'motion'\n : !sharpOk\n ? 'blur'\n : null;\n\n return {\n luminance,\n sharpness,\n glare,\n motion,\n lightOk,\n sharpOk,\n glareOk,\n steady,\n ok: issue === null,\n issue,\n luma: lum,\n };\n}\n\n/**\n * Échantillonne la zone du cadre de guidage sur un canvas réduit et mesure la\n * qualité. `state.previous` conserve la luminance de l'échantillon précédent\n * pour la détection de mouvement.\n */\nexport function measureFrameQuality(\n video: HTMLVideoElement,\n scratch: HTMLCanvasElement,\n state: { previous: Float32Array | null } = { previous: null },\n region: Region = DOCUMENT_REGION,\n sampleWidth = 240,\n): FrameQuality {\n const vw = video.videoWidth;\n const vh = video.videoHeight;\n const empty: FrameQuality = {\n luminance: 0,\n sharpness: 0,\n glare: 0,\n motion: 0,\n lightOk: false,\n sharpOk: false,\n glareOk: true,\n steady: true,\n ok: false,\n issue: 'dark',\n };\n if (vw < 8 || vh < 8) return empty;\n\n const sx = Math.floor(vw * region.x);\n const sy = Math.floor(vh * region.y);\n const sw = Math.floor(vw * region.w);\n const sh = Math.floor(vh * region.h);\n const scale = Math.min(1, sampleWidth / sw);\n const w = Math.max(8, Math.round(sw * scale));\n const h = Math.max(8, Math.round(sh * scale));\n\n scratch.width = w;\n scratch.height = h;\n const ctx = scratch.getContext('2d', { willReadFrequently: true });\n if (!ctx) return empty;\n ctx.drawImage(video, sx, sy, sw, sh, 0, 0, w, h);\n const { data } = ctx.getImageData(0, 0, w, h);\n const q = analyzePixels(data, w, h, state.previous);\n state.previous = q.luma;\n const { luma: _luma, ...rest } = q;\n return rest;\n}\n\n/**\n * Compresse une source (vidéo, canvas ou image) en data-URL JPEG. `region`\n * recadre sur une fraction de la source — la zone du gabarit document — ce\n * qui réduit le poids et améliore l'OCR.\n */\nexport function toJpegDataUrl(\n source: HTMLCanvasElement | HTMLVideoElement | HTMLImageElement | ImageBitmap,\n maxDimension = 1600,\n quality = 0.85,\n region?: Region,\n): string {\n const srcW =\n source instanceof HTMLVideoElement\n ? source.videoWidth\n : source instanceof HTMLImageElement\n ? source.naturalWidth\n : source.width;\n const srcH =\n source instanceof HTMLVideoElement\n ? source.videoHeight\n : source instanceof HTMLImageElement\n ? source.naturalHeight\n : source.height;\n const sx = region ? Math.floor(srcW * region.x) : 0;\n const sy = region ? Math.floor(srcH * region.y) : 0;\n const sw = region ? Math.floor(srcW * region.w) : srcW;\n const sh = region ? Math.floor(srcH * region.h) : srcH;\n\n const scale = Math.min(1, maxDimension / Math.max(sw, sh));\n const w = Math.max(1, Math.round(sw * scale));\n const h = Math.max(1, Math.round(sh * scale));\n\n const canvas = document.createElement('canvas');\n canvas.width = w;\n canvas.height = h;\n const ctx = canvas.getContext('2d');\n if (!ctx) return '';\n ctx.drawImage(source as CanvasImageSource, sx, sy, sw, sh, 0, 0, w, h);\n return canvas.toDataURL('image/jpeg', quality);\n}\n\n/** Compatibilité : trame vidéo entière en JPEG. */\nexport function canvasToJpegDataUrl(\n source: HTMLCanvasElement | HTMLVideoElement,\n maxDimension = 1600,\n quality = 0.85,\n): string {\n return toJpegDataUrl(source, maxDimension, quality);\n}\n\n/**\n * Lit un fichier image importé (orientation EXIF respectée quand le\n * navigateur le permet) et rend un JPEG compressé. Rejette si illisible.\n */\nexport async function fileToJpegDataUrl(file: File, maxDimension = 1600, quality = 0.85): Promise<string> {\n if (!file.type.startsWith('image/')) throw new Error('not-an-image');\n if (typeof createImageBitmap === 'function') {\n try {\n const bmp = await createImageBitmap(file, { imageOrientation: 'from-image' } as ImageBitmapOptions);\n const out = toJpegDataUrl(bmp, maxDimension, quality);\n bmp.close();\n if (out) return out;\n } catch {\n // Repli sur <img> ci-dessous.\n }\n }\n const url = URL.createObjectURL(file);\n try {\n const img = await new Promise<HTMLImageElement>((resolve, reject) => {\n const el = new Image();\n el.onload = () => resolve(el);\n el.onerror = () => reject(new Error('not-an-image'));\n el.src = url;\n });\n return toJpegDataUrl(img, maxDimension, quality);\n } finally {\n URL.revokeObjectURL(url);\n }\n}\n","import type { NayaFlow } from '../flow/flow';\nimport { buildShell, type Screen } from '../ui/components';\nimport { iconSvg } from '../ui/icons';\nimport { escapeHtml } from '../ui/dom';\nimport {\n DOCUMENT_REGION,\n type FrameQuality,\n type Region,\n fileToJpegDataUrl,\n measureFrameQuality,\n toJpegDataUrl,\n} from '../utils/image-utils';\nimport { hasEnvironmentCamera } from '../support/capabilities';\n\nconst CARD_ASPECT = 1.586;\nconst QUALITY_INTERVAL_MS = 300;\nconst STABLE_SAMPLES_BEFORE_CAPTURE = 3;\nconst COUNTDOWN_TICK_MS = 450;\n\n/**\n * Zone de la trame vidéo réellement visible dans le cadre (object-fit: cover),\n * pour mesurer la qualité et recadrer sur ce que l'utilisateur a aligné.\n */\nexport function visibleRegion(videoW: number, videoH: number, cardAspect = CARD_ASPECT, inset = 0): Region {\n if (videoW <= 0 || videoH <= 0) return DOCUMENT_REGION;\n const videoAspect = videoW / videoH;\n let x = 0,\n y = 0,\n w = 1,\n h = 1;\n if (videoAspect > cardAspect) {\n w = cardAspect / videoAspect;\n x = (1 - w) / 2;\n } else {\n h = videoAspect / cardAspect;\n y = (1 - h) / 2;\n }\n return { x: x + w * inset, y: y + h * inset, w: w * (1 - 2 * inset), h: h * (1 - 2 * inset) };\n}\n\n/**\n * Écrans 3-4 — Capture du document (recto puis verso pour la CNI).\n *\n * Caméra arrière, cadre au ratio carte, contrôles qualité en direct\n * (lumière, reflets, mouvement, netteté) avec consignes actionnables,\n * capture automatique quand tout est stable, import de fichier sur\n * ordinateur, bascule de caméra et lampe torche quand disponibles.\n */\nexport class DocumentCaptureScreen implements Screen {\n readonly el: HTMLElement;\n private readonly content: HTMLElement;\n private readonly scratch = document.createElement('canvas');\n private readonly qualityState = { previous: null as Float32Array | null };\n\n private video: HTMLVideoElement | null = null;\n private cardEl!: HTMLElement;\n private shutterEl!: HTMLButtonElement;\n private hintEl!: HTMLElement;\n private bannerEl!: HTMLElement;\n private countdownEl!: HTMLElement;\n private loadingEl!: HTMLElement;\n private lightPill!: HTMLElement;\n private sharpPill!: HTMLElement;\n private fileInput!: HTMLInputElement;\n\n private stream: MediaStream | null = null;\n private facing: 'environment' | 'user' = 'environment';\n private torchOn = false;\n private qualityTimer: ReturnType<typeof setInterval> | null = null;\n private countdownTimer: ReturnType<typeof setTimeout> | null = null;\n private stableCount = 0;\n private lastQuality: FrameQuality | null = null;\n private streaming = false;\n private capturing = false;\n private disposed = false;\n private hidden = false;\n\n constructor(\n private readonly flow: NayaFlow,\n private readonly side: 'recto' | 'verso',\n ) {\n const s = flow.strings;\n const { root, content } = buildShell({\n poweredBy: s.t('poweredBy'),\n backLabel: s.t('back'),\n closeLabel: s.t('close'),\n screenClass: 'n-capture',\n dark: true,\n canBack: flow.canGoBack,\n onBack: () => flow.back(),\n onClose: () => flow.cancel(),\n });\n this.el = root;\n this.content = content;\n\n const instruction = side === 'recto' ? s.t('captureRectoInstruction') : s.t('captureVersoInstruction');\n const auto = flow.config.capture.autoCapture;\n content.innerHTML = `\n <div class=\"pad\">\n <p class=\"instruction\" id=\"n-cap-instr\">${escapeHtml(instruction)}</p>\n <div class=\"cardWrap\">\n <div class=\"card\" data-card>\n <video class=\"preview\" playsinline muted autoplay aria-describedby=\"n-cap-instr\"></video>\n <div class=\"camMsg\" data-loading><span class=\"loader\"></span></div>\n <svg class=\"corners\" viewBox=\"0 0 100 63\" preserveAspectRatio=\"none\" aria-hidden=\"true\">\n <path d=\"M2,14 L2,6 Q2,2 6,2 L16,2\"/>\n <path d=\"M84,2 L94,2 Q98,2 98,6 L98,14\"/>\n <path d=\"M98,49 L98,57 Q98,61 94,61 L84,61\"/>\n <path d=\"M16,61 L6,61 Q2,61 2,57 L2,49\"/>\n </svg>\n <div class=\"countdown\" data-countdown hidden></div>\n </div>\n </div>\n <div class=\"banner\" data-banner role=\"status\" aria-live=\"polite\">${escapeHtml(auto ? s.t('captureHint') : s.t('captureManualHint'))}</div>\n <div class=\"pills\">\n <span class=\"pill\" data-pill=\"light\"><span class=\"pico\" data-ico>${iconSvg('sun', 15, 2.4)}</span><span>${escapeHtml(s.t('qualityLight'))}</span></span>\n <span class=\"pill\" data-pill=\"sharp\"><span class=\"pico\" data-ico>${iconSvg('focus', 15, 2.4)}</span><span>${escapeHtml(s.t('qualitySharpness'))}</span></span>\n </div>\n <div class=\"tools\">\n <button type=\"button\" class=\"tool\" data-act=\"import\" hidden>${iconSvg('upload', 22)}<span>${escapeHtml(s.t('importPhoto'))}</span></button>\n <button type=\"button\" class=\"tool\" data-act=\"flip\" hidden>${iconSvg('flip', 22)}<span>${escapeHtml(s.t('switchCamera'))}</span></button>\n <button type=\"button\" class=\"tool\" data-act=\"torch\" hidden aria-pressed=\"false\">${iconSvg('flash', 22)}<span>${escapeHtml(s.t('torch'))}</span></button>\n </div>\n <button type=\"button\" class=\"shutter\" data-act=\"capture\" disabled aria-label=\"${escapeHtml(s.t('shutterLabel'))}\"></button>\n <p class=\"hint\">${escapeHtml(auto ? s.t('captureHint') : s.t('captureManualHint'))}</p>\n <input type=\"file\" accept=\"image/*\" data-file hidden aria-hidden=\"true\">\n </div>`;\n\n this.video = content.querySelector('.preview');\n this.cardEl = content.querySelector('[data-card]')!;\n this.shutterEl = content.querySelector('[data-act=\"capture\"]')!;\n this.hintEl = content.querySelector('.hint')!;\n this.bannerEl = content.querySelector('[data-banner]')!;\n this.countdownEl = content.querySelector('[data-countdown]')!;\n this.loadingEl = content.querySelector('[data-loading]')!;\n this.lightPill = content.querySelector('[data-pill=\"light\"]')!;\n this.sharpPill = content.querySelector('[data-pill=\"sharp\"]')!;\n this.fileInput = content.querySelector('[data-file]')!;\n\n this.shutterEl.addEventListener('click', () => void this.capture());\n content.querySelector('[data-act=\"import\"]')!.addEventListener('click', () => this.fileInput.click());\n content.querySelector('[data-act=\"flip\"]')!.addEventListener('click', () => void this.flipCamera());\n content.querySelector('[data-act=\"torch\"]')!.addEventListener('click', () => void this.toggleTorch());\n this.fileInput.addEventListener('change', () => void this.importFile());\n\n if (flow.wantsFileUpload) this.showTool('import');\n flow.preloadLiveness();\n void this.startCamera();\n }\n\n dispose(): void {\n this.disposed = true;\n this.stopCamera();\n }\n\n onVisibility(visible: boolean): void {\n this.hidden = !visible;\n if (!visible) {\n this.cancelCountdown();\n }\n }\n\n private showTool(name: 'import' | 'flip' | 'torch', on = true): void {\n const b = this.content.querySelector<HTMLElement>(`[data-act=\"${name}\"]`);\n if (b) b.hidden = !on;\n }\n\n // ── Caméra ─────────────────────────────────────────────────────────────────\n private async startCamera(): Promise<void> {\n if (!navigator.mediaDevices?.getUserMedia) {\n this.showCameraError(new DOMException('no-mediadevices', 'NotFoundError'));\n return;\n }\n try {\n const stream = await navigator.mediaDevices.getUserMedia({\n video: { facingMode: { ideal: this.facing }, width: { ideal: 1920 } },\n audio: false,\n });\n // L'écran a pu être quitté pendant l'attente d'autorisation.\n if (this.disposed || !this.video) {\n stream.getTracks().forEach((t) => t.stop());\n return;\n }\n this.stream = stream;\n this.video.srcObject = stream;\n await this.video.play().catch(() => {});\n this.loadingEl.hidden = true;\n this.streaming = true;\n this.updateReady();\n this.startQualityLoop();\n void this.detectTools(stream);\n } catch (err) {\n this.showCameraError(err);\n }\n }\n\n private async detectTools(stream: MediaStream): Promise<void> {\n const track = stream.getVideoTracks()[0];\n const caps = (track?.getCapabilities?.() ?? {}) as { torch?: boolean; facingMode?: string[] };\n if (caps.torch) this.showTool('torch');\n const env = await hasEnvironmentCamera();\n if (this.disposed) return;\n if (env === false) this.showTool('import');\n try {\n const cams = (await navigator.mediaDevices.enumerateDevices()).filter((d) => d.kind === 'videoinput');\n if (cams.length > 1) this.showTool('flip');\n } catch {\n /* ignore */\n }\n }\n\n private async flipCamera(): Promise<void> {\n this.facing = this.facing === 'environment' ? 'user' : 'environment';\n this.torchOn = false;\n this.stopCamera();\n this.loadingEl.hidden = false;\n this.loadingEl.innerHTML = '<span class=\"loader\"></span>';\n if (this.video) this.video.hidden = false;\n await this.startCamera();\n }\n\n private async toggleTorch(): Promise<void> {\n const track = this.stream?.getVideoTracks()[0];\n if (!track) return;\n this.torchOn = !this.torchOn;\n try {\n await track.applyConstraints({ advanced: [{ torch: this.torchOn } as MediaTrackConstraintSet] });\n const b = this.content.querySelector<HTMLElement>('[data-act=\"torch\"]')!;\n b.classList.toggle('on', this.torchOn);\n b.setAttribute('aria-pressed', String(this.torchOn));\n } catch {\n this.torchOn = false;\n }\n }\n\n private showCameraError(err: unknown): void {\n if (this.disposed) return;\n const n = this.flow.normalizeError(err, 'camera_unavailable');\n this.flow.telemetry.track('camera_error', { code: n.code, side: this.side });\n if (this.video) this.video.hidden = true;\n this.loadingEl.hidden = false;\n this.loadingEl.innerHTML = `<span>${escapeHtml(n.message)}</span><button type=\"button\" class=\"n-btn n-btn-secondary\" data-act=\"retry-cam\" style=\"width:auto;min-height:40px\">${escapeHtml(this.flow.strings.t('retry'))}</button>`;\n this.loadingEl.querySelector('[data-act=\"retry-cam\"]')?.addEventListener('click', () => {\n this.loadingEl.innerHTML = '<span class=\"loader\"></span>';\n if (this.video) this.video.hidden = false;\n void this.startCamera();\n });\n // Sans caméra, l'import de fichier reste une issue.\n this.showTool('import');\n }\n\n private stopCamera(): void {\n if (this.qualityTimer) clearInterval(this.qualityTimer);\n this.qualityTimer = null;\n this.cancelCountdown();\n this.stream?.getTracks().forEach((t) => t.stop());\n this.stream = null;\n this.streaming = false;\n }\n\n // ── Qualité et capture automatique ─────────────────────────────────────────\n private startQualityLoop(): void {\n this.qualityTimer = setInterval(() => {\n if (this.capturing || this.hidden || !this.video || this.video.videoWidth < 8) return;\n const region = visibleRegion(this.video.videoWidth, this.video.videoHeight, CARD_ASPECT, 0.06);\n const q = measureFrameQuality(this.video, this.scratch, this.qualityState, region);\n this.lastQuality = q;\n this.render(q);\n if (this.flow.config.capture.autoCapture) this.autoCapture(q);\n }, QUALITY_INTERVAL_MS);\n }\n\n private render(q: FrameQuality): void {\n const s = this.flow.strings;\n this.lightPill.classList.toggle('ok', q.lightOk && q.glareOk);\n this.lightPill.querySelector('[data-ico]')!.innerHTML = iconSvg(\n q.lightOk && q.glareOk ? 'check' : 'sun',\n 15,\n 2.4,\n );\n this.sharpPill.classList.toggle('ok', q.sharpOk && q.steady);\n this.sharpPill.querySelector('[data-ico]')!.innerHTML = iconSvg(\n q.sharpOk && q.steady ? 'check' : 'focus',\n 15,\n 2.4,\n );\n\n const msg =\n q.issue === 'dark'\n ? s.t('guideTooDark')\n : q.issue === 'bright'\n ? s.t('guideTooBright')\n : q.issue === 'glare'\n ? s.t('guideGlare')\n : q.issue === 'motion'\n ? s.t('guideHoldSteady')\n : q.issue === 'blur'\n ? s.t('guideBlurry')\n : s.t('guideGood');\n if (this.bannerEl.textContent !== msg) this.bannerEl.textContent = msg;\n this.bannerEl.classList.toggle('good', q.ok);\n this.cardEl.classList.toggle('ready', q.ok);\n this.shutterEl.classList.toggle('ready', q.ok);\n this.hintEl.classList.toggle('ready', q.ok);\n this.updateReady();\n }\n\n private autoCapture(q: FrameQuality): void {\n if (q.ok) {\n this.stableCount += 1;\n if (this.stableCount === STABLE_SAMPLES_BEFORE_CAPTURE && !this.countdownTimer) this.countdown(2);\n } else {\n this.stableCount = 0;\n this.cancelCountdown();\n }\n }\n\n private countdown(n: number): void {\n const s = this.flow.strings;\n this.countdownEl.hidden = false;\n this.countdownEl.textContent = String(n);\n this.bannerEl.textContent = s.t('captureAuto', { n });\n this.countdownTimer = setTimeout(() => {\n this.countdownTimer = null;\n if (this.disposed || !this.lastQuality?.ok) {\n this.cancelCountdown();\n return;\n }\n if (n > 1) this.countdown(n - 1);\n else void this.capture();\n }, COUNTDOWN_TICK_MS);\n }\n\n private cancelCountdown(): void {\n if (this.countdownTimer) clearTimeout(this.countdownTimer);\n this.countdownTimer = null;\n this.countdownEl.hidden = true;\n this.stableCount = 0;\n }\n\n private updateReady(): void {\n this.shutterEl.disabled = !this.streaming || this.capturing;\n }\n\n // ── Capture ────────────────────────────────────────────────────────────────\n private async capture(): Promise<void> {\n if (!this.video || this.capturing || !this.streaming) return;\n this.capturing = true;\n this.cancelCountdown();\n this.shutterEl.innerHTML = '<span class=\"loader sm\"></span>';\n this.updateReady();\n try {\n const region = visibleRegion(this.video.videoWidth, this.video.videoHeight, CARD_ASPECT, 0.01);\n const dataUrl = toJpegDataUrl(this.video, this.flow.imageMaxDimension, 0.85, region);\n this.flow.telemetry.track('capture_quality', {\n side: this.side,\n source: 'camera',\n auto: this.flow.config.capture.autoCapture,\n luminance: Math.round(this.lastQuality?.luminance ?? 0),\n sharpness: Math.round(this.lastQuality?.sharpness ?? 0),\n glare: Number((this.lastQuality?.glare ?? 0).toFixed(3)),\n facing: this.facing,\n delegate: null,\n });\n this.stopCamera();\n this.accept(dataUrl);\n } catch (err) {\n this.flow.log.warn('capture failed', err);\n this.capturing = false;\n this.shutterEl.innerHTML = '';\n this.updateReady();\n }\n }\n\n private async importFile(): Promise<void> {\n const file = this.fileInput.files?.[0];\n this.fileInput.value = '';\n if (!file || this.capturing) return;\n this.capturing = true;\n try {\n const dataUrl = await fileToJpegDataUrl(file, this.flow.imageMaxDimension);\n this.flow.telemetry.track('capture_quality', {\n side: this.side,\n source: 'file',\n sizeKb: Math.round(file.size / 1024),\n });\n this.stopCamera();\n this.accept(dataUrl);\n } catch {\n this.capturing = false;\n this.bannerEl.textContent = this.flow.strings.t('fileInvalid');\n this.bannerEl.classList.remove('good');\n }\n }\n\n private accept(dataUrl: string): void {\n const flow = this.flow;\n flow.haptic('tap');\n flow.captureAttempts += 1;\n if (this.side === 'recto') flow.rectoBase64 = dataUrl;\n else flow.versoBase64 = dataUrl;\n flow.emit('document_captured', { side: this.side });\n\n const next = flow.nextAfterCapture(this.side);\n // Dernière face : l'envoi (session + document) part en arrière-plan\n // pendant que l'utilisateur enchaîne sur le selfie.\n if (next !== 'capture-verso') flow.startDocumentUpload();\n this.capturing = false;\n flow.go(next);\n }\n}\n","import type { NayaFlow } from '../flow/flow';\nimport { buildShell, ghostButtonHtml, primaryButtonHtml, type Screen } from '../ui/components';\nimport { iconSvg, type NayaIconName } from '../ui/icons';\nimport { escapeHtml } from '../ui/dom';\nimport { toJpegDataUrl } from '../utils/image-utils';\nimport {\n LivenessChallenge,\n type ChallengeStep,\n type KeyFrame,\n type LivenessPhase,\n} from '../liveness/liveness-challenge';\nimport { FaceTracker } from '../liveness/face-tracker';\n\nconst RING_PATH = 'M105,4 A101,131 0 0 1 105,266 A101,131 0 0 1 105,4 Z';\n/** Cadence maximale de détection : inutile d'analyser 60 trames/s sur mobile. */\nconst DETECT_INTERVAL_MS = 66;\nconst KEYFRAME_MAX_DIMENSION = 640;\nconst MAX_TIMEOUTS_BEFORE_PASSIVE = 2;\n/**\n * Après le dernier geste, temps laissé à l'utilisateur pour redresser la tête\n * avant de prendre la photo telle quelle (le serveur sait alors qu'elle n'a\n * pas été prise « tête droite »).\n */\nconst HOLD_TIMEOUT_MS = 6000;\n\nfunction stepIcon(step: ChallengeStep): NayaIconName {\n switch (step) {\n case 'blink':\n return 'eye';\n case 'turn-left':\n return 'rotate-left';\n case 'turn-right':\n return 'rotate-right';\n case 'smile':\n return 'smile';\n }\n}\n\n/**\n * Écran 5 — Selfie avec défi de vivacité imposé par le serveur.\n *\n * Caméra frontale, chaque trame alimente le suivi facial puis la machine à\n * états (visage → gestes dans l'ordre du serveur). Les trames clés et la\n * preuve horodatée partent avec le selfie ; l'analyse locale ne sert qu'à\n * guider l'utilisateur, la décision de vivacité revient au serveur.\n */\nexport class LivenessScreen implements Screen {\n readonly el: HTMLElement;\n private readonly content: HTMLElement;\n\n private video: HTMLVideoElement | null = null;\n private progEl!: SVGPathElement;\n private ringEl!: SVGElement;\n private instrEl!: HTMLElement;\n private instrIcon!: HTMLElement;\n private instrText!: HTMLElement;\n private stepEls: HTMLElement[] = [];\n private loadingEl!: HTMLElement;\n private panelEl!: HTMLElement;\n private ovalWrap!: HTMLElement;\n\n private challenge: LivenessChallenge;\n private readonly tracker = new FaceTracker();\n private stream: MediaStream | null = null;\n private rafId = 0;\n private lastDetect = 0;\n private phase: LivenessPhase = 'searching-face';\n private guidance: string | null = null;\n private frames = new Map<KeyFrame, string>();\n private streaming = false;\n private finishing = false;\n private disposed = false;\n private hidden = false;\n private watchdog: ReturnType<typeof setTimeout> | null = null;\n private timeouts = 0;\n\n constructor(private readonly flow: NayaFlow) {\n const s = flow.strings;\n this.challenge = new LivenessChallenge(flow.challengeSteps);\n const { root, content } = buildShell({\n poweredBy: s.t('poweredBy'),\n backLabel: s.t('back'),\n closeLabel: s.t('close'),\n screenClass: 'n-liveness',\n onClose: () => flow.cancel(),\n });\n this.el = root;\n this.content = content;\n\n const csteps = [s.t('livenessStepFace'), ...this.challenge.steps.map((st) => s.challengeInstruction(st))]\n .map(\n (label, i) =>\n `<div class=\"cstep\"><span class=\"cdot\" data-cdot>${i === 0 ? iconSvg('user', 13, 2.5) : ''}</span><span class=\"clbl\">${escapeHtml(label)}</span></div>`,\n )\n .join('');\n\n content.innerHTML = `\n <div class=\"pad\">\n <h1 class=\"title\">${escapeHtml(s.t('livenessTitle'))}</h1>\n <p class=\"sub\">${escapeHtml(s.t('livenessSubtitle'))}</p>\n <div class=\"ovalWrap\" data-oval>\n <div class=\"oval\">\n <video class=\"preview\" playsinline muted autoplay></video>\n <div class=\"camMsg\" data-loading><span class=\"loader\"></span><span>${escapeHtml(s.t('livenessLoading'))}</span></div>\n </div>\n <svg class=\"ring\" viewBox=\"0 0 210 270\" aria-hidden=\"true\" data-ring>\n <path class=\"track\" d=\"${RING_PATH}\"/>\n <path class=\"prog\" data-prog d=\"${RING_PATH}\" pathLength=\"100\" stroke-dasharray=\"100\" stroke-dashoffset=\"100\"/>\n </svg>\n </div>\n <div class=\"instruction\" data-instr role=\"status\" aria-live=\"assertive\">\n <span data-instr-ico>${iconSvg('focus', 22, 2)}</span>\n <span data-instr-text>${escapeHtml(s.t('livenessLookStraight'))}</span>\n </div>\n <div class=\"steps\">${csteps}</div>\n <div data-panel></div>\n <div class=\"spacer\"></div>\n <p class=\"privacy\">${escapeHtml(s.t('livenessPrivacy'))}</p>\n </div>`;\n\n this.video = content.querySelector('.preview');\n this.progEl = content.querySelector('[data-prog]')!;\n this.ringEl = content.querySelector('[data-ring]')!;\n this.instrEl = content.querySelector('[data-instr]')!;\n this.instrIcon = content.querySelector('[data-instr-ico]')!;\n this.instrText = content.querySelector('[data-instr-text]')!;\n this.loadingEl = content.querySelector('[data-loading]')!;\n this.panelEl = content.querySelector('[data-panel]')!;\n this.ovalWrap = content.querySelector('[data-oval]')!;\n this.stepEls = Array.from(content.querySelectorAll<HTMLElement>('[data-cdot]'));\n\n void this.start();\n }\n\n dispose(): void {\n this.disposed = true;\n this.teardown();\n }\n\n onVisibility(visible: boolean): void {\n this.hidden = !visible;\n if (visible && this.streaming && !this.finishing) this.loop();\n }\n\n // ── Démarrage ──────────────────────────────────────────────────────────────\n private async start(): Promise<void> {\n const s = this.flow.strings;\n if (!navigator.mediaDevices?.getUserMedia) {\n this.showError(s.t('cameraUnavailable'), 'camera_unavailable');\n return;\n }\n try {\n // Le modèle et son WASM sont normalement déjà en cache (préchargement).\n await this.tracker.init(this.flow.config.livenessAssets);\n this.flow.livenessDelegate = this.tracker.activeDelegate;\n } catch (err) {\n this.flow.log.error('liveness assets', err);\n this.flow.telemetry.track('liveness_assets_error');\n this.showError(s.t('livenessAssetsError'), 'liveness_assets', true);\n return;\n }\n if (this.disposed) return;\n try {\n const stream = await navigator.mediaDevices.getUserMedia({\n video: { facingMode: { ideal: 'user' }, width: { ideal: 1280 } },\n audio: false,\n });\n if (this.disposed || !this.video) {\n stream.getTracks().forEach((t) => t.stop());\n return;\n }\n this.stream = stream;\n this.video.srcObject = stream;\n await this.video.play().catch(() => {});\n this.loadingEl.hidden = true;\n this.streaming = true;\n this.armWatchdog();\n this.loop();\n } catch (err) {\n const n = this.flow.normalizeError(err, 'camera_unavailable');\n this.flow.telemetry.track('camera_error', { code: n.code, side: 'selfie' });\n this.showError(n.message, n.code, true);\n }\n }\n\n // ── Boucle de détection ────────────────────────────────────────────────────\n private loop = (): void => {\n if (!this.video || this.finishing || this.disposed || this.hidden) return;\n const now = performance.now();\n if (now - this.lastDetect >= DETECT_INTERVAL_MS && this.tracker.ready && this.video.videoWidth > 8) {\n this.lastDetect = now;\n try {\n const signals = this.tracker.detect(this.video, now);\n const out = this.challenge.onFrame(signals);\n if (out.capture) this.captureKeyFrame(out.capture);\n if (out.completed) this.onCompleted(out.completed);\n if (this.challenge.phase === 'hold' && this.challenge.holdElapsed > HOLD_TIMEOUT_MS) {\n this.flow.telemetry.track('liveness_hold_timeout', { guidance: out.guidance });\n this.challenge.forceDone();\n }\n if (out.changed || out.guidance !== this.guidance) {\n this.guidance = out.guidance;\n this.render(this.challenge.phase, out.guidance);\n }\n if (this.challenge.isDone) {\n void this.finish('active');\n return;\n }\n } catch {\n // Trame illisible : ignorée, la suivante arrive au prochain rAF.\n }\n }\n this.rafId = requestAnimationFrame(this.loop);\n };\n\n private captureKeyFrame(kind: KeyFrame): void {\n if (!this.video || this.frames.has(kind)) return;\n try {\n this.frames.set(kind, toJpegDataUrl(this.video, KEYFRAME_MAX_DIMENSION, 0.75));\n } catch {\n /* ignore */\n }\n }\n\n private onCompleted(step: ChallengeStep): void {\n const s = this.flow.strings;\n this.flow.haptic('success');\n const proof = this.challenge.proof;\n this.flow.telemetry.track('liveness_step', { step, at: proof[proof.length - 1]?.at ?? 0 });\n this.flow.emit('liveness_step', { step });\n const toast = document.createElement('div');\n toast.className = 'toast';\n toast.innerHTML = `${iconSvg('check', 12, 3)}<span>${escapeHtml(s.t('livenessDetected'))}</span>`;\n this.ovalWrap.appendChild(toast);\n setTimeout(() => toast.remove(), 900);\n this.armWatchdog();\n }\n\n private render(phase: LivenessPhase, guidance: string | null): void {\n this.phase = phase;\n const s = this.flow.strings;\n\n this.progEl.setAttribute('stroke-dashoffset', String(100 * (1 - this.challenge.progress)));\n this.ringEl.classList.toggle('done', this.challenge.isDone);\n\n let icon: NayaIconName = 'focus';\n let text = s.t('livenessLookStraight');\n let cls = '';\n if (guidance && phase !== 'done') {\n cls = 'guide';\n text =\n guidance === 'multiple-faces'\n ? s.t('livenessOneFace')\n : guidance === 'too-small'\n ? s.t('livenessCloser')\n : guidance === 'too-large'\n ? s.t('livenessFarther')\n : guidance === 'off-center'\n ? s.t('livenessCenter')\n : guidance === 'tilted'\n ? s.t('livenessStraighten')\n : guidance === 'eyes-closed'\n ? s.t('livenessEyesOpen')\n : s.t('livenessLookStraight');\n icon = guidance === 'multiple-faces' ? 'user' : guidance === 'eyes-closed' ? 'eye' : 'focus';\n } else if (phase === 'done' || phase === 'hold') {\n // Gestes terminés : tête droite et immobile, la photo arrive.\n cls = 'ok';\n icon = 'hourglass';\n text = s.t('livenessHold');\n } else if (phase !== 'searching-face') {\n icon = stepIcon(phase);\n text = s.challengeInstruction(phase);\n }\n this.instrIcon.innerHTML = iconSvg(icon, 22, 2);\n if (this.instrText.textContent !== text) this.instrText.textContent = text;\n this.instrEl.className = `instruction ${cls}`.trim();\n\n // Pastilles : visage puis chaque geste.\n const done =\n phase === 'done' || phase === 'hold'\n ? this.stepEls.length\n : phase === 'searching-face'\n ? 0\n : 1 + this.challenge.completedCount;\n this.stepEls.forEach((dot, i) => {\n const isDone = i < done;\n const active = i === done && phase !== 'done' && phase !== 'hold';\n dot.classList.toggle('done', isDone);\n dot.classList.toggle('active', active);\n if (i > 0) dot.innerHTML = isDone ? iconSvg('check', 13, 3) : '';\n });\n }\n\n // ── Délai dépassé, parcours passif ─────────────────────────────────────────\n private armWatchdog(): void {\n if (this.watchdog) clearTimeout(this.watchdog);\n this.watchdog = setTimeout(() => this.onTimeout(), this.flow.config.liveness.timeoutMs);\n }\n\n private onTimeout(): void {\n if (this.disposed || this.finishing || this.challenge.isDone) return;\n this.timeouts += 1;\n this.flow.telemetry.track('liveness_timeout', {\n count: this.timeouts,\n phase: this.phase,\n completed: this.challenge.completedCount,\n });\n cancelAnimationFrame(this.rafId);\n const s = this.flow.strings;\n const allowPassive =\n this.flow.config.liveness.allowPassive && this.timeouts >= Math.min(MAX_TIMEOUTS_BEFORE_PASSIVE, 2);\n this.panelEl.innerHTML = `\n <div class=\"n-alert n-alert-warning\" role=\"alert\"><div><strong>${escapeHtml(s.t('livenessTimeoutTitle'))}</strong><br>${escapeHtml(s.t('livenessTimeoutBody'))}</div></div>\n <div class=\"cta\" style=\"margin-top:10px\">\n ${primaryButtonHtml(s.t('retry'), { act: 'retry', icon: 'refresh' })}\n ${allowPassive ? ghostButtonHtml(s.t('livenessPassiveCta'), 'passive', 'hand') : ''}\n </div>\n ${allowPassive ? `<p class=\"privacy\" style=\"margin-top:6px\">${escapeHtml(s.t('livenessPassiveNote'))}</p>` : ''}`;\n this.panelEl.querySelector('[data-act=\"retry\"]')?.addEventListener('click', () => this.restart());\n this.panelEl\n .querySelector('[data-act=\"passive\"]')\n ?.addEventListener('click', () => void this.finish('passive'));\n }\n\n private restart(): void {\n this.panelEl.innerHTML = '';\n this.challenge = new LivenessChallenge(this.flow.challengeSteps);\n this.frames.clear();\n this.guidance = null;\n this.render('searching-face', null);\n this.armWatchdog();\n this.loop();\n }\n\n // ── Fin ────────────────────────────────────────────────────────────────────\n private async finish(mode: 'active' | 'passive'): Promise<void> {\n if (this.finishing) return;\n this.finishing = true;\n cancelAnimationFrame(this.rafId);\n if (this.watchdog) clearTimeout(this.watchdog);\n this.panelEl.innerHTML = '';\n if (mode === 'active') this.render('done', null);\n\n // Libérer MediaPipe (contexte WebGL/GPU) AVANT la capture : sur iOS Safari,\n // dessiner la vidéo sur un canvas 2D pendant que MediaPipe détient sa\n // texture GPU corrompt l'image — ce que l'anti-fraude serveur interprète,\n // à raison, comme une photo d'écran.\n this.tracker.close();\n\n try {\n await this.waitFrames(3);\n await new Promise((r) => setTimeout(r, 300));\n if (this.disposed) return;\n const flow = this.flow;\n if (this.video && this.video.videoWidth > 8) {\n flow.selfieBase64 = toJpegDataUrl(this.video, 1080, 0.85);\n flow.livenessMode = mode;\n flow.livenessScore = mode === 'active' ? this.challenge.score() : 0;\n flow.livenessProof = mode === 'active' ? this.challenge.proof : [];\n const order: KeyFrame[] = ['neutral', 'eyes-closed', 'turned', 'smile'];\n flow.livenessFrames =\n mode === 'active' ? order.map((k) => this.frames.get(k)).filter((f): f is string => !!f) : [];\n }\n this.stopStream();\n flow.telemetry.track('liveness_done', {\n mode,\n delegate: flow.livenessDelegate,\n steps: this.challenge.completedCount,\n timeouts: this.timeouts,\n settled: mode === 'active' ? this.challenge.settled : null,\n });\n flow.emit('liveness_done', { mode });\n flow.haptic('success');\n flow.replace(flow.nextAfterLiveness());\n } catch {\n this.finishing = false;\n this.stopStream();\n this.showError(this.flow.strings.t('cameraGeneric'), 'camera_busy', true);\n }\n }\n\n /** Attend `n` trames d'affichage — laisse le compositeur présenter du frais. */\n private waitFrames(n: number): Promise<void> {\n return new Promise((resolve) => {\n let i = 0;\n const tick = (): void => {\n if (++i >= n) resolve();\n else requestAnimationFrame(tick);\n };\n requestAnimationFrame(tick);\n });\n }\n\n private showError(msg: string, code: string, retry = false): void {\n if (this.disposed) return;\n if (this.video) this.video.hidden = true;\n this.loadingEl.hidden = false;\n this.loadingEl.innerHTML = `<span>${escapeHtml(msg)}</span>${retry ? `<button type=\"button\" class=\"n-btn n-btn-secondary\" data-act=\"retry-cam\" style=\"width:auto;min-height:40px;color:#fff;border-color:#fff\">${escapeHtml(this.flow.strings.t('retry'))}</button>` : ''}`;\n this.loadingEl.querySelector('[data-act=\"retry-cam\"]')?.addEventListener('click', () => {\n this.loadingEl.innerHTML = '<span class=\"loader\"></span>';\n if (this.video) this.video.hidden = false;\n this.teardown();\n this.finishing = false;\n void this.start();\n });\n this.flow.log.warn('liveness error', { code, msg });\n }\n\n private stopStream(): void {\n this.stream?.getTracks().forEach((t) => t.stop());\n this.stream = null;\n this.streaming = false;\n }\n\n private teardown(): void {\n cancelAnimationFrame(this.rafId);\n if (this.watchdog) clearTimeout(this.watchdog);\n this.tracker.close();\n this.stopStream();\n }\n}\n","/** Dates de documents : format ISO `YYYY-MM-DD` attendu par l'API. */\n\nconst ISO = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\n\nexport function parseIsoDate(value: string | undefined | null): Date | null {\n if (!value) return null;\n const m = value.trim().match(ISO);\n if (!m) return null;\n const y = Number(m[1]);\n const mo = Number(m[2]);\n const d = Number(m[3]);\n if (mo < 1 || mo > 12 || d < 1 || d > 31) return null;\n const date = new Date(Date.UTC(y, mo - 1, d));\n if (date.getUTCMonth() !== mo - 1 || date.getUTCDate() !== d) return null;\n return date;\n}\n\n/** Accepte `JJ/MM/AAAA`, `JJ-MM-AAAA`, `JJ.MM.AAAA` ou ISO et rend l'ISO, sinon null. */\nexport function normalizeDateInput(raw: string): string | null {\n const s = raw.trim();\n if (parseIsoDate(s)) return s;\n const m = s.match(/^(\\d{1,2})[\\/.\\-](\\d{1,2})[\\/.\\-](\\d{4})$/);\n if (!m) return null;\n const iso = `${m[3]}-${m[2]!.padStart(2, '0')}-${m[1]!.padStart(2, '0')}`;\n return parseIsoDate(iso) ? iso : null;\n}\n\n/** Vrai si la date ISO est strictement passée (comparaison en jours UTC). */\nexport function isExpired(iso: string | undefined | null, now: Date = new Date()): boolean {\n const d = parseIsoDate(iso);\n if (!d) return false;\n const today = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());\n return d.getTime() < today;\n}\n\n/** Date de naissance plausible : entre 0 et 120 ans, pas dans le futur. */\nexport function isPlausibleBirthDate(iso: string | undefined | null, now: Date = new Date()): boolean {\n const d = parseIsoDate(iso);\n if (!d) return false;\n const years = (now.getTime() - d.getTime()) / (365.25 * 24 * 3600 * 1000);\n return years >= 0 && years <= 120;\n}\n","import type { NayaFlow } from '../flow/flow';\nimport {\n buildShell,\n alertHtml,\n fieldHtml,\n primaryButtonHtml,\n secondaryButtonHtml,\n type Screen,\n} from '../ui/components';\nimport { escapeHtml } from '../ui/dom';\nimport type { NayaOcrData } from '../models/result';\nimport { isExpired, isPlausibleBirthDate, normalizeDateInput } from '../utils/dates';\n\ntype FieldKey =\n | 'lastName'\n | 'firstName'\n | 'dateOfBirth'\n | 'documentNumber'\n | 'expirationDate'\n | 'nationality'\n | 'gender'\n | 'placeOfBirth';\n\nconst FIELDS: Array<{\n key: FieldKey;\n label: string;\n wide?: boolean;\n date?: boolean;\n required?: boolean;\n autocomplete?: string;\n}> = [\n { key: 'lastName', label: 'ocrLastName', required: true, autocomplete: 'family-name' },\n { key: 'firstName', label: 'ocrFirstName', required: true, autocomplete: 'given-name' },\n { key: 'dateOfBirth', label: 'ocrDateOfBirth', date: true, required: true, autocomplete: 'bday' },\n { key: 'placeOfBirth', label: 'ocrPlaceOfBirth' },\n { key: 'documentNumber', label: 'ocrDocumentNumber' },\n { key: 'expirationDate', label: 'ocrExpirationDate', date: true },\n { key: 'nationality', label: 'ocrNationality' },\n { key: 'gender', label: 'ocrGender' },\n];\n\n/**\n * Écran 5b — Données lues sur le document, à la demande de l'intégrateur.\n *\n * L'extraction serveur (`ocrData`) n'est **jamais** modifiée par cet écran :\n * en mode `display`, l'utilisateur dit seulement si elle est exacte\n * (`dataDisputed`) ; en mode `edit`, ce qu'il saisit part à part\n * (`declaredData`) et le serveur signale les écarts sans corriger. Contrôles\n * locaux en saisie : dates au bon format, naissance plausible, expiration.\n */\nexport class OcrConfirmScreen implements Screen {\n readonly el: HTMLElement;\n private readonly content: HTMLElement;\n private disposed = false;\n\n constructor(private readonly flow: NayaFlow) {\n const s = flow.strings;\n const { root, content } = buildShell({\n poweredBy: s.t('poweredBy'),\n backLabel: s.t('back'),\n closeLabel: s.t('close'),\n screenClass: 'n-ocr',\n onClose: () => flow.cancel(),\n });\n this.el = root;\n this.content = content;\n this.renderWaiting();\n void this.load();\n }\n\n dispose(): void {\n this.disposed = true;\n }\n\n private renderWaiting(): void {\n const s = this.flow.strings;\n this.content.innerHTML = `\n <div class=\"pad\">\n <h1 class=\"title\">${escapeHtml(s.t('ocrTitle'))}</h1>\n <p class=\"body\">${escapeHtml(s.t('ocrSubtitle'))}</p>\n <div class=\"waiting\" role=\"status\" aria-live=\"polite\"><span class=\"loader sm\"></span><span>${escapeHtml(s.t('ocrWaiting'))}</span></div>\n </div>`;\n }\n\n private async load(): Promise<void> {\n const flow = this.flow;\n let ocr: NayaOcrData | undefined;\n try {\n ocr = await flow.ensureDocumentUploaded();\n } catch (err) {\n if (this.disposed) return;\n const n = flow.normalizeError(err);\n if (\n n.code === 'upload_limit' ||\n n.code === 'session_closed' ||\n n.code === 'session_expired' ||\n n.code === 'origin_not_allowed' ||\n n.code === 'quota'\n ) {\n flow.fail(err);\n return;\n }\n this.renderError(n.message, n.requestId);\n return;\n }\n if (this.disposed) return;\n const data = ocr ?? flow.ocrData;\n if (flow.config.confirmOcr === 'display') this.renderDisplay(data);\n else this.renderForm(data);\n }\n\n /** Lecture seule : « ces informations sont-elles exactes ? ». */\n private renderDisplay(ocr: NayaOcrData | undefined): void {\n const s = this.flow.strings;\n const rows = FIELDS.map((f) => {\n const raw = ocr?.[f.key] ?? '';\n const wide = f.key === 'lastName' || f.key === 'firstName' || f.key === 'placeOfBirth';\n const value = raw\n ? f.key === 'gender'\n ? s.t(raw.toUpperCase().startsWith('F') ? 'ocrGenderF' : 'ocrGenderM')\n : raw\n : s.t('ocrEmptyValue');\n return (\n `<div${wide ? ' class=\"wide\"' : ''}><dt>${escapeHtml(s.t(f.label as 'ocrLastName'))}</dt>` +\n `<dd${raw ? '' : ' class=\"empty\"'}>${escapeHtml(value)}</dd></div>`\n );\n }).join('');\n\n this.content.innerHTML = `\n <div class=\"pad\">\n <h1 class=\"title\">${escapeHtml(s.t('ocrTitle'))}</h1>\n <p class=\"body\">${escapeHtml(s.t('ocrReadSubtitle'))}</p>\n ${ocr ? '' : alertHtml('warning', escapeHtml(s.t('ocrNone')))}\n <dl class=\"dl\">${rows}</dl>\n <div class=\"spacer\"></div>\n <p class=\"question\" id=\"n-ocr-q\">${escapeHtml(s.t('ocrQuestion'))}</p>\n <div class=\"cta\" role=\"group\" aria-labelledby=\"n-ocr-q\">\n ${primaryButtonHtml(s.t('ocrYes'), { act: 'yes', icon: 'check' })}\n ${secondaryButtonHtml(s.t('ocrNo'), 'no', 'alert')}\n </div>\n </div>`;\n\n const finish = (disputed: boolean): void => {\n const flow = this.flow;\n flow.declaredData = undefined;\n flow.dataDisputed = disputed;\n flow.telemetry.track('ocr_reviewed', { hasOcr: !!ocr, disputed });\n flow.haptic(disputed ? 'error' : 'tap');\n flow.replace('processing');\n };\n this.content.querySelector('[data-act=\"yes\"]')?.addEventListener('click', () => finish(false));\n this.content.querySelector('[data-act=\"no\"]')?.addEventListener('click', () => finish(true));\n this.flow.telemetry.track('ocr_confirm_shown', {\n mode: 'display',\n hasOcr: !!ocr,\n fields: ocr ? Object.keys(ocr).length : 0,\n });\n }\n\n private renderError(message: string, requestId?: string): void {\n const s = this.flow.strings;\n this.content.innerHTML = `\n <div class=\"pad\">\n <h1 class=\"title\">${escapeHtml(s.t('errorTitle'))}</h1>\n ${alertHtml('error', `${escapeHtml(message)}${requestId ? `<br><small class=\"mono\">${escapeHtml(s.t('errorRef', { id: requestId }))}</small>` : ''}`)}\n <div class=\"spacer\"></div>\n <div class=\"cta\">${primaryButtonHtml(s.t('retry'), { act: 'retry', icon: 'refresh' })}${secondaryButtonHtml(s.t('backToApp'), 'quit')}</div>\n </div>`;\n this.content.querySelector('[data-act=\"retry\"]')?.addEventListener('click', () => {\n this.renderWaiting();\n void this.load();\n });\n this.content\n .querySelector('[data-act=\"quit\"]')\n ?.addEventListener('click', () => this.flow.fail(new Error(message), 'network'));\n }\n\n private renderForm(ocr: NayaOcrData | undefined): void {\n const s = this.flow.strings;\n const fields = FIELDS.map(\n (f) =>\n `<div class=\"${f.wide || f.key === 'lastName' || f.key === 'firstName' || f.key === 'placeOfBirth' ? 'wide' : ''}\">${fieldHtml(\n {\n id: f.key,\n label: s.t(f.label as 'ocrLastName'),\n value: ocr?.[f.key] ?? '',\n required: f.required,\n placeholder: f.date ? 'AAAA-MM-JJ' : undefined,\n help: f.date ? s.t('ocrDateFormat') : undefined,\n autocomplete: f.autocomplete,\n inputmode: f.date ? 'numeric' : undefined,\n maxlength: 80,\n },\n )}</div>`,\n ).join('');\n\n this.content.innerHTML = `\n <div class=\"pad\">\n <h1 class=\"title\">${escapeHtml(s.t('ocrTitle'))}</h1>\n <p class=\"body\">${escapeHtml(s.t('ocrSubtitle'))}</p>\n ${ocr ? '' : alertHtml('warning', escapeHtml(s.t('ocrNone')))}\n <form class=\"grid\" novalidate data-form>${fields}</form>\n <div data-msg></div>\n <div class=\"spacer\"></div>\n ${primaryButtonHtml(s.t('confirm'), { act: 'confirm' })}\n </div>`;\n\n const form = this.content.querySelector<HTMLFormElement>('[data-form]')!;\n form.addEventListener('submit', (e) => {\n e.preventDefault();\n this.confirm();\n });\n this.content.querySelector('[data-act=\"confirm\"]')?.addEventListener('click', () => this.confirm());\n this.flow.telemetry.track('ocr_confirm_shown', {\n mode: 'edit',\n hasOcr: !!ocr,\n fields: ocr ? Object.keys(ocr).length : 0,\n });\n }\n\n private setFieldState(key: string, error: string | null): void {\n const wrap = this.content.querySelector<HTMLElement>(`[data-field=\"${key}\"]`);\n if (!wrap) return;\n wrap.classList.toggle('invalid', !!error);\n const msg = wrap.querySelector<HTMLElement>('.n-field-msg');\n if (msg)\n msg.textContent =\n error ??\n (key === 'dateOfBirth' || key === 'expirationDate' ? this.flow.strings.t('ocrDateFormat') : '');\n }\n\n private confirm(): void {\n const s = this.flow.strings;\n const flow = this.flow;\n const values: Record<string, string> = {};\n let valid = true;\n let firstInvalid: HTMLElement | null = null;\n const warnings: string[] = [];\n\n for (const f of FIELDS) {\n const input = this.content.querySelector<HTMLInputElement>(`#n-f-${f.key}`);\n if (!input) continue;\n let value = input.value.trim();\n let error: string | null = null;\n if (f.date && value) {\n const iso = normalizeDateInput(value);\n if (!iso) error = s.t('ocrDateFormat');\n else {\n value = iso;\n input.value = iso;\n if (f.key === 'dateOfBirth' && !isPlausibleBirthDate(iso)) error = s.t('ocrDobInvalid');\n if (f.key === 'expirationDate' && isExpired(iso)) warnings.push(s.t('ocrExpired'));\n }\n }\n if (f.required && !value) error = s.t('ocrRequired');\n this.setFieldState(f.key, error);\n if (error) {\n valid = false;\n firstInvalid ??= input;\n }\n if (value) values[f.key] = value;\n }\n\n const msg = this.content.querySelector<HTMLElement>('[data-msg]')!;\n msg.innerHTML = warnings.map((w) => alertHtml('warning', escapeHtml(w))).join('');\n if (!valid) {\n firstInvalid?.focus();\n flow.haptic('error');\n return;\n }\n\n // Seules les valeurs différentes de l'extraction (ou absentes) sont\n // déclarées. Le serveur les conserve à part : l'extraction reste intacte,\n // et un écart plafonne la décision à la revue.\n const declared: Record<string, string> = {};\n for (const [k, v] of Object.entries(values)) {\n if ((flow.ocrData?.[k as keyof NayaOcrData] ?? '') !== v) declared[k] = v;\n }\n flow.declaredData = Object.keys(declared).length ? declared : undefined;\n flow.dataDisputed = false;\n flow.telemetry.track('ocr_confirmed', {\n corrected: Object.keys(declared).length,\n expiredWarning: warnings.length > 0,\n });\n flow.haptic('tap');\n flow.replace('processing');\n }\n}\n","import type { NayaFlow } from '../flow/flow';\nimport { NayaApiError } from '../api/client';\nimport { buildShell, brandHtml, primaryButtonHtml, secondaryButtonHtml, type Screen } from '../ui/components';\nimport { iconSvg } from '../ui/icons';\nimport { escapeHtml } from '../ui/dom';\n\nconst STAGES = ['ocr', 'face', 'aml', 'decision'] as const;\nconst POLL_MS = 2500;\nconst LONG_WAIT_MS = 60_000;\n\n/**\n * Écran 6 — Traitement : envoi du selfie et de la preuve du défi, puis\n * `submit` (OCR différé, biométrie, AML, décision). La progression affichée\n * est réelle : elle suit `processingStage` exposé par l'API pendant l'analyse.\n */\nexport class ProcessingScreen implements Screen {\n readonly el: HTMLElement;\n readonly canClose = false;\n private readonly content: HTMLElement;\n private readonly closeBtn: HTMLElement | null;\n\n private stageIndex = -1;\n private pollTimer: ReturnType<typeof setTimeout> | null = null;\n private longTimer: ReturnType<typeof setTimeout> | null = null;\n private disposed = false;\n\n private readonly steps: { label: string; index: number }[];\n\n constructor(private readonly flow: NayaFlow) {\n const s = flow.strings;\n const { root, content } = buildShell({\n poweredBy: s.t('poweredBy'),\n backLabel: s.t('back'),\n closeLabel: s.t('close'),\n screenClass: 'n-processing',\n canClose: false,\n onClose: () => flow.cancel(),\n });\n this.el = root;\n this.content = content;\n this.closeBtn = root.querySelector('[data-nav=\"close\"]');\n\n this.steps = [\n { label: s.t('processingDocument'), index: 0 },\n { label: s.t('processingFace'), index: 1 },\n { label: s.t('processingCompliance'), index: 2 },\n { label: s.t('processingDecision'), index: 3 },\n ];\n\n this.renderProgress();\n void this.run();\n }\n\n dispose(): void {\n this.disposed = true;\n this.stopTimers();\n }\n\n private stopTimers(): void {\n if (this.pollTimer) clearTimeout(this.pollTimer);\n if (this.longTimer) clearTimeout(this.longTimer);\n this.pollTimer = this.longTimer = null;\n }\n\n private renderProgress(): void {\n const s = this.flow.strings;\n const rows = this.steps\n .map(\n (item) =>\n `<li class=\"row\" data-row=\"${item.index}\"><span class=\"dot idle\"></span><span class=\"lbl\">${escapeHtml(item.label)}</span></li>`,\n )\n .join('');\n this.content.innerHTML = `\n <div class=\"pad\">\n ${brandHtml()}\n <div class=\"spacer\"></div>\n <span class=\"spin\" aria-hidden=\"true\"></span>\n <h1 class=\"title sr-only\">${escapeHtml(s.t('processingDecision'))}</h1>\n <ul class=\"steps\" aria-live=\"polite\">${rows}</ul>\n <div class=\"spacer\"></div>\n <p class=\"wait\" data-wait>${escapeHtml(s.t('processingWait'))}</p>\n </div>`;\n if (this.closeBtn) this.closeBtn.hidden = true;\n this.stageIndex = -1;\n this.updateSteps();\n this.longTimer = setTimeout(() => {\n const w = this.content.querySelector<HTMLElement>('[data-wait]');\n if (w) w.textContent = s.t('processingLong');\n }, LONG_WAIT_MS);\n }\n\n private updateSteps(): void {\n const cur = this.stageIndex;\n this.steps.forEach((item) => {\n const row = this.content.querySelector<HTMLElement>(`[data-row=\"${item.index}\"]`);\n if (!row) return;\n const dot = row.querySelector('.dot')!;\n const lbl = row.querySelector('.lbl')!;\n if (item.index < cur) {\n dot.className = 'dot done';\n dot.innerHTML = iconSvg('check', 12, 3);\n } else if (item.index === cur) {\n dot.className = 'dot active';\n dot.innerHTML = '';\n } else {\n dot.className = 'dot idle';\n dot.innerHTML = '';\n }\n lbl.classList.toggle('dim', item.index > cur);\n });\n }\n\n private setStage(stage: string | null): void {\n const idx = stage === 'done' ? STAGES.length : STAGES.indexOf(stage as (typeof STAGES)[number]);\n if (idx > this.stageIndex) {\n this.stageIndex = idx;\n this.updateSteps();\n }\n }\n\n /** Suit `processingStage` pendant l'attente du `submit`. */\n private poll(): void {\n if (this.disposed) return;\n this.pollTimer = setTimeout(async () => {\n const id = this.flow.session?.verificationId;\n if (!id || this.disposed) return;\n try {\n const v = await this.flow.client.getVerification(id);\n if (!this.disposed) this.setStage(v.processingStage);\n } catch {\n /* la prochaine lecture rattrapera */\n }\n this.poll();\n }, POLL_MS);\n }\n\n private async run(): Promise<void> {\n const flow = this.flow;\n try {\n this.setStage('ocr');\n // L'envoi du document est parti pendant le selfie — on s'assure qu'il\n // est terminé (et on le relance s'il a échoué).\n await flow.ensureDocumentUploaded();\n const session = await flow.ensureSession();\n if (this.disposed) return;\n\n if (!flow.selfieBase64) throw new NayaApiError('Selfie manquant.', 'invalid_params');\n await flow.client.submitLiveness(session.verificationId, {\n selfieBase64: flow.selfieBase64,\n livenessMode: flow.livenessMode,\n challengeProof: flow.livenessMode === 'active' ? flow.livenessProof : undefined,\n frames: flow.livenessFrames,\n clientScore: flow.livenessScore,\n });\n if (this.disposed) return;\n\n this.poll();\n const response = await flow.client.submit(session.verificationId, flow.declaredData, flow.dataDisputed);\n this.stopTimers();\n if (this.disposed) return;\n this.setStage('done');\n flow.submitResponse = response;\n flow.emit('submitted', { status: response.status, reasonCodes: response.reasonCodes });\n flow.telemetry.track('submitted', {\n status: response.status,\n reasons: response.reasonCodes.length,\n replayed: !!response.replayed,\n });\n flow.haptic(response.status === 'rejected' ? 'error' : 'success');\n flow.replace('result');\n } catch (err) {\n this.stopTimers();\n if (this.disposed) return;\n const n = flow.normalizeError(err, 'server');\n flow.telemetry.track('error', { code: n.code, status: n.statusCode ?? null, step: 'processing' });\n const fatal =\n n.code === 'upload_limit' ||\n n.code === 'session_closed' ||\n n.code === 'session_expired' ||\n n.code === 'origin_not_allowed' ||\n n.code === 'quota' ||\n n.code === 'kyb_pending' ||\n n.code === 'unauthorized' ||\n n.code === 'invalid_params';\n if (fatal) {\n flow.fail(err, n.code);\n return;\n }\n this.renderError(n.message, n.requestId);\n }\n }\n\n private renderError(message: string, requestId?: string): void {\n const s = this.flow.strings;\n if (this.closeBtn) this.closeBtn.hidden = false;\n this.content.innerHTML = `\n <div class=\"pad center\">\n ${iconSvg('wifi-off', 48, 1.8)}\n <h1 class=\"title\">${escapeHtml(s.t('errorTitle'))}</h1>\n <p class=\"body\">${escapeHtml(message)}</p>\n ${requestId ? `<p class=\"sub mono\">${escapeHtml(s.t('errorRef', { id: requestId }))}</p>` : ''}\n <div class=\"cta\">\n ${primaryButtonHtml(s.t('retry'), { act: 'retry', icon: 'refresh', autofocus: true })}\n ${secondaryButtonHtml(s.t('backToApp'), 'quit')}\n </div>\n </div>`;\n this.content.querySelector('[data-act=\"retry\"]')?.addEventListener('click', () => {\n this.renderProgress();\n void this.run();\n });\n this.content\n .querySelector('[data-act=\"quit\"]')\n ?.addEventListener('click', () =>\n this.flow.fail(new NayaApiError(message, 'server', { requestId }), 'server'),\n );\n }\n}\n","import type { NayaFlow } from '../flow/flow';\nimport type { NayaStatus } from '../models/result';\nimport { buildShell, primaryButtonHtml, secondaryButtonHtml, type Screen } from '../ui/components';\nimport { iconSvg, type NayaIconName } from '../ui/icons';\nimport { escapeHtml } from '../ui/dom';\n\n/** Écran 7 — Résultat : approuvé, en revue ou rejeté, avec motifs expliqués. */\nexport class ResultScreen implements Screen {\n readonly el: HTMLElement;\n readonly canClose = false;\n\n constructor(private readonly flow: NayaFlow) {\n const s = flow.strings;\n const response = flow.submitResponse;\n const status: NayaStatus =\n response?.status === 'approved' ? 'approved' : response?.status === 'rejected' ? 'rejected' : 'review';\n const view = this.viewFor(status);\n\n const fullName = [\n response?.ocrData?.firstName ?? flow.declaredData?.firstName,\n response?.ocrData?.lastName ?? flow.declaredData?.lastName,\n ]\n .filter((p) => p && p.length)\n .join(' ');\n const id = flow.session?.verificationId;\n const reference = id ? id.split('-')[0]!.toUpperCase() : '—';\n\n // Motifs stables traduits ; la note libre du serveur sert de secours.\n const codes = (response?.reasonCodes ?? []).filter(\n (c) => (c !== 'AUTO_APPROVED' && c !== 'SCORE_BELOW_THRESHOLD') || status !== 'approved',\n );\n const reasons = codes.map((c) => s.reason(c)).filter((r): r is string => !!r);\n if (status === 'rejected' && reasons.length === 0 && response?.note) reasons.push(response.note);\n\n let middle = '';\n if (status === 'approved') {\n const nameRow = fullName\n ? `<div class=\"srow\"><span class=\"k\">${escapeHtml(s.t('resultName'))}</span><span class=\"v\">${escapeHtml(fullName)}</span></div>`\n : '';\n middle = `<div class=\"summary\">${nameRow}<div class=\"srow\"><span class=\"k\">${escapeHtml(s.t('resultReference'))}</span><span class=\"v mono\">${escapeHtml(reference)}</span></div></div>`;\n } else if (status === 'review') {\n const bullets = [s.t('resultReviewB1'), s.t('resultReviewB2'), s.t('resultReviewB3')]\n .map((b) => `<li><span class=\"pip\"></span><span>${escapeHtml(b)}</span></li>`)\n .join('');\n middle = `<ul class=\"bullets\">${bullets}</ul>`;\n } else if (reasons.length) {\n middle = `<p class=\"sub\"><strong>${escapeHtml(s.t('resultRejectedReason'))}</strong></p><ul class=\"reasons\">${reasons\n .map((r) => `<li>${iconSvg('alert', 16, 2.2)}<span>${escapeHtml(r)}</span></li>`)\n .join('')}</ul>`;\n }\n\n const canRetry = status === 'rejected' && flow.canRetry;\n const buttons = canRetry\n ? `${primaryButtonHtml(s.t('retry'), { icon: 'refresh', act: 'retry', autofocus: true })}<div class=\"gap\"></div>${secondaryButtonHtml(s.t('backToApp'), 'done')}`\n : primaryButtonHtml(s.t(response?.ocrData ? 'continue' : 'backToApp'), {\n act: 'done',\n autofocus: true,\n });\n\n const { root, content } = buildShell({\n poweredBy: s.t('poweredBy'),\n backLabel: s.t('back'),\n closeLabel: s.t('close'),\n screenClass: 'n-result',\n canClose: false,\n clientLogoUrl: flow.config.clientLogoUrl,\n });\n this.el = root;\n\n content.innerHTML = `\n <div class=\"pad\">\n <div class=\"spacer\"></div>\n <span class=\"badge\" style=\"background:${view.color}\">${iconSvg(view.icon, 44, 3)}</span>\n <h1 class=\"title\">${escapeHtml(view.title)}</h1>\n ${view.subtitle ? `<p class=\"body\">${escapeHtml(view.subtitle)}</p>` : ''}\n ${middle}\n <div class=\"spacer\"></div>\n <div class=\"cta\">${buttons}</div>\n </div>`;\n\n content.querySelector('[data-act=\"retry\"]')?.addEventListener('click', () => this.retry());\n content.querySelector('[data-act=\"done\"]')?.addEventListener('click', () => this.done(status));\n }\n\n dispose(): void {}\n\n private viewFor(status: NayaStatus): {\n icon: NayaIconName;\n color: string;\n title: string;\n subtitle: string;\n } {\n const s = this.flow.strings;\n switch (status) {\n case 'approved':\n return {\n icon: 'check',\n color: 'var(--naya-success)',\n title: s.t('resultApprovedTitle'),\n subtitle: s.t('resultApprovedSubtitle'),\n };\n case 'rejected':\n return { icon: 'close', color: 'var(--naya-error)', title: s.t('resultRejectedTitle'), subtitle: '' };\n default:\n return {\n icon: 'clock',\n color: 'var(--naya-warning)',\n title: s.t('resultReviewTitle'),\n subtitle: s.t('resultReviewSubtitle'),\n };\n }\n }\n\n private retry(): void {\n this.flow.resetForRetry();\n this.flow.replace(this.flow.tipsShown.document ? 'capture-recto' : 'tips-document');\n }\n\n private done(status: NayaStatus): void {\n const r = this.flow.submitResponse;\n this.flow.complete({\n status,\n verificationId: this.flow.session?.verificationId,\n reasonCodes: r?.reasonCodes ?? [],\n livenessMode: this.flow.livenessMode,\n riskScore: r?.riskScore,\n matchScore: r?.matchScore,\n authenticityScore: r?.authenticityScore,\n livenessScore: r?.livenessScore,\n ocrConfidence: r?.ocrConfidence,\n ocrData: r?.ocrData,\n declaredData: r?.declaredData,\n dataMismatches: r?.dataMismatches,\n dataDisputed: r?.dataDisputed,\n note: r?.note,\n });\n }\n}\n","import { buildThemeVars, effectiveMode } from '../theme/theme';\nimport { STYLES } from '../ui/styles';\nimport type { Screen } from '../ui/components';\nimport type { NayaAuth, ResolvedNayaConfig } from '../models/config';\nimport { type NayaResult, errorResult } from '../models/result';\nimport { NayaFlow, type NayaStep, type StepDirection } from './flow';\nimport { trapFocus, focusFirst } from '../support/focus-trap';\nimport { WelcomeScreen } from '../screens/welcome';\nimport { UnsupportedScreen } from '../screens/unsupported';\nimport { ConsentScreen } from '../screens/consent';\nimport { HandoffScreen } from '../screens/handoff';\nimport { DocumentSelectionScreen } from '../screens/document-selection';\nimport { TipsScreen } from '../screens/tips';\nimport { DocumentCaptureScreen } from '../screens/document-capture';\nimport { LivenessScreen } from '../screens/liveness';\nimport { OcrConfirmScreen } from '../screens/ocr-confirm';\nimport { ProcessingScreen } from '../screens/processing';\nimport { ResultScreen } from '../screens/result';\n\n/** Instancie l'écran correspondant à une étape. */\nfunction createScreen(step: NayaStep, flow: NayaFlow): Screen {\n switch (step) {\n case 'unsupported':\n return new UnsupportedScreen(flow);\n case 'welcome':\n return new WelcomeScreen(flow);\n case 'consent':\n return new ConsentScreen(flow);\n case 'handoff':\n return new HandoffScreen(flow);\n case 'select':\n return new DocumentSelectionScreen(flow);\n case 'tips-document':\n return new TipsScreen(flow, 'document');\n case 'tips-selfie':\n return new TipsScreen(flow, 'selfie');\n case 'capture-recto':\n return new DocumentCaptureScreen(flow, 'recto');\n case 'capture-verso':\n return new DocumentCaptureScreen(flow, 'verso');\n case 'liveness':\n return new LivenessScreen(flow);\n case 'ocr-confirm':\n return new OcrConfirmScreen(flow);\n case 'processing':\n return new ProcessingScreen(flow);\n case 'result':\n return new ResultScreen(flow);\n }\n}\n\n/** Étapes pendant lesquelles quitter la page ferait perdre du travail. */\nconst BUSY_STEPS: ReadonlySet<NayaStep> = new Set(['liveness', 'ocr-confirm', 'processing']);\n\nexport interface MountHandle {\n result: Promise<NayaResult>;\n flow: NayaFlow;\n close: () => void;\n}\n\n/**\n * Monte l'interface Naya, en overlay plein écran au-dessus de l'application ou\n * dans un conteneur hôte, dans un **Shadow DOM** — le CSS du SDK et celui de\n * la page restent mutuellement isolés. Résout le `NayaResult` à la fermeture ;\n * ne rejette jamais.\n */\nexport function mountNayaFlow(auth: NayaAuth, config: ResolvedNayaConfig): MountHandle {\n if (typeof document === 'undefined') {\n const result = Promise.resolve(\n errorResult('Le SDK Naya nécessite un environnement navigateur.', undefined, {\n errorCode: 'unsupported_browser',\n }),\n );\n return { result, flow: null as unknown as NayaFlow, close: () => {} };\n }\n\n let closeFn: () => void = () => {};\n let flowRef!: NayaFlow;\n\n const result = new Promise<NayaResult>((resolve) => {\n const inline = !!config.container;\n const container = document.createElement('div');\n container.setAttribute('data-naya-id', '');\n if (inline) container.style.cssText = 'display:block;height:100%;';\n const shadow = container.attachShadow({ mode: 'open' });\n\n const style = document.createElement('style');\n style.textContent = STYLES;\n shadow.appendChild(style);\n\n const hostEl = document.createElement('div');\n hostEl.className = 'naya-host' + (inline ? ' n-inline' : '');\n hostEl.setAttribute('role', 'dialog');\n hostEl.setAttribute('aria-modal', inline ? 'false' : 'true');\n shadow.appendChild(hostEl);\n\n const frame = document.createElement('div');\n frame.className = 'n-frame';\n hostEl.appendChild(frame);\n\n const applyTheme = (): void => {\n const vars = buildThemeVars(config);\n for (const [k, v] of Object.entries(vars)) hostEl.style.setProperty(k, v);\n hostEl.style.colorScheme = effectiveMode(config);\n };\n applyTheme();\n let mql: MediaQueryList | null = null;\n if (config.theme.mode === 'auto' && typeof matchMedia === 'function') {\n mql = matchMedia('(prefers-color-scheme: dark)');\n mql.addEventListener?.('change', applyTheme);\n }\n\n const prevOverflow = document.body.style.overflow;\n const previouslyFocused = document.activeElement as HTMLElement | null;\n let settled = false;\n let current: Screen | null = null;\n let releaseTrap: () => void = () => {};\n\n const onBeforeUnload = (e: BeforeUnloadEvent): void => {\n if (BUSY_STEPS.has(flow.step) || flow.documentUploadInFlight) {\n e.preventDefault();\n e.returnValue = '';\n }\n };\n const onVisibility = (): void => current?.onVisibility?.(document.visibilityState === 'visible');\n\n const finish = (final: NayaResult): void => {\n if (settled) return;\n settled = true;\n current?.dispose();\n document.removeEventListener('keydown', onKey);\n document.removeEventListener('visibilitychange', onVisibility);\n window.removeEventListener('beforeunload', onBeforeUnload);\n releaseTrap();\n mql?.removeEventListener?.('change', applyTheme);\n if (!inline) document.body.style.overflow = prevOverflow;\n container.remove();\n try {\n previouslyFocused?.focus?.({ preventScroll: true });\n } catch {\n /* ignore */\n }\n resolve(final);\n };\n\n const flow = new NayaFlow(auth, config, finish);\n flowRef = flow;\n hostEl.setAttribute('aria-label', flow.strings.t('dialogLabel'));\n\n const route = (step: NayaStep, direction: StepDirection): void => {\n const leaving = current;\n current = createScreen(step, flow);\n current.el.classList.add(direction === 'back' ? 'n-enter-back' : 'n-enter');\n if (leaving) {\n leaving.dispose();\n leaving.el.classList.add('n-leave');\n leaving.el.setAttribute('aria-hidden', 'true');\n frame.appendChild(current.el);\n const gone = leaving.el;\n setTimeout(() => gone.remove(), 180);\n } else {\n frame.replaceChildren(current.el);\n }\n const h1 = current.el.querySelector<HTMLElement>('h1');\n if (h1 && !h1.hasAttribute('tabindex')) h1.setAttribute('tabindex', '-1');\n focusFirst(current.el);\n };\n flow.onStep = route;\n\n // Échap ferme le parcours (annulation), sauf sur les écrans qui l'interdisent\n // (traitement en cours, résultat).\n const onKey = (e: KeyboardEvent): void => {\n if (e.key === 'Escape' && current?.canClose !== false) flow.cancel();\n };\n document.addEventListener('keydown', onKey);\n document.addEventListener('visibilitychange', onVisibility);\n window.addEventListener('beforeunload', onBeforeUnload);\n\n if (inline) {\n config.container!.replaceChildren(container);\n } else {\n document.body.appendChild(container);\n document.body.style.overflow = 'hidden'; // fige le défilement de la page\n releaseTrap = trapFocus(shadow);\n }\n\n closeFn = () => flow.cancel();\n route(flow.step, 'replace');\n flow.emit('ready', { resumed: flow.resumed, support: flow.support.ok });\n\n // Reprise de session : lecture anticipée du défi et du document pendant\n // que l'accueil s'affiche. Un échec est rendu à l'hôte avec le motif.\n if (flow.resumed && flow.support.ok) {\n flow.prepare().catch((err: unknown) => flow.fail(err, 'session_expired'));\n }\n });\n\n return { result, flow: flowRef, close: () => closeFn() };\n}\n","/** Émetteur d'événements minimal, sans dépendance. */\nexport type Listener<T> = (payload: T) => void;\n\nexport class Emitter<Events extends Record<string, unknown>> {\n private readonly listeners = new Map<keyof Events, Set<Listener<any>>>();\n\n on<K extends keyof Events>(event: K, cb: Listener<Events[K]>): () => void {\n let set = this.listeners.get(event);\n if (!set) {\n set = new Set();\n this.listeners.set(event, set);\n }\n set.add(cb);\n return () => set!.delete(cb);\n }\n\n emit<K extends keyof Events>(event: K, payload: Events[K]): void {\n const set = this.listeners.get(event);\n if (!set) return;\n for (const cb of Array.from(set)) {\n try {\n cb(payload);\n } catch {\n // Un écouteur hôte qui lève ne doit jamais casser le parcours.\n }\n }\n }\n\n clear(): void {\n this.listeners.clear();\n }\n}\n","import {\n type NayaAuth,\n type NayaConfig,\n type NayaEvent,\n type NayaEventName,\n resolveConfig,\n} from './models/config';\nimport type { NayaResult } from './models/result';\nimport { mountNayaFlow } from './flow/host';\nimport { detectSupport, type NayaSupport } from './support/capabilities';\nimport { Emitter } from './support/emitter';\nimport { SDK_VERSION } from './version';\n\nexport interface StartVerificationParams {\n /** Clé d'application `naya_live_…` / `naya_test_…` (lisible côté navigateur). */\n apiKey?: string;\n /**\n * Jeton de session rendu par `POST /verifications/start`, obtenu par votre\n * backend (à privilégier). Va toujours avec `verificationId` : le SDK reprend\n * la vérification ouverte par le serveur au lieu d'en ouvrir une nouvelle.\n */\n sessionToken?: string;\n /** Identifiant de la vérification ouverte par votre backend (avec `sessionToken`). */\n verificationId?: string;\n /** Alternative aux champs ci-dessus, forme objet. */\n auth?: NayaAuth;\n /** Configuration optionnelle (pays, documents, langue, thème, conteneur…). */\n config?: NayaConfig;\n}\n\nfunction validateAuth(params: StartVerificationParams): { auth: NayaAuth; error?: NayaResult } {\n const auth: NayaAuth = params.auth ?? {\n apiKey: params.apiKey,\n sessionToken: params.sessionToken,\n verificationId: params.verificationId,\n };\n // Un jeton de session ne désigne qu'une vérification : il ne peut pas en\n // ouvrir une nouvelle, l'identifiant est donc indispensable — et réciproquement.\n if (auth.sessionToken && !auth.verificationId) {\n return {\n auth,\n error: {\n status: 'error',\n errorCode: 'invalid_params',\n errorMessage:\n 'sessionToken doit être accompagné du verificationId rendu par POST /verifications/start.',\n },\n };\n }\n if (auth.verificationId && !auth.sessionToken) {\n return {\n auth,\n error: {\n status: 'error',\n errorCode: 'invalid_params',\n errorMessage: 'verificationId doit être accompagné de son sessionToken.',\n verificationId: auth.verificationId,\n },\n };\n }\n if (!auth.apiKey && !auth.sessionToken) {\n return {\n auth,\n error: {\n status: 'error',\n errorCode: 'invalid_params',\n errorMessage: 'Authentification manquante : fournissez apiKey, ou verificationId + sessionToken.',\n },\n };\n }\n return { auth };\n}\n\n/**\n * Lance le parcours de vérification d'identité : l'interface Naya s'ouvre en\n * plein écran au-dessus de la page (ou dans `config.container`), prend en\n * charge le consentement, la capture du document, la vivacité, la\n * confirmation des données et la décision, puis résout un `NayaResult`.\n *\n * **Ne rejette jamais** : une erreur ou une annulation revient toujours sous\n * forme de `NayaResult` (`status: 'error'` avec `errorCode`, ou `'cancelled'`).\n */\nexport async function startVerification(params: StartVerificationParams): Promise<NayaResult> {\n const { auth, error } = validateAuth(params);\n if (error) return error;\n return mountNayaFlow(auth, resolveConfig(params.config)).result;\n}\n\n/** Vérifie que le navigateur peut exécuter le parcours, avant de l'ouvrir. */\nexport function isSupported(): NayaSupport {\n return detectSupport();\n}\n\nexport interface NayaVerification {\n /** Monte l'interface et résout à la fermeture. Un seul `open` à la fois. */\n open(): Promise<NayaResult>;\n /** Ferme le parcours (résultat `cancelled`). */\n close(): void;\n /** Abonne un écouteur ; rend la fonction de désabonnement. */\n on(event: NayaEventName | 'result', cb: (payload: NayaEvent | NayaResult) => void): () => void;\n /** Ferme et libère les écouteurs. */\n destroy(): void;\n readonly isOpen: boolean;\n}\n\n/**\n * API programmatique : instance réutilisable avec `open`, `close`, `on`.\n * Utile aux enveloppes de framework et à l'analytique de l'hôte.\n */\nexport function create(params: StartVerificationParams): NayaVerification {\n const emitter = new Emitter<Record<string, NayaEvent | NayaResult>>();\n let handle: ReturnType<typeof mountNayaFlow> | null = null;\n let open = false;\n\n const instance: NayaVerification = {\n async open() {\n if (open) throw new Error('NayaId: le parcours est déjà ouvert.');\n const { auth, error } = validateAuth(params);\n if (error) {\n emitter.emit('result', error);\n return error;\n }\n open = true;\n const hostOnEvent = params.config?.onEvent;\n const config = resolveConfig({\n ...params.config,\n onEvent: (e) => {\n emitter.emit(e.type, e);\n hostOnEvent?.(e);\n },\n });\n handle = mountNayaFlow(auth, config);\n try {\n const result = await handle.result;\n emitter.emit('result', result);\n return result;\n } finally {\n open = false;\n handle = null;\n }\n },\n close() {\n handle?.close();\n },\n on(event, cb) {\n return emitter.on(event, cb);\n },\n destroy() {\n handle?.close();\n emitter.clear();\n },\n get isOpen() {\n return open;\n },\n };\n return instance;\n}\n\n// ── Web Component ─────────────────────────────────────────────────────────────\nconst ELEMENT_TAG = 'naya-id-verification';\n\n/**\n * `<naya-id-verification api-key=\"…\" country=\"BJ\" locale=\"fr\" inline auto>`\n * Attributs : `api-key`, `session-token`, `verification-id`, `locale`,\n * `country`, `document-types` (liste séparée par des virgules), `callback-url`,\n * `inline` (monte dans l'élément), `auto` (démarre à l'insertion), `theme-primary`,\n * `theme-accent`, `theme-mode`. Événements : `naya-event`, `naya-result`.\n */\nexport function defineElement(tag: string = ELEMENT_TAG): void {\n if (typeof customElements === 'undefined' || customElements.get(tag)) return;\n\n class NayaIdVerificationElement extends HTMLElement {\n private verification: NayaVerification | null = null;\n\n connectedCallback(): void {\n if (this.hasAttribute('auto')) void this.start();\n }\n\n disconnectedCallback(): void {\n this.verification?.destroy();\n this.verification = null;\n }\n\n private params(): StartVerificationParams {\n const attr = (n: string): string | undefined => this.getAttribute(n) ?? undefined;\n const docs = attr('document-types')\n ?.split(',')\n .map((s) => s.trim())\n .filter(Boolean) as NayaConfig['documentTypes'];\n const config: NayaConfig = {\n locale: attr('locale') as NayaConfig['locale'],\n country: attr('country') as NayaConfig['country'],\n documentTypes: docs && docs.length ? docs : undefined,\n callbackUrl: attr('callback-url'),\n container: this.hasAttribute('inline') ? this : null,\n theme: {\n primaryColor: attr('theme-primary'),\n accentColor: attr('theme-accent'),\n mode: attr('theme-mode') as 'light' | 'dark' | 'auto' | undefined,\n },\n onEvent: (e) => this.dispatchEvent(new CustomEvent('naya-event', { detail: e, bubbles: true })),\n };\n return {\n apiKey: attr('api-key'),\n sessionToken: attr('session-token'),\n verificationId: attr('verification-id'),\n config,\n };\n }\n\n /** Démarre le parcours ; résout avec le résultat, émis aussi en `naya-result`. */\n async start(): Promise<NayaResult> {\n this.verification?.destroy();\n this.verification = create(this.params());\n const result = await this.verification.open();\n this.dispatchEvent(new CustomEvent('naya-result', { detail: result, bubbles: true }));\n return result;\n }\n\n close(): void {\n this.verification?.close();\n }\n }\n\n customElements.define(tag, NayaIdVerificationElement);\n}\n\ndeclare const __NAYA_AUTO_DEFINE__: boolean | undefined;\n// Le bundle « balise script » enregistre l'élément automatiquement ; les\n// consommateurs ESM/CJS appellent `defineElement()` (aucun effet de bord à l'import).\nif (typeof __NAYA_AUTO_DEFINE__ !== 'undefined' && __NAYA_AUTO_DEFINE__) {\n try {\n defineElement();\n } catch {\n /* environnement sans customElements */\n }\n}\n\n/** Version du SDK. */\nexport const version = SDK_VERSION;\n\n// ── Surface publique : modèles, constantes et types ─────────────────────────\nexport {\n type NayaConfig,\n type NayaAuth,\n type NayaEvent,\n type NayaEventName,\n type NayaThemeOverrides,\n type NayaLivenessAssets,\n type NayaConsentOptions,\n type NayaCaptureOptions,\n type NayaLivenessOptions,\n type NayaHandoffOptions,\n type NayaCountryCode,\n type NayaDocumentType,\n type NayaLocale,\n type ResolvedNayaConfig,\n NAYA_COUNTRIES,\n NAYA_DOCUMENT_TYPES,\n NAYA_LOCALES,\n NAYA_DEFAULT_PRIMARY,\n NAYA_DEFAULT_ACCENT,\n NAYA_DEFAULT_BASE_URL,\n countryLabel,\n documentNeedsVerso,\n resolveConfig,\n detectLocale,\n} from './models/config';\nexport {\n type NayaResult,\n type NayaStatus,\n type NayaErrorCode,\n type NayaOcrData,\n parseOcrData,\n ocrToDeclaredData,\n cancelledResult,\n errorResult,\n} from './models/result';\nexport { NayaApiError } from './api/client';\nexport type { NayaSupport } from './support/capabilities';\n\nconst _default = { startVerification, create, isSupported, defineElement, version };\nexport default _default;\n"]}
|