@ekyc_qoobiss/qbs-ect-cmp 3.2.1 → 3.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/cjs/agreement-check_18.cjs.entry.js +379 -267
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/qbs-ect-cmp.cjs.js +1 -1
  4. package/dist/collection/components/base-component.js +48 -0
  5. package/dist/collection/components/common/camera-error/camera-error.js +9 -36
  6. package/dist/collection/components/common/id-back-capture/id-back-capture.js +2 -27
  7. package/dist/collection/components/common/id-capture/id-capture.js +2 -27
  8. package/dist/collection/components/common/selfie-capture/selfie-capture.js +4 -28
  9. package/dist/collection/components/controls/camera/camera.js +3 -23
  10. package/dist/collection/components/flow/agreement-info/agreement-info.js +6 -9
  11. package/dist/collection/components/flow/end-redirect/end-redirect.js +4 -9
  12. package/dist/collection/components/flow/id-double-side/id-double-side.js +31 -51
  13. package/dist/collection/components/flow/id-single-side/id-single-side.js +14 -42
  14. package/dist/collection/components/flow/landing-validation/landing-validation.js +19 -40
  15. package/dist/collection/components/flow/mobile-redirect/mobile-redirect.js +7 -10
  16. package/dist/collection/components/flow/sms-code-validation/sms-code-validation.js +12 -15
  17. package/dist/collection/components/flow/user-liveness/user-liveness.js +29 -49
  18. package/dist/collection/components/identification-component/identification-component.js +14 -15
  19. package/dist/collection/helpers/ApiCall.js +3 -3
  20. package/dist/collection/helpers/Cameras.js +3 -2
  21. package/dist/collection/helpers/DeviceDetection.js +83 -0
  22. package/dist/collection/helpers/Events.js +9 -0
  23. package/dist/collection/helpers/Stream.js +9 -8
  24. package/dist/collection/helpers/index.js +0 -33
  25. package/dist/collection/helpers/store.js +2 -0
  26. package/dist/collection/models/FlowSteps.js +19 -13
  27. package/dist/collection/models/IDevice.js +22 -1
  28. package/dist/collection/models/IEctStore.js +1 -0
  29. package/dist/esm/agreement-check_18.entry.js +379 -267
  30. package/dist/esm/loader.js +1 -1
  31. package/dist/esm/qbs-ect-cmp.js +1 -1
  32. package/dist/qbs-ect-cmp/{p-92eaaff9.entry.js → p-f242dbd4.entry.js} +2 -2
  33. package/dist/qbs-ect-cmp/qbs-ect-cmp.esm.js +1 -1
  34. package/dist/types/components/base-component.d.ts +14 -0
  35. package/dist/types/components/common/camera-error/camera-error.d.ts +1 -3
  36. package/dist/types/components/common/id-back-capture/id-back-capture.d.ts +0 -2
  37. package/dist/types/components/common/id-capture/id-capture.d.ts +0 -2
  38. package/dist/types/components/common/selfie-capture/selfie-capture.d.ts +0 -2
  39. package/dist/types/components/controls/camera/camera.d.ts +0 -2
  40. package/dist/types/components/flow/agreement-info/agreement-info.d.ts +3 -3
  41. package/dist/types/components/flow/end-redirect/end-redirect.d.ts +1 -1
  42. package/dist/types/components/flow/id-double-side/id-double-side.d.ts +4 -5
  43. package/dist/types/components/flow/id-single-side/id-single-side.d.ts +3 -5
  44. package/dist/types/components/flow/landing-validation/landing-validation.d.ts +2 -3
  45. package/dist/types/components/flow/mobile-redirect/mobile-redirect.d.ts +1 -1
  46. package/dist/types/components/flow/sms-code-validation/sms-code-validation.d.ts +2 -2
  47. package/dist/types/components/flow/user-liveness/user-liveness.d.ts +3 -4
  48. package/dist/types/components/identification-component/identification-component.d.ts +1 -2
  49. package/dist/types/components.d.ts +0 -19
  50. package/dist/types/helpers/ApiCall.d.ts +4 -4
  51. package/dist/types/helpers/Cameras.d.ts +4 -4
  52. package/dist/types/helpers/DeviceDetection.d.ts +18 -0
  53. package/dist/types/helpers/Events.d.ts +2 -0
  54. package/dist/types/helpers/Stream.d.ts +1 -3
  55. package/dist/types/helpers/index.d.ts +0 -2
  56. package/dist/types/helpers/store.d.ts +2 -17
  57. package/dist/types/models/FlowSteps.d.ts +18 -13
  58. package/dist/types/models/IDevice.d.ts +32 -9
  59. package/dist/types/models/IEctStore.d.ts +20 -0
  60. package/package.json +1 -1
@@ -374,6 +374,8 @@ const { state, onChange } = createStore({
374
374
  phoneValidation: true,
375
375
  phoneNumber: '',
376
376
  apiBaseUrl: 'https://apiro.id-kyc.com',
377
+ device: null,
378
+ recordingRetryCount: 0,
377
379
  });
