@aws-amplify/ui-react-liveness 1.0.0 → 1.0.1

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 (41) hide show
  1. package/dist/esm/components/FaceLivenessDetector/FaceLivenessDetector.mjs +1 -1
  2. package/dist/esm/components/FaceLivenessDetector/LivenessCheck/LivenessCameraModule.mjs +1 -1
  3. package/dist/esm/components/FaceLivenessDetector/LivenessCheck/LivenessCheck.mjs +1 -1
  4. package/dist/esm/components/FaceLivenessDetector/StartLiveness/StartLiveness.mjs +1 -1
  5. package/dist/esm/components/FaceLivenessDetector/service/machine/index.mjs +1 -1
  6. package/dist/esm/components/FaceLivenessDetector/service/types/error.mjs +1 -0
  7. package/dist/esm/components/FaceLivenessDetector/service/types/liveness.mjs +1 -1
  8. package/dist/esm/components/FaceLivenessDetector/service/utils/blazefaceFaceDetection.mjs +1 -1
  9. package/dist/esm/components/FaceLivenessDetector/service/utils/freshnessColorDisplay.mjs +1 -1
  10. package/dist/esm/components/FaceLivenessDetector/service/utils/liveness.mjs +1 -1
  11. package/dist/esm/components/FaceLivenessDetector/service/utils/streamProvider.mjs +1 -1
  12. package/dist/esm/components/FaceLivenessDetector/service/utils/videoRecorder.mjs +1 -1
  13. package/dist/esm/components/FaceLivenessDetector/shared/DefaultStartScreenComponents.mjs +1 -1
  14. package/dist/esm/components/FaceLivenessDetector/shared/FaceLivenessErrorModal.mjs +1 -1
  15. package/dist/esm/components/FaceLivenessDetector/shared/Hint.mjs +1 -1
  16. package/dist/index.js +1 -1
  17. package/dist/styles.css +1 -1
  18. package/dist/types/components/FaceLivenessDetector/FaceLivenessDetector.d.ts +1 -1
  19. package/dist/types/components/FaceLivenessDetector/LivenessCheck/LivenessCameraModule.d.ts +4 -4
  20. package/dist/types/components/FaceLivenessDetector/LivenessCheck/LivenessCheck.d.ts +2 -2
  21. package/dist/types/components/FaceLivenessDetector/displayText.d.ts +6 -6
  22. package/dist/types/components/FaceLivenessDetector/hooks/useLivenessActor.d.ts +1 -1
  23. package/dist/types/components/FaceLivenessDetector/hooks/useLivenessSelector.d.ts +1 -1
  24. package/dist/types/components/FaceLivenessDetector/service/machine/index.d.ts +3 -3
  25. package/dist/types/components/FaceLivenessDetector/service/types/error.d.ts +13 -0
  26. package/dist/types/components/FaceLivenessDetector/service/types/faceDetection.d.ts +5 -4
  27. package/dist/types/components/FaceLivenessDetector/service/types/index.d.ts +1 -0
  28. package/dist/types/components/FaceLivenessDetector/service/types/liveness.d.ts +5 -18
  29. package/dist/types/components/FaceLivenessDetector/service/types/machine.d.ts +32 -30
  30. package/dist/types/components/FaceLivenessDetector/service/types/service.d.ts +0 -69
  31. package/dist/types/components/FaceLivenessDetector/service/utils/blazefaceFaceDetection.d.ts +1 -1
  32. package/dist/types/components/FaceLivenessDetector/service/utils/eventUtils.d.ts +1 -5
  33. package/dist/types/components/FaceLivenessDetector/service/utils/freshnessColorDisplay.d.ts +0 -1
  34. package/dist/types/components/FaceLivenessDetector/service/utils/liveness.d.ts +1 -1
  35. package/dist/types/components/FaceLivenessDetector/service/utils/support.d.ts +0 -4
  36. package/dist/types/components/FaceLivenessDetector/service/utils/videoRecorder.d.ts +0 -1
  37. package/dist/types/components/FaceLivenessDetector/shared/FaceLivenessErrorModal.d.ts +1 -1
  38. package/dist/types/components/FaceLivenessDetector/shared/Hint.d.ts +5 -5
  39. package/dist/types/version.d.ts +1 -1
  40. package/package.json +7 -6
  41. package/dist/esm/node_modules/tslib/tslib.es6.mjs +0 -1
