@aws-amplify/ui-react-liveness 3.3.9 → 3.4.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 (61) hide show
  1. package/dist/esm/components/FaceLivenessDetector/FaceLivenessDetectorCore.mjs +4 -2
  2. package/dist/esm/components/FaceLivenessDetector/LivenessCheck/CameraSelector.mjs +13 -0
  3. package/dist/esm/components/FaceLivenessDetector/LivenessCheck/LivenessCameraModule.mjs +50 -28
  4. package/dist/esm/components/FaceLivenessDetector/LivenessCheck/LivenessCheck.mjs +5 -4
  5. package/dist/esm/components/FaceLivenessDetector/service/machine/machine.mjs +247 -314
  6. package/dist/esm/components/FaceLivenessDetector/service/utils/ColorSequenceDisplay/ColorSequenceDisplay.mjs +140 -0
  7. package/dist/esm/components/FaceLivenessDetector/service/utils/StreamRecorder/StreamRecorder.mjs +171 -0
  8. package/dist/esm/components/FaceLivenessDetector/service/utils/TelemetryReporter/TelemetryReporter.mjs +27 -0
  9. package/dist/esm/components/FaceLivenessDetector/service/utils/constants.mjs +30 -7
  10. package/dist/esm/components/FaceLivenessDetector/service/utils/createRequestStreamGenerator/createRequestStreamGenerator.mjs +32 -0
  11. package/dist/esm/components/FaceLivenessDetector/service/utils/createRequestStreamGenerator/utils.mjs +148 -0
  12. package/dist/esm/components/FaceLivenessDetector/service/utils/createStreamingClient/Signer.mjs +2 -3
  13. package/dist/esm/components/FaceLivenessDetector/service/utils/createStreamingClient/createStreamingClient.mjs +36 -6
  14. package/dist/esm/components/FaceLivenessDetector/service/utils/createStreamingClient/resolveCredentials.mjs +7 -6
  15. package/dist/esm/components/FaceLivenessDetector/service/utils/getFaceMatchStateInLivenessOval.mjs +9 -5
  16. package/dist/esm/components/FaceLivenessDetector/service/utils/liveness.mjs +19 -34
  17. package/dist/esm/components/FaceLivenessDetector/service/utils/{eventUtils.mjs → responseStreamEvent.mjs} +2 -2
  18. package/dist/esm/components/FaceLivenessDetector/service/utils/sessionInformation.mjs +45 -0
  19. package/dist/esm/components/FaceLivenessDetector/shared/DefaultStartScreenComponents.mjs +3 -2
  20. package/dist/esm/components/FaceLivenessDetector/shared/FaceLivenessErrorModal.mjs +4 -2
  21. package/dist/esm/components/FaceLivenessDetector/shared/Hint.mjs +4 -7
  22. package/dist/esm/components/FaceLivenessDetector/types/classNames.mjs +3 -0
  23. package/dist/esm/components/FaceLivenessDetector/utils/device.mjs +12 -12
  24. package/dist/esm/index.mjs +12 -0
  25. package/dist/esm/version.mjs +1 -1
  26. package/dist/index.js +956 -775
  27. package/dist/styles.css +17 -2
  28. package/dist/types/components/FaceLivenessDetector/LivenessCheck/CameraSelector.d.ts +8 -0
  29. package/dist/types/components/FaceLivenessDetector/LivenessCheck/LivenessCameraModule.d.ts +1 -0
  30. package/dist/types/components/FaceLivenessDetector/index.d.ts +1 -0
  31. package/dist/types/components/FaceLivenessDetector/service/types/machine.d.ts +37 -24
  32. package/dist/types/components/FaceLivenessDetector/service/utils/ColorSequenceDisplay/ColorSequenceDisplay.d.ts +55 -0
  33. package/dist/types/components/FaceLivenessDetector/service/utils/ColorSequenceDisplay/index.d.ts +2 -0
  34. package/dist/types/components/FaceLivenessDetector/service/utils/StreamRecorder/StreamRecorder.d.ts +15 -0
  35. package/dist/types/components/FaceLivenessDetector/service/utils/StreamRecorder/index.d.ts +1 -0
  36. package/dist/types/components/FaceLivenessDetector/service/utils/TelemetryReporter/TelemetryReporter.d.ts +8 -0
  37. package/dist/types/components/FaceLivenessDetector/service/utils/TelemetryReporter/index.d.ts +2 -0
  38. package/dist/types/components/FaceLivenessDetector/service/utils/constants.d.ts +27 -3
  39. package/dist/types/components/FaceLivenessDetector/service/utils/createRequestStreamGenerator/createRequestStreamGenerator.d.ts +15 -0
  40. package/dist/types/components/FaceLivenessDetector/service/utils/createRequestStreamGenerator/index.d.ts +2 -0
  41. package/dist/types/components/FaceLivenessDetector/service/utils/createRequestStreamGenerator/utils.d.ts +30 -0
  42. package/dist/types/components/FaceLivenessDetector/service/utils/createStreamingClient/Signer.d.ts +0 -1
  43. package/dist/types/components/FaceLivenessDetector/service/utils/createStreamingClient/createStreamingClient.d.ts +27 -5
  44. package/dist/types/components/FaceLivenessDetector/service/utils/createStreamingClient/index.d.ts +1 -0
  45. package/dist/types/components/FaceLivenessDetector/service/utils/getFaceMatchStateInLivenessOval.d.ts +3 -4
  46. package/dist/types/components/FaceLivenessDetector/service/utils/index.d.ts +7 -4
  47. package/dist/types/components/FaceLivenessDetector/service/utils/liveness.d.ts +15 -26
  48. package/dist/types/components/FaceLivenessDetector/service/utils/{eventUtils.d.ts → responseStreamEvent.d.ts} +1 -1
  49. package/dist/types/components/FaceLivenessDetector/service/utils/sessionInformation.d.ts +7 -0
  50. package/dist/types/components/FaceLivenessDetector/service/utils/types.d.ts +21 -0
  51. package/dist/types/components/FaceLivenessDetector/types/classNames.d.ts +3 -0
  52. package/dist/types/components/FaceLivenessDetector/utils/device.d.ts +1 -0
  53. package/dist/types/version.d.ts +1 -1
  54. package/package.json +8 -8
  55. package/dist/esm/components/FaceLivenessDetector/service/utils/freshnessColorDisplay.mjs +0 -131
  56. package/dist/esm/components/FaceLivenessDetector/service/utils/streamProvider.mjs +0 -126
  57. package/dist/esm/components/FaceLivenessDetector/service/utils/videoRecorder.mjs +0 -108
  58. package/dist/types/components/FaceLivenessDetector/service/types/service.d.ts +0 -5
  59. package/dist/types/components/FaceLivenessDetector/service/utils/freshnessColorDisplay.d.ts +0 -21
  60. package/dist/types/components/FaceLivenessDetector/service/utils/streamProvider.d.ts +0 -42
  61. package/dist/types/components/FaceLivenessDetector/service/utils/videoRecorder.d.ts +0 -27
