vishwam-react-ent-sdk 1.0.8 → 1.0.9-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -34,6 +34,25 @@ function _taggedTemplateLiteralLoose(strings, raw) {
34
34
  return strings;
35
35
  }
36
36
 
37
+ // A type of promise-like that resolves synchronously and supports only one observer
38
+
39
+ const _iteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.iterator || (Symbol.iterator = Symbol("Symbol.iterator"))) : "@@iterator";
40
+
41
+ const _asyncIteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.asyncIterator || (Symbol.asyncIterator = Symbol("Symbol.asyncIterator"))) : "@@asyncIterator";
42
+
43
+ // Asynchronously call a function and send errors to recovery continuation
44
+ function _catch(body, recover) {
45
+ try {
46
+ var result = body();
47
+ } catch(e) {
48
+ return recover(e);
49
+ }
50
+ if (result && result.then) {
51
+ return result.then(void 0, recover);
52
+ }
53
+ return result;
54
+ }
55
+
37
56
  var requestToken = function requestToken(url, expiry) {
38
57
  try {
39
58
  var formData = new FormData();
@@ -399,6 +418,13 @@ var videoConstraints = {
399
418
  facingMode: 'user'
400
419
  }
401
420
  };
421
+ var FRONTAL_FACE_RX_MIN = 0.15;
422
+ var FRONTAL_FACE_RX_MAX = 2.53;
423
+ var FRONTAL_FACE_RY_MIN = 0.16;
424
+ var FRONTAL_FACE_RY_MAX = 2.56;
425
+ var FACE_TOO_FAR_RATIO = 6;
426
+ var FACE_TOO_CLOSE_RATIO = 3.2;
427
+ var FACE_MAX_ROLL_DEG = 12;
402
428
 
403
429
  function frontalFaceCheck(landmarks) {
404
430
  if (!landmarks || landmarks.length < 68) {
@@ -421,12 +447,10 @@ function frontalFaceCheck(landmarks) {
421
447
  x: (rightEyeCenter.x - landmarks[30].x) / (landmarks[30].x - leftEyeCenter.x),
422
448
  y: (landmarks[66].y - landmarks[30].y) / (landmarks[30].y - faceMiddlePoint.y)
423
449
  };
424
-
425
- if (ratio.x > 0.75 && ratio.x < 1.33 && ratio.y > 0.56 && ratio.y < 1.56) {
426
- return true;
427
- }
428
-
429
- return false;
450
+ var rollRad = Math.atan2(rightEyeCenter.y - leftEyeCenter.y, rightEyeCenter.x - leftEyeCenter.x);
451
+ var rollDeg = Math.abs(rollRad * 180 / Math.PI);
452
+ var rollOk = rollDeg <= FACE_MAX_ROLL_DEG || rollDeg >= 180 - FACE_MAX_ROLL_DEG;
453
+ return rollOk && ratio.x > FRONTAL_FACE_RX_MIN && ratio.x < FRONTAL_FACE_RX_MAX && ratio.y > FRONTAL_FACE_RY_MIN && ratio.y < FRONTAL_FACE_RY_MAX;
430
454
  }
431
455
 
432
456
  (function polyfillGetUserMedia() {
@@ -489,18 +513,53 @@ function CheckLiveness(_ref) {
489
513
 
490
514
  var _temp4 = function () {
491
515
  if (!stopFaceDetection) {
492
- return Promise.resolve(detectFace()).then(function (detection) {
493
- if (detection) {
494
- var isFrontal = frontalFaceCheck(detection.landmarks.positions);
495
-
496
- if (isFrontal) {
497
- setFrontal(true);
498
- } else {
516
+ return Promise.resolve(detectFace()).then(function (detections) {
517
+ if (detections.length > 1) {
518
+ setFrontal(false);
519
+ setIsTooFar(false);
520
+ setIsTooClose(false);
521
+ setGuidanceText(multipleFacesMessageText);
522
+ } else if (detections.length === 0) {
523
+ setFrontal(false);
524
+ setIsTooFar(false);
525
+ setIsTooClose(false);
526
+ setGuidanceText(noFaceMessageText);
527
+ } else {
528
+ var _detections$0$detecti = detections[0].detection.box,
529
+ width = _detections$0$detecti.width,
530
+ height = _detections$0$detecti.height;
531
+ var videoEl = webcamRef.current;
532
+ var faceArea = width * height;
533
+ var videoArea = (videoEl === null || videoEl === void 0 ? void 0 : videoEl.videoWidth) * (videoEl === null || videoEl === void 0 ? void 0 : videoEl.videoHeight);
534
+ var faceRatio = videoArea / faceArea;
535
+
536
+ if (faceRatio > FACE_TOO_FAR_RATIO) {
537
+ setIsTooFar(true);
538
+ setIsTooClose(false);
539
+ setFrontal(false);
540
+ setGuidanceText('');
541
+ } else if (faceRatio < FACE_TOO_CLOSE_RATIO) {
542
+ setIsTooFar(false);
543
+ setIsTooClose(true);
499
544
  setFrontal(false);
545
+ setGuidanceText('');
546
+ } else {
547
+ setIsTooFar(false);
548
+ setIsTooClose(false);
549
+ var isFrontal = frontalFaceCheck(detections[0].landmarks.positions);
550
+ setFrontal(isFrontal);
551
+ setGuidanceText(isFrontal ? '' : straightFaceMessageText);
500
552
  }
501
- } else {
553
+ }
554
+
555
+ if (!navigator.onLine) {
502
556
  setFrontal(false);
557
+ setIsTooFar(false);
558
+ setIsTooClose(false);
559
+ setGuidanceText('');
503
560
  }
561
+
562
+ setLoadingText('');
504
563
  });
505
564
  }
506
565
  }();
@@ -573,8 +632,42 @@ function CheckLiveness(_ref) {
573
632
  var detectFace = function detectFace() {
574
633
  try {
575
634
  var videoEl = document.getElementById('webcam');
635
+
636
+ if (!videoEl) {
637
+ return Promise.resolve([]);
638
+ }
639
+
576
640
  var options = new faceapi.TinyFaceDetectorOptions();
577
- return Promise.resolve(faceapi.detectSingleFace(videoEl, options).withFaceLandmarks(true));
641
+
642
+ if (videoEl.readyState !== HTMLVideoElement.HAVE_ENOUGH_DATA) {
643
+ return Promise.resolve(new Promise(function (resolve) {
644
+ videoEl.addEventListener('loadeddata', function () {
645
+ try {
646
+ var _temp6 = _catch(function () {
647
+ return Promise.resolve(faceapi.detectAllFaces(videoEl, options).withFaceLandmarks(true)).then(function (result) {
648
+ resolve(result);
649
+ });
650
+ }, function (error) {
651
+ console.error('Face detection error:', error);
652
+ resolve([]);
653
+ });
654
+
655
+ return Promise.resolve(_temp6 && _temp6.then ? _temp6.then(function () {}) : void 0);
656
+ } catch (e) {
657
+ return Promise.reject(e);
658
+ }
659
+ }, {
660
+ once: true
661
+ });
662
+ }));
663
+ }
664
+
665
+ return Promise.resolve(_catch(function () {
666
+ return Promise.resolve(faceapi.detectAllFaces(videoEl, options).withFaceLandmarks(true));
667
+ }, function (error) {
668
+ console.error('Face detection error:', error);
669
+ return [];
670
+ }));
578
671
  } catch (e) {
579
672
  return Promise.reject(e);
580
673
  }
@@ -589,6 +682,11 @@ function CheckLiveness(_ref) {
589
682
  storeId = _ref.storeId,
590
683
  whiteBackground = _ref.whiteBackground,
591
684
  expiryIn = _ref.expiryIn,
685
+ tooFarMessage = _ref.tooFarMessage,
686
+ tooCloseMessage = _ref.tooCloseMessage,
687
+ multipleFacesMessage = _ref.multipleFacesMessage,
688
+ noFaceMessage = _ref.noFaceMessage,
689
+ straightFaceMessage = _ref.straightFaceMessage,
592
690
  getLivenessResponse = _ref.getLivenessResponse;
593
691
  var webcamRef = React.useRef();
594
692
 
@@ -608,10 +706,27 @@ function CheckLiveness(_ref) {
608
706
  cameraAvailable = _React$useState[0],
609
707
  setCameraAvailable = _React$useState[1];
610
708
 
611
- var _useState4 = React.useState('Please wait, while the face detector is initializing'),
612
- loadingText = _useState4[0],
613
- setLoadingText = _useState4[1];
709
+ var _useState4 = React.useState(false),
710
+ isTooFar = _useState4[0],
711
+ setIsTooFar = _useState4[1];
712
+
713
+ var _useState5 = React.useState(false),
714
+ isTooClose = _useState5[0],
715
+ setIsTooClose = _useState5[1];
614
716
 
717
+ var _useState6 = React.useState(''),
718
+ guidanceText = _useState6[0],
719
+ setGuidanceText = _useState6[1];
720
+
721
+ var _useState7 = React.useState('Please wait, while the face detector is initializing'),
722
+ loadingText = _useState7[0],
723
+ setLoadingText = _useState7[1];
724
+
725
+ var tooFarMessageText = tooFarMessage || 'Move a little closer';
726
+ var tooCloseMessageText = tooCloseMessage || 'Move a little further away';
727
+ var multipleFacesMessageText = multipleFacesMessage || 'Multiple faces detected. Only one person is allowed.';
728
+ var noFaceMessageText = noFaceMessage || 'No face detected. Keep your face in the circle.';
729
+ var straightFaceMessageText = straightFaceMessage || 'Look straight at the camera.';
615
730
  var interval;
616
731
  var videoStream = null;
617
732
  var stopFaceDetection = false;
@@ -650,7 +765,7 @@ function CheckLiveness(_ref) {
650
765
 
651
766
  console.log('came here return');
652
767
 
653
- if (!videoStream) {
768
+ if (videoStream) {
654
769
  videoStream.getTracks().forEach(function (track) {
655
770
  track.stop();
656
771
  });
@@ -817,7 +932,31 @@ function CheckLiveness(_ref) {
817
932
  marginBottom: '0',
818
933
  fontWeight: '400'
819
934
  }
820
- }, loadingText), /*#__PURE__*/React__default.createElement(Button, {
935
+ }, loadingText), isTooFar ? /*#__PURE__*/React__default.createElement(Text, {
936
+ style: {
937
+ width: '75%',
938
+ fontSize: '1rem',
939
+ marginTop: '1%',
940
+ marginBottom: '0',
941
+ fontWeight: '400'
942
+ }
943
+ }, tooFarMessageText) : null, isTooClose ? /*#__PURE__*/React__default.createElement(Text, {
944
+ style: {
945
+ width: '75%',
946
+ fontSize: '1rem',
947
+ marginTop: '1%',
948
+ marginBottom: '0',
949
+ fontWeight: '400'
950
+ }
951
+ }, tooCloseMessageText) : null, guidanceText ? /*#__PURE__*/React__default.createElement(Text, {
952
+ style: {
953
+ width: '75%',
954
+ fontSize: '1rem',
955
+ marginTop: '1%',
956
+ marginBottom: '0',
957
+ fontWeight: '400'
958
+ }
959
+ }, guidanceText) : null, /*#__PURE__*/React__default.createElement(Button, {
821
960
  disabled: disabled || !frontal,
822
961
  onClick: capture
823
962
  }, disabled || frontal ? /*#__PURE__*/React__default.createElement(SvgEnabled, {
@@ -865,7 +1004,31 @@ function CheckLiveness(_ref) {
865
1004
  marginBottom: '0',
866
1005
  fontWeight: '400'
867
1006
  }
868
- }, loadingText), cameraAvailable ? /*#__PURE__*/React__default.createElement("div", null) : /*#__PURE__*/React__default.createElement(Text, {
1007
+ }, loadingText), isTooFar ? /*#__PURE__*/React__default.createElement(Text, {
1008
+ style: {
1009
+ width: '75%',
1010
+ fontSize: '1rem',
1011
+ marginTop: '1%',
1012
+ marginBottom: '0',
1013
+ fontWeight: '400'
1014
+ }
1015
+ }, tooFarMessageText) : null, isTooClose ? /*#__PURE__*/React__default.createElement(Text, {
1016
+ style: {
1017
+ width: '75%',
1018
+ fontSize: '1rem',
1019
+ marginTop: '1%',
1020
+ marginBottom: '0',
1021
+ fontWeight: '400'
1022
+ }
1023
+ }, tooCloseMessageText) : null, guidanceText ? /*#__PURE__*/React__default.createElement(Text, {
1024
+ style: {
1025
+ width: '75%',
1026
+ fontSize: '1rem',
1027
+ marginTop: '1%',
1028
+ marginBottom: '0',
1029
+ fontWeight: '400'
1030
+ }
1031
+ }, guidanceText) : null, cameraAvailable ? /*#__PURE__*/React__default.createElement("div", null) : /*#__PURE__*/React__default.createElement(Text, {
869
1032
  style: {
870
1033
  width: '75%',
871
1034
  fontSize: '1rem',
@@ -913,25 +1076,6 @@ function dataURItoBlob(dataURI, imageType) {
913
1076
  return bb;
914
1077
  }
915
1078
 
916
- // A type of promise-like that resolves synchronously and supports only one observer
917
-
918
- const _iteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.iterator || (Symbol.iterator = Symbol("Symbol.iterator"))) : "@@iterator";
919
-
920
- const _asyncIteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.asyncIterator || (Symbol.asyncIterator = Symbol("Symbol.asyncIterator"))) : "@@asyncIterator";
921
-
922
- // Asynchronously call a function and send errors to recovery continuation
923
- function _catch(body, recover) {
924
- try {
925
- var result = body();
926
- } catch(e) {
927
- return recover(e);
928
- }
929
- if (result && result.then) {
930
- return result.then(void 0, recover);
931
- }
932
- return result;
933
- }
934
-
935
1079
  var _path$1, _path2$1;
936
1080
 
937
1081
  function _extends$4() {