@ekyc_qoobiss/qbs-ect-cmp 3.2.0 → 3.2.2

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 (61) hide show
  1. package/README.md +19 -0
  2. package/dist/cjs/agreement-check_18.cjs.entry.js +393 -277
  3. package/dist/cjs/loader.cjs.js +1 -1
  4. package/dist/cjs/qbs-ect-cmp.cjs.js +1 -1
  5. package/dist/collection/components/base-component.js +48 -0
  6. package/dist/collection/components/common/camera-error/camera-error.js +9 -36
  7. package/dist/collection/components/common/id-back-capture/id-back-capture.js +2 -27
  8. package/dist/collection/components/common/id-capture/id-capture.js +2 -27
  9. package/dist/collection/components/common/selfie-capture/selfie-capture.js +4 -28
  10. package/dist/collection/components/controls/camera/camera.js +3 -23
  11. package/dist/collection/components/flow/agreement-info/agreement-info.js +6 -9
  12. package/dist/collection/components/flow/end-redirect/end-redirect.js +4 -9
  13. package/dist/collection/components/flow/id-double-side/id-double-side.js +31 -51
  14. package/dist/collection/components/flow/id-single-side/id-single-side.js +14 -42
  15. package/dist/collection/components/flow/landing-validation/landing-validation.js +19 -40
  16. package/dist/collection/components/flow/mobile-redirect/mobile-redirect.js +7 -10
  17. package/dist/collection/components/flow/sms-code-validation/sms-code-validation.js +12 -15
  18. package/dist/collection/components/flow/user-liveness/user-liveness.js +29 -49
  19. package/dist/collection/components/identification-component/identification-component.js +28 -25
  20. package/dist/collection/helpers/ApiCall.js +3 -3
  21. package/dist/collection/helpers/Cameras.js +3 -2
  22. package/dist/collection/helpers/DeviceDetection.js +83 -0
  23. package/dist/collection/helpers/Events.js +9 -0
  24. package/dist/collection/helpers/Stream.js +9 -8
  25. package/dist/collection/helpers/index.js +0 -33
  26. package/dist/collection/helpers/store.js +2 -0
  27. package/dist/collection/models/FlowSteps.js +19 -13
  28. package/dist/collection/models/IDevice.js +22 -1
  29. package/dist/collection/models/IEctStore.js +1 -0
  30. package/dist/esm/agreement-check_18.entry.js +393 -277
  31. package/dist/esm/loader.js +1 -1
  32. package/dist/esm/qbs-ect-cmp.js +1 -1
  33. package/dist/qbs-ect-cmp/{p-acda46c1.entry.js → p-29f81591.entry.js} +2 -2
  34. package/dist/qbs-ect-cmp/qbs-ect-cmp.esm.js +1 -1
  35. package/dist/types/components/base-component.d.ts +14 -0
  36. package/dist/types/components/common/camera-error/camera-error.d.ts +1 -3
  37. package/dist/types/components/common/id-back-capture/id-back-capture.d.ts +0 -2
  38. package/dist/types/components/common/id-capture/id-capture.d.ts +0 -2
  39. package/dist/types/components/common/selfie-capture/selfie-capture.d.ts +0 -2
  40. package/dist/types/components/controls/camera/camera.d.ts +0 -2
  41. package/dist/types/components/flow/agreement-info/agreement-info.d.ts +3 -3
  42. package/dist/types/components/flow/end-redirect/end-redirect.d.ts +1 -1
  43. package/dist/types/components/flow/id-double-side/id-double-side.d.ts +4 -5
  44. package/dist/types/components/flow/id-single-side/id-single-side.d.ts +3 -5
  45. package/dist/types/components/flow/landing-validation/landing-validation.d.ts +2 -3
  46. package/dist/types/components/flow/mobile-redirect/mobile-redirect.d.ts +1 -1
  47. package/dist/types/components/flow/sms-code-validation/sms-code-validation.d.ts +2 -2
  48. package/dist/types/components/flow/user-liveness/user-liveness.d.ts +3 -4
  49. package/dist/types/components/identification-component/identification-component.d.ts +1 -2
  50. package/dist/types/components.d.ts +0 -19
  51. package/dist/types/helpers/ApiCall.d.ts +4 -4
  52. package/dist/types/helpers/Cameras.d.ts +4 -4
  53. package/dist/types/helpers/DeviceDetection.d.ts +18 -0
  54. package/dist/types/helpers/Events.d.ts +2 -0
  55. package/dist/types/helpers/Stream.d.ts +1 -3
  56. package/dist/types/helpers/index.d.ts +0 -2
  57. package/dist/types/helpers/store.d.ts +2 -17
  58. package/dist/types/models/FlowSteps.d.ts +18 -13
  59. package/dist/types/models/IDevice.d.ts +32 -9
  60. package/dist/types/models/IEctStore.d.ts +20 -0
  61. 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["MobileRedirect"] = "mobile-redirect";
