@incodetech/core 0.0.0-dev-20260508-a05aa65 → 0.0.0-dev-20260508-4bd5e49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/dist/{addressSearch-DGVL5bWp.esm.js → addressSearch-DayrVNF_.esm.js} +1 -1
  2. package/dist/{ae-signature-CW0Y3VGK.esm.js → ae-signature-DsoDilvy.esm.js} +1 -1
  3. package/dist/ae-signature.d.ts +1 -1
  4. package/dist/ae-signature.esm.js +3 -3
  5. package/dist/antifraud.esm.js +2 -2
  6. package/dist/{antifraudStateMachine-D4G28SI4.esm.js → antifraudStateMachine-Dcg1T07S.esm.js} +1 -1
  7. package/dist/authentication.esm.js +5 -5
  8. package/dist/{authenticationManager-CO8WhECt.esm.js → authenticationManager-CVoZsbJX.esm.js} +3 -3
  9. package/dist/{authenticationStateMachine-BNH4XOow.esm.js → authenticationStateMachine-DyimpeBS.esm.js} +2 -2
  10. package/dist/consent.d.ts +47 -47
  11. package/dist/consent.esm.js +2 -2
  12. package/dist/{consentStateMachine-Bda2QqSh.esm.js → consentStateMachine-arnGM2iE.esm.js} +1 -1
  13. package/dist/cpf-ocr.d.ts +23 -23
  14. package/dist/cpf-ocr.esm.js +1 -1
  15. package/dist/cross-document-data-match.esm.js +1 -1
  16. package/dist/curp-validation.esm.js +2 -2
  17. package/dist/{curpValidationStateMachine-CYXt-Why.esm.js → curpValidationStateMachine-B0Yhzej1.esm.js} +1 -1
  18. package/dist/custom-fields.esm.js +1 -1
  19. package/dist/custom-watchlist.esm.js +1 -1
  20. package/dist/document-capture.d.ts +68 -68
  21. package/dist/document-capture.esm.js +2 -2
  22. package/dist/document-upload.d.ts +40 -40
  23. package/dist/document-upload.esm.js +1 -1
  24. package/dist/{documentCaptureStateMachine-SQ3AsME6.esm.js → documentCaptureStateMachine-fpqYHdZV.esm.js} +1 -1
  25. package/dist/dynamic-forms.esm.js +1 -1
  26. package/dist/ekyb.esm.js +5 -5
  27. package/dist/{ekybStateMachine-FXI54YYY.esm.js → ekybStateMachine-OJY8Sbql.esm.js} +3 -3
  28. package/dist/ekyc.esm.js +3 -3
  29. package/dist/{ekycStateMachine-B-R_nMk9.esm.js → ekycStateMachine-6OaK23Ab.esm.js} +2 -2
  30. package/dist/electronic-signature.d.ts +1 -1
  31. package/dist/electronic-signature.esm.js +2 -2
  32. package/dist/{electronicSignatureManager-W3dYg32m.esm.js → electronicSignatureManager-DYooXM8e.esm.js} +1 -1
  33. package/dist/email.esm.js +3 -3
  34. package/dist/{emailManager-Dcdv3r8N.esm.js → emailManager-CJAgi4be.esm.js} +2 -2
  35. package/dist/{emailStateMachine-CfL8um8y.esm.js → emailStateMachine-BW4tiYqt.esm.js} +1 -1
  36. package/dist/extensibility.d.ts +1 -1
  37. package/dist/extensibility.esm.js +14 -14
  38. package/dist/face-match.esm.js +2 -2
  39. package/dist/{faceCaptureManagerFactory-bM8uVQhs.esm.js → faceCaptureManagerFactory-ByAGjOLF.esm.js} +1 -1
  40. package/dist/{faceCaptureSetup-DPJ8f1ce.esm.js → faceCaptureSetup-D3dirkMC.esm.js} +1 -1
  41. package/dist/{faceMatchStateMachine-o_4FAl-g.esm.js → faceMatchStateMachine-Fwkg2Q37.esm.js} +1 -1
  42. package/dist/flow.d.ts +2 -2
  43. package/dist/flow.esm.js +4 -4
  44. package/dist/{flowServices-B41pWry3.esm.js → flowServices-MYPXBfNj.esm.js} +1 -1
  45. package/dist/geolocation.esm.js +2 -2
  46. package/dist/{geolocationStateMachine-Oj4giZl6.esm.js → geolocationStateMachine-15aagr2_.esm.js} +1 -1
  47. package/dist/government-validation.esm.js +2 -2
  48. package/dist/{governmentValidationStateMachine-DwZUuGG9.esm.js → governmentValidationStateMachine-Bg4F9j-0.esm.js} +1 -1
  49. package/dist/home.d.ts +10 -10
  50. package/dist/home.esm.js +1 -1
  51. package/dist/id-ocr.d.ts +52 -52
  52. package/dist/id-ocr.esm.js +2 -2
  53. package/dist/id.d.ts +1 -1
  54. package/dist/id.esm.js +4 -4
  55. package/dist/{idCaptureManager-6AfsPFbT.esm.js → idCaptureManager-BFE_QfGu.esm.js} +24 -22
  56. package/dist/{idCaptureManager-xbLvlmaw.d.ts → idCaptureManager-C4xBRJNt.d.ts} +25 -27
  57. package/dist/{idCaptureStateMachine-CjhFzer8.esm.js → idCaptureStateMachine-Em0doWas.esm.js} +377 -360
  58. package/dist/{idOcrStateMachine-Bh_LFdKk.esm.js → idOcrStateMachine-Dw4i2Yyo.esm.js} +1 -1
  59. package/dist/identity-reuse.d.ts +43 -43
  60. package/dist/identity-reuse.esm.js +1 -1
  61. package/dist/{index-CorEGzgE.d.ts → index-NXSeOGaz.d.ts} +119 -119
  62. package/dist/index.esm.js +2 -2
  63. package/dist/mandatory-consent.d.ts +47 -47
  64. package/dist/mandatory-consent.esm.js +2 -2
  65. package/dist/{mandatoryConsentStateMachine-b5d37Xvb.esm.js → mandatoryConsentStateMachine-D0CiwKkK.esm.js} +1 -1
  66. package/dist/phone.esm.js +3 -3
  67. package/dist/{phoneManager-CBupL3Zp.esm.js → phoneManager-BgAfR0DQ.esm.js} +2 -2
  68. package/dist/{phoneStateMachine-B0KqPCut.esm.js → phoneStateMachine-dDqWuk_Q.esm.js} +1 -1
  69. package/dist/{qe-signature-CLobj5mQ.esm.js → qe-signature-CaxK1LMD.esm.js} +1 -1
  70. package/dist/qe-signature.d.ts +1 -1
  71. package/dist/qe-signature.esm.js +3 -3
  72. package/dist/redirect-to-mobile.esm.js +2 -2
  73. package/dist/{redirectToMobileStateMachine-Dvias_ax.esm.js → redirectToMobileStateMachine-7bW5wC2f.esm.js} +1 -1
  74. package/dist/{runChildModule-BpsyjQ6x.esm.js → runChildModule-B16ocpd4.esm.js} +1 -1
  75. package/dist/selfie.esm.js +5 -5
  76. package/dist/{selfieManager-CNus5KCH.esm.js → selfieManager-C55Fsp9Q.esm.js} +3 -3
  77. package/dist/{selfieStateMachine-DCwYz6V1.esm.js → selfieStateMachine-CLqNjiIq.esm.js} +2 -2
  78. package/dist/{session-f758tX1l.esm.js → session-CSrf0jcz.esm.js} +1 -1
  79. package/dist/session.esm.js +1 -1
  80. package/dist/{setup-BOSxfmSM.esm.js → setup-NRuFzREQ.esm.js} +1 -1
  81. package/dist/signature.esm.js +2 -2
  82. package/dist/{signatureStateMachine-PoXfqqBQ.esm.js → signatureStateMachine-CB7XiLfo.esm.js} +1 -1
  83. package/dist/wasm.esm.js +2 -2
  84. package/dist/watchlist-for-business.esm.js +1 -1
  85. package/dist/watchlist.esm.js +1 -1
  86. package/dist/workflow.d.ts +87 -87
  87. package/dist/workflow.esm.js +27 -27
  88. package/dist/{xstate.esm-C19_S3_9.esm.js → xstate.esm-7GmmAwg6.esm.js} +1 -1
  89. package/package.json +3 -3
