@41devs/naya-id-js 0.1.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.
@@ -0,0 +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 ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' })[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"]}