@@ -7,9 +7,11 @@ import '@tensorflow-models/face-detection';
7
7
  import '@tensorflow/tfjs-backend-wasm';
8
8
  import '@tensorflow/tfjs-backend-cpu';
9
9
  import '@aws-amplify/core/internals/utils';
10
- import '@aws-sdk/client-rekognitionstreaming';
10
+ import './service/utils/constants.mjs';
11
+ import './service/utils/ColorSequenceDisplay/ColorSequenceDisplay.mjs';
12
+ import '@aws-amplify/ui';
11
13
  import './service/utils/createStreamingClient/createStreamingClient.mjs';
12
- import './service/utils/freshnessColorDisplay.mjs';
14
+ import './service/utils/StreamRecorder/StreamRecorder.mjs';
13
15
  import { View, Flex } from '@aws-amplify/ui-react';
14
16
  import { FaceLivenessDetectorProvider } from './providers/FaceLivenessDetectorProvider.mjs';
15
17
  import { LivenessCheck } from './LivenessCheck/LivenessCheck.mjs';
@@ -0,0 +1,13 @@
1
+ import { Flex, View, Label, SelectField } from '@aws-amplify/ui-react';
2
+ import React__default from 'react';
3
+ import { LivenessClassNames } from '../types/classNames.mjs';
4
+
5
+ const CameraSelector = (props) => {
6
+ const { onSelect: onCameraChange, devices: selectableDevices, deviceId: selectedDeviceId, } = props;
7
+ return (React__default.createElement(Flex, { className: LivenessClassNames.StartScreenCameraSelect },
8
+ React__default.createElement(View, { className: LivenessClassNames.StartScreenCameraSelectContainer },
9
+ React__default.createElement(Label, { htmlFor: "amplify-liveness-camera-select", className: `${LivenessClassNames.StartScreenCameraSelect}__label` }, "Camera:"),
10
+ React__default.createElement(SelectField, { id: "amplify-liveness-camera-select", testId: "amplify-liveness-camera-select", label: "Camera", labelHidden: true, value: selectedDeviceId, onChange: onCameraChange }, selectableDevices.map((device) => (React__default.createElement("option", { value: device.deviceId, key: device.deviceId }, device.label)))))));
11
+ };
12
+
13
+ export { CameraSelector };
@@ -1,6 +1,6 @@
1
1
  import React__default, { useRef, useState } from 'react';
