@aws-amplify/ui-react-liveness 2.0.10 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/esm/components/FaceLivenessDetector/FaceLivenessDetector.mjs +17 -1
  2. package/dist/esm/components/FaceLivenessDetector/FaceLivenessDetectorCore.mjs +42 -1
  3. package/dist/esm/components/FaceLivenessDetector/LivenessCheck/LivenessCameraModule.mjs +199 -1
  4. package/dist/esm/components/FaceLivenessDetector/LivenessCheck/LivenessCheck.mjs +97 -1
  5. package/dist/esm/components/FaceLivenessDetector/displayText.mjs +50 -1
  6. package/dist/esm/components/FaceLivenessDetector/hooks/useLivenessActor.mjs +13 -1
  7. package/dist/esm/components/FaceLivenessDetector/hooks/useLivenessSelector.mjs +12 -1
  8. package/dist/esm/components/FaceLivenessDetector/hooks/useMediaStreamInVideo.mjs +38 -1
  9. package/dist/esm/components/FaceLivenessDetector/providers/FaceLivenessDetectorProvider.mjs +15 -1
  10. package/dist/esm/components/FaceLivenessDetector/service/machine/index.mjs +1130 -1
  11. package/dist/esm/components/FaceLivenessDetector/service/types/error.mjs +16 -1
  12. package/dist/esm/components/FaceLivenessDetector/service/types/faceDetection.mjs +15 -1
  13. package/dist/esm/components/FaceLivenessDetector/service/types/liveness.mjs +23 -1
  14. package/dist/esm/components/FaceLivenessDetector/service/utils/CustomWebSocketFetchHandler.mjs +200 -1
  15. package/dist/esm/components/FaceLivenessDetector/service/utils/blazefaceFaceDetection.mjs +102 -1
  16. package/dist/esm/components/FaceLivenessDetector/service/utils/constants.mjs +18 -1
  17. package/dist/esm/components/FaceLivenessDetector/service/utils/eventUtils.mjs +30 -1
  18. package/dist/esm/components/FaceLivenessDetector/service/utils/freshnessColorDisplay.mjs +131 -1
  19. package/dist/esm/components/FaceLivenessDetector/service/utils/liveness.mjs +462 -1
  20. package/dist/esm/components/FaceLivenessDetector/service/utils/streamProvider.mjs +144 -1
  21. package/dist/esm/components/FaceLivenessDetector/service/utils/support.mjs +14 -1
  22. package/dist/esm/components/FaceLivenessDetector/service/utils/videoRecorder.mjs +98 -1
  23. package/dist/esm/components/FaceLivenessDetector/shared/CancelButton.mjs +24 -1
  24. package/dist/esm/components/FaceLivenessDetector/shared/DefaultStartScreenComponents.mjs +41 -1
  25. package/dist/esm/components/FaceLivenessDetector/shared/FaceLivenessErrorModal.mjs +88 -1
  26. package/dist/esm/components/FaceLivenessDetector/shared/Hint.mjs +114 -1
  27. package/dist/esm/components/FaceLivenessDetector/shared/LandscapeErrorModal.mjs +30 -1
  28. package/dist/esm/components/FaceLivenessDetector/shared/LivenessIconWithPopover.mjs +37 -1
  29. package/dist/esm/components/FaceLivenessDetector/shared/MatchIndicator.mjs +24 -1
  30. package/dist/esm/components/FaceLivenessDetector/shared/Overlay.mjs +9 -1
  31. package/dist/esm/components/FaceLivenessDetector/shared/RecordingIcon.mjs +13 -1
  32. package/dist/esm/components/FaceLivenessDetector/shared/Toast.mjs +12 -1
  33. package/dist/esm/components/FaceLivenessDetector/types/classNames.mjs +54 -1
  34. package/dist/esm/components/FaceLivenessDetector/utils/device.mjs +24 -1
  35. package/dist/esm/components/FaceLivenessDetector/utils/getDisplayText.mjs +78 -1
  36. package/dist/esm/components/FaceLivenessDetector/utils/helpers.mjs +14 -0
  37. package/dist/esm/components/FaceLivenessDetector/utils/platform.mjs +8 -1
  38. package/dist/esm/index.mjs +2 -1
  39. package/dist/esm/version.mjs +3 -1
  40. package/dist/index.js +3208 -1
  41. package/dist/styles.css +343 -680
  42. package/dist/types/components/FaceLivenessDetector/FaceLivenessDetector.d.ts +1 -1
  43. package/dist/types/components/FaceLivenessDetector/FaceLivenessDetectorCore.d.ts +1 -3
  44. package/dist/types/components/FaceLivenessDetector/LivenessCheck/LivenessCameraModule.d.ts +7 -3
  45. package/dist/types/components/FaceLivenessDetector/LivenessCheck/LivenessCheck.d.ts +5 -3
  46. package/dist/types/components/FaceLivenessDetector/displayText.d.ts +3 -10
  47. package/dist/types/components/FaceLivenessDetector/service/machine/index.d.ts +1 -1
  48. package/dist/types/components/FaceLivenessDetector/service/types/faceDetection.d.ts +2 -0
  49. package/dist/types/components/FaceLivenessDetector/service/types/liveness.d.ts +1 -1
  50. package/dist/types/components/FaceLivenessDetector/service/types/machine.d.ts +3 -1
  51. package/dist/types/components/FaceLivenessDetector/service/utils/blazefaceFaceDetection.d.ts +4 -3
  52. package/dist/types/components/FaceLivenessDetector/service/utils/liveness.d.ts +5 -2
  53. package/dist/types/components/FaceLivenessDetector/shared/DefaultStartScreenComponents.d.ts +9 -15
  54. package/dist/types/components/FaceLivenessDetector/shared/Overlay.d.ts +2 -5
  55. package/dist/types/components/FaceLivenessDetector/shared/Toast.d.ts +1 -0
  56. package/dist/types/components/FaceLivenessDetector/types/classNames.d.ts +3 -0
  57. package/dist/types/version.d.ts +1 -1
  58. package/package.json +16 -37
  59. package/dist/esm/components/FaceLivenessDetector/StartLiveness/StartLiveness.mjs +0 -1
  60. package/dist/esm/components/FaceLivenessDetector/StartLiveness/helpers.mjs +0 -1
  61. package/dist/esm/components/FaceLivenessDetector/shared/GoodFitIllustration.mjs +0 -1
  62. package/dist/esm/components/FaceLivenessDetector/shared/StartScreenFigure.mjs +0 -1
  63. package/dist/esm/components/FaceLivenessDetector/shared/TooFarIllustration.mjs +0 -1
  64. package/dist/types/components/FaceLivenessDetector/StartLiveness/StartLiveness.d.ts +0 -9
  65. package/dist/types/components/FaceLivenessDetector/StartLiveness/index.d.ts +0 -1
  66. /package/dist/types/components/FaceLivenessDetector/{StartLiveness → utils}/helpers.d.ts +0 -0