@@ -3,8 +3,8 @@ import { t as BrowserTimerProvider } from "./BrowserTimerProvider-BZGH3sYJ.esm.j
3
3
  import { r as getToken, t as api } from "./api-eqRXuVG-.esm.js";
4
4
  import { S as revokeObjectURL } from "./events-Bt1azl2B.esm.js";
5
5
  import { t as endpoints } from "./endpoints-B3V1U9Dg.esm.js";
6
- import { t as getDisableIpify } from "./session-f758tX1l.esm.js";
7
- import { i as fromPromise, n as assign, r as fromCallback, t as setup } from "./xstate.esm-C19_S3_9.esm.js";
6
+ import { t as getDisableIpify } from "./session-CSrf0jcz.esm.js";
7
+ import { a as fromPromise, i as fromCallback, n as sendTo, r as assign, t as setup } from "./xstate.esm-7GmmAwg6.esm.js";
8
8
  import { _ as StreamCanvasCapture, d as createRecordingSession, f as startRecording, g as flagIdManualReview, m as StreamCanvasProcessingSession, n as preloadOpenViduProvider, p as stopRecording$1 } from "./recordingService-Dc8qrd2u.esm.js";
9
9
  import { n as IncodeCanvas } from "./deepsightService-gNTXZu7Y.esm.js";
10
10
  import { n as requestPermission, r as clearCameraPermissionCache, t as checkPermission } from "./permissionServices-DIxFacTA.esm.js";
@@ -197,6 +197,12 @@ async function getIdCameraStream(deviceId) {
197
197
  return getBackCameraStream(deviceId);
198
198
  }
199
199
 
200
+ //#endregion
201
+ //#region src/modules/id/manualUpload/types.ts
202
+ const MANUAL_UPLOAD_MAX_RETRIES = 3;
203
+ const MANUAL_UPLOAD_MAX_FILE_SIZE_BYTES = 5 * 1024 * 1024;
204
+ const MANUAL_UPLOAD_EXHAUSTION_FORWARD_MS = 5e3;
205
+
200
206
  //#endregion
201
207
  //#region src/modules/id/types.ts