378
380
  onChange('environment', value => {
379
381
  state.debug = value == 'QA';
@@ -402,20 +404,26 @@ onChange('phoneValidation', value => {
402
404
 
403
405
  var FlowSteps;
404
406
  (function (FlowSteps) {
405
- FlowSteps[FlowSteps["MobileRedirect"] = 0] = "MobileRedirect";
406
- FlowSteps[FlowSteps["Landing"] = 1] = "Landing";
407
- FlowSteps[FlowSteps["Agreements"] = 2] = "Agreements";
408
- FlowSteps[FlowSteps["OtpSend"] = 3] = "OtpSend";
409
- FlowSteps[FlowSteps["OtpCheck"] = 4] = "OtpCheck";
410
- FlowSteps[FlowSteps["CiFrontHowTo"] = 5] = "CiFrontHowTo";
411
- FlowSteps[FlowSteps["CiFront"] = 6] = "CiFront";
412
- FlowSteps[FlowSteps["CiBackHowTo"] = 7] = "CiBackHowTo";
413
- FlowSteps[FlowSteps["CiBack"] = 8] = "CiBack";
414
- FlowSteps[FlowSteps["SelfieHowTo"] = 9] = "SelfieHowTo";
415
- FlowSteps[FlowSteps["Selfie"] = 10] = "Selfie";
416
- FlowSteps[FlowSteps["End"] = 11] = "End";
417
- FlowSteps[FlowSteps["CameraError"] = 12] = "CameraError";
418
- })(FlowSteps || (FlowSteps = {}));
407
+ FlowSteps[FlowSteps["MobileRedirect"] = 'mobile-redirect'] = "MobileRedirect";
408
+ FlowSteps[FlowSteps["Landing"] = 'landing'] = "Landing";
409
+ FlowSteps[FlowSteps["Agreements"] = 'agreements'] = "Agreements";
410
+ FlowSteps[FlowSteps["OtpSend"] = 'otp-send'] = "OtpSend";
411
+ FlowSteps[FlowSteps["OtpCheck"] = 'otp-check'] = "OtpCheck";
412
+ FlowSteps[FlowSteps["CiFrontHowTo"] = 'ci-front-how-to'] = "CiFrontHowTo";
413
+ FlowSteps[FlowSteps["CiFront"] = 'ci-front'] = "CiFront";
414
+ FlowSteps[FlowSteps["CiBackHowTo"] = 'ci-back-how-to'] = "CiBackHowTo";
415
+ FlowSteps[FlowSteps["CiBack"] = 'ci-back'] = "CiBack";
416
+ FlowSteps[FlowSteps["SelfieHowTo"] = 'selfie-how-to'] = "SelfieHowTo";
417
+ FlowSteps[FlowSteps["Selfie"] = 'selfie'] = "Selfie";
418
+ FlowSteps[FlowSteps["End"] = 'end'] = "End";
419
+ FlowSteps[FlowSteps["CameraError"] = 'camera-error'] = "CameraError";
420
+ })(FlowSteps || (FlowSteps = {}));
421
+ var FlowMoments;
422
+ (function (FlowMoments) {
423
+ FlowMoments[FlowMoments["Initialized"] = 'initialized'] = "Initialized";
424
+ FlowMoments[FlowMoments["Finalized"] = 'finalized'] = "Finalized";
425
+ FlowMoments[FlowMoments["None"] = 'none'] = "None";
426
+ })(FlowMoments || (FlowMoments = {}));
419
427
 
420
428
  class ApiCall {
421
429
  constructor() {
@@ -537,8 +545,8 @@ class ApiCall {
537
545
  }
538
546
  catch (_a) { }
539
547
  }
540
- async AddStep(step) {
541
- let data = { requestId: state.requestId, redirectId: state.redirectId, step: FlowSteps[step] };
548
+ async AddStep(step, moment) {
549
+ let data = { requestId: state.requestId, redirectId: state.redirectId, step: FlowSteps[step], moment: FlowMoments[moment] };
542
550
  let result = await this.post(this.urls.AddStep, JSON.stringify(data));
543
551
  return result.saved;
544
552
  }
@@ -580,6 +588,215 @@ const AgreementCheck = class {
580
588
  };
581
589
  AgreementCheck.style = agreementCheckCss;
582
590
 
591
+ var MobileOS;
592
+ (function (MobileOS) {
593
+ MobileOS["Android"] = "android";
594
+ MobileOS["iOS"] = "ios";
595
+ MobileOS["Unknown"] = "unknown";
596
+ MobileOS["WindowsPhone"] = "Windows Phone";
597
+ })(MobileOS || (MobileOS = {}));
598
+ var DesktopOS;
599
+ (function (DesktopOS) {
600
+ DesktopOS["Linux"] = "linux";
601
+ DesktopOS["MacOS"] = "mac_os";
602
+ DesktopOS["Unix"] = "unix";
603
+ DesktopOS["Unknown"] = "unknown";
604
+ DesktopOS["Windows"] = "windows";
605
+ })(DesktopOS || (DesktopOS = {}));
606
+ var Browser;
607
+ (function (Browser) {
608
+ Browser["Chrome"] = "chrome";
609
+ Browser["Firefox"] = "firefox";
610
+ Browser["Safari"] = "safari";
611
+ Browser["Unknown"] = "unknown";
612
+ })(Browser || (Browser = {}));
613
+
614
+ class DeviceDetection {
615
+ constructor() {
616
+ var _a, _b, _c, _d;
617
+ this.supportedScreenOrientation = (_b = (_a = ((screen === null || screen === void 0 ? void 0 : screen.orientation) || {}).type) !== null && _a !== void 0 ? _a : screen.mozOrientation) !== null && _b !== void 0 ? _b : screen.msOrientation;
618
+ this.safariScreenOrientation = !(screen === null || screen === void 0 ? void 0 : screen.orientation) && matchMedia('(orientation: portrait)').matches ? 'portrait-primary' : 'landscape-primary';
619
+ this.initialScreenOrientation = (_d = (_c = this.supportedScreenOrientation) !== null && _c !== void 0 ? _c : this.safariScreenOrientation) !== null && _d !== void 0 ? _d : 'portrait-primary';
620
+ this.userAgent = navigator.userAgent || navigator.vendor || window.opera || undefined;
621
+ this.isMobile = this.isMobileDevice();
622
+ this.isTablet = this.isTabletDevice();
623
+ this.isDesktop = !this.isMobile && !this.isTablet;
624
+ }
625
+ // Device typology
626
+ isMobileDevice() {
627
+ const regexs = [/(Android)(.+)(Mobile)/i, /BlackBerry/i, /iPhone|iPod/i, /Opera Mini/i, /IEMobile/i];
628
+ return regexs.some(b => this.userAgent.match(b));
629
+ }
630
+ isTabletDevice() {
631
+ const regex = /(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/;
632
+ return regex.test(this.userAgent.toLowerCase());
633
+ }
634
+ // Device Operating System
635
+ getMobileOS() {
636
+ if (this.isMobileDevice()) {
637
+ if (/windows phone/i.test(this.userAgent))
638
+ return MobileOS.WindowsPhone;
639
+ else if (/android/i.test(this.userAgent))
640
+ return MobileOS.Android;
641
+ else if (/iPad|iPhone|iPod/.test(this.userAgent) && !window.MSStream)
642
+ return MobileOS.iOS;
643
+ return MobileOS.Unknown;
644
+ }
645
+ else
646
+ return undefined;
647
+ }
648
+ getDesktopOS() {
649
+ if (this.isDesktop) {
650
+ if (this.userAgent.indexOf('Win') !== -1)
651
+ return DesktopOS.Windows;
652
+ else if (this.userAgent.indexOf('Mac') !== -1)
653
+ return DesktopOS.MacOS;
654
+ else if (this.userAgent.indexOf('X11') !== -1)
655
+ return DesktopOS.Unix;
656
+ else if (this.userAgent.indexOf('Linux') !== -1)
657
+ return DesktopOS.Linux;
658
+ return DesktopOS.Unknown;
659
+ }
660
+ else
661
+ return undefined;
662
+ }
663
+ getDeviceOS() {
664
+ var _a;
665
+ return (_a = this.getMobileOS()) !== null && _a !== void 0 ? _a : this.getDesktopOS();
666
+ }
667
+ getBrowser() {
668
+ var isChrome = /chrome/i.test(this.userAgent);
669
+ if (isChrome)
670
+ return Browser.Chrome;
671
+ if (/firefox/i.test(navigator.userAgent))
672
+ return Browser.Firefox;
673
+ else if (!isChrome && /safari/i.test(navigator.userAgent))
674
+ return Browser.Safari;
675
+ else
676
+ return Browser.Unknown;
677
+ }
678
+ getDevice() {
679
+ var device = {
680
+ isDesktop: this.isDesktop,
681
+ desktopOS: this.getDesktopOS(),
682
+ isWindowsDesktop: this.getDeviceOS() === DesktopOS.Windows,
683
+ isLinuxOrUnixDesktop: this.getDeviceOS() === DesktopOS.Linux || this.getDeviceOS() === DesktopOS.Unix,
684
+ isMobile: this.isMobile,
685
+ mobileOS: this.getMobileOS(),
686
+ isAndroidDevice: this.getDeviceOS() === MobileOS.Android,
687
+ isAppleDevice: this.getDeviceOS() === MobileOS.iOS || this.getDeviceOS() === DesktopOS.MacOS,
688
+ isUnknownMobileDevice: this.getDeviceOS() === MobileOS.Unknown,
689
+ browser: this.getBrowser(),
690
+ isTablet: this.isTablet,
691
+ initialScreenOrientation: this.initialScreenOrientation,
692
+ };
693
+ return device;
694
+ }
695
+ }
696
+
697
+ class Events {
698
+ static init(element) {
699
+ this.callingModule = element;
700
+ }
701
+ static flowEvent(step, moment) {
702
+ const eventName = `ect-${step.toString()}-${moment.toString()}-event`;
703
+ this.callingModule.dispatchEvent(new CustomEvent(eventName, {
704
+ detail: {},
705
+ bubbles: true,
706
+ cancelable: true,
707
+ composed: true,
708
+ }));
709
+ }
710
+ static flowStarted() {
711
+ this.callingModule.dispatchEvent(new CustomEvent('ect-started', {
712
+ detail: {},
713
+ bubbles: true,
714
+ cancelable: true,
715
+ composed: true,
716
+ }));
717
+ }
718
+ static flowAborted() {
719
+ sessionStorage.clear();
720
+ this.callingModule.dispatchEvent(new CustomEvent('ect-aborted', {
721
+ detail: {},
722
+ bubbles: true,
723
+ cancelable: true,
724
+ composed: true,
725
+ }));
726
+ }
727
+ static flowCompleted() {
728
+ sessionStorage.clear();
729
+ this.callingModule.dispatchEvent(new CustomEvent('ect-completed', {
730
+ detail: {},
731
+ bubbles: true,
732
+ cancelable: true,
733
+ composed: true,
734
+ }));
735
+ }
736
+ static flowError(error) {
737
+ sessionStorage.clear();
738
+ this.callingModule.dispatchEvent(new CustomEvent('ect-error', {
739
+ detail: { error },
740
+ bubbles: true,
741
+ cancelable: true,
742
+ composed: true,
743
+ }));
744
+ }
745
+ static tokenExpired() {
746
+ sessionStorage.clear();
747
+ this.callingModule.dispatchEvent(new CustomEvent('ect-session-expired', {
748
+ detail: {},
749
+ bubbles: true,
750
+ cancelable: true,
751
+ composed: true,
752
+ }));
753
+ }
754
+ }
755
+
756
+ class BaseComponent {
757
+ constructor(step) {
758
+ this.apiErrorEvent = null;
759
+ this.processError = null;
760
+ this.apiCall = new ApiCall();
761
+ if (step)
762
+ this.flowStep = step;
763
+ if (!state.device) {
764
+ state.device = new DeviceDetection().getDevice();
765
+ }
766
+ Events.init(window);
767
+ }
768
+ setEventEmitter(event) {
769
+ this.apiErrorEvent = event;
770
+ }
771
+ setErrorCallback(callback) {
772
+ this.processError = callback;
773
+ }
774
+ async initialize() {
775
+ Events.flowEvent(this.flowStep, FlowMoments.Initialized);
776
+ try {
777
+ await this.apiCall.AddStep(this.flowStep, FlowMoments.Initialized);
778
+ }
779
+ catch (e) {
780
+ if (this.apiErrorEvent)
781
+ this.apiErrorEvent.emit(e);
782
+ else
783
+ this.processError(e, FlowMoments.Initialized);
784
+ }
785
+ }
786
+ async finalize() {
787
+ Events.flowEvent(this.flowStep, FlowMoments.Finalized);
788
+ try {
789
+ await this.apiCall.AddStep(this.flowStep, FlowMoments.Finalized);
790
+ }
791
+ catch (e) {
792
+ if (this.apiErrorEvent)
793
+ this.apiErrorEvent.emit(e);
794
+ else
795
+ this.processError(e, FlowMoments.Initialized);
796
+ }
797
+ }
798
+ }
799
+
583
800
  const agreementInfoCss = "";
584
801
 
585
802
  const AgreementInfo = class {
@@ -590,24 +807,21 @@ const AgreementInfo = class {
590
807
  this.termsChecked = undefined;
591
808
  this.openAgreements = undefined;
592
809
  this.openTerms = undefined;
810
+ this.baseComponent = new BaseComponent(FlowSteps.Agreements);
811
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
593
812
  this.agreementsChecked = false;
594
813
  this.termsChecked = false;
595
- this.apiCall = new ApiCall();
596
814
  }
597
815
  async componentDidLoad() {
598
- try {
599
- await this.apiCall.AddStep(FlowSteps.Agreements);
600
- }
601
- catch (e) {
602
- this.apiErrorEvent.emit(e);
603
- }
816
+ await this.baseComponent.initialize();
604
817
  }
605
818
  componentWillLoad() {
606
819
  this.openAgreements = false;
607
820
  this.openTerms = false;
608
821
  }
609
- buttonClick() {
822
+ async buttonClick() {
610
823
  if (this.agreementsChecked && this.termsChecked) {
824
+ await this.baseComponent.finalize();
611
825
  state.flowStatus = FlowStatus.PHONE;
612
826
  }
613
827
  }
@@ -4905,7 +5119,7 @@ class Stream {
4905
5119
  setVerificationFinished(fun) {
4906
5120
  this.verificationFinished = fun;
4907
5121
  }
4908
- constructor(device, _modelPath) {
5122
+ constructor(_modelPath) {
4909
5123
  this.streamPaused = false;
4910
5124
  this.recordedChunks = [];
4911
5125
  this.videoSize = { width: 0, height: 0 };
@@ -4916,13 +5130,12 @@ class Stream {
4916
5130
  // this.dropMask();
4917
5131
  // if (this.faceDetection) Detector.getInstance().stopDetector();
4918
5132
  };
4919
- this.device = device;
4920
- this.idML5Detector = IDML5Detector.getInstance(this, device.isMobile);
4921
- this.faceML5Detector = FaceML5Detector.getInstance(this, device.isMobile);
5133
+ this.idML5Detector = IDML5Detector.getInstance(this, state.device.isMobile);
5134
+ this.faceML5Detector = FaceML5Detector.getInstance(this, state.device.isMobile);
4922
5135
  }
4923
- static getInstance(device, modelPath) {
5136
+ static getInstance(modelPath) {
4924
5137
  if (!Stream.instance) {
4925
- Stream.instance = new Stream(device, modelPath);
5138
+ Stream.instance = new Stream(modelPath);
4926
5139
  }
4927
5140
  return Stream.instance;
4928
5141
  }
@@ -4983,7 +5196,7 @@ class Stream {
4983
5196
  recordStream() {
4984
5197
  var options = { mimeType: Stream.webmMimeType.mime, videoBitsPerSecond: 1500000 };
4985
5198
  if (!MediaRecorder.isTypeSupported(options.mimeType)) {
4986
- if (this.device.isIos || this.device.isSafari)
5199
+ if (state.device.mobileOS == MobileOS.iOS || state.device.browser == Browser.Safari)
4987
5200
  options.mimeType = Stream.mp4MimeType.mime;
4988
5201
  }
4989
5202
  this.recordedChunks = [];
@@ -5038,7 +5251,7 @@ class Stream {
5038
5251
  const context = canvas.getContext('2d');
5039
5252
  context.drawImage(this.videoElement, 0, 0, canvas.width, canvas.height);
5040
5253
  canvas.toBlob((frame) => {
5041
- if (frame.type === ImageFormat.JPEG && !this.device.isIos) {
5254
+ if (frame.type === ImageFormat.JPEG && !state.device.isAppleDevice) {
5042
5255
  try {
5043
5256
  addExifInImg(frame, this.stream.getTracks()[0], this.videoSize).then(updatedFrame => resolve(updatedFrame));
5044
5257
  }
@@ -5131,7 +5344,6 @@ const Camera = class {
5131
5344
  this.verificationFinished.emit();
5132
5345
  };
5133
5346
  this.modelPath = undefined;
5134
- this.device = undefined;
5135
5347
  this.probabilityThreshold = undefined;
5136
5348
  this.captureMode = undefined;
5137
5349
  }
@@ -5141,7 +5353,7 @@ const Camera = class {
5141
5353
  render() {
5142
5354
  let cameraVideoClass = 'cameraVideo';
5143
5355
  let cameraCanvasClass = 'cameraCanvas';
5144
- if (this.device.isWin) {
5356
+ if (state.device.isDesktop) {
5145
5357
  cameraVideoClass = 'cameraVideoSelfieDesk';
5146
5358
  cameraCanvasClass = 'cameraCanvasSelfieDesk';
5147
5359
  }
@@ -5153,7 +5365,7 @@ const Camera = class {
5153
5365
  }
5154
5366
  startStream() {
5155
5367
  if (!Stream.instance)
5156
- Stream.getInstance(this.device, this.modelPath);
5368
+ Stream.getInstance(this.modelPath);
5157
5369
  const stream = Stream.getInstance();
5158
5370
  stream.updateHtmlElements(this.cameraVideo, this.cameraCanvas, this.component);
5159
5371
  if (this.captureMode == 'selfie') {
@@ -5185,12 +5397,12 @@ const CameraError = class {
5185
5397
  constructor(hostRef) {
5186
5398
  registerInstance(this, hostRef);
5187
5399
  this.apiErrorEvent = createEvent(this, "apiError", 7);
5188
- this.device = undefined;
5189
5400
  this.title = undefined;
5190
5401
  this.description = undefined;
5191
5402
  this.buttonDisabled = undefined;
5192
5403
  this.demoVideo = undefined;
5193
- this.apiCall = new ApiCall();
5404
+ this.baseComponent = new BaseComponent(FlowSteps.CameraError);
5405
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
5194
5406
  }
5195
5407
  async componentWillLoad() {
5196
5408
  this.buttonDisabled = false;
@@ -5199,7 +5411,8 @@ const CameraError = class {
5199
5411
  this.buttonText = CameraErrorValues.Button;
5200
5412
  }
5201
5413
  async componentDidLoad() {
5202
- if (!this.device.isIos) {
5414
+ await this.baseComponent.initialize();
5415
+ if (state.device.mobileOS != MobileOS.iOS) {
5203
5416
  this.demoVideo.src = CameraErrorValues.HowToLink;
5204
5417
  this.demoVideo.loop = true;
5205
5418
  this.demoVideo.play();
@@ -5211,16 +5424,11 @@ const CameraError = class {
5211
5424
  state.flowStatus = FlowStatus.LANDING;
5212
5425
  }
5213
5426
  }
5214
- try {
5215
- await this.apiCall.AddStep(FlowSteps.CameraError);
5216
- }
5217
- catch (e) {
5218
- this.apiErrorEvent.emit(e);
5219
- }
5220
5427
  }
5221
5428
  async buttonClick() {
5222
5429
  this.buttonDisabled = true;
5223
- if (this.device.isIos) {
5430
+ await this.baseComponent.finalize();
5431
+ if (state.device.mobileOS == MobileOS.iOS) {
5224
5432
  sessionStorage.setItem(SessionKeys.RefreshDoneKey, 'true');
5225
5433
  window.location.reload();
5226
5434
  }
@@ -5229,7 +5437,7 @@ const CameraError = class {
5229
5437
  }
5230
5438
  }
5231
5439
  render() {
5232
- return (h("div", { class: "container" }, h("div", { class: "row" }, h("h1", { class: "color-red" }, this.title), h("div", null, h("p", { class: "color-red font-weight-bold font-size-25 mt-5" }, this.description)), h("div", { hidden: this.device.isIos }, h("video", { id: "howtoPermissions", class: "video-demo", playsinline: true, ref: el => (this.demoVideo = el) }, h("source", { type: "video/mp4" }))), h("div", { class: "pos-relative show-bottom" }, h("div", { class: "btn-buletin" }, h("button", { class: "main-button", type: "button", disabled: this.buttonDisabled, onClick: () => this.buttonClick() }, this.buttonText), h("p", { class: "main-text font-size-18 text-right mb-0" }, CameraErrorValues.FooterText))))));
5440
+ return (h("div", { class: "container" }, h("div", { class: "row" }, h("h1", { class: "color-red" }, this.title), h("div", null, h("p", { class: "color-red font-weight-bold font-size-25 mt-5" }, this.description)), h("div", { hidden: state.device.mobileOS == MobileOS.iOS }, h("video", { id: "howtoPermissions", class: "video-demo", playsinline: true, ref: el => (this.demoVideo = el) }, h("source", { type: "video/mp4" }))), h("div", { class: "pos-relative show-bottom" }, h("div", { class: "btn-buletin" }, h("button", { class: "main-button", type: "button", disabled: this.buttonDisabled, onClick: () => this.buttonClick() }, this.buttonText), h("p", { class: "main-text font-size-18 text-right mb-0" }, CameraErrorValues.FooterText))))));
5233
5441
  }
5234
5442
  };
5235
5443
  CameraError.style = cameraErrorCss;
@@ -5279,74 +5487,19 @@ CaptureError.style = captureErrorCss;
5279
5487
 
5280
5488
  const completeSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODMiIGhlaWdodD0iODQiIHZpZXdCb3g9IjAgMCA4MyA4NCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxwYXRoIGQ9Ik00MS41IDgzLjcwNjJDMzAuNDE0NyA4My43MDYyIDE5Ljk5MjkgNzkuMzgwNCAxMi4xNTQ2IDcxLjUyNUM0LjMxNjQxIDYzLjY2OTcgMCA1My4yMjUxIDAgNDIuMTE1NkMwIDMxLjAwNjEgNC4zMTY0MSAyMC41NjE1IDEyLjE1NDYgMTIuNzA2MUMxOS45OTI5IDQuODUwNzUgMzAuNDE0NyAwLjUyNDkwMiA0MS41IDAuNTI0OTAyQzUyLjU4NTMgMC41MjQ5MDIgNjMuMDA3MSA0Ljg1MDc1IDcwLjg0NTMgMTIuNzA2MUM3OC42ODM2IDIwLjU2MTUgODMgMzEuMDA2MSA4MyA0Mi4xMTU2QzgzIDUzLjIyNTEgNzguNjgzNiA2My42Njk3IDcwLjg0NTMgNzEuNTI1QzYzLjAwNzEgNzkuMzgwNCA1Mi41ODUzIDgzLjcwNjIgNDEuNSA4My43MDYyWk00MS41IDQuNzYzMTNDMjAuOTQ4MyA0Ljc2MzEzIDQuMjI4OTkgMjEuNTE4OSA0LjIyODk5IDQyLjExNTZDNC4yMjg5OSA2Mi43MTIyIDIwLjk0ODMgNzkuNDY4IDQxLjUgNzkuNDY4QzYyLjA1MTcgNzkuNDY4IDc4Ljc3MSA2Mi43MTIyIDc4Ljc3MSA0Mi4xMTU2Qzc4Ljc3MSAyMS41MTg5IDYyLjA1MTcgNC43NjMxMyA0MS41IDQuNzYzMTNaIiBmaWxsPSIjNURDMUFDIi8+DQo8cGF0aCBkPSJNMzcuNDY3NiA2Mi42NjJIMzcuNDYzQzM0Ljk2MDUgNjIuNjYyIDMyLjYwOTUgNjEuNjgyNiAzMC44NDA4IDU5LjkwODRMMTguOTQzOCA0Ny45NjY2QzE1LjMwMDIgNDQuMzA4OCAxNS4zMDE3IDM4LjM1NzQgMTguOTUgMzQuNzAyOEMyMC43MjM0IDMyLjkyNTUgMjMuMDc0NCAzMS45NTA4IDI1LjU3NTMgMzEuOTUwOEMyOC4wNzYxIDMxLjk1MDggMzAuNDI3MSAzMi45MjcxIDMyLjE5NTggMzQuNjk5NkwzNy40ODE3IDM5Ljk5N0w1MC44MTAzIDI2LjYzOTNDNTQuNDYwMSAyMi45ODE1IDYwLjQgMjIuOTgxNSA2NC4wNTE0IDI2LjYzOTNDNjcuNzAxMyAzMC4yOTcxIDY3LjcwMTMgMzYuMjUwMSA2NC4wNTE0IDM5LjkwOTRMNDQuMDg4MiA1OS45MTYzQzQyLjMxOTUgNjEuNjg4OCAzOS45Njg1IDYyLjY2NTEgMzcuNDY3NiA2Mi42NjUxVjYyLjY2MlpNMjUuNTc1MyAzNi4xODlDMjQuMjA0NiAzNi4xODkgMjIuOTE1MiAzNi43MjQxIDIxLjk0NTcgMzcuNjk1N0MxOS45NDEzIDM5LjcwNDUgMTkuOTQxMyA0Mi45NjQ5IDIxLjkzNzkgNDQuOTcwNkwzMy44MzUgNTYuOTEyNEMzNC44MDQ0IDU3Ljg4NTUgMzYuMDkzOSA1OC40MjIyIDM3LjQ2NDUgNTguNDIyMkgzNy40NjYxQzM4LjgzNjcgNTguNDIyMiA0MC4xMjYyIDU3Ljg4NzEgNDEuMDk1NiA1Ni45MTU1TDYxLjA1ODggMzYuOTA4N0M2My4wNjAxIDM0LjkwMyA2My4wNjAxIDMxLjYzOTUgNjEuMDU4OCAyOS42MzM4QzU5LjA1NzUgMjcuNjI4MSA1NS44MDExIDI3LjYyODEgNTMuNzk5NyAyOS42MzM4TDUyLjMwNDIgMjguMTM1TDUzLjc5OTcgMjkuNjMzOEwzOC45NzU3IDQ0LjQ5MDNDMzguMTQ5OCA0NS4zMTc5IDM2LjgxMDQgNDUuMzE3OSAzNS45ODQ2IDQ0LjQ5MDNMMjkuMjAzMiAzNy42OTQxQzI4LjIzMzggMzYuNzIyNSAyNi45NDQzIDM2LjE4NzUgMjUuNTczNyAzNi4xODc1TDI1LjU3NTMgMzYuMTg5WiIgZmlsbD0iIzVEQzFBQyIvPg0KPC9zdmc+DQo=';
5281
5489
 
5282
- class Events {
5283
- static init(element) {
5284
- this.callingModule = element;
5285
- }
5286
- static flowStarted() {
5287
- this.callingModule.dispatchEvent(new CustomEvent('ect-started', {
5288
- detail: {},
5289
- bubbles: true,
5290
- cancelable: true,
5291
- composed: true,
5292
- }));
5293
- }
5294
- static flowAborted() {
5295
- sessionStorage.clear();
5296
- this.callingModule.dispatchEvent(new CustomEvent('ect-aborted', {
5297
- detail: {},
5298
- bubbles: true,
5299
- cancelable: true,
5300
- composed: true,
5301
- }));
5302
- }
5303
- static flowCompleted() {
5304
- sessionStorage.clear();
5305
- this.callingModule.dispatchEvent(new CustomEvent('ect-completed', {
5306
- detail: {},
5307
- bubbles: true,
5308
- cancelable: true,
5309
- composed: true,
5310
- }));
5311
- }
5312
- static flowError(error) {
5313
- sessionStorage.clear();
5314
- this.callingModule.dispatchEvent(new CustomEvent('ect-error', {
5315
- detail: { error },
5316
- bubbles: true,
5317
- cancelable: true,
5318
- composed: true,
5319
- }));
5320
- }
5321
- static tokenExpired() {
5322
- sessionStorage.clear();
5323
- this.callingModule.dispatchEvent(new CustomEvent('ect-session-expired', {
5324
- detail: {},
5325
- bubbles: true,
5326
- cancelable: true,
5327
- composed: true,
5328
- }));
5329
- }
5330
- }
5331
-
5332
5490
  const endRedirectCss = "h1{font-family:'Inter', sans-serif;font-style:normal;font-weight:900;font-size:4vh;line-height:4vh;letter-spacing:0.01em;color:#1f2024}p{font-family:'Inter', sans-serif;font-style:normal;font-weight:400;font-size:2vh;line-height:3vh;color:#1f2024;text-align:justify}.container{gap:10rem;text-align:center}.greet{color:rgb(73, 78, 79);visibility:hidden;animation-name:rise;animation-delay:1s;animation-fill-mode:forwards}@keyframes rise{0%{visibility:hidden}50%{visibility:visible}100%{visibility:visible}}.container-coin{background-color:transparent;perspective:1000px;rotate:120deg 0deg}.coin-flip{animation:flip 0.4s ease-in;animation-delay:0.5s;transform-style:preserve-3d;animation-fill-mode:forwards;visibility:hidden}.coin-scale{animation:show 0.4s ease-in;animation-delay:0.5s;transform-style:preserve-3d;animation-fill-mode:forwards}.coin{margin-top:10rem}@keyframes flip{0%{transform:rotateX(140deg);visibility:visible}25%{transform:rotateX(120deg);visibility:visible}50%{transform:rotateX(90deg);visibility:visible}75%{transform:rotateX(75deg);visibility:visible}100%{transform:rotateX(0deg);visibility:visible}}@keyframes show{0%{transform:scale(0)}25%{transform:scale(0.2)}40%{transform:scale(0.4)}50%{transform:scale(0.5)}60%{transform:scale(0.6)}70%{transform:scale(0.7)}100%{transform:scale(1)}}";
5333
5491
 
5334
5492
  const EndRedirect = class {
5335
5493
  constructor(hostRef) {
5336
5494
  registerInstance(this, hostRef);
5337
5495
  this.apiErrorEvent = createEvent(this, "apiError", 7);
5338
- this.apiCall = new ApiCall();
5496
+ this.baseComponent = new BaseComponent(FlowSteps.End);
5497
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
5339
5498
  }
5340
5499
  async componentDidLoad() {
5341
- Events.init(window);
5342
5500
  Events.flowCompleted();
5343
5501
  if (state.environment !== 'DEMO') {
5344
- try {
5345
- await this.apiCall.AddStep(FlowSteps.End);
5346
- }
5347
- catch (e) {
5348
- this.apiErrorEvent.emit(e);
5349
- }
5502
+ await this.baseComponent.initialize();
5350
5503
  }
5351
5504
  }
5352
5505
  render() {
@@ -5428,7 +5581,7 @@ class Cameras {
5428
5581
  const stream = await navigator.mediaDevices.getUserMedia(updatedConstraints);
5429
5582
  stream.getVideoTracks().forEach(track => {
5430
5583
  var _a, _b;
5431
- if (deviceInfo.isFirefox) {
5584
+ if (deviceInfo.browser === Browser.Firefox) {
5432
5585
  const settings = track.getSettings();
5433
5586
  let facingMode = settings.facingMode && settings.facingMode.length > 0 ? settings.facingMode[0] : '';
5434
5587
  facingMode = facingMode === 'e' ? 'environment' : facingMode;
@@ -5494,7 +5647,7 @@ class Cameras {
5494
5647
  exact: selectedDeviceId,
5495
5648
  };
5496
5649
  }
5497
- if (device.isWin) {
5650
+ if (device.isDesktop) {
5498
5651
  constraints.video.width = { ideal: 1280 };
5499
5652
  }
5500
5653
  else {
@@ -5550,7 +5703,6 @@ const IdBackCapture = class {
5550
5703
  //this.closeCamera();
5551
5704
  this.eventPhotoCapture.emit(photos);
5552
5705
  };
5553
- this.device = undefined;
5554
5706
  this.videoStarted = undefined;
5555
5707
  this.cameraSize = undefined;
5556
5708
  this.captureTaken = undefined;
@@ -5595,7 +5747,7 @@ const IdBackCapture = class {
5595
5747
  this.openCamera();
5596
5748
  }
5597
5749
  async openCamera() {
5598
- var constraints = this.cameras.GetConstraints(state.cameraId, this.device);
5750
+ var constraints = this.cameras.GetConstraints(state.cameraId, state.device);
5599
5751
  setTimeout(() => {
5600
5752
  navigator.mediaDevices
5601
5753
  .getUserMedia(constraints)
@@ -5648,7 +5800,7 @@ const IdBackCapture = class {
5648
5800
  let titleClass = this.verified ? 'color-black-2 text-center' : 'color-white text-center';
5649
5801
  //let videoClass = this.device.isMobile ? '' : 'video-demo';
5650
5802
  let bgDemo = this.verified ? 'container' : 'container bg-black';
5651
- return (h("div", { class: bgDemo }, h("div", { class: "container-video" }, h("div", { hidden: this.showDemo == false }, h("video", { id: "howtoBack", class: "video-demo", playsinline: true, ref: el => (this.demoVideo = el) }, h("source", { type: "video/mp4" }))), h("div", { hidden: this.showDemo }, h("div", { hidden: this.verified }, h("div", { class: "video-capture" }, h("div", { style: cameraStyle }, h("div", { style: cameraStyleInner }, h("camera-comp", { device: this.device, "capture-mode": "id" })))))), h("div", { class: "capture-title" }, h("h1", { class: titleClass }, this.titleMesage), h("p", { class: "main-text font-size-18 text-right mb-0" }, IdCaptureValues.FooterText)))));
5803
+ return (h("div", { class: bgDemo }, h("div", { class: "container-video" }, h("div", { hidden: this.showDemo == false }, h("video", { id: "howtoBack", class: "video-demo", playsinline: true, ref: el => (this.demoVideo = el) }, h("source", { type: "video/mp4" }))), h("div", { hidden: this.showDemo }, h("div", { hidden: this.verified }, h("div", { class: "video-capture" }, h("div", { style: cameraStyle }, h("div", { style: cameraStyleInner }, h("camera-comp", { "capture-mode": "id" })))))), h("div", { class: "capture-title" }, h("h1", { class: titleClass }, this.titleMesage), h("p", { class: "main-text font-size-18 text-right mb-0" }, IdCaptureValues.FooterText)))));
5652
5804
  }
5653
5805
  get component() { return getElement(this); }
5654
5806
  };
@@ -5665,7 +5817,6 @@ const IdCapture = class {
5665
5817
  //this.closeCamera();
5666
5818
  this.eventPhotoCapture.emit(photos);
5667
5819
  };
5668
- this.device = undefined;
5669
5820
  this.videoStarted = undefined;
5670
5821
  this.cameraSize = undefined;
5671
5822
  this.captureTaken = undefined;
@@ -5706,7 +5857,7 @@ const IdCapture = class {
5706
5857
  this.openCamera();
5707
5858
  }
5708
5859
  async openCamera() {
5709
- var constraints = this.cameras.GetConstraints(state.cameraId, this.device);
5860
+ var constraints = this.cameras.GetConstraints(state.cameraId, state.device);
5710
5861
  setTimeout(() => {
5711
5862
  navigator.mediaDevices
5712
5863
  .getUserMedia(constraints)
@@ -5764,7 +5915,7 @@ const IdCapture = class {
5764
5915
  let titleClass = this.verified ? 'color-black-2 text-center' : 'color-white text-center';
5765
5916
  //let videoClass = this.device.isMobile ? '' : 'video-demo';
5766
5917
  let bgDemo = this.verified ? 'container' : 'container bg-black';
5767
- return (h("div", { class: bgDemo }, h("div", { class: "container-video" }, h("div", { hidden: this.showDemo == false }, h("video", { id: "howtoFront", class: "video-demo", playsinline: true, ref: el => (this.demoVideo = el) }, h("source", { type: "video/mp4" }))), h("div", { hidden: this.showDemo }, h("div", { hidden: this.verified }, h("div", { class: "video-capture" }, h("div", { style: cameraStyle }, h("div", { style: cameraStyleInner }, h("camera-comp", { device: this.device, "capture-mode": "id" })))))), h("div", { class: "capture-title" }, h("h1", { class: titleClass }, this.titleMesage), h("p", { class: "main-text font-size-18 text-right mb-0" }, IdCaptureValues.FooterText)))));
5918
+ return (h("div", { class: bgDemo }, h("div", { class: "container-video" }, h("div", { hidden: this.showDemo == false }, h("video", { id: "howtoFront", class: "video-demo", playsinline: true, ref: el => (this.demoVideo = el) }, h("source", { type: "video/mp4" }))), h("div", { hidden: this.showDemo }, h("div", { hidden: this.verified }, h("div", { class: "video-capture" }, h("div", { style: cameraStyle }, h("div", { style: cameraStyleInner }, h("camera-comp", { "capture-mode": "id" })))))), h("div", { class: "capture-title" }, h("h1", { class: titleClass }, this.titleMesage), h("p", { class: "main-text font-size-18 text-right mb-0" }, IdCaptureValues.FooterText)))));
5768
5919
  }
5769
5920
  get component() { return getElement(this); }
5770
5921
  };
@@ -5776,7 +5927,6 @@ const IdDoubleSide = class {
5776
5927
  constructor(hostRef) {
5777
5928
  registerInstance(this, hostRef);
5778
5929
  this.apiErrorEvent = createEvent(this, "apiError", 7);
5779
- this.device = undefined;
5780
5930
  this.showTimeout = undefined;
5781
5931
  this.showInvalid = undefined;
5782
5932
  this.showHowTo = undefined;
@@ -5792,7 +5942,8 @@ const IdDoubleSide = class {
5792
5942
  recordingFileName: '',
5793
5943
  recordingUploadType: '',
5794
5944
  };
5795
- this.apiCall = new ApiCall();
5945
+ this.baseComponent = new BaseComponent(FlowSteps.CiBack);
5946
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
5796
5947
  }
5797
5948
  componentWillLoad() {
5798
5949
  this.captureRetryCount = 0;
@@ -5829,7 +5980,7 @@ const IdDoubleSide = class {
5829
5980
  async captureIdImage(event) {
5830
5981
  let idPhoto = event.detail;
5831
5982
  if (idPhoto.length == 0 || idPhoto.size == 0) {
5832
- await this.apiCall.AddLog({ message: 'Empty id photo', blobData: idPhoto }, getLogMessage());
5983
+ await this.baseComponent.apiCall.AddLog({ message: 'Empty id photo', blobData: idPhoto }, getLogMessage());
5833
5984
  return;
5834
5985
  }
5835
5986
  try {
@@ -5843,7 +5994,7 @@ const IdDoubleSide = class {
5843
5994
  async captureIdBackImage(event) {
5844
5995
  let idPhoto = event.detail;
5845
5996
  if (idPhoto.length == 0 || idPhoto.size == 0) {
5846
- await this.apiCall.AddLog({ message: 'Empty id photo', blobData: idPhoto }, getLogMessage());
5997
+ await this.baseComponent.apiCall.AddLog({ message: 'Empty id photo', blobData: idPhoto }, getLogMessage());
5847
5998
  return;
5848
5999
  }
5849
6000
  try {
@@ -5857,7 +6008,7 @@ const IdDoubleSide = class {
5857
6008
  async capturedIdRecording(event) {
5858
6009
  let idRecording = event.detail;
5859
6010
  if (idRecording.length == 0 || idRecording.size == 0) {
5860
- await this.apiCall.AddLog({ message: 'Empty recording', blobData: idRecording }, getLogMessage());
6011
+ await this.baseComponent.apiCall.AddLog({ message: 'Empty recording', blobData: idRecording }, getLogMessage());
5861
6012
  return;
5862
6013
  }
5863
6014
  let mimeType = idRecording.type == Stream.mp4MimeType.type ? Stream.mp4MimeType : Stream.webmMimeType;
@@ -5866,51 +6017,53 @@ const IdDoubleSide = class {
5866
6017
  this.uploadRecording();
5867
6018
  }
5868
6019
  catch (e) {
5869
- this.apiErrorEvent.emit(e);
6020
+ if (state.recordingRetryCount < 3) {
6021
+ state.recordingRetryCount++;
6022
+ this.triggerErrorFlow();
6023
+ }
6024
+ else {
6025
+ this.apiErrorEvent.emit(e);
6026
+ }
5870
6027
  }
5871
6028
  }
5872
6029
  async verificationFinished(_event) {
5873
6030
  this.flow.verificationFinished = true;
5874
- this.endFlow();
6031
+ await this.endFlow();
5875
6032
  }
5876
6033
  async componentDidLoad() {
5877
- try {
5878
- await this.apiCall.AddStep(FlowSteps.CiBack);
5879
- }
5880
- catch (e) {
5881
- this.apiErrorEvent.emit(e);
5882
- }
6034
+ await this.baseComponent.initialize();
5883
6035
  }
5884
6036
  async uploadPhoto() {
5885
6037
  if (this.flow.photoFile == null || this.flow.photoDone) {
5886
6038
  return;
5887
6039
  }
5888
- this.flow.photoDone = await this.apiCall.UploadFileForRequestB64(state.requestId, this.flow.photoUploadType, this.flow.photoFile);
6040
+ this.flow.photoDone = await this.baseComponent.apiCall.UploadFileForRequestB64(state.requestId, this.flow.photoUploadType, this.flow.photoFile);
5889
6041
  if (this.flow.photoDone) {
5890
- this.endFlow();
6042
+ await this.endFlow();
5891
6043
  }
5892
6044
  else {
5893
- this.flow.photoFile = null;
5894
- this.flow.recordingFile = null;
5895
6045
  this.switchCamera();
5896
- this.showInvalid = true;
6046
+ this.triggerErrorFlow();
5897
6047
  }
5898
6048
  }
5899
6049
  async uploadRecording() {
5900
6050
  if (this.flow.recordingFile == null || this.flow.recordingDone) {
5901
6051
  return;
5902
6052
  }
5903
- this.flow.recordingDone = await this.apiCall.UploadFileForRequestB64(state.requestId, this.flow.recordingUploadType, this.flow.recordingFile);
6053
+ this.flow.recordingDone = await this.baseComponent.apiCall.UploadFileForRequestB64(state.requestId, this.flow.recordingUploadType, this.flow.recordingFile);
5904
6054
  if (this.flow.recordingDone) {
5905
- this.endFlow();
6055
+ await this.endFlow();
5906
6056
  }
5907
6057
  else {
5908
- this.flow.photoFile = null;
5909
- this.flow.recordingFile = null;
5910
- this.showInvalid = true;
6058
+ this.triggerErrorFlow();
5911
6059
  }
5912
6060
  }
5913
- endFlow() {
6061
+ triggerErrorFlow() {
6062
+ this.flow.photoFile = null;
6063
+ this.flow.recordingFile = null;
6064
+ this.showInvalid = true;
6065
+ }
6066
+ async endFlow() {
5914
6067
  if (!this.flow.photoDone) {
5915
6068
  return;
5916
6069
  }
@@ -5933,6 +6086,8 @@ const IdDoubleSide = class {
5933
6086
  if (!this.flow.verificationFinished) {
5934
6087
  return;
5935
6088
  }
6089
+ state.recordingRetryCount = 0;
6090
+ await this.baseComponent.finalize();
5936
6091
  state.flowStatus = FlowStatus.LIVENESS;
5937
6092
  }
5938
6093
  switchCamera() {
@@ -5947,8 +6102,8 @@ const IdDoubleSide = class {
5947
6102
  }
5948
6103
  render() {
5949
6104
  let error = h("capture-error", { type: "ID" });
5950
- let frontCapture = h("id-capture", { id: "idFront", device: this.device });
5951
- let secondCapture = h("id-back-capture", { id: "idBack", device: this.device });
6105
+ let frontCapture = h("id-capture", { id: "idFront" });
6106
+ let secondCapture = h("id-back-capture", { id: "idBack" });
5952
6107
  let howToInfo = h("how-to-info", { idSide: this.front ? 'front' : 'back' });
5953
6108
  return this.showHowTo ? howToInfo : this.showInvalid || this.showTimeout ? error : this.front ? frontCapture : secondCapture;
5954
6109
  }
@@ -5961,7 +6116,6 @@ const IdSingleSide = class {
5961
6116
  constructor(hostRef) {
5962
6117
  registerInstance(this, hostRef);
5963
6118
  this.apiErrorEvent = createEvent(this, "apiError", 7);
5964
- this.device = undefined;
5965
6119
  this.showTimeout = undefined;
5966
6120
  this.showHowTo = undefined;
5967
6121
  this.idFlow = {
@@ -5971,7 +6125,8 @@ const IdSingleSide = class {
5971
6125
  photoFile: null,
5972
6126
  recordingFile: null,
5973
6127
  };
5974
- this.apiCall = new ApiCall();
6128
+ this.baseComponent = new BaseComponent(FlowSteps.CiFront);
6129
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
5975
6130
  this.captureRetryCount = 0;
5976
6131
  this.showHowTo = true;
5977
6132
  }
@@ -5989,7 +6144,7 @@ const IdSingleSide = class {
5989
6144
  async captureIdImage(event) {
5990
6145
  let idPhoto = event.detail;
5991
6146
  if (idPhoto.length == 0 || idPhoto.size == 0) {
5992
- await this.apiCall.AddLog({ message: 'Empty id photo', blobData: idPhoto }, getLogMessage());
6147
+ await this.baseComponent.apiCall.AddLog({ message: 'Empty id photo', blobData: idPhoto }, getLogMessage());
5993
6148
  return;
5994
6149
  }
5995
6150
  try {
@@ -6002,12 +6157,12 @@ const IdSingleSide = class {
6002
6157
  }
6003
6158
  async verificationFinished(_event) {
6004
6159
  this.idFlow.verificationFinished = true;
6005
- this.endFlow();
6160
+ await this.endFlow();
6006
6161
  }
6007
6162
  async capturedIdRecording(event) {
6008
6163
  let idRecording = event.detail;
6009
6164
  if (idRecording.length == 0 || idRecording.size == 0) {
6010
- await this.apiCall.AddLog({ message: 'Empty recording', blobData: idRecording }, getLogMessage());
6165
+ await this.baseComponent.apiCall.AddLog({ message: 'Empty recording', blobData: idRecording }, getLogMessage());
6011
6166
  return;
6012
6167
  }
6013
6168
  let mimeType = idRecording.type == Stream.mp4MimeType.type ? Stream.mp4MimeType : Stream.webmMimeType;
@@ -6022,20 +6177,15 @@ const IdSingleSide = class {
6022
6177
  }
6023
6178
  }
6024
6179
  async componentDidLoad() {
6025
- try {
6026
- await this.apiCall.AddStep(FlowSteps.CiFront);
6027
- }
6028
- catch (e) {
6029
- this.apiErrorEvent.emit(e);
6030
- }
6180
+ await this.baseComponent.initialize();
6031
6181
  }
6032
6182
  async uploadPhoto() {
6033
6183
  if (this.idFlow.photoFile == null || this.idFlow.photoDone) {
6034
6184
  return;
6035
6185
  }
6036
- this.idFlow.photoDone = await this.apiCall.UploadFileForRequestB64(state.requestId, 'IdFront', this.idFlow.photoFile);
6186
+ this.idFlow.photoDone = await this.baseComponent.apiCall.UploadFileForRequestB64(state.requestId, 'IdFront', this.idFlow.photoFile);
6037
6187
  if (this.idFlow.photoDone) {
6038
- this.endFlow();
6188
+ await this.endFlow();
6039
6189
  }
6040
6190
  else {
6041
6191
  this.idFlow.photoFile = null;
@@ -6048,9 +6198,9 @@ const IdSingleSide = class {
6048
6198
  if (this.idFlow.recordingFile == null || this.idFlow.recordingDone) {
6049
6199
  return;
6050
6200
  }
6051
- this.idFlow.recordingDone = await this.apiCall.UploadFileForRequestB64(state.requestId, 'IdFrontVideo', this.idFlow.recordingFile);
6201
+ this.idFlow.recordingDone = await this.baseComponent.apiCall.UploadFileForRequestB64(state.requestId, 'IdFrontVideo', this.idFlow.recordingFile);
6052
6202
  if (this.idFlow.recordingDone) {
6053
- this.endFlow();
6203
+ await this.endFlow();
6054
6204
  }
6055
6205
  else {
6056
6206
  this.idFlow.photoFile = null;
@@ -6058,7 +6208,7 @@ const IdSingleSide = class {
6058
6208
  this.showTimeout = true;
6059
6209
  }
6060
6210
  }
6061
- endFlow() {
6211
+ async endFlow() {
6062
6212
  if (!this.idFlow.photoDone) {
6063
6213
  return;
6064
6214
  }
@@ -6068,6 +6218,7 @@ const IdSingleSide = class {
6068
6218
  if (!this.idFlow.verificationFinished) {
6069
6219
  return;
6070
6220
  }
6221
+ await this.baseComponent.finalize();
6071
6222
  state.flowStatus = FlowStatus.LIVENESS;
6072
6223
  }
6073
6224
  switchCamera() {
@@ -6082,47 +6233,13 @@ const IdSingleSide = class {
6082
6233
  }
6083
6234
  render() {
6084
6235
  let error = h("capture-error", { type: "ID" });
6085
- let capture = h("id-capture", { id: "idFront", device: this.device });
6236
+ let capture = h("id-capture", { id: "idFront" });
6086
6237
  let howToInfo = h("how-to-info", { idSide: "front" });
6087
6238
  return this.showHowTo ? howToInfo : this.showTimeout ? error : capture;
6088
6239
  }
6089
6240
  };
6090
6241
  IdSingleSide.style = idSingleSideCss;
6091
6242
 
6092
- const initDevice = () => {
6093
- let device = {
6094
- isMobile: false,
6095
- isAndroid: false,
6096
- isLinux: false,
6097
- isMac: false,
6098
- isWin: false,
6099
- isChrome: false,
6100
- isFirefox: false,
6101
- isSafari: false,
6102
- isIos: false,
6103
- };
6104
- device.isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
6105
- device.isAndroid = /Android/i.test(navigator.userAgent);
6106
- device.isIos = /iPhone|iPad|iPod/i.test(navigator.userAgent);
6107
- device.isLinux = /linux/i.test(navigator.platform);
6108
- device.isMac = /mac/i.test(navigator.platform);
6109
- device.isWin = /win/i.test(navigator.platform);
6110
- device.isChrome = /chrome/i.test(navigator.userAgent);
6111
- device.isFirefox = /firefox/i.test(navigator.userAgent);
6112
- device.isSafari = !device.isChrome ? /safari/i.test(navigator.userAgent) : false;
6113
- device.isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
6114
- device.isAndroid = /Android/i.test(navigator.userAgent);
6115
- device.isIos = /iPhone|iPad|iPod/i.test(navigator.userAgent);
6116
- if (!device.isIos) {
6117
- const isIPad = navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints && navigator.maxTouchPoints > 2;
6118
- if (isIPad) {
6119
- device.isIos = true;
6120
- device.isMobile = true;
6121
- }
6122
- }
6123
- return device;
6124
- };
6125
-
6126
6243
  // Unique ID creation requires a high quality random # generator. In the browser we therefore
6127
6244
  // require the crypto API and do not support built-in fallback to lower quality random number
6128
6245
  // generators (like Math.random()).
@@ -6189,7 +6306,7 @@ function v4(options, buf, offset) {
6189
6306
  }
6190
6307
 
6191
6308
  const name = "@ekyc_qoobiss/qbs-ect-cmp";
6192
- const version$1 = "3.2.1";
6309
+ const version$1 = "3.2.3";
6193
6310
  const description = "Person Identification Component";
6194
6311
  const main = "./dist/index.cjs.js";
6195
6312
  const module = "./dist/index.js";
@@ -6325,7 +6442,7 @@ const IdentificationComponent = class {
6325
6442
  }
6326
6443
  agreementAcceptanceEmitted(data) {
6327
6444
  try {
6328
- this.apiCall.GenerateAgreement(data.detail.agreementType);
6445
+ this.baseComponent.apiCall.GenerateAgreement(data.detail.agreementType);
6329
6446
  }
6330
6447
  catch (e) {
6331
6448
  this.apiErrorEmitter(e, 'Agreement Acceptance');
@@ -6347,7 +6464,7 @@ const IdentificationComponent = class {
6347
6464
  else {
6348
6465
  this.errorTitle = data;
6349
6466
  }
6350
- await this.apiCall.AddLog(apiLogData, getLogMessage(this.order_id, this.redirect_id, this.token));
6467
+ await this.baseComponent.apiCall.AddLog(apiLogData, getLogMessage(this.order_id, this.redirect_id, this.token));
6351
6468
  Events.flowError(data);
6352
6469
  state.flowStatus = FlowStatus.ERROREND;
6353
6470
  }
@@ -6363,7 +6480,8 @@ const IdentificationComponent = class {
6363
6480
  this.idSide = '';
6364
6481
  this.errorMessage = undefined;
6365
6482
  this.errorTitle = undefined;
6366
- this.device = initDevice();
6483
+ this.baseComponent = new BaseComponent(null);
6484
+ this.baseComponent.setErrorCallback(this.apiErrorEmitter);
6367
6485
  }
6368
6486
  async componentWillLoad() {
6369
6487
  Events.init(window);
@@ -6434,7 +6552,6 @@ const IdentificationComponent = class {
6434
6552
  flowStatusToSet = FlowStatus.LANDING;
6435
6553
  }
6436
6554
  }
6437
- this.apiCall = new ApiCall();
6438
6555
  await this.initializeRequest();
6439
6556
  state.flowStatus = flowStatusToSet;
6440
6557
  }
@@ -6453,16 +6570,16 @@ const IdentificationComponent = class {
6453
6570
  }
6454
6571
  try {
6455
6572
  if (state.debug)
6456
- this.apiCall.AddLog('init log', this.logInit);
6573
+ this.baseComponent.apiCall.AddLog('init log', this.logInit);
6457
6574
  }
6458
6575
  catch (_a) { }
6459
6576
  try {
6460
- if (!this.device.isMobile && state.redirectId == '') {
6577
+ if (!state.device.isMobile && state.redirectId == '') {
6461
6578
  state.redirectId = v4();
6462
6579
  this.redirect_id = state.redirectId;
6463
6580
  }
6464
6581
  if (state.token != '' && (state.requestId != '' || state.redirectId != '')) {
6465
- state.initialised = await this.apiCall.AddIdentificationRequest(this.device, packageJson.version);
6582
+ state.initialised = await this.baseComponent.apiCall.AddIdentificationRequest(state.device, packageJson.version);
6466
6583
  if (!this.order_id || this.order_id == '') {
6467
6584
  this.order_id = state.requestId;
6468
6585
  }
@@ -6475,9 +6592,9 @@ const IdentificationComponent = class {
6475
6592
  }
6476
6593
  render() {
6477
6594
  let currentBlock = h("div", null);
6478
- if (this.device.isMobile || state.environment == 'DEMO') {
6595
+ if (state.device.isMobile || state.environment == 'DEMO') {
6479
6596
  if (state.flowStatus == FlowStatus.LANDING) {
6480
- currentBlock = h("landing-validation", { device: this.device });
6597
+ currentBlock = h("landing-validation", null);
6481
6598
  }
6482
6599
  }
6483
6600
  else {
@@ -6496,13 +6613,13 @@ const IdentificationComponent = class {
6496
6613
  currentBlock = h("sms-code-validation", null);
6497
6614
  }
6498
6615
  if (state.flowStatus == FlowStatus.ID && !state.hasIdBack) {
6499
- currentBlock = h("id-single-side", { id: "idFront", device: this.device });
6616
+ currentBlock = h("id-single-side", { id: "idFront" });
6500
6617
  }
6501
6618
  if (state.flowStatus == FlowStatus.ID && state.hasIdBack) {
6502
- currentBlock = h("id-double-side", { id: "idFront", device: this.device });
6619
+ currentBlock = h("id-double-side", { id: "idFront" });
6503
6620
  }
6504
6621
  if (state.flowStatus == FlowStatus.LIVENESS) {
6505
- currentBlock = h("user-liveness", { device: this.device, id: "camera" });
6622
+ currentBlock = h("user-liveness", { id: "camera" });
6506
6623
  }
6507
6624
  if (state.flowStatus == FlowStatus.COMPLETE) {
6508
6625
  currentBlock = h("end-redirect", null);
@@ -6511,7 +6628,7 @@ const IdentificationComponent = class {
6511
6628
  currentBlock = h("error-end", { errorTitle: this.errorTitle, message: this.errorMessage });
6512
6629
  }
6513
6630
  if (state.flowStatus == FlowStatus.CAMERAERROR) {
6514
- currentBlock = h("camera-error", { device: this.device });
6631
+ currentBlock = h("camera-error", null);
6515
6632
  }
6516
6633
  return h("div", null, currentBlock);
6517
6634
  }
@@ -6530,22 +6647,23 @@ const infoSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNiIgaGVpZ2h0PSIyOCIgd
6530
6647
 
6531
6648
  const idSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDYiIGhlaWdodD0iMzkiIHZpZXdCb3g9IjAgMCA0NiAzOSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzMuMjIwNiAxLjc1MTIyQzM0LjM2MDYgMS4yNjg0IDM1LjY4MDYgMS44MDQyIDM2LjE2MjggMi45NDU2M0wzNy4yNzkyIDUuNTg4MDFIMzguODMxTDM3LjQ3OTIgMi4zODgyNEMzNy4wOTY4IDEuNDgzMTYgMzYuMzg1MyAwLjc4MTQ5MyAzNS40NzU5IDAuNDEyMjExQzM0LjU2NjQgMC4wNDI5Mjc2IDMzLjU2NzcgMC4wNTA0OTYxIDMyLjY2MzcgMC40MzMzMzlMMjAuNDkzMiA1LjU4ODE2SDI0LjE2MThMMzMuMjIwNiAxLjc1MTM3VjEuNzUxMjJaTTE2LjY3ODggMTkuNTIwNUMxNy40Mjk1IDE5LjgzODQgMTguMTAzNyAyMC4yOTM0IDE4LjY4MjQgMjAuODcyOUMxOS4yNjEyIDIxLjQ1MjQgMTkuNzE1NSAyMi4xMjcyIDIwLjAzMzEgMjIuODc5QzIwLjM2MjEgMjMuNjU3OCAyMC41Mjg5IDI0LjQ4NDUgMjAuNTI4OSAyNS4zMzYzQzIwLjUyODkgMjUuNzMxNCAyMC4yMDg5IDI2LjA1MTggMTkuODE0MiAyNi4wNTE4QzE5LjQxOTYgMjYuMDUxOCAxOS4wOTk2IDI1LjczMTQgMTkuMDk5NiAyNS4zMzYzQzE5LjA5OTYgMjIuNjQ0OSAxNi45MTI3IDIwLjQ1NTIgMTQuMjI0NiAyMC40NTUyQzExLjUzNjYgMjAuNDU1MiA5LjM0OTY2IDIyLjY0NDkgOS4zNDk2NiAyNS4zMzYzQzkuMzQ5NjYgMjUuNzMxNCA5LjAyOTY2IDI2LjA1MTggOC42MzUwMiAyNi4wNTE4QzguMjQwMzcgMjYuMDUxOCA3LjkyMDM3IDI1LjczMTQgNy45MjAzNyAyNS4zMzYzQzcuOTIwMzcgMjQuNDg0NCA4LjA4NzE0IDIzLjY1NzYgOC40MTYxMiAyMi44NzlDOC43MzM2IDIyLjEyNzQgOS4xODgwOSAyMS40NTI0IDkuNzY2ODMgMjAuODcyOUMxMC4yNzUzIDIwLjM2MzkgMTAuODU3NCAxOS45NTA5IDExLjUwMDQgMTkuNjQyNUMxMS4zMzIgMTkuNTE4MSAxMS4xNzE5IDE5LjM4MDMgMTEuMDIxMyAxOS4yMjk2QzEwLjIzMiAxOC40MzkxIDkuNzk3MjIgMTcuMzg4MyA5Ljc5NzIyIDE2LjI3MDRDOS43OTcyMiAxNS4xNTI1IDEwLjIzMTkgMTQuMTAxNyAxMS4wMjEzIDEzLjMxMTNDMTEuODEwOCAxMi41MjEgMTIuODYwNCAxMi4wODU2IDEzLjk3NjggMTIuMDg1NkMxNS4wOTMxIDEyLjA4NTYgMTYuMTQyNyAxMi41MjA4IDE2LjkzMjIgMTMuMzExM0MxNy43MjE1IDE0LjEwMTcgMTguMTU2MyAxNS4xNTI2IDE4LjE1NjMgMTYuMjcwNEMxOC4xNTYzIDE3LjM4ODIgMTcuNzIxNiAxOC40MzkxIDE2LjkzMjIgMTkuMjI5NkMxNi44MzYzIDE5LjMyNTYgMTYuNzM2NCAxOS40MTYyIDE2LjYzMzMgMTkuNTAxNkwxNi42NTAxIDE5LjUwODVMMTYuNjc4OCAxOS41MjA1Wk0xMS4yMjY1IDE2LjI3MDRDMTEuMjI2NSAxNy43ODg4IDEyLjQ2MDIgMTkuMDI0MSAxMy45NzY4IDE5LjAyNDFDMTUuNDkzMyAxOS4wMjQxIDE2LjcyNyAxNy43ODg4IDE2LjcyNyAxNi4yNzA0QzE2LjcyNyAxNC43NTIgMTUuNDkzMyAxMy41MTY3IDEzLjk3NjggMTMuNTE2N0MxMi40NjAyIDEzLjUxNjcgMTEuMjI2NSAxNC43NTIgMTEuMjI2NSAxNi4yNzA0Wk0yMy45Mzg0IDEyLjA4NTZIMzYuMjA5OUMzNi42MDQ1IDEyLjA4NTYgMzYuOTI0NSAxMi40MDYgMzYuOTI0NSAxMi44MDEyQzM2LjkyNDUgMTMuMTk2MyAzNi42MDQ1IDEzLjUxNjcgMzYuMjA5OSAxMy41MTY3SDIzLjkzODRDMjMuNTQzNyAxMy41MTY3IDIzLjIyMzcgMTMuMTk2MyAyMy4yMjM3IDEyLjgwMTJDMjMuMjIzNyAxMi40MDYgMjMuNTQzNyAxMi4wODU2IDIzLjkzODQgMTIuMDg1NlpNMjMuOTM4NCAxOC4zNTQxSDM2LjIwOTlDMzYuNjA0NSAxOC4zNTQxIDM2LjkyNDUgMTguNjc0NSAzNi45MjQ1IDE5LjA2OTdDMzYuOTI0NSAxOS40NjQ4IDM2LjYwNDUgMTkuNzg1MiAzNi4yMDk5IDE5Ljc4NTJIMjMuOTM4NEMyMy41NDM3IDE5Ljc4NTIgMjMuMjIzNyAxOS40NjQ4IDIzLjIyMzcgMTkuMDY5N0MyMy4yMjM3IDE4LjY3NDUgMjMuNTQzNyAxOC4zNTQxIDIzLjkzODQgMTguMzU0MVpNMzYuMjA5OSAyNC42MjA3SDIzLjkzODRDMjMuNTQzNyAyNC42MjA3IDIzLjIyMzcgMjQuOTQxMSAyMy4yMjM3IDI1LjMzNjNDMjMuMjIzNyAyNS43MzE0IDIzLjU0MzcgMjYuMDUxOCAyMy45Mzg0IDI2LjA1MThIMzYuMjA5OUMzNi42MDQ1IDI2LjA1MTggMzYuOTI0NSAyNS43MzE0IDM2LjkyNDUgMjUuMzM2M0MzNi45MjQ1IDI0Ljk0MTEgMzYuNjA0NSAyNC42MjA3IDM2LjIwOTkgMjQuNjIwN1pNNDIuODQzNiAxNS4wODU2TDQ1LjA3MjMgMjAuMzYwN0w0NS4wNzI2IDIwLjM2MDZDNDUuNDU0OSAyMS4yNjU3IDQ1LjQ2MjUgMjIuMjY1NyA0NS4wOTM3IDIzLjE3NjNDNDQuNzI0OSAyNC4wODY4IDQ0LjAyNDEgMjQuNzk5MiA0My4xMjAxIDI1LjE4MjFMNDIuODQzOSAyNS4yOTkxVjI4LjgyNjhDNDIuODQzOSAyOS44MDk1IDQyLjQ2MTcgMzAuNzMzMyA0MS43Njc3IDMxLjQyODJDNDEuMDczNyAzMi4xMjMxIDQwLjE1MSAzMi41MDU4IDM5LjE2OTYgMzIuNTA1OEgyNS44MjkxTDEzLjMzNjIgMzcuNzk3MUMxMi40MzIyIDM4LjE4IDExLjQzMzUgMzguMTg3NiAxMC41MjQgMzcuODE4M0M5LjYxNDU4IDM3LjQ0OSA4LjkwMzA4IDM2Ljc0NzMgOC41MjA3MiAzNS44NDIyTDcuMTExMTEgMzIuNTA1OUg2LjgzMDQ4QzUuODQ5MDYgMzIuNTA1OSA0LjkyNjM4IDMyLjEyMzIgNC4yMzIzNiAzMS40Mjg0QzMuNTM4MzUgMzAuNzMzNSAzLjE1NjE0IDI5LjgwOTYgMy4xNTYxNCAyOC44MjdWMjMuMTQ0N0wwLjkyNzQ3OSAxNy44Njk2QzAuNTQ1MTE2IDE2Ljk2NDUgMC41Mzc1NTcgMTUuOTY0NSAwLjkwNjM3NiAxNS4wNTM5QzEuMjc1MiAxNC4xNDMzIDEuOTc1OTggMTMuNDMwOSAyLjg3OTkyIDEzLjA0ODFMMy4xNTYxNCAxMi45MzExVjkuMzEyMzdDMy4xNTYxNCA4LjMyOTcyIDMuNTM4MzUgNy40MDU4OCA0LjIzMjM2IDYuNzEwOTlDNC45MjYzOCA2LjAxNjExIDUuODQ5MDYgNS42MzM0MiA2LjgzMDQ4IDUuNjMzNDJIMzkuMTY5M0M0MC4xNTA3IDUuNjMzNDIgNDEuMDczMyA2LjAxNjExIDQxLjc2NzQgNi43MTA5OUM0Mi40NjE0IDcuNDA1ODggNDIuODQzNiA4LjMyOTcyIDQyLjg0MzYgOS4zMTIzN1YxNS4wODU2Wk0yLjI0Mzg2IDE3LjMxMTlMMy4xNTYxNCAxOS40NzEzVjE0LjUwOTNDMi4yMTIzNiAxNS4wNzU3IDEuODAzMDcgMTYuMjY4NyAyLjI0Mzg2IDE3LjMxMTlaTTkuODM2OTQgMzUuMjg0NUMxMC4zMTkxIDM2LjQyNiAxMS42MzkxIDM2Ljk2MTggMTIuNzc5MSAzNi40NzlMMjIuMTYwMyAzMi41MDU2SDguNjYyOTJMOS44MzY5NCAzNS4yODQ1Wk0zOS4xNjk0IDMxLjA3NDVDNDAuNDA3MiAzMS4wNzQ1IDQxLjQxNDMgMzAuMDY2MyA0MS40MTQzIDI4LjgyNjhWOS4zMTIzN0M0MS40MTQzIDguMDcyODYgNDAuNDA3MiA3LjA2NDUxIDM5LjE2OTQgNy4wNjQ1MUg2LjgzMDQ4QzUuNTkyNjggNy4wNjQ1MSA0LjU4NTU5IDguMDcyODYgNC41ODU1OSA5LjMxMjM3VjI4LjgyNjhDNC41ODU1OSAzMC4wNjYyIDUuNTkyNjggMzEuMDc0NSA2LjgzMDQ4IDMxLjA3NDVIMzkuMTY5NFpNNDIuODQzNiAxOC43NTg3VjIzLjcyMDdDNDMuNzg3NCAyMy4xNTQzIDQ0LjE5NjUgMjEuOTYxMyA0My43NTU5IDIwLjkxODFMNDIuODQzNiAxOC43NTg3WiIgZmlsbD0iIzZFNzQ4OCIvPg0KPC9zdmc+DQo=';
6532
6649
 
6533
- const deviceSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDYiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCA0NiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xNF8xNTkyKSI+DQo8cGF0aCBkPSJNMzAuMTU3IDMxLjY1NDNIMy40NzczOEMxLjc3ODc0IDMxLjY1NDMgMC4zOTc3MDUgMzAuMzA4NSAwLjM5NzcwNSAyOC42NTQ5VjI2LjQ2NzJDMC4zOTc3MDUgMjUuOTg5MSAwLjc4ODI1MyAyNS42MDQyIDEuMjcwNTYgMjUuNjA0MkgxNi43NjU0QzE3LjAwMyAyNS42MDQyIDE3LjIyODkgMjUuNjk5OSAxNy4zOTM2IDI1Ljg2NzhMMTguNTIwNSAyNy4wMjdIMjcuMDI1NUMyNy41MDc4IDI3LjAyNyAyNy44OTg0IDI3LjQxMTggMjcuODk4NCAyNy44ODk5QzI3Ljg5ODQgMjguMzY4MSAyNy41MDc4IDI4Ljc1MjkgMjcuMDI1NSAyOC43NTI5SDE4LjE0ODhDMTcuOTExMiAyOC43NTI5IDE3LjY4NTMgMjguNjU3MyAxNy41MjA2IDI4LjQ4OTNMMTYuMzkzNyAyNy4zMzAySDIuMTQzNDFWMjguNjU0OUMyLjE0MzQxIDI5LjM1NyAyLjc0MDk5IDI5LjkyNiAzLjQ3NzM4IDI5LjkyNkgzMC4xNTdDMzAuNjM5MyAyOS45MjYgMzEuMDI5OCAzMC4zMTA5IDMxLjAyOTggMzAuNzg5QzMxLjAyOTggMzEuMjY3MSAzMC42MzkzIDMxLjY1MiAzMC4xNTcgMzEuNjUyVjMxLjY1NDNaTTI5LjkwMDUgMjcuMzMwMkgyOS4yMzQ3QzI4Ljc1MjQgMjcuMzMwMiAyOC4zNjE4IDI2Ljk0NTMgMjguMzYxOCAyNi40NjcyQzI4LjM2MTggMjUuOTg5MSAyOC43NTI0IDI1LjYwNDIgMjkuMjM0NyAyNS42MDQySDI5LjkwMDVDMzAuMzgyOCAyNS42MDQyIDMwLjc3MzQgMjUuOTg5MSAzMC43NzM0IDI2LjQ2NzJDMzAuNzczNCAyNi45NDUzIDMwLjM4MjggMjcuMzMwMiAyOS45MDA1IDI3LjMzMDJaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8cGF0aCBkPSJNMy4zMjIwNyAyNC44MzdDMi44Mzk3NyAyNC44MzcgMi40NDkyMiAyNC40NTIyIDIuNDQ5MjIgMjMuOTc0MVYzLjY3ODE2QzIuNDQ5MjIgMS45Njg1NyAzLjg1Mzc4IDAuNTc2MTcyIDUuNTgwNjYgMC41NzYxNzJINDAuNDE5NEM0Mi4xNDYzIDAuNTc2MTcyIDQzLjU1MDggMS45Njg1NyA0My41NTA4IDMuNjc4MTZWNy4wMzQzOEM0My41NTA4IDcuNTEyNTEgNDMuMTYwMyA3Ljg5OTY3IDQyLjY3OCA3Ljg5OTY3QzQyLjE5NTcgNy44OTk2NyA0MS44MDUxIDcuNTEyNTEgNDEuODA1MSA3LjAzNDM4VjMuNjc4MTZDNDEuODA1MSAyLjkzNDE1IDQxLjE2OTkgMi4zMDQ0MiA0MC40MTk0IDIuMzA0NDJINS41ODA2NkM0LjgzMDE1IDIuMzA0NDIgNC4xOTQ5MiAyLjkzNDE1IDQuMTk0OTIgMy42NzgxNlYyMy45NzQxQzQuMTk0OTIgMjQuNDUyMiAzLjgwNDM3IDI0LjgzNyAzLjMyMjA3IDI0LjgzN1oiIGZpbGw9IiM2RTc0ODgiLz4NCjxwYXRoIGQ9Ik0zOS45NTgyIDUuNTA5MTVIMy4zMjIwN0MyLjgzOTc3IDUuNTA5MTUgMi40NDkyMiA1LjEyMTk4IDIuNDQ5MjIgNC42NDM4NkMyLjQ0OTIyIDQuMTY1NzMgMi44Mzk3NyAzLjc3ODU2IDMuMzIyMDcgMy43Nzg1NkgzOS45NTgyQzQwLjQ0MDUgMy43Nzg1NiA0MC44MzExIDQuMTY1NzMgNDAuODMxMSA0LjY0Mzg2QzQwLjgzMTEgNS4xMjE5OCA0MC40NDA1IDUuNTA5MTUgMzkuOTU4MiA1LjUwOTE1WiIgZmlsbD0iIzZFNzQ4OCIvPg0KPHBhdGggZD0iTTQzLjM5NTYgMzEuNjU0M0gzMy44NTMxQzMyLjY0MzggMzEuNjU0MyAzMS42OTggMzAuNzE2NyAzMS42OTggMjkuNTE3OVYxMC45NTI2QzMxLjY5OCA5Ljc0NjggMzIuNjY1IDguNzY0ODkgMzMuODUzMSA4Ljc2NDg5SDQzLjM5NTZDNDQuNTkwOCA4Ljc2NDg5IDQ1LjYwMjQgOS43Njc3OSA0NS42MDI0IDEwLjk1MjZWMTcuNzY3N0M0NS42MDI0IDE4LjI0NTggNDUuMjExOSAxOC42MzA2IDQ0LjcyOTYgMTguNjMwNkM0NC4yNDczIDE4LjYzMDYgNDMuODU2NyAxOC4yNDU4IDQzLjg1NjcgMTcuNzY3N1YxMC45NTI2QzQzLjg1NjcgMTAuNzE3IDQzLjYzMzIgMTAuNDk1NSA0My4zOTU2IDEwLjQ5NTVIMzMuODUzMUMzMy42Mjk2IDEwLjQ5NTUgMzMuNDQzNyAxMC43MDU0IDMzLjQ0MzcgMTAuOTUyNlYyOS41MTc5QzMzLjQ0MzcgMjkuNzUxMiAzMy42MjAyIDI5LjkyNjEgMzMuODUzMSAyOS45MjYxSDQzLjM5NTZDNDMuNjQ3MyAyOS45MjYxIDQzLjg1NjcgMjkuNzM5NSA0My44NTY3IDI5LjUxNzlWMjAuNjY2N0M0My44NTY3IDIwLjE4ODYgNDQuMjQ3MyAxOS44MDM4IDQ0LjcyOTYgMTkuODAzOEM0NS4yMTE5IDE5LjgwMzggNDUuNjAyNCAyMC4xODg2IDQ1LjYwMjQgMjAuNjY2N1YyOS41MTc5QzQ1LjYwMjQgMzAuNjk1NyA0NC42MTE5IDMxLjY1NDMgNDMuMzk1NiAzMS42NTQzWiIgZmlsbD0iIzZFNzQ4OCIvPg0KPHBhdGggZD0iTTM4LjkzMDIgMjkuMTYxMkgzOC4zMTM4QzM3LjgzMTUgMjkuMTYxMiAzNy40NDA5IDI4Ljc3NjQgMzcuNDQwOSAyOC4yOTgzQzM3LjQ0MDkgMjcuODIwMSAzNy44MzE1IDI3LjQzNTMgMzguMzEzOCAyNy40MzUzSDM4LjkzMDJDMzkuNDEyNSAyNy40MzUzIDM5LjgwMyAyNy44MjAxIDM5LjgwMyAyOC4yOTgzQzM5LjgwMyAyOC43NzY0IDM5LjQxMjUgMjkuMTYxMiAzOC45MzAyIDI5LjE2MTJaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8L2c+DQo8ZGVmcz4NCjxjbGlwUGF0aCBpZD0iY2xpcDBfMTRfMTU5MiI+DQo8cmVjdCB3aWR0aD0iNDUuMjA0NyIgaGVpZ2h0PSIzMS4wNzgyIiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4zOTc3MDUgMC41NzYxNzIpIi8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPC9zdmc+DQo=';
6534
-
6535
6650
  const validationSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDQiIHZpZXdCb3g9IjAgMCA0MCA0NCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xNF8xNjAxKSI+DQo8cGF0aCBkPSJNMTYuNzUxNCAyOS40MTExTDE2LjcyMjggMjMuMjczMUgxNC45NTk2QzEzLjAyODMgMjMuMjczMSAxMS40NTY1IDIxLjc1MzcgMTEuNDU2NSAxOS44ODY0VjMuOTAwMTNDMTEuNDU2NSAyLjAzMjc5IDEyLjk5MzQgMC41MTM0MjggMTQuODgxOCAwLjUxMzQyOEgzNi4zMTUyQzM4LjIwMzYgMC41MTM0MjggMzkuNzM5NiAyLjAzMjc5IDM5LjczOTYgMy45MDAxM1YxOS44ODY0QzM5LjczOTYgMjEuNzUzNyAzOC4yMDM2IDIzLjI3MzEgMzYuMzE1MiAyMy4yNzMxSDI0LjgwMDZDMjQuNzQxNSAyMy4yNzMxIDI0LjY4NTIgMjMuMjkxMiAyNC42NDIyIDIzLjMyNDZMMTYuNzUxNCAyOS40MTExWk0xNC44ODE4IDIuMTQwMzRDMTMuODgxNyAyLjE0MDM0IDEzLjA2NzYgMi45Mjk0IDEzLjA2NzYgMy45MDAxM1YxOS44ODY0QzEzLjA2NzYgMjAuODU3MSAxMy45MTY2IDIxLjY0NjIgMTQuOTYwNSAyMS42NDYySDE3LjE3OTlDMTcuODEyMyAyMS42NDYyIDE4LjMyODUgMjIuMTU2OCAxOC4zMzEyIDIyLjc4NUwxOC4zNDY0IDI2LjEzMzhMMjMuNjY1NCAyMi4wMzEyQzIzLjk4NzQgMjEuNzgyNyAyNC4zOTA5IDIxLjY0NjIgMjQuODAwNiAyMS42NDYySDM2LjMxNTJDMzcuMzE1MyAyMS42NDYyIDM4LjEyOTQgMjAuODU3MSAzOC4xMjk0IDE5Ljg4NjRWMy45MDAxM0MzOC4xMjk0IDIuOTI5NCAzNy4zMTUzIDIuMTQwMzQgMzYuMzE1MiAyLjE0MDM0SDE0Ljg4MThaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8cGF0aCBkPSJNMTcuNDc2OSA0My43MTcxSDUuMzgxNjhDMi41NTc1OCA0My43MTcxIDAuMjYwMzc2IDQxLjM5NiAwLjI2MDM3NiAzOC41NDI2VjExLjU2NTZDMC4yNjAzNzYgOC43MTIxOCAyLjU1NzU4IDYuMzkxMTEgNS4zODE2OCA2LjM5MTExSDkuNTM4NjZWOC4wMTgwM0g1LjM4MTY4QzMuNDQ1ODcgOC4wMTgwMyAxLjg3MDU3IDkuNjA5NyAxLjg3MDU3IDExLjU2NTZWMzguNTQyNkMxLjg3MDU3IDQwLjQ5ODUgMy40NDU4NyA0Mi4wOTAyIDUuMzgxNjggNDIuMDkwMkgxNy40NzY5QzE5LjQxMjcgNDIuMDkwMiAyMC45ODggNDAuNDk4NSAyMC45ODggMzguNTQyNlYyOC45Mjg0SDIyLjU5ODJWMzguNTQyNkMyMi41OTgyIDQxLjM5NiAyMC4zMDEgNDMuNzE3MSAxNy40NzY5IDQzLjcxNzFaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8cGF0aCBkPSJNOS4zODkzNSAxMS44NDIzSDEuMDY1NTVWMTMuNDY5Mkg5LjM4OTM1VjExLjg0MjNaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8cGF0aCBkPSJNMjEuNzkyMyAzNi45MTMxSDEuMDY1NTVWMzguNTRIMjEuNzkyM1YzNi45MTMxWiIgZmlsbD0iIzZFNzQ4OCIvPg0KPHBhdGggZD0iTTI0LjM4NDMgMTIuN0MyNC4zODQzIDEzLjM3MjMgMjQuOTIxNiAxMy45MzExIDI1LjU5ODUgMTMuOTMxMUMyNi4yNzU0IDEzLjkzMTEgMjYuODEyNyAxMy4zNzIzIDI2LjgxMjcgMTIuN0MyNi44MTI3IDEyLjAyNzYgMjYuMjc1NCAxMS40Njg5IDI1LjU5ODUgMTEuNDY4OUMyNC45MjE2IDExLjQ2ODkgMjQuMzg0MyAxMi4wMjc2IDI0LjM4NDMgMTIuN1pNMjUuMjAyNSAxMi43QzI1LjIwMjUgMTIuNDgxOCAyNS4zODAxIDEyLjMwNDEgMjUuNTk4NSAxMi4zMDQxQzI1LjgxNjkgMTIuMzA0MSAyNS45OTQ1IDEyLjQ4MTggMjUuOTk0NSAxMi43QzI1Ljk5NDUgMTIuOTE4MSAyNS44MTY5IDEzLjA5NTggMjUuNTk4NSAxMy4wOTU4QzI1LjM4MDEgMTMuMDk1OCAyNS4yMDI1IDEyLjkxODEgMjUuMjAyNSAxMi43WiIgZmlsbD0iIzZFNzQ4OCIgc3Ryb2tlPSIjNkU3NDg4IiBzdHJva2Utd2lkdGg9IjAuNzQ0ODkxIi8+DQo8cGF0aCBkPSJNMzAuMjQwMSAxMi43QzMwLjI0MDEgMTMuMzcyMyAzMC43Nzc0IDEzLjkzMTEgMzEuNDU0MyAxMy45MzExQzMyLjEzMTIgMTMuOTMxMSAzMi42Njg1IDEzLjM3MjMgMzIuNjY4NSAxMi43QzMyLjY2ODUgMTIuMDI3NiAzMi4xMzEyIDExLjQ2ODkgMzEuNDU0MyAxMS40Njg5QzMwLjc3NzQgMTEuNDY4OSAzMC4yNDAxIDEyLjAyNzYgMzAuMjQwMSAxMi43Wk0zMS4wNTgzIDEyLjdDMzEuMDU4MyAxMi40ODE4IDMxLjIzNTkgMTIuMzA0MSAzMS40NTQzIDEyLjMwNDFDMzEuNjcyNyAxMi4zMDQxIDMxLjg1MDMgMTIuNDgxOCAzMS44NTAzIDEyLjdDMzEuODUwMyAxMi45MTgxIDMxLjY3MjcgMTMuMDk1OCAzMS40NTQzIDEzLjA5NThDMzEuMjM1OSAxMy4wOTU4IDMxLjA1ODMgMTIuOTE4MSAzMS4wNTgzIDEyLjdaIiBmaWxsPSIjNkU3NDg4IiBzdHJva2U9IiM2RTc0ODgiIHN0cm9rZS13aWR0aD0iMC43NDQ4OTEiLz4NCjxwYXRoIGQ9Ik0xOC41Mjg2IDEyLjdDMTguNTI4NiAxMy4zNzIzIDE5LjA2NTkgMTMuOTMxMSAxOS43NDI4IDEzLjkzMTFDMjAuNDE5NyAxMy45MzExIDIwLjk1NyAxMy4zNzIzIDIwLjk1NyAxMi43QzIwLjk1NyAxMi4wMjc2IDIwLjQxOTcgMTEuNDY4OSAxOS43NDI4IDExLjQ2ODlDMTkuMDY1OSAxMS40Njg5IDE4LjUyODYgMTIuMDI3NiAxOC41Mjg2IDEyLjdaTTE5LjM0NjggMTIuN0MxOS4zNDY4IDEyLjQ4MTggMTkuNTI0NCAxMi4zMDQxIDE5Ljc0MjggMTIuMzA0MUMxOS45NjEyIDEyLjMwNDEgMjAuMTM4NyAxMi40ODE4IDIwLjEzODcgMTIuN0MyMC4xMzg3IDEyLjkxODEgMTkuOTYxMiAxMy4wOTU4IDE5Ljc0MjggMTMuMDk1OEMxOS41MjQ0IDEzLjA5NTggMTkuMzQ2OCAxMi45MTgxIDE5LjM0NjggMTIuN1oiIGZpbGw9IiM2RTc0ODgiIHN0cm9rZT0iIzZFNzQ4OCIgc3Ryb2tlLXdpZHRoPSIwLjc0NDg5MSIvPg0KPC9nPg0KPGRlZnM+DQo8Y2xpcFBhdGggaWQ9ImNsaXAwXzE0XzE2MDEiPg0KPHJlY3Qgd2lkdGg9IjM5LjQ3OTIiIGhlaWdodD0iNDMuMjAzNyIgZmlsbD0id2hpdGUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuMjYwMzc2IDAuNTEzNDI4KSIvPg0KPC9jbGlwUGF0aD4NCjwvZGVmcz4NCjwvc3ZnPg0K';
6536
6651
 
6652
+ const deviceSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDYiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCA0NiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xNF8xNTkyKSI+DQo8cGF0aCBkPSJNMzAuMTU3IDMxLjY1NDNIMy40NzczOEMxLjc3ODc0IDMxLjY1NDMgMC4zOTc3MDUgMzAuMzA4NSAwLjM5NzcwNSAyOC42NTQ5VjI2LjQ2NzJDMC4zOTc3MDUgMjUuOTg5MSAwLjc4ODI1MyAyNS42MDQyIDEuMjcwNTYgMjUuNjA0MkgxNi43NjU0QzE3LjAwMyAyNS42MDQyIDE3LjIyODkgMjUuNjk5OSAxNy4zOTM2IDI1Ljg2NzhMMTguNTIwNSAyNy4wMjdIMjcuMDI1NUMyNy41MDc4IDI3LjAyNyAyNy44OTg0IDI3LjQxMTggMjcuODk4NCAyNy44ODk5QzI3Ljg5ODQgMjguMzY4MSAyNy41MDc4IDI4Ljc1MjkgMjcuMDI1NSAyOC43NTI5SDE4LjE0ODhDMTcuOTExMiAyOC43NTI5IDE3LjY4NTMgMjguNjU3MyAxNy41MjA2IDI4LjQ4OTNMMTYuMzkzNyAyNy4zMzAySDIuMTQzNDFWMjguNjU0OUMyLjE0MzQxIDI5LjM1NyAyLjc0MDk5IDI5LjkyNiAzLjQ3NzM4IDI5LjkyNkgzMC4xNTdDMzAuNjM5MyAyOS45MjYgMzEuMDI5OCAzMC4zMTA5IDMxLjAyOTggMzAuNzg5QzMxLjAyOTggMzEuMjY3MSAzMC42MzkzIDMxLjY1MiAzMC4xNTcgMzEuNjUyVjMxLjY1NDNaTTI5LjkwMDUgMjcuMzMwMkgyOS4yMzQ3QzI4Ljc1MjQgMjcuMzMwMiAyOC4zNjE4IDI2Ljk0NTMgMjguMzYxOCAyNi40NjcyQzI4LjM2MTggMjUuOTg5MSAyOC43NTI0IDI1LjYwNDIgMjkuMjM0NyAyNS42MDQySDI5LjkwMDVDMzAuMzgyOCAyNS42MDQyIDMwLjc3MzQgMjUuOTg5MSAzMC43NzM0IDI2LjQ2NzJDMzAuNzczNCAyNi45NDUzIDMwLjM4MjggMjcuMzMwMiAyOS45MDA1IDI3LjMzMDJaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8cGF0aCBkPSJNMy4zMjIwNyAyNC44MzdDMi44Mzk3NyAyNC44MzcgMi40NDkyMiAyNC40NTIyIDIuNDQ5MjIgMjMuOTc0MVYzLjY3ODE2QzIuNDQ5MjIgMS45Njg1NyAzLjg1Mzc4IDAuNTc2MTcyIDUuNTgwNjYgMC41NzYxNzJINDAuNDE5NEM0Mi4xNDYzIDAuNTc2MTcyIDQzLjU1MDggMS45Njg1NyA0My41NTA4IDMuNjc4MTZWNy4wMzQzOEM0My41NTA4IDcuNTEyNTEgNDMuMTYwMyA3Ljg5OTY3IDQyLjY3OCA3Ljg5OTY3QzQyLjE5NTcgNy44OTk2NyA0MS44MDUxIDcuNTEyNTEgNDEuODA1MSA3LjAzNDM4VjMuNjc4MTZDNDEuODA1MSAyLjkzNDE1IDQxLjE2OTkgMi4zMDQ0MiA0MC40MTk0IDIuMzA0NDJINS41ODA2NkM0LjgzMDE1IDIuMzA0NDIgNC4xOTQ5MiAyLjkzNDE1IDQuMTk0OTIgMy42NzgxNlYyMy45NzQxQzQuMTk0OTIgMjQuNDUyMiAzLjgwNDM3IDI0LjgzNyAzLjMyMjA3IDI0LjgzN1oiIGZpbGw9IiM2RTc0ODgiLz4NCjxwYXRoIGQ9Ik0zOS45NTgyIDUuNTA5MTVIMy4zMjIwN0MyLjgzOTc3IDUuNTA5MTUgMi40NDkyMiA1LjEyMTk4IDIuNDQ5MjIgNC42NDM4NkMyLjQ0OTIyIDQuMTY1NzMgMi44Mzk3NyAzLjc3ODU2IDMuMzIyMDcgMy43Nzg1NkgzOS45NTgyQzQwLjQ0MDUgMy43Nzg1NiA0MC44MzExIDQuMTY1NzMgNDAuODMxMSA0LjY0Mzg2QzQwLjgzMTEgNS4xMjE5OCA0MC40NDA1IDUuNTA5MTUgMzkuOTU4MiA1LjUwOTE1WiIgZmlsbD0iIzZFNzQ4OCIvPg0KPHBhdGggZD0iTTQzLjM5NTYgMzEuNjU0M0gzMy44NTMxQzMyLjY0MzggMzEuNjU0MyAzMS42OTggMzAuNzE2NyAzMS42OTggMjkuNTE3OVYxMC45NTI2QzMxLjY5OCA5Ljc0NjggMzIuNjY1IDguNzY0ODkgMzMuODUzMSA4Ljc2NDg5SDQzLjM5NTZDNDQuNTkwOCA4Ljc2NDg5IDQ1LjYwMjQgOS43Njc3OSA0NS42MDI0IDEwLjk1MjZWMTcuNzY3N0M0NS42MDI0IDE4LjI0NTggNDUuMjExOSAxOC42MzA2IDQ0LjcyOTYgMTguNjMwNkM0NC4yNDczIDE4LjYzMDYgNDMuODU2NyAxOC4yNDU4IDQzLjg1NjcgMTcuNzY3N1YxMC45NTI2QzQzLjg1NjcgMTAuNzE3IDQzLjYzMzIgMTAuNDk1NSA0My4zOTU2IDEwLjQ5NTVIMzMuODUzMUMzMy42Mjk2IDEwLjQ5NTUgMzMuNDQzNyAxMC43MDU0IDMzLjQ0MzcgMTAuOTUyNlYyOS41MTc5QzMzLjQ0MzcgMjkuNzUxMiAzMy42MjAyIDI5LjkyNjEgMzMuODUzMSAyOS45MjYxSDQzLjM5NTZDNDMuNjQ3MyAyOS45MjYxIDQzLjg1NjcgMjkuNzM5NSA0My44NTY3IDI5LjUxNzlWMjAuNjY2N0M0My44NTY3IDIwLjE4ODYgNDQuMjQ3MyAxOS44MDM4IDQ0LjcyOTYgMTkuODAzOEM0NS4yMTE5IDE5LjgwMzggNDUuNjAyNCAyMC4xODg2IDQ1LjYwMjQgMjAuNjY2N1YyOS41MTc5QzQ1LjYwMjQgMzAuNjk1NyA0NC42MTE5IDMxLjY1NDMgNDMuMzk1NiAzMS42NTQzWiIgZmlsbD0iIzZFNzQ4OCIvPg0KPHBhdGggZD0iTTM4LjkzMDIgMjkuMTYxMkgzOC4zMTM4QzM3LjgzMTUgMjkuMTYxMiAzNy40NDA5IDI4Ljc3NjQgMzcuNDQwOSAyOC4yOTgzQzM3LjQ0MDkgMjcuODIwMSAzNy44MzE1IDI3LjQzNTMgMzguMzEzOCAyNy40MzUzSDM4LjkzMDJDMzkuNDEyNSAyNy40MzUzIDM5LjgwMyAyNy44MjAxIDM5LjgwMyAyOC4yOTgzQzM5LjgwMyAyOC43NzY0IDM5LjQxMjUgMjkuMTYxMiAzOC45MzAyIDI5LjE2MTJaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8L2c+DQo8ZGVmcz4NCjxjbGlwUGF0aCBpZD0iY2xpcDBfMTRfMTU5MiI+DQo8cmVjdCB3aWR0aD0iNDUuMjA0NyIgaGVpZ2h0PSIzMS4wNzgyIiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4zOTc3MDUgMC41NzYxNzIpIi8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPC9zdmc+DQo=';
6653
+
6537
6654
  const landingValidationCss = "";
6538
6655
 
6539
6656
  const LandingValidation = class {
6540
6657
  constructor(hostRef) {
6541
6658
  registerInstance(this, hostRef);
6542
6659
  this.apiErrorEvent = createEvent(this, "apiError", 7);
6543
- this.device = undefined;
6544
6660
  this.warningText = undefined;
6545
6661
  this.buttonDisabled = undefined;
6662
+ this.baseComponent = new BaseComponent(FlowSteps.Landing);
6663
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
6546
6664
  }
6547
6665
  async componentWillLoad() {
6548
- this.apiCall = new ApiCall();
6666
+ this.baseComponent.apiCall = new ApiCall();
6549
6667
  this.buttonDisabled = false;
6550
6668
  await this.initRequest();
6551
6669
  }
@@ -6553,12 +6671,7 @@ const LandingValidation = class {
6553
6671
  Events.init(window);
6554
6672
  Events.flowStarted();
6555
6673
  if (state.environment !== 'DEMO') {
6556
- try {
6557
- await this.apiCall.AddStep(FlowSteps.Landing);
6558
- }
6559
- catch (e) {
6560
- this.apiErrorEvent.emit(e);
6561
- }
6674
+ await this.baseComponent.initialize();
6562
6675
  }
6563
6676
  }
6564
6677
  async initRequest() {
@@ -6576,8 +6689,9 @@ const LandingValidation = class {
6576
6689
  state.flowStatus = FlowStatus.COMPLETE;
6577
6690
  return;
6578
6691
  }
6579
- if (!(await Cameras.InitCameras(this.device))) {
6580
- if (this.device.isIos)
6692
+ await this.baseComponent.finalize();
6693
+ if (!(await Cameras.InitCameras(state.device))) {
6694
+ if (state.device.mobileOS == MobileOS.iOS)
6581
6695
  sessionStorage.setItem(SessionKeys.RefreshDoneKey, 'false');
6582
6696
  state.flowStatus = FlowStatus.CAMERAERROR;
6583
6697
  }
@@ -6597,7 +6711,8 @@ const LandingValidation = class {
6597
6711
  return;
6598
6712
  state.initialised = false;
6599
6713
  try {
6600
- await this.apiCall.AbortRequest();
6714
+ await this.baseComponent.apiCall.AbortRequest();
6715
+ await this.baseComponent.finalize();
6601
6716
  Events.flowAborted();
6602
6717
  }
6603
6718
  catch (e) {
@@ -9499,7 +9614,8 @@ const MobileRedirect = class {
9499
9614
  this.redirectLink = undefined;
9500
9615
  this.qrCode = undefined;
9501
9616
  this.prefilledPhone = false;
9502
- this.apiCall = new ApiCall();
9617
+ this.baseComponent = new BaseComponent(FlowSteps.MobileRedirect);
9618
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
9503
9619
  this.invalidValue = false;
9504
9620
  this.waitingMobile = false;
9505
9621
  }
@@ -9523,12 +9639,7 @@ const MobileRedirect = class {
9523
9639
  async componentDidLoad() {
9524
9640
  Events.init(window);
9525
9641
  Events.flowStarted();
9526
- try {
9527
- await this.apiCall.AddStep(FlowSteps.MobileRedirect);
9528
- }
9529
- catch (e) {
9530
- this.apiErrorEvent.emit(e);
9531
- }
9642
+ await this.baseComponent.initialize();
9532
9643
  await delay(5000);
9533
9644
  await this.checkStatus();
9534
9645
  while (this.orderStatus == OrderStatuses.Capturing || this.orderStatus == OrderStatuses.Waiting) {
@@ -9537,9 +9648,10 @@ const MobileRedirect = class {
9537
9648
  }
9538
9649
  }
9539
9650
  async checkStatus() {
9540
- this.orderStatus = await this.apiCall.GetStatus(state.requestId);
9651
+ this.orderStatus = await this.baseComponent.apiCall.GetStatus(state.requestId);
9541
9652
  if (this.orderStatus == OrderStatuses.FinishedCapturing) {
9542
9653
  this.waitingMobile = false;
9654
+ await this.baseComponent.finalize();
9543
9655
  state.flowStatus = FlowStatus.COMPLETE;
9544
9656
  }
9545
9657
  if (this.orderStatus == OrderStatuses.NotFound) {
@@ -9562,7 +9674,7 @@ const MobileRedirect = class {
9562
9674
  this.waitingMobile = true;
9563
9675
  this.infoTextTop = MobileRedirectValues.InfoWaiting;
9564
9676
  try {
9565
- await this.apiCall.SendLink(this.redirectLink, this.contact);
9677
+ await this.baseComponent.apiCall.SendLink(this.redirectLink, this.contact);
9566
9678
  }
9567
9679
  catch (e) {
9568
9680
  this.apiErrorEvent.emit(e);
@@ -9594,7 +9706,6 @@ const SelfieCapture = class {
9594
9706
  //this.closeCamera();
9595
9707
  this.eventPhotoCapture.emit(photos);
9596
9708
  };
9597
- this.device = undefined;
9598
9709
  this.videoStarted = undefined;
9599
9710
  this.captureTaken = undefined;
9600
9711
  this.verified = undefined;
@@ -9647,7 +9758,7 @@ const SelfieCapture = class {
9647
9758
  this.openCamera();
9648
9759
  }
9649
9760
  async openCamera() {
9650
- const constraints = this.cameras.GetConstraints('', this.device, true);
9761
+ const constraints = this.cameras.GetConstraints('', state.device, true);
9651
9762
  setTimeout(() => {
9652
9763
  navigator.mediaDevices
9653
9764
  .getUserMedia(constraints)
@@ -9691,7 +9802,7 @@ const SelfieCapture = class {
9691
9802
  }
9692
9803
  render() {
9693
9804
  let cameraStyle;
9694
- if (this.device.isMobile && this.videoStarted) {
9805
+ if (state.device.isMobile && this.videoStarted) {
9695
9806
  cameraStyle = {
9696
9807
  'width': this.captureWidth + 'px',
9697
9808
  'height': this.captureHeight + 'px',
@@ -9704,7 +9815,7 @@ const SelfieCapture = class {
9704
9815
  let titleClass = this.verified ? 'color-black-2 text-center' : 'color-white text-center';
9705
9816
  //let videoClass = this.device.isMobile ? '' : 'video-demo';
9706
9817
  let bgDemo = this.verified ? 'container' : 'container bg-black';
9707
- return (h("div", { class: bgDemo }, h("div", { class: "container-video" }, h("div", { hidden: this.demoEnded }, h("video", { id: "howtoSelfie", class: "video-demo", playsinline: true, ref: el => (this.demoVideo = el) }, h("source", { type: "video/mp4" }))), h("div", { hidden: this.demoEnded == false }, h("div", { hidden: this.verified }, h("div", { class: "video-capture" }, h("div", { style: cameraStyle }, h("camera-comp", { device: this.device, "capture-mode": "selfie" }))))), h("div", { class: "capture-title" }, h("h1", { class: titleClass }, this.titleMesage), h("p", { class: "main-text font-size-18 text-right mb-0" }, SelfieCaptureValues.FooterText)))));
9818
+ return (h("div", { class: bgDemo }, h("div", { class: "container-video" }, h("div", { hidden: this.demoEnded }, h("video", { id: "howtoSelfie", class: "video-demo", playsinline: true, ref: el => (this.demoVideo = el) }, h("source", { type: "video/mp4" }))), h("div", { hidden: this.demoEnded == false }, h("div", { hidden: this.verified }, h("div", { class: "video-capture" }, h("div", { style: cameraStyle }, h("camera-comp", { "capture-mode": "selfie" }))))), h("div", { class: "capture-title" }, h("h1", { class: titleClass }, this.titleMesage), h("p", { class: "main-text font-size-18 text-right mb-0" }, SelfieCaptureValues.FooterText)))));
9708
9819
  }
9709
9820
  get component() { return getElement(this); }
9710
9821
  };
@@ -9723,13 +9834,20 @@ const SmsCodeValidation = class {
9723
9834
  this.code = undefined;
9724
9835
  this.prefilledPhone = false;
9725
9836
  this.canSend = false;
9726
- this.apiCall = new ApiCall();
9837
+ if (state.flowStatus == FlowStatus.PHONE) {
9838
+ this.baseComponent = new BaseComponent(FlowSteps.OtpSend);
9839
+ }
9840
+ if (state.flowStatus == FlowStatus.CODE) {
9841
+ this.baseComponent = new BaseComponent(FlowSteps.OtpCheck);
9842
+ }
9843
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
9727
9844
  }
9728
9845
  async doAction() {
9729
9846
  try {
9730
9847
  this.canSend = false;
9848
+ await this.baseComponent.finalize();
9731
9849
  if (state.flowStatus == FlowStatus.CODE || state.flowStatus == FlowStatus.CODEERROR) {
9732
- var codeChecked = await this.apiCall.CheckOTPCode(state.requestId, this.code);
9850
+ var codeChecked = await this.baseComponent.apiCall.CheckOTPCode(state.requestId, this.code);
9733
9851
  if (codeChecked === true) {
9734
9852
  state.flowStatus = FlowStatus.ID;
9735
9853
  }
@@ -9738,7 +9856,7 @@ const SmsCodeValidation = class {
9738
9856
  }
9739
9857
  }
9740
9858
  if (state.flowStatus == FlowStatus.PHONE) {
9741
- var codeSent = await this.apiCall.SendOTPCode(state.requestId, this.phoneNumber);
9859
+ var codeSent = await this.baseComponent.apiCall.SendOTPCode(state.requestId, this.phoneNumber);
9742
9860
  if (codeSent === true) {
9743
9861
  state.flowStatus = FlowStatus.CODE;
9744
9862
  }
@@ -9766,17 +9884,7 @@ const SmsCodeValidation = class {
9766
9884
  }
9767
9885
  }
9768
9886
  async componentDidLoad() {
9769
- try {
9770
- if (state.flowStatus == FlowStatus.PHONE) {
9771
- await this.apiCall.AddStep(FlowSteps.OtpSend);
9772
- }
9773
- if (state.flowStatus == FlowStatus.CODE) {
9774
- await this.apiCall.AddStep(FlowSteps.OtpCheck);
9775
- }
9776
- }
9777
- catch (e) {
9778
- this.apiErrorEvent.emit(e);
9779
- }
9887
+ await this.baseComponent.initialize();
9780
9888
  }
9781
9889
  handleChangePhone(ev) {
9782
9890
  let value = ev.target ? ev.target.value : '';
@@ -9817,7 +9925,6 @@ const UserLiveness = class {
9817
9925
  constructor(hostRef) {
9818
9926
  registerInstance(this, hostRef);
9819
9927
  this.apiErrorEvent = createEvent(this, "apiError", 7);
9820
- this.device = undefined;
9821
9928
  this.showError = undefined;
9822
9929
  this.showHowTo = undefined;
9823
9930
  this.selfieFlow = {
@@ -9827,15 +9934,11 @@ const UserLiveness = class {
9827
9934
  photoFile: null,
9828
9935
  recordingFile: null,
9829
9936
  };
9830
- this.apiCall = new ApiCall();
9937
+ this.baseComponent = new BaseComponent(FlowSteps.Selfie);
9938
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
9831
9939
  }
9832
9940
  async componentDidLoad() {
9833
- try {
9834
- await this.apiCall.AddStep(FlowSteps.Selfie);
9835
- }
9836
- catch (e) {
9837
- this.apiErrorEvent.emit(e);
9838
- }
9941
+ await this.baseComponent.initialize();
9839
9942
  }
9840
9943
  componentWillLoad() {
9841
9944
  this.showHowTo = true;
@@ -9856,7 +9959,7 @@ const UserLiveness = class {
9856
9959
  async captureSelfieImage(event) {
9857
9960
  let selfiePhoto = event.detail;
9858
9961
  if (selfiePhoto.length == 0 || selfiePhoto.size == 0) {
9859
- await this.apiCall.AddLog({ message: 'Empty selfie', blobData: selfiePhoto }, getLogMessage());
9962
+ await this.baseComponent.apiCall.AddLog({ message: 'Empty selfie', blobData: selfiePhoto }, getLogMessage());
9860
9963
  return;
9861
9964
  }
9862
9965
  try {
@@ -9870,7 +9973,7 @@ const UserLiveness = class {
9870
9973
  async capturedSelfieRecording(event) {
9871
9974
  let selfieRecording = event.detail;
9872
9975
  if (selfieRecording.length == 0 || selfieRecording.size == 0) {
9873
- await this.apiCall.AddLog({ message: 'Empty recording', blobData: selfieRecording }, getLogMessage());
9976
+ await this.baseComponent.apiCall.AddLog({ message: 'Empty recording', blobData: selfieRecording }, getLogMessage());
9874
9977
  return;
9875
9978
  }
9876
9979
  let mimeType = selfieRecording.type == Stream.mp4MimeType.type ? Stream.mp4MimeType : Stream.webmMimeType;
@@ -9879,42 +9982,49 @@ const UserLiveness = class {
9879
9982
  await this.uploadRecording();
9880
9983
  }
9881
9984
  catch (e) {
9882
- this.apiErrorEvent.emit(e);
9985
+ if (state.recordingRetryCount < 3) {
9986
+ state.recordingRetryCount++;
9987
+ this.triggerErrorFlow();
9988
+ }
9989
+ else {
9990
+ this.apiErrorEvent.emit(e);
9991
+ }
9883
9992
  }
9884
9993
  }
9885
9994
  async verificationFinished(_event) {
9886
9995
  this.selfieFlow.verificationFinished = true;
9887
- this.endFlow();
9996
+ await this.endFlow();
9888
9997
  }
9889
9998
  async uploadPhoto() {
9890
9999
  if (this.selfieFlow.photoFile == null || this.selfieFlow.photoDone) {
9891
10000
  return;
9892
10001
  }
9893
- this.selfieFlow.photoDone = await this.apiCall.UploadFileForRequestB64(state.requestId, 'Selfie', this.selfieFlow.photoFile);
10002
+ this.selfieFlow.photoDone = await this.baseComponent.apiCall.UploadFileForRequestB64(state.requestId, 'Selfie', this.selfieFlow.photoFile);
9894
10003
  if (this.selfieFlow.photoDone) {
9895
- this.endFlow();
10004
+ await this.endFlow();
9896
10005
  }
9897
10006
  else {
9898
- this.selfieFlow.photoFile = null;
9899
- this.selfieFlow.recordingFile = null;
9900
- this.showError = true;
10007
+ this.triggerErrorFlow();
9901
10008
  }
9902
10009
  }
9903
10010
  async uploadRecording() {
9904
10011
  if (this.selfieFlow.recordingFile == null || this.selfieFlow.recordingDone) {
9905
10012
  return;
9906
10013
  }
9907
- this.selfieFlow.recordingDone = await this.apiCall.UploadFileForRequestB64(state.requestId, 'SelfieVideo', this.selfieFlow.recordingFile);
10014
+ this.selfieFlow.recordingDone = await this.baseComponent.apiCall.UploadFileForRequestB64(state.requestId, 'SelfieVideo', this.selfieFlow.recordingFile);
9908
10015
  if (this.selfieFlow.recordingDone) {
9909
- this.endFlow();
10016
+ await this.endFlow();
9910
10017
  }
9911
10018
  else {
9912
- this.selfieFlow.photoFile = null;
9913
- this.selfieFlow.recordingFile = null;
9914
- this.showError = true;
10019
+ this.triggerErrorFlow();
9915
10020
  }
9916
10021
  }
9917
- endFlow() {
10022
+ triggerErrorFlow() {
10023
+ this.selfieFlow.photoFile = null;
10024
+ this.selfieFlow.recordingFile = null;
10025
+ this.showError = true;
10026
+ }
10027
+ async endFlow() {
9918
10028
  if (!this.selfieFlow.photoDone) {
9919
10029
  return;
9920
10030
  }
@@ -9924,11 +10034,13 @@ const UserLiveness = class {
9924
10034
  if (!this.selfieFlow.verificationFinished) {
9925
10035
  return;
9926
10036
  }
10037
+ state.recordingRetryCount = 0;
10038
+ await this.baseComponent.finalize();
9927
10039
  state.flowStatus = FlowStatus.COMPLETE;
9928
10040
  }
9929
10041
  render() {
9930
10042
  let howTo = h("how-to-info", { idSide: "" });
9931
- let capture = h("selfie-capture", { device: this.device, id: "camera" });
10043
+ let capture = h("selfie-capture", { id: "camera" });
9932
10044
  let error = h("capture-error", { type: "LIVENESS" });
9933
10045
  return this.showHowTo ? howTo : this.showError ? error : capture;
9934
10046
  }