2
2
  import { classNames } from '@aws-amplify/ui';
3
- import { Loader, View, Flex, Text, Label, SelectField, Button } from '@aws-amplify/ui-react';
3
+ import { View, Flex, Loader, Text, Button } from '@aws-amplify/ui-react';
4
4
  import { useColorMode } from '@aws-amplify/ui-react/internal';
5
5
  import '../service/machine/machine.mjs';
6
6
  import { FaceMatchState } from '../service/types/liveness.mjs';
@@ -10,9 +10,10 @@ import '@tensorflow/tfjs-backend-wasm';
10
10
  import '@tensorflow/tfjs-backend-cpu';
11
11
  import '@aws-amplify/core/internals/utils';
12
12
  import { drawStaticOval, clearOvalCanvas } from '../service/utils/liveness.mjs';
13
- import '@aws-sdk/client-rekognitionstreaming';
13
+ import { FACE_MOVEMENT_CHALLENGE } from '../service/utils/constants.mjs';
14
+ import '../service/utils/ColorSequenceDisplay/ColorSequenceDisplay.mjs';
14
15
  import '../service/utils/createStreamingClient/createStreamingClient.mjs';
15
- import '../service/utils/freshnessColorDisplay.mjs';
16
+ import '../service/utils/StreamRecorder/StreamRecorder.mjs';
16
17
  import { useLivenessActor } from '../hooks/useLivenessActor.mjs';
17
18
  import { useLivenessSelector, createLivenessSelector } from '../hooks/useLivenessSelector.mjs';
18
19
  import { useMediaStreamInVideo } from '../hooks/useMediaStreamInVideo.mjs';
@@ -20,16 +21,18 @@ import { LivenessClassNames } from '../types/classNames.mjs';
20
21
  import { selectErrorState, Hint } from '../shared/Hint.mjs';
21
22
  import { MatchIndicator } from '../shared/MatchIndicator.mjs';
22
23
  import { Overlay } from '../shared/Overlay.mjs';
24
+ import { isDeviceUserFacing } from '../utils/device.mjs';
23
25
  import { FaceLivenessErrorModal, renderErrorModal } from '../shared/FaceLivenessErrorModal.mjs';
24
26
  import { DefaultPhotosensitiveWarning, DefaultRecordingIcon, DefaultCancelButton } from '../shared/DefaultStartScreenComponents.mjs';
27
+ import { CameraSelector } from './CameraSelector.mjs';
25
28
 
29
+ const selectChallengeType = createLivenessSelector((state) => state.context.parsedSessionInformation?.Challenge?.Name);
26
30
  const selectVideoConstraints = createLivenessSelector((state) => state.context.videoAssociatedParams?.videoConstraints);
27
31
  const selectVideoStream = createLivenessSelector((state) => state.context.videoAssociatedParams?.videoMediaStream);
28
32
  const selectFaceMatchPercentage = createLivenessSelector((state) => state.context.faceMatchAssociatedParams?.faceMatchPercentage);
29
33
  const selectFaceMatchState = createLivenessSelector((state) => state.context.faceMatchAssociatedParams?.faceMatchState);
30
34
  const selectSelectedDeviceId = createLivenessSelector((state) => state.context.videoAssociatedParams?.selectedDeviceId);
31
35
  const selectSelectableDevices = createLivenessSelector((state) => state.context.videoAssociatedParams?.selectableDevices);