408
+ FlowSteps["Landing"] = "landing";
409
+ FlowSteps["Agreements"] = "agreements";
410
+ FlowSteps["OtpSend"] = "otp-send";
411
+ FlowSteps["OtpCheck"] = "otp-check";
412
+ FlowSteps["CiFrontHowTo"] = "ci-front-how-to";
413
+ FlowSteps["CiFront"] = "ci-front";
414
+ FlowSteps["CiBackHowTo"] = "ci-back-how-to";
415
+ FlowSteps["CiBack"] = "ci-back";
416
+ FlowSteps["SelfieHowTo"] = "selfie-how-to";
417
+ FlowSteps["Selfie"] = "selfie";
418
+ FlowSteps["End"] = "end";
419
+ FlowSteps["CameraError"] = "camera-error";
420
+ })(FlowSteps || (FlowSteps = {}));
421
+ var FlowMoments;
422
+ (function (FlowMoments) {
423
+ FlowMoments["Initialized"] = "initialized";
424
+ FlowMoments["Finalized"] = "finalized";
425
+ FlowMoments["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.0";
6309
+ const version$1 = "3.2.2";
6193
6310
  const description = "Person Identification Component";
6194
6311
  const main = "./dist/index.cjs.js";
6195
6312
  const module = "./dist/index.js";
@@ -6278,10 +6395,10 @@ const IdentificationComponent = class {
6278
6395
  if (state.requestId !== newValue && newValue != '') {
6279
6396
  state.requestId = newValue;
6280
6397
  state.initialised = false;
6398
+ await this.initializeRequest();
6281
6399
  if (state.flowStatus != FlowStatus.LANDING) {
6282
6400
  state.flowStatus = FlowStatus.LANDING;
6283
6401
  }
6284
- await this.initializeRequest();
6285
6402
  }
6286
6403
  }
6287
6404
  onApiUrlChange(newValue, _oldValue) {
@@ -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);
@@ -6390,13 +6508,6 @@ const IdentificationComponent = class {
6390
6508
  if (this.phone_number && this.phone_number != '') {
6391
6509
  state.phoneNumber = this.phone_number;
6392
6510
  }
6393
- var flowSt = sessionStorage.getItem(SessionKeys.FlowStatusKey);
6394
- if (flowSt) {
6395
- state.flowStatus = FlowStatus[flowSt];
6396
- }
6397
- else {
6398
- state.flowStatus = FlowStatus.LANDING;
6399
- }
6400
6511
  var ini = sessionStorage.getItem(SessionKeys.InitialisedKey);
6401
6512
  if (ini && ini.toLowerCase() == 'true') {
6402
6513
  state.initialised = true;
@@ -6413,17 +6524,18 @@ const IdentificationComponent = class {
6413
6524
  if (phoneVal && phoneVal.toLowerCase() == 'true') {
6414
6525
  state.phoneValidation = true;
6415
6526
  }
6527
+ var flowStatusToSet = null;
6416
6528
  const savedRequest = sessionStorage.getItem(SessionKeys.RequestIdKey);
6417
6529
  if (this.order_id && this.order_id != '') {
6530
+ state.requestId = this.order_id;
6418
6531
  if (state.debug)
6419
6532
  console.log('Current RequestId has value: ' + this.order_id);
6420
6533
  if (savedRequest && savedRequest != '' && savedRequest != this.order_id) {
6421
6534
  if (state.debug)
6422
6535
  console.log('Session RequestId: ' + savedRequest + ' has different value than property one: ' + this.order_id);
6423
- state.flowStatus = FlowStatus.LANDING;
6536
+ flowStatusToSet = FlowStatus.LANDING;
6424
6537
  state.initialised = false;
6425
6538
  }
6426
- state.requestId = this.order_id;
6427
6539
  }
6428
6540
  else if (savedRequest) {
6429
6541
  if (state.debug)
@@ -6431,8 +6543,17 @@ const IdentificationComponent = class {
6431
6543
  state.requestId = savedRequest;
6432
6544
  this.order_id = savedRequest;
6433
6545
  }
6434
- this.apiCall = new ApiCall();
6546
+ if (flowStatusToSet == null) {
6547
+ var flowSt = sessionStorage.getItem(SessionKeys.FlowStatusKey);
6548
+ if (flowSt) {
6549
+ flowStatusToSet = FlowStatus[flowSt];
6550
+ }
6551
+ else {
6552
+ flowStatusToSet = FlowStatus.LANDING;
6553
+ }
6554
+ }
6435
6555
  await this.initializeRequest();
6556
+ state.flowStatus = flowStatusToSet;
6436
6557
  }
6437
6558
  componentWillRender() {
6438
6559
  if (this.idSide == '') {
@@ -6449,16 +6570,16 @@ const IdentificationComponent = class {
6449
6570
  }
6450
6571
  try {
6451
6572
  if (state.debug)
6452
- this.apiCall.AddLog('init log', this.logInit);
6573
+ this.baseComponent.apiCall.AddLog('init log', this.logInit);
6453
6574
  }
6454
6575
  catch (_a) { }
6455
6576
  try {
6456
- if (!this.device.isMobile && state.redirectId == '') {
6577
+ if (!state.device.isMobile && state.redirectId == '') {
6457
6578
  state.redirectId = v4();
6458
6579
  this.redirect_id = state.redirectId;
6459
6580
  }
6460
6581
  if (state.token != '' && (state.requestId != '' || state.redirectId != '')) {
6461
- state.initialised = await this.apiCall.AddIdentificationRequest(this.device, packageJson.version);
6582
+ state.initialised = await this.baseComponent.apiCall.AddIdentificationRequest(state.device, packageJson.version);
6462
6583
  if (!this.order_id || this.order_id == '') {
6463
6584
  this.order_id = state.requestId;
6464
6585
  }
@@ -6471,9 +6592,9 @@ const IdentificationComponent = class {
6471
6592
  }
6472
6593
  render() {
6473
6594
  let currentBlock = h("div", null);
6474
- if (this.device.isMobile || state.environment == 'DEMO') {
6595
+ if (state.device.isMobile || state.environment == 'DEMO') {
6475
6596
  if (state.flowStatus == FlowStatus.LANDING) {
6476
- currentBlock = h("landing-validation", { device: this.device });
6597
+ currentBlock = h("landing-validation", null);
6477
6598
  }
6478
6599
  }
6479
6600
  else {
@@ -6492,13 +6613,13 @@ const IdentificationComponent = class {
6492
6613
  currentBlock = h("sms-code-validation", null);
6493
6614
  }
6494
6615
  if (state.flowStatus == FlowStatus.ID && !state.hasIdBack) {
6495
- currentBlock = h("id-single-side", { id: "idFront", device: this.device });
6616
+ currentBlock = h("id-single-side", { id: "idFront" });
6496
6617
  }
6497
6618
  if (state.flowStatus == FlowStatus.ID && state.hasIdBack) {
6498
- currentBlock = h("id-double-side", { id: "idFront", device: this.device });
6619
+ currentBlock = h("id-double-side", { id: "idFront" });
6499
6620
  }
6500
6621
  if (state.flowStatus == FlowStatus.LIVENESS) {
6501
- currentBlock = h("user-liveness", { device: this.device, id: "camera" });
6622
+ currentBlock = h("user-liveness", { id: "camera" });
6502
6623
  }
6503
6624
  if (state.flowStatus == FlowStatus.COMPLETE) {
6504
6625
  currentBlock = h("end-redirect", null);
@@ -6507,7 +6628,7 @@ const IdentificationComponent = class {
6507
6628
  currentBlock = h("error-end", { errorTitle: this.errorTitle, message: this.errorMessage });
6508
6629
  }
6509
6630
  if (state.flowStatus == FlowStatus.CAMERAERROR) {
6510
- currentBlock = h("camera-error", { device: this.device });
6631
+ currentBlock = h("camera-error", null);
6511
6632
  }
6512
6633
  return h("div", null, currentBlock);
6513
6634
  }
@@ -6526,22 +6647,23 @@ const infoSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNiIgaGVpZ2h0PSIyOCIgd
6526
6647
 
6527
6648
  const idSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDYiIGhlaWdodD0iMzkiIHZpZXdCb3g9IjAgMCA0NiAzOSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzMuMjIwNiAxLjc1MTIyQzM0LjM2MDYgMS4yNjg0IDM1LjY4MDYgMS44MDQyIDM2LjE2MjggMi45NDU2M0wzNy4yNzkyIDUuNTg4MDFIMzguODMxTDM3LjQ3OTIgMi4zODgyNEMzNy4wOTY4IDEuNDgzMTYgMzYuMzg1MyAwLjc4MTQ5MyAzNS40NzU5IDAuNDEyMjExQzM0LjU2NjQgMC4wNDI5Mjc2IDMzLjU2NzcgMC4wNTA0OTYxIDMyLjY2MzcgMC40MzMzMzlMMjAuNDkzMiA1LjU4ODE2SDI0LjE2MThMMzMuMjIwNiAxLjc1MTM3VjEuNzUxMjJaTTE2LjY3ODggMTkuNTIwNUMxNy40Mjk1IDE5LjgzODQgMTguMTAzNyAyMC4yOTM0IDE4LjY4MjQgMjAuODcyOUMxOS4yNjEyIDIxLjQ1MjQgMTkuNzE1NSAyMi4xMjcyIDIwLjAzMzEgMjIuODc5QzIwLjM2MjEgMjMuNjU3OCAyMC41Mjg5IDI0LjQ4NDUgMjAuNTI4OSAyNS4zMzYzQzIwLjUyODkgMjUuNzMxNCAyMC4yMDg5IDI2LjA1MTggMTkuODE0MiAyNi4wNTE4QzE5LjQxOTYgMjYuMDUxOCAxOS4wOTk2IDI1LjczMTQgMTkuMDk5NiAyNS4zMzYzQzE5LjA5OTYgMjIuNjQ0OSAxNi45MTI3IDIwLjQ1NTIgMTQuMjI0NiAyMC40NTUyQzExLjUzNjYgMjAuNDU1MiA5LjM0OTY2IDIyLjY0NDkgOS4zNDk2NiAyNS4zMzYzQzkuMzQ5NjYgMjUuNzMxNCA5LjAyOTY2IDI2LjA1MTggOC42MzUwMiAyNi4wNTE4QzguMjQwMzcgMjYuMDUxOCA3LjkyMDM3IDI1LjczMTQgNy45MjAzNyAyNS4zMzYzQzcuOTIwMzcgMjQuNDg0NCA4LjA4NzE0IDIzLjY1NzYgOC40MTYxMiAyMi44NzlDOC43MzM2IDIyLjEyNzQgOS4xODgwOSAyMS40NTI0IDkuNzY2ODMgMjAuODcyOUMxMC4yNzUzIDIwLjM2MzkgMTAuODU3NCAxOS45NTA5IDExLjUwMDQgMTkuNjQyNUMxMS4zMzIgMTkuNTE4MSAxMS4xNzE5IDE5LjM4MDMgMTEuMDIxMyAxOS4yMjk2QzEwLjIzMiAxOC40MzkxIDkuNzk3MjIgMTcuMzg4MyA5Ljc5NzIyIDE2LjI3MDRDOS43OTcyMiAxNS4xNTI1IDEwLjIzMTkgMTQuMTAxNyAxMS4wMjEzIDEzLjMxMTNDMTEuODEwOCAxMi41MjEgMTIuODYwNCAxMi4wODU2IDEzLjk3NjggMTIuMDg1NkMxNS4wOTMxIDEyLjA4NTYgMTYuMTQyNyAxMi41MjA4IDE2LjkzMjIgMTMuMzExM0MxNy43MjE1IDE0LjEwMTcgMTguMTU2MyAxNS4xNTI2IDE4LjE1NjMgMTYuMjcwNEMxOC4xNTYzIDE3LjM4ODIgMTcuNzIxNiAxOC40MzkxIDE2LjkzMjIgMTkuMjI5NkMxNi44MzYzIDE5LjMyNTYgMTYuNzM2NCAxOS40MTYyIDE2LjYzMzMgMTkuNTAxNkwxNi42NTAxIDE5LjUwODVMMTYuNjc4OCAxOS41MjA1Wk0xMS4yMjY1IDE2LjI3MDRDMTEuMjI2NSAxNy43ODg4IDEyLjQ2MDIgMTkuMDI0MSAxMy45NzY4IDE5LjAyNDFDMTUuNDkzMyAxOS4wMjQxIDE2LjcyNyAxNy43ODg4IDE2LjcyNyAxNi4yNzA0QzE2LjcyNyAxNC43NTIgMTUuNDkzMyAxMy41MTY3IDEzLjk3NjggMTMuNTE2N0MxMi40NjAyIDEzLjUxNjcgMTEuMjI2NSAxNC43NTIgMTEuMjI2NSAxNi4yNzA0Wk0yMy45Mzg0IDEyLjA4NTZIMzYuMjA5OUMzNi42MDQ1IDEyLjA4NTYgMzYuOTI0NSAxMi40MDYgMzYuOTI0NSAxMi44MDEyQzM2LjkyNDUgMTMuMTk2MyAzNi42MDQ1IDEzLjUxNjcgMzYuMjA5OSAxMy41MTY3SDIzLjkzODRDMjMuNTQzNyAxMy41MTY3IDIzLjIyMzcgMTMuMTk2MyAyMy4yMjM3IDEyLjgwMTJDMjMuMjIzNyAxMi40MDYgMjMuNTQzNyAxMi4wODU2IDIzLjkzODQgMTIuMDg1NlpNMjMuOTM4NCAxOC4zNTQxSDM2LjIwOTlDMzYuNjA0NSAxOC4zNTQxIDM2LjkyNDUgMTguNjc0NSAzNi45MjQ1IDE5LjA2OTdDMzYuOTI0NSAxOS40NjQ4IDM2LjYwNDUgMTkuNzg1MiAzNi4yMDk5IDE5Ljc4NTJIMjMuOTM4NEMyMy41NDM3IDE5Ljc4NTIgMjMuMjIzNyAxOS40NjQ4IDIzLjIyMzcgMTkuMDY5N0MyMy4yMjM3IDE4LjY3NDUgMjMuNTQzNyAxOC4zNTQxIDIzLjkzODQgMTguMzU0MVpNMzYuMjA5OSAyNC42MjA3SDIzLjkzODRDMjMuNTQzNyAyNC42MjA3IDIzLjIyMzcgMjQuOTQxMSAyMy4yMjM3IDI1LjMzNjNDMjMuMjIzNyAyNS43MzE0IDIzLjU0MzcgMjYuMDUxOCAyMy45Mzg0IDI2LjA1MThIMzYuMjA5OUMzNi42MDQ1IDI2LjA1MTggMzYuOTI0NSAyNS43MzE0IDM2LjkyNDUgMjUuMzM2M0MzNi45MjQ1IDI0Ljk0MTEgMzYuNjA0NSAyNC42MjA3IDM2LjIwOTkgMjQuNjIwN1pNNDIuODQzNiAxNS4wODU2TDQ1LjA3MjMgMjAuMzYwN0w0NS4wNzI2IDIwLjM2MDZDNDUuNDU0OSAyMS4yNjU3IDQ1LjQ2MjUgMjIuMjY1NyA0NS4wOTM3IDIzLjE3NjNDNDQuNzI0OSAyNC4wODY4IDQ0LjAyNDEgMjQuNzk5MiA0My4xMjAxIDI1LjE4MjFMNDIuODQzOSAyNS4yOTkxVjI4LjgyNjhDNDIuODQzOSAyOS44MDk1IDQyLjQ2MTcgMzAuNzMzMyA0MS43Njc3IDMxLjQyODJDNDEuMDczNyAzMi4xMjMxIDQwLjE1MSAzMi41MDU4IDM5LjE2OTYgMzIuNTA1OEgyNS44MjkxTDEzLjMzNjIgMzcuNzk3MUMxMi40MzIyIDM4LjE4IDExLjQzMzUgMzguMTg3NiAxMC41MjQgMzcuODE4M0M5LjYxNDU4IDM3LjQ0OSA4LjkwMzA4IDM2Ljc0NzMgOC41MjA3MiAzNS44NDIyTDcuMTExMTEgMzIuNTA1OUg2LjgzMDQ4QzUuODQ5MDYgMzIuNTA1OSA0LjkyNjM4IDMyLjEyMzIgNC4yMzIzNiAzMS40Mjg0QzMuNTM4MzUgMzAuNzMzNSAzLjE1NjE0IDI5LjgwOTYgMy4xNTYxNCAyOC44MjdWMjMuMTQ0N0wwLjkyNzQ3OSAxNy44Njk2QzAuNTQ1MTE2IDE2Ljk2NDUgMC41Mzc1NTcgMTUuOTY0NSAwLjkwNjM3NiAxNS4wNTM5QzEuMjc1MiAxNC4xNDMzIDEuOTc1OTggMTMuNDMwOSAyLjg3OTkyIDEzLjA0ODFMMy4xNTYxNCAxMi45MzExVjkuMzEyMzdDMy4xNTYxNCA4LjMyOTcyIDMuNTM4MzUgNy40MDU4OCA0LjIzMjM2IDYuNzEwOTlDNC45MjYzOCA2LjAxNjExIDUuODQ5MDYgNS42MzM0MiA2LjgzMDQ4IDUuNjMzNDJIMzkuMTY5M0M0MC4xNTA3IDUuNjMzNDIgNDEuMDczMyA2LjAxNjExIDQxLjc2NzQgNi43MTA5OUM0Mi40NjE0IDcuNDA1ODggNDIuODQzNiA4LjMyOTcyIDQyLjg0MzYgOS4zMTIzN1YxNS4wODU2Wk0yLjI0Mzg2IDE3LjMxMTlMMy4xNTYxNCAxOS40NzEzVjE0LjUwOTNDMi4yMTIzNiAxNS4wNzU3IDEuODAzMDcgMTYuMjY4NyAyLjI0Mzg2IDE3LjMxMTlaTTkuODM2OTQgMzUuMjg0NUMxMC4zMTkxIDM2LjQyNiAxMS42MzkxIDM2Ljk2MTggMTIuNzc5MSAzNi40NzlMMjIuMTYwMyAzMi41MDU2SDguNjYyOTJMOS44MzY5NCAzNS4yODQ1Wk0zOS4xNjk0IDMxLjA3NDVDNDAuNDA3MiAzMS4wNzQ1IDQxLjQxNDMgMzAuMDY2MyA0MS40MTQzIDI4LjgyNjhWOS4zMTIzN0M0MS40MTQzIDguMDcyODYgNDAuNDA3MiA3LjA2NDUxIDM5LjE2OTQgNy4wNjQ1MUg2LjgzMDQ4QzUuNTkyNjggNy4wNjQ1MSA0LjU4NTU5IDguMDcyODYgNC41ODU1OSA5LjMxMjM3VjI4LjgyNjhDNC41ODU1OSAzMC4wNjYyIDUuNTkyNjggMzEuMDc0NSA2LjgzMDQ4IDMxLjA3NDVIMzkuMTY5NFpNNDIuODQzNiAxOC43NTg3VjIzLjcyMDdDNDMuNzg3NCAyMy4xNTQzIDQ0LjE5NjUgMjEuOTYxMyA0My43NTU5IDIwLjkxODFMNDIuODQzNiAxOC43NTg3WiIgZmlsbD0iIzZFNzQ4OCIvPg0KPC9zdmc+DQo=';
6528
6649
 
6529
- const deviceSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDYiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCA0NiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xNF8xNTkyKSI+DQo8cGF0aCBkPSJNMzAuMTU3IDMxLjY1NDNIMy40NzczOEMxLjc3ODc0IDMxLjY1NDMgMC4zOTc3MDUgMzAuMzA4NSAwLjM5NzcwNSAyOC42NTQ5VjI2LjQ2NzJDMC4zOTc3MDUgMjUuOTg5MSAwLjc4ODI1MyAyNS42MDQyIDEuMjcwNTYgMjUuNjA0MkgxNi43NjU0QzE3LjAwMyAyNS42MDQyIDE3LjIyODkgMjUuNjk5OSAxNy4zOTM2IDI1Ljg2NzhMMTguNTIwNSAyNy4wMjdIMjcuMDI1NUMyNy41MDc4IDI3LjAyNyAyNy44OTg0IDI3LjQxMTggMjcuODk4NCAyNy44ODk5QzI3Ljg5ODQgMjguMzY4MSAyNy41MDc4IDI4Ljc1MjkgMjcuMDI1NSAyOC43NTI5SDE4LjE0ODhDMTcuOTExMiAyOC43NTI5IDE3LjY4NTMgMjguNjU3MyAxNy41MjA2IDI4LjQ4OTNMMTYuMzkzNyAyNy4zMzAySDIuMTQzNDFWMjguNjU0OUMyLjE0MzQxIDI5LjM1NyAyLjc0MDk5IDI5LjkyNiAzLjQ3NzM4IDI5LjkyNkgzMC4xNTdDMzAuNjM5MyAyOS45MjYgMzEuMDI5OCAzMC4zMTA5IDMxLjAyOTggMzAuNzg5QzMxLjAyOTggMzEuMjY3MSAzMC42MzkzIDMxLjY1MiAzMC4xNTcgMzEuNjUyVjMxLjY1NDNaTTI5LjkwMDUgMjcuMzMwMkgyOS4yMzQ3QzI4Ljc1MjQgMjcuMzMwMiAyOC4zNjE4IDI2Ljk0NTMgMjguMzYxOCAyNi40NjcyQzI4LjM2MTggMjUuOTg5MSAyOC43NTI0IDI1LjYwNDIgMjkuMjM0NyAyNS42MDQySDI5LjkwMDVDMzAuMzgyOCAyNS42MDQyIDMwLjc3MzQgMjUuOTg5MSAzMC43NzM0IDI2LjQ2NzJDMzAuNzczNCAyNi45NDUzIDMwLjM4MjggMjcuMzMwMiAyOS45MDA1IDI3LjMzMDJaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8cGF0aCBkPSJNMy4zMjIwNyAyNC44MzdDMi44Mzk3NyAyNC44MzcgMi40NDkyMiAyNC40NTIyIDIuNDQ5MjIgMjMuOTc0MVYzLjY3ODE2QzIuNDQ5MjIgMS45Njg1NyAzLjg1Mzc4IDAuNTc2MTcyIDUuNTgwNjYgMC41NzYxNzJINDAuNDE5NEM0Mi4xNDYzIDAuNTc2MTcyIDQzLjU1MDggMS45Njg1NyA0My41NTA4IDMuNjc4MTZWNy4wMzQzOEM0My41NTA4IDcuNTEyNTEgNDMuMTYwMyA3Ljg5OTY3IDQyLjY3OCA3Ljg5OTY3QzQyLjE5NTcgNy44OTk2NyA0MS44MDUxIDcuNTEyNTEgNDEuODA1MSA3LjAzNDM4VjMuNjc4MTZDNDEuODA1MSAyLjkzNDE1IDQxLjE2OTkgMi4zMDQ0MiA0MC40MTk0IDIuMzA0NDJINS41ODA2NkM0LjgzMDE1IDIuMzA0NDIgNC4xOTQ5MiAyLjkzNDE1IDQuMTk0OTIgMy42NzgxNlYyMy45NzQxQzQuMTk0OTIgMjQuNDUyMiAzLjgwNDM3IDI0LjgzNyAzLjMyMjA3IDI0LjgzN1oiIGZpbGw9IiM2RTc0ODgiLz4NCjxwYXRoIGQ9Ik0zOS45NTgyIDUuNTA5MTVIMy4zMjIwN0MyLjgzOTc3IDUuNTA5MTUgMi40NDkyMiA1LjEyMTk4IDIuNDQ5MjIgNC42NDM4NkMyLjQ0OTIyIDQuMTY1NzMgMi44Mzk3NyAzLjc3ODU2IDMuMzIyMDcgMy43Nzg1NkgzOS45NTgyQzQwLjQ0MDUgMy43Nzg1NiA0MC44MzExIDQuMTY1NzMgNDAuODMxMSA0LjY0Mzg2QzQwLjgzMTEgNS4xMjE5OCA0MC40NDA1IDUuNTA5MTUgMzkuOTU4MiA1LjUwOTE1WiIgZmlsbD0iIzZFNzQ4OCIvPg0KPHBhdGggZD0iTTQzLjM5NTYgMzEuNjU0M0gzMy44NTMxQzMyLjY0MzggMzEuNjU0MyAzMS42OTggMzAuNzE2NyAzMS42OTggMjkuNTE3OVYxMC45NTI2QzMxLjY5OCA5Ljc0NjggMzIuNjY1IDguNzY0ODkgMzMuODUzMSA4Ljc2NDg5SDQzLjM5NTZDNDQuNTkwOCA4Ljc2NDg5IDQ1LjYwMjQgOS43Njc3OSA0NS42MDI0IDEwLjk1MjZWMTcuNzY3N0M0NS42MDI0IDE4LjI0NTggNDUuMjExOSAxOC42MzA2IDQ0LjcyOTYgMTguNjMwNkM0NC4yNDczIDE4LjYzMDYgNDMuODU2NyAxOC4yNDU4IDQzLjg1NjcgMTcuNzY3N1YxMC45NTI2QzQzLjg1NjcgMTAuNzE3IDQzLjYzMzIgMTAuNDk1NSA0My4zOTU2IDEwLjQ5NTVIMzMuODUzMUMzMy42Mjk2IDEwLjQ5NTUgMzMuNDQzNyAxMC43MDU0IDMzLjQ0MzcgMTAuOTUyNlYyOS41MTc5QzMzLjQ0MzcgMjkuNzUxMiAzMy42MjAyIDI5LjkyNjEgMzMuODUzMSAyOS45MjYxSDQzLjM5NTZDNDMuNjQ3MyAyOS45MjYxIDQzLjg1NjcgMjkuNzM5NSA0My44NTY3IDI5LjUxNzlWMjAuNjY2N0M0My44NTY3IDIwLjE4ODYgNDQuMjQ3MyAxOS44MDM4IDQ0LjcyOTYgMTkuODAzOEM0NS4yMTE5IDE5LjgwMzggNDUuNjAyNCAyMC4xODg2IDQ1LjYwMjQgMjAuNjY2N1YyOS41MTc5QzQ1LjYwMjQgMzAuNjk1NyA0NC42MTE5IDMxLjY1NDMgNDMuMzk1NiAzMS42NTQzWiIgZmlsbD0iIzZFNzQ4OCIvPg0KPHBhdGggZD0iTTM4LjkzMDIgMjkuMTYxMkgzOC4zMTM4QzM3LjgzMTUgMjkuMTYxMiAzNy40NDA5IDI4Ljc3NjQgMzcuNDQwOSAyOC4yOTgzQzM3LjQ0MDkgMjcuODIwMSAzNy44MzE1IDI3LjQzNTMgMzguMzEzOCAyNy40MzUzSDM4LjkzMDJDMzkuNDEyNSAyNy40MzUzIDM5LjgwMyAyNy44MjAxIDM5LjgwMyAyOC4yOTgzQzM5LjgwMyAyOC43NzY0IDM5LjQxMjUgMjkuMTYxMiAzOC45MzAyIDI5LjE2MTJaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8L2c+DQo8ZGVmcz4NCjxjbGlwUGF0aCBpZD0iY2xpcDBfMTRfMTU5MiI+DQo8cmVjdCB3aWR0aD0iNDUuMjA0NyIgaGVpZ2h0PSIzMS4wNzgyIiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4zOTc3MDUgMC41NzYxNzIpIi8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPC9zdmc+DQo=';
6530
-
6531
6650
  const validationSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDQiIHZpZXdCb3g9IjAgMCA0MCA0NCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xNF8xNjAxKSI+DQo8cGF0aCBkPSJNMTYuNzUxNCAyOS40MTExTDE2LjcyMjggMjMuMjczMUgxNC45NTk2QzEzLjAyODMgMjMuMjczMSAxMS40NTY1IDIxLjc1MzcgMTEuNDU2NSAxOS44ODY0VjMuOTAwMTNDMTEuNDU2NSAyLjAzMjc5IDEyLjk5MzQgMC41MTM0MjggMTQuODgxOCAwLjUxMzQyOEgzNi4zMTUyQzM4LjIwMzYgMC41MTM0MjggMzkuNzM5NiAyLjAzMjc5IDM5LjczOTYgMy45MDAxM1YxOS44ODY0QzM5LjczOTYgMjEuNzUzNyAzOC4yMDM2IDIzLjI3MzEgMzYuMzE1MiAyMy4yNzMxSDI0LjgwMDZDMjQuNzQxNSAyMy4yNzMxIDI0LjY4NTIgMjMuMjkxMiAyNC42NDIyIDIzLjMyNDZMMTYuNzUxNCAyOS40MTExWk0xNC44ODE4IDIuMTQwMzRDMTMuODgxNyAyLjE0MDM0IDEzLjA2NzYgMi45Mjk0IDEzLjA2NzYgMy45MDAxM1YxOS44ODY0QzEzLjA2NzYgMjAuODU3MSAxMy45MTY2IDIxLjY0NjIgMTQuOTYwNSAyMS42NDYySDE3LjE3OTlDMTcuODEyMyAyMS42NDYyIDE4LjMyODUgMjIuMTU2OCAxOC4zMzEyIDIyLjc4NUwxOC4zNDY0IDI2LjEzMzhMMjMuNjY1NCAyMi4wMzEyQzIzLjk4NzQgMjEuNzgyNyAyNC4zOTA5IDIxLjY0NjIgMjQuODAwNiAyMS42NDYySDM2LjMxNTJDMzcuMzE1MyAyMS42NDYyIDM4LjEyOTQgMjAuODU3MSAzOC4xMjk0IDE5Ljg4NjRWMy45MDAxM0MzOC4xMjk0IDIuOTI5NCAzNy4zMTUzIDIuMTQwMzQgMzYuMzE1MiAyLjE0MDM0SDE0Ljg4MThaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8cGF0aCBkPSJNMTcuNDc2OSA0My43MTcxSDUuMzgxNjhDMi41NTc1OCA0My43MTcxIDAuMjYwMzc2IDQxLjM5NiAwLjI2MDM3NiAzOC41NDI2VjExLjU2NTZDMC4yNjAzNzYgOC43MTIxOCAyLjU1NzU4IDYuMzkxMTEgNS4zODE2OCA2LjM5MTExSDkuNTM4NjZWOC4wMTgwM0g1LjM4MTY4QzMuNDQ1ODcgOC4wMTgwMyAxLjg3MDU3IDkuNjA5NyAxLjg3MDU3IDExLjU2NTZWMzguNTQyNkMxLjg3MDU3IDQwLjQ5ODUgMy40NDU4NyA0Mi4wOTAyIDUuMzgxNjggNDIuMDkwMkgxNy40NzY5QzE5LjQxMjcgNDIuMDkwMiAyMC45ODggNDAuNDk4NSAyMC45ODggMzguNTQyNlYyOC45Mjg0SDIyLjU5ODJWMzguNTQyNkMyMi41OTgyIDQxLjM5NiAyMC4zMDEgNDMuNzE3MSAxNy40NzY5IDQzLjcxNzFaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8cGF0aCBkPSJNOS4zODkzNSAxMS44NDIzSDEuMDY1NTVWMTMuNDY5Mkg5LjM4OTM1VjExLjg0MjNaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8cGF0aCBkPSJNMjEuNzkyMyAzNi45MTMxSDEuMDY1NTVWMzguNTRIMjEuNzkyM1YzNi45MTMxWiIgZmlsbD0iIzZFNzQ4OCIvPg0KPHBhdGggZD0iTTI0LjM4NDMgMTIuN0MyNC4zODQzIDEzLjM3MjMgMjQuOTIxNiAxMy45MzExIDI1LjU5ODUgMTMuOTMxMUMyNi4yNzU0IDEzLjkzMTEgMjYuODEyNyAxMy4zNzIzIDI2LjgxMjcgMTIuN0MyNi44MTI3IDEyLjAyNzYgMjYuMjc1NCAxMS40Njg5IDI1LjU5ODUgMTEuNDY4OUMyNC45MjE2IDExLjQ2ODkgMjQuMzg0MyAxMi4wMjc2IDI0LjM4NDMgMTIuN1pNMjUuMjAyNSAxMi43QzI1LjIwMjUgMTIuNDgxOCAyNS4zODAxIDEyLjMwNDEgMjUuNTk4NSAxMi4zMDQxQzI1LjgxNjkgMTIuMzA0MSAyNS45OTQ1IDEyLjQ4MTggMjUuOTk0NSAxMi43QzI1Ljk5NDUgMTIuOTE4MSAyNS44MTY5IDEzLjA5NTggMjUuNTk4NSAxMy4wOTU4QzI1LjM4MDEgMTMuMDk1OCAyNS4yMDI1IDEyLjkxODEgMjUuMjAyNSAxMi43WiIgZmlsbD0iIzZFNzQ4OCIgc3Ryb2tlPSIjNkU3NDg4IiBzdHJva2Utd2lkdGg9IjAuNzQ0ODkxIi8+DQo8cGF0aCBkPSJNMzAuMjQwMSAxMi43QzMwLjI0MDEgMTMuMzcyMyAzMC43Nzc0IDEzLjkzMTEgMzEuNDU0MyAxMy45MzExQzMyLjEzMTIgMTMuOTMxMSAzMi42Njg1IDEzLjM3MjMgMzIuNjY4NSAxMi43QzMyLjY2ODUgMTIuMDI3NiAzMi4xMzEyIDExLjQ2ODkgMzEuNDU0MyAxMS40Njg5QzMwLjc3NzQgMTEuNDY4OSAzMC4yNDAxIDEyLjAyNzYgMzAuMjQwMSAxMi43Wk0zMS4wNTgzIDEyLjdDMzEuMDU4MyAxMi40ODE4IDMxLjIzNTkgMTIuMzA0MSAzMS40NTQzIDEyLjMwNDFDMzEuNjcyNyAxMi4zMDQxIDMxLjg1MDMgMTIuNDgxOCAzMS44NTAzIDEyLjdDMzEuODUwMyAxMi45MTgxIDMxLjY3MjcgMTMuMDk1OCAzMS40NTQzIDEzLjA5NThDMzEuMjM1OSAxMy4wOTU4IDMxLjA1ODMgMTIuOTE4MSAzMS4wNTgzIDEyLjdaIiBmaWxsPSIjNkU3NDg4IiBzdHJva2U9IiM2RTc0ODgiIHN0cm9rZS13aWR0aD0iMC43NDQ4OTEiLz4NCjxwYXRoIGQ9Ik0xOC41Mjg2IDEyLjdDMTguNTI4NiAxMy4zNzIzIDE5LjA2NTkgMTMuOTMxMSAxOS43NDI4IDEzLjkzMTFDMjAuNDE5NyAxMy45MzExIDIwLjk1NyAxMy4zNzIzIDIwLjk1NyAxMi43QzIwLjk1NyAxMi4wMjc2IDIwLjQxOTcgMTEuNDY4OSAxOS43NDI4IDExLjQ2ODlDMTkuMDY1OSAxMS40Njg5IDE4LjUyODYgMTIuMDI3NiAxOC41Mjg2IDEyLjdaTTE5LjM0NjggMTIuN0MxOS4zNDY4IDEyLjQ4MTggMTkuNTI0NCAxMi4zMDQxIDE5Ljc0MjggMTIuMzA0MUMxOS45NjEyIDEyLjMwNDEgMjAuMTM4NyAxMi40ODE4IDIwLjEzODcgMTIuN0MyMC4xMzg3IDEyLjkxODEgMTkuOTYxMiAxMy4wOTU4IDE5Ljc0MjggMTMuMDk1OEMxOS41MjQ0IDEzLjA5NTggMTkuMzQ2OCAxMi45MTgxIDE5LjM0NjggMTIuN1oiIGZpbGw9IiM2RTc0ODgiIHN0cm9rZT0iIzZFNzQ4OCIgc3Ryb2tlLXdpZHRoPSIwLjc0NDg5MSIvPg0KPC9nPg0KPGRlZnM+DQo8Y2xpcFBhdGggaWQ9ImNsaXAwXzE0XzE2MDEiPg0KPHJlY3Qgd2lkdGg9IjM5LjQ3OTIiIGhlaWdodD0iNDMuMjAzNyIgZmlsbD0id2hpdGUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuMjYwMzc2IDAuNTEzNDI4KSIvPg0KPC9jbGlwUGF0aD4NCjwvZGVmcz4NCjwvc3ZnPg0K';
6532
6651
 
6652
+ const deviceSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDYiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCA0NiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xNF8xNTkyKSI+DQo8cGF0aCBkPSJNMzAuMTU3IDMxLjY1NDNIMy40NzczOEMxLjc3ODc0IDMxLjY1NDMgMC4zOTc3MDUgMzAuMzA4NSAwLjM5NzcwNSAyOC42NTQ5VjI2LjQ2NzJDMC4zOTc3MDUgMjUuOTg5MSAwLjc4ODI1MyAyNS42MDQyIDEuMjcwNTYgMjUuNjA0MkgxNi43NjU0QzE3LjAwMyAyNS42MDQyIDE3LjIyODkgMjUuNjk5OSAxNy4zOTM2IDI1Ljg2NzhMMTguNTIwNSAyNy4wMjdIMjcuMDI1NUMyNy41MDc4IDI3LjAyNyAyNy44OTg0IDI3LjQxMTggMjcuODk4NCAyNy44ODk5QzI3Ljg5ODQgMjguMzY4MSAyNy41MDc4IDI4Ljc1MjkgMjcuMDI1NSAyOC43NTI5SDE4LjE0ODhDMTcuOTExMiAyOC43NTI5IDE3LjY4NTMgMjguNjU3MyAxNy41MjA2IDI4LjQ4OTNMMTYuMzkzNyAyNy4zMzAySDIuMTQzNDFWMjguNjU0OUMyLjE0MzQxIDI5LjM1NyAyLjc0MDk5IDI5LjkyNiAzLjQ3NzM4IDI5LjkyNkgzMC4xNTdDMzAuNjM5MyAyOS45MjYgMzEuMDI5OCAzMC4zMTA5IDMxLjAyOTggMzAuNzg5QzMxLjAyOTggMzEuMjY3MSAzMC42MzkzIDMxLjY1MiAzMC4xNTcgMzEuNjUyVjMxLjY1NDNaTTI5LjkwMDUgMjcuMzMwMkgyOS4yMzQ3QzI4Ljc1MjQgMjcuMzMwMiAyOC4zNjE4IDI2Ljk0NTMgMjguMzYxOCAyNi40NjcyQzI4LjM2MTggMjUuOTg5MSAyOC43NTI0IDI1LjYwNDIgMjkuMjM0NyAyNS42MDQySDI5LjkwMDVDMzAuMzgyOCAyNS42MDQyIDMwLjc3MzQgMjUuOTg5MSAzMC43NzM0IDI2LjQ2NzJDMzAuNzczNCAyNi45NDUzIDMwLjM4MjggMjcuMzMwMiAyOS45MDA1IDI3LjMzMDJaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8cGF0aCBkPSJNMy4zMjIwNyAyNC44MzdDMi44Mzk3NyAyNC44MzcgMi40NDkyMiAyNC40NTIyIDIuNDQ5MjIgMjMuOTc0MVYzLjY3ODE2QzIuNDQ5MjIgMS45Njg1NyAzLjg1Mzc4IDAuNTc2MTcyIDUuNTgwNjYgMC41NzYxNzJINDAuNDE5NEM0Mi4xNDYzIDAuNTc2MTcyIDQzLjU1MDggMS45Njg1NyA0My41NTA4IDMuNjc4MTZWNy4wMzQzOEM0My41NTA4IDcuNTEyNTEgNDMuMTYwMyA3Ljg5OTY3IDQyLjY3OCA3Ljg5OTY3QzQyLjE5NTcgNy44OTk2NyA0MS44MDUxIDcuNTEyNTEgNDEuODA1MSA3LjAzNDM4VjMuNjc4MTZDNDEuODA1MSAyLjkzNDE1IDQxLjE2OTkgMi4zMDQ0MiA0MC40MTk0IDIuMzA0NDJINS41ODA2NkM0LjgzMDE1IDIuMzA0NDIgNC4xOTQ5MiAyLjkzNDE1IDQuMTk0OTIgMy42NzgxNlYyMy45NzQxQzQuMTk0OTIgMjQuNDUyMiAzLjgwNDM3IDI0LjgzNyAzLjMyMjA3IDI0LjgzN1oiIGZpbGw9IiM2RTc0ODgiLz4NCjxwYXRoIGQ9Ik0zOS45NTgyIDUuNTA5MTVIMy4zMjIwN0MyLjgzOTc3IDUuNTA5MTUgMi40NDkyMiA1LjEyMTk4IDIuNDQ5MjIgNC42NDM4NkMyLjQ0OTIyIDQuMTY1NzMgMi44Mzk3NyAzLjc3ODU2IDMuMzIyMDcgMy43Nzg1NkgzOS45NTgyQzQwLjQ0MDUgMy43Nzg1NiA0MC44MzExIDQuMTY1NzMgNDAuODMxMSA0LjY0Mzg2QzQwLjgzMTEgNS4xMjE5OCA0MC40NDA1IDUuNTA5MTUgMzkuOTU4MiA1LjUwOTE1WiIgZmlsbD0iIzZFNzQ4OCIvPg0KPHBhdGggZD0iTTQzLjM5NTYgMzEuNjU0M0gzMy44NTMxQzMyLjY0MzggMzEuNjU0MyAzMS42OTggMzAuNzE2NyAzMS42OTggMjkuNTE3OVYxMC45NTI2QzMxLjY5OCA5Ljc0NjggMzIuNjY1IDguNzY0ODkgMzMuODUzMSA4Ljc2NDg5SDQzLjM5NTZDNDQuNTkwOCA4Ljc2NDg5IDQ1LjYwMjQgOS43Njc3OSA0NS42MDI0IDEwLjk1MjZWMTcuNzY3N0M0NS42MDI0IDE4LjI0NTggNDUuMjExOSAxOC42MzA2IDQ0LjcyOTYgMTguNjMwNkM0NC4yNDczIDE4LjYzMDYgNDMuODU2NyAxOC4yNDU4IDQzLjg1NjcgMTcuNzY3N1YxMC45NTI2QzQzLjg1NjcgMTAuNzE3IDQzLjYzMzIgMTAuNDk1NSA0My4zOTU2IDEwLjQ5NTVIMzMuODUzMUMzMy42Mjk2IDEwLjQ5NTUgMzMuNDQzNyAxMC43MDU0IDMzLjQ0MzcgMTAuOTUyNlYyOS41MTc5QzMzLjQ0MzcgMjkuNzUxMiAzMy42MjAyIDI5LjkyNjEgMzMuODUzMSAyOS45MjYxSDQzLjM5NTZDNDMuNjQ3MyAyOS45MjYxIDQzLjg1NjcgMjkuNzM5NSA0My44NTY3IDI5LjUxNzlWMjAuNjY2N0M0My44NTY3IDIwLjE4ODYgNDQuMjQ3MyAxOS44MDM4IDQ0LjcyOTYgMTkuODAzOEM0NS4yMTE5IDE5LjgwMzggNDUuNjAyNCAyMC4xODg2IDQ1LjYwMjQgMjAuNjY2N1YyOS41MTc5QzQ1LjYwMjQgMzAuNjk1NyA0NC42MTE5IDMxLjY1NDMgNDMuMzk1NiAzMS42NTQzWiIgZmlsbD0iIzZFNzQ4OCIvPg0KPHBhdGggZD0iTTM4LjkzMDIgMjkuMTYxMkgzOC4zMTM4QzM3LjgzMTUgMjkuMTYxMiAzNy40NDA5IDI4Ljc3NjQgMzcuNDQwOSAyOC4yOTgzQzM3LjQ0MDkgMjcuODIwMSAzNy44MzE1IDI3LjQzNTMgMzguMzEzOCAyNy40MzUzSDM4LjkzMDJDMzkuNDEyNSAyNy40MzUzIDM5LjgwMyAyNy44MjAxIDM5LjgwMyAyOC4yOTgzQzM5LjgwMyAyOC43NzY0IDM5LjQxMjUgMjkuMTYxMiAzOC45MzAyIDI5LjE2MTJaIiBmaWxsPSIjNkU3NDg4Ii8+DQo8L2c+DQo8ZGVmcz4NCjxjbGlwUGF0aCBpZD0iY2xpcDBfMTRfMTU5MiI+DQo8cmVjdCB3aWR0aD0iNDUuMjA0NyIgaGVpZ2h0PSIzMS4wNzgyIiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4zOTc3MDUgMC41NzYxNzIpIi8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPC9zdmc+DQo=';
6653
+
6533
6654
  const landingValidationCss = "";
6534
6655
 
6535
6656
  const LandingValidation = class {
6536
6657
  constructor(hostRef) {
6537
6658
  registerInstance(this, hostRef);
6538
6659
  this.apiErrorEvent = createEvent(this, "apiError", 7);
6539
- this.device = undefined;
6540
6660
  this.warningText = undefined;
6541
6661
  this.buttonDisabled = undefined;
6662
+ this.baseComponent = new BaseComponent(FlowSteps.Landing);
6663
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
6542
6664
  }
6543
6665
  async componentWillLoad() {
6544
- this.apiCall = new ApiCall();
6666
+ this.baseComponent.apiCall = new ApiCall();
6545
6667
  this.buttonDisabled = false;
6546
6668
  await this.initRequest();
6547
6669
  }
@@ -6549,12 +6671,7 @@ const LandingValidation = class {
6549
6671
  Events.init(window);
6550
6672
  Events.flowStarted();
6551
6673
  if (state.environment !== 'DEMO') {
6552
- try {
6553
- await this.apiCall.AddStep(FlowSteps.Landing);
6554
- }
6555
- catch (e) {
6556
- this.apiErrorEvent.emit(e);
6557
- }
6674
+ await this.baseComponent.initialize();
6558
6675
  }
6559
6676
  }
6560
6677
  async initRequest() {
@@ -6572,8 +6689,9 @@ const LandingValidation = class {
6572
6689
  state.flowStatus = FlowStatus.COMPLETE;
6573
6690
  return;
6574
6691
  }
6575
- if (!(await Cameras.InitCameras(this.device))) {
6576
- if (this.device.isIos)
6692
+ await this.baseComponent.finalize();
6693
+ if (!(await Cameras.InitCameras(state.device))) {
6694
+ if (state.device.mobileOS == MobileOS.iOS)
6577
6695
  sessionStorage.setItem(SessionKeys.RefreshDoneKey, 'false');
6578
6696
  state.flowStatus = FlowStatus.CAMERAERROR;
6579
6697
  }
@@ -6593,7 +6711,8 @@ const LandingValidation = class {
6593
6711
  return;
6594
6712
  state.initialised = false;
6595
6713
  try {
6596
- await this.apiCall.AbortRequest();
6714
+ await this.baseComponent.apiCall.AbortRequest();
6715
+ await this.baseComponent.finalize();
6597
6716
  Events.flowAborted();
6598
6717
  }
6599
6718
  catch (e) {
@@ -9495,7 +9614,8 @@ const MobileRedirect = class {
9495
9614
  this.redirectLink = undefined;
9496
9615
  this.qrCode = undefined;
9497
9616
  this.prefilledPhone = false;
9498
- this.apiCall = new ApiCall();
9617
+ this.baseComponent = new BaseComponent(FlowSteps.MobileRedirect);
9618
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
9499
9619
  this.invalidValue = false;
9500
9620
  this.waitingMobile = false;
9501
9621
  }
@@ -9519,12 +9639,7 @@ const MobileRedirect = class {
9519
9639
  async componentDidLoad() {
9520
9640
  Events.init(window);
9521
9641
  Events.flowStarted();
9522
- try {
9523
- await this.apiCall.AddStep(FlowSteps.MobileRedirect);
9524
- }
9525
- catch (e) {
9526
- this.apiErrorEvent.emit(e);
9527
- }
9642
+ await this.baseComponent.initialize();
9528
9643
  await delay(5000);
9529
9644
  await this.checkStatus();
9530
9645
  while (this.orderStatus == OrderStatuses.Capturing || this.orderStatus == OrderStatuses.Waiting) {
@@ -9533,9 +9648,10 @@ const MobileRedirect = class {
9533
9648
  }
9534
9649
  }
9535
9650
  async checkStatus() {
9536
- this.orderStatus = await this.apiCall.GetStatus(state.requestId);
9651
+ this.orderStatus = await this.baseComponent.apiCall.GetStatus(state.requestId);
9537
9652
  if (this.orderStatus == OrderStatuses.FinishedCapturing) {
9538
9653
  this.waitingMobile = false;
9654
+ await this.baseComponent.finalize();
9539
9655
  state.flowStatus = FlowStatus.COMPLETE;
9540
9656
  }
9541
9657
  if (this.orderStatus == OrderStatuses.NotFound) {
@@ -9558,7 +9674,7 @@ const MobileRedirect = class {
9558
9674
  this.waitingMobile = true;
9559
9675
  this.infoTextTop = MobileRedirectValues.InfoWaiting;
9560
9676
  try {
9561
- await this.apiCall.SendLink(this.redirectLink, this.contact);
9677
+ await this.baseComponent.apiCall.SendLink(this.redirectLink, this.contact);
9562
9678
  }
9563
9679
  catch (e) {
9564
9680
  this.apiErrorEvent.emit(e);
@@ -9590,7 +9706,6 @@ const SelfieCapture = class {
9590
9706
  //this.closeCamera();
9591
9707
  this.eventPhotoCapture.emit(photos);
9592
9708
  };
9593
- this.device = undefined;
9594
9709
  this.videoStarted = undefined;
9595
9710
  this.captureTaken = undefined;
9596
9711
  this.verified = undefined;
@@ -9643,7 +9758,7 @@ const SelfieCapture = class {
9643
9758
  this.openCamera();
9644
9759
  }
9645
9760
  async openCamera() {
9646
- const constraints = this.cameras.GetConstraints('', this.device, true);
9761
+ const constraints = this.cameras.GetConstraints('', state.device, true);
9647
9762
  setTimeout(() => {
9648
9763
  navigator.mediaDevices
9649
9764
  .getUserMedia(constraints)
@@ -9687,7 +9802,7 @@ const SelfieCapture = class {
9687
9802
  }
9688
9803
  render() {
9689
9804
  let cameraStyle;
9690
- if (this.device.isMobile && this.videoStarted) {
9805
+ if (state.device.isMobile && this.videoStarted) {
9691
9806
  cameraStyle = {
9692
9807
  'width': this.captureWidth + 'px',
9693
9808
  'height': this.captureHeight + 'px',
@@ -9700,7 +9815,7 @@ const SelfieCapture = class {
9700
9815
  let titleClass = this.verified ? 'color-black-2 text-center' : 'color-white text-center';
9701
9816
  //let videoClass = this.device.isMobile ? '' : 'video-demo';
9702
9817
  let bgDemo = this.verified ? 'container' : 'container bg-black';
9703
- 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)))));
9704
9819
  }
9705
9820
  get component() { return getElement(this); }
9706
9821
  };
@@ -9719,13 +9834,20 @@ const SmsCodeValidation = class {
9719
9834
  this.code = undefined;
9720
9835
  this.prefilledPhone = false;
9721
9836
  this.canSend = false;
9722
- 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);
9723
9844
  }
9724
9845
  async doAction() {
9725
9846
  try {
9726
9847
  this.canSend = false;
9848
+ await this.baseComponent.finalize();
9727
9849
  if (state.flowStatus == FlowStatus.CODE || state.flowStatus == FlowStatus.CODEERROR) {
9728
- var codeChecked = await this.apiCall.CheckOTPCode(state.requestId, this.code);
9850
+ var codeChecked = await this.baseComponent.apiCall.CheckOTPCode(state.requestId, this.code);
9729
9851
  if (codeChecked === true) {
9730
9852
  state.flowStatus = FlowStatus.ID;
9731
9853
  }
@@ -9734,7 +9856,7 @@ const SmsCodeValidation = class {
9734
9856
  }
9735
9857
  }
9736
9858
  if (state.flowStatus == FlowStatus.PHONE) {
9737
- var codeSent = await this.apiCall.SendOTPCode(state.requestId, this.phoneNumber);
9859
+ var codeSent = await this.baseComponent.apiCall.SendOTPCode(state.requestId, this.phoneNumber);
9738
9860
  if (codeSent === true) {
9739
9861
  state.flowStatus = FlowStatus.CODE;
9740
9862
  }
@@ -9762,17 +9884,7 @@ const SmsCodeValidation = class {
9762
9884
  }
9763
9885
  }
9764
9886
  async componentDidLoad() {
9765
- try {
9766
- if (state.flowStatus == FlowStatus.PHONE) {
9767
- await this.apiCall.AddStep(FlowSteps.OtpSend);
9768
- }
9769
- if (state.flowStatus == FlowStatus.CODE) {
9770
- await this.apiCall.AddStep(FlowSteps.OtpCheck);
9771
- }
9772
- }
9773
- catch (e) {
9774
- this.apiErrorEvent.emit(e);
9775
- }
9887
+ await this.baseComponent.initialize();
9776
9888
  }
9777
9889
  handleChangePhone(ev) {
9778
9890
  let value = ev.target ? ev.target.value : '';
@@ -9813,7 +9925,6 @@ const UserLiveness = class {
9813
9925
  constructor(hostRef) {
9814
9926
  registerInstance(this, hostRef);
9815
9927
  this.apiErrorEvent = createEvent(this, "apiError", 7);
9816
- this.device = undefined;
9817
9928
  this.showError = undefined;
9818
9929
  this.showHowTo = undefined;
9819
9930
  this.selfieFlow = {
@@ -9823,15 +9934,11 @@ const UserLiveness = class {
9823
9934
  photoFile: null,
9824
9935
  recordingFile: null,
9825
9936
  };
9826
- this.apiCall = new ApiCall();
9937
+ this.baseComponent = new BaseComponent(FlowSteps.Selfie);
9938
+ this.baseComponent.setEventEmitter(this.apiErrorEvent);
9827
9939
  }
9828
9940
  async componentDidLoad() {
9829
- try {
9830
- await this.apiCall.AddStep(FlowSteps.Selfie);
9831
- }
9832
- catch (e) {
9833
- this.apiErrorEvent.emit(e);
9834
- }
9941
+ await this.baseComponent.initialize();
9835
9942
  }
9836
9943
  componentWillLoad() {
9837
9944
  this.showHowTo = true;
@@ -9852,7 +9959,7 @@ const UserLiveness = class {
9852
9959
  async captureSelfieImage(event) {
9853
9960
  let selfiePhoto = event.detail;
9854
9961
  if (selfiePhoto.length == 0 || selfiePhoto.size == 0) {
9855
- await this.apiCall.AddLog({ message: 'Empty selfie', blobData: selfiePhoto }, getLogMessage());
9962
+ await this.baseComponent.apiCall.AddLog({ message: 'Empty selfie', blobData: selfiePhoto }, getLogMessage());
9856
9963
  return;
9857
9964
  }
9858
9965
  try {
@@ -9866,7 +9973,7 @@ const UserLiveness = class {
9866
9973
  async capturedSelfieRecording(event) {
9867
9974
  let selfieRecording = event.detail;
9868
9975
  if (selfieRecording.length == 0 || selfieRecording.size == 0) {
9869
- await this.apiCall.AddLog({ message: 'Empty recording', blobData: selfieRecording }, getLogMessage());
9976
+ await this.baseComponent.apiCall.AddLog({ message: 'Empty recording', blobData: selfieRecording }, getLogMessage());
9870
9977
  return;
9871
9978
  }
9872
9979
  let mimeType = selfieRecording.type == Stream.mp4MimeType.type ? Stream.mp4MimeType : Stream.webmMimeType;
@@ -9875,42 +9982,49 @@ const UserLiveness = class {
9875
9982
  await this.uploadRecording();
9876
9983
  }
9877
9984
  catch (e) {
9878
- this.apiErrorEvent.emit(e);
9985
+ if (state.recordingRetryCount < 3) {
9986
+ state.recordingRetryCount++;
9987
+ this.triggerErrorFlow();
9988
+ }
9989
+ else {
9990
+ this.apiErrorEvent.emit(e);
9991
+ }
9879
9992
  }
9880
9993
  }
9881
9994
  async verificationFinished(_event) {
9882
9995
  this.selfieFlow.verificationFinished = true;
9883
- this.endFlow();
9996
+ await this.endFlow();
9884
9997
  }
9885
9998
  async uploadPhoto() {
9886
9999
  if (this.selfieFlow.photoFile == null || this.selfieFlow.photoDone) {
9887
10000
  return;
9888
10001
  }
9889
- 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);
9890
10003
  if (this.selfieFlow.photoDone) {
9891
- this.endFlow();
10004
+ await this.endFlow();
9892
10005
  }
9893
10006
  else {
9894
- this.selfieFlow.photoFile = null;
9895
- this.selfieFlow.recordingFile = null;
9896
- this.showError = true;
10007
+ this.triggerErrorFlow();
9897
10008
  }
9898
10009
  }
9899
10010
  async uploadRecording() {
9900
10011
  if (this.selfieFlow.recordingFile == null || this.selfieFlow.recordingDone) {
9901
10012
  return;
9902
10013
  }
9903
- 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);
9904
10015
  if (this.selfieFlow.recordingDone) {
9905
- this.endFlow();
10016
+ await this.endFlow();
9906
10017
  }
9907
10018
  else {
9908
- this.selfieFlow.photoFile = null;
9909
- this.selfieFlow.recordingFile = null;
9910
- this.showError = true;
10019
+ this.triggerErrorFlow();
9911
10020
  }
9912
10021
  }
9913
- endFlow() {
10022
+ triggerErrorFlow() {
10023
+ this.selfieFlow.photoFile = null;
10024
+ this.selfieFlow.recordingFile = null;
10025
+ this.showError = true;
10026
+ }
10027
+ async endFlow() {
9914
10028
  if (!this.selfieFlow.photoDone) {
9915
10029
  return;
9916
10030
  }
@@ -9920,11 +10034,13 @@ const UserLiveness = class {
9920
10034
  if (!this.selfieFlow.verificationFinished) {
9921
10035
  return;
9922
10036
  }
10037
+ state.recordingRetryCount = 0;
10038
+ await this.baseComponent.finalize();
9923
10039
  state.flowStatus = FlowStatus.COMPLETE;
9924
10040
  }
9925
10041
  render() {
9926
10042
  let howTo = h("how-to-info", { idSide: "" });
9927
- let capture = h("selfie-capture", { device: this.device, id: "camera" });
10043
+ let capture = h("selfie-capture", { id: "camera" });
9928
10044
  let error = h("capture-error", { type: "LIVENESS" });
9929
10045
  return this.showHowTo ? howTo : this.showError ? error : capture;
9930
10046
  }