202
208
  const ID_ERROR_CODES = {
@@ -216,9 +222,6 @@ const ID_ERROR_CODES = {
216
222
  USER_CANCELLED: "USER_CANCELLED",
217
223
  SERVER: "SERVER_ERROR"
218
224
  };
219
- const MANUAL_UPLOAD_MAX_RETRIES = 3;
220
- const MANUAL_UPLOAD_MAX_FILE_SIZE_BYTES = 5 * 1024 * 1024;
221
- const MANUAL_UPLOAD_EXHAUSTION_FORWARD_MS = 5e3;
222
225
 
223
226
  //#endregion
224
227
  //#region src/modules/id/idCaptureServices.ts
@@ -501,6 +504,337 @@ async function uploadManualIdFile(params) {
501
504
  return res.data;
502
505
  }
503
506
 
507
+ //#endregion
508
+ //#region src/modules/id/manualUpload/manualUploadErrors.ts
509
+ /**
510
+ * i18n keys for manual-upload user-facing error copy.
511
+ * Keep in sync with `packages/ui/src/i18n/**.json` under the `manualIdUpload.*` namespace.
512
+ */
513
+ const MANUAL_UPLOAD_ERROR_KEYS = {
514
+ wrongSide: "manualIdUpload.wrongSide",
515
+ wrongDocument: "manualIdUpload.wrongDocument",
516
+ fileTooBig: "manualIdUpload.fileTooBig",
517
+ generic: "manualIdUpload.generic",
518
+ lowSharpness: "manualIdUpload.lowSharpness",
519
+ glareDetected: "manualIdUpload.glareDetected",
520
+ readabilityIssue: "manualIdUpload.readabilityIssue",
521
+ qualityRejected: "manualIdUpload.qualityRejected"
522
+ };
523
+ /**
524
+ * Map the server's `failReason` (plus client-side passport/ID tab mismatch and
525
+ * per-image quality flags) onto an i18n key. Mirrors v1's `shouldUploadAgain`
526
+ * branch logic in
527
+ * `ms-incodesmile-web/packages/incode-welcome/src/manualIdUpload/manuaIdUpload.tsx`,
528
+ * extended to also reject responses where the backend flagged a per-image
529
+ * quality issue (`correctSharpness`, `correctGlare`, `readability`, or
530
+ * `idQualityAttemptApproved` set to `false`).
531
+ *
532
+ * Quality flags are checked with `=== false` so missing/undefined values
533
+ * (older backends, partial payloads) keep the legacy "trust the server"
534
+ * behaviour and do not produce false positives.
535
+ *
536
+ * Returns `null` when the response represents a successful upload — the caller
537
+ * should treat `null` as "no error, advance to next slot".
538
+ */
539
+ function mapFailReasonToErrorKey(response, expectedTab) {
540
+ const failReason = response.failReason;
541
+ if (failReason === "WRONG_DOCUMENT_SIDE") return MANUAL_UPLOAD_ERROR_KEYS.wrongSide;
542
+ if (failReason === "WRONG_ONE_SIDED_DOCUMENT" || failReason === "UNKNOWN_DOCUMENT_TYPE") return MANUAL_UPLOAD_ERROR_KEYS.wrongDocument;
543
+ if (failReason === "ID_TYPE_UNACCEPTABLE") return MANUAL_UPLOAD_ERROR_KEYS.wrongDocument;
544
+ if (expectedTab === "passport" && response.typeOfId && response.typeOfId.toLowerCase() !== "passport") return MANUAL_UPLOAD_ERROR_KEYS.wrongDocument;
545
+ if (expectedTab === "id" && response.typeOfId?.toLowerCase() === "passport") return MANUAL_UPLOAD_ERROR_KEYS.wrongDocument;
546
+ if (response.correctSharpness === false) return MANUAL_UPLOAD_ERROR_KEYS.lowSharpness;
547
+ if (response.correctGlare === false) return MANUAL_UPLOAD_ERROR_KEYS.glareDetected;
548
+ if (response.readability === false) return MANUAL_UPLOAD_ERROR_KEYS.readabilityIssue;
549
+ if (response.idQualityAttemptApproved === false) return MANUAL_UPLOAD_ERROR_KEYS.qualityRejected;
550
+ return null;
551
+ }
552
+
553
+ //#endregion
554
+ //#region src/modules/id/manualUpload/manualUploadServices.ts
555
+ /**
556
+ * Read a File's bytes and return the raw base64 payload (the portion after
557
+ * `data:<mime>;base64,`). The backend's `/omni/add/*-id/v2` endpoints reject
558
+ * full data-URLs with `IllegalArgumentException: Illegal base64 character 3a`,
559
+ * so the prefix must be stripped before posting. Mirrors the live-camera
560
+ * path in `packages/infra/src/media/canvas.ts:getBase64Image()`.
561
+ */
562
+ function fileToBase64Payload(file) {
563
+ return new Promise((resolve, reject) => {
564
+ const reader = new FileReader();
565
+ reader.onload = () => {
566
+ const result = reader.result;
567
+ if (typeof result !== "string") {
568
+ reject(/* @__PURE__ */ new Error("FileReader produced non-string result"));
569
+ return;
570
+ }
571
+ const commaIndex = result.indexOf(",");
572
+ resolve(commaIndex === -1 ? result : result.slice(commaIndex + 1));
573
+ };
574
+ reader.onerror = () => {
575
+ reject(reader.error ?? /* @__PURE__ */ new Error("FileReader failed"));
576
+ };
577
+ reader.readAsDataURL(file);
578
+ });
579
+ }
580
+
581
+ //#endregion
582
+ //#region src/modules/id/manualUpload/manualUploadStateMachine.ts
583
+ const uploadManualFileActor = fromPromise(async ({ input, signal }) => {
584
+ const base64Image = await fileToBase64Payload(input.file);
585
+ return uploadManualIdFile({
586
+ side: input.side,
587
+ base64Image,
588
+ retry: input.retry,
589
+ onlyFront: input.onlyFront,
590
+ isSecondId: input.isSecondId,
591
+ signal
592
+ });
593
+ });
594
+ const getUploadResponseFromEvent = (event) => {
595
+ if ("output" in event) return event.output;
596
+ };
597
+ const _manualUploadMachine = setup({
598
+ types: {
599
+ context: {},
600
+ events: {},
601
+ input: {},
602
+ output: {}
603
+ },
604
+ actors: { uploadManualFile: uploadManualFileActor },
605
+ actions: {
606
+ setManualUploadActiveTab: assign(({ event }) => {
607
+ if (event.type !== "MANUAL_UPLOAD_TAB_CHANGED") return {};
608
+ return {
609
+ activeTab: event.tab,
610
+ frontFile: null,
611
+ backFile: null,
612
+ passportFile: null,
613
+ frontUploaded: false,
614
+ backUploaded: false,
615
+ passportUploaded: false,
616
+ skipBackFromServer: false,
617
+ errorMessage: null,
618
+ retriesLeft: MANUAL_UPLOAD_MAX_RETRIES
619
+ };
620
+ }),
621
+ resetManualUpload: assign(() => ({
622
+ frontFile: null,
623
+ backFile: null,
624
+ passportFile: null,
625
+ frontUploaded: false,
626
+ backUploaded: false,
627
+ passportUploaded: false,
628
+ skipBackFromServer: false,
629
+ errorMessage: null,
630
+ retriesLeft: MANUAL_UPLOAD_MAX_RETRIES
631
+ })),
632
+ storeSelectedFile: assign(({ event }) => {
633
+ if (event.type !== "MANUAL_UPLOAD_FILE_SELECTED") return {};
634
+ const updated = { errorMessage: null };
635
+ if (event.side === "front") updated.frontFile = event.file;
636
+ else if (event.side === "back") updated.backFile = event.file;
637
+ else updated.passportFile = event.file;
638
+ return updated;
639
+ }),
640
+ markFrontUploaded: assign(() => ({
641
+ frontUploaded: true,
642
+ errorMessage: null
643
+ })),
644
+ markBackUploaded: assign(() => ({
645
+ backUploaded: true,
646
+ errorMessage: null
647
+ })),
648
+ markPassportUploaded: assign(() => ({
649
+ passportUploaded: true,
650
+ errorMessage: null
651
+ })),
652
+ recordSkipBackFromResponse: assign(({ event }) => {
653
+ if (!("output" in event)) return {};
654
+ if (!event.output.skipBackIdCapture) return {};
655
+ return { skipBackFromServer: true };
656
+ }),
657
+ decrementManualUploadRetries: assign(({ context }) => ({ retriesLeft: Math.max(0, context.retriesLeft - 1) })),
658
+ setManualUploadErrorFromResponse: assign(({ context, event }) => {
659
+ if (!("output" in event)) return {};
660
+ const response = event.output;
661
+ return { errorMessage: mapFailReasonToErrorKey(response, context.activeTab) ?? "manualIdUpload.generic" };
662
+ }),
663
+ setManualUploadGenericError: assign(() => ({ errorMessage: "manualIdUpload.generic" })),
664
+ setManualUploadFileTooLargeError: assign(() => ({ errorMessage: "manualIdUpload.fileTooBig" })),
665
+ clearManualUploadError: assign(() => ({ errorMessage: null }))
666
+ },
667
+ guards: {
668
+ isSelectedFileTooLarge: ({ event }) => {
669
+ if (event.type !== "MANUAL_UPLOAD_FILE_SELECTED") return false;
670
+ return event.file.size > MANUAL_UPLOAD_MAX_FILE_SIZE_BYTES;
671
+ },
672
+ isFrontFileSelection: ({ event }) => event.type === "MANUAL_UPLOAD_FILE_SELECTED" && event.side === "front",
673
+ isBackFileSelection: ({ event }) => event.type === "MANUAL_UPLOAD_FILE_SELECTED" && event.side === "back",
674
+ isPassportFileSelection: ({ event }) => event.type === "MANUAL_UPLOAD_FILE_SELECTED" && event.side === "passport",
675
+ manualUploadRetriesExhausted: ({ context }) => context.retriesLeft <= 0,
676
+ canContinueFromIdTab: ({ context }) => {
677
+ if (context.activeTab !== "id") return false;
678
+ if (!context.frontUploaded) return false;
679
+ if (context.onlyFront) return true;
680
+ if (context.skipBackFromServer) return true;
681
+ return context.backUploaded;
682
+ },
683
+ canContinueFromPassportTab: ({ context }) => context.activeTab === "passport" && context.passportUploaded,
684
+ manualUploadResponseHasError: ({ context, event }) => {
685
+ const response = getUploadResponseFromEvent(event);
686
+ if (!response) return false;
687
+ return mapFailReasonToErrorKey(response, context.activeTab) !== null;
688
+ }
689
+ }
690
+ }).createMachine({
691
+ id: "manualUpload",
692
+ initial: "selecting",
693
+ context: ({ input }) => ({
694
+ onlyFront: input.onlyFront,
695
+ isSecondId: input.isSecondId,
696
+ frontFile: null,
697
+ backFile: null,
698
+ passportFile: null,
699
+ activeTab: "id",
700
+ retriesLeft: MANUAL_UPLOAD_MAX_RETRIES,
701
+ errorMessage: null,
702
+ skipBackFromServer: false,
703
+ frontUploaded: false,
704
+ backUploaded: false,
705
+ passportUploaded: false
706
+ }),
707
+ on: {
708
+ MANUAL_UPLOAD_TAB_CHANGED: {
709
+ target: ".selecting",
710
+ actions: ["setManualUploadActiveTab"]
711
+ },
712
+ MANUAL_UPLOAD_RESET: {
713
+ target: ".selecting",
714
+ actions: ["resetManualUpload"]
715
+ }
716
+ },
717
+ states: {
718
+ selecting: { on: {
719
+ MANUAL_UPLOAD_FILE_SELECTED: [
720
+ {
721
+ guard: "isSelectedFileTooLarge",
722
+ actions: ["setManualUploadFileTooLargeError"]
723
+ },
724
+ {
725
+ guard: "isFrontFileSelection",
726
+ target: "uploadingFront",
727
+ actions: ["storeSelectedFile"]
728
+ },
729
+ {
730
+ guard: "isBackFileSelection",
731
+ target: "uploadingBack",
732
+ actions: ["storeSelectedFile"]
733
+ },
734
+ {
735
+ guard: "isPassportFileSelection",
736
+ target: "uploadingPassport",
737
+ actions: ["storeSelectedFile"]
738
+ }
739
+ ],
740
+ MANUAL_UPLOAD_CONTINUE: [{
741
+ guard: "canContinueFromIdTab",
742
+ target: "finished"
743
+ }, {
744
+ guard: "canContinueFromPassportTab",
745
+ target: "finished"
746
+ }]
747
+ } },
748
+ uploadingFront: { invoke: {
749
+ id: "uploadManualFile",
750
+ src: "uploadManualFile",
751
+ input: ({ context }) => ({
752
+ side: "front",
753
+ file: context.frontFile,
754
+ retry: context.retriesLeft < MANUAL_UPLOAD_MAX_RETRIES,
755
+ onlyFront: context.onlyFront,
756
+ isSecondId: context.isSecondId
757
+ }),
758
+ onDone: [{
759
+ guard: "manualUploadResponseHasError",
760
+ target: "checkRetries",
761
+ actions: ["decrementManualUploadRetries", "setManualUploadErrorFromResponse"]
762
+ }, {
763
+ target: "selecting",
764
+ actions: [
765
+ "markFrontUploaded",
766
+ "recordSkipBackFromResponse",
767
+ "clearManualUploadError"
768
+ ]
769
+ }],
770
+ onError: {
771
+ target: "checkRetries",
772
+ actions: ["decrementManualUploadRetries", "setManualUploadGenericError"]
773
+ }
774
+ } },
775
+ uploadingBack: { invoke: {
776
+ id: "uploadManualFile",
777
+ src: "uploadManualFile",
778
+ input: ({ context }) => ({
779
+ side: "back",
780
+ file: context.backFile,
781
+ retry: context.retriesLeft < MANUAL_UPLOAD_MAX_RETRIES,
782
+ onlyFront: false,
783
+ isSecondId: context.isSecondId
784
+ }),
785
+ onDone: [{
786
+ guard: "manualUploadResponseHasError",
787
+ target: "checkRetries",
788
+ actions: ["decrementManualUploadRetries", "setManualUploadErrorFromResponse"]
789
+ }, {
790
+ target: "selecting",
791
+ actions: ["markBackUploaded", "clearManualUploadError"]
792
+ }],
793
+ onError: {
794
+ target: "checkRetries",
795
+ actions: ["decrementManualUploadRetries", "setManualUploadGenericError"]
796
+ }
797
+ } },
798
+ uploadingPassport: { invoke: {
799
+ id: "uploadManualFile",
800
+ src: "uploadManualFile",
801
+ input: ({ context }) => ({
802
+ side: "passport",
803
+ file: context.passportFile,
804
+ retry: context.retriesLeft < MANUAL_UPLOAD_MAX_RETRIES,
805
+ onlyFront: false,
806
+ isSecondId: context.isSecondId
807
+ }),
808
+ onDone: [{
809
+ guard: "manualUploadResponseHasError",
810
+ target: "checkRetries",
811
+ actions: ["decrementManualUploadRetries", "setManualUploadErrorFromResponse"]
812
+ }, {
813
+ target: "selecting",
814
+ actions: ["markPassportUploaded", "clearManualUploadError"]
815
+ }],
816
+ onError: {
817
+ target: "checkRetries",
818
+ actions: ["decrementManualUploadRetries", "setManualUploadGenericError"]
819
+ }
820
+ } },
821
+ checkRetries: { always: [{
822
+ guard: "manualUploadRetriesExhausted",
823
+ target: "retriesExhausted"
824
+ }, { target: "selecting" }] },
825
+ retriesExhausted: { after: { [MANUAL_UPLOAD_EXHAUSTION_FORWARD_MS]: { target: "exhausted" } } },
826
+ exhausted: {
827
+ type: "final",
828
+ output: { result: "exhausted" }
829
+ },
830
+ finished: {
831
+ type: "final",
832
+ output: { result: "success" }
833
+ }
834
+ }
835
+ });
836
+ const manualUploadMachine = _manualUploadMachine;
837
+
504
838
  //#endregion
505
839
  //#region ../infra/src/wasm/idCaptureDefaults.ts
506
840
  /**
@@ -611,7 +945,7 @@ const runDetectionActor = fromCallback(({ input, sendBack }) => {
611
945
  windowInnerWidth: windowDimensions.innerWidth,
612
946
  windowInnerHeight: windowDimensions.innerHeight
613
947
  });
614
- const idType = input.currentMode === "back" ? "BackId" : input.currentMode === "passport" || input.currentMode === "front" && input.config.onlyFront ? "Passport" : "FrontId";
948
+ const idType = input.currentMode === "back" ? "BackId" : input.currentMode === "passport" ? "Passport" : "FrontId";
615
949
  provider.setSettings({
616
950
  isFixedMask: input.config.settings?.isFixedMask ?? false,
617
951
  isIPhone14OrHigher: input.config.settings?.isIPhone14OrHigher ?? false,
@@ -854,88 +1188,6 @@ const checkVirtualCameraActor = fromPromise(async ({ input }) => {
854
1188
  if (!videoTrack) return false;
855
1189
  return input.deepsightService.checkVirtualCamera(videoTrack);
856
1190
  });
857
- /**
858
- * Read a File's bytes and return the raw base64 payload (the portion after
859
- * `data:<mime>;base64,`). The backend's `/omni/add/*-id/v2` endpoints reject
860
- * full data-URLs with `IllegalArgumentException: Illegal base64 character 3a`,
861
- * so the prefix must be stripped before posting. Mirrors the live-camera
862
- * path in `packages/infra/src/media/canvas.ts:getBase64Image()`.
863
- */
864
- function fileToBase64Payload(file) {
865
- return new Promise((resolve, reject) => {
866
- const reader = new FileReader();
867
- reader.onload = () => {
868
- const result = reader.result;
869
- if (typeof result !== "string") {
870
- reject(/* @__PURE__ */ new Error("FileReader produced non-string result"));
871
- return;
872
- }
873
- const commaIndex = result.indexOf(",");
874
- resolve(commaIndex === -1 ? result : result.slice(commaIndex + 1));
875
- };
876
- reader.onerror = () => {
877
- reject(reader.error ?? /* @__PURE__ */ new Error("FileReader failed"));
878
- };
879
- reader.readAsDataURL(file);
880
- });
881
- }
882
- const uploadManualFileActor = fromPromise(async ({ input, signal }) => {
883
- const base64Image = await fileToBase64Payload(input.file);
884
- return uploadManualIdFile({
885
- side: input.side,
886
- base64Image,
887
- retry: input.retry,
888
- onlyFront: input.onlyFront,
889
- isSecondId: input.isSecondId,
890
- signal
891
- });
892
- });
893
-
894
- //#endregion
895
- //#region src/modules/id/manualUploadErrors.ts
896
- /**
897
- * i18n keys for manual-upload user-facing error copy.
898
- * Keep in sync with `packages/ui/src/i18n/**.json` under the `manualIdUpload.*` namespace.
899
- */
900
- const MANUAL_UPLOAD_ERROR_KEYS = {
901
- wrongSide: "manualIdUpload.wrongSide",
902
- wrongDocument: "manualIdUpload.wrongDocument",
903
- fileTooBig: "manualIdUpload.fileTooBig",
904
- generic: "manualIdUpload.generic",
905
- lowSharpness: "manualIdUpload.lowSharpness",
906
- glareDetected: "manualIdUpload.glareDetected",
907
- readabilityIssue: "manualIdUpload.readabilityIssue",
908
- qualityRejected: "manualIdUpload.qualityRejected"
909
- };
910
- /**
911
- * Map the server's `failReason` (plus client-side passport/ID tab mismatch and
912
- * per-image quality flags) onto an i18n key. Mirrors v1's `shouldUploadAgain`
913
- * branch logic in
914
- * `ms-incodesmile-web/packages/incode-welcome/src/manualIdUpload/manuaIdUpload.tsx`,
915
- * extended to also reject responses where the backend flagged a per-image
916
- * quality issue (`correctSharpness`, `correctGlare`, `readability`, or
917
- * `idQualityAttemptApproved` set to `false`).
918
- *
919
- * Quality flags are checked with `=== false` so missing/undefined values
920
- * (older backends, partial payloads) keep the legacy "trust the server"
921
- * behaviour and do not produce false positives.
922
- *
923
- * Returns `null` when the response represents a successful upload — the caller
924
- * should treat `null` as "no error, advance to next slot".
925
- */
926
- function mapFailReasonToErrorKey(response, expectedTab) {
927
- const failReason = response.failReason;
928
- if (failReason === "WRONG_DOCUMENT_SIDE") return MANUAL_UPLOAD_ERROR_KEYS.wrongSide;
929
- if (failReason === "WRONG_ONE_SIDED_DOCUMENT" || failReason === "UNKNOWN_DOCUMENT_TYPE") return MANUAL_UPLOAD_ERROR_KEYS.wrongDocument;
930
- if (failReason === "ID_TYPE_UNACCEPTABLE") return MANUAL_UPLOAD_ERROR_KEYS.wrongDocument;
931
- if (expectedTab === "passport" && response.typeOfId && response.typeOfId.toLowerCase() !== "passport") return MANUAL_UPLOAD_ERROR_KEYS.wrongDocument;
932
- if (expectedTab === "id" && response.typeOfId?.toLowerCase() === "passport") return MANUAL_UPLOAD_ERROR_KEYS.wrongDocument;
933
- if (response.correctSharpness === false) return MANUAL_UPLOAD_ERROR_KEYS.lowSharpness;
934
- if (response.correctGlare === false) return MANUAL_UPLOAD_ERROR_KEYS.glareDetected;
935
- if (response.readability === false) return MANUAL_UPLOAD_ERROR_KEYS.readabilityIssue;
936
- if (response.idQualityAttemptApproved === false) return MANUAL_UPLOAD_ERROR_KEYS.qualityRejected;
937
- return null;
938
- }
939
1191
 
940
1192
  //#endregion
941
1193
  //#region src/modules/id/idCaptureActions.ts
@@ -1202,10 +1454,18 @@ const hasUploadValidationErrorGuard = ({ context }) => {
1202
1454
  }) !== void 0;