32
- const centeredLoader = (React__default.createElement(Loader, { size: "large", className: LivenessClassNames.Loader, "data-testid": "centered-loader" }));
33
36
  const showMatchIndicatorStates = [
34
37
  FaceMatchState.TOO_FAR,
35
38
  FaceMatchState.CANT_IDENTIFY,
@@ -47,6 +50,7 @@ const LivenessCameraModule = (props) => {
47
50
  const { cancelLivenessCheckText, recordingIndicatorText } = streamDisplayText;
48
51
  const { ErrorView = FaceLivenessErrorModal, PhotosensitiveWarning = DefaultPhotosensitiveWarning, } = customComponents ?? {};
49
52
  const [state, send] = useLivenessActor();
53
+ const isFaceMovementChallenge = useLivenessSelector(selectChallengeType) === FACE_MOVEMENT_CHALLENGE.type;
50
54
  const videoStream = useLivenessSelector(selectVideoStream);
51
55
  const videoConstraints = useLivenessSelector(selectVideoConstraints);
52
56
  const selectedDeviceId = useLivenessSelector(selectSelectedDeviceId);
@@ -59,8 +63,14 @@ const LivenessCameraModule = (props) => {
59
63
  const canvasRef = useRef(null);
60
64
  const freshnessColorRef = useRef(null);
61
65
  const [isCameraReady, setIsCameraReady] = useState(false);
62
- const isCheckingCamera = state.matches('cameraCheck');
63
- const isWaitingForCamera = state.matches('waitForDOMAndCameraDetails');
66
+ const [isMetadataLoaded, setIsMetadataLoaded] = useState(false);
67
+ const [isCameraUserFacing, setIsCameraUserFacing] = useState(true);
68
+ const isInitCamera = state.matches('initCamera');
69
+ const isInitWebsocket = state.matches('initWebsocket');
70
+ const isCheckingCamera = state.matches({ initCamera: 'cameraCheck' });
71
+ const isWaitingForCamera = state.matches({
72
+ initCamera: 'waitForDOMAndCameraDetails',
73
+ });
64
74
  const isStartView = state.matches('start') || state.matches('userCancel');
65
75
  const isDetectFaceBeforeStart = state.matches('detectFaceBeforeStart');
66
76
  const isRecording = state.matches('recording');
@@ -74,18 +84,29 @@ const LivenessCameraModule = (props) => {
74
84
  const [mediaWidth, setMediaWidth] = useState(videoWidth);
75
85
  const [mediaHeight, setMediaHeight] = useState(videoHeight);
76
86
  const [aspectRatio, setAspectRatio] = useState(() => videoWidth && videoHeight ? videoWidth / videoHeight : 0);
87
+ // Only mobile device camera selection for no light challenge
88
+ const hasMultipleDevices = !!selectableDevices?.length && selectableDevices.length > 1;
89
+ const allowDeviceSelection = isStartView &&
90
+ hasMultipleDevices &&
91
+ (!isMobileScreen || isFaceMovementChallenge);
77
92
  React__default.useEffect(() => {
78
- if (canvasRef?.current && videoRef?.current && videoStream && isStartView) {
79
- drawStaticOval(canvasRef.current, videoRef.current, videoStream);
93
+ async function checkCameraFacing() {
94
+ const isUserFacing = await isDeviceUserFacing(selectedDeviceId);
95
+ setIsCameraUserFacing(isUserFacing);
80
96
  }
81
- }, [canvasRef, videoRef, videoStream, colorMode, isStartView]);
97
+ checkCameraFacing();
98
+ }, [selectedDeviceId]);
82
99
  React__default.useEffect(() => {
100
+ const shouldDrawOval = canvasRef?.current &&
101
+ videoRef?.current &&
102
+ videoStream &&
103
+ isStartView &&
104
+ isMetadataLoaded;
105
+ if (shouldDrawOval) {
106
+ drawStaticOval(canvasRef.current, videoRef.current, videoStream);
107
+ }
83
108
  const updateColorModeHandler = (e) => {
84
- if (e.matches &&
85
- canvasRef?.current &&
86
- videoRef?.current &&
87
- videoStream &&
88
- isStartView) {
109
+ if (e.matches && shouldDrawOval) {
89
110
  drawStaticOval(canvasRef.current, videoRef.current, videoStream);
90
111
  }
91
112
  };
@@ -97,7 +118,7 @@ const LivenessCameraModule = (props) => {
97
118
  darkModePreference.removeEventListener('change', updateColorModeHandler);
98
119
  lightModePreference.addEventListener('change', updateColorModeHandler);
99
120
  };
100
- }, [canvasRef, videoRef, videoStream, isStartView]);
121
+ }, [videoRef, videoStream, colorMode, isStartView, isMetadataLoaded]);
101
122
  React__default.useLayoutEffect(() => {
102
123
  if (isCameraReady) {
103
124
  send({
@@ -128,6 +149,9 @@ const LivenessCameraModule = (props) => {
128
149
  const handleMediaPlay = () => {
129
150
  setIsCameraReady(true);
130
151
  };
152
+ const handleLoadedMetadata = () => {
153
+ setIsMetadataLoaded(true);
154
+ };
131
155
  const beginLivenessCheck = React__default.useCallback(() => {
132
156
  send({
133
157
  type: 'BEGIN',
@@ -136,6 +160,7 @@ const LivenessCameraModule = (props) => {
136
160
  const onCameraChange = React__default.useCallback((e) => {
137
161
  const newDeviceId = e.target.value;
138
162
  const changeCamera = async () => {
163
+ setIsMetadataLoaded(false);
139
164
  const newStream = await navigator.mediaDevices.getUserMedia({
140
165
  video: {
141
166
  ...videoConstraints,
@@ -152,16 +177,19 @@ const LivenessCameraModule = (props) => {
152
177
  }, [videoConstraints, send]);
153
178
  if (isCheckingCamera) {
154
179
  return (React__default.createElement(Flex, { justifyContent: 'center', className: LivenessClassNames.StartScreenCameraWaiting },
155
- React__default.createElement(Loader, { size: "large", className: LivenessClassNames.Loader, "data-testid": "centered-loader", position: "unset" }),
180
+ React__default.createElement(Loader, { size: "large", className: LivenessClassNames.CenteredLoader, "data-testid": "centered-loader", position: "unset" }),
156
181
  React__default.createElement(Text, { fontSize: "large", fontWeight: "bold", "data-testid": "waiting-camera-permission", className: `${LivenessClassNames.StartScreenCameraWaiting}__text` }, cameraDisplayText.waitingCameraPermissionText)));
157
182
  }
183
+ const shouldShowCenteredLoader = isInitCamera || isInitWebsocket;
158
184
  // We don't show full screen camera on the pre check screen (isStartView/isWaitingForCamera)
159
- const shouldShowFullScreenCamera = isMobileScreen && !isStartView && !isWaitingForCamera;
185
+ const shouldShowFullScreenCamera = isMobileScreen && !isStartView && !shouldShowCenteredLoader;
160
186
  return (React__default.createElement(React__default.Fragment, null,
161
- photoSensitivityWarning,
187
+ !isFaceMovementChallenge && photoSensitivityWarning,
188
+ shouldShowCenteredLoader && (React__default.createElement(Flex, { className: LivenessClassNames.ConnectingLoader },
189
+ React__default.createElement(Loader, { size: "large", className: LivenessClassNames.Loader, "data-testid": "centered-loader" }),
190
+ React__default.createElement(Text, { className: LivenessClassNames.LandscapeErrorModalHeader }, hintDisplayText.hintConnectingText))),
162
191
  React__default.createElement(Flex, { className: classNames(LivenessClassNames.CameraModule, shouldShowFullScreenCamera &&
163
192
  `${LivenessClassNames.CameraModule}--mobile`), "data-testid": testId, gap: "zero" },
164
- !isCameraReady && centeredLoader,
165
193
  React__default.createElement(Overlay, { horizontal: "center", vertical: isRecording && !isFlashingFreshness ? 'start' : 'space-between', className: LivenessClassNames.InstructionOverlay },
166
194
  isRecording && (React__default.createElement(DefaultRecordingIcon, { recordingIndicatorText: recordingIndicatorText })),
167
195
  !isStartView && !isWaitingForCamera && !isCheckSucceeded && (React__default.createElement(DefaultCancelButton, { cancelLivenessCheckText: cancelLivenessCheckText })),
@@ -180,19 +208,13 @@ const LivenessCameraModule = (props) => {
180
208
  React__default.createElement(View, { className: LivenessClassNames.VideoAnchor, style: {
181
209
  aspectRatio: `${aspectRatio}`,
182
210
  } },
183
- React__default.createElement("video", { ref: videoRef, muted: true, autoPlay: true, playsInline: true, width: mediaWidth, height: mediaHeight, onCanPlay: handleMediaPlay, "data-testid": "video", className: classNames(LivenessClassNames.Video, isRecordingStopped && LivenessClassNames.FadeOut), "aria-label": cameraDisplayText.a11yVideoLabelText }),
211
+ React__default.createElement("video", { ref: videoRef, muted: true, autoPlay: true, playsInline: true, width: mediaWidth, height: mediaHeight, onCanPlay: handleMediaPlay, onLoadedMetadata: handleLoadedMetadata, "data-testid": "video", className: classNames(LivenessClassNames.Video, isCameraUserFacing && LivenessClassNames.UserFacingVideo, isRecordingStopped && LivenessClassNames.FadeOut), "aria-label": cameraDisplayText.a11yVideoLabelText }),
184
212
  React__default.createElement(Flex, { className: classNames(LivenessClassNames.OvalCanvas, shouldShowFullScreenCamera &&
185
213
  `${LivenessClassNames.OvalCanvas}--mobile`, isRecordingStopped && LivenessClassNames.FadeOut) },
186
214
  React__default.createElement(View, { as: "canvas", ref: canvasRef })),
187
- isStartView &&
188
- !isMobileScreen &&
189
- selectableDevices &&
190
- selectableDevices.length > 1 && (React__default.createElement(Flex, { className: LivenessClassNames.StartScreenCameraSelect },
191
- React__default.createElement(View, { className: LivenessClassNames.StartScreenCameraSelectContainer },
192
- React__default.createElement(Label, { htmlFor: "amplify-liveness-camera-select", className: `${LivenessClassNames.StartScreenCameraSelect}__label` }, "Camera:"),
193
- React__default.createElement(SelectField, { id: "amplify-liveness-camera-select", label: "Camera", labelHidden: true, value: selectedDeviceId, onChange: onCameraChange }, selectableDevices?.map((device) => (React__default.createElement("option", { value: device.deviceId, key: device.deviceId }, device.label))))))))),
215
+ allowDeviceSelection ? (React__default.createElement(CameraSelector, { onSelect: onCameraChange, devices: selectableDevices, deviceId: selectedDeviceId })) : null)),
194
216
  isStartView && (React__default.createElement(Flex, { justifyContent: "center" },
195
217
  React__default.createElement(Button, { variation: "primary", type: "button", onClick: beginLivenessCheck }, instructionDisplayText.startScreenBeginCheckText)))));
196
218
  };
197
219
 
198
- export { LivenessCameraModule, selectFaceMatchPercentage, selectFaceMatchState, selectSelectableDevices, selectSelectedDeviceId, selectVideoConstraints, selectVideoStream };
220
+ export { LivenessCameraModule, selectChallengeType, selectFaceMatchPercentage, selectFaceMatchState, selectSelectableDevices, selectSelectedDeviceId, selectVideoConstraints, selectVideoStream };
@@ -8,14 +8,15 @@ import '@tensorflow-models/face-detection';
8
8
  import '@tensorflow/tfjs-backend-wasm';
9
9
  import '@tensorflow/tfjs-backend-cpu';
10
10
  import '@aws-amplify/core/internals/utils';
11
- import { getLandscapeMediaQuery, isMobileScreen } from '../utils/device.mjs';
12
- import '@aws-sdk/client-rekognitionstreaming';
11
+ import '../service/utils/constants.mjs';
12
+ import '../service/utils/ColorSequenceDisplay/ColorSequenceDisplay.mjs';
13
+ import '@aws-amplify/ui';
13
14
  import '../service/utils/createStreamingClient/createStreamingClient.mjs';
14
- import '../service/utils/freshnessColorDisplay.mjs';
15
+ import '../service/utils/StreamRecorder/StreamRecorder.mjs';
15
16
  import { LivenessCameraModule } from './LivenessCameraModule.mjs';
16
17
  import { useLivenessActor } from '../hooks/useLivenessActor.mjs';
17
18
  import { useLivenessSelector, createLivenessSelector } from '../hooks/useLivenessSelector.mjs';
18
- import '@aws-amplify/ui';
19
+ import { getLandscapeMediaQuery, isMobileScreen } from '../utils/device.mjs';
19
20
  import { CancelButton } from '../shared/CancelButton.mjs';
20
21
  import { defaultErrorDisplayText } from '../displayText.mjs';
21
22
  import { LandscapeErrorModal } from '../shared/LandscapeErrorModal.mjs';