@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
@@ -378,6 +378,8 @@ const { state, onChange } = createStore({
378
378
  phoneValidation: true,
379
379
  phoneNumber: '',
380
380
  apiBaseUrl: 'https://apiro.id-kyc.com',
381
+ device: null,
382
+ recordingRetryCount: 0,
381
383
  });
382
384
  onChange('environment', value => {
383
385
  state.debug = value == 'QA';
@@ -406,20 +408,26 @@ onChange('phoneValidation', value => {
406
408
 
407
409
  var FlowSteps;
408
410
  (function (FlowSteps) {
409
- FlowSteps[FlowSteps["MobileRedirect"] = 0] = "MobileRedirect";
410
- FlowSteps[FlowSteps["Landing"] = 1] = "Landing";
411
- FlowSteps[FlowSteps["Agreements"] = 2] = "Agreements";
412
- FlowSteps[FlowSteps["OtpSend"] = 3] = "OtpSend";
413
- FlowSteps[FlowSteps["OtpCheck"] = 4] = "OtpCheck";
414
- FlowSteps[FlowSteps["CiFrontHowTo"] = 5] = "CiFrontHowTo";
415
- FlowSteps[FlowSteps["CiFront"] = 6] = "CiFront";
416
- FlowSteps[FlowSteps["CiBackHowTo"] = 7] = "CiBackHowTo";
417
- FlowSteps[FlowSteps["CiBack"] = 8] = "CiBack";
418
- FlowSteps[FlowSteps["SelfieHowTo"] = 9] = "SelfieHowTo";
419
- FlowSteps[FlowSteps["Selfie"] = 10] = "Selfie";
420
- FlowSteps[FlowSteps["End"] = 11] = "End";
421
- FlowSteps[FlowSteps["CameraError"] = 12] = "CameraError";
422
- })(FlowSteps || (FlowSteps = {}));
411
+ FlowSteps[FlowSteps["MobileRedirect"] = 'mobile-redirect'] = "MobileRedirect";
412
+ FlowSteps[FlowSteps["Landing"] = 'landing'] = "Landing";
413
+ FlowSteps[FlowSteps["Agreements"] = 'agreements'] = "Agreements";
414
+ FlowSteps[FlowSteps["OtpSend"] = 'otp-send'] = "OtpSend";
415
+ FlowSteps[FlowSteps["OtpCheck"] = 'otp-check'] = "OtpCheck";
416
+ FlowSteps[FlowSteps["CiFrontHowTo"] = 'ci-front-how-to'] = "CiFrontHowTo";
417
+ FlowSteps[FlowSteps["CiFront"] = 'ci-front'] = "CiFront";
418
+ FlowSteps[FlowSteps["CiBackHowTo"] = 'ci-back-how-to'] = "CiBackHowTo";
419
+ FlowSteps[FlowSteps["CiBack"] = 'ci-back'] = "CiBack";
420
+ FlowSteps[FlowSteps["SelfieHowTo"] = 'selfie-how-to'] = "SelfieHowTo";
421
+ FlowSteps[FlowSteps["Selfie"] = 'selfie'] = "Selfie";
422
+ FlowSteps[FlowSteps["End"] = 'end'] = "End";
423
+ FlowSteps[FlowSteps["CameraError"] = 'camera-error'] = "CameraError";
424
+ })(FlowSteps || (FlowSteps = {}));
425
+ var FlowMoments;
426
+ (function (FlowMoments) {
427
+ FlowMoments[FlowMoments["Initialized"] = 'initialized'] = "Initialized";
428
+ FlowMoments[FlowMoments["Finalized"] = 'finalized'] = "Finalized";
429
+ FlowMoments[FlowMoments["None"] = 'none'] = "None";
430
+ })(FlowMoments || (FlowMoments = {}));
423
431
 
424
432
  class ApiCall {
425
433
  constructor() {
@@ -541,8 +549,8 @@ class ApiCall {
541
549
  }
542
550
  catch (_a) { }
543
551
  }
544
- async AddStep(step) {
545
- let data = { requestId: state.requestId, redirectId: state.redirectId, step: FlowSteps[step] };
552
+ async AddStep(step, moment) {
553
+ let data = { requestId: state.requestId, redirectId: state.redirectId, step: FlowSteps[step], moment: FlowMoments[moment] };
546
554
  let result = await this.post(this.urls.AddStep, JSON.stringify(data));
547
555
  return result.saved;
548
556
  }
@@ -584,6 +592,215 @@ const AgreementCheck = class {
584
592
  };
585
593
  AgreementCheck.style = agreementCheckCss;
586
594
 
595
+ var MobileOS;
596
+ (function (MobileOS) {
597
+ MobileOS["Android"] = "android";
598
+ MobileOS["iOS"] = "ios";
599
+ MobileOS["Unknown"] = "unknown";
600
+ MobileOS["WindowsPhone"] = "Windows Phone";
601
+ })(MobileOS || (MobileOS = {}));
602
+ var DesktopOS;
603
+ (function (DesktopOS) {
604
+ DesktopOS["Linux"] = "linux";
605
+ DesktopOS["MacOS"] = "mac_os";
606
+ DesktopOS["Unix"] = "unix";
607
+ DesktopOS["Unknown"] = "unknown";
608
+ DesktopOS["Windows"] = "windows";
609
+ })(DesktopOS || (DesktopOS = {}));
610
+ var Browser;
611
+ (function (Browser) {
612
+ Browser["Chrome"] = "chrome";
613
+ Browser["Firefox"] = "firefox";
614
+ Browser["Safari"] = "safari";
615
+ Browser["Unknown"] = "unknown";
616
+ })(Browser || (Browser = {}));
617
+
618
+ class DeviceDetection {
619
+ constructor() {
620
+ var _a, _b, _c, _d;
621
+ 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;
622
+ this.safariScreenOrientation = !(screen === null || screen === void 0 ? void 0 : screen.orientation) && matchMedia('(orientation: portrait)').matches ? 'portrait-primary' : 'landscape-primary';
623
+ this.initialScreenOrientation = (_d = (_c = this.supportedScreenOrientation) !== null && _c !== void 0 ? _c : this.safariScreenOrientation) !== null && _d !== void 0 ? _d : 'portrait-primary';
624
+ this.userAgent = navigator.userAgent || navigator.vendor || window.opera || undefined;
625
+ this.isMobile = this.isMobileDevice();
626
+ this.isTablet = this.isTabletDevice();
627
+ this.isDesktop = !this.isMobile && !this.isTablet;
628
+ }
629
+ // Device typology
630
+ isMobileDevice() {
631
+ const regexs = [/(Android)(.+)(Mobile)/i, /BlackBerry/i, /iPhone|iPod/i, /Opera Mini/i, /IEMobile/i];
632
+ return regexs.some(b => this.userAgent.match(b));
633
+ }
634
+ isTabletDevice() {
635
+ const regex = /(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/;
636
+ return regex.test(this.userAgent.toLowerCase());
637
+ }
638
+ // Device Operating System
639
+ getMobileOS() {
640
+ if (this.isMobileDevice()) {
641
+ if (/windows phone/i.test(this.userAgent))
642
+ return MobileOS.WindowsPhone;
643
+ else if (/android/i.test(this.userAgent))
644
+ return MobileOS.Android;
645
+ else if (/iPad|iPhone|iPod/.test(this.userAgent) && !window.MSStream)
646
+ return MobileOS.iOS;
647
+ return MobileOS.Unknown;
648
+ }
649
+ else
650
+ return undefined;
651
+ }
652
+ getDesktopOS() {
653
+ if (this.isDesktop) {
654
+ if (this.userAgent.indexOf('Win') !== -1)
655
+ return DesktopOS.Windows;
656
+ else if (this.userAgent.indexOf('Mac') !== -1)
657
+ return DesktopOS.MacOS;
658
+ else if (this.userAgent.indexOf('X11') !== -1)
659
+ return DesktopOS.Unix;
660
+ else if (this.userAgent.indexOf('Linux') !== -1)
661
+ return DesktopOS.Linux;
662
+ return DesktopOS.Unknown;
663
+ }
664
+ else
665
+ return undefined;
666
+ }
667
+ getDeviceOS() {
668
+ var _a;
669
+ return (_a = this.getMobileOS()) !== null && _a !== void 0 ? _a : this.getDesktopOS();
670
+ }
671
+ getBrowser() {
672
+ var isChrome = /chrome/i.test(this.userAgent);
673
+ if (isChrome)
674
+ return Browser.Chrome;
675
+ if (/firefox/i.test(navigator.userAgent))
676
+ return Browser.Firefox;
677
+ else if (!isChrome && /safari/i.test(navigator.userAgent))
678
+ return Browser.Safari;
679
+ else
680
+ return Browser.Unknown;
681
+ }
682
+ getDevice() {
683
+ var device = {
684
+ isDesktop: this.isDesktop,
685
+ desktopOS: this.getDesktopOS(),
686
+ isWindowsDesktop: this.getDeviceOS() === DesktopOS.Windows,
687
+ isLinuxOrUnixDesktop: this.getDeviceOS() === DesktopOS.Linux || this.getDeviceOS() === DesktopOS.Unix,
688
+ isMobile: this.isMobile,
689
+ mobileOS: this.getMobileOS(),
690
+ isAndroidDevice: this.getDeviceOS() === MobileOS.Android,
691
+ isAppleDevice: this.getDeviceOS() === MobileOS.iOS || this.getDeviceOS() === DesktopOS.MacOS,
692
+ isUnknownMobileDevice: this.getDeviceOS() === MobileOS.Unknown,
693
+ browser: this.getBrowser(),
694
+ isTablet: this.isTablet,
695
+ initialScreenOrientation: this.initialScreenOrientation,
696
+ };
697
+ return device;
698
+ }
699
+ }
700
+
701
+ class Events {
702
+ static init(element) {
703
+ this.callingModule = element;
704
+ }
705
+ static flowEvent(step, moment) {
706
+ const eventName = `ect-${step.toString()}-${moment.toString()}-event`;
707
+ this.callingModule.dispatchEvent(new CustomEvent(eventName, {
708
+ detail: {},
709
+ bubbles: true,
710
+ cancelable: true,
711
+ composed: true,
712
+ }));
713
+ }
714
+ static flowStarted() {
715
+ this.callingModule.dispatchEvent(new CustomEvent('ect-started', {
716
+ detail: {},
717
+ bubbles: true,
718
+ cancelable: true,
719
+ composed: true,
720
+ }));
721
+ }
722
+ static flowAborted() {
723
+ sessionStorage.clear();
724
+ this.callingModule.dispatchEvent(new CustomEvent('ect-aborted', {
725
+ detail: {},
726
+ bubbles: true,
727
+ cancelable: true,
728
+ composed: true,
729
+ }));
730
+ }
731
+ static flowCompleted() {
732
+ sessionStorage.clear();
733
+ this.callingModule.dispatchEvent(new CustomEvent('ect-completed', {
734
+ detail: {},
735
+ bubbles: true,
736
+ cancelable: true,
737
+ composed: true,
738
+ }));
739
+ }
740
+ static flowError(error) {
741
+ sessionStorage.clear();
742
+ this.callingModule.dispatchEvent(new CustomEvent('ect-error', {
743
+ detail: { error },
744
+ bubbles: true,
745
+ cancelable: true,
746
+ composed: true,
747
+ }));
748
+ }
749
+ static tokenExpired() {
750
+ sessionStorage.clear();
751
+ this.callingModule.dispatchEvent(new CustomEvent('ect-session-expired', {
752
+ detail: {},
753
+ bubbles: true,
754
+ cancelable: true,
755
+ composed: true,
756
+ }));
757
+ }
758
+ }
759
+
760
+ class BaseComponent {
761
+ constructor(step) {
762
+ this.apiErrorEvent = null;
763
+ this.processError = null;
764
+ this.apiCall = new ApiCall();
765
+ if (step)
766
+ this.flowStep = step;
767
+ if (!state.device) {
768
+ state.device = new DeviceDetection().getDevice();
769
+ }
770
+ Events.init(window);
771
+ }
772
+ setEventEmitter(event) {
773
+ this.apiErrorEvent = event;
774
+ }
775
+ setErrorCallback(callback) {
776
+ this.processError = callback;
777
+ }
778
+ async initialize() {
779
+ Events.flowEvent(this.flowStep, FlowMoments.Initialized);
780
+ try {
781
+ await this.apiCall.AddStep(this.flowStep, FlowMoments.Initialized);
782
+ }
783
+ catch (e) {
784
+ if (this.apiErrorEvent)
785
+ this.apiErrorEvent.emit(e);
786
+ else
787
+ this.processError(e, FlowMoments.Initialized);
788
+ }
789
+ }
790
+ async finalize() {
791
+ Events.flowEvent(this.flowStep, FlowMoments.Finalized);
792
+ try {
793
+ await this.apiCall.AddStep(this.flowStep, FlowMoments.Finalized);
794
+ }
795
+ catch (e) {
796
+ if (this.apiErrorEvent)
797
+ this.apiErrorEvent.emit(e);
798
+ else
799
+ this.processError(e, FlowMoments.Initialized);
800
+ }
801
+ }
802
+ }
803
+
587
804
  const agreementInfoCss = "";
588
805
 
589
806
  const AgreementInfo = class {
@@ -594,24 +811,21 @@ const AgreementInfo = class {
594
811
  this.termsChecked = undefined;
595
812
  this.openAgreements = undefined;
596
813
  this.openTerms = undefined;
814
+ this.baseComponent = new BaseComponent(FlowSteps.Agreements);
815
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
597
816
  this.agreementsChecked = false;
598
817
  this.termsChecked = false;
599
- this.apiCall = new ApiCall();
600
818
  }
601
819
  async componentDidLoad() {
602
- try {
603
- await this.apiCall.AddStep(FlowSteps.Agreements);
604
- }
605
- catch (e) {
606
- this.apiErrorEvent.emit(e);
607
- }
820
+ await this.baseComponent.initialize();
608
821
  }
609
822
  componentWillLoad() {
610
823
  this.openAgreements = false;
611
824
  this.openTerms = false;
612
825
  }
613
- buttonClick() {
826
+ async buttonClick() {
614
827
  if (this.agreementsChecked && this.termsChecked) {
828
+ await this.baseComponent.finalize();
615
829
  state.flowStatus = FlowStatus.PHONE;
616
830
  }
617
831
  }
@@ -4909,7 +5123,7 @@ class Stream {
4909
5123
  setVerificationFinished(fun) {
4910
5124
  this.verificationFinished = fun;
4911
5125
  }
4912
- constructor(device, _modelPath) {
5126
+ constructor(_modelPath) {
4913
5127
  this.streamPaused = false;
4914
5128
  this.recordedChunks = [];
4915
5129
  this.videoSize = { width: 0, height: 0 };
@@ -4920,13 +5134,12 @@ class Stream {
4920
5134
  // this.dropMask();
4921
5135
  // if (this.faceDetection) Detector.getInstance().stopDetector();
4922
5136
  };
4923
- this.device = device;
4924
- this.idML5Detector = IDML5Detector.getInstance(this, device.isMobile);
4925
- this.faceML5Detector = FaceML5Detector.getInstance(this, device.isMobile);
5137
+ this.idML5Detector = IDML5Detector.getInstance(this, state.device.isMobile);
5138
+ this.faceML5Detector = FaceML5Detector.getInstance(this, state.device.isMobile);
4926
5139
  }
4927
- static getInstance(device, modelPath) {
5140
+ static getInstance(modelPath) {
4928
5141
  if (!Stream.instance) {
4929
- Stream.instance = new Stream(device, modelPath);
5142
+ Stream.instance = new Stream(modelPath);
4930
5143
  }
4931
5144
  return Stream.instance;
4932
5145
  }
@@ -4987,7 +5200,7 @@ class Stream {
4987
5200
  recordStream() {
4988
5201
  var options = { mimeType: Stream.webmMimeType.mime, videoBitsPerSecond: 1500000 };
4989
5202
  if (!MediaRecorder.isTypeSupported(options.mimeType)) {
4990
- if (this.device.isIos || this.device.isSafari)
5203
+ if (state.device.mobileOS == MobileOS.iOS || state.device.browser == Browser.Safari)
4991
5204
  options.mimeType = Stream.mp4MimeType.mime;
4992
5205
  }
4993
5206
  this.recordedChunks = [];
@@ -5042,7 +5255,7 @@ class Stream {
5042
5255
  const context = canvas.getContext('2d');
5043
5256
  context.drawImage(this.videoElement, 0, 0, canvas.width, canvas.height);
5044
5257
  canvas.toBlob((frame) => {
5045
- if (frame.type === ImageFormat.JPEG && !this.device.isIos) {
5258
+ if (frame.type === ImageFormat.JPEG && !state.device.isAppleDevice) {
5046
5259
  try {
5047
5260
  addExifInImg(frame, this.stream.getTracks()[0], this.videoSize).then(updatedFrame => resolve(updatedFrame));
5048
5261
  }
@@ -5135,7 +5348,6 @@ const Camera = class {
5135
5348
  this.verificationFinished.emit();
5136
5349
  };
5137
5350
  this.modelPath = undefined;
5138
- this.device = undefined;
5139
5351
  this.probabilityThreshold = undefined;
5140
5352
  this.captureMode = undefined;
5141
5353
  }
@@ -5145,7 +5357,7 @@ const Camera = class {
5145
5357
  render() {
5146
5358
  let cameraVideoClass = 'cameraVideo';
5147
5359
  let cameraCanvasClass = 'cameraCanvas';
5148
- if (this.device.isWin) {
5360
+ if (state.device.isDesktop) {
5149
5361
  cameraVideoClass = 'cameraVideoSelfieDesk';
5150
5362
  cameraCanvasClass = 'cameraCanvasSelfieDesk';
5151
5363
  }
@@ -5157,7 +5369,7 @@ const Camera = class {
5157
5369
  }
5158
5370
  startStream() {
5159
5371
  if (!Stream.instance)
5160
- Stream.getInstance(this.device, this.modelPath);
5372
+ Stream.getInstance(this.modelPath);
5161
5373
  const stream = Stream.getInstance();
5162
5374
  stream.updateHtmlElements(this.cameraVideo, this.cameraCanvas, this.component);
5163
5375
  if (this.captureMode == 'selfie') {
@@ -5189,12 +5401,12 @@ const CameraError = class {
5189
5401
  constructor(hostRef) {
5190
5402
  index.registerInstance(this, hostRef);
5191
5403
  this.apiErrorEvent = index.createEvent(this, "apiError", 7);
5192
- this.device = undefined;
5193
5404
  this.title = undefined;
5194
5405
  this.description = undefined;
5195
5406
  this.buttonDisabled = undefined;
5196
5407
  this.demoVideo = undefined;
5197
- this.apiCall = new ApiCall();
5408
+ this.baseComponent = new BaseComponent(FlowSteps.CameraError);
5409
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
5198
5410
  }
5199
5411
  async componentWillLoad() {
5200
5412
  this.buttonDisabled = false;
@@ -5203,7 +5415,8 @@ const CameraError = class {
5203
5415
  this.buttonText = CameraErrorValues.Button;
5204
5416
  }
5205
5417
  async componentDidLoad() {
5206
- if (!this.device.isIos) {
5418
+ await this.baseComponent.initialize();
5419
+ if (state.device.mobileOS != MobileOS.iOS) {
5207
5420
  this.demoVideo.src = CameraErrorValues.HowToLink;
5208
5421
  this.demoVideo.loop = true;
5209
5422
  this.demoVideo.play();
@@ -5215,16 +5428,11 @@ const CameraError = class {
5215
5428
  state.flowStatus = FlowStatus.LANDING;
5216
5429
  }
5217
5430
  }
5218
- try {
5219
- await this.apiCall.AddStep(FlowSteps.CameraError);
5220
- }
5221
- catch (e) {
5222
- this.apiErrorEvent.emit(e);
5223
- }
5224
5431
  }
5225
5432
  async buttonClick() {
5226
5433
  this.buttonDisabled = true;
5227
- if (this.device.isIos) {
5434
+ await this.baseComponent.finalize();
5435
+ if (state.device.mobileOS == MobileOS.iOS) {
5228
5436
  sessionStorage.setItem(SessionKeys.RefreshDoneKey, 'true');
5229
5437
  window.location.reload();
5230
5438
  }
@@ -5233,7 +5441,7 @@ const CameraError = class {
5233
5441
  }
5234
5442
  }
5235
5443
  render() {
5236
- return (index.h("div", { class: "container" }, index.h("div", { class: "row" }, index.h("h1", { class: "color-red" }, this.title), index.h("div", null, index.h("p", { class: "color-red font-weight-bold font-size-25 mt-5" }, this.description)), index.h("div", { hidden: this.device.isIos }, index.h("video", { id: "howtoPermissions", class: "video-demo", playsinline: true, ref: el => (this.demoVideo = el) }, index.h("source", { type: "video/mp4" }))), index.h("div", { class: "pos-relative show-bottom" }, index.h("div", { class: "btn-buletin" }, index.h("button", { class: "main-button", type: "button", disabled: this.buttonDisabled, onClick: () => this.buttonClick() }, this.buttonText), index.h("p", { class: "main-text font-size-18 text-right mb-0" }, CameraErrorValues.FooterText))))));
5444
+ return (index.h("div", { class: "container" }, index.h("div", { class: "row" }, index.h("h1", { class: "color-red" }, this.title), index.h("div", null, index.h("p", { class: "color-red font-weight-bold font-size-25 mt-5" }, this.description)), index.h("div", { hidden: state.device.mobileOS == MobileOS.iOS }, index.h("video", { id: "howtoPermissions", class: "video-demo", playsinline: true, ref: el => (this.demoVideo = el) }, index.h("source", { type: "video/mp4" }))), index.h("div", { class: "pos-relative show-bottom" }, index.h("div", { class: "btn-buletin" }, index.h("button", { class: "main-button", type: "button", disabled: this.buttonDisabled, onClick: () => this.buttonClick() }, this.buttonText), index.h("p", { class: "main-text font-size-18 text-right mb-0" }, CameraErrorValues.FooterText))))));
5237
5445
  }
5238
5446
  };
5239
5447
  CameraError.style = cameraErrorCss;
@@ -5283,74 +5491,19 @@ CaptureError.style = captureErrorCss;
5283
5491
 
5284
5492
  const completeSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODMiIGhlaWdodD0iODQiIHZpZXdCb3g9IjAgMCA4MyA4NCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxwYXRoIGQ9Ik00MS41IDgzLjcwNjJDMzAuNDE0NyA4My43MDYyIDE5Ljk5MjkgNzkuMzgwNCAxMi4xNTQ2IDcxLjUyNUM0LjMxNjQxIDYzLjY2OTcgMCA1My4yMjUxIDAgNDIuMTE1NkMwIDMxLjAwNjEgNC4zMTY0MSAyMC41NjE1IDEyLjE1NDYgMTIuNzA2MUMxOS45OTI5IDQuODUwNzUgMzAuNDE0NyAwLjUyNDkwMiA0MS41IDAuNTI0OTAyQzUyLjU4NTMgMC41MjQ5MDIgNjMuMDA3MSA0Ljg1MDc1IDcwLjg0NTMgMTIuNzA2MUM3OC42ODM2IDIwLjU2MTUgODMgMzEuMDA2MSA4MyA0Mi4xMTU2QzgzIDUzLjIyNTEgNzguNjgzNiA2My42Njk3IDcwLjg0NTMgNzEuNTI1QzYzLjAwNzEgNzkuMzgwNCA1Mi41ODUzIDgzLjcwNjIgNDEuNSA4My43MDYyWk00MS41IDQuNzYzMTNDMjAuOTQ4MyA0Ljc2MzEzIDQuMjI4OTkgMjEuNTE4OSA0LjIyODk5IDQyLjExNTZDNC4yMjg5OSA2Mi43MTIyIDIwLjk0ODMgNzkuNDY4IDQxLjUgNzkuNDY4QzYyLjA1MTcgNzkuNDY4IDc4Ljc3MSA2Mi43MTIyIDc4Ljc3MSA0Mi4xMTU2Qzc4Ljc3MSAyMS41MTg5IDYyLjA1MTcgNC43NjMxMyA0MS41IDQuNzYzMTNaIiBmaWxsPSIjNURDMUFDIi8+DQo8cGF0aCBkPSJNMzcuNDY3NiA2Mi42NjJIMzcuNDYzQzM0Ljk2MDUgNjIuNjYyIDMyLjYwOTUgNjEuNjgyNiAzMC44NDA4IDU5LjkwODRMMTguOTQzOCA0Ny45NjY2QzE1LjMwMDIgNDQuMzA4OCAxNS4zMDE3IDM4LjM1NzQgMTguOTUgMzQuNzAyOEMyMC43MjM0IDMyLjkyNTUgMjMuMDc0NCAzMS45NTA4IDI1LjU3NTMgMzEuOTUwOEMyOC4wNzYxIDMxLjk1MDggMzAuNDI3MSAzMi45MjcxIDMyLjE5NTggMzQuNjk5NkwzNy40ODE3IDM5Ljk5N0w1MC44MTAzIDI2LjYzOTNDNTQuNDYwMSAyMi45ODE1IDYwLjQgMjIuOTgxNSA2NC4wNTE0IDI2LjYzOTNDNjcuNzAxMyAzMC4yOTcxIDY3LjcwMTMgMzYuMjUwMSA2NC4wNTE0IDM5LjkwOTRMNDQuMDg4MiA1OS45MTYzQzQyLjMxOTUgNjEuNjg4OCAzOS45Njg1IDYyLjY2NTEgMzcuNDY3NiA2Mi42NjUxVjYyLjY2MlpNMjUuNTc1MyAzNi4xODlDMjQuMjA0NiAzNi4xODkgMjIuOTE1MiAzNi43MjQxIDIxLjk0NTcgMzcuNjk1N0MxOS45NDEzIDM5LjcwNDUgMTkuOTQxMyA0Mi45NjQ5IDIxLjkzNzkgNDQuOTcwNkwzMy44MzUgNTYuOTEyNEMzNC44MDQ0IDU3Ljg4NTUgMzYuMDkzOSA1OC40MjIyIDM3LjQ2NDUgNTguNDIyMkgzNy40NjYxQzM4LjgzNjcgNTguNDIyMiA0MC4xMjYyIDU3Ljg4NzEgNDEuMDk1NiA1Ni45MTU1TDYxLjA1ODggMzYuOTA4N0M2My4wNjAxIDM0LjkwMyA2My4wNjAxIDMxLjYzOTUgNjEuMDU4OCAyOS42MzM4QzU5LjA1NzUgMjcuNjI4MSA1NS44MDExIDI3LjYyODEgNTMuNzk5NyAyOS42MzM4TDUyLjMwNDIgMjguMTM1TDUzLjc5OTcgMjkuNjMzOEwzOC45NzU3IDQ0LjQ5MDNDMzguMTQ5OCA0NS4zMTc5IDM2LjgxMDQgNDUuMzE3OSAzNS45ODQ2IDQ0LjQ5MDNMMjkuMjAzMiAzNy42OTQxQzI4LjIzMzggMzYuNzIyNSAyNi45NDQzIDM2LjE4NzUgMjUuNTczNyAzNi4xODc1TDI1LjU3NTMgMzYuMTg5WiIgZmlsbD0iIzVEQzFBQyIvPg0KPC9zdmc+DQo=';
5285
5493
 
5286
- class Events {
5287
- static init(element) {
5288
- this.callingModule = element;
5289
- }
5290
- static flowStarted() {
5291
- this.callingModule.dispatchEvent(new CustomEvent('ect-started', {
5292
- detail: {},
5293
- bubbles: true,
5294
- cancelable: true,
5295
- composed: true,
5296
- }));
5297
- }
5298
- static flowAborted() {
5299
- sessionStorage.clear();
5300
- this.callingModule.dispatchEvent(new CustomEvent('ect-aborted', {
5301
- detail: {},
5302
- bubbles: true,
5303
- cancelable: true,
5304
- composed: true,
5305
- }));
5306
- }
5307
- static flowCompleted() {
5308
- sessionStorage.clear();
5309
- this.callingModule.dispatchEvent(new CustomEvent('ect-completed', {
5310
- detail: {},
5311
- bubbles: true,
5312
- cancelable: true,
5313
- composed: true,
5314
- }));
5315
- }
5316
- static flowError(error) {
5317
- sessionStorage.clear();
5318
- this.callingModule.dispatchEvent(new CustomEvent('ect-error', {
5319
- detail: { error },
5320
- bubbles: true,
5321
- cancelable: true,
5322
- composed: true,
5323
- }));
5324
- }
5325
- static tokenExpired() {
5326
- sessionStorage.clear();
5327
- this.callingModule.dispatchEvent(new CustomEvent('ect-session-expired', {
5328
- detail: {},
5329
- bubbles: true,
5330
- cancelable: true,
5331
- composed: true,
5332
- }));
5333
- }
5334
- }
5335
-
5336
5494
  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)}}";
5337
5495
 
5338
5496
  const EndRedirect = class {
5339
5497
  constructor(hostRef) {
5340
5498
  index.registerInstance(this, hostRef);
5341
5499
  this.apiErrorEvent = index.createEvent(this, "apiError", 7);
5342
- this.apiCall = new ApiCall();
5500
+ this.baseComponent = new BaseComponent(FlowSteps.End);
5501
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
5343
5502
  }
5344
5503
  async componentDidLoad() {
5345
- Events.init(window);
5346
5504
  Events.flowCompleted();
5347
5505
  if (state.environment !== 'DEMO') {
5348
- try {
5349
- await this.apiCall.AddStep(FlowSteps.End);
5350
- }
5351
- catch (e) {
5352
- this.apiErrorEvent.emit(e);
5353
- }
5506
+ await this.baseComponent.initialize();
5354
5507
  }
5355
5508
  }
5356
5509
  render() {
@@ -5432,7 +5585,7 @@ class Cameras {
5432
5585
  const stream = await navigator.mediaDevices.getUserMedia(updatedConstraints);
5433
5586
  stream.getVideoTracks().forEach(track => {
5434
5587
  var _a, _b;
5435
- if (deviceInfo.isFirefox) {
5588
+ if (deviceInfo.browser === Browser.Firefox) {
5436
5589
  const settings = track.getSettings();
5437
5590
  let facingMode = settings.facingMode && settings.facingMode.length > 0 ? settings.facingMode[0] : '';
5438
5591
  facingMode = facingMode === 'e' ? 'environment' : facingMode;
@@ -5498,7 +5651,7 @@ class Cameras {
5498
5651
  exact: selectedDeviceId,
5499
5652
  };
5500
5653
  }
5501
- if (device.isWin) {
5654
+ if (device.isDesktop) {
5502
5655
  constraints.video.width = { ideal: 1280 };
5503
5656
  }
5504
5657
  else {
@@ -5554,7 +5707,6 @@ const IdBackCapture = class {
5554
5707
  //this.closeCamera();
5555
5708
  this.eventPhotoCapture.emit(photos);
5556
5709
  };
5557
- this.device = undefined;
5558
5710
  this.videoStarted = undefined;
5559
5711
  this.cameraSize = undefined;
5560
5712
  this.captureTaken = undefined;
@@ -5599,7 +5751,7 @@ const IdBackCapture = class {
5599
5751
  this.openCamera();
5600
5752
  }
5601
5753
  async openCamera() {
5602
- var constraints = this.cameras.GetConstraints(state.cameraId, this.device);
5754
+ var constraints = this.cameras.GetConstraints(state.cameraId, state.device);
5603
5755
  setTimeout(() => {
5604
5756
  navigator.mediaDevices
5605
5757
  .getUserMedia(constraints)
@@ -5652,7 +5804,7 @@ const IdBackCapture = class {
5652
5804
  let titleClass = this.verified ? 'color-black-2 text-center' : 'color-white text-center';
5653
5805
  //let videoClass = this.device.isMobile ? '' : 'video-demo';
5654
5806
  let bgDemo = this.verified ? 'container' : 'container bg-black';
5655
- return (index.h("div", { class: bgDemo }, index.h("div", { class: "container-video" }, index.h("div", { hidden: this.showDemo == false }, index.h("video", { id: "howtoBack", class: "video-demo", playsinline: true, ref: el => (this.demoVideo = el) }, index.h("source", { type: "video/mp4" }))), index.h("div", { hidden: this.showDemo }, index.h("div", { hidden: this.verified }, index.h("div", { class: "video-capture" }, index.h("div", { style: cameraStyle }, index.h("div", { style: cameraStyleInner }, index.h("camera-comp", { device: this.device, "capture-mode": "id" })))))), index.h("div", { class: "capture-title" }, index.h("h1", { class: titleClass }, this.titleMesage), index.h("p", { class: "main-text font-size-18 text-right mb-0" }, IdCaptureValues.FooterText)))));
5807
+ return (index.h("div", { class: bgDemo }, index.h("div", { class: "container-video" }, index.h("div", { hidden: this.showDemo == false }, index.h("video", { id: "howtoBack", class: "video-demo", playsinline: true, ref: el => (this.demoVideo = el) }, index.h("source", { type: "video/mp4" }))), index.h("div", { hidden: this.showDemo }, index.h("div", { hidden: this.verified }, index.h("div", { class: "video-capture" }, index.h("div", { style: cameraStyle }, index.h("div", { style: cameraStyleInner }, index.h("camera-comp", { "capture-mode": "id" })))))), index.h("div", { class: "capture-title" }, index.h("h1", { class: titleClass }, this.titleMesage), index.h("p", { class: "main-text font-size-18 text-right mb-0" }, IdCaptureValues.FooterText)))));
5656
5808
  }
5657
5809
  get component() { return index.getElement(this); }
5658
5810
  };
@@ -5669,7 +5821,6 @@ const IdCapture = class {
5669
5821
  //this.closeCamera();
5670
5822
  this.eventPhotoCapture.emit(photos);
5671
5823
  };
5672
- this.device = undefined;
5673
5824
  this.videoStarted = undefined;
5674
5825
  this.cameraSize = undefined;
5675
5826
  this.captureTaken = undefined;
@@ -5710,7 +5861,7 @@ const IdCapture = class {
5710
5861
  this.openCamera();
5711
5862
  }
5712
5863
  async openCamera() {
5713
- var constraints = this.cameras.GetConstraints(state.cameraId, this.device);
5864
+ var constraints = this.cameras.GetConstraints(state.cameraId, state.device);
5714
5865
  setTimeout(() => {
5715
5866
  navigator.mediaDevices
5716
5867
  .getUserMedia(constraints)
@@ -5768,7 +5919,7 @@ const IdCapture = class {
5768
5919
  let titleClass = this.verified ? 'color-black-2 text-center' : 'color-white text-center';
5769
5920
  //let videoClass = this.device.isMobile ? '' : 'video-demo';
5770
5921
  let bgDemo = this.verified ? 'container' : 'container bg-black';
5771
- return (index.h("div", { class: bgDemo }, index.h("div", { class: "container-video" }, index.h("div", { hidden: this.showDemo == false }, index.h("video", { id: "howtoFront", class: "video-demo", playsinline: true, ref: el => (this.demoVideo = el) }, index.h("source", { type: "video/mp4" }))), index.h("div", { hidden: this.showDemo }, index.h("div", { hidden: this.verified }, index.h("div", { class: "video-capture" }, index.h("div", { style: cameraStyle }, index.h("div", { style: cameraStyleInner }, index.h("camera-comp", { device: this.device, "capture-mode": "id" })))))), index.h("div", { class: "capture-title" }, index.h("h1", { class: titleClass }, this.titleMesage), index.h("p", { class: "main-text font-size-18 text-right mb-0" }, IdCaptureValues.FooterText)))));
5922
+ return (index.h("div", { class: bgDemo }, index.h("div", { class: "container-video" }, index.h("div", { hidden: this.showDemo == false }, index.h("video", { id: "howtoFront", class: "video-demo", playsinline: true, ref: el => (this.demoVideo = el) }, index.h("source", { type: "video/mp4" }))), index.h("div", { hidden: this.showDemo }, index.h("div", { hidden: this.verified }, index.h("div", { class: "video-capture" }, index.h("div", { style: cameraStyle }, index.h("div", { style: cameraStyleInner }, index.h("camera-comp", { "capture-mode": "id" })))))), index.h("div", { class: "capture-title" }, index.h("h1", { class: titleClass }, this.titleMesage), index.h("p", { class: "main-text font-size-18 text-right mb-0" }, IdCaptureValues.FooterText)))));
5772
5923
  }
5773
5924
  get component() { return index.getElement(this); }
5774
5925
  };
@@ -5780,7 +5931,6 @@ const IdDoubleSide = class {
5780
5931
  constructor(hostRef) {
5781
5932
  index.registerInstance(this, hostRef);
5782
5933
  this.apiErrorEvent = index.createEvent(this, "apiError", 7);
5783
- this.device = undefined;
5784
5934
  this.showTimeout = undefined;
5785
5935
  this.showInvalid = undefined;
5786
5936
  this.showHowTo = undefined;
@@ -5796,7 +5946,8 @@ const IdDoubleSide = class {
5796
5946
  recordingFileName: '',
5797
5947
  recordingUploadType: '',
5798
5948
  };
5799
- this.apiCall = new ApiCall();
5949
+ this.baseComponent = new BaseComponent(FlowSteps.CiBack);
5950
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
5800
5951
  }
5801
5952
  componentWillLoad() {
5802
5953
  this.captureRetryCount = 0;
@@ -5833,7 +5984,7 @@ const IdDoubleSide = class {
5833
5984
  async captureIdImage(event) {
5834
5985
  let idPhoto = event.detail;
5835
5986
  if (idPhoto.length == 0 || idPhoto.size == 0) {
5836
- await this.apiCall.AddLog({ message: 'Empty id photo', blobData: idPhoto }, getLogMessage());
5987
+ await this.baseComponent.apiCall.AddLog({ message: 'Empty id photo', blobData: idPhoto }, getLogMessage());
5837
5988
  return;
5838
5989
  }
5839
5990
  try {
@@ -5847,7 +5998,7 @@ const IdDoubleSide = class {
5847
5998
  async captureIdBackImage(event) {
5848
5999
  let idPhoto = event.detail;
5849
6000
  if (idPhoto.length == 0 || idPhoto.size == 0) {
5850
- await this.apiCall.AddLog({ message: 'Empty id photo', blobData: idPhoto }, getLogMessage());
6001
+ await this.baseComponent.apiCall.AddLog({ message: 'Empty id photo', blobData: idPhoto }, getLogMessage());
5851
6002
  return;
5852
6003
  }
5853
6004
  try {
@@ -5861,7 +6012,7 @@ const IdDoubleSide = class {
5861
6012
  async capturedIdRecording(event) {
5862
6013
  let idRecording = event.detail;
5863
6014
  if (idRecording.length == 0 || idRecording.size == 0) {
5864
- await this.apiCall.AddLog({ message: 'Empty recording', blobData: idRecording }, getLogMessage());
6015
+ await this.baseComponent.apiCall.AddLog({ message: 'Empty recording', blobData: idRecording }, getLogMessage());
5865
6016
  return;
5866
6017
  }
5867
6018
  let mimeType = idRecording.type == Stream.mp4MimeType.type ? Stream.mp4MimeType : Stream.webmMimeType;
@@ -5870,51 +6021,53 @@ const IdDoubleSide = class {
5870
6021
  this.uploadRecording();
5871
6022
  }
5872
6023
  catch (e) {
5873
- this.apiErrorEvent.emit(e);
6024
+ if (state.recordingRetryCount < 3) {
6025
+ state.recordingRetryCount++;
6026
+ this.triggerErrorFlow();
6027
+ }
6028
+ else {
6029
+ this.apiErrorEvent.emit(e);
6030
+ }
5874
6031
  }
5875
6032
  }
5876
6033
  async verificationFinished(_event) {
5877
6034
  this.flow.verificationFinished = true;
5878
- this.endFlow();
6035
+ await this.endFlow();
5879
6036
  }
5880
6037
  async componentDidLoad() {
5881
- try {
5882
- await this.apiCall.AddStep(FlowSteps.CiBack);
5883
- }
5884
- catch (e) {
5885
- this.apiErrorEvent.emit(e);
5886
- }
6038
+ await this.baseComponent.initialize();
5887
6039
  }
5888
6040
  async uploadPhoto() {
5889
6041
  if (this.flow.photoFile == null || this.flow.photoDone) {
5890
6042
  return;
5891
6043
  }
5892
- this.flow.photoDone = await this.apiCall.UploadFileForRequestB64(state.requestId, this.flow.photoUploadType, this.flow.photoFile);
6044
+ this.flow.photoDone = await this.baseComponent.apiCall.UploadFileForRequestB64(state.requestId, this.flow.photoUploadType, this.flow.photoFile);
5893
6045
  if (this.flow.photoDone) {
5894
- this.endFlow();
6046
+ await this.endFlow();
5895
6047
  }
5896
6048
  else {
5897
- this.flow.photoFile = null;
5898
- this.flow.recordingFile = null;
5899
6049
  this.switchCamera();
5900
- this.showInvalid = true;
6050
+ this.triggerErrorFlow();
5901
6051
  }
5902
6052
  }
5903
6053
  async uploadRecording() {
5904
6054
  if (this.flow.recordingFile == null || this.flow.recordingDone) {
5905
6055
  return;
5906
6056
  }
5907
- this.flow.recordingDone = await this.apiCall.UploadFileForRequestB64(state.requestId, this.flow.recordingUploadType, this.flow.recordingFile);
6057
+ this.flow.recordingDone = await this.baseComponent.apiCall.UploadFileForRequestB64(state.requestId, this.flow.recordingUploadType, this.flow.recordingFile);
5908
6058
  if (this.flow.recordingDone) {
5909
- this.endFlow();
6059
+ await this.endFlow();
5910
6060
  }
5911
6061
  else {
5912
- this.flow.photoFile = null;
5913
- this.flow.recordingFile = null;
5914
- this.showInvalid = true;
6062
+ this.triggerErrorFlow();
5915
6063
  }
5916
6064
  }
5917
- endFlow() {
6065
+ triggerErrorFlow() {
6066
+ this.flow.photoFile = null;
6067
+ this.flow.recordingFile = null;
6068
+ this.showInvalid = true;
6069
+ }
6070
+ async endFlow() {
5918
6071
  if (!this.flow.photoDone) {
5919
6072
  return;
5920
6073
  }
@@ -5937,6 +6090,8 @@ const IdDoubleSide = class {
5937
6090
  if (!this.flow.verificationFinished) {
5938
6091
  return;
5939
6092
  }
6093
+ state.recordingRetryCount = 0;
6094
+ await this.baseComponent.finalize();
5940
6095
  state.flowStatus = FlowStatus.LIVENESS;
5941
6096
  }
5942
6097
  switchCamera() {
@@ -5951,8 +6106,8 @@ const IdDoubleSide = class {
5951
6106
  }
5952
6107
  render() {
5953
6108
  let error = index.h("capture-error", { type: "ID" });
5954
- let frontCapture = index.h("id-capture", { id: "idFront", device: this.device });
5955
- let secondCapture = index.h("id-back-capture", { id: "idBack", device: this.device });
6109
+ let frontCapture = index.h("id-capture", { id: "idFront" });
6110
+ let secondCapture = index.h("id-back-capture", { id: "idBack" });
5956
6111
  let howToInfo = index.h("how-to-info", { idSide: this.front ? 'front' : 'back' });
5957
6112
  return this.showHowTo ? howToInfo : this.showInvalid || this.showTimeout ? error : this.front ? frontCapture : secondCapture;
5958
6113
  }
@@ -5965,7 +6120,6 @@ const IdSingleSide = class {
5965
6120
  constructor(hostRef) {
5966
6121
  index.registerInstance(this, hostRef);
5967
6122
  this.apiErrorEvent = index.createEvent(this, "apiError", 7);
5968
- this.device = undefined;
5969
6123
  this.showTimeout = undefined;
5970
6124
  this.showHowTo = undefined;
5971
6125
  this.idFlow = {
@@ -5975,7 +6129,8 @@ const IdSingleSide = class {
5975
6129
  photoFile: null,
5976
6130
  recordingFile: null,
5977
6131
  };
5978
- this.apiCall = new ApiCall();
6132
+ this.baseComponent = new BaseComponent(FlowSteps.CiFront);
6133
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
5979
6134
  this.captureRetryCount = 0;
5980
6135
  this.showHowTo = true;
5981
6136
  }
@@ -5993,7 +6148,7 @@ const IdSingleSide = class {
5993
6148
  async captureIdImage(event) {
5994
6149
  let idPhoto = event.detail;
5995
6150
  if (idPhoto.length == 0 || idPhoto.size == 0) {
5996
- await this.apiCall.AddLog({ message: 'Empty id photo', blobData: idPhoto }, getLogMessage());
6151
+ await this.baseComponent.apiCall.AddLog({ message: 'Empty id photo', blobData: idPhoto }, getLogMessage());
5997
6152
  return;
5998
6153
  }
5999
6154
  try {
@@ -6006,12 +6161,12 @@ const IdSingleSide = class {
6006
6161
  }
6007
6162
  async verificationFinished(_event) {
6008
6163
  this.idFlow.verificationFinished = true;
6009
- this.endFlow();
6164
+ await this.endFlow();
6010
6165
  }
6011
6166
  async capturedIdRecording(event) {
6012
6167
  let idRecording = event.detail;
6013
6168
  if (idRecording.length == 0 || idRecording.size == 0) {
6014
- await this.apiCall.AddLog({ message: 'Empty recording', blobData: idRecording }, getLogMessage());
6169
+ await this.baseComponent.apiCall.AddLog({ message: 'Empty recording', blobData: idRecording }, getLogMessage());
6015
6170
  return;
6016
6171
  }
6017
6172
  let mimeType = idRecording.type == Stream.mp4MimeType.type ? Stream.mp4MimeType : Stream.webmMimeType;
@@ -6026,20 +6181,15 @@ const IdSingleSide = class {
6026
6181
  }
6027
6182
  }
6028
6183
  async componentDidLoad() {
6029
- try {
6030
- await this.apiCall.AddStep(FlowSteps.CiFront);
6031
- }
6032
- catch (e) {
6033
- this.apiErrorEvent.emit(e);
6034
- }
6184
+ await this.baseComponent.initialize();
6035
6185
  }
6036
6186
  async uploadPhoto() {
6037
6187
  if (this.idFlow.photoFile == null || this.idFlow.photoDone) {
6038
6188
  return;
6039
6189
  }
6040
- this.idFlow.photoDone = await this.apiCall.UploadFileForRequestB64(state.requestId, 'IdFront', this.idFlow.photoFile);
6190
+ this.idFlow.photoDone = await this.baseComponent.apiCall.UploadFileForRequestB64(state.requestId, 'IdFront', this.idFlow.photoFile);
6041
6191
  if (this.idFlow.photoDone) {
6042
- this.endFlow();
6192
+ await this.endFlow();
6043
6193
  }
6044
6194
  else {
6045
6195
  this.idFlow.photoFile = null;
@@ -6052,9 +6202,9 @@ const IdSingleSide = class {
6052
6202
  if (this.idFlow.recordingFile == null || this.idFlow.recordingDone) {
6053
6203
  return;
6054
6204
  }
6055
- this.idFlow.recordingDone = await this.apiCall.UploadFileForRequestB64(state.requestId, 'IdFrontVideo', this.idFlow.recordingFile);
6205
+ this.idFlow.recordingDone = await this.baseComponent.apiCall.UploadFileForRequestB64(state.requestId, 'IdFrontVideo', this.idFlow.recordingFile);
6056
6206
  if (this.idFlow.recordingDone) {
6057
- this.endFlow();
6207
+ await this.endFlow();
6058
6208
  }
6059
6209
  else {
6060
6210
  this.idFlow.photoFile = null;
@@ -6062,7 +6212,7 @@ const IdSingleSide = class {
6062
6212
  this.showTimeout = true;
6063
6213
  }
6064
6214
  }
6065
- endFlow() {
6215
+ async endFlow() {
6066
6216
  if (!this.idFlow.photoDone) {
6067
6217
  return;
6068
6218
  }
@@ -6072,6 +6222,7 @@ const IdSingleSide = class {
6072
6222
  if (!this.idFlow.verificationFinished) {
6073
6223
  return;
6074
6224
  }
6225
+ await this.baseComponent.finalize();
6075
6226
  state.flowStatus = FlowStatus.LIVENESS;
6076
6227
  }
6077
6228
  switchCamera() {
@@ -6086,47 +6237,13 @@ const IdSingleSide = class {
6086
6237
  }
6087
6238
  render() {
6088
6239
  let error = index.h("capture-error", { type: "ID" });
6089
- let capture = index.h("id-capture", { id: "idFront", device: this.device });
6240
+ let capture = index.h("id-capture", { id: "idFront" });
6090
6241
  let howToInfo = index.h("how-to-info", { idSide: "front" });
6091
6242
  return this.showHowTo ? howToInfo : this.showTimeout ? error : capture;
6092
6243
  }
6093
6244
  };
6094
6245
  IdSingleSide.style = idSingleSideCss;
6095
6246
 
6096
- const initDevice = () => {
6097
- let device = {
6098
- isMobile: false,
6099
- isAndroid: false,
6100
- isLinux: false,
6101
- isMac: false,
6102
- isWin: false,
6103
- isChrome: false,
6104
- isFirefox: false,
6105
- isSafari: false,
6106
- isIos: false,
6107
- };
6108
- device.isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
6109
- device.isAndroid = /Android/i.test(navigator.userAgent);
6110
- device.isIos = /iPhone|iPad|iPod/i.test(navigator.userAgent);
6111
- device.isLinux = /linux/i.test(navigator.platform);
6112
- device.isMac = /mac/i.test(navigator.platform);
6113
- device.isWin = /win/i.test(navigator.platform);
6114
- device.isChrome = /chrome/i.test(navigator.userAgent);
6115
- device.isFirefox = /firefox/i.test(navigator.userAgent);
6116
- device.isSafari = !device.isChrome ? /safari/i.test(navigator.userAgent) : false;
6117
- device.isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
6118
- device.isAndroid = /Android/i.test(navigator.userAgent);
6119
- device.isIos = /iPhone|iPad|iPod/i.test(navigator.userAgent);
6120
- if (!device.isIos) {
6121
- const isIPad = navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints && navigator.maxTouchPoints > 2;
6122
- if (isIPad) {
6123
- device.isIos = true;
6124
- device.isMobile = true;
6125
- }
6126
- }
6127
- return device;
6128
- };
6129
-
6130
6247
  // Unique ID creation requires a high quality random # generator. In the browser we therefore
6131
6248
  // require the crypto API and do not support built-in fallback to lower quality random number
6132
6249
  // generators (like Math.random()).
@@ -6193,7 +6310,7 @@ function v4(options, buf, offset) {
6193
6310
  }
6194
6311
 
6195
6312
  const name = "@ekyc_qoobiss/qbs-ect-cmp";
6196
- const version$1 = "3.2.1";
6313
+ const version$1 = "3.2.3";
6197
6314
  const description = "Person Identification Component";
6198
6315
  const main = "./dist/index.cjs.js";
6199
6316
  const module$1 = "./dist/index.js";
@@ -6329,7 +6446,7 @@ const IdentificationComponent = class {
6329
6446
  }
6330
6447
  agreementAcceptanceEmitted(data) {
6331
6448
  try {
6332
- this.apiCall.GenerateAgreement(data.detail.agreementType);
6449
+ this.baseComponent.apiCall.GenerateAgreement(data.detail.agreementType);
6333
6450
  }
6334
6451
  catch (e) {
6335
6452
  this.apiErrorEmitter(e, 'Agreement Acceptance');
@@ -6351,7 +6468,7 @@ const IdentificationComponent = class {
6351
6468
  else {
6352
6469
  this.errorTitle = data;
6353
6470
  }
6354
- await this.apiCall.AddLog(apiLogData, getLogMessage(this.order_id, this.redirect_id, this.token));
6471
+ await this.baseComponent.apiCall.AddLog(apiLogData, getLogMessage(this.order_id, this.redirect_id, this.token));
6355
6472
  Events.flowError(data);
6356
6473
  state.flowStatus = FlowStatus.ERROREND;
6357
6474
  }
@@ -6367,7 +6484,8 @@ const IdentificationComponent = class {
6367
6484
  this.idSide = '';
6368
6485
  this.errorMessage = undefined;
6369
6486
  this.errorTitle = undefined;
6370
- this.device = initDevice();
6487
+ this.baseComponent = new BaseComponent(null);
6488
+ this.baseComponent.setErrorCallback(this.apiErrorEmitter);
6371
6489
  }
6372
6490
  async componentWillLoad() {
6373
6491
  Events.init(window);
@@ -6438,7 +6556,6 @@ const IdentificationComponent = class {
6438
6556
  flowStatusToSet = FlowStatus.LANDING;
6439
6557
  }
6440
6558
  }
6441
- this.apiCall = new ApiCall();
6442
6559
  await this.initializeRequest();
6443
6560
  state.flowStatus = flowStatusToSet;
6444
6561
  }
@@ -6457,16 +6574,16 @@ const IdentificationComponent = class {
6457
6574
  }
6458
6575
  try {
6459
6576
  if (state.debug)
6460
- this.apiCall.AddLog('init log', this.logInit);
6577
+ this.baseComponent.apiCall.AddLog('init log', this.logInit);
6461
6578
  }
6462
6579
  catch (_a) { }
6463
6580
  try {
6464
- if (!this.device.isMobile && state.redirectId == '') {
6581
+ if (!state.device.isMobile && state.redirectId == '') {
6465
6582
  state.redirectId = v4();
6466
6583
  this.redirect_id = state.redirectId;
6467
6584
  }
6468
6585
  if (state.token != '' && (state.requestId != '' || state.redirectId != '')) {
6469
- state.initialised = await this.apiCall.AddIdentificationRequest(this.device, packageJson.version);
6586
+ state.initialised = await this.baseComponent.apiCall.AddIdentificationRequest(state.device, packageJson.version);
6470
6587
  if (!this.order_id || this.order_id == '') {
6471
6588
  this.order_id = state.requestId;
6472
6589
  }
@@ -6479,9 +6596,9 @@ const IdentificationComponent = class {
6479
6596
  }
6480
6597
  render() {
6481
6598
  let currentBlock = index.h("div", null);
6482
- if (this.device.isMobile || state.environment == 'DEMO') {
6599
+ if (state.device.isMobile || state.environment == 'DEMO') {
6483
6600
  if (state.flowStatus == FlowStatus.LANDING) {
6484
- currentBlock = index.h("landing-validation", { device: this.device });
6601
+ currentBlock = index.h("landing-validation", null);
6485
6602
  }
6486
6603
  }
6487
6604
  else {
@@ -6500,13 +6617,13 @@ const IdentificationComponent = class {
6500
6617
  currentBlock = index.h("sms-code-validation", null);
6501
6618
  }
6502
6619
  if (state.flowStatus == FlowStatus.ID && !state.hasIdBack) {
6503
- currentBlock = index.h("id-single-side", { id: "idFront", device: this.device });
6620
+ currentBlock = index.h("id-single-side", { id: "idFront" });
6504
6621
  }
6505
6622
  if (state.flowStatus == FlowStatus.ID && state.hasIdBack) {
6506
- currentBlock = index.h("id-double-side", { id: "idFront", device: this.device });
6623
+ currentBlock = index.h("id-double-side", { id: "idFront" });
6507
6624
  }
6508
6625
  if (state.flowStatus == FlowStatus.LIVENESS) {
6509
- currentBlock = index.h("user-liveness", { device: this.device, id: "camera" });
6626
+ currentBlock = index.h("user-liveness", { id: "camera" });
6510
6627
  }
6511
6628
  if (state.flowStatus == FlowStatus.COMPLETE) {
6512
6629
  currentBlock = index.h("end-redirect", null);
@@ -6515,7 +6632,7 @@ const IdentificationComponent = class {
6515
6632
  currentBlock = index.h("error-end", { errorTitle: this.errorTitle, message: this.errorMessage });
6516
6633
  }
6517
6634
  if (state.flowStatus == FlowStatus.CAMERAERROR) {
6518
- currentBlock = index.h("camera-error", { device: this.device });
6635
+ currentBlock = index.h("camera-error", null);
6519
6636
  }
6520
6637
  return index.h("div", null, currentBlock);
6521
6638
  }
@@ -6534,22 +6651,23 @@ const infoSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNiIgaGVpZ2h0PSIyOCIgd
6534
6651
 
6535
6652
  const idSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDYiIGhlaWdodD0iMzkiIHZpZXdCb3g9IjAgMCA0NiAzOSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzMuMjIwNiAxLjc1MTIyQzM0LjM2MDYgMS4yNjg0IDM1LjY4MDYgMS44MDQyIDM2LjE2MjggMi45NDU2M0wzNy4yNzkyIDUuNTg4MDFIMzguODMxTDM3LjQ3OTIgMi4zODgyNEMzNy4wOTY4IDEuNDgzMTYgMzYuMzg1MyAwLjc4MTQ5MyAzNS40NzU5IDAuNDEyMjExQzM0LjU2NjQgMC4wNDI5Mjc2IDMzLjU2NzcgMC4wNTA0OTYxIDMyLjY2MzcgMC40MzMzMzlMMjAuNDkzMiA1LjU4ODE2SDI0LjE2MThMMzMuMjIwNiAxLjc1MTM3VjEuNzUxMjJaTTE2LjY3ODggMTkuNTIwNUMxNy40Mjk1IDE5LjgzODQgMTguMTAzNyAyMC4yOTM0IDE4LjY4MjQgMjAuODcyOUMxOS4yNjEyIDIxLjQ1MjQgMTkuNzE1NSAyMi4xMjcyIDIwLjAzMzEgMjIuODc5QzIwLjM2MjEgMjMuNjU3OCAyMC41Mjg5IDI0LjQ4NDUgMjAuNTI4OSAyNS4zMzYzQzIwLjUyODkgMjUuNzMxNCAyMC4yMDg5IDI2LjA1MTggMTkuODE0MiAyNi4wNTE4QzE5LjQxOTYgMjYuMDUxOCAxOS4wOTk2IDI1LjczMTQgMTkuMDk5NiAyNS4zMzYzQzE5LjA5OTYgMjIuNjQ0OSAxNi45MTI3IDIwLjQ1NTIgMTQuMjI0NiAyMC40NTUyQzExLjUzNjYgMjAuNDU1MiA5LjM0OTY2IDIyLjY0NDkgOS4zNDk2NiAyNS4zMzYzQzkuMzQ5NjYgMjUuNzMxNCA5LjAyOTY2IDI2LjA1MTggOC42MzUwMiAyNi4wNTE4QzguMjQwMzcgMjYuMDUxOCA3LjkyMDM3IDI1LjczMTQgNy45MjAzNyAyNS4zMzYzQzcuOTIwMzcgMjQuNDg0NCA4LjA4NzE0IDIzLjY1NzYgOC40MTYxMiAyMi44NzlDOC43MzM2IDIyLjEyNzQgOS4xODgwOSAyMS40NTI0IDkuNzY2ODMgMjAuODcyOUMxMC4yNzUzIDIwLjM2MzkgMTAuODU3NCAxOS45NTA5IDExLjUwMDQgMTkuNjQyNUMxMS4zMzIgMTkuNTE4MSAxMS4xNzE5IDE5LjM4MDMgMTEuMDIxMyAxOS4yMjk2QzEwLjIzMiAxOC40MzkxIDkuNzk3MjIgMTcuMzg4MyA5Ljc5NzIyIDE2LjI3MDRDOS43OTcyMiAxNS4xNTI1IDEwLjIzMTkgMTQuMTAxNyAxMS4wMjEzIDEzLjMxMTNDMTEuODEwOCAxMi41MjEgMTIuODYwNCAxMi4wODU2IDEzLjk3NjggMTIuMDg1NkMxNS4wOTMxIDEyLjA4NTYgMTYuMTQyNyAxMi41MjA4IDE2LjkzMjIgMTMuMzExM0MxNy43MjE1IDE0LjEwMTcgMTguMTU2MyAxNS4xNTI2IDE4LjE1NjMgMTYuMjcwNEMxOC4xNTYzIDE3LjM4ODIgMTcuNzIxNiAxOC40MzkxIDE2LjkzMjIgMTkuMjI5NkMxNi44MzYzIDE5LjMyNTYgMTYuNzM2NCAxOS40MTYyIDE2LjYzMzMgMTkuNTAxNkwxNi42NTAxIDE5LjUwODVMMTYuNjc4OCAxOS41MjA1Wk0xMS4yMjY1IDE2LjI3MDRDMTEuMjI2NSAxNy43ODg4IDEyLjQ2MDIgMTkuMDI0MSAxMy45NzY4IDE5LjAyNDFDMTUuNDkzMyAxOS4wMjQxIDE2LjcyNyAxNy43ODg4IDE2LjcyNyAxNi4yNzA0QzE2LjcyNyAxNC43NTIgMTUuNDkzMyAxMy41MTY3IDEzLjk3NjggMTMuNTE2N0MxMi40NjAyIDEzLjUxNjcgMTEuMjI2NSAxNC43NTIgMTEuMjI2NSAxNi4yNzA0Wk0yMy45Mzg0IDEyLjA4NTZIMzYuMjA5OUMzNi42MDQ1IDEyLjA4NTYgMzYuOTI0NSAxMi40MDYgMzYuOTI0NSAxMi44MDEyQzM2LjkyNDUgMTMuMTk2MyAzNi42MDQ1IDEzLjUxNjcgMzYuMjA5OSAxMy41MTY3SDIzLjkzODRDMjMuNTQzNyAxMy41MTY3IDIzLjIyMzcgMTMuMTk2MyAyMy4yMjM3IDEyLjgwMTJDMjMuMjIzNyAxMi40MDYgMjMuNTQzNyAxMi4wODU2IDIzLjkzODQgMTIuMDg1NlpNMjMuOTM4NCAxOC4zNTQxSDM2LjIwOTlDMzYuNjA0NSAxOC4zNTQxIDM2LjkyNDUgMTguNjc0NSAzNi45MjQ1IDE5LjA2OTdDMzYuOTI0NSAxOS40NjQ4IDM2LjYwNDUgMTkuNzg1MiAzNi4yMDk5IDE5Ljc4NTJIMjMuOTM4NEMyMy41NDM3IDE5Ljc4NTIgMjMuMjIzNyAxOS40NjQ4IDIzLjIyMzcgMTkuMDY5N0MyMy4yMjM3IDE4LjY3NDUgMjMuNTQzNyAxOC4zNTQxIDIzLjkzODQgMTguMzU0MVpNMzYuMjA5OSAyNC42MjA3SDIzLjkzODRDMjMuNTQzNyAyNC42MjA3IDIzLjIyMzcgMjQuOTQxMSAyMy4yMjM3IDI1LjMzNjNDMjMuMjIzNyAyNS43MzE0IDIzLjU0MzcgMjYuMDUxOCAyMy45Mzg0IDI2LjA1MThIMzYuMjA5OUMzNi42MDQ1IDI2LjA1MTggMzYuOTI0NSAyNS43MzE0IDM2LjkyNDUgMjUuMzM2M0MzNi45MjQ1IDI0Ljk0MTEgMzYuNjA0NSAyNC42MjA3IDM2LjIwOTkgMjQuNjIwN1pNNDIuODQzNiAxNS4wODU2TDQ1LjA3MjMgMjAuMzYwN0w0NS4wNzI2IDIwLjM2MDZDNDUuNDU0OSAyMS4yNjU3IDQ1LjQ2MjUgMjIuMjY1NyA0NS4wOTM3IDIzLjE3NjNDNDQuNzI0OSAyNC4wODY4IDQ0LjAyNDEgMjQuNzk5MiA0My4xMjAxIDI1LjE4MjFMNDIuODQzOSAyNS4yOTkxVjI4LjgyNjhDNDIuODQzOSAyOS44MDk1IDQyLjQ2MTcgMzAuNzMzMyA0MS43Njc3IDMxLjQyODJDNDEuMDczNyAzMi4xMjMxIDQwLjE1MSAzMi41MDU4IDM5LjE2OTYgMzIuNTA1OEgyNS44MjkxTDEzLjMzNjIgMzcuNzk3MUMxMi40MzIyIDM4LjE4IDExLjQzMzUgMzguMTg3NiAxMC41MjQgMzcuODE4M0M5LjYxNDU4IDM3LjQ0OSA4LjkwMzA4IDM2Ljc0NzMgOC41MjA3MiAzNS44NDIyTDcuMTExMTEgMzIuNTA1OUg2LjgzMDQ4QzUuODQ5MDYgMzIuNTA1OSA0LjkyNjM4IDMyLjEyMzIgNC4yMzIzNiAzMS40Mjg0QzMuNTM4MzUgMzAuNzMzNSAzLjE1NjE0IDI5LjgwOTYgMy4xNTYxNCAyOC44MjdWMjMuMTQ0N0wwLjkyNzQ3OSAxNy44Njk2QzAuNTQ1MTE2IDE2Ljk2NDUgMC41Mzc1NTcgMTUuOTY0NSAwLjkwNjM3NiAxNS4wNTM5QzEuMjc1MiAxNC4xNDMzIDEuOTc1OTggMTMuNDMwOSAyLjg3OTkyIDEzLjA0ODFMMy4xNTYxNCAxMi45MzExVjkuMzEyMzdDMy4xNTYxNCA4LjMyOTcyIDMuNTM4MzUgNy40MDU4OCA0LjIzMjM2IDYuNzEwOTlDNC45MjYzOCA2LjAxNjExIDUuODQ5MDYgNS42MzM0MiA2LjgzMDQ4IDUuNjMzNDJIMzkuMTY5M0M0MC4xNTA3IDUuNjMzNDIgNDEuMDczMyA2LjAxNjExIDQxLjc2NzQgNi43MTA5OUM0Mi40NjE0IDcuNDA1ODggNDIuODQzNiA4LjMyOTcyIDQyLjg0MzYgOS4zMTIzN1YxNS4wODU2Wk0yLjI0Mzg2IDE3LjMxMTlMMy4xNTYxNCAxOS40NzEzVjE0LjUwOTNDMi4yMTIzNiAxNS4wNzU3IDEuODAzMDcgMTYuMjY4NyAyLjI0Mzg2IDE3LjMxMTlaTTkuODM2OTQgMzUuMjg0NUMxMC4zMTkxIDM2LjQyNiAxMS42MzkxIDM2Ljk2MTggMTIuNzc5MSAzNi40NzlMMjIuMTYwMyAzMi41MDU2SDguNjYyOTJMOS44MzY5NCAzNS4yODQ1Wk0zOS4xNjk0IDMxLjA3NDVDNDAuNDA3MiAzMS4wNzQ1IDQxLjQxNDMgMzAuMDY2MyA0MS40MTQzIDI4LjgyNjhWOS4zMTIzN0M0MS40MTQzIDguMDcyODYgNDAuNDA3MiA3LjA2NDUxIDM5LjE2OTQgNy4wNjQ1MUg2LjgzMDQ4QzUuNTkyNjggNy4wNjQ1MSA0LjU4NTU5IDguMDcyODYgNC41ODU1OSA5LjMxMjM3VjI4LjgyNjhDNC41ODU1OSAzMC4wNjYyIDUuNTkyNjggMzEuMDc0NSA2LjgzMDQ4IDMxLjA3NDVIMzkuMTY5NFpNNDIuODQzNiAxOC43NTg3VjIzLjcyMDdDNDMuNzg3NCAyMy4xNTQzIDQ0LjE5NjUgMjEuOTYxMyA0My43NTU5IDIwLjkxODFMNDIuODQzNiAxOC43NTg3WiIgZmlsbD0iIzZFNzQ4OCIvPg0KPC9zdmc+DQo=';
6536
6653
 
6537
- const deviceSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDYiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCA0NiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xNF8xNTkyKSI+DQo8cGF0aCBkPSJNMzAuMTU3IDMxLjY1NDNIMy40NzczOEMxLjc3ODc0IDMxLjY1NDMgMC4zOTc3MDUgMzAuMzA4NSAwLjM5NzcwNSAyOC42NTQ5VjI2LjQ2NzJDMC4zOTc3MDUgMjUuOTg5MSAwLjc4ODI1MyAyNS42MDQyIDEuMjcwNTYgMjUuNjA0MkgxNi43NjU0QzE3LjAwMyAyNS42MDQyIDE3LjIyODkgMjUuNjk5OSAxNy4zOTM2IDI1Ljg2NzhMMTguNTIwNSAyNy4wMjdIMjcuMDI1NUMyNy41MDc4IDI3LjAyNyAyNy44OTg0IDI3LjQxMTggMjcuODk4NCAyNy44ODk5QzI3Ljg5ODQgMjguMzY4MSAyNy41MDc4IDI4Ljc1MjkgMjcuMDI1NSAyOC43NTI5SDE4LjE0ODhDMTcuOTExMiAyOC43NTI5IDE3LjY4NTMgMjguNjU3MyAxNy41MjA2IDI4LjQ4OTNMMTYuMzkzNyAyNy4zMzAySDIuMTQzNDFWMjguNjU0OUMyLjE0MzQxIDI5LjM1NyAyLjc0MDk5IDI5LjkyNiAzLjQ3NzM4IDI5LjkyNkgzMC4xNTdDMzAuNjM5MyAyOS45MjYgMzEuMDI5OCAzMC4zMTA5IDMxLjAyOTggMzAuNzg5QzMxLjAyOTggMzEuMjY3MSAzMC42MzkzIDMxLjY1MiAzMC4xNTcgMzEuNjUyVjMxLjY1NDNaTTI5LjkwMDUgMjcuMzMwMkgyOS4yMzQ3QzI4Ljc1MjQgMjcuMzMwMiAyOC4zNjE4IDI2Ljk0NTMgMjguMzYxOCAyNi40NjcyQzI4LjM2MTggMjUuOTg5MSAyOC43NTI0IDI1LjYwNDIgMjkuMjM0NyAyNS42MDQySDI5LjkwMDVDMzAuMzgyOCAyNS42MDQyIDMwLjc3MzQgMjUuOTg5MSAzMC43NzM0IDI2LjQ2NzJDMzAuNzczNCAyNi45NDUzIDMwLjM4MjggMjcuMzMwMiAyOS45MDA1IDI3LjMzMDJaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8cGF0aCBkPSJNMy4zMjIwNyAyNC44MzdDMi44Mzk3NyAyNC44MzcgMi40NDkyMiAyNC40NTIyIDIuNDQ5MjIgMjMuOTc0MVYzLjY3ODE2QzIuNDQ5MjIgMS45Njg1NyAzLjg1Mzc4IDAuNTc2MTcyIDUuNTgwNjYgMC41NzYxNzJINDAuNDE5NEM0Mi4xNDYzIDAuNTc2MTcyIDQzLjU1MDggMS45Njg1NyA0My41NTA4IDMuNjc4MTZWNy4wMzQzOEM0My41NTA4IDcuNTEyNTEgNDMuMTYwMyA3Ljg5OTY3IDQyLjY3OCA3Ljg5OTY3QzQyLjE5NTcgNy44OTk2NyA0MS44MDUxIDcuNTEyNTEgNDEuODA1MSA3LjAzNDM4VjMuNjc4MTZDNDEuODA1MSAyLjkzNDE1IDQxLjE2OTkgMi4zMDQ0MiA0MC40MTk0IDIuMzA0NDJINS41ODA2NkM0LjgzMDE1IDIuMzA0NDIgNC4xOTQ5MiAyLjkzNDE1IDQuMTk0OTIgMy42NzgxNlYyMy45NzQxQzQuMTk0OTIgMjQuNDUyMiAzLjgwNDM3IDI0LjgzNyAzLjMyMjA3IDI0LjgzN1oiIGZpbGw9IiM2RTc0ODgiLz4NCjxwYXRoIGQ9Ik0zOS45NTgyIDUuNTA5MTVIMy4zMjIwN0MyLjgzOTc3IDUuNTA5MTUgMi40NDkyMiA1LjEyMTk4IDIuNDQ5MjIgNC42NDM4NkMyLjQ0OTIyIDQuMTY1NzMgMi44Mzk3NyAzLjc3ODU2IDMuMzIyMDcgMy43Nzg1NkgzOS45NTgyQzQwLjQ0MDUgMy43Nzg1NiA0MC44MzExIDQuMTY1NzMgNDAuODMxMSA0LjY0Mzg2QzQwLjgzMTEgNS4xMjE5OCA0MC40NDA1IDUuNTA5MTUgMzkuOTU4MiA1LjUwOTE1WiIgZmlsbD0iIzZFNzQ4OCIvPg0KPHBhdGggZD0iTTQzLjM5NTYgMzEuNjU0M0gzMy44NTMxQzMyLjY0MzggMzEuNjU0MyAzMS42OTggMzAuNzE2NyAzMS42OTggMjkuNTE3OVYxMC45NTI2QzMxLjY5OCA5Ljc0NjggMzIuNjY1IDguNzY0ODkgMzMuODUzMSA4Ljc2NDg5SDQzLjM5NTZDNDQuNTkwOCA4Ljc2NDg5IDQ1LjYwMjQgOS43Njc3OSA0NS42MDI0IDEwLjk1MjZWMTcuNzY3N0M0NS42MDI0IDE4LjI0NTggNDUuMjExOSAxOC42MzA2IDQ0LjcyOTYgMTguNjMwNkM0NC4yNDczIDE4LjYzMDYgNDMuODU2NyAxOC4yNDU4IDQzLjg1NjcgMTcuNzY3N1YxMC45NTI2QzQzLjg1NjcgMTAuNzE3IDQzLjYzMzIgMTAuNDk1NSA0My4zOTU2IDEwLjQ5NTVIMzMuODUzMUMzMy42Mjk2IDEwLjQ5NTUgMzMuNDQzNyAxMC43MDU0IDMzLjQ0MzcgMTAuOTUyNlYyOS41MTc5QzMzLjQ0MzcgMjkuNzUxMiAzMy42MjAyIDI5LjkyNjEgMzMuODUzMSAyOS45MjYxSDQzLjM5NTZDNDMuNjQ3MyAyOS45MjYxIDQzLjg1NjcgMjkuNzM5NSA0My44NTY3IDI5LjUxNzlWMjAuNjY2N0M0My44NTY3IDIwLjE4ODYgNDQuMjQ3MyAxOS44MDM4IDQ0LjcyOTYgMTkuODAzOEM0NS4yMTE5IDE5LjgwMzggNDUuNjAyNCAyMC4xODg2IDQ1LjYwMjQgMjAuNjY2N1YyOS41MTc5QzQ1LjYwMjQgMzAuNjk1NyA0NC42MTE5IDMxLjY1NDMgNDMuMzk1NiAzMS42NTQzWiIgZmlsbD0iIzZFNzQ4OCIvPg0KPHBhdGggZD0iTTM4LjkzMDIgMjkuMTYxMkgzOC4zMTM4QzM3LjgzMTUgMjkuMTYxMiAzNy40NDA5IDI4Ljc3NjQgMzcuNDQwOSAyOC4yOTgzQzM3LjQ0MDkgMjcuODIwMSAzNy44MzE1IDI3LjQzNTMgMzguMzEzOCAyNy40MzUzSDM4LjkzMDJDMzkuNDEyNSAyNy40MzUzIDM5LjgwMyAyNy44MjAxIDM5LjgwMyAyOC4yOTgzQzM5LjgwMyAyOC43NzY0IDM5LjQxMjUgMjkuMTYxMiAzOC45MzAyIDI5LjE2MTJaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8L2c+DQo8ZGVmcz4NCjxjbGlwUGF0aCBpZD0iY2xpcDBfMTRfMTU5MiI+DQo8cmVjdCB3aWR0aD0iNDUuMjA0NyIgaGVpZ2h0PSIzMS4wNzgyIiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4zOTc3MDUgMC41NzYxNzIpIi8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPC9zdmc+DQo=';
6538
-
6539
6654
  const validationSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDQiIHZpZXdCb3g9IjAgMCA0MCA0NCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xNF8xNjAxKSI+DQo8cGF0aCBkPSJNMTYuNzUxNCAyOS40MTExTDE2LjcyMjggMjMuMjczMUgxNC45NTk2QzEzLjAyODMgMjMuMjczMSAxMS40NTY1IDIxLjc1MzcgMTEuNDU2NSAxOS44ODY0VjMuOTAwMTNDMTEuNDU2NSAyLjAzMjc5IDEyLjk5MzQgMC41MTM0MjggMTQuODgxOCAwLjUxMzQyOEgzNi4zMTUyQzM4LjIwMzYgMC41MTM0MjggMzkuNzM5NiAyLjAzMjc5IDM5LjczOTYgMy45MDAxM1YxOS44ODY0QzM5LjczOTYgMjEuNzUzNyAzOC4yMDM2IDIzLjI3MzEgMzYuMzE1MiAyMy4yNzMxSDI0LjgwMDZDMjQuNzQxNSAyMy4yNzMxIDI0LjY4NTIgMjMuMjkxMiAyNC42NDIyIDIzLjMyNDZMMTYuNzUxNCAyOS40MTExWk0xNC44ODE4IDIuMTQwMzRDMTMuODgxNyAyLjE0MDM0IDEzLjA2NzYgMi45Mjk0IDEzLjA2NzYgMy45MDAxM1YxOS44ODY0QzEzLjA2NzYgMjAuODU3MSAxMy45MTY2IDIxLjY0NjIgMTQuOTYwNSAyMS42NDYySDE3LjE3OTlDMTcuODEyMyAyMS42NDYyIDE4LjMyODUgMjIuMTU2OCAxOC4zMzEyIDIyLjc4NUwxOC4zNDY0IDI2LjEzMzhMMjMuNjY1NCAyMi4wMzEyQzIzLjk4NzQgMjEuNzgyNyAyNC4zOTA5IDIxLjY0NjIgMjQuODAwNiAyMS42NDYySDM2LjMxNTJDMzcuMzE1MyAyMS42NDYyIDM4LjEyOTQgMjAuODU3MSAzOC4xMjk0IDE5Ljg4NjRWMy45MDAxM0MzOC4xMjk0IDIuOTI5NCAzNy4zMTUzIDIuMTQwMzQgMzYuMzE1MiAyLjE0MDM0SDE0Ljg4MThaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8cGF0aCBkPSJNMTcuNDc2OSA0My43MTcxSDUuMzgxNjhDMi41NTc1OCA0My43MTcxIDAuMjYwMzc2IDQxLjM5NiAwLjI2MDM3NiAzOC41NDI2VjExLjU2NTZDMC4yNjAzNzYgOC43MTIxOCAyLjU1NzU4IDYuMzkxMTEgNS4zODE2OCA2LjM5MTExSDkuNTM4NjZWOC4wMTgwM0g1LjM4MTY4QzMuNDQ1ODcgOC4wMTgwMyAxLjg3MDU3IDkuNjA5NyAxLjg3MDU3IDExLjU2NTZWMzguNTQyNkMxLjg3MDU3IDQwLjQ5ODUgMy40NDU4NyA0Mi4wOTAyIDUuMzgxNjggNDIuMDkwMkgxNy40NzY5QzE5LjQxMjcgNDIuMDkwMiAyMC45ODggNDAuNDk4NSAyMC45ODggMzguNTQyNlYyOC45Mjg0SDIyLjU5ODJWMzguNTQyNkMyMi41OTgyIDQxLjM5NiAyMC4zMDEgNDMuNzE3MSAxNy40NzY5IDQzLjcxNzFaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8cGF0aCBkPSJNOS4zODkzNSAxMS44NDIzSDEuMDY1NTVWMTMuNDY5Mkg5LjM4OTM1VjExLjg0MjNaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8cGF0aCBkPSJNMjEuNzkyMyAzNi45MTMxSDEuMDY1NTVWMzguNTRIMjEuNzkyM1YzNi45MTMxWiIgZmlsbD0iIzZFNzQ4OCIvPg0KPHBhdGggZD0iTTI0LjM4NDMgMTIuN0MyNC4zODQzIDEzLjM3MjMgMjQuOTIxNiAxMy45MzExIDI1LjU5ODUgMTMuOTMxMUMyNi4yNzU0IDEzLjkzMTEgMjYuODEyNyAxMy4zNzIzIDI2LjgxMjcgMTIuN0MyNi44MTI3IDEyLjAyNzYgMjYuMjc1NCAxMS40Njg5IDI1LjU5ODUgMTEuNDY4OUMyNC45MjE2IDExLjQ2ODkgMjQuMzg0MyAxMi4wMjc2IDI0LjM4NDMgMTIuN1pNMjUuMjAyNSAxMi43QzI1LjIwMjUgMTIuNDgxOCAyNS4zODAxIDEyLjMwNDEgMjUuNTk4NSAxMi4zMDQxQzI1LjgxNjkgMTIuMzA0MSAyNS45OTQ1IDEyLjQ4MTggMjUuOTk0NSAxMi43QzI1Ljk5NDUgMTIuOTE4MSAyNS44MTY5IDEzLjA5NTggMjUuNTk4NSAxMy4wOTU4QzI1LjM4MDEgMTMuMDk1OCAyNS4yMDI1IDEyLjkxODEgMjUuMjAyNSAxMi43WiIgZmlsbD0iIzZFNzQ4OCIgc3Ryb2tlPSIjNkU3NDg4IiBzdHJva2Utd2lkdGg9IjAuNzQ0ODkxIi8+DQo8cGF0aCBkPSJNMzAuMjQwMSAxMi43QzMwLjI0MDEgMTMuMzcyMyAzMC43Nzc0IDEzLjkzMTEgMzEuNDU0MyAxMy45MzExQzMyLjEzMTIgMTMuOTMxMSAzMi42Njg1IDEzLjM3MjMgMzIuNjY4NSAxMi43QzMyLjY2ODUgMTIuMDI3NiAzMi4xMzEyIDExLjQ2ODkgMzEuNDU0MyAxMS40Njg5QzMwLjc3NzQgMTEuNDY4OSAzMC4yNDAxIDEyLjAyNzYgMzAuMjQwMSAxMi43Wk0zMS4wNTgzIDEyLjdDMzEuMDU4MyAxMi40ODE4IDMxLjIzNTkgMTIuMzA0MSAzMS40NTQzIDEyLjMwNDFDMzEuNjcyNyAxMi4zMDQxIDMxLjg1MDMgMTIuNDgxOCAzMS44NTAzIDEyLjdDMzEuODUwMyAxMi45MTgxIDMxLjY3MjcgMTMuMDk1OCAzMS40NTQzIDEzLjA5NThDMzEuMjM1OSAxMy4wOTU4IDMxLjA1ODMgMTIuOTE4MSAzMS4wNTgzIDEyLjdaIiBmaWxsPSIjNkU3NDg4IiBzdHJva2U9IiM2RTc0ODgiIHN0cm9rZS13aWR0aD0iMC43NDQ4OTEiLz4NCjxwYXRoIGQ9Ik0xOC41Mjg2IDEyLjdDMTguNTI4NiAxMy4zNzIzIDE5LjA2NTkgMTMuOTMxMSAxOS43NDI4IDEzLjkzMTFDMjAuNDE5NyAxMy45MzExIDIwLjk1NyAxMy4zNzIzIDIwLjk1NyAxMi43QzIwLjk1NyAxMi4wMjc2IDIwLjQxOTcgMTEuNDY4OSAxOS43NDI4IDExLjQ2ODlDMTkuMDY1OSAxMS40Njg5IDE4LjUyODYgMTIuMDI3NiAxOC41Mjg2IDEyLjdaTTE5LjM0NjggMTIuN0MxOS4zNDY4IDEyLjQ4MTggMTkuNTI0NCAxMi4zMDQxIDE5Ljc0MjggMTIuMzA0MUMxOS45NjEyIDEyLjMwNDEgMjAuMTM4NyAxMi40ODE4IDIwLjEzODcgMTIuN0MyMC4xMzg3IDEyLjkxODEgMTkuOTYxMiAxMy4wOTU4IDE5Ljc0MjggMTMuMDk1OEMxOS41MjQ0IDEzLjA5NTggMTkuMzQ2OCAxMi45MTgxIDE5LjM0NjggMTIuN1oiIGZpbGw9IiM2RTc0ODgiIHN0cm9rZT0iIzZFNzQ4OCIgc3Ryb2tlLXdpZHRoPSIwLjc0NDg5MSIvPg0KPC9nPg0KPGRlZnM+DQo8Y2xpcFBhdGggaWQ9ImNsaXAwXzE0XzE2MDEiPg0KPHJlY3Qgd2lkdGg9IjM5LjQ3OTIiIGhlaWdodD0iNDMuMjAzNyIgZmlsbD0id2hpdGUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuMjYwMzc2IDAuNTEzNDI4KSIvPg0KPC9jbGlwUGF0aD4NCjwvZGVmcz4NCjwvc3ZnPg0K';
6540
6655
 
6656
+ const deviceSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDYiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCA0NiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xNF8xNTkyKSI+DQo8cGF0aCBkPSJNMzAuMTU3IDMxLjY1NDNIMy40NzczOEMxLjc3ODc0IDMxLjY1NDMgMC4zOTc3MDUgMzAuMzA4NSAwLjM5NzcwNSAyOC42NTQ5VjI2LjQ2NzJDMC4zOTc3MDUgMjUuOTg5MSAwLjc4ODI1MyAyNS42MDQyIDEuMjcwNTYgMjUuNjA0MkgxNi43NjU0QzE3LjAwMyAyNS42MDQyIDE3LjIyODkgMjUuNjk5OSAxNy4zOTM2IDI1Ljg2NzhMMTguNTIwNSAyNy4wMjdIMjcuMDI1NUMyNy41MDc4IDI3LjAyNyAyNy44OTg0IDI3LjQxMTggMjcuODk4NCAyNy44ODk5QzI3Ljg5ODQgMjguMzY4MSAyNy41MDc4IDI4Ljc1MjkgMjcuMDI1NSAyOC43NTI5SDE4LjE0ODhDMTcuOTExMiAyOC43NTI5IDE3LjY4NTMgMjguNjU3MyAxNy41MjA2IDI4LjQ4OTNMMTYuMzkzNyAyNy4zMzAySDIuMTQzNDFWMjguNjU0OUMyLjE0MzQxIDI5LjM1NyAyLjc0MDk5IDI5LjkyNiAzLjQ3NzM4IDI5LjkyNkgzMC4xNTdDMzAuNjM5MyAyOS45MjYgMzEuMDI5OCAzMC4zMTA5IDMxLjAyOTggMzAuNzg5QzMxLjAyOTggMzEuMjY3MSAzMC42MzkzIDMxLjY1MiAzMC4xNTcgMzEuNjUyVjMxLjY1NDNaTTI5LjkwMDUgMjcuMzMwMkgyOS4yMzQ3QzI4Ljc1MjQgMjcuMzMwMiAyOC4zNjE4IDI2Ljk0NTMgMjguMzYxOCAyNi40NjcyQzI4LjM2MTggMjUuOTg5MSAyOC43NTI0IDI1LjYwNDIgMjkuMjM0NyAyNS42MDQySDI5LjkwMDVDMzAuMzgyOCAyNS42MDQyIDMwLjc3MzQgMjUuOTg5MSAzMC43NzM0IDI2LjQ2NzJDMzAuNzczNCAyNi45NDUzIDMwLjM4MjggMjcuMzMwMiAyOS45MDA1IDI3LjMzMDJaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8cGF0aCBkPSJNMy4zMjIwNyAyNC44MzdDMi44Mzk3NyAyNC44MzcgMi40NDkyMiAyNC40NTIyIDIuNDQ5MjIgMjMuOTc0MVYzLjY3ODE2QzIuNDQ5MjIgMS45Njg1NyAzLjg1Mzc4IDAuNTc2MTcyIDUuNTgwNjYgMC41NzYxNzJINDAuNDE5NEM0Mi4xNDYzIDAuNTc2MTcyIDQzLjU1MDggMS45Njg1NyA0My41NTA4IDMuNjc4MTZWNy4wMzQzOEM0My41NTA4IDcuNTEyNTEgNDMuMTYwMyA3Ljg5OTY3IDQyLjY3OCA3Ljg5OTY3QzQyLjE5NTcgNy44OTk2NyA0MS44MDUxIDcuNTEyNTEgNDEuODA1MSA3LjAzNDM4VjMuNjc4MTZDNDEuODA1MSAyLjkzNDE1IDQxLjE2OTkgMi4zMDQ0MiA0MC40MTk0IDIuMzA0NDJINS41ODA2NkM0LjgzMDE1IDIuMzA0NDIgNC4xOTQ5MiAyLjkzNDE1IDQuMTk0OTIgMy42NzgxNlYyMy45NzQxQzQuMTk0OTIgMjQuNDUyMiAzLjgwNDM3IDI0LjgzNyAzLjMyMjA3IDI0LjgzN1oiIGZpbGw9IiM2RTc0ODgiLz4NCjxwYXRoIGQ9Ik0zOS45NTgyIDUuNTA5MTVIMy4zMjIwN0MyLjgzOTc3IDUuNTA5MTUgMi40NDkyMiA1LjEyMTk4IDIuNDQ5MjIgNC42NDM4NkMyLjQ0OTIyIDQuMTY1NzMgMi44Mzk3NyAzLjc3ODU2IDMuMzIyMDcgMy43Nzg1NkgzOS45NTgyQzQwLjQ0MDUgMy43Nzg1NiA0MC44MzExIDQuMTY1NzMgNDAuODMxMSA0LjY0Mzg2QzQwLjgzMTEgNS4xMjE5OCA0MC40NDA1IDUuNTA5MTUgMzkuOTU4MiA1LjUwOTE1WiIgZmlsbD0iIzZFNzQ4OCIvPg0KPHBhdGggZD0iTTQzLjM5NTYgMzEuNjU0M0gzMy44NTMxQzMyLjY0MzggMzEuNjU0MyAzMS42OTggMzAuNzE2NyAzMS42OTggMjkuNTE3OVYxMC45NTI2QzMxLjY5OCA5Ljc0NjggMzIuNjY1IDguNzY0ODkgMzMuODUzMSA4Ljc2NDg5SDQzLjM5NTZDNDQuNTkwOCA4Ljc2NDg5IDQ1LjYwMjQgOS43Njc3OSA0NS42MDI0IDEwLjk1MjZWMTcuNzY3N0M0NS42MDI0IDE4LjI0NTggNDUuMjExOSAxOC42MzA2IDQ0LjcyOTYgMTguNjMwNkM0NC4yNDczIDE4LjYzMDYgNDMuODU2NyAxOC4yNDU4IDQzLjg1NjcgMTcuNzY3N1YxMC45NTI2QzQzLjg1NjcgMTAuNzE3IDQzLjYzMzIgMTAuNDk1NSA0My4zOTU2IDEwLjQ5NTVIMzMuODUzMUMzMy42Mjk2IDEwLjQ5NTUgMzMuNDQzNyAxMC43MDU0IDMzLjQ0MzcgMTAuOTUyNlYyOS41MTc5QzMzLjQ0MzcgMjkuNzUxMiAzMy42MjAyIDI5LjkyNjEgMzMuODUzMSAyOS45MjYxSDQzLjM5NTZDNDMuNjQ3MyAyOS45MjYxIDQzLjg1NjcgMjkuNzM5NSA0My44NTY3IDI5LjUxNzlWMjAuNjY2N0M0My44NTY3IDIwLjE4ODYgNDQuMjQ3MyAxOS44MDM4IDQ0LjcyOTYgMTkuODAzOEM0NS4yMTE5IDE5LjgwMzggNDUuNjAyNCAyMC4xODg2IDQ1LjYwMjQgMjAuNjY2N1YyOS41MTc5QzQ1LjYwMjQgMzAuNjk1NyA0NC42MTE5IDMxLjY1NDMgNDMuMzk1NiAzMS42NTQzWiIgZmlsbD0iIzZFNzQ4OCIvPg0KPHBhdGggZD0iTTM4LjkzMDIgMjkuMTYxMkgzOC4zMTM4QzM3LjgzMTUgMjkuMTYxMiAzNy40NDA5IDI4Ljc3NjQgMzcuNDQwOSAyOC4yOTgzQzM3LjQ0MDkgMjcuODIwMSAzNy44MzE1IDI3LjQzNTMgMzguMzEzOCAyNy40MzUzSDM4LjkzMDJDMzkuNDEyNSAyNy40MzUzIDM5LjgwMyAyNy44MjAxIDM5LjgwMyAyOC4yOTgzQzM5LjgwMyAyOC43NzY0IDM5LjQxMjUgMjkuMTYxMiAzOC45MzAyIDI5LjE2MTJaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8L2c+DQo8ZGVmcz4NCjxjbGlwUGF0aCBpZD0iY2xpcDBfMTRfMTU5MiI+DQo8cmVjdCB3aWR0aD0iNDUuMjA0NyIgaGVpZ2h0PSIzMS4wNzgyIiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4zOTc3MDUgMC41NzYxNzIpIi8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPC9zdmc+DQo=';
6657
+
6541
6658
  const landingValidationCss = "";
6542
6659
 
6543
6660
  const LandingValidation = class {
6544
6661
  constructor(hostRef) {
6545
6662
  index.registerInstance(this, hostRef);
6546
6663
  this.apiErrorEvent = index.createEvent(this, "apiError", 7);
6547
- this.device = undefined;
6548
6664
  this.warningText = undefined;
6549
6665
  this.buttonDisabled = undefined;
6666
+ this.baseComponent = new BaseComponent(FlowSteps.Landing);
6667
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
6550
6668
  }
6551
6669
  async componentWillLoad() {
6552
- this.apiCall = new ApiCall();
6670
+ this.baseComponent.apiCall = new ApiCall();
6553
6671
  this.buttonDisabled = false;
6554
6672
  await this.initRequest();
6555
6673
  }
@@ -6557,12 +6675,7 @@ const LandingValidation = class {
6557
6675
  Events.init(window);
6558
6676
  Events.flowStarted();
6559
6677
  if (state.environment !== 'DEMO') {
6560
- try {
6561
- await this.apiCall.AddStep(FlowSteps.Landing);
6562
- }
6563
- catch (e) {
6564
- this.apiErrorEvent.emit(e);
6565
- }
6678
+ await this.baseComponent.initialize();
6566
6679
  }
6567
6680
  }
6568
6681
  async initRequest() {
@@ -6580,8 +6693,9 @@ const LandingValidation = class {
6580
6693
  state.flowStatus = FlowStatus.COMPLETE;
6581
6694
  return;
6582
6695
  }
6583
- if (!(await Cameras.InitCameras(this.device))) {
6584
- if (this.device.isIos)
6696
+ await this.baseComponent.finalize();
6697
+ if (!(await Cameras.InitCameras(state.device))) {
6698
+ if (state.device.mobileOS == MobileOS.iOS)
6585
6699
  sessionStorage.setItem(SessionKeys.RefreshDoneKey, 'false');
6586
6700
  state.flowStatus = FlowStatus.CAMERAERROR;
6587
6701
  }
@@ -6601,7 +6715,8 @@ const LandingValidation = class {
6601
6715
  return;
6602
6716
  state.initialised = false;
6603
6717
  try {
6604
- await this.apiCall.AbortRequest();
6718
+ await this.baseComponent.apiCall.AbortRequest();
6719
+ await this.baseComponent.finalize();
6605
6720
  Events.flowAborted();
6606
6721
  }
6607
6722
  catch (e) {
@@ -9503,7 +9618,8 @@ const MobileRedirect = class {
9503
9618
  this.redirectLink = undefined;
9504
9619
  this.qrCode = undefined;
9505
9620
  this.prefilledPhone = false;
9506
- this.apiCall = new ApiCall();
9621
+ this.baseComponent = new BaseComponent(FlowSteps.MobileRedirect);
9622
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
9507
9623
  this.invalidValue = false;
9508
9624
  this.waitingMobile = false;
9509
9625
  }
@@ -9527,12 +9643,7 @@ const MobileRedirect = class {
9527
9643
  async componentDidLoad() {
9528
9644
  Events.init(window);
9529
9645
  Events.flowStarted();
9530
- try {
9531
- await this.apiCall.AddStep(FlowSteps.MobileRedirect);
9532
- }
9533
- catch (e) {
9534
- this.apiErrorEvent.emit(e);
9535
- }
9646
+ await this.baseComponent.initialize();
9536
9647
  await delay(5000);
9537
9648
  await this.checkStatus();
9538
9649
  while (this.orderStatus == OrderStatuses.Capturing || this.orderStatus == OrderStatuses.Waiting) {
@@ -9541,9 +9652,10 @@ const MobileRedirect = class {
9541
9652
  }
9542
9653
  }
9543
9654
  async checkStatus() {
9544
- this.orderStatus = await this.apiCall.GetStatus(state.requestId);
9655
+ this.orderStatus = await this.baseComponent.apiCall.GetStatus(state.requestId);
9545
9656
  if (this.orderStatus == OrderStatuses.FinishedCapturing) {
9546
9657
  this.waitingMobile = false;
9658
+ await this.baseComponent.finalize();
9547
9659
  state.flowStatus = FlowStatus.COMPLETE;
9548
9660
  }
9549
9661
  if (this.orderStatus == OrderStatuses.NotFound) {
@@ -9566,7 +9678,7 @@ const MobileRedirect = class {
9566
9678
  this.waitingMobile = true;
9567
9679
  this.infoTextTop = MobileRedirectValues.InfoWaiting;
9568
9680
  try {
9569
- await this.apiCall.SendLink(this.redirectLink, this.contact);
9681
+ await this.baseComponent.apiCall.SendLink(this.redirectLink, this.contact);
9570
9682
  }
9571
9683
  catch (e) {
9572
9684
  this.apiErrorEvent.emit(e);
@@ -9598,7 +9710,6 @@ const SelfieCapture = class {
9598
9710
  //this.closeCamera();
9599
9711
  this.eventPhotoCapture.emit(photos);
9600
9712
  };
9601
- this.device = undefined;
9602
9713
  this.videoStarted = undefined;
9603
9714
  this.captureTaken = undefined;
9604
9715
  this.verified = undefined;
@@ -9651,7 +9762,7 @@ const SelfieCapture = class {
9651
9762
  this.openCamera();
9652
9763
  }
9653
9764
  async openCamera() {
9654
- const constraints = this.cameras.GetConstraints('', this.device, true);
9765
+ const constraints = this.cameras.GetConstraints('', state.device, true);
9655
9766
  setTimeout(() => {
9656
9767
  navigator.mediaDevices
9657
9768
  .getUserMedia(constraints)
@@ -9695,7 +9806,7 @@ const SelfieCapture = class {
9695
9806
  }
9696
9807
  render() {
9697
9808
  let cameraStyle;
9698
- if (this.device.isMobile && this.videoStarted) {
9809
+ if (state.device.isMobile && this.videoStarted) {
9699
9810
  cameraStyle = {
9700
9811
  'width': this.captureWidth + 'px',
9701
9812
  'height': this.captureHeight + 'px',
@@ -9708,7 +9819,7 @@ const SelfieCapture = class {
9708
9819
  let titleClass = this.verified ? 'color-black-2 text-center' : 'color-white text-center';
9709
9820
  //let videoClass = this.device.isMobile ? '' : 'video-demo';
9710
9821
  let bgDemo = this.verified ? 'container' : 'container bg-black';
9711
- return (index.h("div", { class: bgDemo }, index.h("div", { class: "container-video" }, index.h("div", { hidden: this.demoEnded }, index.h("video", { id: "howtoSelfie", class: "video-demo", playsinline: true, ref: el => (this.demoVideo = el) }, index.h("source", { type: "video/mp4" }))), index.h("div", { hidden: this.demoEnded == false }, index.h("div", { hidden: this.verified }, index.h("div", { class: "video-capture" }, index.h("div", { style: cameraStyle }, index.h("camera-comp", { device: this.device, "capture-mode": "selfie" }))))), index.h("div", { class: "capture-title" }, index.h("h1", { class: titleClass }, this.titleMesage), index.h("p", { class: "main-text font-size-18 text-right mb-0" }, SelfieCaptureValues.FooterText)))));
9822
+ return (index.h("div", { class: bgDemo }, index.h("div", { class: "container-video" }, index.h("div", { hidden: this.demoEnded }, index.h("video", { id: "howtoSelfie", class: "video-demo", playsinline: true, ref: el => (this.demoVideo = el) }, index.h("source", { type: "video/mp4" }))), index.h("div", { hidden: this.demoEnded == false }, index.h("div", { hidden: this.verified }, index.h("div", { class: "video-capture" }, index.h("div", { style: cameraStyle }, index.h("camera-comp", { "capture-mode": "selfie" }))))), index.h("div", { class: "capture-title" }, index.h("h1", { class: titleClass }, this.titleMesage), index.h("p", { class: "main-text font-size-18 text-right mb-0" }, SelfieCaptureValues.FooterText)))));
9712
9823
  }
9713
9824
  get component() { return index.getElement(this); }
9714
9825
  };
@@ -9727,13 +9838,20 @@ const SmsCodeValidation = class {
9727
9838
  this.code = undefined;
9728
9839
  this.prefilledPhone = false;
9729
9840
  this.canSend = false;
9730
- this.apiCall = new ApiCall();
9841
+ if (state.flowStatus == FlowStatus.PHONE) {
9842
+ this.baseComponent = new BaseComponent(FlowSteps.OtpSend);
9843
+ }
9844
+ if (state.flowStatus == FlowStatus.CODE) {
9845
+ this.baseComponent = new BaseComponent(FlowSteps.OtpCheck);
9846
+ }
9847
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
9731
9848
  }
9732
9849
  async doAction() {
9733
9850
  try {
9734
9851
  this.canSend = false;
9852
+ await this.baseComponent.finalize();
9735
9853
  if (state.flowStatus == FlowStatus.CODE || state.flowStatus == FlowStatus.CODEERROR) {
9736
- var codeChecked = await this.apiCall.CheckOTPCode(state.requestId, this.code);
9854
+ var codeChecked = await this.baseComponent.apiCall.CheckOTPCode(state.requestId, this.code);
9737
9855
  if (codeChecked === true) {
9738
9856
  state.flowStatus = FlowStatus.ID;
9739
9857
  }
@@ -9742,7 +9860,7 @@ const SmsCodeValidation = class {
9742
9860
  }
9743
9861
  }
9744
9862
  if (state.flowStatus == FlowStatus.PHONE) {
9745
- var codeSent = await this.apiCall.SendOTPCode(state.requestId, this.phoneNumber);
9863
+ var codeSent = await this.baseComponent.apiCall.SendOTPCode(state.requestId, this.phoneNumber);
9746
9864
  if (codeSent === true) {
9747
9865
  state.flowStatus = FlowStatus.CODE;
9748
9866
  }
@@ -9770,17 +9888,7 @@ const SmsCodeValidation = class {
9770
9888
  }
9771
9889
  }
9772
9890
  async componentDidLoad() {
9773
- try {
9774
- if (state.flowStatus == FlowStatus.PHONE) {
9775
- await this.apiCall.AddStep(FlowSteps.OtpSend);
9776
- }
9777
- if (state.flowStatus == FlowStatus.CODE) {
9778
- await this.apiCall.AddStep(FlowSteps.OtpCheck);
9779
- }
9780
- }
9781
- catch (e) {
9782
- this.apiErrorEvent.emit(e);
9783
- }
9891
+ await this.baseComponent.initialize();
9784
9892
  }
9785
9893
  handleChangePhone(ev) {
9786
9894
  let value = ev.target ? ev.target.value : '';
@@ -9821,7 +9929,6 @@ const UserLiveness = class {
9821
9929
  constructor(hostRef) {
9822
9930
  index.registerInstance(this, hostRef);
9823
9931
  this.apiErrorEvent = index.createEvent(this, "apiError", 7);
9824
- this.device = undefined;
9825
9932
  this.showError = undefined;
9826
9933
  this.showHowTo = undefined;
9827
9934
  this.selfieFlow = {
@@ -9831,15 +9938,11 @@ const UserLiveness = class {
9831
9938
  photoFile: null,
9832
9939
  recordingFile: null,
9833
9940
  };
9834
- this.apiCall = new ApiCall();
9941
+ this.baseComponent = new BaseComponent(FlowSteps.Selfie);
9942
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
9835
9943
  }
9836
9944
  async componentDidLoad() {
9837
- try {
9838
- await this.apiCall.AddStep(FlowSteps.Selfie);
9839
- }
9840
- catch (e) {
9841
- this.apiErrorEvent.emit(e);
9842
- }
9945
+ await this.baseComponent.initialize();
9843
9946
  }
9844
9947
  componentWillLoad() {
9845
9948
  this.showHowTo = true;
@@ -9860,7 +9963,7 @@ const UserLiveness = class {
9860
9963
  async captureSelfieImage(event) {
9861
9964
  let selfiePhoto = event.detail;
9862
9965
  if (selfiePhoto.length == 0 || selfiePhoto.size == 0) {
9863
- await this.apiCall.AddLog({ message: 'Empty selfie', blobData: selfiePhoto }, getLogMessage());
9966
+ await this.baseComponent.apiCall.AddLog({ message: 'Empty selfie', blobData: selfiePhoto }, getLogMessage());
9864
9967
  return;
9865
9968
  }
9866
9969
  try {
@@ -9874,7 +9977,7 @@ const UserLiveness = class {
9874
9977
  async capturedSelfieRecording(event) {
9875
9978
  let selfieRecording = event.detail;
9876
9979
  if (selfieRecording.length == 0 || selfieRecording.size == 0) {
9877
- await this.apiCall.AddLog({ message: 'Empty recording', blobData: selfieRecording }, getLogMessage());
9980
+ await this.baseComponent.apiCall.AddLog({ message: 'Empty recording', blobData: selfieRecording }, getLogMessage());
9878
9981
  return;
9879
9982
  }
9880
9983
  let mimeType = selfieRecording.type == Stream.mp4MimeType.type ? Stream.mp4MimeType : Stream.webmMimeType;
@@ -9883,42 +9986,49 @@ const UserLiveness = class {
9883
9986
  await this.uploadRecording();
9884
9987
  }
9885
9988
  catch (e) {
9886
- this.apiErrorEvent.emit(e);
9989
+ if (state.recordingRetryCount < 3) {
9990
+ state.recordingRetryCount++;
9991
+ this.triggerErrorFlow();
9992
+ }
9993
+ else {
9994
+ this.apiErrorEvent.emit(e);
9995
+ }
9887
9996
  }
9888
9997
  }
9889
9998
  async verificationFinished(_event) {
9890
9999
  this.selfieFlow.verificationFinished = true;
9891
- this.endFlow();
10000
+ await this.endFlow();
9892
10001
  }
9893
10002
  async uploadPhoto() {
9894
10003
  if (this.selfieFlow.photoFile == null || this.selfieFlow.photoDone) {
9895
10004
  return;
9896
10005
  }
9897
- this.selfieFlow.photoDone = await this.apiCall.UploadFileForRequestB64(state.requestId, 'Selfie', this.selfieFlow.photoFile);
10006
+ this.selfieFlow.photoDone = await this.baseComponent.apiCall.UploadFileForRequestB64(state.requestId, 'Selfie', this.selfieFlow.photoFile);
9898
10007
  if (this.selfieFlow.photoDone) {
9899
- this.endFlow();
10008
+ await this.endFlow();
9900
10009
  }
9901
10010
  else {
9902
- this.selfieFlow.photoFile = null;
9903
- this.selfieFlow.recordingFile = null;
9904
- this.showError = true;
10011
+ this.triggerErrorFlow();
9905
10012
  }
9906
10013
  }
9907
10014
  async uploadRecording() {
9908
10015
  if (this.selfieFlow.recordingFile == null || this.selfieFlow.recordingDone) {
9909
10016
  return;
9910
10017
  }
9911
- this.selfieFlow.recordingDone = await this.apiCall.UploadFileForRequestB64(state.requestId, 'SelfieVideo', this.selfieFlow.recordingFile);
10018
+ this.selfieFlow.recordingDone = await this.baseComponent.apiCall.UploadFileForRequestB64(state.requestId, 'SelfieVideo', this.selfieFlow.recordingFile);
9912
10019
  if (this.selfieFlow.recordingDone) {
9913
- this.endFlow();
10020
+ await this.endFlow();
9914
10021
  }
9915
10022
  else {
9916
- this.selfieFlow.photoFile = null;
9917
- this.selfieFlow.recordingFile = null;
9918
- this.showError = true;
10023
+ this.triggerErrorFlow();
9919
10024
  }
9920
10025
  }
9921
- endFlow() {
10026
+ triggerErrorFlow() {
10027
+ this.selfieFlow.photoFile = null;
10028
+ this.selfieFlow.recordingFile = null;
10029
+ this.showError = true;
10030
+ }
10031
+ async endFlow() {
9922
10032
  if (!this.selfieFlow.photoDone) {
9923
10033
  return;
9924
10034
  }
@@ -9928,11 +10038,13 @@ const UserLiveness = class {
9928
10038
  if (!this.selfieFlow.verificationFinished) {
9929
10039
  return;
9930
10040
  }
10041
+ state.recordingRetryCount = 0;
10042
+ await this.baseComponent.finalize();
9931
10043
  state.flowStatus = FlowStatus.COMPLETE;
9932
10044
  }
9933
10045
  render() {
9934
10046
  let howTo = index.h("how-to-info", { idSide: "" });
9935
- let capture = index.h("selfie-capture", { device: this.device, id: "camera" });
10047
+ let capture = index.h("selfie-capture", { id: "camera" });
9936
10048
  let error = index.h("capture-error", { type: "LIVENESS" });
9937
10049
  return this.showHowTo ? howTo : this.showError ? error : capture;
9938
10050
  }