@@ -1 +1,98 @@
1
- import{__awaiter as e}from"tslib";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)}getVideoChunkSize(){return this._chunks.length}_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._recorder.addEventListener("endStreamWithCode",(t=>{e.enqueue({type:"endStreamWithCode",code:t.data.code})})))}}),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
+ /**
2
+ * Helper wrapper class over the native MediaRecorder.
3
+ */
4
+ class VideoRecorder {
5
+ constructor(stream, options = {}) {
6
+ if (typeof MediaRecorder === 'undefined') {
7
+ throw Error('MediaRecorder is not supported by this browser');
8
+ }
9
+ this._stream = stream;
10
+ this._options = options;
11
+ this._chunks = [];
12
+ this._recorder = new MediaRecorder(stream, { bitsPerSecond: 1000000 });
13
+ this._setupCallbacks();
14
+ }
15
+ getState() {
16
+ return this._recorder.state;
17
+ }
18
+ start(timeSlice) {
19
+ this.clearRecordedData();
20
+ this.recordingStartApiTimestamp = Date.now();
21
+ this._recorder.start(timeSlice);
22
+ }
23
+ async stop() {
24
+ if (this.getState() === 'recording') {
25
+ this._recorder.stop();
26
+ }
27
+ return this._recorderStopped;
28
+ }
29
+ pause() {
30
+ this._recorder.pause();
31
+ }
32
+ clearRecordedData() {
33
+ this._chunks = [];
34
+ }
35
+ dispatch(event) {
36
+ this._recorder.dispatchEvent(event);
37
+ }
38
+ getVideoChunkSize() {
39
+ return this._chunks.length;
40
+ }
41
+ _setupCallbacks() {
42
+ // Creates a Readablestream of video chunks. Waits to receive a clientSessionInfo event before pushing
43
+ // a livenessActionDocument to the ReadableStream and finally closing the ReadableStream
44
+ this.videoStream = new ReadableStream({
45
+ start: (controller) => {
46
+ if (!this._recorder) {
47
+ return;
48
+ }
49
+ this._recorder.ondataavailable = (e) => {
50
+ if (e.data && e.data.size > 0) {
51
+ if (this._chunks.length === 0) {
52
+ this.firstChunkTimestamp = Date.now();
53
+ }
54
+ this._chunks.push(e.data);
55
+ controller.enqueue(e.data);
56
+ }
57
+ };
58
+ this._recorder.addEventListener('clientSesssionInfo', (e) => {
59
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
60
+ controller.enqueue(e.data.clientInfo);
61
+ });
62
+ this._recorder.addEventListener('stopVideo', () => {
63
+ controller.enqueue('stopVideo');
64
+ });
65
+ this._recorder.addEventListener('endStream', () => {
66
+ controller.close();
67
+ });
68
+ this._recorder.addEventListener('endStreamWithCode', (e) => {
69
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
70
+ controller.enqueue({
71
+ type: 'endStreamWithCode',
72
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
73
+ code: e.data.code,
74
+ });
75
+ });
76
+ },
77
+ });
78
+ this.recorderStarted = new Promise((resolve) => {
79
+ this._recorder.onstart = () => {
80
+ this.recorderStartTimestamp = Date.now();
81
+ resolve();
82
+ };
83
+ });
84
+ this._recorderStopped = new Promise((resolve) => {
85
+ this._recorder.onstop = () => {
86
+ this.recorderEndTimestamp = Date.now();
87
+ resolve();
88
+ };
89
+ });
90
+ this._recorder.onerror = () => {
91
+ if (this.getState() !== 'stopped') {
92
+ this.stop();
93
+ }
94
+ };
95
+ }
96
+ }
97
+
98
+ export { VideoRecorder };
@@ -1 +1,24 @@
1
- import e from"react";import{Button as t}from"@aws-amplify/ui-react";import{IconClose as r}from"@aws-amplify/ui-react/internal";import{useLivenessActor as a}from"../hooks/useLivenessActor.mjs";import"@xstate/react";import"../providers/FaceLivenessDetectorProvider.mjs";import"@aws-amplify/ui";import{LivenessClassNames as i}from"../types/classNames.mjs";const o=({ariaLabel:o})=>{const[s,m]=a();return s.done?null:e.createElement(t,{autoFocus:!0,variation:"link",onClick:()=>{m({type:"CANCEL"})},size:"large",className:i.CancelButton,"aria-label":o},e.createElement(r,{"aria-hidden":"true","data-testid":"close-icon"}))};export{o as CancelButton};
1
+ import React__default from 'react';
2
+ import { Button } from '@aws-amplify/ui-react';
3
+ import { IconClose } from '@aws-amplify/ui-react/internal';
4
+ import { useLivenessActor } from '../hooks/useLivenessActor.mjs';
5
+ import '@xstate/react';
6
+ import '../providers/FaceLivenessDetectorProvider.mjs';
7
+ import '@aws-amplify/ui';
8
+ import { LivenessClassNames } from '../types/classNames.mjs';
9
+
10
+ const CancelButton = ({ ariaLabel }) => {
11
+ const [state, send] = useLivenessActor();
12
+ const isFinalState = state.done;
13
+ const handleClick = () => {
14
+ send({
15
+ type: 'CANCEL',
16
+ });
17
+ };
18
+ if (isFinalState)
19
+ return null;
20
+ return (React__default.createElement(Button, { autoFocus: true, variation: "link", onClick: handleClick, size: "large", className: LivenessClassNames.CancelButton, "aria-label": ariaLabel },
21
+ React__default.createElement(IconClose, { "aria-hidden": "true", "data-testid": "close-icon" })));
22
+ };
23
+
24
+ export { CancelButton };
@@ -1 +1,41 @@
1
- import e from"react";import{View as t,Flex as r,ComponentClassNames as a,Text as s}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 o}from"../types/classNames.mjs";import"../service/machine/index.mjs";import"../service/types/liveness.mjs";import"tslib";import"@tensorflow/tfjs-core";import"@tensorflow-models/blazeface";import"@tensorflow/tfjs-backend-wasm";import"@tensorflow/tfjs-backend-cpu";import"@aws-amplify/core";import"@aws-sdk/client-rekognitionstreaming";import"@aws-sdk/util-format-url";import"@smithy/eventstream-serde-browser";import"@smithy/fetch-http-handler";import"@smithy/protocol-http";import"../service/utils/freshnessColorDisplay.mjs";import{StartScreenFigure as i}from"./StartScreenFigure.mjs";import{GoodFitIllustration as m}from"./GoodFitIllustration.mjs";import{TooFarIllustration as n}from"./TooFarIllustration.mjs";import{LivenessIconWithPopover as l}from"./LivenessIconWithPopover.mjs";const c=({headingText:r,bodyText:a})=>e.createElement(t,{className:o.StartScreenHeader},e.createElement(t,{className:o.StartScreenHeaderHeading},r),e.createElement(t,{className:o.StartScreenHeaderBody},a)),p=({headingText:s,bodyText:i,infoText:m})=>e.createElement(r,{className:`${a.Alert} ${o.StartScreenWarning}`},e.createElement(t,{flex:"1"},e.createElement(t,{className:a.AlertHeading},s),e.createElement(t,{className:a.AlertBody},i)),e.createElement(l,null,m)),d=({headingText:t,goodFitCaptionText:a,goodFitAltText:l,tooFarCaptionText:c,tooFarAltText:p,steps:d})=>e.createElement(r,{direction:"column"},e.createElement(s,{className:o.StartScreenInstructionsHeading},t),e.createElement(r,{className:o.Figures},e.createElement(i,{variation:"success",caption:a},e.createElement(m,{title:l})),e.createElement(i,{variation:"error",caption:c},e.createElement(n,{title:p}))),e.createElement(r,{as:"ol",className:o.InstructionList},d.map(((t,a)=>e.createElement(r,{as:"li",key:a+1},e.createElement(s,{as:"span","aria-hidden":"true"},a+1,"."),e.createElement(s,{as:"span"},t))))));export{c as DefaultHeader,d as DefaultInstructions,p as DefaultPhotosensitiveWarning};
1
+ import React__default from 'react';
2
+ import { ComponentClassName } from '@aws-amplify/ui';
3
+ import { Flex, View } from '@aws-amplify/ui-react';
4
+ import { CancelButton } from './CancelButton.mjs';
5
+ import '../service/machine/index.mjs';
6
+ import '../service/types/liveness.mjs';
7
+ import '@tensorflow/tfjs-core';
8
+ import '@tensorflow-models/face-detection';
9
+ import '@tensorflow/tfjs-backend-wasm';
10
+ import '@tensorflow/tfjs-backend-cpu';
11
+ import '@aws-amplify/core/internals/utils';
12
+ import 'aws-amplify/auth';
13
+ import '@aws-sdk/client-rekognitionstreaming';
14
+ import '@aws-sdk/util-format-url';
15
+ import '@smithy/eventstream-serde-browser';
16
+ import '@smithy/fetch-http-handler';
17
+ import '@smithy/protocol-http';
18
+ import '../service/utils/freshnessColorDisplay.mjs';
19
+ import '@xstate/react';
20
+ import '../providers/FaceLivenessDetectorProvider.mjs';
21
+ import { LivenessClassNames } from '../types/classNames.mjs';
22
+ import { RecordingIcon } from './RecordingIcon.mjs';
23
+ import { LivenessIconWithPopover } from './LivenessIconWithPopover.mjs';
24
+
25
+ const DefaultPhotosensitiveWarning = ({ headingText, bodyText, infoText, }) => {
26
+ return (React__default.createElement(Flex, { className: `${ComponentClassName.Alert} ${LivenessClassNames.StartScreenWarning}`, style: { zIndex: '3' } },
27
+ React__default.createElement(View, { flex: "1" },
28
+ React__default.createElement(View, { className: ComponentClassName.AlertHeading }, headingText),
29
+ React__default.createElement(View, { className: ComponentClassName.AlertBody }, bodyText)),
30
+ React__default.createElement(LivenessIconWithPopover, null, infoText)));
31
+ };
32
+ const DefaultRecordingIcon = ({ recordingIndicatorText, }) => {
33
+ return (React__default.createElement(View, { className: LivenessClassNames.RecordingIconContainer },
34
+ React__default.createElement(RecordingIcon, null, recordingIndicatorText)));
35
+ };
36
+ const DefaultCancelButton = ({ cancelLivenessCheckText, }) => {
37
+ return (React__default.createElement(View, { className: LivenessClassNames.CancelContainer },
38
+ React__default.createElement(CancelButton, { ariaLabel: cancelLivenessCheckText })));
39
+ };
40
+
41
+ export { DefaultCancelButton, DefaultPhotosensitiveWarning, DefaultRecordingIcon };
@@ -1 +1,88 @@
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"../service/types/liveness.mjs";import{LivenessErrorState as i}from"../service/types/error.mjs";import"tslib";import"@tensorflow/tfjs-core";import"@tensorflow-models/blazeface";import"@tensorflow/tfjs-backend-wasm";import"@tensorflow/tfjs-backend-cpu";import"@aws-amplify/core";import"@aws-sdk/client-rekognitionstreaming";import"@aws-sdk/util-format-url";import"@smithy/eventstream-serde-browser";import"@smithy/fetch-http-handler";import"@smithy/protocol-http";import"../service/utils/freshnessColorDisplay.mjs";import{Toast as o}from"./Toast.mjs";import{Overlay as m}from"./Overlay.mjs";import{defaultErrorDisplayText as l}from"../displayText.mjs";import{LivenessClassNames as n}from"../types/classNames.mjs";const c=({errorState:s,overrideErrorDisplayText:o})=>{const m=Object.assign(Object.assign({},l),o);return s===i.CAMERA_ACCESS_ERROR||s===i.CAMERA_FRAMERATE_ERROR||s===i.MOBILE_LANDSCAPE_ERROR?null:(s=>{const{error:o,displayText:m}=s,{timeoutHeaderText:l,timeoutMessageText:c,faceDistanceHeaderText:p,faceDistanceMessageText:E,multipleFacesHeaderText:R,multipleFacesMessageText:f,clientHeaderText:d,clientMessageText:T,serverHeaderText:y,serverMessageText:u}=m;let x,j;switch(o){case i.TIMEOUT:x=l,j=c;break;case i.FACE_DISTANCE_ERROR:x=p,j=E;break;case i.MULTIPLE_FACES_ERROR:x=R,j=f;break;case i.RUNTIME_ERROR:x=d,j=T;break;case i.SERVER_ERROR:default:x=y,j=u}return e.createElement(e.Fragment,null,e.createElement(t,{className:n.ErrorModal},e.createElement(a,{ariaHidden:!0,variation:"error"}),e.createElement(r,{className:n.ErrorModalHeading},x)),j)})({error:s,displayText:m})},p=r=>{const{children:a,onRetry:i,displayText:c}=r,p=Object.assign(Object.assign({},l),c),{tryAgainText:E}=p;return e.createElement(m,{className:n.OpaqueOverlay},e.createElement(o,null,a,e.createElement(t,{justifyContent:"center"},e.createElement(s,{variation:"primary",type:"button",onClick:i},E))))};export{p as FaceLivenessErrorModal,c as renderErrorModal};
1
+ import React__default from 'react';
2
+ import { Flex, Text, Button } from '@aws-amplify/ui-react';
3
+ import { AlertIcon } from '@aws-amplify/ui-react/internal';
4
+ import '../service/machine/index.mjs';
5
+ import '../service/types/liveness.mjs';
6
+ import { LivenessErrorState } from '../service/types/error.mjs';
7
+ import '@tensorflow/tfjs-core';
8
+ import '@tensorflow-models/face-detection';
9
+ import '@tensorflow/tfjs-backend-wasm';
10
+ import '@tensorflow/tfjs-backend-cpu';
11
+ import '@aws-amplify/core/internals/utils';
12
+ import 'aws-amplify/auth';
13
+ import '@aws-sdk/client-rekognitionstreaming';
14
+ import '@aws-sdk/util-format-url';
15
+ import '@smithy/eventstream-serde-browser';
16
+ import '@smithy/fetch-http-handler';
17
+ import '@smithy/protocol-http';
18
+ import '../service/utils/freshnessColorDisplay.mjs';
19
+ import { Toast } from './Toast.mjs';
20
+ import { Overlay } from './Overlay.mjs';
21
+ import { defaultErrorDisplayText } from '../displayText.mjs';
22
+ import { LivenessClassNames } from '../types/classNames.mjs';
23
+
24
+ const renderToastErrorModal = (props) => {
25
+ const { error: errorState, displayText } = props;
26
+ const { timeoutHeaderText, timeoutMessageText, faceDistanceHeaderText, faceDistanceMessageText, multipleFacesHeaderText, multipleFacesMessageText, clientHeaderText, clientMessageText, serverHeaderText, serverMessageText, } = displayText;
27
+ let heading;
28
+ let message;
29
+ switch (errorState) {
30
+ case LivenessErrorState.TIMEOUT:
31
+ heading = timeoutHeaderText;
32
+ message = timeoutMessageText;
33
+ break;
34
+ case LivenessErrorState.FACE_DISTANCE_ERROR:
35
+ heading = faceDistanceHeaderText;
36
+ message = faceDistanceMessageText;
37
+ break;
38
+ case LivenessErrorState.MULTIPLE_FACES_ERROR:
39
+ heading = multipleFacesHeaderText;
40
+ message = multipleFacesMessageText;
41
+ break;
42
+ case LivenessErrorState.RUNTIME_ERROR:
43
+ heading = clientHeaderText;
44
+ message = clientMessageText;
45
+ break;
46
+ case LivenessErrorState.SERVER_ERROR:
47
+ default:
48
+ heading = serverHeaderText;
49
+ message = serverMessageText;
50
+ }
51
+ return (React__default.createElement(React__default.Fragment, null,
52
+ React__default.createElement(Flex, { className: LivenessClassNames.ErrorModal },
53
+ React__default.createElement(AlertIcon, { ariaHidden: true, variation: "error" }),
54
+ React__default.createElement(Text, { className: LivenessClassNames.ErrorModalHeading }, heading)),
55
+ message));
56
+ };
57
+ const renderErrorModal = ({ errorState, overrideErrorDisplayText, }) => {
58
+ const displayText = {
59
+ ...defaultErrorDisplayText,
60
+ ...overrideErrorDisplayText,
61
+ };
62
+ if (errorState === LivenessErrorState.CAMERA_ACCESS_ERROR ||
63
+ errorState === LivenessErrorState.CAMERA_FRAMERATE_ERROR ||
64
+ errorState === LivenessErrorState.MOBILE_LANDSCAPE_ERROR) {
65
+ return null;
66
+ }
67
+ else {
68
+ return renderToastErrorModal({
69
+ error: errorState,
70
+ displayText,
71
+ });
72
+ }
73
+ };
74
+ const FaceLivenessErrorModal = (props) => {
75
+ const { children, onRetry, displayText: overrideErrorDisplayText } = props;
76
+ const displayText = {
77
+ ...defaultErrorDisplayText,
78
+ ...overrideErrorDisplayText,
79
+ };
80
+ const { tryAgainText } = displayText;
81
+ return (React__default.createElement(Overlay, { className: LivenessClassNames.OpaqueOverlay },
82
+ React__default.createElement(Toast, null,
83
+ children,
84
+ React__default.createElement(Flex, { justifyContent: "center" },
85
+ React__default.createElement(Button, { variation: "primary", type: "button", onClick: onRetry }, tryAgainText)))));
86
+ };
87
+
88
+ export { FaceLivenessErrorModal, renderErrorModal };
@@ -1 +1,114 @@
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 a,IlluminationState as n}from"../service/types/liveness.mjs";import"tslib";import"@tensorflow/tfjs-core";import"@tensorflow-models/blazeface";import"@tensorflow/tfjs-backend-wasm";import"@tensorflow/tfjs-backend-cpu";import"@aws-amplify/core";import"@aws-sdk/client-rekognitionstreaming";import"@aws-sdk/util-format-url";import"@smithy/eventstream-serde-browser";import"@smithy/fetch-http-handler";import"@smithy/protocol-http";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";import{LivenessClassNames as h}from"../types/classNames.mjs";const f=s((e=>e.context.errorState)),p=s((e=>e.context.faceMatchAssociatedParams.faceMatchState)),T=s((e=>e.context.faceMatchAssociatedParams.illuminationState)),u=s((e=>e.context.isFaceFarEnoughBeforeRecording)),O=s((e=>e.context.faceMatchStateBeforeStart)),E=({hintDisplayText:s})=>{const[E]=i(),d=c(f),x=c(p),F=c(T),y=c(O),g=c(u),C=E.matches("checkFaceDetectedBeforeStart"),v=E.matches("checkFaceDistanceBeforeRecording"),A=E.matches("recording"),N=E.matches("notRecording"),k=E.matches("uploading"),S=E.matches("checkSucceeded"),j=E.matches("checkFailed"),w=E.matches({recording:"flashFreshnessColors"}),M={[a.CANT_IDENTIFY]:s.hintCanNotIdentifyText,[a.FACE_IDENTIFIED]:s.hintTooFarText,[a.TOO_MANY]:s.hintTooManyFacesText,[a.TOO_CLOSE]:s.hintTooCloseText,[a.TOO_FAR]:s.hintTooFarText,[a.MATCHED]:s.hintHoldFaceForFreshnessText},D={[n.BRIGHT]:s.hintIlluminationTooBrightText,[n.DARK]:s.hintIlluminationTooDarkText,[n.NORMAL]:s.hintIlluminationNormalText},I=(()=>{if(!(d||j||S)){if(!A){if(C)return y===a.TOO_MANY?e.createElement(l,null,M[y]):e.createElement(l,null,s.hintMoveFaceFrontOfCameraText);if(v&&!1===g)return e.createElement(l,null,s.hintTooCloseText);if(N)return e.createElement(l,null,e.createElement(t,{className:h.HintText},e.createElement(r,null),e.createElement(o,null,s.hintConnectingText)));if(k)return e.createElement(m,{className:h.OpaqueOverlay,anchorOrigin:{horizontal:"center",vertical:"end"}},e.createElement(l,null,e.createElement(t,{className:h.HintText},e.createElement(r,null),e.createElement(o,null,s.hintVerifyingText))));if(F&&F!==n.NORMAL)return e.createElement(l,null,D[F])}return w?e.createElement(l,{size:"large",variation:"primary"},s.hintHoldFaceForFreshnessText):A&&!w?e.createElement(l,{size:"large",variation:x===a.TOO_CLOSE?"error":"primary"},x===a.TOO_CLOSE?M[a.TOO_CLOSE]:M[a.TOO_FAR]):null}})();return I||null};export{E as Hint,f as selectErrorState,p as selectFaceMatchState,O as selectFaceMatchStateBeforeStart,T as selectIlluminationState,u as selectIsFaceFarEnoughBeforeRecording};
1
+ import * as React from 'react';
2
+ import { Flex, Loader, View } from '@aws-amplify/ui-react';
3
+ import '../service/machine/index.mjs';
4
+ import { FaceMatchState, IlluminationState } from '../service/types/liveness.mjs';
5
+ import '@tensorflow/tfjs-core';
6
+ import '@tensorflow-models/face-detection';
7
+ import '@tensorflow/tfjs-backend-wasm';
8
+ import '@tensorflow/tfjs-backend-cpu';
9
+ import '@aws-amplify/core/internals/utils';
10
+ import 'aws-amplify/auth';
11
+ import '@aws-sdk/client-rekognitionstreaming';
12
+ import '@aws-sdk/util-format-url';
13
+ import '@smithy/eventstream-serde-browser';
14
+ import '@smithy/fetch-http-handler';
15
+ import '@smithy/protocol-http';
16
+ import '../service/utils/freshnessColorDisplay.mjs';
17
+ import { useLivenessActor } from '../hooks/useLivenessActor.mjs';
18
+ import { createLivenessSelector, useLivenessSelector } from '../hooks/useLivenessSelector.mjs';
19
+ import '@aws-amplify/ui';
20
+ import { Toast } from './Toast.mjs';
21
+ import { LivenessClassNames } from '../types/classNames.mjs';
22
+
23
+ const selectErrorState = createLivenessSelector((state) => state.context.errorState);
24
+ const selectFaceMatchState = createLivenessSelector((state) => state.context.faceMatchAssociatedParams.faceMatchState);
25
+ const selectIlluminationState = createLivenessSelector((state) => state.context.faceMatchAssociatedParams.illuminationState);
26
+ const selectIsFaceFarEnoughBeforeRecording = createLivenessSelector((state) => state.context.isFaceFarEnoughBeforeRecording);
27
+ const selectFaceMatchStateBeforeStart = createLivenessSelector((state) => state.context.faceMatchStateBeforeStart);
28
+ const Hint = ({ hintDisplayText }) => {
29
+ const [state] = useLivenessActor();
30
+ // NOTE: Do not change order of these selectors as the unit tests depend on this order
31
+ const errorState = useLivenessSelector(selectErrorState);
32
+ const faceMatchState = useLivenessSelector(selectFaceMatchState);
33
+ const illuminationState = useLivenessSelector(selectIlluminationState);
34
+ const faceMatchStateBeforeStart = useLivenessSelector(selectFaceMatchStateBeforeStart);
35
+ const isFaceFarEnoughBeforeRecordingState = useLivenessSelector(selectIsFaceFarEnoughBeforeRecording);
36
+ const isCheckFaceDetectedBeforeStart = state.matches('checkFaceDetectedBeforeStart');
37
+ const isCheckFaceDistanceBeforeRecording = state.matches('checkFaceDistanceBeforeRecording');
38
+ const isStartView = state.matches('start') || state.matches('userCancel');
39
+ const isRecording = state.matches('recording');
40
+ const isNotRecording = state.matches('notRecording');
41
+ const isUploading = state.matches('uploading');
42
+ const isCheckSuccessful = state.matches('checkSucceeded');
43
+ const isCheckFailed = state.matches('checkFailed');
44
+ const isFlashingFreshness = state.matches({
45
+ recording: 'flashFreshnessColors',
46
+ });
47
+ const FaceMatchStateStringMap = {
48
+ [FaceMatchState.CANT_IDENTIFY]: hintDisplayText.hintCanNotIdentifyText,
49
+ [FaceMatchState.FACE_IDENTIFIED]: hintDisplayText.hintTooFarText,
50
+ [FaceMatchState.TOO_MANY]: hintDisplayText.hintTooManyFacesText,
51
+ [FaceMatchState.TOO_CLOSE]: hintDisplayText.hintTooCloseText,
52
+ [FaceMatchState.TOO_FAR]: hintDisplayText.hintTooFarText,
53
+ [FaceMatchState.MATCHED]: hintDisplayText.hintHoldFaceForFreshnessText,
54
+ };
55
+ const IlluminationStateStringMap = {
56
+ [IlluminationState.BRIGHT]: hintDisplayText.hintIlluminationTooBrightText,
57
+ [IlluminationState.DARK]: hintDisplayText.hintIlluminationTooDarkText,
58
+ [IlluminationState.NORMAL]: hintDisplayText.hintIlluminationNormalText,
59
+ };
60
+ const getInstructionContent = () => {
61
+ if (isStartView) {
62
+ return (React.createElement(Toast, { size: "large", variation: "primary", isInitial: true }, hintDisplayText.hintCenterFaceText));
63
+ }
64
+ if (errorState ?? (isCheckFailed || isCheckSuccessful)) {
65
+ return;
66
+ }
67
+ if (!isRecording) {
68
+ if (isCheckFaceDetectedBeforeStart) {
69
+ if (faceMatchStateBeforeStart === FaceMatchState.TOO_MANY) {
70
+ return (React.createElement(Toast, { size: "large", variation: "primary" }, FaceMatchStateStringMap[faceMatchStateBeforeStart]));
71
+ }
72
+ return (React.createElement(Toast, { size: "large", variation: "primary" }, hintDisplayText.hintMoveFaceFrontOfCameraText));
73
+ }
74
+ // Specifically checking for false here because initially the value is undefined and we do not want to show the instruction
75
+ if (isCheckFaceDistanceBeforeRecording &&
76
+ isFaceFarEnoughBeforeRecordingState === false) {
77
+ return (React.createElement(Toast, { size: "large", variation: "primary" }, hintDisplayText.hintTooCloseText));
78
+ }
79
+ if (isNotRecording) {
80
+ return (React.createElement(Toast, null,
81
+ React.createElement(Flex, { className: LivenessClassNames.HintText },
82
+ React.createElement(Loader, null),
83
+ React.createElement(View, null, hintDisplayText.hintConnectingText))));
84
+ }
85
+ if (isUploading) {
86
+ return (React.createElement(Toast, null,
87
+ React.createElement(Flex, { className: LivenessClassNames.HintText },
88
+ React.createElement(Loader, null),
89
+ React.createElement(View, null, hintDisplayText.hintVerifyingText))));
90
+ }
91
+ if (illuminationState && illuminationState !== IlluminationState.NORMAL) {
92
+ return (React.createElement(Toast, { size: "large", variation: "primary" }, IlluminationStateStringMap[illuminationState]));
93
+ }
94
+ }
95
+ if (isFlashingFreshness) {
96
+ return (React.createElement(Toast, { size: "large", variation: "primary" }, hintDisplayText.hintHoldFaceForFreshnessText));
97
+ }
98
+ if (isRecording && !isFlashingFreshness) {
99
+ // During face matching, we want to only show the TOO_CLOSE or
100
+ // TOO_FAR texts. If FaceMatchState matches TOO_CLOSE, we'll show
101
+ // the TOO_CLOSE text, but for FACE_IDENTIFED, CANT_IDENTIFY, TOO_MANY
102
+ // we are defaulting to the TOO_FAR text (for now). For MATCHED state,
103
+ // we don't want to show any toasts.
104
+ return (React.createElement(Toast, { size: "large", variation: faceMatchState === FaceMatchState.TOO_CLOSE ? 'error' : 'primary' }, faceMatchState === FaceMatchState.TOO_CLOSE
105
+ ? FaceMatchStateStringMap[FaceMatchState.TOO_CLOSE]
106
+ : FaceMatchStateStringMap[FaceMatchState.TOO_FAR]));
107
+ }
108
+ return null;
109
+ };
110
+ const instructionContent = getInstructionContent();
111
+ return instructionContent ? instructionContent : null;
112
+ };
113
+
114
+ export { Hint, selectErrorState, selectFaceMatchState, selectFaceMatchStateBeforeStart, selectIlluminationState, selectIsFaceFarEnoughBeforeRecording };
@@ -1 +1,30 @@
1
- import*as e from"react";import{Flex as t,Text as a,Button as r}from"@aws-amplify/ui-react";import{getLandscapeMediaQuery as s}from"../utils/device.mjs";import{LivenessClassNames as n}from"../types/classNames.mjs";const o=o=>{const{onRetry:c,header:m,portraitMessage:l,landscapeMessage:i,tryAgainText:p}=o,[d,u]=e.useState(!0);return e.useLayoutEffect((()=>{const e=s();return u(e.matches),e.addEventListener("change",(e=>{u(e.matches)})),()=>{e.removeEventListener("change",(e=>u(e.matches)))}}),[]),e.createElement(t,{className:n.LandscapeErrorModal,height:d?"auto":480},e.createElement(a,{className:n.LandscapeErrorModalHeader},m),e.createElement(a,null,d?i:l),d?null:e.createElement(t,{className:n.LandscapeErrorModalButton},e.createElement(r,{variation:"primary",type:"button",onClick:c},p)))};export{o as LandscapeErrorModal};
1
+ import * as React from 'react';
2
+ import { Flex, Text, Button } from '@aws-amplify/ui-react';
3
+ import { getLandscapeMediaQuery } from '../utils/device.mjs';
4
+ import { LivenessClassNames } from '../types/classNames.mjs';
5
+
6
+ const LandscapeErrorModal = (props) => {
7
+ const { onRetry, header, portraitMessage, landscapeMessage, tryAgainText } = props;
8
+ const [isLandscape, setIsLandscape] = React.useState(true);
9
+ React.useLayoutEffect(() => {
10
+ // Get orientation: landscape media query
11
+ const landscapeMediaQuery = getLandscapeMediaQuery();
12
+ // Set ui state for initial orientation
13
+ setIsLandscape(landscapeMediaQuery.matches);
14
+ // Listen for future orientation changes
15
+ landscapeMediaQuery.addEventListener('change', (e) => {
16
+ setIsLandscape(e.matches);
17
+ });
18
+ // Remove matchMedia event listener
19
+ return () => {
20
+ landscapeMediaQuery.removeEventListener('change', (e) => setIsLandscape(e.matches));
21
+ };
22
+ }, []);
23
+ return (React.createElement(Flex, { className: LivenessClassNames.LandscapeErrorModal, height: isLandscape ? 'auto' : 480 },
24
+ React.createElement(Text, { className: LivenessClassNames.LandscapeErrorModalHeader }, header),
25
+ React.createElement(Text, null, isLandscape ? landscapeMessage : portraitMessage),
26
+ !isLandscape ? (React.createElement(Flex, { className: LivenessClassNames.LandscapeErrorModalButton },
27
+ React.createElement(Button, { variation: "primary", type: "button", onClick: onRetry }, tryAgainText))) : null));
28
+ };
29
+
30
+ export { LandscapeErrorModal };
@@ -1 +1,37 @@
1
- import*as e from"react";import{Flex as t}from"@aws-amplify/ui-react";import{useThemeBreakpoint as r,AlertIcon as o}from"@aws-amplify/ui-react/internal";import{LivenessClassNames as n}from"../types/classNames.mjs";const a=({children:a})=>{const s=r(),[c,m]=e.useState(!1),i=e.useRef(null),l="base"===s;return e.useEffect((()=>{function e(e){c&&i.current&&!i.current.contains(e.target)&&m(!1)}return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}}),[i,c]),e.createElement(t,{className:n.Popover,onClick:()=>m(!c),ref:i,testId:"popover-icon"},e.createElement(o,{ariaHidden:!0,variation:"info"}),c&&e.createElement(e.Fragment,null,e.createElement(t,{className:n.PopoverAnchor}),e.createElement(t,{className:n.PopoverAnchorSecondary}),e.createElement(t,{className:n.PopoverContainer,left:l?-190:-108,"data-testid":"popover-text"},a)))};a.displayName="LivenessIconWithPopover";export{a as LivenessIconWithPopover};
1
+ import * as React from 'react';
2
+ import { Flex } from '@aws-amplify/ui-react';
3
+ import { useThemeBreakpoint, AlertIcon } from '@aws-amplify/ui-react/internal';
4
+ import { LivenessClassNames } from '../types/classNames.mjs';
5
+
6
+ /**
7
+ * Copied from src/primitives/Alert/AlertIcon.tsx because we want to re-use the icon but it is not currently expored by AlertIcon.
8
+ * We currently don't want to make a change to the AlertIcon primitive itself and may expose the icon in the future but for now so as not to introduce cross component dependencies we have duplicated it.
9
+ */
10
+ const LivenessIconWithPopover = ({ children }) => {
11
+ const breakpoint = useThemeBreakpoint();
12
+ const [shouldShowPopover, setShouldShowPopover] = React.useState(false);
13
+ const wrapperRef = React.useRef(null);
14
+ const isMobileScreen = breakpoint === 'base';
15
+ React.useEffect(() => {
16
+ function handleClickOutside(event) {
17
+ if (shouldShowPopover &&
18
+ wrapperRef.current &&
19
+ !wrapperRef.current.contains(event.target)) {
20
+ setShouldShowPopover(false);
21
+ }
22
+ }
23
+ document.addEventListener('mousedown', handleClickOutside);
24
+ return () => {
25
+ document.removeEventListener('mousedown', handleClickOutside);
26
+ };
27
+ }, [wrapperRef, shouldShowPopover]);
28
+ return (React.createElement(Flex, { className: LivenessClassNames.Popover, onClick: () => setShouldShowPopover(!shouldShowPopover), ref: wrapperRef, testId: "popover-icon" },
29
+ React.createElement(AlertIcon, { ariaHidden: true, variation: "info" }),
30
+ shouldShowPopover && (React.createElement(React.Fragment, null,
31
+ React.createElement(Flex, { className: LivenessClassNames.PopoverAnchor }),
32
+ React.createElement(Flex, { className: LivenessClassNames.PopoverAnchorSecondary }),
33
+ React.createElement(Flex, { className: LivenessClassNames.PopoverContainer, left: isMobileScreen ? -190 : -108, "data-testid": "popover-text" }, children)))));
34
+ };
35
+ LivenessIconWithPopover.displayName = 'LivenessIconWithPopover';
36
+
37
+ export { LivenessIconWithPopover };
@@ -1 +1,24 @@
1
- import e from"react";import{LivenessClassNames as t}from"../types/classNames.mjs";const a=({percentage:a,initialPercentage:c=25,testId:s})=>{const[r,n]=e.useState(c);e.useEffect((()=>{n(a<0?0:a>100?100:a)}),[a]);const i={"--percentage":`${r}%`};return e.createElement("div",{className:t.MatchIndicator,"data-testid":s},e.createElement("div",{className:`${t.MatchIndicator}__bar`,style:i}))};export{a as MatchIndicator};
1
+ import React__default from 'react';
2
+ import { LivenessClassNames } from '../types/classNames.mjs';
3
+
4
+ const MatchIndicator = ({ percentage, initialPercentage = 25, testId, }) => {
5
+ const [matchPercentage, setMatchPercentage] = React__default.useState(initialPercentage);
6
+ React__default.useEffect(() => {
7
+ if (percentage < 0) {
8
+ setMatchPercentage(0);
9
+ }
10
+ else if (percentage > 100) {
11
+ setMatchPercentage(100);
12
+ }
13
+ else {
14
+ setMatchPercentage(percentage);
15
+ }
16
+ }, [percentage]);
17
+ const percentageStyles = {
18
+ '--percentage': `${matchPercentage}%`,
19
+ };
20
+ return (React__default.createElement("div", { className: LivenessClassNames.MatchIndicator, "data-testid": testId },
21
+ React__default.createElement("div", { className: `${LivenessClassNames.MatchIndicator}__bar`, style: percentageStyles })));
22
+ };
23
+
24
+ export { MatchIndicator };
@@ -1 +1,9 @@
1
- import{__rest as r}from"tslib";import*as e from"react";import{Flex as a}from"@aws-amplify/ui-react";import{LivenessClassNames as t}from"../types/classNames.mjs";const i=i=>{var{children:s,anchorOrigin:c={horizontal:"center",vertical:"center"},className:n}=i,o=r(i,["children","anchorOrigin","className"]);return e.createElement(a,Object.assign({className:`${t.Overlay} ${n}`,alignItems:c.horizontal,justifyContent:c.vertical},o),s)};export{i as Overlay};
1
+ import * as React from 'react';
2
+ import { Flex } from '@aws-amplify/ui-react';
3
+ import { LivenessClassNames } from '../types/classNames.mjs';
4
+
5
+ const Overlay = ({ children, horizontal = 'center', vertical = 'center', className, ...rest }) => {
6
+ return (React.createElement(Flex, { className: `${LivenessClassNames.Overlay} ${className}`, alignItems: horizontal, justifyContent: vertical, ...rest }, children));
7
+ };
8
+
9
+ export { Overlay };
@@ -1 +1,13 @@
1
- import e from"react";import{Flex as t,Icon as r,Text as c}from"@aws-amplify/ui-react";import{LivenessClassNames as i}from"../types/classNames.mjs";const a=({children:a})=>e.createElement(t,{className:i.RecordingIcon},e.createElement(t,{"data-testid":"rec-icon",justifyContent:"center"},e.createElement(r,{viewBox:{width:20,height:20},width:"20",height:"20"},e.createElement("circle",{cx:"10",cy:"10",r:"8",fill:"red"}))),e.createElement(c,{as:"span",fontWeight:"bold"},a));export{a as RecordingIcon};
1
+ import React__default from 'react';
2
+ import { Flex, Icon, Text } from '@aws-amplify/ui-react';
3
+ import { LivenessClassNames } from '../types/classNames.mjs';
4
+
5
+ const RecordingIcon = ({ children }) => {
6
+ return (React__default.createElement(Flex, { className: LivenessClassNames.RecordingIcon },
7
+ React__default.createElement(Flex, { "data-testid": "rec-icon", justifyContent: "center" },
8
+ React__default.createElement(Icon, { viewBox: { width: 20, height: 20 }, width: "20", height: "20" },
9
+ React__default.createElement("circle", { cx: "10", cy: "10", r: "8", fill: "red" }))),
10
+ React__default.createElement(Text, { as: "span", fontWeight: "bold" }, children)));
11
+ };
12
+
13
+ export { RecordingIcon };
@@ -1 +1,12 @@
1
- import{__rest as a}from"tslib";import*as e from"react";import{View as s,Flex as t}from"@aws-amplify/ui-react";import{LivenessClassNames as r}from"../types/classNames.mjs";const m=m=>{var{variation:i="default",size:o="medium",children:l}=m,c=a(m,["variation","size","children"]);return e.createElement(s,Object.assign({className:`${r.Toast} ${r.Toast}--${i} ${r.Toast}--${o}`,maxWidth:{base:"100%",small:"70%"}},c),e.createElement(t,{className:r.ToastContainer},e.createElement(t,{className:r.ToastMessage},l)))};export{m as Toast};
1
+ import * as React from 'react';
2
+ import { useTheme, View, Flex } from '@aws-amplify/ui-react';
3
+ import { LivenessClassNames } from '../types/classNames.mjs';
4
+
5
+ const Toast = ({ variation = 'default', size = 'medium', children, isInitial = false, ...rest }) => {
6
+ const { tokens } = useTheme();
7
+ return (React.createElement(View, { className: `${LivenessClassNames.Toast} ${LivenessClassNames.Toast}--${variation} ${LivenessClassNames.Toast}--${size}`, ...(isInitial && { backgroundColor: tokens.colors.background.primary }), ...rest },
8
+ React.createElement(Flex, { className: LivenessClassNames.ToastContainer },
9
+ React.createElement(Flex, { className: LivenessClassNames.ToastMessage, ...(isInitial ? { color: tokens.colors.font.primary } : {}) }, children))));
10
+ };
11
+
12
+ export { Toast };
@@ -1 +1,54 @@
1
- var e;!function(e){e.CameraModule="amplify-liveness-camera-module",e.CancelContainer="amplify-liveness-cancel-container",e.CancelButton="amplify-liveness-cancel-button",e.CountdownContainer="amplify-liveness-countdown-container",e.DescriptionBullet="amplify-liveness-description-bullet",e.DescriptionBulletIndex="amplify-liveness-description-bullet__index",e.DescriptionBulletIndexText="amplify-liveness-description-bullet__index__text",e.DescriptionBulletMessage="amplify-liveness-description-bullet__message",e.ErrorModal="amplify-liveness-error-modal",e.ErrorModalHeading="amplify-liveness-error-modal__heading",e.FadeOut="amplify-liveness-fade-out",e.FreshnessCanvas="amplify-liveness-freshness-canvas",e.InstructionList="amplify-liveness-instruction-list",e.InstructionOverlay="amplify-liveness-instruction-overlay",e.Figure="amplify-liveness-figure",e.FigureCaption="amplify-liveness-figure__caption",e.FigureIcon="amplify-liveness-figure__icon",e.FigureImage="amplify-liveness-figure__image",e.Figures="amplify-liveness-figures",e.Hint="amplify-liveness-hint",e.HintText="amplify-liveness-hint__text",e.LandscapeErrorModal="amplify-liveness-landscape-error-modal",e.LandscapeErrorModalButton="amplify-liveness-landscape-error-modal__button",e.LandscapeErrorModalHeader="amplify-liveness-landscape-error-modal__header",e.Loader="amplify-liveness-loader",e.MatchIndicator="amplify-liveness-match-indicator",e.OvalCanvas="amplify-liveness-oval-canvas",e.OpaqueOverlay="amplify-liveness-overlay-opaque",e.Overlay="amplify-liveness-overlay",e.Popover="amplify-liveness-popover",e.PopoverContainer="amplify-liveness-popover__container",e.PopoverAnchor="amplify-liveness-popover__anchor",e.PopoverAnchorSecondary="amplify-liveness-popover__anchor-secondary",e.RecordingIconContainer="amplify-liveness-recording-icon-container",e.RecordingIcon="amplify-liveness-recording-icon",e.StartScreenHeader="amplify-liveness-start-screen-header",e.StartScreenHeaderBody="amplify-liveness-start-screen-header__body",e.StartScreenHeaderHeading="amplify-liveness-start-screen-header__heading",e.StartScreenWarning="amplify-liveness-start-screen-warning",e.StartScreenInstructions="amplify-liveness-start-screen-instructions",e.StartScreenInstructionsHeading="amplify-liveness-start-screen-instructions__heading",e.Toast="amplify-liveness-toast",e.ToastContainer="amplify-liveness-toast__container",e.ToastMessage="amplify-liveness-toast__message",e.Video="amplify-liveness-video",e.VideoAnchor="amplify-liveness-video-anchor"}(e||(e={}));export{e as LivenessClassNames};
1
+ var LivenessClassNames;
2
+ (function (LivenessClassNames) {
3
+ LivenessClassNames["CameraModule"] = "amplify-liveness-camera-module";
4
+ LivenessClassNames["CancelContainer"] = "amplify-liveness-cancel-container";
5
+ LivenessClassNames["CancelButton"] = "amplify-liveness-cancel-button";
6
+ LivenessClassNames["CountdownContainer"] = "amplify-liveness-countdown-container";
7
+ LivenessClassNames["DescriptionBullet"] = "amplify-liveness-description-bullet";
8
+ LivenessClassNames["DescriptionBulletIndex"] = "amplify-liveness-description-bullet__index";
9
+ LivenessClassNames["DescriptionBulletIndexText"] = "amplify-liveness-description-bullet__index__text";
10
+ LivenessClassNames["DescriptionBulletMessage"] = "amplify-liveness-description-bullet__message";
11
+ LivenessClassNames["ErrorModal"] = "amplify-liveness-error-modal";
12
+ LivenessClassNames["ErrorModalHeading"] = "amplify-liveness-error-modal__heading";
13
+ LivenessClassNames["FadeOut"] = "amplify-liveness-fade-out";
14
+ LivenessClassNames["FreshnessCanvas"] = "amplify-liveness-freshness-canvas";
15
+ LivenessClassNames["InstructionList"] = "amplify-liveness-instruction-list";
16
+ LivenessClassNames["InstructionOverlay"] = "amplify-liveness-instruction-overlay";
17
+ LivenessClassNames["Figure"] = "amplify-liveness-figure";
18
+ LivenessClassNames["FigureCaption"] = "amplify-liveness-figure__caption";
19
+ LivenessClassNames["FigureIcon"] = "amplify-liveness-figure__icon";
20
+ LivenessClassNames["FigureImage"] = "amplify-liveness-figure__image";
21
+ LivenessClassNames["Figures"] = "amplify-liveness-figures";
22
+ LivenessClassNames["Hint"] = "amplify-liveness-hint";
23
+ LivenessClassNames["HintText"] = "amplify-liveness-hint__text";
24
+ LivenessClassNames["LandscapeErrorModal"] = "amplify-liveness-landscape-error-modal";
25
+ LivenessClassNames["LandscapeErrorModalButton"] = "amplify-liveness-landscape-error-modal__button";
26
+ LivenessClassNames["LandscapeErrorModalHeader"] = "amplify-liveness-landscape-error-modal__header";
27
+ LivenessClassNames["Loader"] = "amplify-liveness-loader";
28
+ LivenessClassNames["MatchIndicator"] = "amplify-liveness-match-indicator";
29
+ LivenessClassNames["OvalCanvas"] = "amplify-liveness-oval-canvas";
30
+ LivenessClassNames["OpaqueOverlay"] = "amplify-liveness-overlay-opaque";
31
+ LivenessClassNames["Overlay"] = "amplify-liveness-overlay";
32
+ LivenessClassNames["Popover"] = "amplify-liveness-popover";
33
+ LivenessClassNames["PopoverContainer"] = "amplify-liveness-popover__container";
34
+ LivenessClassNames["PopoverAnchor"] = "amplify-liveness-popover__anchor";
35
+ LivenessClassNames["PopoverAnchorSecondary"] = "amplify-liveness-popover__anchor-secondary";
36
+ LivenessClassNames["RecordingIconContainer"] = "amplify-liveness-recording-icon-container";
37
+ LivenessClassNames["RecordingIcon"] = "amplify-liveness-recording-icon";
38
+ LivenessClassNames["StartScreenCameraSelect"] = "amplify-liveness-start-screen-camera-select";
39
+ LivenessClassNames["StartScreenCameraSelectContainer"] = "amplify-liveness-start-screen-camera-select__container";
40
+ LivenessClassNames["StartScreenCameraWaiting"] = "amplify-liveness-start-screen-camera-waiting";
41
+ LivenessClassNames["StartScreenHeader"] = "amplify-liveness-start-screen-header";
42
+ LivenessClassNames["StartScreenHeaderBody"] = "amplify-liveness-start-screen-header__body";
43
+ LivenessClassNames["StartScreenHeaderHeading"] = "amplify-liveness-start-screen-header__heading";
44
+ LivenessClassNames["StartScreenWarning"] = "amplify-liveness-start-screen-warning";
45
+ LivenessClassNames["StartScreenInstructions"] = "amplify-liveness-start-screen-instructions";
46
+ LivenessClassNames["StartScreenInstructionsHeading"] = "amplify-liveness-start-screen-instructions__heading";
47
+ LivenessClassNames["Toast"] = "amplify-liveness-toast";
48
+ LivenessClassNames["ToastContainer"] = "amplify-liveness-toast__container";
49
+ LivenessClassNames["ToastMessage"] = "amplify-liveness-toast__message";
50
+ LivenessClassNames["Video"] = "amplify-liveness-video";
51
+ LivenessClassNames["VideoAnchor"] = "amplify-liveness-video-anchor";
52
+ })(LivenessClassNames || (LivenessClassNames = {}));
53
+
54
+ export { LivenessClassNames };
@@ -1 +1,24 @@
1
- function n(){return/Android|iPhone|iPad/i.test(navigator.userAgent)||/Macintosh/i.test(navigator.userAgent)&&!!navigator.maxTouchPoints&&navigator.maxTouchPoints>1}function t(){return window.matchMedia("(orientation: landscape)")}export{t as getLandscapeMediaQuery,n as isMobileScreen};
1
+ function isNewerIpad() {
2
+ // iPads on iOS13+ return as if a desktop Mac
3
+ // so check for maxTouchPoints also.
4
+ return (/Macintosh/i.test(navigator.userAgent) &&
5
+ !!navigator.maxTouchPoints &&
6
+ navigator.maxTouchPoints > 1);
7
+ }
8
+ function isMobileScreen() {
9
+ const isMobileDevice =
10
+ // Test Android/iPhone/iPad
11
+ /Android|iPhone|iPad/i.test(navigator.userAgent) || isNewerIpad();
12
+ return isMobileDevice;
13
+ }
14
+ /**
15
+ * Use window.matchMedia to direct landscape orientation
16
+ * screen.orientation is not supported in Safari so we will use
17
+ * media query detection to listen for changes instead.
18
+ * @returns MediaQueryList object
19
+ */
20
+ function getLandscapeMediaQuery() {
21
+ return window.matchMedia('(orientation: landscape)');
22
+ }
23
+
24
+ export { getLandscapeMediaQuery, isMobileScreen };