@@ -1 +1 @@
1
- import*as e from"react";import{useInterpret as t,useActor as s}from"@xstate/react";import{livenessMachine as r}from"./service/machine/index.mjs";import"./service/types/liveness.mjs";import"@tensorflow/tfjs-core";import"@tensorflow-models/blazeface";import"@tensorflow/tfjs-backend-wasm";import"@tensorflow/tfjs-backend-cpu";import"@aws-amplify/core";import"./service/utils/liveness.mjs";import"./service/utils/streamProvider.mjs";import"./service/utils/freshnessColorDisplay.mjs";import{View as o,Flex as i}from"@aws-amplify/ui-react";import{FaceLivenessDetectorProvider as n}from"./providers/FaceLivenessDetectorProvider.mjs";import{StartLiveness as m}from"./StartLiveness/StartLiveness.mjs";import{LivenessCheck as a}from"./LivenessCheck/LivenessCheck.mjs";import{getVideoConstraints as c}from"./StartLiveness/helpers.mjs";import{getDisplayText as l}from"./utils/getDisplayText.mjs";function p(p){const{disableInstructionScreen:f=!1,components:v,config:u,displayText:d}=p,y=e.useRef(null),{hintDisplayText:x,cameraDisplayText:j,instructionDisplayText:D,streamDisplayText:T,errorDisplayText:h}=l(d),E=t(r,{devTools:"development"===process.env.NODE_ENV,context:{componentProps:Object.assign(Object.assign({},p),{config:null!=u?u:{}})}}),[b,L]=s(E),w=b.matches("start")||b.matches("userCancel"),C=e.useCallback((()=>{const e=c();L({type:"BEGIN",data:{videoConstraints:e}})}),[L]);return e.useLayoutEffect((()=>{f&&w&&C()}),[C,f,w]),e.createElement(o,{className:"liveness-detector",testId:"liveness-detector"},e.createElement(n,{componentProps:p,service:E},e.createElement(i,{direction:"column",ref:y},w?e.createElement(m,{beginLivenessCheck:C,components:v,instructionDisplayText:D}):e.createElement(a,{hintDisplayText:x,cameraDisplayText:j,streamDisplayText:T,errorDisplayText:h,components:v}))))}export{p as default};
1
+ import*as e from"react";import{useInterpret as t,useActor as s}from"@xstate/react";import{livenessMachine as r}from"./service/machine/index.mjs";import"./service/types/liveness.mjs";import"./service/types/error.mjs";import"@tensorflow/tfjs-core";import"@tensorflow-models/blazeface";import"@tensorflow/tfjs-backend-wasm";import"@tensorflow/tfjs-backend-cpu";import"@aws-amplify/core";import"./service/utils/liveness.mjs";import"./service/utils/streamProvider.mjs";import"./service/utils/freshnessColorDisplay.mjs";import{View as o,Flex as i}from"@aws-amplify/ui-react";import{FaceLivenessDetectorProvider as m}from"./providers/FaceLivenessDetectorProvider.mjs";import{StartLiveness as n}from"./StartLiveness/StartLiveness.mjs";import{LivenessCheck as a}from"./LivenessCheck/LivenessCheck.mjs";import{getVideoConstraints as c}from"./StartLiveness/helpers.mjs";import{getDisplayText as p}from"./utils/getDisplayText.mjs";const l="liveness-detector";function f(f){const{disableInstructionScreen:v=!1,components:u,config:y,displayText:d}=f,j=e.useRef(null),{hintDisplayText:x,cameraDisplayText:D,instructionDisplayText:T,streamDisplayText:h,errorDisplayText:E}=p(d),b=t(r,{devTools:"development"===process.env.NODE_ENV,context:{componentProps:Object.assign(Object.assign({},f),{config:null!=y?y:{}})}}),[L,w]=s(b),C=L.matches("start")||L.matches("userCancel"),g=e.useCallback((()=>{const e=c();w({type:"BEGIN",data:{videoConstraints:e}})}),[w]);return e.useLayoutEffect((()=>{v&&C&&g()}),[g,v,C]),e.createElement(o,{className:l,testId:l},e.createElement(m,{componentProps:f,service:b},e.createElement(i,{direction:"column",ref:j},C?e.createElement(n,{beginLivenessCheck:g,components:u,instructionDisplayText:T}):e.createElement(a,{hintDisplayText:x,cameraDisplayText:D,streamDisplayText:h,errorDisplayText:E,components:u}))))}export{f as default};
@@ -1 +1 @@
1
- import e,{useRef as t,useState as r}from"react";import a from"react-countdown-circle-timer";import o from"classnames";import{Loader as s,useTheme as i,Flex as n,View as c,Text as m}from"@aws-amplify/ui-react";import"../service/machine/index.mjs";import{FaceMatchState as l}from"../service/types/liveness.mjs";import"@tensorflow/tfjs-core";import"@tensorflow-models/blazeface";import"@tensorflow/tfjs-backend-wasm";import"@tensorflow/tfjs-backend-cpu";import"@aws-amplify/core";import"../service/utils/liveness.mjs";import"../service/utils/streamProvider.mjs";import"../service/utils/freshnessColorDisplay.mjs";import{useLivenessActor as d}from"../hooks/useLivenessActor.mjs";import{useLivenessSelector as h,createLivenessSelector as p}from"../hooks/useLivenessSelector.mjs";import{useMediaStreamInVideo as v}from"../hooks/useMediaStreamInVideo.mjs";import{CancelButton as u}from"../shared/CancelButton.mjs";import{selectErrorState as f,Hint as E}from"../shared/Hint.mjs";import{MatchIndicator as C}from"../shared/MatchIndicator.mjs";import{Overlay as y}from"../shared/Overlay.mjs";import{RecordingIcon as g}from"../shared/RecordingIcon.mjs";import{LivenessClassNames as j}from"../types/classNames.mjs";import{renderErrorModal as w,FaceLivenessErrorModal as N}from"../shared/FaceLivenessErrorModal.mjs";const T=p((e=>{var t;return null===(t=e.context.videoAssociatedParams)||void 0===t?void 0:t.videoConstraints})),x=p((e=>{var t;return null===(t=e.context.videoAssociatedParams)||void 0===t?void 0:t.videoMediaStream})),I=p((e=>e.context.faceMatchAssociatedParams.faceMatchPercentage)),A=p((e=>e.context.faceMatchAssociatedParams.faceMatchState)),M=e.createElement(s,{size:"large",className:j.Loader,"data-testid":"centered-loader"}),D=s=>{const{isMobileScreen:p,isRecordingStopped:D,streamDisplayText:b,hintDisplayText:k,errorDisplayText:R,components:S,testId:O}=s,{cancelLivenessCheckText:L,recordingIndicatorText:P}=b,{ErrorView:F=N}=null!=S?S:{},{tokens:_}=i(),[z,W]=d(),H=h(x),V=h(T),$=h(I),B=h(A),G=h(f),X=[l.TOO_FAR,l.CANT_IDENTIFY,l.FACE_IDENTIFIED],{videoRef:Y,videoWidth:q,videoHeight:J}=v(H,V),K=t(null),Q=t(null),[U,Z]=r(!1),[ee,te]=r(!1),re=z.matches("cameraCheck"),ae=z.matches("notRecording"),oe=z.matches("recording"),se=z.matches("checkSucceeded"),ie=z.matches({recording:"flashFreshnessColors"}),[ne,ce]=r(q),[me,le]=r(J),[de,he]=r((()=>q&&J?q/J:0));e.useLayoutEffect((()=>{ee&&W({type:"SET_DOM_AND_CAMERA_DETAILS",data:{videoEl:Y.current,canvasEl:K.current,freshnessColorEl:Q.current,isMobile:p}}),Y.current&&(ce(Y.current.videoWidth),le(Y.current.videoHeight),he(Y.current.videoWidth/Y.current.videoHeight))}),[W,Y,ee,p]);return re?e.createElement(n,{height:J,width:"100%",position:"relative"},M):e.createElement(n,{className:o(j.CameraModule,p&&`${j.CameraModule}--mobile`),"data-testid":O},!ee&&M,e.createElement(c,{as:"canvas",ref:Q,className:j.FreshnessCanvas,hidden:!0}),e.createElement(c,{className:j.VideoAnchor,style:{aspectRatio:`${de}`}},e.createElement("video",{ref:Y,muted:!0,autoPlay:!0,playsInline:!0,style:{transform:"scaleX(-1)"},width:ne,height:me,onCanPlay:()=>{te(!0),Z(!0)},"data-testid":"video",className:j.Video}),e.createElement(n,{className:o(j.OvalCanvas,p&&`${j.OvalCanvas}--mobile`,D&&j.FadeOut)},e.createElement(c,{as:"canvas",width:"100%",height:"100%",ref:K})),oe&&e.createElement(c,{className:j.RecordingIconContainer},e.createElement(g,null,P)),!se&&e.createElement(c,{className:j.CancelContainer},e.createElement(u,{ariaLabel:L})),U&&e.createElement(y,{anchorOrigin:{horizontal:"center",vertical:oe&&!ie?"start":"space-between"},className:j.InstructionOverlay},e.createElement(E,{hintDisplayText:k}),G&&e.createElement(F,{onRetry:()=>{W({type:"CANCEL"})}},w({errorState:G,overrideErrorDisplayText:R})),oe&&X.includes(B)?e.createElement(C,{percentage:$}):null,ae&&e.createElement(c,{className:j.CountdownContainer,testId:"liveness-camera-countdown-timer"},e.createElement(a.CountdownCircleTimer,{isPlaying:ae,size:85,strokeWidth:8,duration:3,rotation:"counterclockwise",colors:"#40aabf",trailColor:`${_.colors.background.primary}`,onComplete:()=>{W({type:"START_RECORDING"})}},(({remainingTime:t})=>e.createElement(m,{fontSize:"xxxl",fontWeight:"bold"},t)))))))};export{D as LivenessCameraModule,I as selectFaceMatchPercentage,A as selectFaceMatchState,T as selectVideoConstraints,x as selectVideoStream};
1
+ import e,{useRef as t,useState as r}from"react";import a from"react-countdown-circle-timer";import o from"classnames";import{Loader as s,useTheme as i,Flex as n,View as c,Text as m}from"@aws-amplify/ui-react";import"../service/machine/index.mjs";import{FaceMatchState as l}from"../service/types/liveness.mjs";import"../service/types/error.mjs";import"@tensorflow/tfjs-core";import"@tensorflow-models/blazeface";import"@tensorflow/tfjs-backend-wasm";import"@tensorflow/tfjs-backend-cpu";import"@aws-amplify/core";import"../service/utils/liveness.mjs";import"../service/utils/streamProvider.mjs";import"../service/utils/freshnessColorDisplay.mjs";import{useLivenessActor as d}from"../hooks/useLivenessActor.mjs";import{useLivenessSelector as h,createLivenessSelector as p}from"../hooks/useLivenessSelector.mjs";import{useMediaStreamInVideo as v}from"../hooks/useMediaStreamInVideo.mjs";import{CancelButton as u}from"../shared/CancelButton.mjs";import{selectErrorState as f,Hint as E}from"../shared/Hint.mjs";import{MatchIndicator as C}from"../shared/MatchIndicator.mjs";import{Overlay as y}from"../shared/Overlay.mjs";import{RecordingIcon as g}from"../shared/RecordingIcon.mjs";import{LivenessClassNames as j}from"../types/classNames.mjs";import{renderErrorModal as T,FaceLivenessErrorModal as w}from"../shared/FaceLivenessErrorModal.mjs";const N=p((e=>{var t;return null===(t=e.context.videoAssociatedParams)||void 0===t?void 0:t.videoConstraints})),x=p((e=>{var t;return null===(t=e.context.videoAssociatedParams)||void 0===t?void 0:t.videoMediaStream})),A=p((e=>e.context.faceMatchAssociatedParams.faceMatchPercentage)),I=p((e=>e.context.faceMatchAssociatedParams.faceMatchState)),M=e.createElement(s,{size:"large",className:j.Loader,"data-testid":"centered-loader"}),D=s=>{const{isMobileScreen:p,isRecordingStopped:D,streamDisplayText:b,hintDisplayText:k,errorDisplayText:R,components:S,testId:O}=s,{cancelLivenessCheckText:L,recordingIndicatorText:P}=b,{ErrorView:F=w}=null!=S?S:{},{tokens:_}=i(),[z,H]=d(),W=h(x),V=h(N),$=h(A),B=h(I),G=h(f),X=[l.TOO_FAR,l.CANT_IDENTIFY,l.FACE_IDENTIFIED,l.MATCHED],{videoRef:Y,videoWidth:q,videoHeight:J}=v(W,V),K=t(null),Q=t(null),[U,Z]=r(!1),[ee,te]=r(!1),re=z.matches("cameraCheck"),ae=z.matches("notRecording"),oe=z.matches("recording"),se=z.matches("checkSucceeded"),ie=z.matches({recording:"flashFreshnessColors"}),[ne,ce]=r(q),[me,le]=r(J),[de,he]=r((()=>q&&J?q/J:0));e.useLayoutEffect((()=>{ee&&H({type:"SET_DOM_AND_CAMERA_DETAILS",data:{videoEl:Y.current,canvasEl:K.current,freshnessColorEl:Q.current,isMobile:p}}),Y.current&&(ce(Y.current.videoWidth),le(Y.current.videoHeight),he(Y.current.videoWidth/Y.current.videoHeight))}),[H,Y,ee,p]);return re?e.createElement(n,{height:J,width:"100%",position:"relative"},M):e.createElement(n,{className:o(j.CameraModule,p&&`${j.CameraModule}--mobile`),"data-testid":O},!ee&&M,e.createElement(c,{as:"canvas",ref:Q,className:j.FreshnessCanvas,hidden:!0}),e.createElement(c,{className:j.VideoAnchor,style:{aspectRatio:`${de}`}},e.createElement("video",{ref:Y,muted:!0,autoPlay:!0,playsInline:!0,style:{transform:"scaleX(-1)"},width:ne,height:me,onCanPlay:()=>{te(!0),Z(!0)},"data-testid":"video",className:j.Video}),e.createElement(n,{className:o(j.OvalCanvas,p&&`${j.OvalCanvas}--mobile`,D&&j.FadeOut)},e.createElement(c,{as:"canvas",width:"100%",height:"100%",ref:K})),oe&&e.createElement(c,{className:j.RecordingIconContainer},e.createElement(g,null,P)),!se&&e.createElement(c,{className:j.CancelContainer},e.createElement(u,{ariaLabel:L})),U&&e.createElement(y,{anchorOrigin:{horizontal:"center",vertical:oe&&!ie?"start":"space-between"},className:j.InstructionOverlay},e.createElement(E,{hintDisplayText:k}),G&&e.createElement(F,{onRetry:()=>{H({type:"CANCEL"})}},T({errorState:G,overrideErrorDisplayText:R})),oe&&!ie&&X.includes(B)?e.createElement(C,{percentage:$}):null,ae&&e.createElement(c,{className:j.CountdownContainer,testId:"liveness-camera-countdown-timer"},e.createElement(a.CountdownCircleTimer,{isPlaying:ae,size:85,strokeWidth:8,duration:3,rotation:"counterclockwise",colors:"#40aabf",trailColor:`${_.colors.background.primary}`,onComplete:()=>{H({type:"START_RECORDING"})}},(({remainingTime:t})=>e.createElement(m,{fontSize:"xxxl",fontWeight:"bold"},t)))))))};export{D as LivenessCameraModule,A as selectFaceMatchPercentage,I as selectFaceMatchState,N as selectVideoConstraints,x as selectVideoStream};
@@ -1 +1 @@
1
- import*as e from"react";import{Flex as t,Text as r,Button as s,View as i}from"@aws-amplify/ui-react";import"../service/machine/index.mjs";import{LivenessErrorState as o}from"../service/types/liveness.mjs";import"@tensorflow/tfjs-core";import"@tensorflow-models/blazeface";import"@tensorflow/tfjs-backend-wasm";import"@tensorflow/tfjs-backend-cpu";import"@aws-amplify/core";import"../service/utils/liveness.mjs";import"../service/utils/streamProvider.mjs";import"../service/utils/freshnessColorDisplay.mjs";import{LivenessCameraModule as a}from"./LivenessCameraModule.mjs";import{useLivenessActor as n}from"../hooks/useLivenessActor.mjs";import{useLivenessSelector as m,createLivenessSelector as c}from"../hooks/useLivenessSelector.mjs";import"@aws-amplify/ui";import{isMobileScreen as l,getLandscapeMediaQuery as p}from"../utils/device.mjs";import{CancelButton as d}from"../shared/CancelButton.mjs";import{defaultErrorDisplayText as u}from"../displayText.mjs";import{LandscapeErrorModal as f}from"../shared/LandscapeErrorModal.mjs";const E=c((e=>e.context.errorState)),g=c((e=>e.context.isRecordingStopped)),y=({hintDisplayText:c,cameraDisplayText:y,streamDisplayText:x,errorDisplayText:h,components:R})=>{const[T,A]=n(),v=m(E),j=m(g),C=T.matches("permissionDenied"),M=l(),b=()=>{A({type:"RETRY_CAMERA_CHECK"})},{cameraMinSpecificationsHeadingText:L,cameraMinSpecificationsMessageText:k,cameraNotFoundHeadingText:D,cameraNotFoundMessageText:w,retryCameraPermissionsText:S}=y,{cancelLivenessCheckText:_}=x;e.useLayoutEffect((()=>{if(M){const e=e=>{e&&A({type:"MOBILE_LANDSCAPE_WARNING"})},t=p();return e(t.matches),t.addEventListener("change",(t=>{e(t.matches)})),()=>{t.removeEventListener("change",(t=>e(t.matches)))}}}),[M,A]);return e.createElement(t,{direction:"column",position:"relative",testId:"liveness-detector-check",className:"liveness-detector-check"},(()=>{if(v===o.MOBILE_LANDSCAPE_ERROR){const r=Object.assign(Object.assign({},u),h),{landscapeHeaderText:s,portraitMessageText:i,landscapeMessageText:o,tryAgainText:a}=r;return e.createElement(t,{backgroundColor:"background.primary",direction:"column",textAlign:"center",alignItems:"center",justifyContent:"center",position:"absolute",width:"100%"},e.createElement(f,{header:s,portraitMessage:i,landscapeMessage:o,tryAgainText:a,onRetry:()=>{A({type:"CANCEL"})}}))}return C?e.createElement(t,{backgroundColor:"background.primary",direction:"column",textAlign:"center",alignItems:"center",justifyContent:"center",width:"100%",height:480},e.createElement(r,{fontSize:"large",fontWeight:"bold"},v===o.CAMERA_FRAMERATE_ERROR?L:D),e.createElement(r,{maxWidth:300},v===o.CAMERA_FRAMERATE_ERROR?k:w),e.createElement(s,{variation:"primary",type:"button",onClick:b},S),e.createElement(i,{position:"absolute",top:"medium",right:"medium"},e.createElement(d,{ariaLabel:_}))):e.createElement(a,{isMobileScreen:M,isRecordingStopped:j,streamDisplayText:x,hintDisplayText:c,errorDisplayText:h,components:R})})())};export{y as LivenessCheck,E as selectErrorState,g as selectIsRecordingStopped};
1
+ import*as e from"react";import{Flex as t,Text as r,Button as s,View as i}from"@aws-amplify/ui-react";import"../service/machine/index.mjs";import"../service/types/liveness.mjs";import{LivenessErrorState as o}from"../service/types/error.mjs";import"@tensorflow/tfjs-core";import"@tensorflow-models/blazeface";import"@tensorflow/tfjs-backend-wasm";import"@tensorflow/tfjs-backend-cpu";import"@aws-amplify/core";import"../service/utils/liveness.mjs";import"../service/utils/streamProvider.mjs";import"../service/utils/freshnessColorDisplay.mjs";import{LivenessCameraModule as a}from"./LivenessCameraModule.mjs";import{useLivenessActor as n}from"../hooks/useLivenessActor.mjs";import{useLivenessSelector as m,createLivenessSelector as c}from"../hooks/useLivenessSelector.mjs";import"@aws-amplify/ui";import{isMobileScreen as p,getLandscapeMediaQuery as l}from"../utils/device.mjs";import{CancelButton as d}from"../shared/CancelButton.mjs";import{defaultErrorDisplayText as u}from"../displayText.mjs";import{LandscapeErrorModal as f}from"../shared/LandscapeErrorModal.mjs";const E="liveness-detector-check",g=c((e=>e.context.errorState)),y=c((e=>e.context.isRecordingStopped)),x=({hintDisplayText:c,cameraDisplayText:x,streamDisplayText:h,errorDisplayText:R,components:T})=>{const[A,j]=n(),v=m(g),C=m(y),M=A.matches("permissionDenied"),b=p(),L=()=>{j({type:"RETRY_CAMERA_CHECK"})},{cameraMinSpecificationsHeadingText:k,cameraMinSpecificationsMessageText:D,cameraNotFoundHeadingText:w,cameraNotFoundMessageText:S,retryCameraPermissionsText:_}=x,{cancelLivenessCheckText:N}=h;e.useLayoutEffect((()=>{if(b){const e=e=>{e&&j({type:"MOBILE_LANDSCAPE_WARNING"})},t=l();return e(t.matches),t.addEventListener("change",(t=>{e(t.matches)})),()=>{t.removeEventListener("change",(t=>e(t.matches)))}}}),[b,j]);return e.createElement(t,{direction:"column",position:"relative",testId:E,className:E},(()=>{if(v===o.MOBILE_LANDSCAPE_ERROR){const r=Object.assign(Object.assign({},u),R),{landscapeHeaderText:s,portraitMessageText:i,landscapeMessageText:o,tryAgainText:a}=r;return e.createElement(t,{backgroundColor:"background.primary",direction:"column",textAlign:"center",alignItems:"center",justifyContent:"center",position:"absolute",width:"100%"},e.createElement(f,{header:s,portraitMessage:i,landscapeMessage:o,tryAgainText:a,onRetry:()=>{j({type:"CANCEL"})}}))}return M?e.createElement(t,{backgroundColor:"background.primary",direction:"column",textAlign:"center",alignItems:"center",justifyContent:"center",width:"100%",height:480},e.createElement(r,{fontSize:"large",fontWeight:"bold"},v===o.CAMERA_FRAMERATE_ERROR?k:w),e.createElement(r,{maxWidth:300},v===o.CAMERA_FRAMERATE_ERROR?D:S),e.createElement(s,{variation:"primary",type:"button",onClick:L},_),e.createElement(i,{position:"absolute",top:"medium",right:"medium"},e.createElement(d,{ariaLabel:N}))):e.createElement(a,{isMobileScreen:b,isRecordingStopped:C,streamDisplayText:h,hintDisplayText:c,errorDisplayText:R,components:T})})())};export{x as LivenessCheck,g as selectErrorState,y as selectIsRecordingStopped};
@@ -1 +1 @@
1
- import*as t from"react";import{Card as e,Flex as n,Button as i}from"@aws-amplify/ui-react";import{DefaultHeader as o,DefaultPhotosensitiveWarning as r,DefaultInstructions as s}from"../shared/DefaultStartScreenComponents.mjs";function a(a){const{beginLivenessCheck:c,components:l,instructionDisplayText:T}=a;return t.createElement(e,{className:"liveness-detector-start","data-testid":"liveness-detector-start"},t.createElement(n,{direction:"column"},(null==l?void 0:l.Header)?t.createElement(l.Header,null):t.createElement(o,{headingText:T.instructionsHeaderHeadingText,bodyText:T.instructionsHeaderBodyText}),(null==l?void 0:l.PhotosensitiveWarning)?t.createElement(l.PhotosensitiveWarning,null):t.createElement(r,{headingText:T.photosensitivyWarningHeadingText,bodyText:T.photosensitivyWarningBodyText,infoText:T.photosensitivyWarningInfoText}),(null==l?void 0:l.Instructions)?t.createElement(l.Instructions,null):t.createElement(s,{headingText:T.instructionListHeadingText,goodFitCaptionText:T.goodFitCaptionText,goodFitAltText:T.goodFitAltText,tooFarCaptionText:T.tooFarCaptionText,tooFarAltText:T.tooFarAltText,steps:[T.instructionListStepOneText,T.instructionListStepTwoText,T.instructionListStepThreeText,T.instructionListStepFourText]}),t.createElement(n,{justifyContent:"center"},t.createElement(i,{variation:"primary",type:"button",onClick:c},T.instructionsBeginCheckText))))}export{a as StartLiveness};
1
+ import*as t from"react";import{Card as e,Flex as n,Button as i}from"@aws-amplify/ui-react";import{DefaultHeader as o,DefaultPhotosensitiveWarning as r,DefaultInstructions as s}from"../shared/DefaultStartScreenComponents.mjs";const a="liveness-detector-start";function c(c){const{beginLivenessCheck:l,components:T,instructionDisplayText:x}=c;return t.createElement(e,{className:a,"data-testid":a},t.createElement(n,{direction:"column"},(null==T?void 0:T.Header)?t.createElement(T.Header,null):t.createElement(o,{headingText:x.instructionsHeaderHeadingText,bodyText:x.instructionsHeaderBodyText}),(null==T?void 0:T.PhotosensitiveWarning)?t.createElement(T.PhotosensitiveWarning,null):t.createElement(r,{headingText:x.photosensitivyWarningHeadingText,bodyText:x.photosensitivyWarningBodyText,infoText:x.photosensitivyWarningInfoText}),(null==T?void 0:T.Instructions)?t.createElement(T.Instructions,null):t.createElement(s,{headingText:x.instructionListHeadingText,goodFitCaptionText:x.goodFitCaptionText,goodFitAltText:x.goodFitAltText,tooFarCaptionText:x.tooFarCaptionText,tooFarAltText:x.tooFarAltText,steps:[x.instructionListStepOneText,x.instructionListStepTwoText,x.instructionListStepThreeText,x.instructionListStepFourText]}),t.createElement(n,{justifyContent:"center"},t.createElement(i,{variation:"primary",type:"button",onClick:l},x.instructionsBeginCheckText))))}export{c as StartLiveness};
@@ -1 +1 @@
1
- import{__awaiter as e,__asyncValues as t}from"../../../../node_modules/tslib/tslib.es6.mjs";import{createMachine as a,assign as o,spawn as r,actions as i}from"xstate";import{getBoundingBox as s,getColorsSequencesFromSessionInformation as n,LivenessErrorStateStringMap as c,isCameraDeviceVirtual as d,getFaceMatchState as l,isFaceDistanceBelowThreshold as v,estimateIllumination as m,getOvalDetailsFromSessionInformation as h,generateBboxFromLandmarks as g,drawLivenessOvalInCanvas as u,getOvalBoundingBox as f,getIntersectionOverUnion as S,getFaceMatchStateInLivenessOval as p,getStaticLivenessOvalDetails as F}from"../utils/liveness.mjs";import{LivenessErrorState as E,FaceMatchState as D}from"../types/liveness.mjs";import{BlazeFaceFaceDetection as A}from"../utils/blazefaceFaceDetection.mjs";import{LivenessStreamProvider as M}from"../utils/streamProvider.mjs";import{FreshnessColorDisplay as R}from"../utils/freshnessColorDisplay.mjs";import{nanoid as C}from"nanoid";import{isServerSesssionInformationEvent as P,isDisconnectionEvent as T,isValidationExceptionEvent as O,isInternalServerExceptionEvent as I,isThrottlingExceptionEvent as w,isServiceQuotaExceededExceptionEvent as y,isInvalidSignatureRegionException as b}from"../utils/eventUtils.mjs";const k=500;let B;const j=a({id:"livenessMachine",initial:"start",predictableActionArguments:!0,context:{challengeId:C(),maxFailedAttempts:0,failedAttempts:0,componentProps:void 0,serverSessionInformation:void 0,videoAssociatedParams:void 0,ovalAssociatedParams:void 0,faceMatchAssociatedParams:{illuminationState:void 0,faceMatchState:void 0,faceMatchPercentage:25,currentDetectedFace:void 0,startFace:void 0,endFace:void 0,initialFaceMatchTime:void 0},freshnessColorAssociatedParams:{freshnessColorEl:void 0,freshnessColors:[],freshnessColorsComplete:!1,freshnessColorDisplay:void 0},errorState:null,livenessStreamProvider:void 0,responseStreamActorRef:void 0,shouldDisconnect:!1,faceMatchStateBeforeStart:void 0,isFaceFarEnoughBeforeRecording:void 0,isRecordingStopped:!1},on:{CANCEL:"userCancel",TIMEOUT:{target:"retryableTimeout",actions:"updateErrorStateForTimeout"},SET_SESSION_INFO:{internal:!0,actions:"updateSessionInfo"},DISCONNECT_EVENT:{internal:!0,actions:"updateShouldDisconnect"},SET_DOM_AND_CAMERA_DETAILS:{actions:"setDOMAndCameraDetails"},SERVER_ERROR:{target:"error",actions:"updateErrorStateForServer"},MOBILE_LANDSCAPE_WARNING:{target:"mobileLandscapeWarning",actions:"updateErrorStateForServer"}},states:{start:{on:{BEGIN:"cameraCheck"}},cameraCheck:{entry:["resetErrorState","setVideoConstraints","initializeFaceDetector"],invoke:{src:"checkVirtualCameraAndGetStream",onDone:{target:"waitForDOMAndCameraDetails",actions:["updateVideoMediaStream"]},onError:{target:"permissionDenied"}}},waitForDOMAndCameraDetails:{after:{0:{target:"detectFaceBeforeStart",cond:"hasDOMAndCameraDetails"},500:{target:"waitForDOMAndCameraDetails"}}},detectFaceBeforeStart:{invoke:{src:"detectFace",onDone:{target:"checkFaceDetectedBeforeStart",actions:["updateFaceMatchBeforeStartDetails"]}}},checkFaceDetectedBeforeStart:{after:{0:{target:"detectFaceDistanceBeforeRecording",cond:"hasSingleFaceBeforeStart"},100:{target:"detectFaceBeforeStart"}}},detectFaceDistanceBeforeRecording:{invoke:{src:"detectFaceDistance",onDone:{target:"checkFaceDistanceBeforeRecording",actions:["updateFaceDistanceBeforeRecording"]}}},checkFaceDistanceBeforeRecording:{after:{0:{target:"initializeLivenessStream",cond:"hasEnoughFaceDistanceBeforeRecording"},100:{target:"detectFaceDistanceBeforeRecording"}}},initializeLivenessStream:{invoke:{src:"openLivenessStreamConnection",onDone:{target:"waitForSessionInfo",actions:["updateLivenessStreamProvider","spawnResponseStreamActor"]}}},waitForSessionInfo:{after:{0:{target:"notRecording",cond:"hasServerSessionInfo"},100:{target:"waitForSessionInfo"}}},notRecording:{on:{START_RECORDING:"recording"},initial:"detectFaceDistanceDuringCountdown",states:{detectFaceDistanceDuringCountdown:{invoke:{src:"detectFaceDistance",onDone:{target:"checkFaceDistanceDuringCountdown",actions:["updateFaceDistanceBeforeRecording"]}}},checkFaceDistanceDuringCountdown:{after:{0:{target:"failure",cond:"hasNotEnoughFaceDistanceBeforeRecording"},200:{target:"detectFaceDistanceDuringCountdown"}}},failure:{entry:"sendTimeoutAfterFaceDistanceDelay",type:"final"}}},recording:{entry:["clearErrorState","startRecording"],initial:"ovalDrawing",states:{ovalDrawing:{entry:["sendTimeoutAfterOvalDrawingDelay"],invoke:{src:"detectInitialFaceAndDrawOval",onDone:{target:"checkFaceDetected",actions:["updateOvalAndFaceDetailsPostDraw","sendTimeoutAfterOvalMatchDelay"]},onError:{target:"#livenessMachine.error",actions:"updateErrorStateForRuntime"}}},checkFaceDetected:{after:{0:{target:"checkRecordingStarted",cond:"hasSingleFace"},100:{target:"ovalDrawing"}}},checkRecordingStarted:{after:{0:{target:"ovalMatching",cond:"hasRecordingStarted",actions:["updateRecordingStartTimestampMs"]},100:{target:"checkRecordingStarted"}}},ovalMatching:{entry:["cancelOvalDrawingTimeout"],invoke:{src:"detectFaceAndMatchOval",onDone:{target:"checkMatch",actions:"updateFaceDetailsPostMatch"}}},checkMatch:{after:{0:{target:"flashFreshnessColors",cond:"hasFaceMatchedInOvalWithMinTime",actions:["updateEndFaceMatch","setupFlashFreshnessColors","cancelOvalMatchTimeout","cancelOvalDrawingTimeout"]},.1:{target:"ovalMatching",cond:"hasFaceMatchedInOval",actions:"setFaceMatchTimeAndStartFace"},1:{target:"ovalMatching",cond:"hasNotFaceMatchedInOval"}}},flashFreshnessColors:{invoke:{src:"flashColors",onDone:[{target:"success",cond:"hasFreshnessColorShown"},{target:"flashFreshnessColors",actions:"updateFreshnessDetails"}]}},flashFreshnessColorError:{entry:["updateErrorStateForFreshnessTimeout"],always:[{target:"#livenessMachine.timeout"}]},success:{entry:["stopRecording"],type:"final"}},onDone:"uploading"},uploading:{initial:"pending",states:{pending:{entry:["sendTimeoutAfterWaitingForDisconnect","pauseVideoStream"],invoke:{src:"stopVideo",onDone:"waitForDisconnectEvent",onError:{target:"#livenessMachine.error",actions:"updateErrorStateForRuntime"}}},waitForDisconnectEvent:{after:{0:{target:"getLivenessResult",cond:"getShouldDisconnect"},100:{target:"waitForDisconnectEvent"}}},getLivenessResult:{entry:["cancelWaitForDisconnectTimeout","freezeStream"],invoke:{src:"getLiveness",onError:{target:"#livenessMachine.error",actions:"updateErrorStateForServer"}}}}},retryableTimeout:{entry:"updateFailedAttempts",always:[{target:"timeout",cond:"shouldTimeoutOnFailedAttempts"},{target:"notRecording"}]},permissionDenied:{entry:"callUserPermissionDeniedCallback",on:{RETRY_CAMERA_CHECK:"cameraCheck"}},mobileLandscapeWarning:{entry:"callMobileLandscapeWarningCallback",always:[{target:"error"}]},timeout:{entry:["cleanUpResources","callUserTimeoutCallback","freezeStream"]},error:{entry:["cleanUpResources","callErrorCallback","cancelOvalDrawingTimeout","cancelWaitForDisconnectTimeout","cancelOvalMatchTimeout","freezeStream"]},userCancel:{entry:["cleanUpResources","callUserCancelCallback","resetContext"],always:[{target:"start"}]}}},{actions:{spawnResponseStreamActor:o({responseStreamActorRef:()=>r(_)}),updateFailedAttempts:o({failedAttempts:e=>e.failedAttempts+1}),setVideoConstraints:o({videoAssociatedParams:(e,t)=>{var a,o;return Object.assign(Object.assign({},e.videoAssociatedParams),{videoConstraints:(null===(a=t.data)||void 0===a?void 0:a.videoConstraints)||(null===(o=e.videoAssociatedParams)||void 0===o?void 0:o.videoConstraints)})}}),updateVideoMediaStream:o({videoAssociatedParams:(e,t)=>{var a;return Object.assign(Object.assign({},e.videoAssociatedParams),{videoMediaStream:null===(a=t.data)||void 0===a?void 0:a.stream})}}),initializeFaceDetector:o({ovalAssociatedParams:e=>{const{componentProps:t}=e,{faceModelUrl:a,binaryPath:o}=t.config,r=new A(o,a);return r.triggerModelLoading(),Object.assign(Object.assign({},e.ovalAssociatedParams),{faceDetector:r})}}),updateLivenessStreamProvider:o({livenessStreamProvider:(e,t)=>{var a;return null===(a=t.data)||void 0===a?void 0:a.livenessStreamProvider}}),setDOMAndCameraDetails:o({videoAssociatedParams:(e,t)=>{var a,o,r;return Object.assign(Object.assign({},e.videoAssociatedParams),{videoEl:null===(a=t.data)||void 0===a?void 0:a.videoEl,canvasEl:null===(o=t.data)||void 0===o?void 0:o.canvasEl,isMobile:null===(r=t.data)||void 0===r?void 0:r.isMobile})},freshnessColorAssociatedParams:(e,t)=>{var a;return Object.assign(Object.assign({},e.freshnessColorAssociatedParams),{freshnessColorEl:null===(a=t.data)||void 0===a?void 0:a.freshnessColorEl})}}),updateRecordingStartTimestampMs:o({videoAssociatedParams:e=>{const{challengeId:t,videoAssociatedParams:{videoMediaStream:a},ovalAssociatedParams:{initialFace:o},livenessStreamProvider:r}=e,{recordingStartApiTimestamp:i,recorderStartTimestamp:n}=r.videoRecorder,c=Math.round(.73*(n-i)+i),{width:d,height:l}=a.getTracks()[0].getSettings(),v=d-o.left-o.width;return e.livenessStreamProvider.sendClientInfo({Challenge:{FaceMovementAndLightChallenge:{ChallengeId:t,VideoStartTimestamp:c,InitialFace:{InitialFaceDetectedTimestamp:o.timestampMs,BoundingBox:s({deviceHeight:l,deviceWidth:d,height:o.height,width:o.width,top:o.top,left:v})}}}}),Object.assign(Object.assign({},e.videoAssociatedParams),{recordingStartTimestampMs:c})}}),startRecording:o({videoAssociatedParams:e=>{if(!e.serverSessionInformation)throw new Error("Session information was not received from response stream");return e.livenessStreamProvider.videoRecorder&&"recording"!==e.livenessStreamProvider.videoRecorder.getState()&&e.livenessStreamProvider.startRecordingLivenessVideo(),Object.assign({},e.videoAssociatedParams)}}),stopRecording:e=>{},updateFaceMatchBeforeStartDetails:o({faceMatchStateBeforeStart:(e,t)=>t.data.faceMatchState}),updateFaceDistanceBeforeRecording:o({isFaceFarEnoughBeforeRecording:(e,t)=>t.data.isFaceFarEnoughBeforeRecording}),updateOvalAndFaceDetailsPostDraw:o({ovalAssociatedParams:(e,t)=>Object.assign(Object.assign({},e.ovalAssociatedParams),{initialFace:t.data.initialFace,ovalDetails:t.data.ovalDetails,scaleFactor:t.data.scaleFactor}),faceMatchAssociatedParams:(e,t)=>Object.assign(Object.assign({},e.faceMatchAssociatedParams),{faceMatchState:t.data.faceMatchState,illuminationState:t.data.illuminationState})}),updateFaceDetailsPostMatch:o({faceMatchAssociatedParams:(e,t)=>Object.assign(Object.assign({},e.faceMatchAssociatedParams),{faceMatchState:t.data.faceMatchState,faceMatchPercentage:t.data.faceMatchPercentage,illuminationState:t.data.illuminationState,currentDetectedFace:t.data.detectedFace})}),updateEndFaceMatch:o({faceMatchAssociatedParams:e=>Object.assign(Object.assign({},e.faceMatchAssociatedParams),{endFace:e.faceMatchAssociatedParams.currentDetectedFace})}),setFaceMatchTimeAndStartFace:o({faceMatchAssociatedParams:e=>Object.assign(Object.assign({},e.faceMatchAssociatedParams),{startFace:void 0===e.faceMatchAssociatedParams.startFace?e.faceMatchAssociatedParams.currentDetectedFace:e.faceMatchAssociatedParams.startFace,initialFaceMatchTime:void 0===e.faceMatchAssociatedParams.initialFaceMatchTime?Date.now():e.faceMatchAssociatedParams.initialFaceMatchTime})}),resetFaceMatchTimeAndStartFace:o({faceMatchAssociatedParams:e=>Object.assign(Object.assign({},e.faceMatchAssociatedParams),{startFace:void 0,endFace:void 0,initialFaceMatchTime:void 0})}),resetErrorState:o({errorState:e=>{}}),updateErrorStateForTimeout:o({errorState:(e,t)=>{var a;return(null===(a=t.data)||void 0===a?void 0:a.errorState)||E.TIMEOUT}}),updateErrorStateForRuntime:o({errorState:e=>E.RUNTIME_ERROR}),updateErrorStateForServer:o({errorState:e=>E.SERVER_ERROR}),clearErrorState:o({errorState:e=>null}),updateSessionInfo:o({serverSessionInformation:(e,t)=>t.data.sessionInfo}),updateShouldDisconnect:o({shouldDisconnect:e=>!0}),updateFreshnessDetails:o({freshnessColorAssociatedParams:(e,t)=>Object.assign(Object.assign({},e.freshnessColorAssociatedParams),{freshnessColorsComplete:t.data.freshnessColorsComplete})}),updateErrorStateForFreshnessTimeout:o({errorState:e=>{const{freshnessColorAssociatedParams:{freshnessColorEl:t}}=e;return t.style.display="none",E.FRESHNESS_TIMEOUT}}),setupFlashFreshnessColors:o({freshnessColorAssociatedParams:e=>{const{serverSessionInformation:t}=e,a=n(t),o=new R(e,a);return Object.assign(Object.assign({},e.freshnessColorAssociatedParams),{freshnessColorDisplay:o})}}),sendTimeoutAfterOvalDrawingDelay:i.send({type:"TIMEOUT"},{delay:5e3,id:"ovalDrawingTimeout"}),cancelOvalDrawingTimeout:i.cancel("ovalDrawingTimeout"),sendTimeoutAfterOvalMatchDelay:i.send({type:"TIMEOUT"},{delay:7e3,id:"ovalMatchTimeout"}),cancelOvalMatchTimeout:i.cancel("ovalMatchTimeout"),sendTimeoutAfterWaitingForDisconnect:i.send({type:"TIMEOUT",data:{errorState:E.SERVER_ERROR}},{delay:2e4,id:"waitForDisconnectTimeout"}),cancelWaitForDisconnectTimeout:i.cancel("waitForDisconnectTimeout"),sendTimeoutAfterFaceDistanceDelay:i.send({type:"TIMEOUT",data:{errorState:E.FACE_DISTANCE_ERROR}},{delay:0,id:"faceDistanceTimeout"}),cancelFaceDistanceTimeout:i.cancel("faceDistanceTimeout"),callUserPermissionDeniedCallback:o({errorState:(e,t)=>{var a,o;let r;r=t.data.message.includes("15 fps")?E.CAMERA_FRAMERATE_ERROR:E.CAMERA_ACCESS_ERROR;const i=t.data.message||t.data.Message,s=new Error(i);return s.name=r,null===(o=(a=e.componentProps).onError)||void 0===o||o.call(a,s),r}}),callMobileLandscapeWarningCallback:o({errorState:e=>E.MOBILE_LANDSCAPE_ERROR}),callUserCancelCallback:t=>e(void 0,void 0,void 0,(function*(){var e,a;null===(a=(e=t.componentProps).onUserCancel)||void 0===a||a.call(e)})),callUserTimeoutCallback:t=>e(void 0,void 0,void 0,(function*(){var e,a;const o=new Error(c[t.errorState]);o.name=t.errorState,null===(a=(e=t.componentProps).onError)||void 0===a||a.call(e,o)})),callErrorCallback:(t,a)=>e(void 0,void 0,void 0,(function*(){var e,o,r,i,s,n;const c=(null===(o=null===(e=a.data)||void 0===e?void 0:e.error)||void 0===o?void 0:o.message)||(null===(i=null===(r=a.data)||void 0===r?void 0:r.error)||void 0===i?void 0:i.Message),d=new Error(c);d.name=t.errorState,null===(n=(s=t.componentProps).onError)||void 0===n||n.call(s,d)})),cleanUpResources:t=>e(void 0,void 0,void 0,(function*(){var e;const{freshnessColorAssociatedParams:{freshnessColorEl:a}}=t;a&&(a.style.display="none"),yield null===(e=t.livenessStreamProvider)||void 0===e?void 0:e.endStream()})),freezeStream:t=>e(void 0,void 0,void 0,(function*(){const{videoAssociatedParams:{videoMediaStream:e,videoEl:a}}=t;t.isRecordingStopped=!0,null==a||a.pause(),null==e||e.getTracks().forEach((function(e){e.stop()}))})),pauseVideoStream:t=>e(void 0,void 0,void 0,(function*(){const{videoAssociatedParams:{videoEl:e}}=t;t.isRecordingStopped=!0,e.pause()})),resetContext:o({challengeId:C(),maxFailedAttempts:0,failedAttempts:0,componentProps:e=>e.componentProps,serverSessionInformation:e=>{},videoAssociatedParams:e=>{},ovalAssociatedParams:e=>{},errorState:e=>null,livenessStreamProvider:e=>{},responseStreamActorRef:e=>{},shouldDisconnect:!1,faceMatchStateBeforeStart:e=>{},isFaceFarEnoughBeforeRecording:e=>{},isRecordingStopped:!1})},guards:{shouldTimeoutOnFailedAttempts:e=>e.failedAttempts>=e.maxFailedAttempts,hasFaceMatchedInOvalWithMinTime:e=>{const{faceMatchState:t,initialFaceMatchTime:a}=e.faceMatchAssociatedParams,o=Date.now()-a;return t===D.MATCHED&&o>=500},hasFaceMatchedInOval:e=>e.faceMatchAssociatedParams.faceMatchState===D.MATCHED,hasNotFaceMatchedInOval:e=>e.faceMatchAssociatedParams.faceMatchState!==D.MATCHED,hasSingleFace:e=>e.faceMatchAssociatedParams.faceMatchState===D.FACE_IDENTIFIED,hasSingleFaceBeforeStart:e=>e.faceMatchStateBeforeStart===D.FACE_IDENTIFIED,hasEnoughFaceDistanceBeforeRecording:e=>e.isFaceFarEnoughBeforeRecording,hasNotEnoughFaceDistanceBeforeRecording:e=>!e.isFaceFarEnoughBeforeRecording,hasLivenessCheckSucceeded:(e,t,a)=>a.state.event.data.isLive,hasFreshnessColorShown:e=>e.freshnessColorAssociatedParams.freshnessColorsComplete,hasServerSessionInfo:e=>void 0!==e.serverSessionInformation,hasDOMAndCameraDetails:e=>void 0!==e.videoAssociatedParams.videoEl&&void 0!==e.videoAssociatedParams.canvasEl&&void 0!==e.freshnessColorAssociatedParams.freshnessColorEl,getShouldDisconnect:e=>!!e.shouldDisconnect,hasRecordingStarted:e=>void 0!==e.livenessStreamProvider.videoRecorder.firstChunkTimestamp},services:{checkVirtualCameraAndGetStream(t){return e(this,void 0,void 0,(function*(){const{videoConstraints:e}=t.videoAssociatedParams,a=yield navigator.mediaDevices.getUserMedia({video:e,audio:!1}),o=(yield navigator.mediaDevices.enumerateDevices()).filter((e=>"videoinput"===e.kind)).filter((e=>!d(e)));if(!o.length)throw new Error("No real video devices found");const r=a.getTracks().filter((e=>e.getSettings().frameRate>=15));if(r.length<1)throw new Error("No camera found with more than 15 fps");const i=r[0].getSettings().deviceId;let s=a;return o.some((e=>e.deviceId===i))||(s=yield navigator.mediaDevices.getUserMedia({video:Object.assign(Object.assign({},e),{deviceId:{exact:o[0].deviceId}}),audio:!1})),{stream:s}}))},openLivenessStreamConnection(t){return e(this,void 0,void 0,(function*(){const e=new M(t.componentProps.sessionId,t.componentProps.region,t.videoAssociatedParams.videoMediaStream,t.videoAssociatedParams.videoEl);return B=e.getResponseStream(),{livenessStreamProvider:e}}))},detectFace(t){return e(this,void 0,void 0,(function*(){const{videoAssociatedParams:{videoEl:e},ovalAssociatedParams:{faceDetector:a}}=t;try{yield a.modelLoadingPromise}catch(e){console.log({err:e})}return{faceMatchState:yield l(a,e)}}))},detectFaceDistance(t){return e(this,void 0,void 0,(function*(){const{videoAssociatedParams:{videoEl:e,videoMediaStream:a,isMobile:o},ovalAssociatedParams:{faceDetector:r},isFaceFarEnoughBeforeRecording:i}=t,{width:s,height:n}=a.getTracks()[0].getSettings(),c=F({width:s,height:n});return{isFaceFarEnoughBeforeRecording:yield v({faceDetector:r,videoEl:e,ovalDetails:c,reduceThreshold:i,isMobile:o})}}))},detectInitialFaceAndDrawOval(t){return e(this,void 0,void 0,(function*(){const{videoAssociatedParams:{videoEl:e,canvasEl:a,isMobile:o},ovalAssociatedParams:{faceDetector:r},serverSessionInformation:i,livenessStreamProvider:s}=t;try{yield r.modelLoadingPromise,yield s.videoRecorder.recorderStarted}catch(e){console.log({err:e})}const n=yield r.detectFaces(e);let c,d,l;switch(n.length){case 0:d=D.CANT_IDENTIFY,l=m(e);break;case 1:d=D.FACE_IDENTIFIED,c=n[0];break;default:d=D.TOO_MANY}if(!c)return{faceMatchState:d,illuminationState:l};const{width:v,height:f}=e.getBoundingClientRect();o?(a.width=window.innerWidth,a.height=window.innerHeight):(a.width=v,a.height=f);const S=v/e.videoWidth,p=h({sessionInformation:i,videoWidth:e.width}),F=g(c,p);return c.top=F.top,c.left=F.left,c.height=F.bottom-F.top,c.width=F.right-F.left,u({canvas:a,oval:p,scaleFactor:S,videoEl:e}),{faceMatchState:d,ovalDetails:p,scaleFactor:S,initialFace:c}}))},detectFaceAndMatchOval(t){return e(this,void 0,void 0,(function*(){const{videoAssociatedParams:{videoEl:e},ovalAssociatedParams:{faceDetector:a,ovalDetails:o,initialFace:r},serverSessionInformation:i}=t,s=yield a.detectFaces(e);let n,c,d,l=0;const v=g(r,o),{ovalBoundingBox:h}=f(o),u=S(v,h);switch(s.length){case 0:n=D.CANT_IDENTIFY,d=m(e);break;case 1:{c=s[0];const{faceMatchState:e,faceMatchPercentage:t}=p(c,o,u,i);n=e,l=t;break}default:n=D.TOO_MANY}return{faceMatchState:n,faceMatchPercentage:l,illuminationState:d,detectedFace:c}}))},flashColors(t){return e(this,void 0,void 0,(function*(){const{freshnessColorAssociatedParams:{freshnessColorsComplete:e,freshnessColorDisplay:a}}=t;if(e)return;return{freshnessColorsComplete:yield a.displayColorTick()}}))},stopVideo(t){return e(this,void 0,void 0,(function*(){const{challengeId:e,videoAssociatedParams:{videoMediaStream:a},ovalAssociatedParams:{initialFace:o,ovalDetails:r},faceMatchAssociatedParams:{startFace:i,endFace:n},livenessStreamProvider:c}=t,{width:d,height:l}=a.getTracks()[0].getSettings(),v=d-o.left-o.width;yield c.stopVideo();const m={Challenge:{FaceMovementAndLightChallenge:{ChallengeId:e,InitialFace:{InitialFaceDetectedTimestamp:o.timestampMs,BoundingBox:s({deviceHeight:l,deviceWidth:d,height:o.height,width:o.width,top:o.top,left:v})},TargetFace:{FaceDetectedInTargetPositionStartTimestamp:i.timestampMs,FaceDetectedInTargetPositionEndTimestamp:n.timestampMs,BoundingBox:s({deviceHeight:l,deviceWidth:d,height:r.height,width:r.width,top:r.centerY-r.height/2,left:r.centerX-r.width/2})},VideoEndTimestamp:c.videoRecorder.recorderEndTimestamp}}};c.sendClientInfo(m),yield c.dispatchStopVideoEvent()}))},getLiveness(t){return e(this,void 0,void 0,(function*(){const{componentProps:{onAnalysisComplete:e},livenessStreamProvider:a}=t;a.endStream(),yield e()}))}}}),_=a=>e(void 0,void 0,void 0,(function*(){var e,o;const r=yield B;try{try{for(var i,s=t(r);!(i=yield s.next()).done;){const e=i.value;P(e)?a({type:"SET_SESSION_INFO",data:{sessionInfo:e.ServerSessionInformationEvent.SessionInformation}}):T(e)?a({type:"DISCONNECT_EVENT"}):O(e)?a({type:"SERVER_ERROR",data:{error:Object.assign({},e.ValidationException)}}):I(e)?a({type:"SERVER_ERROR",data:{error:Object.assign({},e.InternalServerException)}}):w(e)?a({type:"SERVER_ERROR",data:{error:Object.assign({},e.ThrottlingException)}}):y(e)&&a({type:"SERVER_ERROR",data:{error:Object.assign({},e.ServiceQuotaExceededException)}})}}catch(t){e={error:t}}finally{try{i&&!i.done&&(o=s.return)&&(yield o.call(s))}finally{if(e)throw e.error}}}catch(e){let t=e;b(e)&&(t=new Error("Invalid region in FaceLivenessDetector or credentials are scoped to the wrong region.")),a({type:"SERVER_ERROR",data:{error:t}})}}));export{k as MIN_FACE_MATCH_TIME,j as livenessMachine};
1
+ import{__awaiter as e,__asyncValues as t}from"../../../../node_modules/tslib/tslib.es6.mjs";import{createMachine as a,assign as o,spawn as i,actions as r}from"xstate";import{getBoundingBox as s,getColorsSequencesFromSessionInformation as n,LivenessErrorStateStringMap as c,isCameraDeviceVirtual as d,getFaceMatchState as l,isFaceDistanceBelowThreshold as v,estimateIllumination as m,getOvalDetailsFromSessionInformation as h,generateBboxFromLandmarks as g,drawLivenessOvalInCanvas as f,getOvalBoundingBox as u,getIntersectionOverUnion as S,getFaceMatchStateInLivenessOval as p,getStaticLivenessOvalDetails as F}from"../utils/liveness.mjs";import{FaceMatchState as D}from"../types/liveness.mjs";import{LivenessErrorState as E}from"../types/error.mjs";import{BlazeFaceFaceDetection as A}from"../utils/blazefaceFaceDetection.mjs";import{LivenessStreamProvider as M}from"../utils/streamProvider.mjs";import{FreshnessColorDisplay as R}from"../utils/freshnessColorDisplay.mjs";import{nanoid as C}from"nanoid";import{isServerSesssionInformationEvent as P,isDisconnectionEvent as T,isValidationExceptionEvent as O,isInternalServerExceptionEvent as I,isThrottlingExceptionEvent as w,isServiceQuotaExceededExceptionEvent as y,isInvalidSignatureRegionException as b}from"../utils/eventUtils.mjs";const k=500;let B;const j=a({id:"livenessMachine",initial:"start",predictableActionArguments:!0,context:{challengeId:C(),maxFailedAttempts:0,failedAttempts:0,componentProps:void 0,serverSessionInformation:void 0,videoAssociatedParams:void 0,ovalAssociatedParams:void 0,faceMatchAssociatedParams:{illuminationState:void 0,faceMatchState:void 0,faceMatchPercentage:25,currentDetectedFace:void 0,startFace:void 0,endFace:void 0,initialFaceMatchTime:void 0},freshnessColorAssociatedParams:{freshnessColorEl:void 0,freshnessColors:[],freshnessColorsComplete:!1,freshnessColorDisplay:void 0},errorState:void 0,livenessStreamProvider:void 0,responseStreamActorRef:void 0,shouldDisconnect:!1,faceMatchStateBeforeStart:void 0,isFaceFarEnoughBeforeRecording:void 0,isRecordingStopped:!1},on:{CANCEL:"userCancel",TIMEOUT:{target:"retryableTimeout",actions:"updateErrorStateForTimeout"},SET_SESSION_INFO:{internal:!0,actions:"updateSessionInfo"},DISCONNECT_EVENT:{internal:!0,actions:"updateShouldDisconnect"},SET_DOM_AND_CAMERA_DETAILS:{actions:"setDOMAndCameraDetails"},SERVER_ERROR:{target:"error",actions:"updateErrorStateForServer"},MOBILE_LANDSCAPE_WARNING:{target:"mobileLandscapeWarning",actions:"updateErrorStateForServer"}},states:{start:{on:{BEGIN:"cameraCheck"}},cameraCheck:{entry:["resetErrorState","setVideoConstraints","initializeFaceDetector"],invoke:{src:"checkVirtualCameraAndGetStream",onDone:{target:"waitForDOMAndCameraDetails",actions:["updateVideoMediaStream"]},onError:{target:"permissionDenied"}}},waitForDOMAndCameraDetails:{after:{0:{target:"detectFaceBeforeStart",cond:"hasDOMAndCameraDetails"},500:{target:"waitForDOMAndCameraDetails"}}},detectFaceBeforeStart:{invoke:{src:"detectFace",onDone:{target:"checkFaceDetectedBeforeStart",actions:["updateFaceMatchBeforeStartDetails"]}}},checkFaceDetectedBeforeStart:{after:{0:{target:"detectFaceDistanceBeforeRecording",cond:"hasSingleFaceBeforeStart"},100:{target:"detectFaceBeforeStart"}}},detectFaceDistanceBeforeRecording:{invoke:{src:"detectFaceDistance",onDone:{target:"checkFaceDistanceBeforeRecording",actions:["updateFaceDistanceBeforeRecording"]}}},checkFaceDistanceBeforeRecording:{after:{0:{target:"initializeLivenessStream",cond:"hasEnoughFaceDistanceBeforeRecording"},100:{target:"detectFaceDistanceBeforeRecording"}}},initializeLivenessStream:{invoke:{src:"openLivenessStreamConnection",onDone:{target:"waitForSessionInfo",actions:["updateLivenessStreamProvider","spawnResponseStreamActor"]}}},waitForSessionInfo:{after:{0:{target:"notRecording",cond:"hasServerSessionInfo"},100:{target:"waitForSessionInfo"}}},notRecording:{on:{START_RECORDING:"recording"},initial:"detectFaceDistanceDuringCountdown",states:{detectFaceDistanceDuringCountdown:{invoke:{src:"detectFaceDistance",onDone:{target:"checkFaceDistanceDuringCountdown",actions:["updateFaceDistanceBeforeRecording"]}}},checkFaceDistanceDuringCountdown:{after:{0:{target:"failure",cond:"hasNotEnoughFaceDistanceBeforeRecording"},200:{target:"detectFaceDistanceDuringCountdown"}}},failure:{entry:"sendTimeoutAfterFaceDistanceDelay",type:"final"}}},recording:{entry:["clearErrorState","startRecording"],initial:"ovalDrawing",states:{ovalDrawing:{entry:["sendTimeoutAfterOvalDrawingDelay"],invoke:{src:"detectInitialFaceAndDrawOval",onDone:{target:"checkFaceDetected",actions:["updateOvalAndFaceDetailsPostDraw","sendTimeoutAfterOvalMatchDelay"]},onError:{target:"#livenessMachine.error",actions:"updateErrorStateForRuntime"}}},checkFaceDetected:{after:{0:{target:"checkRecordingStarted",cond:"hasSingleFace"},100:{target:"ovalDrawing"}}},checkRecordingStarted:{after:{0:{target:"ovalMatching",cond:"hasRecordingStarted",actions:["updateRecordingStartTimestampMs"]},100:{target:"checkRecordingStarted"}}},ovalMatching:{entry:["cancelOvalDrawingTimeout"],invoke:{src:"detectFaceAndMatchOval",onDone:{target:"checkMatch",actions:"updateFaceDetailsPostMatch"}}},checkMatch:{after:{0:{target:"flashFreshnessColors",cond:"hasFaceMatchedInOvalWithMinTime",actions:["updateEndFaceMatch","setupFlashFreshnessColors","cancelOvalMatchTimeout","cancelOvalDrawingTimeout"]},.1:{target:"ovalMatching",cond:"hasFaceMatchedInOval",actions:"setFaceMatchTimeAndStartFace"},1:{target:"ovalMatching",cond:"hasNotFaceMatchedInOval"}}},flashFreshnessColors:{invoke:{src:"flashColors",onDone:[{target:"success",cond:"hasFreshnessColorShown"},{target:"flashFreshnessColors",actions:"updateFreshnessDetails"}]}},success:{entry:["stopRecording"],type:"final"}},onDone:"uploading"},uploading:{initial:"pending",states:{pending:{entry:["sendTimeoutAfterWaitingForDisconnect","pauseVideoStream"],invoke:{src:"stopVideo",onDone:"waitForDisconnectEvent",onError:{target:"#livenessMachine.error",actions:"updateErrorStateForRuntime"}}},waitForDisconnectEvent:{after:{0:{target:"getLivenessResult",cond:"getShouldDisconnect"},100:{target:"waitForDisconnectEvent"}}},getLivenessResult:{entry:["cancelWaitForDisconnectTimeout","freezeStream"],invoke:{src:"getLiveness",onError:{target:"#livenessMachine.error",actions:"updateErrorStateForServer"}}}}},retryableTimeout:{entry:"updateFailedAttempts",always:[{target:"timeout",cond:"shouldTimeoutOnFailedAttempts"},{target:"notRecording"}]},permissionDenied:{entry:"callUserPermissionDeniedCallback",on:{RETRY_CAMERA_CHECK:"cameraCheck"}},mobileLandscapeWarning:{entry:"callMobileLandscapeWarningCallback",always:[{target:"error"}]},timeout:{entry:["cleanUpResources","callUserTimeoutCallback","freezeStream"]},error:{entry:["cleanUpResources","callErrorCallback","cancelOvalDrawingTimeout","cancelWaitForDisconnectTimeout","cancelOvalMatchTimeout","freezeStream"]},userCancel:{entry:["cleanUpResources","callUserCancelCallback","resetContext"],always:[{target:"start"}]}}},{actions:{spawnResponseStreamActor:o({responseStreamActorRef:()=>i(_)}),updateFailedAttempts:o({failedAttempts:e=>e.failedAttempts+1}),setVideoConstraints:o({videoAssociatedParams:(e,t)=>{var a,o;return Object.assign(Object.assign({},e.videoAssociatedParams),{videoConstraints:(null===(a=t.data)||void 0===a?void 0:a.videoConstraints)||(null===(o=e.videoAssociatedParams)||void 0===o?void 0:o.videoConstraints)})}}),updateVideoMediaStream:o({videoAssociatedParams:(e,t)=>{var a;return Object.assign(Object.assign({},e.videoAssociatedParams),{videoMediaStream:null===(a=t.data)||void 0===a?void 0:a.stream})}}),initializeFaceDetector:o({ovalAssociatedParams:e=>{const{componentProps:t}=e,{faceModelUrl:a,binaryPath:o}=t.config,i=new A(o,a);return i.triggerModelLoading(),Object.assign(Object.assign({},e.ovalAssociatedParams),{faceDetector:i})}}),updateLivenessStreamProvider:o({livenessStreamProvider:(e,t)=>{var a;return null===(a=t.data)||void 0===a?void 0:a.livenessStreamProvider}}),setDOMAndCameraDetails:o({videoAssociatedParams:(e,t)=>{var a,o,i;return Object.assign(Object.assign({},e.videoAssociatedParams),{videoEl:null===(a=t.data)||void 0===a?void 0:a.videoEl,canvasEl:null===(o=t.data)||void 0===o?void 0:o.canvasEl,isMobile:null===(i=t.data)||void 0===i?void 0:i.isMobile})},freshnessColorAssociatedParams:(e,t)=>{var a;return Object.assign(Object.assign({},e.freshnessColorAssociatedParams),{freshnessColorEl:null===(a=t.data)||void 0===a?void 0:a.freshnessColorEl})}}),updateRecordingStartTimestampMs:o({videoAssociatedParams:e=>{const{challengeId:t,videoAssociatedParams:a,ovalAssociatedParams:o,livenessStreamProvider:i}=e,{recordingStartApiTimestamp:r,recorderStartTimestamp:n}=i.videoRecorder,{videoMediaStream:c}=a,{initialFace:d}=o,l=Math.round(.73*(n-r)+r),{width:v,height:m}=c.getTracks()[0].getSettings(),h=v-d.left-d.width;return e.livenessStreamProvider.sendClientInfo({Challenge:{FaceMovementAndLightChallenge:{ChallengeId:t,VideoStartTimestamp:l,InitialFace:{InitialFaceDetectedTimestamp:d.timestampMs,BoundingBox:s({deviceHeight:m,deviceWidth:v,height:d.height,width:d.width,top:d.top,left:h})}}}}),Object.assign(Object.assign({},e.videoAssociatedParams),{recordingStartTimestampMs:l})}}),startRecording:o({videoAssociatedParams:e=>{if(!e.serverSessionInformation)throw new Error("Session information was not received from response stream");return e.livenessStreamProvider.videoRecorder&&"recording"!==e.livenessStreamProvider.videoRecorder.getState()&&e.livenessStreamProvider.startRecordingLivenessVideo(),Object.assign({},e.videoAssociatedParams)}}),stopRecording:e=>{},updateFaceMatchBeforeStartDetails:o({faceMatchStateBeforeStart:(e,t)=>t.data.faceMatchState}),updateFaceDistanceBeforeRecording:o({isFaceFarEnoughBeforeRecording:(e,t)=>t.data.isFaceFarEnoughBeforeRecording}),updateOvalAndFaceDetailsPostDraw:o({ovalAssociatedParams:(e,t)=>Object.assign(Object.assign({},e.ovalAssociatedParams),{initialFace:t.data.initialFace,ovalDetails:t.data.ovalDetails,scaleFactor:t.data.scaleFactor}),faceMatchAssociatedParams:(e,t)=>Object.assign(Object.assign({},e.faceMatchAssociatedParams),{faceMatchState:t.data.faceMatchState,illuminationState:t.data.illuminationState})}),updateFaceDetailsPostMatch:o({faceMatchAssociatedParams:(e,t)=>Object.assign(Object.assign({},e.faceMatchAssociatedParams),{faceMatchState:t.data.faceMatchState,faceMatchPercentage:t.data.faceMatchPercentage,illuminationState:t.data.illuminationState,currentDetectedFace:t.data.detectedFace})}),updateEndFaceMatch:o({faceMatchAssociatedParams:e=>Object.assign(Object.assign({},e.faceMatchAssociatedParams),{endFace:e.faceMatchAssociatedParams.currentDetectedFace})}),setFaceMatchTimeAndStartFace:o({faceMatchAssociatedParams:e=>Object.assign(Object.assign({},e.faceMatchAssociatedParams),{startFace:void 0===e.faceMatchAssociatedParams.startFace?e.faceMatchAssociatedParams.currentDetectedFace:e.faceMatchAssociatedParams.startFace,initialFaceMatchTime:void 0===e.faceMatchAssociatedParams.initialFaceMatchTime?Date.now():e.faceMatchAssociatedParams.initialFaceMatchTime})}),resetErrorState:o({errorState:e=>{}}),updateErrorStateForTimeout:o({errorState:(e,t)=>{var a;return(null===(a=t.data)||void 0===a?void 0:a.errorState)||E.TIMEOUT}}),updateErrorStateForRuntime:o({errorState:e=>E.RUNTIME_ERROR}),updateErrorStateForServer:o({errorState:e=>E.SERVER_ERROR}),clearErrorState:o({errorState:e=>{}}),updateSessionInfo:o({serverSessionInformation:(e,t)=>t.data.sessionInfo}),updateShouldDisconnect:o({shouldDisconnect:e=>!0}),updateFreshnessDetails:o({freshnessColorAssociatedParams:(e,t)=>Object.assign(Object.assign({},e.freshnessColorAssociatedParams),{freshnessColorsComplete:t.data.freshnessColorsComplete})}),setupFlashFreshnessColors:o({freshnessColorAssociatedParams:e=>{const{serverSessionInformation:t}=e,a=n(t),o=new R(e,a);return Object.assign(Object.assign({},e.freshnessColorAssociatedParams),{freshnessColorDisplay:o})}}),sendTimeoutAfterOvalDrawingDelay:r.send({type:"TIMEOUT"},{delay:5e3,id:"ovalDrawingTimeout"}),cancelOvalDrawingTimeout:r.cancel("ovalDrawingTimeout"),sendTimeoutAfterOvalMatchDelay:r.send({type:"TIMEOUT"},{delay:7e3,id:"ovalMatchTimeout"}),cancelOvalMatchTimeout:r.cancel("ovalMatchTimeout"),sendTimeoutAfterWaitingForDisconnect:r.send({type:"TIMEOUT",data:{errorState:E.SERVER_ERROR}},{delay:2e4,id:"waitForDisconnectTimeout"}),cancelWaitForDisconnectTimeout:r.cancel("waitForDisconnectTimeout"),sendTimeoutAfterFaceDistanceDelay:r.send({type:"TIMEOUT",data:{errorState:E.FACE_DISTANCE_ERROR}},{delay:0,id:"faceDistanceTimeout"}),cancelFaceDistanceTimeout:r.cancel("faceDistanceTimeout"),callUserPermissionDeniedCallback:o({errorState:(e,t)=>{var a,o;let i;i=t.data.message.includes("15 fps")?E.CAMERA_FRAMERATE_ERROR:E.CAMERA_ACCESS_ERROR;const r=t.data.message||t.data.Message,s=new Error(r);return s.name=i,null===(o=(a=e.componentProps).onError)||void 0===o||o.call(a,s),i}}),callMobileLandscapeWarningCallback:o({errorState:e=>E.MOBILE_LANDSCAPE_ERROR}),callUserCancelCallback:t=>e(void 0,void 0,void 0,(function*(){var e,a;null===(a=(e=t.componentProps).onUserCancel)||void 0===a||a.call(e)})),callUserTimeoutCallback:t=>e(void 0,void 0,void 0,(function*(){var e,a;const o=new Error(c[t.errorState]);o.name=t.errorState,null===(a=(e=t.componentProps).onError)||void 0===a||a.call(e,o)})),callErrorCallback:(t,a)=>e(void 0,void 0,void 0,(function*(){var e,o,i,r,s,n;const c=(null===(o=null===(e=a.data)||void 0===e?void 0:e.error)||void 0===o?void 0:o.message)||(null===(r=null===(i=a.data)||void 0===i?void 0:i.error)||void 0===r?void 0:r.Message),d=new Error(c);d.name=t.errorState,null===(n=(s=t.componentProps).onError)||void 0===n||n.call(s,d)})),cleanUpResources:t=>e(void 0,void 0,void 0,(function*(){var e;const{freshnessColorEl:a}=t.freshnessColorAssociatedParams;a&&(a.style.display="none"),yield null===(e=t.livenessStreamProvider)||void 0===e?void 0:e.endStream()})),freezeStream:t=>e(void 0,void 0,void 0,(function*(){const{videoMediaStream:e,videoEl:a}=t.videoAssociatedParams;t.isRecordingStopped=!0,null==a||a.pause(),null==e||e.getTracks().forEach((function(e){e.stop()}))})),pauseVideoStream:t=>e(void 0,void 0,void 0,(function*(){const{videoEl:e}=t.videoAssociatedParams;t.isRecordingStopped=!0,e.pause()})),resetContext:o({challengeId:C(),maxFailedAttempts:0,failedAttempts:0,componentProps:e=>e.componentProps,serverSessionInformation:e=>{},videoAssociatedParams:e=>{},ovalAssociatedParams:e=>{},errorState:e=>{},livenessStreamProvider:e=>{},responseStreamActorRef:e=>{},shouldDisconnect:!1,faceMatchStateBeforeStart:e=>{},isFaceFarEnoughBeforeRecording:e=>{},isRecordingStopped:!1})},guards:{shouldTimeoutOnFailedAttempts:e=>e.failedAttempts>=e.maxFailedAttempts,hasFaceMatchedInOvalWithMinTime:e=>{const{faceMatchState:t,initialFaceMatchTime:a}=e.faceMatchAssociatedParams,o=Date.now()-a;return t===D.MATCHED&&o>=500},hasFaceMatchedInOval:e=>e.faceMatchAssociatedParams.faceMatchState===D.MATCHED,hasNotFaceMatchedInOval:e=>e.faceMatchAssociatedParams.faceMatchState!==D.MATCHED,hasSingleFace:e=>e.faceMatchAssociatedParams.faceMatchState===D.FACE_IDENTIFIED,hasSingleFaceBeforeStart:e=>e.faceMatchStateBeforeStart===D.FACE_IDENTIFIED,hasEnoughFaceDistanceBeforeRecording:e=>e.isFaceFarEnoughBeforeRecording,hasNotEnoughFaceDistanceBeforeRecording:e=>!e.isFaceFarEnoughBeforeRecording,hasLivenessCheckSucceeded:(e,t,a)=>a.state.event.data.isLive,hasFreshnessColorShown:e=>e.freshnessColorAssociatedParams.freshnessColorsComplete,hasServerSessionInfo:e=>void 0!==e.serverSessionInformation,hasDOMAndCameraDetails:e=>void 0!==e.videoAssociatedParams.videoEl&&void 0!==e.videoAssociatedParams.canvasEl&&void 0!==e.freshnessColorAssociatedParams.freshnessColorEl,getShouldDisconnect:e=>!!e.shouldDisconnect,hasRecordingStarted:e=>void 0!==e.livenessStreamProvider.videoRecorder.firstChunkTimestamp},services:{checkVirtualCameraAndGetStream(t){return e(this,void 0,void 0,(function*(){const{videoConstraints:e}=t.videoAssociatedParams,a=yield navigator.mediaDevices.getUserMedia({video:e,audio:!1}),o=(yield navigator.mediaDevices.enumerateDevices()).filter((e=>"videoinput"===e.kind)).filter((e=>!d(e)));if(!o.length)throw new Error("No real video devices found");const i=a.getTracks().filter((e=>e.getSettings().frameRate>=15));if(i.length<1)throw new Error("No camera found with more than 15 fps");const r=i[0].getSettings().deviceId;let s=a;return o.some((e=>e.deviceId===r))||(s=yield navigator.mediaDevices.getUserMedia({video:Object.assign(Object.assign({},e),{deviceId:{exact:o[0].deviceId}}),audio:!1})),{stream:s}}))},openLivenessStreamConnection(t){return e(this,void 0,void 0,(function*(){const e=new M(t.componentProps.sessionId,t.componentProps.region,t.videoAssociatedParams.videoMediaStream,t.videoAssociatedParams.videoEl);return B=e.getResponseStream(),{livenessStreamProvider:e}}))},detectFace(t){return e(this,void 0,void 0,(function*(){const{videoEl:e}=t.videoAssociatedParams,{faceDetector:a}=t.ovalAssociatedParams;try{yield a.modelLoadingPromise}catch(e){console.log({err:e})}return{faceMatchState:yield l(a,e)}}))},detectFaceDistance(t){return e(this,void 0,void 0,(function*(){const{isFaceFarEnoughBeforeRecording:e}=t,{videoEl:a,videoMediaStream:o,isMobile:i}=t.videoAssociatedParams,{faceDetector:r}=t.ovalAssociatedParams,{width:s,height:n}=o.getTracks()[0].getSettings(),c=F({width:s,height:n});return{isFaceFarEnoughBeforeRecording:yield v({faceDetector:r,videoEl:a,ovalDetails:c,reduceThreshold:e,isMobile:i})}}))},detectInitialFaceAndDrawOval(t){return e(this,void 0,void 0,(function*(){const{serverSessionInformation:e,livenessStreamProvider:a}=t,{videoEl:o,canvasEl:i,isMobile:r}=t.videoAssociatedParams,{faceDetector:s}=t.ovalAssociatedParams;try{yield s.modelLoadingPromise,yield a.videoRecorder.recorderStarted}catch(e){console.log({err:e})}const n=yield s.detectFaces(o);let c,d,l;switch(n.length){case 0:d=D.CANT_IDENTIFY,l=m(o);break;case 1:d=D.FACE_IDENTIFIED,c=n[0];break;default:d=D.TOO_MANY}if(!c)return{faceMatchState:d,illuminationState:l};const{width:v,height:u}=o.getBoundingClientRect();r?(i.width=window.innerWidth,i.height=window.innerHeight):(i.width=v,i.height=u);const S=v/o.videoWidth,p=h({sessionInformation:e,videoWidth:o.width}),F=g(c,p);return c.top=F.top,c.left=F.left,c.height=F.bottom-F.top,c.width=F.right-F.left,f({canvas:i,oval:p,scaleFactor:S,videoEl:o}),{faceMatchState:d,ovalDetails:p,scaleFactor:S,initialFace:c}}))},detectFaceAndMatchOval(t){return e(this,void 0,void 0,(function*(){const{serverSessionInformation:e}=t,{videoEl:a}=t.videoAssociatedParams,{faceDetector:o,ovalDetails:i,initialFace:r}=t.ovalAssociatedParams,s=yield o.detectFaces(a);let n,c,d,l=0;const v=g(r,i),{ovalBoundingBox:h}=u(i),f=S(v,h);switch(s.length){case 0:n=D.CANT_IDENTIFY,d=m(a);break;case 1:{c=s[0];const{faceMatchState:t,faceMatchPercentage:a}=p(c,i,f,e);n=t,l=a;break}default:n=D.TOO_MANY}return{faceMatchState:n,faceMatchPercentage:l,illuminationState:d,detectedFace:c}}))},flashColors(t){return e(this,void 0,void 0,(function*(){const{freshnessColorsComplete:e,freshnessColorDisplay:a}=t.freshnessColorAssociatedParams;if(e)return;return{freshnessColorsComplete:yield a.displayColorTick()}}))},stopVideo(t){return e(this,void 0,void 0,(function*(){const{challengeId:e,livenessStreamProvider:a}=t,{videoMediaStream:o}=t.videoAssociatedParams,{initialFace:i,ovalDetails:r}=t.ovalAssociatedParams,{startFace:n,endFace:c}=t.faceMatchAssociatedParams,{width:d,height:l}=o.getTracks()[0].getSettings(),v=d-i.left-i.width;yield a.stopVideo();const m={Challenge:{FaceMovementAndLightChallenge:{ChallengeId:e,InitialFace:{InitialFaceDetectedTimestamp:i.timestampMs,BoundingBox:s({deviceHeight:l,deviceWidth:d,height:i.height,width:i.width,top:i.top,left:v})},TargetFace:{FaceDetectedInTargetPositionStartTimestamp:n.timestampMs,FaceDetectedInTargetPositionEndTimestamp:c.timestampMs,BoundingBox:s({deviceHeight:l,deviceWidth:d,height:r.height,width:r.width,top:r.centerY-r.height/2,left:r.centerX-r.width/2})},VideoEndTimestamp:a.videoRecorder.recorderEndTimestamp}}};a.sendClientInfo(m),yield a.dispatchStopVideoEvent()}))},getLiveness(t){return e(this,void 0,void 0,(function*(){const{livenessStreamProvider:e}=t,{onAnalysisComplete:a}=t.componentProps;e.endStream(),yield a()}))}}}),_=a=>e(void 0,void 0,void 0,(function*(){var e,o,i,r;try{const d=yield B;try{for(var s,n=!0,c=t(d);!(e=(s=yield c.next()).done);){r=s.value,n=!1;try{const e=r;P(e)?a({type:"SET_SESSION_INFO",data:{sessionInfo:e.ServerSessionInformationEvent.SessionInformation}}):T(e)?a({type:"DISCONNECT_EVENT"}):O(e)?a({type:"SERVER_ERROR",data:{error:Object.assign({},e.ValidationException)}}):I(e)?a({type:"SERVER_ERROR",data:{error:Object.assign({},e.InternalServerException)}}):w(e)?a({type:"SERVER_ERROR",data:{error:Object.assign({},e.ThrottlingException)}}):y(e)&&a({type:"SERVER_ERROR",data:{error:Object.assign({},e.ServiceQuotaExceededException)}})}finally{n=!0}}}catch(e){o={error:e}}finally{try{n||e||!(i=c.return)||(yield i.call(c))}finally{if(o)throw o.error}}}catch(e){let t=e;b(e)&&(t=new Error("Invalid region in FaceLivenessDetector or credentials are scoped to the wrong region.")),t instanceof Error&&a({type:"SERVER_ERROR",data:{error:t}})}}));export{k as MIN_FACE_MATCH_TIME,j as livenessMachine};
@@ -0,0 +1 @@
1
+ var R;!function(R){R.TIMEOUT="TIMEOUT",R.RUNTIME_ERROR="RUNTIME_ERROR",R.FRESHNESS_TIMEOUT="FRESHNESS_TIMEOUT",R.SERVER_ERROR="SERVER_ERROR",R.CAMERA_FRAMERATE_ERROR="CAMERA_FRAMERATE_ERROR",R.CAMERA_ACCESS_ERROR="CAMERA_ACCESS_ERROR",R.FACE_DISTANCE_ERROR="FACE_DISTANCE_ERROR",R.MOBILE_LANDSCAPE_ERROR="MOBILE_LANDSCAPE_ERROR"}(R||(R={}));export{R as LivenessErrorState};
@@ -1 +1 @@
1
- var E,R,A;!function(E){E.DARK="dark",E.BRIGHT="bright",E.NORMAL="normal"}(E||(E={})),function(E){E.MATCHED="MATCHED",E.TOO_FAR="TOO FAR",E.TOO_CLOSE="TOO CLOSE",E.CANT_IDENTIFY="CANNOT IDENTIFY",E.FACE_IDENTIFIED="ONE FACE IDENTIFIED",E.TOO_MANY="TOO MANY FACES"}(R||(R={})),function(E){E.TIMEOUT="TIMEOUT",E.RUNTIME_ERROR="RUNTIME_ERROR",E.FRESHNESS_TIMEOUT="FRESHNESS_TIMEOUT",E.SERVER_ERROR="SERVER_ERROR",E.CAMERA_FRAMERATE_ERROR="CAMERA_FRAMERATE_ERROR",E.CAMERA_ACCESS_ERROR="CAMERA_ACCESS_ERROR",E.FACE_DISTANCE_ERROR="FACE_DISTANCE_ERROR",E.MOBILE_LANDSCAPE_ERROR="MOBILE_LANDSCAPE_ERROR"}(A||(A={}));export{R as FaceMatchState,E as IlluminationState,A as LivenessErrorState};
1
+ var O,T;!function(O){O.DARK="dark",O.BRIGHT="bright",O.NORMAL="normal"}(O||(O={})),function(O){O.MATCHED="MATCHED",O.TOO_FAR="TOO FAR",O.TOO_CLOSE="TOO CLOSE",O.CANT_IDENTIFY="CANNOT IDENTIFY",O.FACE_IDENTIFIED="ONE FACE IDENTIFIED",O.TOO_MANY="TOO MANY FACES"}(T||(T={}));export{T as FaceMatchState,O as IlluminationState};
@@ -1 +1 @@
1
- import{__awaiter as t}from"../../../../node_modules/tslib/tslib.es6.mjs";import*as e from"@tensorflow/tfjs-core";import*as o from"@tensorflow-models/blazeface";import*as s from"@tensorflow/tfjs-backend-wasm";import"@tensorflow/tfjs-backend-cpu";import{jitteredExponentialRetry as a}from"@aws-amplify/core";import{isWebAssemblySupported as i}from"./support.mjs";import{FaceDetection as r}from"../types/faceDetection.mjs";import"../types/liveness.mjs";class n extends r{constructor(t,e){super(),this.faceModelUrl=e,this.binaryPath=null!=t?t:`https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${s.version_wasm}/dist/`}loadModels(){return t(this,void 0,void 0,(function*(){i()?yield this._loadWebAssemblyBackend():yield this._loadCPUBackend();try{yield e.ready(),this._model=yield a(o.load,[{modelUrl:this.faceModelUrl}])}catch(t){throw new Error("There was an error loading the blazeface model. If you are using a custom blazeface model url ensure that it is a fully qualified url that returns a json file.")}}))}detectFaces(e){return t(this,void 0,void 0,(function*(){const t=yield this._model.estimateFaces(e,!1,!0,!0),o=Date.now();return t.map((t=>{const{topLeft:e,bottomRight:s,probability:a,landmarks:i}=t;if(void 0===i)return;const[r,n]=e,[d,l]=s,m=Math.abs(r-d),c=Math.abs(l-n),f=i[0],h=i[1],u=i[2],p=i[3];return{top:n,left:d,width:m,height:c,timestampMs:o,probability:a[0],rightEye:f,leftEye:h,mouth:p,nose:u}}))}))}_loadWebAssemblyBackend(){return t(this,void 0,void 0,(function*(){try{s.setWasmPaths(this.binaryPath),yield a((()=>t(this,void 0,void 0,(function*(){if(!(yield e.setBackend("wasm")))throw new Error("Initialization of backend wasm failed")}))),[]),this.modelBackend="wasm"}catch(t){throw new Error('There was an error loading the TFJS WASM backend. If you are using a custom WASM path ensure that it ends with "/" and that it is not the full URL as @tensorflow/tfjs-backend-wasm will append the wasm binary file name. Read more: https://github.com/tensorflow/tfjs/blob/master/tfjs-backend-wasm/src/backend_wasm.ts#L475.')}}))}_loadCPUBackend(){return t(this,void 0,void 0,(function*(){yield e.setBackend("cpu"),this.modelBackend="cpu"}))}}export{n as BlazeFaceFaceDetection};
1
+ import{__awaiter as t}from"../../../../node_modules/tslib/tslib.es6.mjs";import*as e from"@tensorflow/tfjs-core";import*as s from"@tensorflow-models/blazeface";import*as o from"@tensorflow/tfjs-backend-wasm";import"@tensorflow/tfjs-backend-cpu";import{jitteredExponentialRetry as a}from"@aws-amplify/core";import{isWebAssemblySupported as r}from"./support.mjs";import{FaceDetection as i}from"../types/faceDetection.mjs";import"../types/liveness.mjs";import"../types/error.mjs";class n extends i{constructor(t,e){super(),this.faceModelUrl=e,this.binaryPath=null!=t?t:`https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${o.version_wasm}/dist/`}loadModels(){return t(this,void 0,void 0,(function*(){r()?yield this._loadWebAssemblyBackend():yield this._loadCPUBackend();try{yield e.ready(),this._model=yield a(s.load,[{modelUrl:this.faceModelUrl}])}catch(t){throw new Error("There was an error loading the blazeface model. If you are using a custom blazeface model url ensure that it is a fully qualified url that returns a json file.")}}))}detectFaces(e){return t(this,void 0,void 0,(function*(){const t=yield this._model.estimateFaces(e,!1,!0,!0),s=Date.now();return t.filter((t=>!!t.landmarks)).map((t=>{const{topLeft:e,bottomRight:o,probability:a,landmarks:r}=t,[i,n]=e,[l,d]=o,m=Math.abs(i-l),c=Math.abs(d-n),f=r[0],h=r[1],u=r[2],p=r[3];return{top:n,left:l,width:m,height:c,timestampMs:s,probability:a[0],rightEye:f,leftEye:h,mouth:p,nose:u}}))}))}_loadWebAssemblyBackend(){return t(this,void 0,void 0,(function*(){try{o.setWasmPaths(this.binaryPath),yield a((()=>t(this,void 0,void 0,(function*(){if(!(yield e.setBackend("wasm")))throw new Error("Initialization of backend wasm failed")}))),[]),this.modelBackend="wasm"}catch(t){throw new Error('There was an error loading the TFJS WASM backend. If you are using a custom WASM path ensure that it ends with "/" and that it is not the full URL as @tensorflow/tfjs-backend-wasm will append the wasm binary file name. Read more: https://github.com/tensorflow/tfjs/blob/master/tfjs-backend-wasm/src/backend_wasm.ts#L475.')}}))}_loadCPUBackend(){return t(this,void 0,void 0,(function*(){yield e.setBackend("cpu"),this.modelBackend="cpu"}))}}export{n as BlazeFaceFaceDetection};
@@ -1 +1 @@
1
- import{__awaiter as e}from"../../../../node_modules/tslib/tslib.es6.mjs";import{fillOverlayCanvasFractional as t,getFaceMatchState as o,getRGBArrayFromColorString as s}from"./liveness.mjs";import{FaceMatchState as r}from"../types/liveness.mjs";var i;!function(e){e.SCROLLING="SCROLLING",e.FLAT="FLAT"}(i||(i={}));class l{constructor(e,t){this.context=e,this.freshnessColorsSequence=t,this.isFirstTick=!0}displayColorTick(){return e(this,void 0,void 0,(function*(){return new Promise(((e,t)=>{setTimeout((()=>{this.displayNextColorTick(e,t)}),Math.min(10))}))}))}init(){this.stageIndex=0,this.currColorIndex=0,this.currColorSequence=this.freshnessColorsSequence[0],this.prevColorSequence=this.freshnessColorsSequence[0],this.stage=i.FLAT,this.timeLastFlatOrScrollChange=Date.now(),this.timeLastFaceMatchChecked=Date.now()}displayNextColorTick(e,o){const{freshnessColorAssociatedParams:{freshnessColorEl:s},ovalAssociatedParams:{ovalDetails:r,scaleFactor:l},videoAssociatedParams:{videoEl:n}}=this.context,c=Date.now();this.isFirstTick&&(this.init(),this.isFirstTick=!1,this.sendColorStartTime({tickStartTime:c,currColor:this.currColorSequence.color,prevColor:this.currColorSequence.color,currColorIndex:this.stageIndex}));let a=c-this.timeLastFlatOrScrollChange;if(s.style.display="block",(this.stage===i.FLAT&&a>=this.currColorSequence.flatDisplayDuration||this.stage===i.SCROLLING&&a>=this.currColorSequence.downscrollDuration)&&(this.incrementStageIndex(c),a=0),this.currColorIndex<this.freshnessColorsSequence.length){const o=a/(this.stage===i.SCROLLING?this.currColorSequence.downscrollDuration:this.currColorSequence.flatDisplayDuration);t({overlayCanvas:s,prevColor:this.prevColorSequence.color,nextColor:this.currColorSequence.color,videoEl:n,ovalDetails:r,heightFraction:o,scaleFactor:l}),e(!1)}else s.style.display="none",e(!0)}incrementStageIndex(e){if(this.stageIndex+=1,this.prevColorSequence=this.freshnessColorsSequence[this.currColorIndex],this.stage===i.FLAT)this.currColorIndex+=1,this.stage=i.SCROLLING;else if(this.stage===i.SCROLLING){this.freshnessColorsSequence[this.currColorIndex].flatDisplayDuration>0?this.stage=i.FLAT:(this.stage=i.SCROLLING,this.currColorIndex+=1)}this.currColorSequence=this.freshnessColorsSequence[this.currColorIndex],this.timeLastFlatOrScrollChange=Date.now(),this.currColorSequence&&this.sendColorStartTime({tickStartTime:e,currColor:this.currColorSequence.color,prevColor:this.prevColorSequence.color,currColorIndex:this.stageIndex})}matchFaceInOval(t){return e(this,void 0,void 0,(function*(){const{ovalAssociatedParams:{faceDetector:e},videoAssociatedParams:{videoEl:s}}=this.context;if(Date.now()-this.timeLastFaceMatchChecked>100){const i=yield o(e,s);if(this.timeLastFaceMatchChecked=Date.now(),i===r.MATCHED)this.timeFaceMatched=Date.now();else{Date.now()-this.timeFaceMatched>1e3&&t()}}}))}sendColorStartTime({tickStartTime:e,currColor:t,prevColor:o,currColorIndex:r}){const{livenessStreamProvider:i,challengeId:l}=this.context;i.sendClientInfo({Challenge:{FaceMovementAndLightChallenge:{ChallengeId:l,ColorDisplayed:{CurrentColor:{RGB:s(t)},PreviousColor:{RGB:s(o)},SequenceNumber:r,CurrentColorStartTimestamp:e}}}})}}export{l as FreshnessColorDisplay};
1
+ import{__awaiter as e}from"../../../../node_modules/tslib/tslib.es6.mjs";import{fillOverlayCanvasFractional as r,getRGBArrayFromColorString as o}from"./liveness.mjs";var t;!function(e){e.SCROLLING="SCROLLING",e.FLAT="FLAT"}(t||(t={}));class s{constructor(e,r){this.context=e,this.freshnessColorsSequence=r,this.isFirstTick=!0}displayColorTick(){return e(this,void 0,void 0,(function*(){return new Promise(((e,r)=>{setTimeout((()=>{this.displayNextColorTick(e,r)}),Math.min(10))}))}))}init(){this.stageIndex=0,this.currColorIndex=0,this.currColorSequence=this.freshnessColorsSequence[0],this.prevColorSequence=this.freshnessColorsSequence[0],this.stage=t.FLAT,this.timeLastFlatOrScrollChange=Date.now(),this.timeLastFaceMatchChecked=Date.now()}displayNextColorTick(e,o){const{freshnessColorEl:s}=this.context.freshnessColorAssociatedParams,{ovalDetails:i,scaleFactor:l}=this.context.ovalAssociatedParams,{videoEl:n}=this.context.videoAssociatedParams,c=Date.now();this.isFirstTick&&(this.init(),this.isFirstTick=!1,this.sendColorStartTime({tickStartTime:c,currColor:this.currColorSequence.color,prevColor:this.currColorSequence.color,currColorIndex:this.stageIndex}));let a=c-this.timeLastFlatOrScrollChange;if(s.style.display="block",(this.stage===t.FLAT&&a>=this.currColorSequence.flatDisplayDuration||this.stage===t.SCROLLING&&a>=this.currColorSequence.downscrollDuration)&&(this.incrementStageIndex(c),a=0),this.currColorIndex<this.freshnessColorsSequence.length){const o=a/(this.stage===t.SCROLLING?this.currColorSequence.downscrollDuration:this.currColorSequence.flatDisplayDuration);r({overlayCanvas:s,prevColor:this.prevColorSequence.color,nextColor:this.currColorSequence.color,videoEl:n,ovalDetails:i,heightFraction:o,scaleFactor:l}),e(!1)}else s.style.display="none",e(!0)}incrementStageIndex(e){if(this.stageIndex+=1,this.prevColorSequence=this.freshnessColorsSequence[this.currColorIndex],this.stage===t.FLAT)this.currColorIndex+=1,this.stage=t.SCROLLING;else if(this.stage===t.SCROLLING){this.freshnessColorsSequence[this.currColorIndex].flatDisplayDuration>0?this.stage=t.FLAT:(this.stage=t.SCROLLING,this.currColorIndex+=1)}this.currColorSequence=this.freshnessColorsSequence[this.currColorIndex],this.timeLastFlatOrScrollChange=Date.now(),this.currColorSequence&&this.sendColorStartTime({tickStartTime:e,currColor:this.currColorSequence.color,prevColor:this.prevColorSequence.color,currColorIndex:this.stageIndex})}sendColorStartTime({tickStartTime:e,currColor:r,prevColor:t,currColorIndex:s}){const{livenessStreamProvider:i,challengeId:l}=this.context;i.sendClientInfo({Challenge:{FaceMovementAndLightChallenge:{ChallengeId:l,ColorDisplayed:{CurrentColor:{RGB:o(r)},PreviousColor:{RGB:o(t)},SequenceNumber:s,CurrentColorStartTimestamp:e}}}})}}export{s as FreshnessColorDisplay};
@@ -1 +1 @@
1
- import{__awaiter as t}from"../../../../node_modules/tslib/tslib.es6.mjs";import{LivenessErrorState as e,FaceMatchState as o,IlluminationState as n}from"../types/liveness.mjs";import{FACE_DISTANCE_THRESHOLD as i,REDUCED_THRESHOLD_MOBILE as l,REDUCED_THRESHOLD as r}from"./constants.mjs";function a(t,e,o){return t*(o-e)+e}function h(t){const e=t.flippedCenterX-t.width/2,o=t.flippedCenterX+t.width/2,n=t.centerY-t.height/2,i=t.centerY+t.height/2;return{ovalBoundingBox:{left:e,top:n,right:o,bottom:i},minOvalX:e,maxOvalX:o,minOvalY:n,maxOvalY:i}}function c(t,e){const o=Math.max(t.left,e.left),n=Math.max(t.top,e.top),i=Math.min(t.right,e.right),l=Math.min(t.bottom,e.bottom),r=Math.abs(Math.max(0,i-o)*Math.max(0,l-n));if(0===r)return 0;return r/(Math.abs((t.right-t.left)*(t.bottom-t.top))+Math.abs((e.right-e.left)*(e.bottom-e.top))-r)}function d({sessionInformation:t,videoWidth:e}){var o,n;const i=null===(n=null===(o=null==t?void 0:t.Challenge)||void 0===o?void 0:o.FaceMovementAndLightChallenge)||void 0===n?void 0:n.OvalParameters;return{flippedCenterX:(null==i?void 0:i.CenterX)?e-(null==i?void 0:i.CenterX):void 0,centerX:null==i?void 0:i.CenterX,centerY:null==i?void 0:i.CenterY,width:null==i?void 0:i.Width,height:null==i?void 0:i.Height}}function s({width:t,height:e,widthSeed:o=1,centerXSeed:n=.5,centerYSeed:i=.5}){const l=e;let r=t;const h=.8*o,c=Math.floor(7*t/16),d=Math.floor(9*t/16),s=Math.floor(7*e/16),f=Math.floor(9*e/16),v=a(n,c,d),u=a(i,s,f);t>=e&&(r=3/4*l);const g=h*r,R=1.618*g;return{flippedCenterX:Math.floor(r-v),centerX:Math.floor(v),centerY:Math.floor(u),width:Math.floor(g),height:Math.floor(R)}}function f({canvas:t,oval:e,scaleFactor:o,videoEl:n}){const{flippedCenterX:i,centerY:l,width:r,height:a}=e,{width:h,height:c}=t.getBoundingClientRect(),d=t.getContext("2d");if(!d)throw new Error("Cannot find Canvas.");{d.clearRect(0,0,h,c),d.fillStyle="rgba(255, 255, 255, 1.0)",d.fillRect(0,0,h,c);const t={width:n.videoWidth,height:n.videoHeight},e={x:(h-t.width*o)/2,y:(c-t.height*o)/2};d.setTransform(o,0,0,o,e.x,e.y),d.beginPath(),d.ellipse(i,l,r/2,a/2,0,0,2*Math.PI),d.strokeStyle="#AEB3B7",d.lineWidth=3,d.stroke(),d.clip(),d.setTransform(1,0,0,1,0,0),d.clearRect(0,0,h,c)}}function v(t,e,n,i){let l;const{OvalIouThreshold:r,OvalIouHeightThreshold:a,OvalIouWidthThreshold:d,FaceIouHeightThreshold:s,FaceIouWidthThreshold:f}=i.Challenge.FaceMovementAndLightChallenge.ChallengeConfig,v=g(t,e),u=v.left,R=v.right,E=v.top,C=v.bottom,{ovalBoundingBox:M,minOvalX:p,minOvalY:m,maxOvalX:w,maxOvalY:O}=h(e),A=c(v,M),T=r,x=e.width*d,b=e.height*a,_=e.width*f,I=e.height*s,S=100*Math.max(Math.min(1,.75*(A-n)/(T-n)+.25),0);return l=A>T&&Math.abs(p-u)<x&&Math.abs(w-R)<x&&Math.abs(O-C)<b?o.MATCHED:m-E>I||C-O>I||p-u>_&&R-w>_?o.TOO_CLOSE:o.TOO_FAR,{faceMatchState:l,faceMatchPercentage:S}}function u(t){const{leftEye:e,rightEye:o,mouth:n}=t,i=[];i[0]=(e[0]+o[0])/2,i[1]=(e[1]+o[1])/2;return{pupilDistance:Math.sqrt(Math.pow(e[0]-o[0],2)+Math.pow(e[1]-o[1],2)),faceHeight:Math.sqrt(Math.pow(i[0]-n[0],2)+Math.pow(i[1]-n[1],2))}}function g(t,e){const{leftEye:o,rightEye:n,nose:i}=t,{height:l,centerY:r}=e,a=r-l/2,h=[];h[0]=(o[0]+n[0])/2,h[1]=(o[1]+n[1])/2;const{pupilDistance:c,faceHeight:d}=u(t),s=(2*c+1.8*d)/2,f=1.618*s;let v,g;h[1]<=(a+l)/2?(v=(h[0]+i[0])/2,g=(h[1]+i[1])/2):(v=h[0],g=h[1]);const R=v-s/2,E=g-f/2;return{left:R,top:E,right:R+s,bottom:E+f}}function R(t){const e=document.createElement("canvas");e.width=t.videoWidth,e.height=t.videoHeight;const o=e.getContext("2d");if(o){o.drawImage(t,0,0,e.width,e.height);const i=o.getImageData(0,0,e.width,e.height).data,l=8,r=new Array(l).fill(0);for(let t=0;t<i.length;t++){r[Math.round(.2126*i[t++]+.7152*i[t++]+.0722*i[t++])%32]++}let a=-1,h=0;for(let t=0;t<l;t++)r[t]>h&&(h=r[t],a=t);return e.remove(),0===a?n.DARK:a===l?n.BRIGHT:n.NORMAL}throw new Error("Cannot find Video Element.")}function E(t){return t.label.toLowerCase().includes("virtual")}const C={[e.RUNTIME_ERROR]:"RUNTIME_ERROR",[e.SERVER_ERROR]:"SERVER_ERROR",[e.TIMEOUT]:"TIMEOUT",[e.FACE_DISTANCE_ERROR]:"FACE_DISTANCE_ERROR",[e.CAMERA_FRAMERATE_ERROR]:"CAMERA_FRAMERATE_ERROR",[e.CAMERA_ACCESS_ERROR]:"CAMERA_ACCESS_ERROR",[e.MOBILE_LANDSCAPE_ERROR]:"MOBILE_LANDSCAPE_ERROR",[e.FRESHNESS_TIMEOUT]:"FRESHNESS_TIMEOUT"};function M({ctx:t,prevColor:e,nextColor:o,fraction:n}){const i=t.canvas.width,l=t.canvas.height;t.fillStyle=o,t.fillRect(0,0,i,l*n),1!==n&&(t.fillStyle=e,t.fillRect(0,l*n,i,l*(1-n)))}function p({overlayCanvas:t,prevColor:e,nextColor:o,videoEl:n,ovalDetails:i,heightFraction:l,scaleFactor:r}){const{x:a,y:h}=n.getBoundingClientRect(),{flippedCenterX:c,centerY:d,width:s,height:f}=i,v=c*r+a,u=d*r+h,g=t.width,R=t.height,E=t.getContext("2d");if(!E)throw new Error("Cannot find Overlay Canvas.");E.canvas.width=window.innerWidth,E.canvas.height=window.innerHeight,E.clearRect(0,0,g,R),M({ctx:E,prevColor:e,nextColor:o,fraction:l}),E.save(),E.beginPath(),E.rect(0,0,g,R),E.clip(),E.clearRect(0,0,g,R),E.globalAlpha=.9,M({ctx:E,prevColor:e,nextColor:o,fraction:l}),E.beginPath(),E.ellipse(v,u,s*r/2,f*r/2,0,0,2*Math.PI),E.strokeStyle="white",E.lineWidth=8,E.stroke(),E.clip(),E.clearRect(0,0,g,R),E.globalAlpha=.75,M({ctx:E,prevColor:e,nextColor:o,fraction:l}),E.restore()}const m=t=>!!t;function w(t){var e,o;const n=null===(o=null===(e=t.Challenge)||void 0===e?void 0:e.FaceMovementAndLightChallenge)||void 0===o?void 0:o.ColorSequences;return[...n||[]].map((({FreshnessColor:t,DownscrollDuration:e,FlatDisplayDuration:o})=>{const n=null==t?void 0:t.RGB,i=n?`rgb(${n[0]},${n[1]},${n[2]})`:"";return void 0!==i&&void 0!==e&&void 0!==o?{color:i,downscrollDuration:e,flatDisplayDuration:o}:void 0})).filter(m)}function O(t){return t.slice(t.indexOf("(")+1,t.indexOf(")")).split(",").map((t=>parseInt(t)))}function A(e,n){return t(this,void 0,void 0,(function*(){let t;switch((yield e.detectFaces(n)).length){case 0:t=o.CANT_IDENTIFY;break;case 1:t=o.FACE_IDENTIFIED;break;default:t=o.TOO_MANY}return t}))}function T({faceDetector:e,videoEl:o,ovalDetails:n,reduceThreshold:a=!1,isMobile:h=!1}){return t(this,void 0,void 0,(function*(){const t=yield e.detectFaces(o);let c,d=!1;switch(t.length){case 0:break;case 1:{c=t[0];const e=null==n?void 0:n.width,{pupilDistance:o,faceHeight:s}=u(c),f=2,v=(f*o+1.8*s)/2/f;e&&(d=v/e<(a?h?l:r:i));break}}return d}))}function x({deviceHeight:t,deviceWidth:e,height:o,width:n,top:i,left:l}){return{Height:o/t,Width:n/e,Top:i/t,Left:l/e}}export{C as LivenessErrorStateStringMap,f as drawLivenessOvalInCanvas,R as estimateIllumination,p as fillOverlayCanvasFractional,g as generateBboxFromLandmarks,x as getBoundingBox,w as getColorsSequencesFromSessionInformation,A as getFaceMatchState,v as getFaceMatchStateInLivenessOval,c as getIntersectionOverUnion,h as getOvalBoundingBox,d as getOvalDetailsFromSessionInformation,O as getRGBArrayFromColorString,s as getStaticLivenessOvalDetails,E as isCameraDeviceVirtual,m as isClientFreshnessColorSequence,T as isFaceDistanceBelowThreshold};
1
+ import{__awaiter as t}from"../../../../node_modules/tslib/tslib.es6.mjs";import{FaceMatchState as e,IlluminationState as o}from"../types/liveness.mjs";import{LivenessErrorState as n}from"../types/error.mjs";import{FACE_DISTANCE_THRESHOLD as i,REDUCED_THRESHOLD_MOBILE as r,REDUCED_THRESHOLD as a}from"./constants.mjs";function h(t,e,o){return t*(o-e)+e}function l(t){const e=t.flippedCenterX-t.width/2,o=t.flippedCenterX+t.width/2,n=t.centerY-t.height/2,i=t.centerY+t.height/2;return{ovalBoundingBox:{left:e,top:n,right:o,bottom:i},minOvalX:e,maxOvalX:o,minOvalY:n,maxOvalY:i}}function c(t,e){const o=Math.max(t.left,e.left),n=Math.max(t.top,e.top),i=Math.min(t.right,e.right),r=Math.min(t.bottom,e.bottom),a=Math.abs(Math.max(0,i-o)*Math.max(0,r-n));if(0===a)return 0;return a/(Math.abs((t.right-t.left)*(t.bottom-t.top))+Math.abs((e.right-e.left)*(e.bottom-e.top))-a)}function s({sessionInformation:t,videoWidth:e}){var o,n;const i=null===(n=null===(o=null==t?void 0:t.Challenge)||void 0===o?void 0:o.FaceMovementAndLightChallenge)||void 0===n?void 0:n.OvalParameters;if(!(i&&i.CenterX&&i.CenterY&&i.Width&&i.Height))throw new Error("Oval parameters not returned from session information.");return{flippedCenterX:e-i.CenterX,centerX:i.CenterX,centerY:i.CenterY,width:i.Width,height:i.Height}}function d({width:t,height:e,widthSeed:o=1,centerXSeed:n=.5,centerYSeed:i=.5}){const r=e;let a=t;const l=.8*o,c=Math.floor(7*t/16),s=Math.floor(9*t/16),d=Math.floor(7*e/16),f=Math.floor(9*e/16),g=h(n,c,s),u=h(i,d,f);t>=e&&(a=3/4*r);const v=l*a,R=1.618*v;return{flippedCenterX:Math.floor(a-g),centerX:Math.floor(g),centerY:Math.floor(u),width:Math.floor(v),height:Math.floor(R)}}function f({canvas:t,oval:e,scaleFactor:o,videoEl:n}){const{flippedCenterX:i,centerY:r,width:a,height:h}=e,{width:l,height:c}=t.getBoundingClientRect(),s=t.getContext("2d");if(!s)throw new Error("Cannot find Canvas.");{s.clearRect(0,0,l,c),s.fillStyle="rgba(255, 255, 255, 1.0)",s.fillRect(0,0,l,c);const t={width:n.videoWidth,height:n.videoHeight},e={x:(l-t.width*o)/2,y:(c-t.height*o)/2};s.setTransform(o,0,0,o,e.x,e.y),s.beginPath(),s.ellipse(i,r,a/2,h/2,0,0,2*Math.PI),s.strokeStyle="#AEB3B7",s.lineWidth=3,s.stroke(),s.clip(),s.setTransform(1,0,0,1,0,0),s.clearRect(0,0,l,c)}}function g(t,o,n,i){var r,a;let h;const s=null===(a=null===(r=null==i?void 0:i.Challenge)||void 0===r?void 0:r.FaceMovementAndLightChallenge)||void 0===a?void 0:a.ChallengeConfig;if(!(s&&s.OvalIouThreshold&&s.OvalIouHeightThreshold&&s.OvalIouWidthThreshold&&s.FaceIouHeightThreshold&&s.FaceIouWidthThreshold))throw new Error("Challenge information not returned from session information.");const{OvalIouThreshold:d,OvalIouHeightThreshold:f,OvalIouWidthThreshold:g,FaceIouHeightThreshold:u,FaceIouWidthThreshold:R}=s,E=v(t,o),C=E.left,m=E.right,p=E.top,M=E.bottom,{ovalBoundingBox:w,minOvalX:O,minOvalY:A,maxOvalX:T,maxOvalY:I}=l(o),x=c(E,w),b=d,_=o.width*g,S=o.height*f,F=o.width*R,D=o.height*u,y=100*Math.max(Math.min(1,.75*(x-n)/(b-n)+.25),0);return h=x>b&&Math.abs(O-C)<_&&Math.abs(T-m)<_&&Math.abs(I-M)<S?e.MATCHED:A-p>D||M-I>D||O-C>F&&m-T>F?e.TOO_CLOSE:e.TOO_FAR,{faceMatchState:h,faceMatchPercentage:y}}function u(t){const{leftEye:e,rightEye:o,mouth:n}=t,i=[];i[0]=(e[0]+o[0])/2,i[1]=(e[1]+o[1])/2;return{pupilDistance:Math.sqrt(Math.pow(e[0]-o[0],2)+Math.pow(e[1]-o[1],2)),faceHeight:Math.sqrt(Math.pow(i[0]-n[0],2)+Math.pow(i[1]-n[1],2))}}function v(t,e){const{leftEye:o,rightEye:n,nose:i}=t,{height:r,centerY:a}=e,h=a-r/2,l=[];l[0]=(o[0]+n[0])/2,l[1]=(o[1]+n[1])/2;const{pupilDistance:c,faceHeight:s}=u(t),d=(2*c+1.8*s)/2,f=1.618*d;let g,v;l[1]<=(h+r)/2?(g=(l[0]+i[0])/2,v=(l[1]+i[1])/2):(g=l[0],v=l[1]);const R=g-d/2,E=v-f/2;return{left:R,top:E,right:R+d,bottom:E+f}}function R(t){const e=document.createElement("canvas");e.width=t.videoWidth,e.height=t.videoHeight;const n=e.getContext("2d");if(n){n.drawImage(t,0,0,e.width,e.height);const i=n.getImageData(0,0,e.width,e.height).data,r=8,a=new Array(r).fill(0);for(let t=0;t<i.length;t++){a[Math.round(.2126*i[t++]+.7152*i[t++]+.0722*i[t++])%32]++}let h=-1,l=0;for(let t=0;t<r;t++)a[t]>l&&(l=a[t],h=t);return e.remove(),0===h?o.DARK:h===r?o.BRIGHT:o.NORMAL}throw new Error("Cannot find Video Element.")}function E(t){return t.label.toLowerCase().includes("virtual")}const C={[n.RUNTIME_ERROR]:"RUNTIME_ERROR",[n.SERVER_ERROR]:"SERVER_ERROR",[n.TIMEOUT]:"TIMEOUT",[n.FACE_DISTANCE_ERROR]:"FACE_DISTANCE_ERROR",[n.CAMERA_FRAMERATE_ERROR]:"CAMERA_FRAMERATE_ERROR",[n.CAMERA_ACCESS_ERROR]:"CAMERA_ACCESS_ERROR",[n.MOBILE_LANDSCAPE_ERROR]:"MOBILE_LANDSCAPE_ERROR",[n.FRESHNESS_TIMEOUT]:"FRESHNESS_TIMEOUT"};function m({ctx:t,prevColor:e,nextColor:o,fraction:n}){const i=t.canvas.width,r=t.canvas.height;t.fillStyle=o,t.fillRect(0,0,i,r*n),1!==n&&(t.fillStyle=e,t.fillRect(0,r*n,i,r*(1-n)))}function p({overlayCanvas:t,prevColor:e,nextColor:o,videoEl:n,ovalDetails:i,heightFraction:r,scaleFactor:a}){const{x:h,y:l}=n.getBoundingClientRect(),{flippedCenterX:c,centerY:s,width:d,height:f}=i,g=c*a+h,u=s*a+l,v=t.width,R=t.height,E=t.getContext("2d");if(!E)throw new Error("Cannot find Overlay Canvas.");E.canvas.width=window.innerWidth,E.canvas.height=window.innerHeight,E.clearRect(0,0,v,R),m({ctx:E,prevColor:e,nextColor:o,fraction:r}),E.save(),E.beginPath(),E.rect(0,0,v,R),E.clip(),E.clearRect(0,0,v,R),E.globalAlpha=.9,m({ctx:E,prevColor:e,nextColor:o,fraction:r}),E.beginPath(),E.ellipse(g,u,d*a/2,f*a/2,0,0,2*Math.PI),E.strokeStyle="white",E.lineWidth=8,E.stroke(),E.clip(),E.clearRect(0,0,v,R),E.globalAlpha=.75,m({ctx:E,prevColor:e,nextColor:o,fraction:r}),E.restore()}const M=t=>!!t;function w(t){return(t.Challenge.FaceMovementAndLightChallenge.ColorSequences||[]).map((({FreshnessColor:t,DownscrollDuration:e,FlatDisplayDuration:o})=>{const n=t.RGB,i=`rgb(${n[0]},${n[1]},${n[2]})`;return void 0!==i&&void 0!==e&&void 0!==o?{color:i,downscrollDuration:e,flatDisplayDuration:o}:void 0})).filter(M)}function O(t){return t.slice(t.indexOf("(")+1,t.indexOf(")")).split(",").map((t=>parseInt(t)))}function A(o,n){return t(this,void 0,void 0,(function*(){let t;switch((yield o.detectFaces(n)).length){case 0:t=e.CANT_IDENTIFY;break;case 1:t=e.FACE_IDENTIFIED;break;default:t=e.TOO_MANY}return t}))}function T({faceDetector:e,videoEl:o,ovalDetails:n,reduceThreshold:h=!1,isMobile:l=!1}){return t(this,void 0,void 0,(function*(){const t=yield e.detectFaces(o);let c,s=!1;switch(t.length){case 0:break;case 1:{c=t[0];const e=n.width,{pupilDistance:o,faceHeight:d}=u(c),f=2;e&&(s=(f*o+1.8*d)/2/f/e<(h?l?r:a:i));break}}return s}))}function I({deviceHeight:t,deviceWidth:e,height:o,width:n,top:i,left:r}){return{Height:o/t,Width:n/e,Top:i/t,Left:r/e}}export{C as LivenessErrorStateStringMap,f as drawLivenessOvalInCanvas,R as estimateIllumination,p as fillOverlayCanvasFractional,v as generateBboxFromLandmarks,I as getBoundingBox,w as getColorsSequencesFromSessionInformation,A as getFaceMatchState,g as getFaceMatchStateInLivenessOval,c as getIntersectionOverUnion,l as getOvalBoundingBox,s as getOvalDetailsFromSessionInformation,O as getRGBArrayFromColorString,d as getStaticLivenessOvalDetails,E as isCameraDeviceVirtual,M as isClientFreshnessColorSequence,T as isFaceDistanceBelowThreshold};
@@ -1 +1 @@
1
- import{__awaiter as e,__asyncGenerator as i,__await as t}from"../../../../node_modules/tslib/tslib.es6.mjs";import{Credentials as o,getAmplifyUserAgent as n}from"@aws-amplify/core";import{AmazonAIInterpretPredictionsProvider as s}from"@aws-amplify/predictions";import{RekognitionStreamingClient as r,StartFaceLivenessSessionCommand as d}from"@aws-sdk/client-rekognitionstreaming";import{VideoRecorder as a}from"./videoRecorder.mjs";const l=process.env.NEXT_PUBLIC_STREAMING_API_URL,h=1e3;function c(e){return void 0!==e.arrayBuffer}function v(e){return void 0!==e.Challenge}class m extends s{constructor(e,i,t,o){super(),this.sessionId=e,this.region=i,this._stream=t,this.videoEl=o,this.videoRecorder=new a(t),this.initPromise=this.init()}getResponseStream(){return e(this,void 0,void 0,(function*(){return yield this.initPromise,this.responseStream}))}startRecordingLivenessVideo(){this.videoRecorder.start(1e3)}sendClientInfo(e){this.videoRecorder.dispatch(new MessageEvent("clientSesssionInfo",{data:{clientInfo:e}}))}stopVideo(){return e(this,void 0,void 0,(function*(){yield this.videoRecorder.stop()}))}dispatchStopVideoEvent(){this.videoRecorder.dispatch(new Event("stopVideo"))}endStream(){return e(this,void 0,void 0,(function*(){if("recording"===this.videoRecorder.getState()&&(yield this.stopVideo(),this.dispatchStopVideoEvent()),this._reader)return yield this._reader.cancel(),this._reader.closed}))}init(){return e(this,void 0,void 0,(function*(){const e=yield o.get();if(!e)throw new Error("No credentials");const i={credentials:e,region:this.region,customUserAgent:n()};l&&(i.endpointProvider=()=>({url:new URL(l)})),this._client=new r(i),this.responseStream=yield this.startLivenessVideoConnection()}))}getAsyncGeneratorFromReadableStream(e){const o=this;return this._reader=e.getReader(),function(){return i(this,arguments,(function*(){for(;;){const{done:e,value:i}=yield t(o._reader.read());if(e)return yield t(void 0);if("stopVideo"===i)yield yield t({VideoEvent:{VideoChunk:[],TimestampMillis:Date.now()}});else if(c(i)){const e=yield t(i.arrayBuffer()),o=new Uint8Array(e);o.length>0&&(yield yield t({VideoEvent:{VideoChunk:o,TimestampMillis:Date.now()}}))}else v(i)&&(yield yield t({ClientSessionInformationEvent:{Challenge:i.Challenge}}))}}))}}startLivenessVideoConnection(){return e(this,void 0,void 0,(function*(){const e=this.getAsyncGeneratorFromReadableStream(this.videoRecorder.videoStream)();return(yield this._client.send(new d({ChallengeVersions:"FaceMovementAndLightChallenge_1.0.0",SessionId:this.sessionId,LivenessRequestStream:e,VideoWidth:this.videoEl.videoWidth.toString(),VideoHeight:this.videoEl.videoHeight.toString()}))).LivenessResponseStream}))}}export{m as LivenessStreamProvider,h as TIME_SLICE};
1
+ import{__awaiter as e,__asyncGenerator as i,__await as t}from"../../../../node_modules/tslib/tslib.es6.mjs";import{Credentials as o,getAmplifyUserAgent as n}from"@aws-amplify/core";import{AmazonAIInterpretPredictionsProvider as s}from"@aws-amplify/predictions";import{RekognitionStreamingClient as r,StartFaceLivenessSessionCommand as d}from"@aws-sdk/client-rekognitionstreaming";import{WebSocketFetchHandler as a}from"@aws-sdk/middleware-websocket";import{VideoRecorder as l}from"./videoRecorder.mjs";const h=process.env.NEXT_PUBLIC_STREAMING_API_URL,c=1e3;function v(e){return void 0!==e.Challenge}class m extends s{constructor(e,i,t,o){super(),this.sessionId=e,this.region=i,this._stream=t,this.videoEl=o,this.videoRecorder=new l(t),this.initPromise=this.init()}getResponseStream(){return e(this,void 0,void 0,(function*(){return yield this.initPromise,this.responseStream}))}startRecordingLivenessVideo(){this.videoRecorder.start(1e3)}sendClientInfo(e){this.videoRecorder.dispatch(new MessageEvent("clientSesssionInfo",{data:{clientInfo:e}}))}stopVideo(){return e(this,void 0,void 0,(function*(){yield this.videoRecorder.stop()}))}dispatchStopVideoEvent(){this.videoRecorder.dispatch(new Event("stopVideo"))}endStream(){return e(this,void 0,void 0,(function*(){if("recording"===this.videoRecorder.getState()&&(yield this.stopVideo(),this.dispatchStopVideoEvent()),this._reader)return yield this._reader.cancel(),this._reader.closed}))}init(){return e(this,void 0,void 0,(function*(){const e=yield o.get();if(!e)throw new Error("No credentials");const i={credentials:e,region:this.region,customUserAgent:n(),requestHandler:new a({connectionTimeout:1e4})};h&&(i.endpointProvider=()=>({url:new URL(h)})),this._client=new r(i),this.responseStream=yield this.startLivenessVideoConnection()}))}getAsyncGeneratorFromReadableStream(e){const o=this;return this._reader=e.getReader(),function(){return i(this,arguments,(function*(){for(;;){const{done:e,value:i}=yield t(o._reader.read());if(e)return yield t(void 0);if("stopVideo"===i)yield yield t({VideoEvent:{VideoChunk:[],TimestampMillis:Date.now()}});else if(void 0!==i.arrayBuffer){const e=yield t(i.arrayBuffer()),o=new Uint8Array(e);o.length>0&&(yield yield t({VideoEvent:{VideoChunk:o,TimestampMillis:Date.now()}}))}else v(i)&&(yield yield t({ClientSessionInformationEvent:{Challenge:i.Challenge}}))}}))}}startLivenessVideoConnection(){return e(this,void 0,void 0,(function*(){const e=this.getAsyncGeneratorFromReadableStream(this.videoRecorder.videoStream)();return(yield this._client.send(new d({ChallengeVersions:"FaceMovementAndLightChallenge_1.0.0",SessionId:this.sessionId,LivenessRequestStream:e,VideoWidth:this.videoEl.videoWidth.toString(),VideoHeight:this.videoEl.videoHeight.toString()}))).LivenessResponseStream}))}}export{m as LivenessStreamProvider,c as TIME_SLICE};
@@ -1 +1 @@
1
- import{__awaiter as e}from"../../../../node_modules/tslib/tslib.es6.mjs";class t{constructor(e,t={}){if("undefined"==typeof MediaRecorder)throw Error("MediaRecorder is not supported by this browser");this._stream=e,this._options=t,this._chunks=[],this._recorder=new MediaRecorder(e,{bitsPerSecond:1e6}),this._setupCallbacks()}getState(){var e;return null===(e=this._recorder)||void 0===e?void 0:e.state}start(e){var t;this.clearRecordedData(),this.recordingStartApiTimestamp=Date.now(),null===(t=this._recorder)||void 0===t||t.start(e)}stop(){var t;return e(this,void 0,void 0,(function*(){return"recording"===this.getState()&&(null===(t=this._recorder)||void 0===t||t.stop()),this._recorderStopped}))}pause(){var e;null===(e=this._recorder)||void 0===e||e.pause()}clearRecordedData(){this._chunks=[]}destroy(){this.stop(),this.clearRecordedData(),this._recorder=null}dispatch(e){var t;null===(t=this._recorder)||void 0===t||t.dispatchEvent(e)}_setupCallbacks(){this.videoStream=new ReadableStream({start:e=>{this._recorder&&(this._recorder.ondataavailable=t=>{t.data&&t.data.size>0&&(0===this._chunks.length&&(this.firstChunkTimestamp=Date.now()),this._chunks.push(t.data),e.enqueue(t.data))},this._recorder.addEventListener("clientSesssionInfo",(t=>{e.enqueue(t.data.clientInfo)})),this._recorder.addEventListener("stopVideo",(()=>{e.enqueue("stopVideo")})),this._recorder.addEventListener("endStream",(()=>{e.close()})))}}),this.recorderStarted=new Promise((e=>{this._recorder.onstart=()=>{this.recorderStartTimestamp=Date.now(),e()}})),this._recorderStopped=new Promise((e=>{this._recorder.onstop=()=>{this.recorderEndTimestamp=Date.now(),e()}})),this._recorder.onerror=()=>{"stopped"!==this.getState()&&this.stop()}}}export{t as VideoRecorder};
1
+ import{__awaiter as e}from"../../../../node_modules/tslib/tslib.es6.mjs";class t{constructor(e,t={}){if("undefined"==typeof MediaRecorder)throw Error("MediaRecorder is not supported by this browser");this._stream=e,this._options=t,this._chunks=[],this._recorder=new MediaRecorder(e,{bitsPerSecond:1e6}),this._setupCallbacks()}getState(){return this._recorder.state}start(e){this.clearRecordedData(),this.recordingStartApiTimestamp=Date.now(),this._recorder.start(e)}stop(){return e(this,void 0,void 0,(function*(){return"recording"===this.getState()&&this._recorder.stop(),this._recorderStopped}))}pause(){this._recorder.pause()}clearRecordedData(){this._chunks=[]}dispatch(e){this._recorder.dispatchEvent(e)}_setupCallbacks(){this.videoStream=new ReadableStream({start:e=>{this._recorder&&(this._recorder.ondataavailable=t=>{t.data&&t.data.size>0&&(0===this._chunks.length&&(this.firstChunkTimestamp=Date.now()),this._chunks.push(t.data),e.enqueue(t.data))},this._recorder.addEventListener("clientSesssionInfo",(t=>{e.enqueue(t.data.clientInfo)})),this._recorder.addEventListener("stopVideo",(()=>{e.enqueue("stopVideo")})),this._recorder.addEventListener("endStream",(()=>{e.close()})))}}),this.recorderStarted=new Promise((e=>{this._recorder.onstart=()=>{this.recorderStartTimestamp=Date.now(),e()}})),this._recorderStopped=new Promise((e=>{this._recorder.onstop=()=>{this.recorderEndTimestamp=Date.now(),e()}})),this._recorder.onerror=()=>{"stopped"!==this.getState()&&this.stop()}}}export{t as VideoRecorder};
@@ -1 +1 @@
1
- import e from"react";import{View as t,Flex as r,ComponentClassNames as o,Text as a}from"@aws-amplify/ui-react";import"@aws-amplify/ui-react/internal";import"@xstate/react";import"../providers/FaceLivenessDetectorProvider.mjs";import"@aws-amplify/ui";import{LivenessClassNames as i}from"../types/classNames.mjs";import"../service/machine/index.mjs";import"../service/types/liveness.mjs";import"@tensorflow/tfjs-core";import"@tensorflow-models/blazeface";import"@tensorflow/tfjs-backend-wasm";import"@tensorflow/tfjs-backend-cpu";import"@aws-amplify/core";import"../service/utils/liveness.mjs";import"../service/utils/streamProvider.mjs";import"../service/utils/freshnessColorDisplay.mjs";import{StartScreenFigure as s}from"./StartScreenFigure.mjs";import{GoodFitIllustration as m}from"./GoodFitIllustration.mjs";import{TooFarIllustration as l}from"./TooFarIllustration.mjs";import{LivenessIconWithPopover as n}from"./LivenessIconWithPopover.mjs";const c=({headingText:r,bodyText:o})=>e.createElement(t,{flex:"1"},e.createElement(t,{color:"font.primary",fontWeight:"bold"},r),e.createElement(t,{color:"font.primary"},o)),p=({headingText:a,bodyText:i,infoText:s})=>e.createElement(r,{className:o.Alert,color:"orange.80",backgroundColor:"orange.20",alignItems:"center"},e.createElement(t,{flex:"1"},e.createElement(t,{className:o.AlertHeading},a),e.createElement(t,{className:o.AlertBody},i)),e.createElement(n,null,s)),f=({headingText:t,goodFitCaptionText:o,goodFitAltText:n,tooFarCaptionText:c,tooFarAltText:p,steps:f})=>e.createElement(r,{direction:"column"},e.createElement(a,{color:"font.primary",fontWeight:"bold"},t),e.createElement(r,{className:i.Figures},e.createElement(s,{variation:"success",caption:o},e.createElement(m,{title:n})),e.createElement(s,{variation:"error",caption:c},e.createElement(l,{title:p}))),e.createElement(r,{as:"ol",className:i.InstructionList},f.map(((t,o)=>e.createElement(r,{as:"li",key:o+1},e.createElement(a,{as:"span","aria-hidden":"true"},o+1,"."),e.createElement(a,{as:"span"},t))))));export{c as DefaultHeader,f as DefaultInstructions,p as DefaultPhotosensitiveWarning};
1
+ import e from"react";import{View as t,Flex as r,ComponentClassNames as o,Text as a}from"@aws-amplify/ui-react";import"@aws-amplify/ui-react/internal";import"@xstate/react";import"../providers/FaceLivenessDetectorProvider.mjs";import"@aws-amplify/ui";import{LivenessClassNames as i}from"../types/classNames.mjs";import"../service/machine/index.mjs";import"../service/types/liveness.mjs";import"../service/types/error.mjs";import"@tensorflow/tfjs-core";import"@tensorflow-models/blazeface";import"@tensorflow/tfjs-backend-wasm";import"@tensorflow/tfjs-backend-cpu";import"@aws-amplify/core";import"../service/utils/liveness.mjs";import"../service/utils/streamProvider.mjs";import"../service/utils/freshnessColorDisplay.mjs";import{StartScreenFigure as s}from"./StartScreenFigure.mjs";import{GoodFitIllustration as m}from"./GoodFitIllustration.mjs";import{TooFarIllustration as l}from"./TooFarIllustration.mjs";import{LivenessIconWithPopover as n}from"./LivenessIconWithPopover.mjs";const c=({headingText:r,bodyText:o})=>e.createElement(t,{flex:"1"},e.createElement(t,{color:"font.primary",fontWeight:"bold"},r),e.createElement(t,{color:"font.primary"},o)),p=({headingText:a,bodyText:i,infoText:s})=>e.createElement(r,{className:o.Alert,color:"orange.80",backgroundColor:"orange.20",alignItems:"center"},e.createElement(t,{flex:"1"},e.createElement(t,{className:o.AlertHeading},a),e.createElement(t,{className:o.AlertBody},i)),e.createElement(n,null,s)),f=({headingText:t,goodFitCaptionText:o,goodFitAltText:n,tooFarCaptionText:c,tooFarAltText:p,steps:f})=>e.createElement(r,{direction:"column"},e.createElement(a,{color:"font.primary",fontWeight:"bold"},t),e.createElement(r,{className:i.Figures},e.createElement(s,{variation:"success",caption:o},e.createElement(m,{title:n})),e.createElement(s,{variation:"error",caption:c},e.createElement(l,{title:p}))),e.createElement(r,{as:"ol",className:i.InstructionList},f.map(((t,o)=>e.createElement(r,{as:"li",key:o+1},e.createElement(a,{as:"span","aria-hidden":"true"},o+1,"."),e.createElement(a,{as:"span"},t))))));export{c as DefaultHeader,f as DefaultInstructions,p as DefaultPhotosensitiveWarning};
@@ -1 +1 @@
1
- import e from"react";import{Flex as t,Text as r,Button as s}from"@aws-amplify/ui-react";import{AlertIcon as a}from"@aws-amplify/ui-react/internal";import"../service/machine/index.mjs";import{LivenessErrorState as o}from"../service/types/liveness.mjs";import"@tensorflow/tfjs-core";import"@tensorflow-models/blazeface";import"@tensorflow/tfjs-backend-wasm";import"@tensorflow/tfjs-backend-cpu";import"@aws-amplify/core";import"../service/utils/liveness.mjs";import"../service/utils/streamProvider.mjs";import"../service/utils/freshnessColorDisplay.mjs";import{Toast as i}from"./Toast.mjs";import{Overlay as n}from"./Overlay.mjs";import{defaultErrorDisplayText as m}from"../displayText.mjs";const c=({errorState:s,overrideErrorDisplayText:i})=>{const n=Object.assign(Object.assign({},m),i);return s===o.CAMERA_ACCESS_ERROR||s===o.CAMERA_FRAMERATE_ERROR||s===o.MOBILE_LANDSCAPE_ERROR?null:(s=>{const{error:i,displayText:n}=s,{timeoutHeaderText:m,timeoutMessageText:c,faceDistanceHeaderText:l,faceDistanceMessageText:p,clientHeaderText:E,clientMessageText:f,serverHeaderText:R,serverMessageText:d}=n;let T,u;switch(i){case o.TIMEOUT:T=m,u=c;break;case o.FACE_DISTANCE_ERROR:T=l,u=p;break;case o.RUNTIME_ERROR:T=E,u=f;break;case o.SERVER_ERROR:default:T=R,u=d}return e.createElement(e.Fragment,null,e.createElement(t,{gap:"xs",alignItems:"center",justifyContent:"center",color:"font.error"},e.createElement(a,{ariaHidden:!0,variation:"error"}),e.createElement(r,{fontWeight:"bold"},T)),u)})({error:s,displayText:n})},l=r=>{const{children:a,onRetry:o,displayText:c}=r,l=Object.assign(Object.assign({},m),c),{tryAgainText:p}=l;return e.createElement(n,{backgroundColor:"overlay.40"},e.createElement(i,null,a,e.createElement(t,{justifyContent:"center"},e.createElement(s,{variation:"primary",type:"button",onClick:o},p))))};export{l as FaceLivenessErrorModal,c as renderErrorModal};
1
+ import e from"react";import{Flex as r,Text as t,Button as s}from"@aws-amplify/ui-react";import{AlertIcon as a}from"@aws-amplify/ui-react/internal";import"../service/machine/index.mjs";import"../service/types/liveness.mjs";import{LivenessErrorState as o}from"../service/types/error.mjs";import"@tensorflow/tfjs-core";import"@tensorflow-models/blazeface";import"@tensorflow/tfjs-backend-wasm";import"@tensorflow/tfjs-backend-cpu";import"@aws-amplify/core";import"../service/utils/liveness.mjs";import"../service/utils/streamProvider.mjs";import"../service/utils/freshnessColorDisplay.mjs";import{Toast as i}from"./Toast.mjs";import{Overlay as n}from"./Overlay.mjs";import{defaultErrorDisplayText as m}from"../displayText.mjs";const c=({errorState:s,overrideErrorDisplayText:i})=>{const n=Object.assign(Object.assign({},m),i);return s===o.CAMERA_ACCESS_ERROR||s===o.CAMERA_FRAMERATE_ERROR||s===o.MOBILE_LANDSCAPE_ERROR?null:(s=>{const{error:i,displayText:n}=s,{timeoutHeaderText:m,timeoutMessageText:c,faceDistanceHeaderText:l,faceDistanceMessageText:p,clientHeaderText:E,clientMessageText:f,serverHeaderText:R,serverMessageText:d}=n;let T,u;switch(i){case o.TIMEOUT:T=m,u=c;break;case o.FACE_DISTANCE_ERROR:T=l,u=p;break;case o.RUNTIME_ERROR:T=E,u=f;break;case o.SERVER_ERROR:default:T=R,u=d}return e.createElement(e.Fragment,null,e.createElement(r,{gap:"xs",alignItems:"center",justifyContent:"center",color:"font.error"},e.createElement(a,{ariaHidden:!0,variation:"error"}),e.createElement(t,{fontWeight:"bold"},T)),u)})({error:s,displayText:n})},l=t=>{const{children:a,onRetry:o,displayText:c}=t,l=Object.assign(Object.assign({},m),c),{tryAgainText:p}=l;return e.createElement(n,{backgroundColor:"overlay.40"},e.createElement(i,null,a,e.createElement(r,{justifyContent:"center"},e.createElement(s,{variation:"primary",type:"button",onClick:o},p))))};export{l as FaceLivenessErrorModal,c as renderErrorModal};
@@ -1 +1 @@
1
- import*as e from"react";import{Flex as t,Loader as r,View as n}from"@aws-amplify/ui-react";import"../service/machine/index.mjs";import{FaceMatchState as o,IlluminationState as a}from"../service/types/liveness.mjs";import"@tensorflow/tfjs-core";import"@tensorflow-models/blazeface";import"@tensorflow/tfjs-backend-wasm";import"@tensorflow/tfjs-backend-cpu";import"@aws-amplify/core";import"../service/utils/liveness.mjs";import"../service/utils/streamProvider.mjs";import"../service/utils/freshnessColorDisplay.mjs";import{useLivenessActor as i}from"../hooks/useLivenessActor.mjs";import{createLivenessSelector as c,useLivenessSelector as s}from"../hooks/useLivenessSelector.mjs";import"@aws-amplify/ui";import{Toast as l}from"./Toast.mjs";import{Overlay as m}from"./Overlay.mjs";const h=c((e=>e.context.errorState)),f=c((e=>e.context.faceMatchAssociatedParams.faceMatchState)),u=c((e=>e.context.faceMatchAssociatedParams.illuminationState)),T=c((e=>e.context.isFaceFarEnoughBeforeRecording)),p=c((e=>e.context.faceMatchStateBeforeStart)),E=({hintDisplayText:c})=>{const[E]=i(),O=s(h),d=s(f),x=s(u),F=s(p),g=s(T),v=E.matches("checkFaceDetectedBeforeStart"),C=E.matches("checkFaceDistanceBeforeRecording"),A=E.matches("recording"),y=E.matches("notRecording"),I=E.matches("waitForSessionInfo"),S=E.matches("uploading"),j=E.matches("checkSucceeded"),M=E.matches("checkFailed"),D=E.matches({recording:"flashFreshnessColors"}),k={[o.CANT_IDENTIFY]:c.hintCanNotIdentifyText,[o.FACE_IDENTIFIED]:c.hintTooFarText,[o.TOO_MANY]:c.hintTooManyFacesText,[o.TOO_CLOSE]:c.hintTooCloseText,[o.TOO_FAR]:c.hintTooFarText,[o.MATCHED]:void 0},w={[a.BRIGHT]:c.hintIlluminationTooBrightText,[a.DARK]:c.hintIlluminationTooDarkText,[a.NORMAL]:c.hintIlluminationNormalText},_=(()=>{if(!(O||M||j)){if(!A){if(v)return F===o.TOO_MANY?e.createElement(l,null,k[F]):e.createElement(l,null,c.hintMoveFaceFrontOfCameraText);if(C&&!1===g)return e.createElement(l,null,c.hintTooCloseText);if(y)return e.createElement(l,null,c.hintHoldFacePositionCountdownText);if(I)return e.createElement(l,null,e.createElement(t,{alignItems:"center",gap:"xs"},e.createElement(r,null),e.createElement(n,null,c.hintConnectingText)));if(S)return e.createElement(m,{backgroundColor:"overlay.40",anchorOrigin:{horizontal:"center",vertical:"end"}},e.createElement(l,null,e.createElement(t,{alignItems:"center",gap:"xs"},e.createElement(r,null),e.createElement(n,null,c.hintVerifyingText))));if(x&&x!==a.NORMAL)return e.createElement(l,null,w[x])}return D?e.createElement(l,{size:"large",variation:"primary"},c.hintHoldFaceForFreshnessText):A&&!D&&d!==o.MATCHED?e.createElement(l,{size:"large",variation:d===o.TOO_CLOSE?"error":"primary"},d===o.TOO_CLOSE?k[o.TOO_CLOSE]:k[o.TOO_FAR]):null}})();return _||null};export{E as Hint,h as selectErrorState,f as selectFaceMatchState,p as selectFaceMatchStateBeforeStart,u as selectIlluminationState,T as selectIsFaceFarEnoughBeforeRecording};
1
+ import*as e from"react";import{Flex as t,Loader as r,View as o}from"@aws-amplify/ui-react";import"../service/machine/index.mjs";import{FaceMatchState as n,IlluminationState as a}from"../service/types/liveness.mjs";import"../service/types/error.mjs";import"@tensorflow/tfjs-core";import"@tensorflow-models/blazeface";import"@tensorflow/tfjs-backend-wasm";import"@tensorflow/tfjs-backend-cpu";import"@aws-amplify/core";import"../service/utils/liveness.mjs";import"../service/utils/streamProvider.mjs";import"../service/utils/freshnessColorDisplay.mjs";import{useLivenessActor as i}from"../hooks/useLivenessActor.mjs";import{createLivenessSelector as s,useLivenessSelector as c}from"../hooks/useLivenessSelector.mjs";import"@aws-amplify/ui";import{Toast as l}from"./Toast.mjs";import{Overlay as m}from"./Overlay.mjs";const h=s((e=>e.context.errorState)),f=s((e=>e.context.faceMatchAssociatedParams.faceMatchState)),u=s((e=>e.context.faceMatchAssociatedParams.illuminationState)),T=s((e=>e.context.isFaceFarEnoughBeforeRecording)),p=s((e=>e.context.faceMatchStateBeforeStart)),E=({hintDisplayText:s})=>{const[E]=i(),x=c(h),O=c(f),d=c(u),F=c(p),g=c(T),v=E.matches("checkFaceDetectedBeforeStart"),C=E.matches("checkFaceDistanceBeforeRecording"),y=E.matches("recording"),j=E.matches("notRecording"),A=E.matches("waitForSessionInfo"),I=E.matches("uploading"),S=E.matches("checkSucceeded"),M=E.matches("checkFailed"),k=E.matches({recording:"flashFreshnessColors"}),w={[n.CANT_IDENTIFY]:s.hintCanNotIdentifyText,[n.FACE_IDENTIFIED]:s.hintTooFarText,[n.TOO_MANY]:s.hintTooManyFacesText,[n.TOO_CLOSE]:s.hintTooCloseText,[n.TOO_FAR]:s.hintTooFarText,[n.MATCHED]:s.hintHoldFaceForFreshnessText},D={[a.BRIGHT]:s.hintIlluminationTooBrightText,[a.DARK]:s.hintIlluminationTooDarkText,[a.NORMAL]:s.hintIlluminationNormalText},_=(()=>{if(!(x||M||S)){if(!y){if(v)return F===n.TOO_MANY?e.createElement(l,null,w[F]):e.createElement(l,null,s.hintMoveFaceFrontOfCameraText);if(C&&!1===g)return e.createElement(l,null,s.hintTooCloseText);if(j)return e.createElement(l,null,s.hintHoldFacePositionCountdownText);if(A)return e.createElement(l,null,e.createElement(t,{alignItems:"center",gap:"xs"},e.createElement(r,null),e.createElement(o,null,s.hintConnectingText)));if(I)return e.createElement(m,{backgroundColor:"overlay.40",anchorOrigin:{horizontal:"center",vertical:"end"}},e.createElement(l,null,e.createElement(t,{alignItems:"center",gap:"xs"},e.createElement(r,null),e.createElement(o,null,s.hintVerifyingText))));if(d&&d!==a.NORMAL)return e.createElement(l,null,D[d])}return k?e.createElement(l,{size:"large",variation:"primary"},s.hintHoldFaceForFreshnessText):y&&!k?e.createElement(l,{size:"large",variation:O===n.TOO_CLOSE?"error":"primary"},O===n.TOO_CLOSE?w[n.TOO_CLOSE]:w[n.TOO_FAR]):null}})();return _||null};export{E as Hint,h as selectErrorState,f as selectFaceMatchState,p as selectFaceMatchStateBeforeStart,u as selectIlluminationState,T as selectIsFaceFarEnoughBeforeRecording};