1203
1455
  };
1204
1456
  const isFrontModeGuard = ({ context }) => context.currentMode === "front" || context.currentMode === "passport";
1205
- const isOnlyFrontGuard = ({ context }) => context.config.onlyFront;
1457
+ /**
1458
+ * `config.onlyFront` from the orchestrated flow JSON is intentionally not
1459
+ * read here: the flow value cannot account for per-document overrides, so the
1460
+ * backend resolves the real policy per document at upload time
1461
+ * (via `skipBackIdCapture` on the upload response). Standalone
1462
+ * `idCaptureManager` consumers that pass `onlyFront: true` directly will
1463
+ * therefore also be ignored — re-wire this guard if that capability is needed
1464
+ * again.
1465
+ */
1466
+ const isOnlyFrontGuard = (_args) => false;
1206
1467
  const shouldContinueToBackGuard = ({ context }) => {
1207
1468
  if (context.currentMode !== "front" && context.currentMode !== "passport") return false;
1208
- if (context.config.onlyFront) return false;
1209
1469
  if (context.config.onlyBack) return false;
1210
1470
  if (context.config.usSmartCapture) return false;
1211
1471
  if (context.uploadResponse?.skipBackIdCapture) {
@@ -1218,45 +1478,6 @@ const hasMandatoryConsentGuard = ({ context }) => context.uploadResponse?.showMa
1218
1478
  const isDeepsightEnabledGuard = ({ context }) => context.dependencies !== void 0;
1219
1479
  const isDeepsightReadyGuard = ({ context }) => context.deepsightService !== void 0;
1220
1480
  const needsDeepsightInitGuard = ({ context }) => context.dependencies !== void 0 && context.deepsightService === void 0 && !context.deepsightInitAttempted;
1221
- const getFileFromEvent = (event) => {
1222
- if (event.type === "MANUAL_UPLOAD_FILE_SELECTED") return event.file;
1223
- };
1224
- const getSideFromEvent = (event) => {
1225
- if (event.type === "MANUAL_UPLOAD_FILE_SELECTED") return event.side;
1226
- };
1227
- const isSelectedFileTooLargeGuard = ({ event }) => {
1228
- const file = getFileFromEvent(event);
1229
- return file ? file.size > MANUAL_UPLOAD_MAX_FILE_SIZE_BYTES : false;
1230
- };
1231
- const isFrontFileSelectionGuard = ({ event }) => getSideFromEvent(event) === "front";
1232
- const isBackFileSelectionGuard = ({ event }) => getSideFromEvent(event) === "back";
1233
- const isPassportFileSelectionGuard = ({ event }) => getSideFromEvent(event) === "passport";
1234
- /**
1235
- * True once `retriesLeft` has been decremented to 0 — evaluated from the
1236
- * `checkRetries` state after the decrement action runs.
1237
- */
1238
- const manualUploadRetriesExhaustedGuard = ({ context }) => context.manualUpload.retriesLeft <= 0;
1239
- const canContinueFromIdTabGuard = ({ context }) => {
1240
- if (context.manualUpload.activeTab !== "id") return false;
1241
- if (!context.manualUpload.frontUploaded) return false;
1242
- if (context.config.onlyFront) return true;
1243
- if (context.manualUpload.skipBackFromServer) return true;
1244
- return context.manualUpload.backUploaded;
1245
- };
1246
- const canContinueFromPassportTabGuard = ({ context }) => context.manualUpload.activeTab === "passport" && context.manualUpload.passportUploaded;
1247
- const getUploadResponseFromEvent = (event) => {
1248
- if ("output" in event) return event.output;
1249
- };
1250
- /**
1251
- * True when the server-side upload response contains a failReason or type
1252
- * mismatch that should be surfaced to the user and counted against retries.
1253
- * Evaluated by the actor's `onDone`, so the response lives on `event.output`.
1254
- */
1255
- const manualUploadResponseHasErrorGuard = ({ context, event }) => {
1256
- const response = getUploadResponseFromEvent(event);
1257
- if (!response) return false;
1258
- return mapFailReasonToErrorKey(response, context.manualUpload.activeTab) !== null;
1259
- };
1260
1481
  const hasOnlyManualUploadAvailableGuard = ({ context }) => context.availableDocumentTypes.length === 1 && context.availableDocumentTypes[0] === "manualIdUpload";
1261
1482
  const isManualIdUploadSelectedGuard = ({ event }) => event.type === "SELECT_DOCUMENT" && event.documentType === "manualIdUpload";
1262
1483
 
@@ -1285,7 +1506,7 @@ const _idCaptureMachine = setup({
1285
1506
  checkMotionSensor: checkMotionSensorActor,
1286
1507
  initializeDeepsightSession: initializeDeepsightSessionActor,
1287
1508
  checkVirtualCamera: checkVirtualCameraActor,
1288
- uploadManualFile: uploadManualFileActor
1509
+ manualUploadMachine
1289
1510
  },
1290
1511
  actions: {
1291
1512
  stopMediaStream: assign(({ context }) => {
@@ -1437,94 +1658,7 @@ const _idCaptureMachine = setup({
1437
1658
  } }),
1438
1659
  setMotionStatus: assign({ motionStatus: ({ event }) => {
1439
1660
  if ("status" in event && event.type === "MOTION_STATUS") return event.status;
1440
- } }),
1441
- setManualUploadActiveTab: assign(({ context, event }) => {
1442
- if (event.type !== "MANUAL_UPLOAD_TAB_CHANGED") return {};
1443
- return { manualUpload: {
1444
- ...context.manualUpload,
1445
- activeTab: event.tab,
1446
- frontFile: null,
1447
- backFile: null,
1448
- passportFile: null,
1449
- frontUploaded: false,
1450
- backUploaded: false,
1451
- passportUploaded: false,
1452
- skipBackFromServer: false,
1453
- errorMessage: null,
1454
- retriesLeft: MANUAL_UPLOAD_MAX_RETRIES
1455
- } };
1456
- }),
1457
- resetManualUpload: assign(({ context }) => ({ manualUpload: {
1458
- ...context.manualUpload,
1459
- frontFile: null,
1460
- backFile: null,
1461
- passportFile: null,
1462
- frontUploaded: false,
1463
- backUploaded: false,
1464
- passportUploaded: false,
1465
- skipBackFromServer: false,
1466
- errorMessage: null,
1467
- retriesLeft: MANUAL_UPLOAD_MAX_RETRIES
1468
- } })),
1469
- storeSelectedFile: assign(({ context, event }) => {
1470
- if (event.type !== "MANUAL_UPLOAD_FILE_SELECTED") return {};
1471
- const updated = {
1472
- ...context.manualUpload,
1473
- errorMessage: null
1474
- };
1475
- if (event.side === "front") updated.frontFile = event.file;
1476
- else if (event.side === "back") updated.backFile = event.file;
1477
- else updated.passportFile = event.file;
1478
- return { manualUpload: updated };
1479
- }),
1480
- markFrontUploaded: assign(({ context }) => ({ manualUpload: {
1481
- ...context.manualUpload,
1482
- frontUploaded: true,
1483
- errorMessage: null
1484
- } })),
1485
- markBackUploaded: assign(({ context }) => ({ manualUpload: {
1486
- ...context.manualUpload,
1487
- backUploaded: true,
1488
- errorMessage: null
1489
- } })),
1490
- markPassportUploaded: assign(({ context }) => ({ manualUpload: {
1491
- ...context.manualUpload,
1492
- passportUploaded: true,
1493
- errorMessage: null
1494
- } })),
1495
- recordSkipBackFromResponse: assign(({ context, event }) => {
1496
- if (!("output" in event)) return {};
1497
- if (!event.output.skipBackIdCapture) return {};
1498
- return { manualUpload: {
1499
- ...context.manualUpload,
1500
- skipBackFromServer: true
1501
- } };
1502
- }),
1503
- decrementManualUploadRetries: assign(({ context }) => ({ manualUpload: {
1504
- ...context.manualUpload,
1505
- retriesLeft: Math.max(0, context.manualUpload.retriesLeft - 1)
1506
- } })),
1507
- setManualUploadErrorFromResponse: assign(({ context, event }) => {
1508
- if (!("output" in event)) return {};
1509
- const response = event.output;
1510
- const errorKey = mapFailReasonToErrorKey(response, context.manualUpload.activeTab);
1511
- return { manualUpload: {
1512
- ...context.manualUpload,
1513
- errorMessage: errorKey ?? "manualIdUpload.generic"
1514
- } };
1515
- }),
1516
- setManualUploadGenericError: assign(({ context }) => ({ manualUpload: {
1517
- ...context.manualUpload,
1518
- errorMessage: "manualIdUpload.generic"
1519
- } })),
1520
- setManualUploadFileTooLargeError: assign(({ context }) => ({ manualUpload: {
1521
- ...context.manualUpload,
1522
- errorMessage: "manualIdUpload.fileTooBig"
1523
- } })),
1524
- clearManualUploadError: assign(({ context }) => ({ manualUpload: {
1525
- ...context.manualUpload,
1526
- errorMessage: null
1527
- } }))
1661
+ } })
1528
1662
  },
1529
1663
  guards: {
1530
1664
  hasShowTutorial: hasShowTutorialGuard,
@@ -1544,16 +1678,9 @@ const _idCaptureMachine = setup({
1544
1678
  isDeepsightEnabled: isDeepsightEnabledGuard,
1545
1679
  isDeepsightReady: isDeepsightReadyGuard,
1546
1680
  needsDeepsightInit: needsDeepsightInitGuard,
1547
- isSelectedFileTooLarge: isSelectedFileTooLargeGuard,
1548
- isFrontFileSelection: isFrontFileSelectionGuard,
1549
- isBackFileSelection: isBackFileSelectionGuard,
1550
- isPassportFileSelection: isPassportFileSelectionGuard,
1551
- manualUploadRetriesExhausted: manualUploadRetriesExhaustedGuard,
1552
- canContinueFromIdTab: canContinueFromIdTabGuard,
1553
- canContinueFromPassportTab: canContinueFromPassportTabGuard,
1554
- manualUploadResponseHasError: manualUploadResponseHasErrorGuard,
1555
1681
  hasOnlyManualUploadAvailable: hasOnlyManualUploadAvailableGuard,
1556
- isManualIdUploadSelected: isManualIdUploadSelectedGuard
1682
+ isManualIdUploadSelected: isManualIdUploadSelectedGuard,
1683
+ isManualUploadExhausted: ({ event }) => event.output?.result === "exhausted"
1557
1684
  }
1558
1685
  }).createMachine({
1559
1686
  id: "idCapture",
@@ -1594,19 +1721,7 @@ const _idCaptureMachine = setup({
1594
1721
  deepsightInitAttempted: false,
1595
1722
  availableDocumentTypes: getAvailableDocumentTypes(input.config),
1596
1723
  captureResolution: void 0,
1597
- cameraFallbackLevel: void 0,
1598
- manualUpload: {
1599
- frontFile: null,
1600
- backFile: null,
1601
- passportFile: null,
1602
- activeTab: "id",
1603
- retriesLeft: MANUAL_UPLOAD_MAX_RETRIES,
1604
- errorMessage: null,
1605
- skipBackFromServer: false,
1606
- frontUploaded: false,
1607
- backUploaded: false,
1608
- passportUploaded: false
1609
- }
1724
+ cameraFallbackLevel: void 0
1610
1725
  };
1611
1726
  },
1612
1727
  on: {
@@ -2057,7 +2172,7 @@ const _idCaptureMachine = setup({
2057
2172
  deepsightService: context.deepsightService,
2058
2173
  stream: context.stream,
2059
2174
  isSecondId: context.config.isSecondId ?? false,
2060
- onlyFront: context.config.onlyFront,
2175
+ onlyFront: false,
2061
2176
  ageAssurance: context.config.ageAssurance,
2062
2177
  dependencies: context.dependencies,
2063
2178
  captureResolution: context.captureResolution,
@@ -2301,127 +2416,29 @@ const _idCaptureMachine = setup({
2301
2416
  } }
2302
2417
  },
2303
2418
  manualIdUpload: {
2304
- initial: "selecting",
2305
- on: {
2306
- QUIT: { target: "closed" },
2307
- MANUAL_UPLOAD_TAB_CHANGED: {
2308
- target: ".selecting",
2309
- actions: ["setManualUploadActiveTab"]
2310
- },
2311
- MANUAL_UPLOAD_RESET: {
2312
- target: ".selecting",
2313
- actions: ["resetManualUpload"]
2419
+ invoke: {
2420
+ id: "manualIdUpload",
2421
+ src: "manualUploadMachine",
2422
+ input: ({ context }) => ({
2423
+ isSecondId: context.config.isSecondId ?? false,
2424
+ onlyFront: false
2425
+ }),
2426
+ onSnapshot: { actions: () => {} },
2427
+ onDone: [{
2428
+ guard: "isManualUploadExhausted",
2429
+ target: "#idCapture.finished"
2430
+ }, { target: "#idCapture.processing" }],
2431
+ onError: {
2432
+ target: "#idCapture.error",
2433
+ actions: assign({ error: ({ event }) => String(event.error) })
2314
2434
  }
2315
2435
  },
2316
- states: {
2317
- selecting: { on: {
2318
- MANUAL_UPLOAD_FILE_SELECTED: [
2319
- {
2320
- guard: "isSelectedFileTooLarge",
2321
- actions: ["setManualUploadFileTooLargeError"]
2322
- },
2323
- {
2324
- guard: "isFrontFileSelection",
2325
- target: "uploadingFront",
2326
- actions: ["storeSelectedFile"]
2327
- },
2328
- {
2329
- guard: "isBackFileSelection",
2330
- target: "uploadingBack",
2331
- actions: ["storeSelectedFile"]
2332
- },
2333
- {
2334
- guard: "isPassportFileSelection",
2335
- target: "uploadingPassport",
2336
- actions: ["storeSelectedFile"]
2337
- }
2338
- ],
2339
- MANUAL_UPLOAD_CONTINUE: [{
2340
- guard: "canContinueFromIdTab",
2341
- target: "#idCapture.processing"
2342
- }, {
2343
- guard: "canContinueFromPassportTab",
2344
- target: "#idCapture.processing"
2345
- }]
2346
- } },
2347
- uploadingFront: { invoke: {
2348
- id: "uploadManualFile",
2349
- src: "uploadManualFile",
2350
- input: ({ context }) => ({
2351
- side: "front",
2352
- file: context.manualUpload.frontFile,
2353
- retry: context.manualUpload.retriesLeft < MANUAL_UPLOAD_MAX_RETRIES,
2354
- onlyFront: context.config.onlyFront ?? false,
2355
- isSecondId: context.config.isSecondId ?? false
2356
- }),
2357
- onDone: [{
2358
- guard: "manualUploadResponseHasError",
2359
- target: "checkRetries",
2360
- actions: ["decrementManualUploadRetries", "setManualUploadErrorFromResponse"]
2361
- }, {
2362
- target: "selecting",
2363
- actions: [
2364
- "markFrontUploaded",
2365
- "recordSkipBackFromResponse",
2366
- "clearManualUploadError"
2367
- ]
2368
- }],
2369
- onError: {
2370
- target: "checkRetries",
2371
- actions: ["decrementManualUploadRetries", "setManualUploadGenericError"]
2372
- }
2373
- } },
2374
- uploadingBack: { invoke: {
2375
- id: "uploadManualFile",
2376
- src: "uploadManualFile",
2377
- input: ({ context }) => ({
2378
- side: "back",
2379
- file: context.manualUpload.backFile,
2380
- retry: context.manualUpload.retriesLeft < MANUAL_UPLOAD_MAX_RETRIES,
2381
- onlyFront: false,
2382
- isSecondId: context.config.isSecondId ?? false
2383
- }),
2384
- onDone: [{
2385
- guard: "manualUploadResponseHasError",
2386
- target: "checkRetries",
2387
- actions: ["decrementManualUploadRetries", "setManualUploadErrorFromResponse"]
2388
- }, {
2389
- target: "selecting",
2390
- actions: ["markBackUploaded", "clearManualUploadError"]
2391
- }],
2392
- onError: {
2393
- target: "checkRetries",
2394
- actions: ["decrementManualUploadRetries", "setManualUploadGenericError"]
2395
- }
2396
- } },
2397
- uploadingPassport: { invoke: {
2398
- id: "uploadManualFile",
2399
- src: "uploadManualFile",
2400
- input: ({ context }) => ({
2401
- side: "passport",
2402
- file: context.manualUpload.passportFile,
2403
- retry: context.manualUpload.retriesLeft < MANUAL_UPLOAD_MAX_RETRIES,
2404
- onlyFront: false,
2405
- isSecondId: context.config.isSecondId ?? false
2406
- }),
2407
- onDone: [{
2408
- guard: "manualUploadResponseHasError",
2409
- target: "checkRetries",
2410
- actions: ["decrementManualUploadRetries", "setManualUploadErrorFromResponse"]
2411
- }, {
2412
- target: "selecting",
2413
- actions: ["markPassportUploaded", "clearManualUploadError"]
2414
- }],
2415
- onError: {
2416
- target: "checkRetries",
2417
- actions: ["decrementManualUploadRetries", "setManualUploadGenericError"]
2418
- }
2419
- } },
2420
- checkRetries: { always: [{
2421
- guard: "manualUploadRetriesExhausted",
2422
- target: "retriesExhausted"
2423
- }, { target: "selecting" }] },
2424
- retriesExhausted: { after: { [MANUAL_UPLOAD_EXHAUSTION_FORWARD_MS]: { target: "#idCapture.finished" } } }
2436
+ on: {
2437
+ QUIT: { target: "closed" },
2438
+ MANUAL_UPLOAD_TAB_CHANGED: { actions: sendTo("manualIdUpload", ({ event }) => event) },
2439
+ MANUAL_UPLOAD_FILE_SELECTED: { actions: sendTo("manualIdUpload", ({ event }) => event) },
2440
+ MANUAL_UPLOAD_CONTINUE: { actions: sendTo("manualIdUpload", ({ event }) => event) },
2441
+ MANUAL_UPLOAD_RESET: { actions: sendTo("manualIdUpload", ({ event }) => event) }
2425
2442
  }
2426
2443
  },
2427
2444
  digitalIdUpload: { on: { QUIT: { target: "closed" } } }